diff --git a/district/forms.py b/district/forms.py index 1203f40a12fb7dcf56035ec31a1655980578405b..d8188b69b16929a1d01cd11a0ff6dd588b45f78e 100644 --- a/district/forms.py +++ b/district/forms.py @@ -7,23 +7,33 @@ from .jekyll_import import perform_import class JekyllImportForm(WagtailAdminPageForm): - article_root_page_id = ( - forms.IntegerField() - ) # TODO resolve circular import and make ModelChoiceField + # TODO resolve circular import and make ModelChoiceField + article_root_page_id = forms.IntegerField() collection = forms.ModelChoiceField(queryset=Collection.objects.all()) dry_run = forms.BooleanField(initial=True) - jekyll_repo_url = forms.URLField() - site = forms.ModelChoiceField(queryset=Site.objects.all()) + jekyll_repo_folder = forms.CharField(max_length=512) - # def clean(self): - # cleaned_data = super().clean() - # return super().clean() + def clean(self): + cleaned_data = super().clean() + + error_list = perform_import( + article_root_page_id=self.cleaned_data["article_root_page_id"], + collection=self.cleaned_data["collection"], + path=self.cleaned_data["jekyll_repo_folder"], + dry_run=self.cleaned_data["dry_run"], + ) + + for error in error_list: + self.add_error("jekyll_repo_folder", error) + + return cleaned_data def save(self, commit=True): perform_import( article_root_page_id=self.cleaned_data["article_root_page_id"], - collection=self.cleaned_data["article_root_page_id"], - path=self.cleaned_data["jekyll_repo_url"], + collection=self.cleaned_data["collection"], + path=self.cleaned_data["jekyll_repo_folder"], + dry_run=self.cleaned_data["dry_run"], ) return super().save(commit=commit) diff --git a/district/jekyll_import.py b/district/jekyll_import.py index 9fe5b71979b8821ec48a0b59299f7dd7d9f4e350..50170891d6450b37fd49e95ec235ce815cc5f3fc 100644 --- a/district/jekyll_import.py +++ b/district/jekyll_import.py @@ -11,6 +11,7 @@ from django.utils.dateparse import parse_date from markdown import Markdown from markdown.extensions import Extension from markdown.inlinepatterns import InlineProcessor +from wagtail.contrib.redirects.models import Redirect from wagtail.images.models import Image # Wagtail to portrebuje https://docs.wagtail.io/en/stable/extending/rich_text_internals.html#data-format @@ -66,16 +67,16 @@ def get_perex(text): POSTS_DIR = "_posts" -TITLE_SUFFIX = " - Piráti České Budějovice" +# TITLE_SUFFIX = " - Piráti České Budějovice" -def get_site_config(path): +def get_site_config(path) -> dict: with open(os.path.join(path, "_config.yml")) as f: config = yaml.safe_load(f.read()) return config -def import_post(path, file_path, parrent, title_suffix): +def import_post(path, file_path, parent, title_suffix, dry_run): from district.models import DistrictArticlePage with open(os.path.join(path, file_path), "rt") as f: @@ -87,8 +88,13 @@ def import_post(path, file_path, parrent, title_suffix): if DistrictArticlePage.objects.filter(title=meta["title"]).exists(): for article in DistrictArticlePage.objects.filter(title=meta["title"]): if article.date == parse_date(meta["date"].split()[0]): - stdout.write("Article already imported: %s" % article) - return article + warning = "Article already imported: %s" % article + stdout.write(warning) + + if dry_run: + return article, warning + + return article, "" article = DistrictArticlePage() @@ -107,13 +113,19 @@ def import_post(path, file_path, parrent, title_suffix): collection = get_collection() article.image = get_or_create_image(path, meta["image"], collection=collection) - parrent.add_child(instance=article) + if dry_run: + return article, "" + else: + try: + parent.add_child(instance=article) + stdout.write("Creating article: %s" % article) + rev = article.save_revision() + if meta["published"]: + rev.publish() + except Exception as e: + return article, "Nelze uložit článek {}: {}".format(article.title, str(e)) - stdout.write("Creating article: %s" % article) - rev = article.save_revision() - if meta["published"]: - rev.publish() - return article + return article, "" def get_collection(): @@ -131,20 +143,24 @@ def get_or_create_image(path, file_path, collection): return image -def perform_import(article_root_page_id, collection, path): +def get_title_from_site_config(site_config: dict) -> str: + if "title" in site_config: + return " - " + site_config.get("title", "") + return "" + + +def perform_import(article_root_page_id, collection, path, dry_run): from district.models import DistrictArticlesPage + error_list = [] + articles = DistrictArticlesPage.objects.get(pk=article_root_page_id) params["kolekce"] = collection site = articles.get_site() path = params["path"] = path site_config = get_site_config(path) - - if "title" in site_config: - title_suffix = " - " + site_config.get("title", "") - else: - title_suffix = "" + title_suffix = get_title_from_site_config(site_config) articlepath = site_config["articlepath"] @@ -159,16 +175,32 @@ def perform_import(article_root_page_id, collection, path): ext = match.group(5) if ext == "md": - article = import_post(path, fname, articles, title_suffix) - from wagtail.contrib.redirects.models import Redirect + article, error = import_post( + path, fname, articles, title_suffix, dry_run + ) + + if error: + error_list.append(error) + continue - r, created = Redirect.objects.get_or_create( + if dry_run: + continue + + Redirect.objects.get_or_create( site=site, old_path="/%s/%s/%s/%s/%s/" % (articlepath, y, m.zfill(2), d.zfill(2), slug), defaults={"is_permanent": True, "redirect_page": article}, ) else: - stdout.write("ERROR: Not Implemented: %s" % ext) + error = "ERROR: This extension is not implemented: %s" % ext + error_list.append(error) + stdout.write(error) else: - stdout.write("WARNING: Skipping: %s" % fn) + warning = "WARNING: Skipping: %s" % fn + stdout.write(warning) + + if dry_run: + error_list.append(warning) + + return error_list diff --git a/district/management/commands/district_import_jekyll.py b/district/management/commands/district_import_jekyll.py index abc99e7c2bf3b19f668a0cab4815f1d19fec68f0..fc3525e22b859a126d2b403d66b736596cc6d8b2 100644 --- a/district/management/commands/district_import_jekyll.py +++ b/district/management/commands/district_import_jekyll.py @@ -26,7 +26,13 @@ class Command(BaseCommand): "--kolekce-id", required=True, type=int, - help="Id id koekce (Collection) pro import obrázků.", + help="Id kolekce (Collection) pro import obrázků.", + ) + parser.add_argument( + "--dry-run", + default=False, + type=bool, + help="Zda je o testovací běh.", ) def handle(self, *args, **options): @@ -34,4 +40,6 @@ class Command(BaseCommand): article_root_page_id=options["clanky_id"], collection=Collection.objects.get(pk=options["kolekce_id"]), path=options["path"], + site=None, + dry_run=options["dry-run"], ) diff --git a/district/models.py b/district/models.py index b701f09c3eadee825cfdb24c57d4d8c6209f43f9..5460eedec5def317bc5f5dfab18bb6f534da263e 100644 --- a/district/models.py +++ b/district/models.py @@ -231,6 +231,18 @@ class DistrictHomePage(MenuMixin, MetadataPageMixin, CalendarMixin, Page): CommentPanel(), ] + import_panels = [ + MultiFieldPanel( + [ + FieldPanel("article_root_page_id"), + FieldPanel("collection"), + FieldPanel("dry_run"), + FieldPanel("jekyll_repo_folder"), + ], + "import z Jekyll repozitáře", + ), + ] + ### EDIT HANDLERS edit_handler = TabbedInterface( [