From 7b0a6b41285ae38926096fc701abb4ae07b5ffd5 Mon Sep 17 00:00:00 2001 From: OndraRehounek <ondra.rehounek@seznam.cz> Date: Mon, 29 Aug 2022 12:45:18 +0200 Subject: [PATCH] main: import --- README.md | 1 + article_import_utils/services.py | 53 -------------- article_import_utils/utils.py | 14 ---- .../management/__init__.py | 0 .../management/commands/__init__.py | 0 .../commands/update_main_timeline_articles.py | 6 +- main/services.py | 66 +++++++++++++++++ main/static/main/css/pattern-scaffolding.css | 70 ------------------- main/static/main/css/styles.css | 2 +- .../source/css/molecules/carousels.pcss | 3 +- main/utils.py | 0 shared/utils.py | 11 +++ 12 files changed, 84 insertions(+), 142 deletions(-) delete mode 100644 article_import_utils/services.py delete mode 100644 article_import_utils/utils.py rename {article_import_utils => main}/management/__init__.py (100%) rename {article_import_utils => main}/management/commands/__init__.py (100%) rename article_import_utils/management/commands/update_articles.py => main/management/commands/update_main_timeline_articles.py (67%) create mode 100644 main/services.py delete mode 100644 main/static/main/css/pattern-scaffolding.css create mode 100644 main/utils.py diff --git a/README.md b/README.md index bc2c3c77..76ed94b3 100644 --- a/README.md +++ b/README.md @@ -173,6 +173,7 @@ Přes CRON je třeba na pozadí spouštět Django `manage.py` commandy: * `clearsessions` - maže expirované sessions (denně až týdně) * `publish_scheduled_pages` - publikuje naplánované stránky (každou hodinu) * `update_callendars` - stáhne a aktualizuje kalendáře (několikrát denně) +* `update_main_timeline_articles` - aktualizuje články na `pirati.cz` z `https://piratipracuji.cz/api/` * `update_redmine_issues` - aktualizuje programované body MS a KS stránek napojených na Redmine (několikrát denně) * `update_tweets` - aktualizuje tweety podle nastavení na Homepage pirati.cz - vyžaduje mít v .env TWITTER_BEARER_TOKEN, parametr --days určuje stáří tweetů (default 1) diff --git a/article_import_utils/services.py b/article_import_utils/services.py deleted file mode 100644 index b1f6e9c4..00000000 --- a/article_import_utils/services.py +++ /dev/null @@ -1,53 +0,0 @@ -import json -import logging -from typing import TYPE_CHECKING - -import requests - -from article_import_utils.utils import create_image_from_url -from main.models import MainArticlePage, MainArticlesPage, ARTICLE_TYPES - -if TYPE_CHECKING: - pass - -logger = logging.getLogger() - - -class ArticleDownloadService: - api_url = 'https://piratipracuji.cz/api/' - - @staticmethod - def get_existing_articles_slugs() -> list[str]: - return MainArticlePage.objects.filter(article_type=ARTICLE_TYPES.WORK_TIMELINE).values_list('slug', flat=True) - - def get_articles_response(self): - response = requests.get(self.api_url) - data = json.loads(response.text) - - return data - - def perform_update(self): - existing_articles_slug_list = self.get_existing_articles_slugs() - - for article in self.get_articles_response(): - if article['slug'] not in existing_articles_slug_list: - if 'thumbnail' in article: - img_filename = 'article-' + str(article['id']) + '.jpg' - img_obj = create_image_from_url(url=article['thumbnail'], filename=img_filename) - else: - img_obj = None - - article_to_save = MainArticlePage(article_type=ARTICLE_TYPES.WORK_TIMELINE, - title=article['title'], - slug=article['slug'], - perex=article['description'].replace(" ", ""), - author='ČESKÁ PIRÁTSKÁ STRANA', - date=article['start_date'], - image=img_obj, - content=json.dumps([ - {'type': 'text', - 'value': article['content'].replace("</p>", "</p><br>")} - ]) - ) - parent = MainArticlesPage.objects.all().first() - parent.add_child(instance=article_to_save) diff --git a/article_import_utils/utils.py b/article_import_utils/utils.py deleted file mode 100644 index 1320c99e..00000000 --- a/article_import_utils/utils.py +++ /dev/null @@ -1,14 +0,0 @@ -import urllib.request -from wagtail.images.models import Image -from django.core.files import File - - -def create_image_from_url(url, filename): - img_data = urllib.request.urlretrieve(url) - img_obj = Image(title=filename) - img_obj.file.save( - filename, - File(open(img_data[0], 'rb')) - ) - img_obj.save() - return img_obj diff --git a/article_import_utils/management/__init__.py b/main/management/__init__.py similarity index 100% rename from article_import_utils/management/__init__.py rename to main/management/__init__.py diff --git a/article_import_utils/management/commands/__init__.py b/main/management/commands/__init__.py similarity index 100% rename from article_import_utils/management/commands/__init__.py rename to main/management/commands/__init__.py diff --git a/article_import_utils/management/commands/update_articles.py b/main/management/commands/update_main_timeline_articles.py similarity index 67% rename from article_import_utils/management/commands/update_articles.py rename to main/management/commands/update_main_timeline_articles.py index f4916750..7a688ecb 100644 --- a/article_import_utils/management/commands/update_articles.py +++ b/main/management/commands/update_main_timeline_articles.py @@ -1,11 +1,11 @@ from django.core.management.base import BaseCommand -from article_import_utils.services import ArticleDownloadService +from main.services import TimelineArticleDownloadService -class Command(BaseCommand): +class Command(BaseCommand): def handle(self, *args, **options): - ads = ArticleDownloadService() + ads = TimelineArticleDownloadService() ads.perform_update() self.stdout.write("\nUpdate of articles finished!") diff --git a/main/services.py b/main/services.py new file mode 100644 index 00000000..b1ea15e0 --- /dev/null +++ b/main/services.py @@ -0,0 +1,66 @@ +import json +import logging +from typing import TYPE_CHECKING + +import requests + +from main.models import ARTICLE_TYPES, MainArticlePage, MainArticlesPage +from shared.utils import create_image_from_url + +if TYPE_CHECKING: + pass + +logger = logging.getLogger() + + +class TimelineArticleDownloadService: + api_url = "https://piratipracuji.cz/api/" + + @staticmethod + def get_existing_articles_slugs() -> list[str]: + return MainArticlePage.objects.filter( + article_type=ARTICLE_TYPES.WORK_TIMELINE + ).values_list("slug", flat=True) + + def get_articles_response(self): + response = requests.get(self.api_url) + data = json.loads(response.text) + + return data + + def perform_update(self): + existing_articles_slug_list = self.get_existing_articles_slugs() + parent = MainArticlesPage.objects.all().first() + + if not parent: + RuntimeError("No MainArticlesPage to import to") + + for article in self.get_articles_response(): + if article["slug"] not in existing_articles_slug_list: + if "thumbnail" in article: + img_filename = "article-" + str(article["id"]) + ".jpg" + img_obj = create_image_from_url( + url=article["thumbnail"], filename=img_filename + ) + else: + img_obj = None + + article_to_save = MainArticlePage( + article_type=ARTICLE_TYPES.WORK_TIMELINE, + title=article["title"], + slug=article["slug"], + perex=article["description"].replace(" ", ""), + author="ČESKÁ PIRÁTSKÁ STRANA", + date=article["start_date"], + image=img_obj, + content=json.dumps( + [ + { + "type": "text", + "value": article["content"].replace("</p>", "</p><br>"), + } + ] + ), + ) + + parent.add_child(instance=article_to_save) diff --git a/main/static/main/css/pattern-scaffolding.css b/main/static/main/css/pattern-scaffolding.css deleted file mode 100644 index d56b035d..00000000 --- a/main/static/main/css/pattern-scaffolding.css +++ /dev/null @@ -1,70 +0,0 @@ -/** - * This stylesheet is for styles you want to include only when displaying demo - * styles for grids, animations, color swatches, etc. - * These styles will not be your production CSS. - */ -#sg-patterns { - -webkit-box-sizing: border-box !important; - box-sizing: border-box !important; - max-width: 100%; - padding: 0 0.5em; -} - -.demo-animate { - background: #ddd; - padding: 1em; - margin-bottom: 1em; - text-align: center; - border-radius: 8px; - cursor: pointer; -} - -.sg-colors { - display: -webkit-box; - display: -ms-flexbox; - display: flex; - -ms-flex-wrap: wrap; - flex-wrap: wrap; - list-style: none !important; - padding: 0 !important; - margin: 0 !important; -} -.sg-colors li { - -webkit-box-flex: 1; - -ms-flex: auto; - flex: auto; - padding: 0.3em; - margin: 0 0.5em 0.5em 0; - min-width: 5em; - max-width: 14em; - border: 1px solid #ddd; - border-radius: 0; -} - -.sg-swatch { - display: block; - height: 8rem; - margin-bottom: 0.5rem; - border-radius: 0; -} - -.sg-label { - font-size: 1rem; -} - -.sg-pattern-example { - font-family: "Roboto", "Helvetica", "Arial", sans-serif !important; -} - -.sg-pattern-head .sg-pattern-title a { - font-family: "Roboto", "Helvetica", "Arial", sans-serif !important; - font-weight: bold !important; - font-size: 1.2rem !important; - color: #202020 !important; -} - -.sg-pattern-category-title a { - font-family: "Bebas Neue", "Helvetica", "Arial", sans-serif !important; - font-weight: 400 !important; - font-size: 3.5rem !important; -} diff --git a/main/static/main/css/styles.css b/main/static/main/css/styles.css index b544028e..7d96ea02 100644 --- a/main/static/main/css/styles.css +++ b/main/static/main/css/styles.css @@ -2551,7 +2551,7 @@ p{ } .btn-carousel{ - @aplly h-11; + height: 2.75rem; top: 28%; } diff --git a/main/styleguide/source/css/molecules/carousels.pcss b/main/styleguide/source/css/molecules/carousels.pcss index f708ae76..31cde331 100644 --- a/main/styleguide/source/css/molecules/carousels.pcss +++ b/main/styleguide/source/css/molecules/carousels.pcss @@ -169,8 +169,9 @@ } } } + .btn-carousel{ - @aplly h-11; + @apply h-11; top: 28%; } diff --git a/main/utils.py b/main/utils.py new file mode 100644 index 00000000..e69de29b diff --git a/shared/utils.py b/shared/utils.py index 698ed7ed..072d2c5e 100644 --- a/shared/utils.py +++ b/shared/utils.py @@ -1,9 +1,11 @@ import json import logging +import urllib.request import bleach import requests from django.conf import settings +from django.core.files import File from django.utils.translation import gettext_lazy from wagtail.admin.edit_handlers import ( CommentPanel, @@ -13,12 +15,21 @@ from wagtail.admin.edit_handlers import ( ) from wagtail.core.models import Page from wagtail.images.edit_handlers import FieldPanel +from wagtail.images.models import Image from tuning import admin_help logger = logging.getLogger() +def create_image_from_url(url, filename): + img_data = urllib.request.urlretrieve(url) + img_obj = Image(title=filename) + img_obj.file.save(filename, File(open(img_data[0], "rb"))) + img_obj.save() + return img_obj + + def get_subpage_url(page, dest_page_type): try: return page.get_descendants().type(dest_page_type).live().first().get_url() -- GitLab