diff --git a/Makefile b/Makefile index 6f7b7e6cec..b7575fe74e 100644 --- a/Makefile +++ b/Makefile @@ -38,7 +38,7 @@ migrate: # 4) Remove the management command from this `deploy-migrate` recipe # 5) Repeat! deploy-migrate: - echo "Nothing to do here" + python contentcuration/manage.py export_channels_to_kolibri_public contentnodegc: python contentcuration/manage.py garbage_collect diff --git a/contentcuration/kolibri_public/management/commands/export_channels_to_kolibri_public.py b/contentcuration/kolibri_public/management/commands/export_channels_to_kolibri_public.py index 2f20a0b78c..f20206abf0 100644 --- a/contentcuration/kolibri_public/management/commands/export_channels_to_kolibri_public.py +++ b/contentcuration/kolibri_public/management/commands/export_channels_to_kolibri_public.py @@ -2,11 +2,16 @@ import os import shutil import tempfile +from datetime import datetime +from datetime import timedelta from django.conf import settings from django.core.files.storage import default_storage as storage from django.core.management import call_command from django.core.management.base import BaseCommand +from django.db.models import F +from django.db.models import Q +from django.utils import timezone from kolibri_content.apps import KolibriContentConfig from kolibri_content.models import ChannelMetadata as ExportedChannelMetadata from kolibri_content.router import get_active_content_database @@ -15,12 +20,37 @@ from kolibri_public.utils.mapper import ChannelMapper from contentcuration.models import Channel +from contentcuration.models import User +from contentcuration.utils.publish import create_content_database logger = logging.getLogger(__file__) class Command(BaseCommand): + def _republish_problem_channels(self): + twenty_19 = datetime(year=2019, month=1, day=1) + five_minutes = timedelta(minutes=5) + try: + chef_user = User.objects.get(email="chef@learningequality.org") + except User.DoesNotExist: + logger.error("Could not find chef user to republish channels") + return + channel_qs = Channel.objects.filter( + public=True, + deleted=False, + main_tree__published=True + ).filter( + Q(last_published__isnull=True) | + Q(last_published__lt=twenty_19, main_tree__modified__lte=F("last_published") + five_minutes) + ) + + for channel in channel_qs: + kolibri_temp_db = create_content_database(channel, True, chef_user.id, False) + os.remove(kolibri_temp_db) + channel.last_published = timezone.now() + channel.save() + def _export_channel(self, channel_id): logger.info("Putting channel {} into kolibri_public".format(channel_id)) db_location = os.path.join(settings.DB_ROOT, "{id}.sqlite3".format(id=channel_id)) @@ -37,6 +67,7 @@ def _export_channel(self, channel_id): mapper.run() def handle(self, *args, **options): + self._republish_problem_channels() public_channel_ids = set(Channel.objects.filter(public=True, deleted=False, main_tree__published=True).values_list("id", flat=True)) kolibri_public_channel_ids = set(ChannelMetadata.objects.all().values_list("id", flat=True)) ids_to_export = public_channel_ids.difference(kolibri_public_channel_ids) @@ -47,4 +78,6 @@ def handle(self, *args, **options): count += 1 except FileNotFoundError: logger.warning("Tried to export channel {} to kolibri_public but its published channel database could not be found".format(channel_id)) + except Exception as e: + logger.exception("Failed to export channel {} to kolibri_public because of error: {}".format(channel_id, e)) logger.info("Successfully put {} channels into kolibri_public".format(count))