Exemplo n.º 1
0
    def run(self):
        """Run post-list directive."""
        start = self.options.get('start')
        stop = self.options.get('stop')
        reverse = self.options.get('reverse', False)
        tags = self.options.get('tags')
        tags = [t.strip().lower() for t in tags.split(',')] if tags else []
        categories = self.options.get('categories')
        categories = [c.strip().lower()
                      for c in categories.split(',')] if categories else []
        slugs = self.options.get('slugs')
        slugs = [s.strip() for s in slugs.split(',')] if slugs else []
        show_all = self.options.get('all', False)
        lang = self.options.get('lang', utils.LocaleBorg().current_lang)
        template = self.options.get('template', 'post_list_directive.tmpl')
        sort = self.options.get('sort')

        output = _do_post_list(start,
                               stop,
                               reverse,
                               tags,
                               categories,
                               slugs,
                               show_all,
                               lang,
                               template,
                               sort,
                               state=self.state,
                               site=self.site)
        self.state.document.settings.record_dependencies.add(
            "####MAGIC####TIMELINE")
        return [nodes.raw('', output, format='html')]
Exemplo n.º 2
0
    def run(self):
        """Run post-list directive."""
        start = self.options.get('start')
        stop = self.options.get('stop')
        reverse = self.options.get('reverse', False)
        tags = self.options.get('tags')
        categories = self.options.get('categories')
        sections = self.options.get('sections')
        slugs = self.options.get('slugs')
        post_type = self.options.get('post_type')
        type = self.options.get('type', False)
        all = self.options.get('all', False)
        lang = self.options.get('lang', utils.LocaleBorg().current_lang)
        template = self.options.get('template', 'post_list_directive.tmpl')
        sort = self.options.get('sort')
        date = self.options.get('date')

        output, deps = _do_post_list(start, stop, reverse, tags, categories, sections, slugs, post_type, type,
                                     all, lang, template, sort, state=self.state, site=self.site, date=date)
        self.state.document.settings.record_dependencies.add("####MAGIC####TIMELINE")
        for d in deps:
            self.state.document.settings.record_dependencies.add(d)
        if output:
            return [nodes.raw('', output, format='html')]
        else:
            return []
Exemplo n.º 3
0
    def run(self):
        start = self.options.get('start')
        stop = self.options.get('stop')
        reverse = self.options.get('reverse', False)
        tags = self.options.get('tags')
        tags = [t.strip().lower() for t in tags.split(',')] if tags else []
        slugs = self.options.get('slugs')
        slugs = [s.strip() for s in slugs.split(',')] if slugs else []
        show_all = self.options.get('all', False)
        lang = self.options.get('lang', utils.LocaleBorg().current_lang)
        template = self.options.get('template', 'post_list_directive.tmpl')
        if self.site.invariant:  # for testing purposes
            post_list_id = self.options.get('id', 'post_list_' + 'fixedvaluethatisnotauuid')
        else:
            post_list_id = self.options.get('id', 'post_list_' + uuid.uuid4().hex)

        posts = []
        step = -1 if reverse is None else None
        if show_all is None:
            timeline = [p for p in self.site.timeline]
        else:
            timeline = [p for p in self.site.timeline if p.use_in_feeds]

        for post in timeline[start:stop:step]:
            if tags:
                cont = True
                for tag in tags:
                    if tag in [t.lower() for t in post.tags]:
                        cont = False

                if cont:
                    continue

            if slugs:
                cont = True
                for slug in slugs:
                    if slug == post.meta('slug'):
                        cont = False

                if cont:
                    continue

            posts += [post]

        if not posts:
            return []

        template_data = {
            'lang': lang,
            'posts': posts,
            'date_format': self.site.GLOBAL_CONTEXT.get('date_format'),
            'post_list_id': post_list_id,
        }
        output = self.site.template_system.render_template(
            template, None, template_data)
        return [nodes.raw('', output, format='html')]
Exemplo n.º 4
0
 def set_site(self, site):
     self.site = site
     if self.site.config['DATE_FANCINESS'] == 0 and not self.site.config.get('BABEL_DATE_FORMAT') is None:
         babel_date_format = utils.TranslatableSetting(
             'BABEL_DATE_FORMAT', self.site.config['BABEL_DATE_FORMAT'], self.site.config['TRANSLATIONS'])
         for lang in self.site.config['TRANSLATIONS']:
             try:
                 self.site.config['DATE_FORMAT'][lang] = babel_date_format(
                     lang)
             except KeyError:
                 self.site.config['DATE_FORMAT'][lang] = 'medium'
         utils.LocaleBorg().add_handler(formatted_date_handler=self.babel_date_formatter)
     super(BabelDates, self).set_site(site)
