Пример #1
0
    def test_watchdog(self):

        PublicatorRegistry.unregister('pdf')
        PublicatorRegistry.unregister('printable-pdf')
        PublicatorRegistry.unregister('epub')
        PublicatorRegistry.unregister('html')

        with open('path', 'w') as f:
            f.write('my_content;/path/to/markdown.md')

        @PublicatorRegistry.register('test', '', '')
        class TestPublicator(Publicator):
            def __init__(self, *__):
                pass

        PublicatorRegistry.get('test').publish = Mock()
        event = FileCreatedEvent('path')
        handler = TutorialIsPublished()
        handler.prepare_generation = Mock()
        handler.finish_generation = Mock()
        handler.on_created(event)

        self.assertTrue(PublicatorRegistry.get('test').publish.called)
        handler.finish_generation.assert_called_with('/path/to', 'path')
        handler.prepare_generation.assert_called_with('/path/to')
        os.remove('path')
Пример #2
0
    def test_watchdog(self):

        PublicatorRegistry.unregister('pdf')
        PublicatorRegistry.unregister('printable-pdf')
        PublicatorRegistry.unregister('epub')
        PublicatorRegistry.unregister('html')

        with open('path', 'w') as f:
            f.write('my_content;/path/to/markdown.md')

        @PublicatorRegistry.register('test', '', '')
        class TestPublicator(Publicator):
            def __init__(self, *__):
                pass

        PublicatorRegistry.get('test').publish = Mock()
        event = FileCreatedEvent('path')
        handler = TutorialIsPublished()
        handler.prepare_generation = Mock()
        handler.finish_generation = Mock()
        handler.on_created(event)

        self.assertTrue(PublicatorRegistry.get('test').publish.called)
        handler.finish_generation.assert_called_with('/path/to', 'path')
        handler.prepare_generation.assert_called_with('/path/to')
        os.remove('path')
Пример #3
0
    def handle(self, *args, **options):
        try:
            ids = list(set(options.get('id')[0].replace('id=', '').split(',')))
        except IndexError:
            ids = []

        if len(ids) > 0:
            public_contents = PublishedContent.objects.filter(
                content_pk__in=ids, must_redirect=False).all()
        else:
            public_contents = PublishedContent.objects.filter(
                must_redirect=False).all()

        num_of_contents = len(public_contents)

        if num_of_contents == 0:
            self.stdout.write(
                _("Aucun contenu n'a été sélectionné, aucun PDF ne sera généré"
                  ))
            return

        self.stdout.write(
            _('Génération de epub pour {} contenu {}').format(
                num_of_contents, 's' if num_of_contents > 1 else ''))

        for content in public_contents:
            with contextlib.suppress(NotAPublicVersion,
                                     FailureDuringPublication):
                self.stdout.write(_('- {}').format(
                    content.content_public_slug),
                                  ending='')
                extra_content_dir = content.get_extra_contents_directory()
                building_extra_content_path = Path(
                    str(Path(extra_content_dir).parent) + '__building',
                    'extra_contents', content.content_public_slug)
                if not building_extra_content_path.exists():
                    building_extra_content_path.mkdir(parents=True)
                base_name = os.path.join(str(extra_content_dir),
                                         content.content_public_slug)

                # delete previous one
                if os.path.exists(base_name + '.epub'):
                    os.remove(base_name + '.epub')
                PublicatorRegistry.get('epub').publish(
                    base_name + '.md', str(building_extra_content_path))

            # check:
            if os.path.exists(base_name + '.epub'):
                self.stdout.write(' [OK]')
            else:
                self.stdout.write(' [ERREUR]')

        os.chdir(settings.BASE_DIR)
Пример #4
0
 def post(self, request, *args, **kwargs):
     try:
         publishable_content = self.get_object()
         if not publishable_content.public_version:
             raise Http404("Not public content")
         self.ensure_directories(publishable_content)
         PublicatorRegistry.get("watchdog").publish_from_published_content(
             publishable_content.public_version)
     except ValueError:
         return Response({}, status=status.HTTP_400_BAD_REQUEST, headers={})
     else:
         return Response({}, status=status.HTTP_201_CREATED, headers={})
