diff --git a/district/forms.py b/district/forms.py index 03efb555b07efea5d2457a5fae28debca7d33a94..48600686a04f6efbc03dbd7de3cbe1dbe5c416c4 100644 --- a/district/forms.py +++ b/district/forms.py @@ -1,52 +1,16 @@ +from shared.forms import JekyllImportForm as SharedJekyllImportForm +import os from django import forms -from django.utils.safestring import mark_safe -from wagtail.admin.forms import WagtailAdminPageForm -from wagtail.models.collections import Collection +from .tasks import import_jekyll_articles -from shared.jekyll_import import JekyllArticleImporter - -class JekyllImportForm(WagtailAdminPageForm): - do_import = forms.BooleanField( - initial=False, required=False, label="Provést import z Jekyllu" - ) - collection = forms.ModelChoiceField( - queryset=Collection.objects.all(), required=False, label="Kolekce obrázků" - ) - dry_run = forms.BooleanField( - initial=True, - required=False, - label="Jenom na zkoušku", - help_text="Žádné články se neuloží, vypíše případné problémy či " - "již existující články - 'ostrému' importu existující " - "články nevadí, přeskočí je", - ) +class JekyllImportForm(SharedJekyllImportForm): use_git = forms.BooleanField( initial=False, required=False, label="Použít Git", help_text="Umožňuje jednodušší zpracování, ale vyžaduje nainstalovaný Git.", ) - jekyll_repo_url = forms.URLField( - max_length=512, - required=False, - help_text=mark_safe( - "V GitHubu tlačítko Code -> a odkaz z <strong>Download zip</strong>, " - "např. <em>https://github.com/pirati-web/cb.pirati.cz/archive/refs/heads/gh-pages.zip</em>. " - "Pokud máte nainstalovaný Git, zvolte <strong>Použít Git</strong> a vložte jednoduše " - "URL repozitáře, např. <em>https://github.com/pirati-web/cb.pirati.cz</em>." - ), - ) - readonly_log = forms.CharField( - disabled=True, - label="Log z posledního importu", - required=False, - widget=forms.Textarea, - ) - - def __init__(self, *args, **kwargs): - super().__init__(*args, **kwargs) - self.fields["readonly_log"].initial = self.instance.last_import_log def clean(self): cleaned_data = super().clean() @@ -54,16 +18,6 @@ class JekyllImportForm(WagtailAdminPageForm): if not cleaned_data.get("do_import"): return cleaned_data - if cleaned_data.get("do_import") and not self.instance.id: - self.add_error( - "do_import", "Import proveďte prosím až po vytvoření stránky" - ) - - if not cleaned_data.get("collection"): - self.add_error("collection", "Pro import je toto pole povinné") - if not cleaned_data.get("jekyll_repo_url"): - self.add_error("jekyll_repo_url", "Pro import je toto pole povinné") - if cleaned_data.get("use_git"): if cleaned_data.get("jekyll_repo_url", "").endswith(".zip"): self.add_error( @@ -81,19 +35,17 @@ class JekyllImportForm(WagtailAdminPageForm): return cleaned_data def handle_import(self): - from .models import DistrictArticlePage + lock_file_name = f"/tmp/.{self.instance.id}.import-lock" - JekyllArticleImporter( - article_parent_page=self.instance, + if os.path.isfile(lock_file_name): + return + + open(lock_file_name, "w").close() + + import_jekyll_articles.delay( + article_parent_page_id=self.instance.id, collection_id=self.cleaned_data["collection"].id, url=self.cleaned_data["jekyll_repo_url"], dry_run=self.cleaned_data["dry_run"], - use_git=self.cleaned_data["use_git"], - page_model=DistrictArticlePage, - ).perform_import() - - def save(self, commit=True): - if self.cleaned_data.get("do_import"): - self.handle_import() - - return super().save(commit=commit) + use_git=True, + ) diff --git a/district/tasks.py b/district/tasks.py new file mode 100644 index 0000000000000000000000000000000000000000..8162ecb06496e59c2bef2bd445984ff4fb7363d9 --- /dev/null +++ b/district/tasks.py @@ -0,0 +1,27 @@ +import logging + +from celery import shared_task +from shared.jekyll_import import JekyllArticleImporter + +logger = logging.getLogger(__name__) + + +@shared_task() +def import_jekyll_articles( + article_parent_page_id, + collection_id, + url, + dry_run, + use_git, +): + from .models import DistrictArticlePage, DistrictArticlesPage + + return JekyllArticleImporter( + article_parent_page_id=article_parent_page_id, + article_parent_page_model=DistrictArticlesPage, + collection_id=collection_id, + url=url, + dry_run=dry_run, + use_git=use_git, + page_model=DistrictArticlePage, + ).perform_import() diff --git a/elections/forms.py b/elections/forms.py new file mode 100644 index 0000000000000000000000000000000000000000..b252a89ac370c1ae3dd2b4dba6d51bb91d689604 --- /dev/null +++ b/elections/forms.py @@ -0,0 +1,21 @@ +from shared.forms import JekyllImportForm as SharedJekyllImportForm +import os +from .tasks import import_jekyll_articles + + +class JekyllImportForm(SharedJekyllImportForm): + def handle_import(self): + lock_file_name = f"/tmp/.{self.instance.id}.import-lock" + + if os.path.isfile(lock_file_name): + return + + open(lock_file_name, "w").close() + + import_jekyll_articles.delay( + article_parent_page_id=self.instance.id, + collection_id=self.cleaned_data["collection"].id, + url=self.cleaned_data["jekyll_repo_url"], + dry_run=self.cleaned_data["dry_run"], + use_git=True, + ) diff --git a/elections/models.py b/elections/models.py index 9f7f1bf88f3e740ab91c9953aef686262610fcc5..7222292745c5a7315b349973434bea4ef403d867 100644 --- a/elections/models.py +++ b/elections/models.py @@ -46,6 +46,7 @@ from shared.models import ( # MenuMixin, ) from shared.utils import make_promote_panels, subscribe_to_newsletter from tuning import admin_help +from .forms import JekyllImportForm from . import blocks @@ -118,6 +119,8 @@ class ElectionsHomePage(MainHomePageMixin): class ElectionsArticlesPage(MainArticlesPageMixin): + base_form_class = JekyllImportForm + parent_page_types = ["elections.ElectionsHomePage"] subpage_types = ["elections.ElectionsArticlePage"] diff --git a/elections/tasks.py b/elections/tasks.py new file mode 100644 index 0000000000000000000000000000000000000000..f3cce43e0f8491caa438ea473f1e9b69fb041c74 --- /dev/null +++ b/elections/tasks.py @@ -0,0 +1,27 @@ +import logging + +from celery import shared_task +from shared.jekyll_import import JekyllArticleImporter + +logger = logging.getLogger(__name__) + + +@shared_task() +def import_jekyll_articles( + article_parent_page_id, + collection_id, + url, + dry_run, + use_git, +): + from .models import ElectionsArticlePage, ElectionsArticlesPage + + return JekyllArticleImporter( + article_parent_page_id=article_parent_page_id, + article_parent_page_model=ElectionsArticlesPage, + collection_id=collection_id, + url=url, + dry_run=dry_run, + use_git=use_git, + page_model=ElectionsArticlePage, + ).perform_import() diff --git a/main/forms.py b/main/forms.py new file mode 100644 index 0000000000000000000000000000000000000000..b252a89ac370c1ae3dd2b4dba6d51bb91d689604 --- /dev/null +++ b/main/forms.py @@ -0,0 +1,21 @@ +from shared.forms import JekyllImportForm as SharedJekyllImportForm +import os +from .tasks import import_jekyll_articles + + +class JekyllImportForm(SharedJekyllImportForm): + def handle_import(self): + lock_file_name = f"/tmp/.{self.instance.id}.import-lock" + + if os.path.isfile(lock_file_name): + return + + open(lock_file_name, "w").close() + + import_jekyll_articles.delay( + article_parent_page_id=self.instance.id, + collection_id=self.cleaned_data["collection"].id, + url=self.cleaned_data["jekyll_repo_url"], + dry_run=self.cleaned_data["dry_run"], + use_git=True, + ) diff --git a/main/models.py b/main/models.py index c120f0404b5e83901ee04bc0002af366b2987715..9f4cc1678e85385e86a0999268714c91875b9dbe 100644 --- a/main/models.py +++ b/main/models.py @@ -46,6 +46,7 @@ from shared.models import ( # MenuMixin, ) from shared.utils import make_promote_panels, subscribe_to_newsletter from tuning import admin_help +from .forms import JekyllImportForm from . import blocks @@ -132,6 +133,8 @@ class MainHomePage(MainHomePageMixin): class MainArticlesPage(MainArticlesPageMixin): + base_form_class = JekyllImportForm + parent_page_types = ["main.MainHomePage"] subpage_types = ["main.MainArticlePage"] diff --git a/shared/tasks.py b/main/tasks.py similarity index 100% rename from shared/tasks.py rename to main/tasks.py diff --git a/shared/forms.py b/shared/forms.py index 934dd0bf2da12a0adbec5ae823eaeb832c1a6580..909728431a623b39325640543a4a6ee1f8aaf03c 100644 --- a/shared/forms.py +++ b/shared/forms.py @@ -1,8 +1,7 @@ from django import forms from wagtail.admin.forms import WagtailAdminPageForm from wagtail.models.collections import Collection - -from .tasks import import_jekyll_articles +import os class SubscribeForm(forms.Form): @@ -65,21 +64,6 @@ class JekyllImportForm(WagtailAdminPageForm): return cleaned_data - def handle_import(self): - # TODO: Portable function - - print("handling import") - - print( - import_jekyll_articles.delay( - article_parent_page_id=self.instance.id, - collection_id=self.cleaned_data["collection"].id, - url=self.cleaned_data["jekyll_repo_url"], - dry_run=self.cleaned_data["dry_run"], - use_git=True, - ) - ) - def save(self, commit=True): if self.cleaned_data.get("do_import"): self.handle_import() diff --git a/shared/jekyll_import.py b/shared/jekyll_import.py index a58508c33cbe6b5a590c2a3071b1d01dc44f11cc..1d5baffa94a1348153750bcddb43f4a20ba3c1be 100644 --- a/shared/jekyll_import.py +++ b/shared/jekyll_import.py @@ -13,6 +13,7 @@ from io import StringIO from typing import List from urllib.error import HTTPError from uuid import uuid4 +import os import bleach import markdown.serializers @@ -665,30 +666,33 @@ class JekyllArticleImporter: Začne vyčištěním logu. """ - self.article_parent_page.last_import_log = "" - self.article_parent_page.save() - - msg = "{} Import započat".format(datetime.now()) - logger.info(msg) - self.page_log += "{}\n\n".format(msg) - - for file_name in os.listdir(os.path.join(self.path, POSTS_DIR)): - # Případ podsložek (typicky po jednotlivých letech) - if os.path.isdir(os.path.join(self.path, POSTS_DIR, file_name)): - posts_sub_folder = os.path.join(self.path, POSTS_DIR, file_name) - for sub_file_name in os.listdir(posts_sub_folder): - file_path = os.path.join(posts_sub_folder, sub_file_name) - self.process_article(sub_file_name, file_path) - # Případ všech článků v jedné složce - else: - file_path = os.path.join(POSTS_DIR, file_name) - self.process_article(file_name, file_path) - - msg = "{} Import ukončen".format(datetime.now()) - logger.info(msg) - self.page_log += "{}\n\n".format(msg) - - self.create_summary_log() + try: + self.article_parent_page.last_import_log = "" + self.article_parent_page.save() + + msg = "{} Import započat".format(datetime.now()) + logger.info(msg) + self.page_log += "{}\n\n".format(msg) + + for file_name in os.listdir(os.path.join(self.path, POSTS_DIR)): + # Případ podsložek (typicky po jednotlivých letech) + if os.path.isdir(os.path.join(self.path, POSTS_DIR, file_name)): + posts_sub_folder = os.path.join(self.path, POSTS_DIR, file_name) + for sub_file_name in os.listdir(posts_sub_folder): + file_path = os.path.join(posts_sub_folder, sub_file_name) + self.process_article(sub_file_name, file_path) + # Případ všech článků v jedné složce + else: + file_path = os.path.join(POSTS_DIR, file_name) + self.process_article(file_name, file_path) + + msg = "{} Import ukončen".format(datetime.now()) + logger.info(msg) + self.page_log += "{}\n\n".format(msg) + + self.create_summary_log() + finally: + os.remove(f"/tmp/.{self.article_parent_page_id}.import-lock") def process_article(self, file_name: str, file_path: str): match = re.match(r"(\d*)-(\d*)-(\d*)-(.*)\.(.*)", file_name) diff --git a/shared/models/main.py b/shared/models/main.py index c9871aec2d8b5522b366a40b8b341e2cd71aa00f..7f4848c62dcc0df32291d05f88e751bbb3551783 100644 --- a/shared/models/main.py +++ b/shared/models/main.py @@ -41,7 +41,7 @@ from shared.blocks import ( TwoTextColumnBlock, ) from shared.const import MONTH_NAMES -from shared.forms import JekyllImportForm, SubscribeForm +from shared.forms import SubscribeForm from shared.utils import make_promote_panels, subscribe_to_newsletter from tuning import admin_help @@ -438,8 +438,6 @@ class MainArticlesPageMixin( ### OTHERS - base_form_class = JekyllImportForm - class Meta: verbose_name = "Rozcestník článků" abstract = True