Beispiel #1
0
    def body_to_stream(self, body):
        soup = BeautifulSoup(body, "html.parser")
        parsed_body = ""
        stream = []
        for el in soup:
            if el.name == "div" and el.get("class") == ["wc-gallery"]:
                # dump existing parsed body into stream
                if len(parsed_body) > 0:
                    stream.append(("paragraph", RichText(parsed_body)))
                    parsed_body = ""

                gallery_photos = []
                for item in el.find_all(class_="gallery-item"):
                    url = item.find("a").get("href")
                    caption = item.parent.find(class_="gallery-caption")
                    if caption is None:
                        self.stderr.write(
                            "unable to determine photographer in gallery")
                        raise Exception()
                    photographer = str(caption.p)[3:-4].strip()
                    image = self.get_or_create_image(url, photographer)

                    gallery_photos.append({"image": image})

                stream.append(("photo_gallery", gallery_photos))
            else:
                if hasattr(el, "stripped_strings") and any(
                        el.stripped_strings):
                    parsed_body += str(el)

        return stream + [("paragraph", RichText(parsed_body))]
def migrate_standardpage_intro_and_body_to_streamfield(apps, schema_editor):
    StandardPage = apps.get_model("torchbox.StandardPage")
    stream_block = StandardPage._meta.get_field("streamfield").stream_block

    # Append body to beginning of streamfield
    for page in StandardPage.objects.exclude(body__in=["", "<p></p>", "<p><br/></p>"]):
        # Add body as first block so it appears in the same place on the template
        page.streamfield = StreamValue(
            stream_block,
            [("paragraph", RichText(page.body), str(uuid3(UUID_NAMESPACE, page.body))),]
            + [(child.block_type, child.value, child.id) for child in page.streamfield],
        )

        page.save()

    # Append intro to beginning of streamfield
    for page in StandardPage.objects.exclude(intro__in=["", "<p></p>", "<p><br/></p>"]):
        # Add intro as first block so it appears in the same place on the template
        page.streamfield = StreamValue(
            stream_block,
            [
                (
                    "paragraph",
                    RichText(page.intro),
                    str(uuid3(UUID_NAMESPACE, page.intro)),
                ),
            ]
            + [(child.block_type, child.value, child.id) for child in page.streamfield],
        )

        page.save()
def convert_rich_text(source, request, absolute):
    try:
        from bs4 import BeautifulSoup
    except ImportError:
        return str(RichText(source))

    soup = BeautifulSoup(source, 'html5lib')

    # Make document links absolute.
    for anchor in soup.find_all('a'):
        if anchor.attrs.get('linktype', '') == 'document':
            try:
                doc = get_document_model().objects.get(pk=anchor.attrs['id'])
                new_tag = soup.new_tag(
                    'a',
                    href=resolve_absolute_url(doc.url,
                                              request,
                                              absolute=absolute))
                new_tag.append(*anchor.contents)
                anchor.replace_with(new_tag)
            except get_document_model().DoesNotExist:
                new_tag = soup.new_tag('a')
                new_tag.append(*anchor.contents)
                anchor.replace_with(new_tag)

    return str(RichText(str(soup)))
def convert_to_streamfield(apps, schema_editor):
    FormPage = apps.get_model('main', 'FormPage')
    for page in FormPage.objects.all():
        if page.body.raw_text and not page.body:
            page.body = [('paragraph', RichText(page.body.raw_text))]
            page.save()

        if page.thank_you_text.raw_text and not page.thank_you_text:
            page.thank_you_text = [('paragraph', RichText(page.thank_you_text.raw_text))]
            page.save()