Пример #5
0
    def handle(self, *__, **options):
        try:
            ids = list(set(options.get("id")[0].replace("id=", "").split(",")))
        except IndexError:
            ids = []

        if len(ids) > 0:
            public_contents = PublishedContent.objects.filter(
                content_pk__in=ids, must_redirect=False).all()
        else:
            public_contents = PublishedContent.objects.filter(
                must_redirect=False).all()

        num_of_contents = len(public_contents)

        if num_of_contents == 0:
            self.stdout.write(
                _("Aucun contenu n'a été sélectionné, aucun markdown ne sera généré"
                  ))
            return

        self.stdout.write(
            _("Génération de epub pour {} contenu {}").format(
                num_of_contents, "s" if num_of_contents > 1 else ""))

        for content in public_contents:
            with contextlib.suppress(NotAPublicVersion,
                                     FailureDuringPublication):
                self.stdout.write(_("- {}").format(
                    content.content_public_slug),
                                  ending="")
                extra_content_dir = content.get_extra_contents_directory()
                building_extra_content_path = Path(
                    str(Path(extra_content_dir).parent) + "__building",
                    "extra_contents", content.content_public_slug)
                if not building_extra_content_path.exists():
                    building_extra_content_path.mkdir(parents=True)
                base_name = str(
                    Path(str(extra_content_dir), content.content_public_slug))

                PublicatorRegistry.get("md").publish(
                    base_name + ".md",
                    str(building_extra_content_path),
                    cur_language=translation.get_language(),
                    versioned=content.content.load_version(public=True),
                )

            # check:
            if Path(base_name + ".md").exists():
                self.stdout.write(" [OK]")
            else:
                self.stdout.write(" [ERREUR]")
Пример #6
0
    def handle(self, *args, **options):
        try:
            ids = list(set(options.get("id")[0].replace("id=", "").split(",")))
        except IndexError:
            ids = []

        if len(ids) > 0:
            public_contents = PublishedContent.objects.filter(
                content_pk__in=ids, must_redirect=False).all()
        else:
            public_contents = PublishedContent.objects.filter(
                must_redirect=False).all()

        num_of_contents = len(public_contents)

        if num_of_contents == 0:
            self.stdout.write(
                _("Aucun contenu n'a été sélectionné, aucun PDF ne sera généré"
                  ))
            return

        self.stdout.write(
            _("Génération de PDF pour {} contenu{}").format(
                num_of_contents, "s" if num_of_contents > 1 else ""))

        for content in public_contents:
            with contextlib.suppress(NotAPublicVersion):
                self.stdout.write(_("- {}").format(
                    content.content_public_slug),
                                  ending="")
                extra_content_dir = content.get_extra_contents_directory()
                building_extra_content_path = Path(
                    str(Path(extra_content_dir).parent) + "__building",
                    "extra_contents", content.content_public_slug)
                if not building_extra_content_path.exists():
                    building_extra_content_path.mkdir(parents=True)
                base_name = os.path.join(extra_content_dir,
                                         content.content_public_slug)

                # delete previous one
                if os.path.exists(base_name + ".pdf"):
                    os.remove(base_name + ".pdf")
                PublicatorRegistry.get("pdf").publish(
                    base_name + ".md", str(building_extra_content_path))

            # check:
            if os.path.exists(base_name + ".pdf"):
                self.stdout.write(" [OK]")
            else:
                self.stdout.write(" [ERREUR]")

        os.chdir(settings.BASE_DIR)