Exemplo n.º 5
0
    def _build_month_post_list(self, lang):
        """Create a list of months."""
        try:
            months = list(self.site.posts_per_month.keys())
            months = sorted(months, reverse=True)
            month_list = []
            for item in months:
                year, month = [int(part) for part in item.split('/')]
                month_name = utils.LocaleBorg().get_month_name(month, lang)
                month_page = Month_Page("{} {}".format(month_name, year), item)
                month_list.append(month_page)

            return month_list
        except KeyError:
            return None
Exemplo n.º 6
0
    def run(self):
        """Run post-list directive."""
        start = self.options.get('start')
        stop = self.options.get('stop')
        reverse = self.options.get('reverse', False)
        tags = self.options.get('tags')
        require_all_tags = 'require_all_tags' in self.options
        categories = self.options.get('categories')
        sections = self.options.get('sections')
        slugs = self.options.get('slugs')
        post_type = self.options.get('post_type')
        type = self.options.get('type', False)
        lang = self.options.get('lang', utils.LocaleBorg().current_lang)
        template = self.options.get('template', 'post_list_directive.tmpl')
        sort = self.options.get('sort')
        date = self.options.get('date')
        filename = self.state.document.settings._nikola_source_path

        output, deps = self.site.plugin_manager.getPluginByName(
            'post_list',
            'ShortcodePlugin').plugin_object.handler(start,
                                                     stop,
                                                     reverse,
                                                     tags,
                                                     require_all_tags,
                                                     categories,
                                                     sections,
                                                     slugs,
                                                     post_type,
                                                     type,
                                                     lang,
                                                     template,
                                                     sort,
                                                     state=self.state,
                                                     site=self.site,
                                                     date=date,
                                                     filename=filename)
        self.state.document.settings.record_dependencies.add(
            "####MAGIC####TIMELINE")
        for d in deps:
            self.state.document.settings.record_dependencies.add(d)
        if output:
            return [nodes.raw('', output, format='html')]
        else:
            return []
Exemplo n.º 7
0
 def formatted_date(self, date_format, date=None):
     """Return the formatted date as unicode."""
     return utils.LocaleBorg().formatted_date(date_format,
                                              date if date else self.date)
Exemplo n.º 8
0
    def run(self):
        start = self.options.get('start')
        stop = self.options.get('stop')
        reverse = self.options.get('reverse', False)
        tags = self.options.get('tags')
        tags = [t.strip().lower() for t in tags.split(',')] if tags else []
        slugs = self.options.get('slugs')
        slugs = [s.strip() for s in slugs.split(',')] if slugs else []
        show_all = self.options.get('all', False)
        lang = self.options.get('lang', utils.LocaleBorg().current_lang)
        template = self.options.get('template', 'post_list_directive.tmpl')
        sort = self.options.get('sort')
        if self.site.invariant:  # for testing purposes
            post_list_id = self.options.get(
                'id', 'post_list_' + 'fixedvaluethatisnotauuid')
        else:
            post_list_id = self.options.get('id',
                                            'post_list_' + uuid.uuid4().hex)

        filtered_timeline = []
        posts = []
        step = -1 if reverse is None else None
        if show_all is None:
            timeline = [p for p in self.site.timeline]
        else:
            timeline = [p for p in self.site.timeline if p.use_in_feeds]

        for post in timeline:
            if tags:
                cont = True
                tags_lower = [t.lower() for t in post.tags]
                for tag in tags:
                    if tag in tags_lower:
                        cont = False

                if cont:
                    continue

            filtered_timeline.append(post)

        if sort:
            filtered_timeline = natsorted(
                filtered_timeline, key=lambda post: post.meta[lang][sort])

        for post in filtered_timeline[start:stop:step]:
            if slugs:
                cont = True
                for slug in slugs:
                    if slug == post.meta('slug'):
                        cont = False

                if cont:
                    continue

            bp = post.translated_base_path(lang)
            if os.path.exists(bp):
                self.state.document.settings.record_dependencies.add(bp)

            posts += [post]

        if not posts:
            return []

        template_data = {
            'lang': lang,
            'posts': posts,
            'date_format': self.site.GLOBAL_CONTEXT.get('date_format'),
            'post_list_id': post_list_id,
        }
        output = self.site.template_system.render_template(
            template, None, template_data)
        return [nodes.raw('', output, format='html')]
