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')
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')
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={})
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)
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]")
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)
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()
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()
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))
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)
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]')
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={})
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)
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