Пример #7
0
    def run(self):
        requested_events = PublicationEvent.objects.select_related(
            "published_object", "published_object__content",
            "published_object__content__image").filter(
                state_of_processing="REQUESTED")

        for publication_event in requested_events.iterator():
            content = publication_event.published_object
            extra_content_dir = content.get_extra_contents_directory()
            building_extra_content_path = Path(
                str(Path(extra_content_dir).parent) + "__building",
                "extra_contents", content.content_public_slug)
            if not building_extra_content_path.exists():
                building_extra_content_path.mkdir(parents=True)
            base_name = str(building_extra_content_path)
            md_file_path = base_name + ".md"

            logger.info("Exporting « %s » as %s", content.title(),
                        publication_event.format_requested)
            publication_event.state_of_processing = "RUNNING"
            publication_event.save()

            publicator = PublicatorRegistry.get(
                publication_event.format_requested)
            try:
                publicator.publish(md_file_path, base_name)
            except FailureDuringPublication:
                logger.error("Failed to export « %s » as %s", content.title(),
                             publication_event.format_requested)
                publication_event.state_of_processing = "FAILURE"
            else:
                logger.info("Succeed to export « %s » as %s", content.title(),
                            publication_event.format_requested)
                publication_event.state_of_processing = "SUCCESS"
            publication_event.save()
Пример #8
0
    def setUp(self):
        self.mas = ProfileFactory().user
        self.overridden_zds_app["member"]["bot_account"] = self.mas.username

        self.licence = LicenceFactory()

        self.user_author = ProfileFactory().user
        self.staff = StaffProfileFactory().user

        self.tuto = PublishableContentFactory(type="TUTORIAL")
        self.tuto.authors.add(self.user_author)
        UserGalleryFactory(gallery=self.tuto.gallery, user=self.user_author, mode="W")
        self.tuto.licence = self.licence
        self.tuto.save()

        self.tuto_draft = self.tuto.load_version()
        self.part1 = ContainerFactory(parent=self.tuto_draft, db_object=self.tuto)
        self.chapter1 = ContainerFactory(parent=self.part1, db_object=self.tuto)
        self.old_registry = {key: value for key, value in PublicatorRegistry.get_all_registered()}

        class TestPdfPublicator(Publicator):
            def publish(self, md_file_path, base_name, **kwargs):
                with Path(base_name + ".pdf").open("w") as f:
                    f.write("bla")
                shutil.copy2(str(Path(base_name + ".pdf")), str(Path(md_file_path.replace("__building", "")).parent))

        PublicatorRegistry.registry["pdf"] = TestPdfPublicator()
Пример #9
0
    def launch_publicators(executor):
        query_set = PublicationEvent.objects.select_related('published_object', 'published_object__content',
                                                            'published_object__content__image') \
                                            .filter(state_of_processing='REQUESTED')

        for publication_event in query_set.iterator():
            logger.info('Export %s -- format=%s',
                        publication_event.published_object.title(),
                        publication_event.format_requested)
            content = publication_event.published_object
            publicator = PublicatorRegistry.get(
                publication_event.format_requested)

            extra_content_dir = content.get_extra_contents_directory()
            building_extra_content_path = Path(
                str(Path(extra_content_dir).parent) + '__building',
                'extra_contents', content.content_public_slug)
            if not building_extra_content_path.exists():
                building_extra_content_path.mkdir(parents=True)
            base_name = str(building_extra_content_path)
            md_file_path = base_name + '.md'

            publication_event.state_of_processing = 'RUNNING'
            publication_event.save()
            future = executor.submit(publicator.publish, md_file_path,
                                     base_name)
            future.add_done_callback(
                Command.get_callback_of(publication_event))
Пример #10
0
    def setUp(self):
        self.mas = ProfileFactory().user
        self.overridden_zds_app['member']['bot_account'] = self.mas.username

        self.licence = LicenceFactory()

        self.user_author = ProfileFactory().user
        self.staff = StaffProfileFactory().user

        self.tuto = PublishableContentFactory(type='TUTORIAL')
        self.tuto.authors.add(self.user_author)
        UserGalleryFactory(gallery=self.tuto.gallery, user=self.user_author, mode='W')
        self.tuto.licence = self.licence
        self.tuto.save()

        self.tuto_draft = self.tuto.load_version()
        self.part1 = ContainerFactory(parent=self.tuto_draft, db_object=self.tuto)
        self.chapter1 = ContainerFactory(parent=self.part1, db_object=self.tuto)
        self.old_registry = {key: value for key, value in PublicatorRegistry.get_all_registered()}

        class TestPdfPublicator(Publicator):
            def publish(self, md_file_path, base_name, **kwargs):
                with Path(base_name + '.pdf').open('w') as f:
                    f.write('bla')
                shutil.copy2(str(Path(base_name + '.pdf')),
                             str(Path(md_file_path.replace('__building', '')).parent))
        PublicatorRegistry.registry['pdf'] = TestPdfPublicator()
