def test_equality(self):
        tag = Tag('test', settings={})
        cat = Category('test', settings={})
        author = Author('test', settings={})

        # same name, but different class
        self.assertNotEqual(tag, cat)
        self.assertNotEqual(tag, author)

        # should be equal vs text representing the same name
        self.assertEqual(tag, u'test')

        # should not be equal vs binary
        self.assertNotEqual(tag, b'test')

        # Tags describing the same should be equal
        tag_equal = Tag('Test', settings={})
        self.assertEqual(tag, tag_equal)

        # Author describing the same should be equal
        author_equal = Author('Test', settings={})
        self.assertEqual(author, author_equal)

        cat_ascii = Category('指導書', settings={})
        self.assertEqual(cat_ascii, u'zhi dao shu')
Пример #2
0
def get_subcategories(generator, metadata):
    if 'SUBCATEGORY_SAVE_AS' not in generator.settings:
        generator.settings['SUBCATEGORY_SAVE_AS'] = os.path.join(
            'subcategory', '{savepath}.html')
    if 'SUBCATEGORY_URL' not in generator.settings:
        generator.settings['SUBCATEGORY_URL'] = 'subcategory/{fullurl}.html'
    if ('PAGINATED_TEMPLATES' in generator.settings and 'subcategory'
            not in generator.settings['PAGINATED_TEMPLATES']):
        generator.settings['PAGINATED_TEMPLATES']['subcategory'] = None

    if 'subcategory_path' in metadata:
        category_list = text_type(metadata.get('subcategory_path')).split('/')
    else:
        category_list = text_type(metadata.get('category')).split('/')

    category = (category_list.pop(0)).strip()
    category = Category(category, generator.settings)
    metadata['category'] = category
    #generate a list of subcategories with their parents
    sub_list = []
    parent = category.name
    for subcategory in category_list:
        subcategory = parent + '/' + subcategory.strip()
        sub_list.append(subcategory)
        parent = subcategory
    metadata['subcategories'] = sub_list
Пример #3
0
        def replacer(m):
            what = m.group('what')
            value = m.group('value')
            origin = m.group('path')

            # we support only filename for now. the plan is to support
            # categories, tags, etc. in the future, but let's keep things
            # simple for now.

            # XXX Put this in a different location.
            if what == 'filename':
                if value.startswith('/'):
                    value = value[1:]
                else:
                    # relative to the source path of this content
                    value = self.get_relative_source_path(
                        os.path.join(self.relative_dir, value)
                    )

                if value in self._context['filenames']:
                    origin = '/'.join((siteurl,
                             self._context['filenames'][value].url))
                    origin = origin.replace('\\', '/')  # Fow windows paths.
                else:
                    logger.warning("Unable to find {fn}, skipping url"
                                   " replacement".format(fn=value))
            elif what == 'category':
                origin = Category(value, self.settings).url
            elif what == 'tag':
                origin = Tag(value, self.settings).url

            return ''.join((m.group('markup'), m.group('quote'), origin,
                            m.group('quote')))
Пример #4
0
        def replacer(m):
            what = m.group('what')
            value = urlparse(m.group('value'))
            path = value.path
            origin = m.group('path')

            # XXX Put this in a different location.
            if what == 'filename':
                if path.startswith('/'):
                    path = path[1:]
                else:
                    # relative to the source path of this content
                    path = self.get_relative_source_path(
                        os.path.join(self.relative_dir, path))

                if path in self._context['filenames']:
                    origin = '/'.join(
                        (siteurl, self._context['filenames'][path].url))
                    origin = origin.replace('\\', '/')  # for Windows paths.
                else:
                    logger.warning("Unable to find {fn}, skipping url"
                                   " replacement".format(fn=path))
            elif what == 'category':
                origin = Category(path, self.settings).url
            elif what == 'tag':
                origin = Tag(path, self.settings).url

            # keep all other parts, such as query, fragment, etc.
            parts = list(value)
            parts[2] = origin
            origin = urlunparse(parts)

            return ''.join((m.group('markup'), m.group('quote'), origin,
                            m.group('quote')))