Exemplo n.º 9
0
    def generate_feed(self, lang, title, link, description, timeline,
                      feed_url, output_name, primary_author=None):
        """Generate a feed and write it to file."""
        utils.LocaleBorg().set_locale(lang)
        items = []
        for post in timeline:
            item = {
                "id": post.guid(lang),
                "url": post.permalink(lang),
                "title": post.title(lang),
                "date_published": post.date.replace(microsecond=0).isoformat(),
                "date_modified": post.updated.replace(microsecond=0).isoformat(),
                "author": {
                    "name": post.author(lang),
                    "url": self.site.link("author", post.author(lang), lang)
                },
                "tags": post.tags_for_language(lang),
            }

            if post.updated == post.date:
                del item["date_modified"]

            link = post.meta[lang].get('link')
            if link:
                item['external_url'] = link

            previewimage = post.meta[lang].get('previewimage')
            if previewimage:
                item['image'] = self.site.url_replacer(post.permalink(), previewimage, lang, 'absolute')

            if self.kw['feed_plain']:
                strip_html = True
                content_tag = "content_text"
            else:
                strip_html = False
                content_tag = "content_html"

            data = post.text(lang, self.kw['feed_teasers'], strip_html, True, True, self.kw['feed_links_append_query'])

            if feed_url is not None and data:
                # Copied from nikola.py
                # Massage the post's HTML (unless plain)
                if not strip_html:
                    if self.kw["feed_previewimage"] and 'previewimage' in post.meta[lang] and post.meta[lang]['previewimage'] not in data:
                        data = "<figure><img src=\"{}\"></figure> {}".format(post.meta[lang]['previewimage'], data)
                    # FIXME: this is duplicated with code in Post.text()
                    try:
                        doc = lxml.html.document_fromstring(data)
                        doc.rewrite_links(lambda dst: self.site.url_replacer(post.permalink(), dst, lang, 'absolute'))
                        try:
                            body = doc.body
                            data = (body.text or '') + ''.join(
                                [lxml.html.tostring(child, encoding='unicode')
                                 for child in body.iterchildren()])
                        except IndexError:  # No body there, it happens sometimes
                            data = ''
                    except lxml.etree.ParserError as e:
                        if str(e) == "Document is empty":
                            data = ""
                        else:  # let other errors raise
                            raise

            item[content_tag] = data
            items.append(item)

        if not primary_author:
            # Override for author pages
            primary_author = {"name": self.kw['blog_author'](lang)}

        feed = {
            "version": "https://jsonfeed.org/version/1",
            "user_comment": ("This feed allows you to read the posts from this "
                             "site in any feed reader that supports the JSON "
                             "Feed format. To add " "this feed to your reader, "
                             "copy the following URL — " + feed_url +
                             " — and add it your reader."),
            "title": title,
            "home_page_url": self.kw['site_url'],
            "feed_url": feed_url,
            "description": description,
            "author": primary_author,
            "items": items
        }

        utils.makedirs(os.path.dirname(output_name))

        with io.open(output_name, 'w', encoding='utf-8') as fh:
            json.dump(feed, fh, ensure_ascii=False, indent=4)