Пример #11
0
    def run(self):
        requested_events = PublicationEvent.objects.select_related('published_object', 'published_object__content',
                                                                   'published_object__content__image') \
                                                   .filter(state_of_processing='REQUESTED')

        for publication_event in requested_events.iterator():
            content = publication_event.published_object
            extra_content_dir = content.get_extra_contents_directory()
            building_extra_content_path = Path(
                str(Path(extra_content_dir).parent) + '__building',
                'extra_contents', content.content_public_slug)
            if not building_extra_content_path.exists():
                building_extra_content_path.mkdir(parents=True)
            base_name = str(building_extra_content_path)
            md_file_path = base_name + '.md'

            logger.info('Exporting « %s » as %s', content.title(),
                        publication_event.format_requested)
            publication_event.state_of_processing = 'RUNNING'
            publication_event.save()

            publicator = PublicatorRegistry.get(
                publication_event.format_requested)
            try:
                publicator.publish(md_file_path, base_name)
            except FailureDuringPublication:
                logger.error('Failed to export « %s » as %s', content.title(),
                             publication_event.format_requested)
                publication_event.state_of_processing = 'FAILURE'
            else:
                logger.info('Succeed to export « %s » as %s', content.title(),
                            publication_event.format_requested)
                publication_event.state_of_processing = 'SUCCESS'
            publication_event.save()
Пример #12
0
    def handle(self, *args, **options):
        try:
            ids = list(set(options.get('id')[0].replace('id=', '').split(',')))
        except IndexError:
            ids = []

        if len(ids) > 0:
            public_contents = PublishedContent.objects.filter(content_pk__in=ids, must_redirect=False).all()
        else:
            public_contents = PublishedContent.objects.filter(must_redirect=False).all()

        num_of_contents = len(public_contents)

        if num_of_contents == 0:
            self.stdout.write(_("Aucun contenu n'a été sélectionné, aucun PDF ne sera généré"))
            return

        self.stdout.write(_('Génération de epub pour {} contenu {}').format(
            num_of_contents, 's' if num_of_contents > 1 else ''))

        for content in public_contents:
            with contextlib.suppress(NotAPublicVersion, FailureDuringPublication):
                self.stdout.write(_('- {}').format(content.content_public_slug), ending='')
                extra_content_dir = content.get_extra_contents_directory()
                building_extra_content_path = Path(str(Path(extra_content_dir).parent) + '__building',
                                                   'extra_contents', content.content_public_slug)
                if not building_extra_content_path.exists():
                    building_extra_content_path.mkdir(parents=True)
                base_name = os.path.join(str(extra_content_dir), content.content_public_slug)

                # delete previous one
                if os.path.exists(base_name + '.epub'):
                    os.remove(base_name + '.epub')
                PublicatorRegistry.get('epub').publish(base_name + '.md', str(building_extra_content_path))

            # check:
            if os.path.exists(base_name + '.epub'):
                self.stdout.write(' [OK]')
            else:
                self.stdout.write(' [ERREUR]')

        os.chdir(settings.BASE_DIR)
Пример #13
0
    def setUp(self):
        self.licence = LicenceFactory()
        self.user_author = ProfileFactory().user

        self.old_registry = {
            key: value
            for key, value in PublicatorRegistry.get_all_registered()
        }
        self.old_build_pdf_when_published = self.overridden_zds_app["content"][
            "build_pdf_when_published"]

        self.overridden_zds_app["content"]["build_pdf_when_published"] = True