Пример #5
0
def get_subcategories(generator, metadata):
    if "SUBCATEGORY_SAVE_AS" not in generator.settings:
        generator.settings["SUBCATEGORY_SAVE_AS"] = os.path.join(
            "subcategory", "{savepath}.html")
    if "SUBCATEGORY_URL" not in generator.settings:
        generator.settings["SUBCATEGORY_URL"] = "subcategory/{fullurl}.html"
    if ("PAGINATED_TEMPLATES" in generator.settings and "subcategory"
            not in generator.settings["PAGINATED_TEMPLATES"]):
        generator.settings["PAGINATED_TEMPLATES"]["subcategory"] = None

    if "subcategory_path" in metadata:
        category_list = text_type(metadata.get("subcategory_path")).split("/")
    else:
        category_list = text_type(metadata.get("category")).split("/")

    category = (category_list.pop(0)).strip()
    category = Category(category, generator.settings)
    metadata["category"] = category
    # generate a list of subcategories with their parents
    sub_list = []
    parent = category.name
    for subcategory in category_list:
        subcategory = parent + "/" + subcategory.strip()
        sub_list.append(subcategory)
        parent = subcategory
    metadata["subcategories"] = sub_list
Пример #6
0
        def replacer(m):
            what = m.group('what')
            value = urlparse(m.group('value'))
            path = value.path
            origin = m.group('path')

            # XXX Put this in a different location.
            if what in {'filename', 'attach'}:
                if path.startswith('/'):
                    path = path[1:]
                else:
                    # relative to the source path of this content
                    path = self.get_relative_source_path(
                        os.path.join(self.relative_dir, path))

                if path not in self._context['filenames']:
                    unquoted_path = path.replace('%20', ' ')

                    if unquoted_path in self._context['filenames']:
                        path = unquoted_path

                linked_content = self._context['filenames'].get(path)
                if linked_content:
                    if what == 'attach':
                        if isinstance(linked_content, Static):
                            linked_content.attach_to(self)
                        else:
                            logger.warning(
                                "%s used {attach} link syntax on a "
                                "non-static file. Use {filename} instead.",
                                self.get_relative_source_path())
                    origin = '/'.join((siteurl, linked_content.url))
                    origin = origin.replace('\\', '/')  # for Windows paths.
                else:
                    logger.warning(
                        "Unable to find `%s`, skipping url replacement.",
                        value.geturl(),
                        extra={
                            'limit_msg': ("Other resources were not found "
                                          "and their urls not replaced")
                        })
            elif what == 'category':
                origin = '/'.join((siteurl, Category(path, self.settings).url))
            elif what == 'tag':
                origin = '/'.join((siteurl, Tag(path, self.settings).url))
            else:
                logger.warning(
                    "Replacement Indicator '%s' not recognized, "
                    "skipping replacement", what)

            # keep all other parts, such as query, fragment, etc.
            parts = list(value)
            parts[2] = origin
            origin = urlunparse(parts)

            return ''.join((m.group('markup'), m.group('quote'), origin,
                            m.group('quote')))