def parse_article_body_blocks(body):
    article_body_blocks = []

    try:
        soup = BeautifulSoup(body, "html.parser")
    except:
        soup = False

        print("Could not parse article body:", body)

    # Placeholder for gathering successive items
    rich_text_value = ""

    if soup:
        for item in soup:

            item_has_value = item.string is not None

            if item_has_value:

                item_contains_pullquote = "pullquote" in item.string

                if item_contains_pullquote:
                    # Add current rich text value as paragraph block, if not empty
                    if rich_text_value != "":
                        rich_text_block = ("paragraph",
                                           RichText(rich_text_value))

                        article_body_blocks.append(rich_text_block)

                        # reset rich text value
                        rich_text_value = ""

                    pullquotes = extract_pullquotes(item)

                    # Add Pullquote block(s) to body streamfield
                    # so they appear above the related rich text field
                    # i.e. near the paragraph containing the pullquote
                    for pullquote in pullquotes:
                        block_content = ("pullquote", pullquote)

                        article_body_blocks.append(block_content)

                    item = clean_pullquote_tags(item)

                rich_text_value += str(item)

        if rich_text_value != "":
            # Add Paragraph Block with remaining rich text elements
            rich_text_block = ("paragraph", RichText(rich_text_value))

            article_body_blocks.append(rich_text_block)

    return article_body_blocks
Beispiel #6
0
class ResourceFactory(factory.django.DjangoModelFactory):
    class Meta:
        model = Resource

    path = factory.Sequence(
        lambda n: u'00010{}'.format(n))  # from wagtailcore_pagerevision
    depth = 3
    numchild = 0
    title = 'Dummy Resource Page'
    slug = factory.LazyAttribute(lambda obj: slugify(obj.title))
    live = True
    has_unpublished_changes = False
    show_in_menus = False
    search_description = ''
    go_live_at = '1995-02-07 12:00'
    expire_at = '2050-12-31 12:43'
    expired = False
    content_type = factory.SubFactory(ContentTypeFactory,
                                      app_label="resource",
                                      model="resource")
    locked = False
    latest_revision_created_at = '1995-02-07 12:00'
    first_published_at = '1995-02-07 12:00'
    language = 'en'

    content = [
        ('authors', RichText('<p>XYZ</p>')),
        ('copyright',
         RichText(
             '<p>XYZ, Professor, Centre for Economic Studies and Planning</p><p>\u00a0</p>'
         )),
        ('focus',
         RichText(
             '<p>The 2008 global food price fluctuations -- especially the policies on bio-fuel and the neglect of agriculture.</p>'
         )),
        ('factoids',
         RichText(
             '<p>Lack of public investment in agriculture and agriculture research .</p>'
         ))
    ]

    @classmethod
    def _setup_next_sequence(cls):
        return getattr(cls, 'starting_sequence_num', 20)

    @factory.post_generation
    def categories(self, create, extracted, **kwargs):
        if not create:
            return

        if extracted:
            for category in extracted:
                self.categories.add(category)
def run_migration(apps, schema_editor):
    BlogPage = apps.get_model('blog', 'BlogPage')

    for page in BlogPage.objects.all():
        if page.body.raw_text and not page.body:
            if page.body.raw_text not in ['', '<p></p>']:
                page.body = [('richtext', RichText(page.body.raw_text))]
                page.save()

        if page.body_de.raw_text and not page.body_de:
            if page.body_de.raw_text not in ['', '<p></p>']:
                page.body_de = [('richtext', RichText(page.body_de.raw_text))]
                page.save()
Beispiel #8
0
def parse_block(b, figure_index):
    val = None
    if b['type'] == 'paragraph':
        val = ('paragraph', RichText(b['html']))
    elif b['type'] == 'heading':
        val = ('heading', b['text'])
    elif b['type'] == 'table':
        val = ('table', b['data'])
    elif b['type'] == 'inline_image':
        val = ('paragraph',
               RichText('<em>[[Figure %s]]</em>' % figure_index['i']))
        figure_index['i'] += 1

    return val
Beispiel #9
0
 def test_render(self):
     text = '<p>To the <a linktype="page" id="{}">moon</a>!</p>'.format(
         self.single_event_page.id)
     value = RichText(text)
     result = str(value)
     expected = ('<p>To the <a href="/foo/pointless-suffix/">moon</a>!</p>')
     self.assertEqual(result, expected)