Пример #14
0
    def handle(self, *__, **options):
        try:
            ids = list(set(options.get('id')[0].replace('id=', '').split(',')))
        except IndexError:
            ids = []

        if len(ids) > 0:
            public_contents = PublishedContent.objects.filter(content_pk__in=ids, must_redirect=False).all()
        else:
            public_contents = PublishedContent.objects.filter(must_redirect=False).all()

        num_of_contents = len(public_contents)

        if num_of_contents == 0:
            self.stdout.write(_("Aucun contenu n'a été sélectionné, aucun markdown ne sera généré"))
            return

        self.stdout.write(_('Génération de epub pour {} contenu {}').format(
            num_of_contents, 's' if num_of_contents > 1 else ''))

        for content in public_contents:
            with contextlib.suppress(NotAPublicVersion, FailureDuringPublication):
                self.stdout.write(_('- {}').format(content.content_public_slug), ending='')
                extra_content_dir = content.get_extra_contents_directory()
                building_extra_content_path = Path(str(Path(extra_content_dir).parent) + '__building',
                                                   'extra_contents', content.content_public_slug)
                if not building_extra_content_path.exists():
                    building_extra_content_path.mkdir(parents=True)
                base_name = str(Path(str(extra_content_dir), content.content_public_slug))

                PublicatorRegistry.get('md').publish(base_name + '.md', str(building_extra_content_path),
                                                     cur_language=translation.get_language(),
                                                     versioned=content.content.load_version(public=True))

            # check:
            if Path(base_name + '.md').exists():
                self.stdout.write(' [OK]')
            else:
                self.stdout.write(' [ERREUR]')
Пример #15
0
    def post(self, request, *args, **kwargs):
        try:
            publishable_content = self.get_object()
            if not publishable_content.public_version:
                raise Http404('Not public content')

            tmp_dir, _ = self.ensure_directories(publishable_content)
            versioned = publishable_content.load_version(public=True)
            base_name = str(Path(tmp_dir, versioned.slug))
            md_file_path = str(Path(tmp_dir, versioned.slug + '.md'))

            PublicatorRegistry.get('md').publish(
                md_file_path,
                base_name,
                versioned=versioned,
                cur_language=translation.get_language())
            PublicatorRegistry.get('watchdog').publish_from_published_content(
                publishable_content.public_version)
        except ValueError:
            return Response({}, status=status.HTTP_400_BAD_REQUEST, headers={})
        else:
            return Response({}, status=status.HTTP_201_CREATED, headers={})
Пример #16
0
    def run(self):
        requested_events = PublicationEvent.objects.select_related(
            "published_object", "published_object__content",
            "published_object__content__image").filter(
                state_of_processing="REQUESTED")

        for publication_event in requested_events.iterator():
            try:
                content = publication_event.published_object
                extra_content_dir = content.get_extra_contents_directory()
                building_extra_content_path = Path(
                    str(Path(extra_content_dir).parent) + "__building",
                    "extra_contents", content.content_public_slug)
                if not building_extra_content_path.exists():
                    building_extra_content_path.mkdir(parents=True)
                base_name = str(building_extra_content_path)
                md_file_path = base_name + ".md"

                logger.info("Exporting « %s » as %s", content.title(),
                            publication_event.format_requested)
                publication_event.state_of_processing = "RUNNING"
                publication_event.save()

                publicator = PublicatorRegistry.get(
                    publication_event.format_requested)
                publicator.publish(md_file_path, base_name)
            except:
                # Update and save the publication state before logging, in case
                # content.title() would raise an exception (it already used to
                # happen!).
                publication_event.state_of_processing = "FAILURE"
                publication_event.save()
                logger.exception("Failed to export « %s » as %s",
                                 content.title(),
                                 publication_event.format_requested)
            else:
                publication_event.state_of_processing = "SUCCESS"
                publication_event.save()
                logger.info("Succeed to export « %s » as %s", content.title(),
                            publication_event.format_requested)
