Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement db saving #13

Merged
merged 11 commits into from
Dec 19, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .github/workflows/formatter.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,5 +19,5 @@ jobs:
pip install isort black
- name: Run isort and black
run: |
isort -c .
black --check .
isort -c src tests
black --check src tests
5 changes: 4 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,7 @@ htmlcov
coverage.xml

# macOS
.DS_Store
.DS_Store

# Files from Django db
/sio3pack
3 changes: 2 additions & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,9 @@ build-backend = "setuptools.build_meta"

[tool.isort]
line_length = 120
multi_line_output = 1
multi_line_output = 3
include_trailing_comma = true
skip = ["migrations", ".venv"]

[tool.black]
line_length = 120
Expand Down
66 changes: 66 additions & 0 deletions src/sio3pack/django/common/handler.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
from typing import Type

from django.core.files import File
from django.db import transaction

from sio3pack.django.common.models import SIO3Package, SIO3PackModelSolution, SIO3PackNameTranslation, SIO3PackStatement
from sio3pack.files.local_file import LocalFile
from sio3pack.packages.exceptions import ImproperlyConfigured, PackageAlreadyExists


class DjangoHandler:
def __init__(self, package: Type["Package"], problem_id: int):
self.package = package
self.problem_id = problem_id
self.db_package = None

@transaction.atomic
def save_to_db(self):
"""
Save the package to the database.
"""
if SIO3Package.objects.filter(problem_id=self.problem_id).exists():
raise PackageAlreadyExists(self.problem_id)

self.db_package = SIO3Package.objects.create(
problem_id=self.problem_id,
short_name=self.package.short_name,
full_name=self.package.full_name,
)

self._save_translated_titles()
self._save_model_solutions()
self._save_problem_statements()

def _save_translated_titles(self):
"""
Save the translated titles to the database.
"""
for lang, title in self.package.get_titles().items():
SIO3PackNameTranslation.objects.create(
package=self.db_package,
language=lang,
name=title,
)

def _save_model_solutions(self):
for order, solution in enumerate(self.package.get_model_solutions()):
instance = SIO3PackModelSolution(
package=self.db_package,
name=solution.filename,
order_key=order,
)
instance.source_file.save(solution.filename, File(open(solution.path, "rb")))

def _save_problem_statements(self):
def _add_statement(language: str, statement: LocalFile):
instance = SIO3PackStatement(
package=self.db_package,
language=language,
)
instance.content.save(statement.filename, File(open(statement.path, "rb")))

if self.package.get_statement():
_add_statement("", self.package.get_statement())
for lang, statement in self.package.get_statements().items():
_add_statement(lang, statement)
287 changes: 287 additions & 0 deletions src/sio3pack/django/common/migrations/0001_initial.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,287 @@
# Generated by Django 5.1.4 on 2024-12-12 10:46

import django.db.models.deletion
import sio3pack.django.common.models
from django.db import migrations, models


class Migration(migrations.Migration):

initial = True

dependencies = []