Пример #7
0
def photoreel(generator):
    if 'PHOTOREEL' in generator.settings.keys():
        if generator.settings['PHOTOREEL'] == False:
            return 0
    else:
        return 0
    if 'SITEURL' in generator.settings.keys():
        siteurl = generator.settings['SITEURL']
    else:
        siteurl = ""
    if 'PHOTOREEL_NUM_ARTICLES' in generator.settings.keys():
        maxcount = generator.settings['PHOTOREEL_NUM_ARTICLES']
    else:
        maxcount = 5
    if 'PHOTOREEL_TRANSITION_TIME' in generator.settings.keys():
        transtime = generator.settings['PHOTOREEL_TRANSITION_TIME']
    else:
        transtime = 1
    if 'PHOTOREEL_NEXT_SLIDE_TIME' in generator.settings.keys():
        nextslidetime = generator.settings['PHOTOREEL_NEXT_SLIDE_TIME']
    else:
        nextslidetime = 3
    count = 0
    content = "<div class='photoreel-container'><div class='photoreel-left'><a>⬅</a></div>"
    dots = "<div class='photoreel-dots'>"
    for article in generator.articles:
        if 'archiveloc' in article.metadata.keys(
        ) and 'mainimg' in article.metadata.keys():
            content += "<div class='photoreel-photo photoreel-photo-" + str(
                count
            ) + "'><a href='" + siteurl + "/" + article.url + "'><img src='" + os.path.join(
                article.metadata['archiveloc'], article.metadata['mainimg']
            ) + "'><span class='photoreel-title'>" + article.metadata[
                'title'] + "</span></a></div>"
            dots += "<a class='photoreel-dot photoreel-dot-" + str(
                count) + "' data-count='" + str(count) + "'></a>"
            count += 1
        if count == maxcount:
            break
    content += "<div class='photoreel-right'><a>➡</a></div>" + dots + "</div></div>"
    content += """
    <link rel="stylesheet" href='""" + siteurl + """/theme/css/photoreel.css' type="text/css" />
    <script>var maxcount = """ + str(maxcount) + """;var transtime = """ + str(
        transtime) + """;var nextslidetime = """ + str(
            nextslidetime) + """;</script>
    <script src='""" + siteurl + """/theme/js/photoreel.js'></script>
    """

    metadata = {
        'title': 'Imperial College Caving Club',
        'date': datetime.strptime('9999-12-31', '%Y-%m-%d'),
        'category': Category('Photo Reel', generator.settings),
        'type': 'stickyindex',
        'save_as': 'articles/photo-reel.html'
    }
    generator.articles.insert(0, Article(content, metadata))
Пример #8
0
def _build_article(content='', **metadata):
    defaults = dict(
        author=Author(AUTHOR, DEFAULT_CONFIG),
        category=Category(CATEGORY, DEFAULT_CONFIG),
        date=DATE,
        title=HEADLINE,
        url=ARTICLE_URL,
    )
    defaults.update(metadata)
    return Article(content=content, settings=DEFAULT_CONFIG, metadata=defaults)
    def test_slugify_with_substitutions_and_dots(self):
        tag = Tag('Tag Dot', settings={'TAG_REGEX_SUBSTITUTIONS': [
            ('Tag Dot', 'tag.dot'),
        ]})
        cat = Category('Category Dot',
                       settings={'CATEGORY_REGEX_SUBSTITUTIONS': [
                           ('Category Dot', 'cat.dot'),
                       ]})

        self.assertEqual(tag.slug, 'tag.dot')
        self.assertEqual(cat.slug, 'cat.dot')
Пример #10
0
def process_article(article, category_hash):
    if not hasattr(article, 'subcategories'):
        return

    for subcategory in article.subcategories:
        if subcategory not in category_hash:
            category_hash[subcategory] = (Category(subcategory,
                                                   article.category.settings),
                                          [])

        category_hash[subcategory][1].append(article)
Пример #11
0
        def replacer(m):
            what = m.group('what')
            value = urlparse(m.group('value'))
            path = value.path
            origin = m.group('path')

            # XXX Put this in a different location.
            if what == 'filename':
                if path.startswith('/'):
                    path = path[1:]
                else:
                    # relative to the source path of this content
                    path = self.get_relative_source_path(
                        os.path.join(self.relative_dir, path))

                if path not in self._context['filenames']:
                    unquoted_path = path.replace('%20', ' ')

                    if unquoted_path in self._context['filenames']:
                        path = unquoted_path

                if path in self._context['filenames']:
                    origin = '/'.join(
                        (siteurl, self._context['filenames'][path].url))
                    origin = origin.replace('\\', '/')  # for Windows paths.
                else:
                    logger.warning(
                        "Unable to find `%s`, skipping url replacement.",
                        value.geturl(),
                        extra={
                            'limit_msg': ("Other resources were not found "
                                          "and their urls not replaced")
                        })
            elif what == 'category':
                origin = Category(path, self.settings).url
            elif what == 'tag':
                origin = Tag(path, self.settings).url

            # keep all other parts, such as query, fragment, etc.
            parts = list(value)
            parts[2] = origin
            origin = urlunparse(parts)

            return ''.join((m.group('markup'), m.group('quote'), origin,
                            m.group('quote')))
