diff --git a/common/apps.py b/common/apps.py index 3ce38941..5756b824 100644 --- a/common/apps.py +++ b/common/apps.py @@ -1,5 +1,14 @@ from django.apps import AppConfig +from django.db.models.signals import post_migrate class CommonConfig(AppConfig): name = "common" + + def ready(self): + post_migrate.connect(self.setup, sender=self) + + def setup(self, **kwargs): + from .setup import Setup + + Setup().run() diff --git a/common/management/commands/setup.py b/common/management/commands/setup.py index 3659c1ef..6f3a23fc 100644 --- a/common/management/commands/setup.py +++ b/common/management/commands/setup.py @@ -13,11 +13,32 @@ from users.models import User class Command(BaseCommand): help = "Post-Migration Setup" + def create_site(self, domain, service_domain): + TakaheDomain.objects.create( + domain=domain, + local=True, + service_domain=service_domain, + notes="NeoDB", + nodeinfo={}, + ) + TakaheConfig.objects.update_or_create( + key="public_timeline", + user=None, + identity=None, + domain=None, + defaults={"json": False}, + ) + def sync_site_config(self): domain = settings.SITE_INFO["site_domain"] + if not domain: + raise ValueError("Panic: site_domain is not set!") icon = settings.SITE_INFO["site_logo"] name = settings.SITE_INFO["site_name"] service_domain = settings.SITE_INFO.get("site_service_domain") + if not TakaheDomain.objects.filter(domain=domain).exists(): + logger.warning(f"Domain {domain} not found, creating...") + self.create_site(domain, service_domain) TakaheConfig.objects.update_or_create( key="site_name", user=None, @@ -55,7 +76,7 @@ class Command(BaseCommand): else: user.is_superuser = True user.save(update_fields=["is_superuser"]) - TakaheUser.objects.filter(email="@" + user.username).update(admin=True) + TakaheUser.objects.filter(email=f"@{user.username}").update(admin=True) logger.info(f"Updated user {user.username} as admin") def handle(self, *args, **options): diff --git a/common/setup.py b/common/setup.py new file mode 100644 index 00000000..24abc6ce --- /dev/null +++ b/common/setup.py @@ -0,0 +1,108 @@ +from django.conf import settings +from loguru import logger + +from catalog.search.typesense import Indexer +from takahe.models import Config as TakaheConfig +from takahe.models import Domain as TakaheDomain +from takahe.models import Identity as TakaheIdentity +from takahe.models import User as TakaheUser +from users.models import User + + +class Setup: + """ + Post-Migration Setup + """ + + def create_site(self, domain, service_domain): + TakaheDomain.objects.create( + domain=domain, + local=True, + service_domain=service_domain, + notes="NeoDB", + nodeinfo={}, + ) + TakaheConfig.objects.update_or_create( + key="public_timeline", + user=None, + identity=None, + domain=None, + defaults={"json": False}, + ) + + def sync_site_config(self): + domain = settings.SITE_INFO["site_domain"] + if not domain: + raise ValueError("Panic: site_domain is not set!") + icon = settings.SITE_INFO["site_logo"] + name = settings.SITE_INFO["site_name"] + service_domain = settings.SITE_INFO.get("site_service_domain") + + if not TakaheDomain.objects.filter(domain=domain).exists(): + logger.info(f"Domain {domain} not found, creating...") + self.create_site(domain, service_domain) + if ( + TakaheIdentity.objects.filter(local=True) + .exclude(domain_id__isnull=True) + .exists() + ): + logger.warning( + f"Local identities are found for other domains, there might be a configuration issue." + ) + + TakaheConfig.objects.update_or_create( + key="site_name", + user=None, + identity=None, + domain=None, + defaults={"json": name}, + ) + TakaheConfig.objects.update_or_create( + key="site_name", + user=None, + identity=None, + domain_id=domain, + defaults={"json": name}, + ) + TakaheConfig.objects.update_or_create( + key="site_icon", + user=None, + identity=None, + domain_id=None, + defaults={"json": icon}, + ) + TakaheConfig.objects.update_or_create( + key="site_icon", + user=None, + identity=None, + domain_id=domain, + defaults={"json": icon}, + ) + + def sync_admin_user(self): + users = User.objects.filter(username__in=settings.SETUP_ADMIN_USERNAMES) + for user in users: + if user.is_superuser: + logger.debug(f"User {user.username} is already admin") + else: + user.is_superuser = True + user.save(update_fields=["is_superuser"]) + TakaheUser.objects.filter(email=f"@{user.username}").update(admin=True) + logger.info(f"Updated user {user.username} as admin") + + def run(self): + logger.info("Running post-migration setup...") + # Update site name if changed + self.sync_site_config() + + # Create/update admin user if configured in env + self.sync_admin_user() + + # Create basic emoji if not exists + + # Create search index if not exists + Indexer.init() + + # Register cron jobs if not yet + + logger.info("Finished post-migration setup.") diff --git a/misc/bin/neodb-init b/misc/bin/neodb-init index 03b5b150..1d63c7c8 100755 --- a/misc/bin/neodb-init +++ b/misc/bin/neodb-init @@ -9,6 +9,5 @@ echo NeoDB initializing... takahe-manage migrate || exit $? neodb-manage migrate || exit $? -neodb-manage setup || exit $? echo NeoDB initialization complete. diff --git a/users/migrations/0013_init_identity.py b/users/migrations/0013_init_identity.py index 41fd8c43..6488f41e 100644 --- a/users/migrations/0013_init_identity.py +++ b/users/migrations/0013_init_identity.py @@ -16,6 +16,12 @@ service_domain = settings.SITE_INFO.get("site_service_domain") def init_domain(apps, schema_editor): + User = apps.get_model("users", "User") + if not User.objects.exists(): + logger.warning( + "No users found, skip domain migration (if you are running initial migration for new site, pls ignore this)" + ) + return d = TakaheDomain.objects.filter(domain=domain).first() if not d: logger.info(f"Creating takahe domain {domain}") @@ -54,6 +60,11 @@ def init_domain(apps, schema_editor): def init_identity(apps, schema_editor): User = apps.get_model("users", "User") + if not User.objects.exists(): + logger.warning( + "No users found, skip identity migration (if you are running initial migration for new site, pls ignore this)" + ) + return APIdentity = apps.get_model("users", "APIdentity") tdomain = TakaheDomain.objects.filter(domain=domain).first() if User.objects.filter(username__isnull=True).exists():