operations = [
migrations.CreateModel(
name="SIO3Package",
fields=[
("id", models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name="ID")),
("problem_id", models.IntegerField()),
("short_name", models.CharField(max_length=30, verbose_name="short name")),
("full_name", models.CharField(default="", max_length=255, verbose_name="full name")),
],
),
migrations.CreateModel(
name="SIO3PackModelSolution",
fields=[
("id", models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name="ID")),
("name", models.CharField(max_length=255, verbose_name="name")),
(
"source_file",
models.FileField(
upload_to=sio3pack.django.common.models.make_problem_filename, verbose_name="source file"
),
),
("order_key", models.IntegerField(default=0)),
("package", models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to="common.sio3package")),
],
),
migrations.CreateModel(
name="SIO3PackStatement",
fields=[
("id", models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name="ID")),
(
"language",
models.CharField(
blank=True,
choices=[
("af", "Afrikaans"),
("ar", "Arabic"),
("ar-dz", "Algerian Arabic"),
("ast", "Asturian"),
("az", "Azerbaijani"),
("bg", "Bulgarian"),
("be", "Belarusian"),
("bn", "Bengali"),
("br", "Breton"),
("bs", "Bosnian"),
("ca", "Catalan"),
("ckb", "Central Kurdish (Sorani)"),
("cs", "Czech"),
("cy", "Welsh"),
("da", "Danish"),
("de", "German"),
("dsb", "Lower Sorbian"),
("el", "Greek"),
("en", "English"),
("en-au", "Australian English"),
("en-gb", "British English"),
("eo", "Esperanto"),
("es", "Spanish"),
("es-ar", "Argentinian Spanish"),
("es-co", "Colombian Spanish"),
("es-mx", "Mexican Spanish"),
("es-ni", "Nicaraguan Spanish"),
("es-ve", "Venezuelan Spanish"),
("et", "Estonian"),
("eu", "Basque"),
("fa", "Persian"),
("fi", "Finnish"),
("fr", "French"),
("fy", "Frisian"),
("ga", "Irish"),
("gd", "Scottish Gaelic"),
("gl", "Galician"),
("he", "Hebrew"),
("hi", "Hindi"),
("hr", "Croatian"),
("hsb", "Upper Sorbian"),
("hu", "Hungarian"),
("hy", "Armenian"),
("ia", "Interlingua"),
("id", "Indonesian"),
("ig", "Igbo"),
("io", "Ido"),
("is", "Icelandic"),
("it", "Italian"),
("ja", "Japanese"),
("ka", "Georgian"),
("kab", "Kabyle"),
("kk", "Kazakh"),
("km", "Khmer"),
("kn", "Kannada"),
("ko", "Korean"),
("ky", "Kyrgyz"),
("lb", "Luxembourgish"),
("lt", "Lithuanian"),
("lv", "Latvian"),
("mk", "Macedonian"),
("ml", "Malayalam"),
("mn", "Mongolian"),
("mr", "Marathi"),
("ms", "Malay"),
("my", "Burmese"),
("nb", "Norwegian Bokmål"),
("ne", "Nepali"),
("nl", "Dutch"),
("nn", "Norwegian Nynorsk"),
("os", "Ossetic"),
("pa", "Punjabi"),
("pl", "Polish"),
("pt", "Portuguese"),
("pt-br", "Brazilian Portuguese"),
("ro", "Romanian"),
("ru", "Russian"),
("sk", "Slovak"),
("sl", "Slovenian"),
("sq", "Albanian"),
("sr", "Serbian"),
("sr-latn", "Serbian Latin"),
("sv", "Swedish"),
("sw", "Swahili"),
("ta", "Tamil"),
("te", "Telugu"),
("tg", "Tajik"),
("th", "Thai"),
("tk", "Turkmen"),
("tr", "Turkish"),
("tt", "Tatar"),
("udm", "Udmurt"),
("ug", "Uyghur"),
("uk", "Ukrainian"),
("ur", "Urdu"),
("uz", "Uzbek"),
("vi", "Vietnamese"),
("zh-hans", "Simplified Chinese"),
("zh-hant", "Traditional Chinese"),
],
max_length=7,
null=True,
verbose_name="language code",
),
),
(
"content",
models.FileField(
upload_to=sio3pack.django.common.models.make_problem_filename, verbose_name="content"
),
),
("package", models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to="common.sio3package")),
],
options={
"verbose_name": "problem statement",
"verbose_name_plural": "problem statements",
},
),
migrations.CreateModel(
name="SIO3PackNameTranslation",
fields=[
("id", models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name="ID")),
(
"language",
models.CharField(
choices=[
("af", "Afrikaans"),
("ar", "Arabic"),
("ar-dz", "Algerian Arabic"),
("ast", "Asturian"),
("az", "Azerbaijani"),
("bg", "Bulgarian"),
("be", "Belarusian"),
("bn", "Bengali"),
("br", "Breton"),
("bs", "Bosnian"),
("ca", "Catalan"),
("ckb", "Central Kurdish (Sorani)"),
("cs", "Czech"),
("cy", "Welsh"),
("da", "Danish"),
("de", "German"),
("dsb", "Lower Sorbian"),
("el", "Greek"),
("en", "English"),
("en-au", "Australian English"),
("en-gb", "British English"),
("eo", "Esperanto"),
("es", "Spanish"),
("es-ar", "Argentinian Spanish"),
("es-co", "Colombian Spanish"),
("es-mx", "Mexican Spanish"),
("es-ni", "Nicaraguan Spanish"),
("es-ve", "Venezuelan Spanish"),
("et", "Estonian"),
("eu", "Basque"),
("fa", "Persian"),
("fi", "Finnish"),
("fr", "French"),
("fy", "Frisian"),
("ga", "Irish"),
("gd", "Scottish Gaelic"),
("gl", "Galician"),
("he", "Hebrew"),
("hi", "Hindi"),
("hr", "Croatian"),
("hsb", "Upper Sorbian"),
("hu", "Hungarian"),
("hy", "Armenian"),
("ia", "Interlingua"),
("id", "Indonesian"),
("ig", "Igbo"),
("io", "Ido"),
("is", "Icelandic"),
("it", "Italian"),
("ja", "Japanese"),
("ka", "Georgian"),
("kab", "Kabyle"),
("kk", "Kazakh"),
("km", "Khmer"),
("kn", "Kannada"),
("ko", "Korean"),
("ky", "Kyrgyz"),
("lb", "Luxembourgish"),
("lt", "Lithuanian"),
("lv", "Latvian"),
("mk", "Macedonian"),
("ml", "Malayalam"),
("mn", "Mongolian"),
("mr", "Marathi"),
("ms", "Malay"),
("my", "Burmese"),
("nb", "Norwegian Bokmål"),
("ne", "Nepali"),
("nl", "Dutch"),
("nn", "Norwegian Nynorsk"),
("os", "Ossetic"),
("pa", "Punjabi"),
("pl", "Polish"),
("pt", "Portuguese"),
("pt-br", "Brazilian Portuguese"),
("ro", "Romanian"),
("ru", "Russian"),
("sk", "Slovak"),
("sl", "Slovenian"),
("sq", "Albanian"),
("sr", "Serbian"),
("sr-latn", "Serbian Latin"),
("sv", "Swedish"),
("sw", "Swahili"),
("ta", "Tamil"),
("te", "Telugu"),
("tg", "Tajik"),
("th", "Thai"),
("tk", "Turkmen"),
("tr", "Turkish"),
("tt", "Tatar"),
("udm", "Udmurt"),
("ug", "Uyghur"),
("uk", "Ukrainian"),
("ur", "Urdu"),
("uz", "Uzbek"),
("vi", "Vietnamese"),
("zh-hans", "Simplified Chinese"),
("zh-hant", "Traditional Chinese"),
],
max_length=7,
verbose_name="language code",
),
),
("name", models.CharField(max_length=255, verbose_name="name translation")),
("package", models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to="common.sio3package")),
],
options={
"verbose_name": "sio3pack's name translation",
"verbose_name_plural": "sio3pack's name translations",
"unique_together": {("package", "language")},
},
),
]
Empty file.
Loading
Loading