Пример #12
0
def get_subcategories(generator, metadata):
    # get the subcat for a given article?
    if 'SUBCATEGORY_SAVE_AS' not in generator.settings:
        generator.settings['SUBCATEGORY_SAVE_AS'] = os.path.join(
            'subcategory', '{savepath}.html')
    if 'SUBCATEGORY_URL' not in generator.settings:
        generator.settings['SUBCATEGORY_URL'] = 'subcategory/{fullurl}.html'

    #category_list = text_type(metadata.get('category')).split('/')
    category_list = text_type(metadata.get('path_no_ext')).split('/')[:-1]
    category = (category_list.pop(0)).strip()
    category = Category(category, generator.settings)
    metadata['category'] = category
    #generate a list of subcategories with their parents
    sub_list = []
    parent = category.name
    for subcategory in category_list:
        subcategory.strip()
        subcategory = parent + '/' + subcategory
        sub_list.append(subcategory)
        parent = subcategory
    metadata['subcategories'] = sub_list
Пример #13
0
    def _link_replacer(self, siteurl, m):
        what = m.group('what')
        value = urlparse(m.group('value'))
        path = value.path
        origin = m.group('path')

        # urllib.parse.urljoin() produces `a.html` for urljoin("..", "a.html")
        # so if RELATIVE_URLS are enabled, we fall back to os.path.join() to
        # properly get `../a.html`. However, os.path.join() produces
        # `baz/http://foo/bar.html` for join("baz", "http://foo/bar.html")
        # instead of correct "http://foo/bar.html", so one has to pick a side
        # as there is no silver bullet.
        if self.settings['RELATIVE_URLS']:
            joiner = os.path.join
        else:
            joiner = urljoin

            # However, it's not *that* simple: urljoin("blog", "index.html")
            # produces just `index.html` instead of `blog/index.html` (unlike
            # os.path.join()), so in order to get a correct answer one needs to
            # append a trailing slash to siteurl in that case. This also makes
            # the new behavior fully compatible with Pelican 3.7.1.
            if not siteurl.endswith('/'):
                siteurl += '/'

        # XXX Put this in a different location.
        if what in {'filename', 'static', 'attach'}:

            def _get_linked_content(key, url):
                nonlocal value

                def _find_path(path):
                    if path.startswith('/'):
                        path = path[1:]
                    else:
                        # relative to the source path of this content
                        path = self.get_relative_source_path(
                            os.path.join(self.relative_dir, path))
                    return self._context[key].get(path, None)

                # try path
                result = _find_path(url.path)
                if result is not None:
                    return result

                # try unquoted path
                result = _find_path(unquote(url.path))
                if result is not None:
                    return result

                # try html unescaped url
                unescaped_url = urlparse(unescape(url.geturl()))
                result = _find_path(unescaped_url.path)
                if result is not None:
                    value = unescaped_url
                    return result

                # check if a static file is linked with {filename}
                if what == 'filename' and key == 'generated_content':
                    linked_content = _get_linked_content(
                        'static_content', value)
                    if linked_content:
                        logger.warning(
                            '{filename} used for linking to static'
                            ' content %s in %s. Use {static} instead',
                            value.path, self.get_relative_source_path())
                        return linked_content

                return None

            if what == 'filename':
                key = 'generated_content'
            else:
                key = 'static_content'

            linked_content = _get_linked_content(key, value)
            if linked_content:
                if what == 'attach':
                    linked_content.attach_to(self)
                origin = joiner(siteurl, linked_content.url)
                origin = origin.replace('\\', '/')  # for Windows paths.
            else:
                logger.warning(
                    "Unable to find '%s', skipping url replacement.",
                    value.geturl(),
                    extra={
                        'limit_msg': ("Other resources were not found "
                                      "and their urls not replaced")
                    })
        elif what == 'category':
            origin = joiner(siteurl, Category(path, self.settings).url)
        elif what == 'tag':
            origin = joiner(siteurl, Tag(path, self.settings).url)
        elif what == 'index':
            origin = joiner(siteurl, self.settings['INDEX_SAVE_AS'])
        elif what == 'author':
            origin = joiner(siteurl, Author(path, self.settings).url)
        else:
            logger.warning(
                "Replacement Indicator '%s' not recognized, "
                "skipping replacement", what)

        # keep all other parts, such as query, fragment, etc.
        parts = list(value)
        parts[2] = origin
        origin = urlunparse(parts)

        return ''.join(
            (m.group('markup'), m.group('quote'), origin, m.group('quote')))