def convert_data(apps, schema_editor):
    for name in ['intro', 'thank_you_text']:
        FormPage = apps.get_model('teratree', 'FormPage')
        for form in FormPage.objects.all():
            print('\n', form.title)
            # edit the live form page
            if getattr(form, name).raw_text and not getattr(form, name):
                setattr(form, name, [('paragraph', RichText(getattr(form, name).raw_text))])
                print('Updated ' + form.title)
                form.save()

            # # edit drafts associated with post
            # if form.has_unpublished_changes:
            print(form.title + ' has revisions...')
            for rev in form.revisions.all():
                data = json.loads(rev.content_json)
                value = data[name]
                print(value)

                print('This is current JSON:', data, '\n')
                data[name] = json.dumps([{
                    "type": "paragraph",
                    "value": value
                }])
                rev.content_json = json.dumps(data)
                print('This is updated JSON:', rev.content_json, '\n')

                rev.save()

            print('Completed ' + form.title + '.' + '\n')
Beispiel #11
0
    def handle_block(self, block_type, block_value, segments):
        if hasattr(block_type, "restore_translated_segments"):
            return block_type.restore_translated_segments(
                block_value, segments)

        elif isinstance(block_type, (blocks.CharBlock, blocks.TextBlock)):
            return segments[0].render_text()

        elif isinstance(block_type, blocks.RichTextBlock):
            format, template, strings = organise_template_segments(segments)
            assert format == "html"
            return RichText(restore_strings(template, strings))

        elif isinstance(block_type, blocks.ChooserBlock):
            return self.handle_related_object_block(block_value, segments)

        elif isinstance(block_type, blocks.StructBlock):
            return self.handle_struct_block(block_value, segments)

        elif isinstance(block_type, blocks.ListBlock):
            return self.handle_list_block(block_value, segments)

        elif isinstance(block_type, blocks.StreamBlock):
            return self.handle_stream_block(block_value, segments)

        else:
            raise Exception(
                "Unrecognised StreamField block type '{}'. Have you implemented restore_translated_segments() on this class?"
                .format(block_type.__class__.__name__))
Beispiel #12
0
def publish_page(page, page_parent, default_body_string, user):
    '''
    Helper function for publishing a manually created Wagtail Page object.
    '''

    logger.debug('publishing page: {}'.format(page))

    paragraph = '<p>{}</p>'.format(default_body_string)
    page.body = [('paragraph', RichText(paragraph))]

    # only set page parent if handling newly created page
    # if page_parent is not None:
    if page.get_parent() is None:
        logger.debug('Set parent: {} for {}'.format(page_parent, page))

        try:
            page_parent.add_child(instance=page)
        except ValidationError:
            slug_string = '{}-{}'.format(page.slug, page.id)
            page.slug = slugify(slug_string)
            logger.debug('page slug set to: {}'.format(page.slug))
            page_parent.add_child(instance=page)

    revision = page.save_revision(
        user=user,
        submitted_for_moderation=False,
    )

    revision.publish()
    page.save()
Beispiel #13
0
def convert_to_streamfield(apps, schema_editor):
    Concert = apps.get_model('main', 'Concert')
    for page in Concert.objects.all():
        if page.description.raw_text and not page.description:
            page.description = [('paragraph',
                                 RichText(page.description.raw_text))]
            page.save()