Exemplo n.º 10
0
def _do_post_list(start=None, stop=None, reverse=False, tags=None, categories=None,
                  sections=None, slugs=None, post_type='post', type=False, all=False,
                  lang=None, template='post_list_directive.tmpl', sort=None,
                  id=None, data=None, state=None, site=None, date=None, filename=None, post=None):
    if lang is None:
        lang = utils.LocaleBorg().current_lang
    if site.invariant:  # for testing purposes
        post_list_id = id or 'post_list_' + 'fixedvaluethatisnotauuid'
    else:
        post_list_id = id or 'post_list_' + uuid.uuid4().hex

    # Get post from filename if available
    if filename:
        self_post = site.post_per_input_file.get(filename)
    else:
        self_post = None

    if self_post:
        self_post.register_depfile("####MAGIC####TIMELINE", lang=lang)

    # If we get strings for start/stop, make them integers
    if start is not None:
        start = int(start)
    if stop is not None:
        stop = int(stop)

    # Parse tags/categories/sections/slugs (input is strings)
    tags = [t.strip().lower() for t in tags.split(',')] if tags else []
    categories = [c.strip().lower() for c in categories.split(',')] if categories else []
    sections = [s.strip().lower() for s in sections.split(',')] if sections else []
    slugs = [s.strip() for s in slugs.split(',')] if slugs else []

    filtered_timeline = []
    posts = []
    step = -1 if reverse is None else None

    if type is not False:
        post_type = type

    # TODO: remove in v8
    if all is not False:
        timeline = [p for p in site.timeline]
    elif post_type == 'page' or post_type == 'pages':
        timeline = [p for p in site.timeline if not p.use_in_feeds]
    elif post_type == 'all':
        timeline = [p for p in site.timeline]
    else:  # post
        timeline = [p for p in site.timeline if p.use_in_feeds]

    # TODO: replaces all, uncomment in v8
    # if post_type == 'page' or post_type == 'pages':
    #    timeline = [p for p in site.timeline if not p.use_in_feeds]
    # elif post_type == 'all':
    #    timeline = [p for p in site.timeline]
    # else: # post
    #    timeline = [p for p in site.timeline if p.use_in_feeds]

    if categories:
        timeline = [p for p in timeline if p.meta('category', lang=lang).lower() in categories]

    if sections:
        timeline = [p for p in timeline if p.section_name(lang).lower() in sections]

    for post in timeline:
        if tags:
            cont = True
            tags_lower = [t.lower() for t in post.tags]
            for tag in tags:
                if tag in tags_lower:
                    cont = False

            if cont:
                continue

        filtered_timeline.append(post)

    if sort:
        filtered_timeline = natsort.natsorted(filtered_timeline, key=lambda post: post.meta[lang][sort], alg=natsort.ns.F | natsort.ns.IC)

    if date:
        filtered_timeline = [p for p in filtered_timeline if date_in_range(date, p.date)]

    for post in filtered_timeline[start:stop:step]:
        if slugs:
            cont = True
            for slug in slugs:
                if slug == post.meta('slug'):
                    cont = False

            if cont:
                continue

        bp = post.translated_base_path(lang)
        if os.path.exists(bp) and state:
            state.document.settings.record_dependencies.add(bp)
        elif os.path.exists(bp) and self_post:
            self_post.register_depfile(bp, lang=lang)

        posts += [post]

    if not posts:
        return '', []

    template_deps = site.template_system.template_deps(template)
    if state:
        # Register template as a dependency (Issue #2391)
        for d in template_deps:
            state.document.settings.record_dependencies.add(d)
    elif self_post:
        for d in template_deps:
            self_post.register_depfile(d, lang=lang)

    template_data = {
        'lang': lang,
        'posts': posts,
        # Need to provide str, not TranslatableSetting (Issue #2104)
        'date_format': site.GLOBAL_CONTEXT.get('date_format')[lang],
        'post_list_id': post_list_id,
        'messages': site.MESSAGES,
    }
    output = site.template_system.render_template(
        template, None, template_data)
    return output, template_deps