Пример #14
0
    def parse_jpeg(self, *, source_path: str) -> Tuple[str, dict]:
        JpegReader.logger.info(source_path)

        img = Image.open(source_path)

        image_data = Exiv2Parser.get_values(source_path)

        title = image_data.get(Exiv.DESCRIPTION.value, 'Untitled')
        author = image_data.get(Exiv.ARTIST.value, 'Unknown')
        date_string = image_data.get(Exiv.DATETIME.value, '')

        date = datetime.strptime(date_string, "%Y:%m:%d %H:%M:%S")
        slug = URLWrapper(image_data.get(Exiv.HEADLINE.value, title),
                          self.settings).slug
        description_long = image_data.get(Exiv.COMMENT.value, '')
        summary = image_data.get(Exiv.CAPTION.value, description_long[:140])

        tags = [
            Tag(tag, self.settings)
            for tag in image_data.get(Exiv.KEYWORDS.value, list())
        ]

        content_root = self.settings[PelicanConfig.PATH.value]
        path_output = self.settings[PelicanConfig.OUTPUT_PATH.value]
        relative_source = dirname(source_path[len(content_root):]).lstrip(sep)
        if self.settings[PelicanConfig.USE_FOLDER_AS_CATEGORY.value]:
            category = relative_source.split(sep)[-1]
        else:
            category = image_data.get(Exiv.CATEGORY.value, None)

        type_of_content = relative_source.split(sep)[
            0]  # either 'blog' or 'pages' as far as I know.
        url_site = self.settings[PelicanConfig.SITE_URL.value]

        if type_of_content.lower() == PelicanClass.PAGES.value:
            url_document = self.settings[PelicanConfig.PAGE_URL.value]
            document_save_as = self.settings[PelicanConfig.PAGE_SAVE_AS.value]
        else:  # Assume PelicanClass.BLOG
            url_document = self.settings[PelicanConfig.ARTICLE_URL.value]
            document_save_as = self.settings[
                PelicanConfig.ARTICLE_SAVE_AS.value]

        page_url_complete = join(url_site, url_document)

        author_wrapper = Author(author, self.settings)

        # Move image in place:
        metadata = {
            PelicanMetadata.TITLE.value: title,
            PelicanMetadata.AUTHORS.value: [author_wrapper],
            PelicanMetadata.DATE.value: date,
            PelicanMetadata.SLUG.value: slug,
            PelicanMetadata.TAGS.value: tags,
            PelicanMetadata.CUSTOM_ALL.value: image_data
        }
        if category is not None:
            metadata[PelicanMetadata.CATEGORY.value] = Category(
                category, self.settings)

        thumb_name = '{0}_thumb.jpg'.format(slug)
        original_name = '{0}.jpg'.format(slug)

        path_output_html = join(path_output,
                                document_save_as).format(**metadata)
        path_output_dir = dirname(path_output_html)
        path_output_original = join(path_output_dir, original_name)
        path_output_thumb = join(path_output_dir, thumb_name)

        # Here we generate the summary info incase this is used for articles we get nice thumbnails and summary
        metadata[PelicanMetadata.SUMMARY.value] = summary
        metadata[PelicanMetadata.FEATURED_IMAGE.value] = join(
            url_site, path_output_thumb[len(path_output):])
        if Exiv.OBJECT_NAME.value in image_data:
            metadata[PelicanMetadata.TEMPLATE.value] = image_data[
                Exiv.OBJECT_NAME.value]

        # Write the size/HTML out before we reduce the image to a thumb
        content = "<img src='{src}' alt='{alt}' style='width: {width}px; height: auto; max-width: 100%;'></img><p>{body}</p>" \
            .format(src=original_name, alt=title, width=img.width, height=img.height, body=description_long)

        # Ensure the directory levels exist
        if not isdir(path_output_dir):
            makedirs(path_output_dir)
        img.save(path_output_original)
        img.thumbnail(self.thumb_size)
        img.save(path_output_thumb)

        # Debug info if we need it
        JpegReader.logger.debug(content)
        JpegReader.logger.debug(str(metadata))
        JpegReader.logger.debug(path_output_html)

        return content, metadata