Пример #17
0
    def test_export_only_ready_to_publish(self):
        """
        Test exported contents contain only ready_to_publish==True parts.
        """

        # We save the current settings for the PDF publicator:
        previous_pdf_publicator = PublicatorRegistry.get("pdf")
        previous_build_pdf_when_published = self.overridden_zds_app["content"][
            "build_pdf_when_published"]
        # We need to produce at least the LaTeX file, so we use the real PDF publicator:
        PublicatorRegistry.registry["pdf"] = ZMarkdownRebberLatexPublicator(
            ".pdf")
        self.overridden_zds_app["content"]["build_pdf_when_published"] = True

        #  Medium-size tutorial
        midsize_tuto = PublishableContentFactory(type="TUTORIAL")

        midsize_tuto.authors.add(self.user_author)
        UserGalleryFactory(gallery=midsize_tuto.gallery,
                           user=self.user_author,
                           mode="W")
        midsize_tuto.licence = self.licence
        midsize_tuto.save()

        # populate with 3 chapters (1 extract each), one not being ready for pubication
        midsize_tuto_draft = midsize_tuto.load_version()
        chapter1 = ContainerFactory(parent=midsize_tuto_draft,
                                    db_object=midsize_tuto,
                                    title="Chapter 1 ready")
        ExtractFactory(container=chapter1, db_object=midsize_tuto)
        chapter2 = ContainerFactory(parent=midsize_tuto_draft,
                                    db_object=midsize_tuto,
                                    title="Chapter 2 ready")
        ExtractFactory(container=chapter2, db_object=midsize_tuto)
        chapter3 = ContainerFactory(parent=midsize_tuto_draft,
                                    db_object=midsize_tuto,
                                    title="Chapter 3 not ready")
        chapter3.ready_to_publish = False
        ExtractFactory(container=chapter3, db_object=midsize_tuto)

        # publish it
        midsize_tuto = PublishableContent.objects.get(pk=midsize_tuto.pk)
        published = publish_content(midsize_tuto, midsize_tuto_draft)
        public = midsize_tuto.load_version(sha=published.sha_public,
                                           public=published)

        # test creation of files:
        self.assertTrue(Path(published.get_prod_path()).is_dir())
        self.assertTrue(
            Path(published.get_prod_path(), "manifest.json").is_file())

        self.assertTrue(
            Path(public.get_prod_path(), public.introduction).is_file())
        self.assertTrue(
            Path(public.get_prod_path(), public.conclusion).is_file())

        self.assertEqual(len(public.children), 2)
        for child in public.children:
            self.assertTrue(os.path.isfile(
                child.get_prod_path()))  # an HTML file for each chapter
            self.assertIsNone(child.introduction)
            self.assertIsNone(child.conclusion)

        # Test Markdown content:
        self.assertTrue(published.has_md())
        with Path(published.get_extra_contents_directory(),
                  published.content_public_slug + ".md").open("r") as md:
            content = md.read()
            self.assertIn(chapter1.title, content)
            self.assertIn(chapter2.title, content)
            self.assertNotIn(chapter3.title, content)

        # TODO: factorize getting the LaTeX file path with what is done in zds.tutorialv2.publication_utils.publish_content()
        tmp_path = os.path.join(
            settings.ZDS_APP["content"]["repo_public_path"],
            published.content_public_slug + "__building")
        build_extra_contents_path = os.path.join(
            tmp_path, settings.ZDS_APP["content"]["extra_contents_dirname"])
        base_name = os.path.join(build_extra_contents_path,
                                 published.content_public_slug)
        tex_file = base_name + ".tex"
        # PDF generation may fail, we only test the LaTeX content:
        with open(tex_file) as tex:
            content = tex.read()
            self.assertIn(chapter1.title, content)
            self.assertIn(chapter2.title, content)
            self.assertNotIn(chapter3.title, content)

        # We set back the previous settings:
        PublicatorRegistry.registry["pdf"] = previous_pdf_publicator
        self.overridden_zds_app["content"][
            "build_pdf_when_published"] = previous_build_pdf_when_published