Exemplo n.º 11
0
    def handler(self, start=None, stop=None, reverse=False, tags=None, require_all_tags=False, categories=None,
                sections=None, slugs=None, post_type='post', type=False,
                lang=None, template='post_list_directive.tmpl', sort=None,
                id=None, data=None, state=None, site=None, date=None, filename=None, post=None):
        """Generate HTML for post-list."""
        if lang is None:
            lang = utils.LocaleBorg().current_lang
        if site.invariant:  # for testing purposes
            post_list_id = id or 'post_list_' + 'fixedvaluethatisnotauuid'
        else:
            post_list_id = id or 'post_list_' + uuid.uuid4().hex

        # Get post from filename if available
        if filename:
            self_post = site.post_per_input_file.get(filename)
        else:
            self_post = None

        if self_post:
            self_post.register_depfile("####MAGIC####TIMELINE", lang=lang)

        # If we get strings for start/stop, make them integers
        if start is not None:
            start = int(start)
        if stop is not None:
            stop = int(stop)

        # Parse tags/categories/sections/slugs (input is strings)
        categories = [c.strip().lower() for c in categories.split(',')] if categories else []
        sections = [s.strip().lower() for s in sections.split(',')] if sections else []
        slugs = [s.strip() for s in slugs.split(',')] if slugs else []

        filtered_timeline = []
        posts = []
        step = None if reverse is False else -1

        if type is not False:
            post_type = type

        if post_type == 'page' or post_type == 'pages':
            timeline = [p for p in site.timeline if not p.use_in_feeds]
        elif post_type == 'all':
            timeline = [p for p in site.timeline]
        else:  # post
            timeline = [p for p in site.timeline if p.use_in_feeds]

        # self_post should be removed from timeline because this is redundant
        timeline = [p for p in timeline if p.source_path != filename]

        if categories:
            timeline = [p for p in timeline if p.meta('category', lang=lang).lower() in categories]

        if sections:
            timeline = [p for p in timeline if p.section_name(lang).lower() in sections]

        if tags:
            tags = {t.strip().lower() for t in tags.split(',')}
            if require_all_tags:
                compare = set.issubset
            else:
                compare = operator.and_
            for post in timeline:
                post_tags = {t.lower() for t in post.tags}
                if compare(tags, post_tags):
                    filtered_timeline.append(post)
        else:
            filtered_timeline = timeline

        if sort:
            filtered_timeline = natsort.natsorted(filtered_timeline, key=lambda post: post.meta[lang][sort], alg=natsort.ns.F | natsort.ns.IC)

        if date:
            _now = utils.current_time()
            filtered_timeline = [p for p in filtered_timeline if date_in_range(utils.html_unescape(date), p.date, now=_now)]

        for post in filtered_timeline[start:stop:step]:
            if slugs:
                cont = True
                for slug in slugs:
                    if slug == post.meta('slug'):
                        cont = False

                if cont:
                    continue

            bp = post.translated_base_path(lang)
            if os.path.exists(bp) and state:
                state.document.settings.record_dependencies.add(bp)
            elif os.path.exists(bp) and self_post:
                self_post.register_depfile(bp, lang=lang)

            posts += [post]

        if not posts:
            return '', []

        template_deps = site.template_system.template_deps(template)
        if state:
            # Register template as a dependency (Issue #2391)
            for d in template_deps:
                state.document.settings.record_dependencies.add(d)
        elif self_post:
            for d in template_deps:
                self_post.register_depfile(d, lang=lang)

        template_data = {
            'lang': lang,
            'posts': posts,
            # Need to provide str, not TranslatableSetting (Issue #2104)
            'date_format': site.GLOBAL_CONTEXT.get('date_format')[lang],
            'post_list_id': post_list_id,
            'messages': site.MESSAGES,
            '_link': site.link,
        }
        output = site.template_system.render_template(
            template, None, template_data)
        return output, template_deps
Exemplo n.º 12
0
def _do_post_list(start=None, stop=None, reverse=False, tags=None, categories=None,
                  slugs=None, show_all=False, lang=None, template='post_list_directive.tmpl',
                  sort=None, id=None, data=None, state=None, site=None):
    if lang is None:
        lang = utils.LocaleBorg().current_lang
    if site.invariant:  # for testing purposes
        post_list_id = id or 'post_list_' + 'fixedvaluethatisnotauuid'
    else:
        post_list_id = id or 'post_list_' + uuid.uuid4().hex

    filtered_timeline = []
    posts = []
    step = -1 if reverse is None else None
    if show_all is None:
        timeline = [p for p in site.timeline]
    else:
        timeline = [p for p in site.timeline if p.use_in_feeds]

    if categories:
        timeline = [p for p in timeline if p.meta('category', lang=lang).lower() in categories]

    for post in timeline:
        if tags:
            cont = True
            tags_lower = [t.lower() for t in post.tags]
            for tag in tags:
                if tag in tags_lower:
                    cont = False

            if cont:
                continue

        filtered_timeline.append(post)

    if sort:
        filtered_timeline = natsort.natsorted(filtered_timeline, key=lambda post: post.meta[lang][sort], alg=natsort.ns.F | natsort.ns.IC)

    for post in filtered_timeline[start:stop:step]:
        if slugs:
            cont = True
            for slug in slugs:
                if slug == post.meta('slug'):
                    cont = False

            if cont:
                continue

        bp = post.translated_base_path(lang)
        if os.path.exists(bp) and state:
            state.document.settings.record_dependencies.add(bp)

        posts += [post]

    if not posts:
        return []

    template_data = {
        'lang': lang,
        'posts': posts,
        # Need to provide str, not TranslatableSetting (Issue #2104)
        'date_format': site.GLOBAL_CONTEXT.get('date_format')[lang],
        'post_list_id': post_list_id,
        'messages': site.MESSAGES,
    }
    output = site.template_system.render_template(
        template, None, template_data)
    return output
Exemplo n.º 13
0
 def formatted_date(self, date_format):
     """Return the formatted localized date."""
     return utils.LocaleBorg().formatted_date(date_format,
                                              self.date_localized)