From 468ed4b3f8d17bd06a6f564723ef8f52588ab495 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Valenta?= <git@imaniti.org> Date: Tue, 4 Apr 2023 23:35:32 +0200 Subject: [PATCH] instagram sync base --- README.md | 1 + instagram_utils/__init__.py | 0 instagram_utils/apps.py | 5 ++ instagram_utils/management/__init__.py | 0 .../management/commands/__init__.py | 0 .../management/commands/update_instagram.py | 15 ++++++ instagram_utils/models.py | 9 ++++ instagram_utils/services.py | 50 +++++++++++++++++++ ...inhomepage_instagram_usernames_and_more.py | 35 +++++++++++++ main/models.py | 20 +++++++- majak/settings/base.py | 4 ++ requirements/base.txt | 6 +-- {twitter_utils => shared}/storages.py | 4 +- ...uthor_img_url_tweet_author_img_and_more.py | 4 +- .../migrations/0003_alter_tweet_author_img.py | 4 +- twitter_utils/models.py | 2 +- 16 files changed, 147 insertions(+), 12 deletions(-) create mode 100644 instagram_utils/__init__.py create mode 100644 instagram_utils/apps.py create mode 100644 instagram_utils/management/__init__.py create mode 100644 instagram_utils/management/commands/__init__.py create mode 100644 instagram_utils/management/commands/update_instagram.py create mode 100644 instagram_utils/models.py create mode 100644 instagram_utils/services.py create mode 100644 main/migrations/0046_mainhomepage_instagram_usernames_and_more.py rename {twitter_utils => shared}/storages.py (96%) diff --git a/README.md b/README.md index 0b4ba971..ff48c297 100644 --- a/README.md +++ b/README.md @@ -176,6 +176,7 @@ Přes CRON je třeba na pozadí spouštět Django `manage.py` commandy: * `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) +* `update_instagram` - aktualizuje Instagramové posty na Homepage pirati.cz - vyžaduje mít v .env `INSTAGRAM_APP_ID` a `INSTAGRAM_APP_SECRET`. ### Fulltextové vyhledávání v češtině diff --git a/instagram_utils/__init__.py b/instagram_utils/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/instagram_utils/apps.py b/instagram_utils/apps.py new file mode 100644 index 00000000..d054dc44 --- /dev/null +++ b/instagram_utils/apps.py @@ -0,0 +1,5 @@ +from django.apps import AppConfig + + +class InstagramUtilsConfig(AppConfig): + name = "instagram_utils" diff --git a/instagram_utils/management/__init__.py b/instagram_utils/management/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/instagram_utils/management/commands/__init__.py b/instagram_utils/management/commands/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/instagram_utils/management/commands/update_instagram.py b/instagram_utils/management/commands/update_instagram.py new file mode 100644 index 00000000..11c2c130 --- /dev/null +++ b/instagram_utils/management/commands/update_instagram.py @@ -0,0 +1,15 @@ +from django.conf import settings +from django.core.management.base import BaseCommand + +from ...services import InstagramDownloadService + + +class Command(BaseCommand): + def handle(self, *args, **options): + service = InstagramDownloadService( + app_id=settings.INSTAGRAM_APP_ID, + app_secret=settings.INSTAGRAM_APP_SECRET, + ) + service.perform_update() + + self.stdout.write("\nInstagram post update finished.") diff --git a/instagram_utils/models.py b/instagram_utils/models.py new file mode 100644 index 00000000..47c408ae --- /dev/null +++ b/instagram_utils/models.py @@ -0,0 +1,9 @@ +from django.db import models + + +class InstagramPost(models.Model): + """ + Model representing an Instgram post obtained from its API through the + update_instagram management command. + """ + diff --git a/instagram_utils/services.py b/instagram_utils/services.py new file mode 100644 index 00000000..6c4349e4 --- /dev/null +++ b/instagram_utils/services.py @@ -0,0 +1,50 @@ +import logging +import requests + +from main.models import MainHomePage, MainPersonPage + +from .models import InstagramPost + + +logger = logging.getLogger() + + +class InstagramDownloadService: + """ + TODO + """ + + def __init__(self, app_id: int, app_secret: str): + self.app_id = app_id + self.app_secret = app_secret + + # https://www.instagram.com/web/search/topsearch/?context=user&count=1&query=that_snowden + # Useful Instagram username search API + + def get_username_list(self) -> list[str]: + instagram_usernames_block = MainHomePage.objects.first().instagram_usernames + + person_username_list = ( + MainPersonPage.objects.filter(instagram_username__isnull=False) + .values_list("instagram_username", flat=True) + .distinct() + ) + homepage_username_list = [ + username_data["value"] for username_data in instagram_usernames_block.raw_data + ] + + # kvůli duplicitám udělám(e) list/set/list konverzi + return list({*person_username_list, *homepage_username_list}) + + def convert_usernames_to_ids(self, username_list) -> list[str]: + user_ids = [] + + for username in username_list: + print(username) + + return user_ids + + def perform_update(self) -> None: + username_list = self.get_username_list() + + user_ids = self.convert_usernames_to_ids(username_list) diff --git a/main/migrations/0046_mainhomepage_instagram_usernames_and_more.py b/main/migrations/0046_mainhomepage_instagram_usernames_and_more.py new file mode 100644 index 00000000..8345a6a7 --- /dev/null +++ b/main/migrations/0046_mainhomepage_instagram_usernames_and_more.py @@ -0,0 +1,35 @@ +# Generated by Django 4.1.7 on 2023-04-04 21:34 + +from django.db import migrations, models +import wagtail.blocks +import wagtail.fields + + +class Migration(migrations.Migration): + + dependencies = [ + ('main', '0045_alter_mainprogrampage_program'), + ] + + operations = [ + migrations.AddField( + model_name='mainhomepage', + name='instagram_usernames', + field=wagtail.fields.StreamField([('username', wagtail.blocks.CharBlock(label='Instagram uživatelské jméno'))], blank=True, use_json_field=True, verbose_name='Uživatelská jména pro synchronizované Instagram účty'), + ), + migrations.AddField( + model_name='mainpersonpage', + name='instagram_username', + field=models.CharField(blank=True, help_text='Uživatelské jméno zadejte bez @ na začátku', max_length=32, null=True, verbose_name='Uživatelské jméno na Instagramu pro získání příspěvků'), + ), + migrations.AlterField( + model_name='mainhomepage', + name='twitter_usernames', + field=wagtail.fields.StreamField([('username', wagtail.blocks.CharBlock(label='Twitter uživatelské jméno'))], blank=True, use_json_field=True, verbose_name='Uživatelská jména pro synchronizované Twitter účty'), + ), + migrations.AlterField( + model_name='mainpersonpage', + name='twitter_username', + field=models.CharField(blank=True, help_text='Uživatelské jméno zadejte bez @ na začátku', max_length=32, null=True, verbose_name='Uživatelské jméno na Twitteru pro získání příspěvků'), + ), + ] diff --git a/main/models.py b/main/models.py index c5ab4ffc..7a330821 100644 --- a/main/models.py +++ b/main/models.py @@ -136,7 +136,15 @@ class MainHomePage( twitter_usernames = StreamField( [("username", CharBlock(label="Twitter uživatelské jméno"))], - verbose_name="Uživatelská jména pro synchronizované twitter účty", + verbose_name="Uživatelská jména pro synchronizované Twitter účty", + blank=True, + max_num=64, + use_json_field=True, + ) + + instagram_usernames = StreamField( + [("username", CharBlock(label="Instagram uživatelské jméno"))], + verbose_name="Uživatelská jména pro synchronizované Instagram účty", blank=True, max_num=64, use_json_field=True, @@ -159,6 +167,7 @@ class MainHomePage( FieldPanel("social_links"), FieldPanel("matomo_id"), FieldPanel("twitter_usernames"), + FieldPanel("instagram_usernames"), ] ### EDIT HANDLERS @@ -683,7 +692,14 @@ class MainPersonPage(ExtendedMetadataPageMixin, SubpageMixin, MetadataPageMixin, text = RichTextField() twitter_username = models.CharField( - "Uživatelské jméno twitter pro získání příspěvků", + "Uživatelské jméno na Twitteru pro získání příspěvků", + blank=True, + null=True, + max_length=32, + help_text="Uživatelské jméno zadejte bez @ na začátku", + ) + instagram_username = models.CharField( + "Uživatelské jméno na Instagramu pro získání příspěvků", blank=True, null=True, max_length=32, diff --git a/majak/settings/base.py b/majak/settings/base.py index 80b8a324..0dc9913f 100644 --- a/majak/settings/base.py +++ b/majak/settings/base.py @@ -48,6 +48,7 @@ INSTALLED_APPS = [ "maps_utils", "redmine_utils", "twitter_utils", + "instagram_utils", "users", "pirates", "tuning", @@ -311,3 +312,6 @@ MAPS_UTILS_MAPPROXY_URL = env.str( ) TWITTER_BEARER_TOKEN = env.str("TWITTER_BEARER_TOKEN", default="") + +INSTAGRAM_APP_ID = env.str("INSTAGRAM_APP_ID", default="") +INSTAGRAM_APP_SECRET = env.str("INSTAGRAM_APP_SECRET", default="") diff --git a/requirements/base.txt b/requirements/base.txt index acf77e06..55415830 100644 --- a/requirements/base.txt +++ b/requirements/base.txt @@ -1,6 +1,6 @@ # -# This file is autogenerated by pip-compile with python 3.10 -# To update, run: +# This file is autogenerated by pip-compile with Python 3.10 +# by the following command: # # pip-compile base.in # @@ -8,8 +8,6 @@ amqp==5.1.1 # via kombu anyascii==0.3.1 # via wagtail -appnope==0.1.3 - # via ipython arrow==1.2.3 # via # -r base.in diff --git a/twitter_utils/storages.py b/shared/storages.py similarity index 96% rename from twitter_utils/storages.py rename to shared/storages.py index 04ffc57c..8c73ea2f 100644 --- a/twitter_utils/storages.py +++ b/shared/storages.py @@ -13,7 +13,9 @@ class OverwriteStorage(get_storage_class()): Found at https://djangosnippets.org/snippets/976/ """ + # If the filename already exists, remove it as if it was a true file system if self.exists(name): os.remove(os.path.join(settings.MEDIA_ROOT, name)) - return name + + return name diff --git a/twitter_utils/migrations/0002_remove_tweet_author_img_url_tweet_author_img_and_more.py b/twitter_utils/migrations/0002_remove_tweet_author_img_url_tweet_author_img_and_more.py index bab86107..4fb0167f 100644 --- a/twitter_utils/migrations/0002_remove_tweet_author_img_url_tweet_author_img_and_more.py +++ b/twitter_utils/migrations/0002_remove_tweet_author_img_url_tweet_author_img_and_more.py @@ -2,7 +2,7 @@ from django.db import migrations, models -import twitter_utils.storages +import shared.storages class Migration(migrations.Migration): @@ -20,7 +20,7 @@ class Migration(migrations.Migration): name="author_img", field=models.ImageField( null=True, - storage=twitter_utils.storages.OverwriteStorage, + storage=shared.storages.OverwriteStorage, upload_to="twitter_accounts", ), ), diff --git a/twitter_utils/migrations/0003_alter_tweet_author_img.py b/twitter_utils/migrations/0003_alter_tweet_author_img.py index bd08e389..2a71f9a0 100644 --- a/twitter_utils/migrations/0003_alter_tweet_author_img.py +++ b/twitter_utils/migrations/0003_alter_tweet_author_img.py @@ -2,7 +2,7 @@ from django.db import migrations, models -import twitter_utils.storages +import shared.storages class Migration(migrations.Migration): @@ -15,7 +15,7 @@ class Migration(migrations.Migration): model_name="tweet", name="author_img", field=models.ImageField( - storage=twitter_utils.storages.OverwriteStorage, + storage=shared.storages.OverwriteStorage, upload_to="twitter_accounts", ), ), diff --git a/twitter_utils/models.py b/twitter_utils/models.py index b15e9eb8..d32203e3 100644 --- a/twitter_utils/models.py +++ b/twitter_utils/models.py @@ -1,6 +1,6 @@ from django.db import models -from twitter_utils.storages import OverwriteStorage +from shared.storages import OverwriteStorage class TweetQueryset(models.QuerySet): -- GitLab