Beispiel #14
0
    def handle_block(self, block_type, block_value, segments):
        # Need to check if the app is installed before importing EmbedBlock
        # See: https://github.com/wagtail/wagtail-localize/issues/309
        if apps.is_installed("wagtail.embeds"):
            from wagtail.embeds.blocks import EmbedBlock, EmbedValue

            if isinstance(block_type, EmbedBlock):
                if len(segments) > 1:
                    raise ValueError(
                        "EmbedBlock can only have a single segment. Found {}".
                        format(len(segments)))

                segment = segments[0]

                if isinstance(segment, OverridableSegmentValue):
                    return EmbedValue(segment.data)

        if hasattr(block_type, "restore_translated_segments"):
            return block_type.restore_translated_segments(
                block_value, segments)

        elif isinstance(
                block_type,
            (blocks.CharBlock, blocks.TextBlock, blocks.URLBlock,
             blocks.EmailBlock),
        ):
            if len(segments) > 1:
                raise ValueError(
                    "TextBlock/CharBlock can only have a single segment. Found {}"
                    .format(len(segments)))

            segment = segments[0]

            if isinstance(segment, OverridableSegmentValue):
                return segment.data
            else:
                # Assume it's a StringSegmentValue
                return segment.render_text()

        elif isinstance(block_type, blocks.RichTextBlock):
            format, template, strings = organise_template_segments(segments)
            assert format == "html"
            return RichText(restore_strings(template, strings))

        elif isinstance(block_type, blocks.ChooserBlock):
            return self.handle_related_object_block(block_value, segments)

        elif isinstance(block_type, blocks.StructBlock):
            return self.handle_struct_block(block_value, segments)

        elif isinstance(block_type, blocks.ListBlock):
            return self.handle_list_block(block_value, segments)

        elif isinstance(block_type, blocks.StreamBlock):
            return self.handle_stream_block(block_value, segments)

        else:
            raise Exception(
                "Unrecognised StreamField block type '{}'. Have you implemented restore_translated_segments() on this class?"
                .format(block_type.__class__.__name__))
Beispiel #15
0
 def test_render(self):
     value = RichText('<p>Merry <a linktype="page" id="4">Christmas</a>!</p>')
     result = str(value)
     self.assertEqual(
         result,
         '<div class="rich-text"><p>Merry <a href="/events/christmas/">Christmas</a>!</p></div>'
     )
Beispiel #16
0
def test_add_block_to_live_post_streamchild(blog_page_factory):
    live_posts = json.dumps([
        {
            "type": "live_post",
            "id": "some-id",
            "value": {
                "message_id": "some-id",
                "created": "2021-01-01T12:00:00",
                "modified": "2021-01-01T12:00:00",
                "show": True,
                "content": [],
            },
        },
    ])
    page = blog_page_factory(channel_id="some-id", live_posts=live_posts)
    live_post = page.get_live_post_by_index(live_post_index=0)
    text_block = construct_text_block(text="Some text")

    add_block_to_live_post(TEXT, text_block, live_post)

    assert isinstance(live_post, StreamValue.StreamChild)
    setattr(RichText, "__eq__",
            lambda self, other: self.source == other.source)
    assert live_post.value["content"] == StreamValue(
        ContentBlock(), [("text", RichText("Some text"))])
Beispiel #17
0
    def test_that_article_with_no_recommended_articles_should_be_valid(self):
        author = BossFactory()
        body_block = StreamBlock([(ArticleBodyBlockNames.PARAGRAPH.value,
                                   RichTextBlock())])
        body = StreamValue(body_block, [
            (ArticleBodyBlockNames.PARAGRAPH.value, RichText("Hello, World"))
        ])
        test_title = "Simple Article Title"
        blog_article_parameter = {
            "title": test_title,
            "page_title": test_title,
            "date": datetime.now(),
            "body": body,
            "author": author,
            "read_time": 7,
            "views": 0,
        }
        articles_block = StreamBlock([("page", PageChooserBlock())])

        blog_article_page = BlogArticlePage(**blog_article_parameter)
        self.blog_index_page.add_child(instance=blog_article_page)
        blog_article_page.save()

        self.assertEqual(blog_article_page.recommended_articles,
                         StreamValue(articles_block, []))
Beispiel #18
0
 def get_rich_text_body(row):
     body = []
     row = row.splitlines()
     for line in row:
         if len(line) != 0:
             body = body + [("paragraph", RichText(line))]
     return body