Пример #15
0
    def _link_replacer(self, siteurl, m):
        what = m.group('what')
        value = urlparse(m.group('value'))
        path = value.path
        origin = m.group('path')

        # urllib.parse.urljoin() produces `a.html` for urljoin("..", "a.html")
        # so if RELATIVE_URLS are enabled, we fall back to os.path.join() to
        # properly get `../a.html`. However, os.path.join() produces
        # `baz/http://foo/bar.html` for join("baz", "http://foo/bar.html")
        # instead of correct "http://foo/bar.html", so one has to pick a side
        # as there is no silver bullet.
        if self.settings['RELATIVE_URLS']:
            joiner = os.path.join
        else:
            joiner = urljoin

            # However, it's not *that* simple: urljoin("blog", "index.html")
            # produces just `index.html` instead of `blog/index.html` (unlike
            # os.path.join()), so in order to get a correct answer one needs to
            # append a trailing slash to siteurl in that case. This also makes
            # the new behavior fully compatible with Pelican 3.7.1.
            if not siteurl.endswith('/'):
                siteurl += '/'

        # XXX Put this in a different location.
        if what in {'filename', 'attach'}:
            if path.startswith('/'):
                path = path[1:]
            else:
                # relative to the source path of this content
                path = self.get_relative_source_path(
                    os.path.join(self.relative_dir, path))

            if path not in self._context['filenames']:
                unquoted_path = path.replace('%20', ' ')

                if unquoted_path in self._context['filenames']:
                    path = unquoted_path

            linked_content = self._context['filenames'].get(path)
            if linked_content:
                if what == 'attach':
                    if isinstance(linked_content, Static):
                        linked_content.attach_to(self)
                    else:
                        logger.warning(
                            "%s used {attach} link syntax on a "
                            "non-static file. Use {filename} instead.",
                            self.get_relative_source_path())
                origin = joiner(siteurl, linked_content.url)
                origin = origin.replace('\\', '/')  # for Windows paths.
            else:
                logger.warning(
                    "Unable to find '%s', skipping url replacement.",
                    value.geturl(),
                    extra={
                        'limit_msg': ("Other resources were not found "
                                      "and their urls not replaced")
                    })
        elif what == 'category':
            origin = joiner(siteurl, Category(path, self.settings).url)
        elif what == 'tag':
            origin = joiner(siteurl, Tag(path, self.settings).url)
        elif what == 'index':
            origin = joiner(siteurl, self.settings['INDEX_SAVE_AS'])
        elif what == 'author':
            origin = joiner(siteurl, Author(path, self.settings).url)
        else:
            logger.warning(
                "Replacement Indicator '%s' not recognized, "
                "skipping replacement", what)

        # keep all other parts, such as query, fragment, etc.
        parts = list(value)
        parts[2] = origin
        origin = urlunparse(parts)

        return ''.join(
            (m.group('markup'), m.group('quote'), origin, m.group('quote')))