Beispiel #19
0
def migrate_blog_body_to_streamfield(apps, schema_editor):
    BlogPage = apps.get_model("blog.BlogPage")
    stream_block = BlogPage._meta.get_field("streamfield").stream_block

    # Update model
    for blog_page in (
        BlogPage.objects.exclude(body="")
        .exclude(body="<p></p>")
        .exclude(body="<p><br/></p>")
    ):
        # Add body as first block so it appears in the same place on the template
        blog_page.streamfield = StreamValue(
            stream_block,
            [
                (
                    "paragraph",
                    RichText(blog_page.body),
                    str(uuid3(UUID_NAMESPACE, blog_page.body)),
                ),
            ]
            + [
                (child.block_type, child.value, child.id)
                for child in blog_page.streamfield
            ],
        )

        blog_page.save()

    # Update revisions
    PageRevision = apps.get_model("wagtailcore.PageRevision")
    ContentType = apps.get_model("contenttypes.ContentType")
    blog_page_content_type = ContentType.objects.get(app_label="blog", model="blogpage")

    for revision in PageRevision.objects.filter(
        page__content_type=blog_page_content_type
    ):
        content = json.loads(revision.content_json)

        if content["body"] and content["body"] not in ["<p></p>", "<p><br/></p>"]:
            streamfield_json = content.get("streamfield", "")

            if streamfield_json:
                streamfield = json.loads(streamfield_json)
            else:
                streamfield = []

            streamfield.insert(
                0,
                {
                    "type": "paragraph",
                    "value": content["body"],
                    "id": str(uuid3(UUID_NAMESPACE, content["body"])),
                },
            )

            content["streamfield"] = json.dumps(streamfield)

            revision.content_json = json.dumps(content)
            revision.save()
def _convert_to_streamfield(apps, schema_editor, field_name):
    RecordEntry = apps.get_model('cms', 'RecordEntry')
    for page in RecordEntry.objects.all():
        field = getattr(page, field_name)

        if field.raw_text and not field:
            setattr(page, field_name, [('text', RichText(field.raw_text))])
            page.save()
Beispiel #21
0
    def setUpTestData(cls):
        # Cart page
        cls.cart = ShoppingCartPage.objects.first()

        # Sample score page
        parent = ScoreListingPage.objects.first()
        with open(join(settings.BASE_DIR, 'data/pdf_example.pdf'), 'rb') as f:
            pdf_file_one = InMemoryUploadedFile(file=f,
                                                field_name=None,
                                                name='pdf_example.pdf',
                                                size=f.tell,
                                                content_type='application/pdf',
                                                charset=None,
                                                content_type_extra=None)
            s1 = ScorePage(title='Example Score One',
                           cover_image=None,
                           description=[('rich_text',
                                         RichText('<p>Description text</p>'))],
                           duration='00:05:43',
                           price='14.99',
                           file=pdf_file_one,
                           preview_score=pdf_file_one)
            parent.add_child(instance=s1)
            s1.save_revision().publish()

        with open(join(settings.BASE_DIR, 'data/pdf_example.pdf'), 'rb') as f:
            pdf_file_two = InMemoryUploadedFile(file=f,
                                                field_name=None,
                                                name='pdf_example.pdf',
                                                size=f.tell,
                                                content_type='application/pdf',
                                                charset=None,
                                                content_type_extra=None)
            s2 = ScorePage(title='Example Score Two',
                           cover_image=None,
                           description=[('rich_text',
                                         RichText('<p>Description text</p>'))],
                           duration='00:05:43',
                           price='14.99',
                           file=pdf_file_two,
                           preview_score=pdf_file_two)
            parent.add_child(instance=s2)
            s2.save_revision().publish()

        cls.scores = [s1, s2]
 def setUp(self):
     super().setUp()
     # Create Blog
     self.blog_page = BlogPageFactory(body=[
         ("heading", "Test heading 1"),
         ("paragraph", RichText("This is a paragraph.")),
         ("heading", "Test heading 2"),
         ("image", wagtail_factories.ImageFactory()),
         ("decimal", decimal.Decimal(1.2)),
         ("date", datetime.date.today()),
         ("datetime", datetime.datetime.now()),
         (
             "carousel",
             StreamValue(
                 stream_block=CarouselBlock(),
                 stream_data=[
                     ("image",
                      wagtail_factories.ImageChooserBlockFactory()),
                     ("image",
                      wagtail_factories.ImageChooserBlockFactory()),
                 ],
             ),
         ),
         (
             "gallery",
             {
                 "title":
                 "Gallery title",
                 "images":
                 StreamValue(
                     stream_block=ImageGalleryImages(),
                     stream_data=[
                         (
                             "image",
                             {
                                 "image":
                                 wagtail_factories.ImageChooserBlockFactory(
                                 )
                             },
                         ),
                         (
                             "image",
                             {
                                 "image":
                                 wagtail_factories.ImageChooserBlockFactory(
                                 )
                             },
                         ),
                     ],
                 ),
             },
         ),
         ("objectives", ["Read all of article!"]),
         ("video", {
             "youtube_link": EmbedValue("https://youtube.com/")
         }),
     ])
Beispiel #23
0
 def setUp(self):
     self.title = 'Awesome'
     self.body = 'Cool'
     self.source_warning = 'Alert'
     self.directory = DirectoryPageFactory(
         title=self.title,
         body=RichText(self.body),
         source_warning=self.source_warning)
     self.search_content = self.directory.get_search_content()
Beispiel #24
0
class HeroTextBlockFactory(wagtail_factories.StructBlockFactory):
    background_image = factory.LazyAttribute(get_an_image)
    text = factory.LazyAttribute(
        lambda x: RichText(fake.text(max_nb_chars=20)))
    button_link = factory.LazyAttribute(get_a_page)
    button_text = factory.LazyAttribute(fake_title)

    class Meta:
        model = HeroTextBlock
Beispiel #25
0
 def setUp(self):
     self.campaign = SaleCampaign.objects.create(
         name='Test campaign',
         subject='The subject',
         body=[
             ('rich_text', RichText('<p>The body</p>'))
         ]
     )
     self.login()
Beispiel #26
0
def generate_article_body() -> StreamValue:
    return StreamValue(
        StreamBlock([("paragraph", RichTextBlock())]),
        [(
            "paragraph",
            RichText((lambda text, tag: f"<{tag}>{text}</{tag}>")(
                faker.paragraph(nb_sentences=random.randint(30, 100)), "p")),
        ) for _ in range(random.randint(2, 7))],
    )
Beispiel #27
0
    def test_legend_display(self):
        """Verify that the legend appears if set."""
        new_legend = "<h3>ZELDA</h3>"
        self.settings.legend = [('rich_text', RichText(new_legend))]
        self.settings.save()

        response = self.client.get(reverse("schedule_conference"))
        self.assertContains(response, new_legend)
        self.assertNotContains(response, "<p>View past PyData event schedules")
Beispiel #28
0
class FacultyBlockFactory(wagtail_factories.StructBlockFactory):
    """FacultyBlock factory class"""

    name = factory.Faker("name")
    image = factory.SubFactory(wagtail_factories.ImageFactory)
    text = factory.LazyFunction(
        lambda: RichText("<p>{}</p>".format(FAKE.paragraph())))

    class Meta:
        model = FacultyBlock
Beispiel #29
0
    def test_can_assign_as_list(self):
        self.json_body.body = [('rich_text', RichText("<h2>hello world</h2>"))]
        self.json_body.save()

        # the body should now be a stream consisting of a single rich_text block
        fetched_body = StreamModel.objects.get(id=self.json_body.id).body
        self.assertIsInstance(fetched_body, StreamValue)
        self.assertEqual(len(fetched_body), 1)
        self.assertIsInstance(fetched_body[0].value, RichText)
        self.assertEqual(fetched_body[0].value.source, "<h2>hello world</h2>")
Beispiel #30
0
def convert_to_streamfield(apps, schema_editor):
    ContentPage = apps.get_model('home', 'ContentPage')
    for page in ContentPage.objects.all():
        # That page.body could be "false-y" yet have a raw_text attribute seems
        # weird; this is an intentional design choice by Wagtail meant to
        # simplify migrations from RichTextField to StreamField.
        if page.body.raw_text and not page.body:
            page.body = [
                ('rich_text', RichText(page.body.raw_text)),
            ]
            page.save()