예제 #1
0
    def write_feed(self,
                   elements,
                   context,
                   path=None,
                   url=None,
                   feed_type='atom',
                   override_output=False,
                   feed_title=None):
        """Generate a feed with the list of articles provided

        Return the feed. If no path or output_path is specified, just
        return the feed object.

        :param elements: the articles to put on the feed.
        :param context: the context to get the feed metadata.
        :param path: the path to output.
        :param url: the publicly visible feed URL; if None, path is used
            instead
        :param feed_type: the feed type to use (atom or rss)
        :param override_output: boolean telling if we can override previous
            output with the same name (and if next files written with the same
            name should be skipped to keep that one)
        :param feed_title: the title of the feed.o
        """
        if not is_selected_for_writing(self.settings, path):
            return

        self.site_url = context.get('SITEURL',
                                    path_to_url(get_relative_path(path)))

        self.feed_domain = context.get('FEED_DOMAIN')
        self.feed_url = self.urljoiner(self.feed_domain, url if url else path)

        feed = self._create_new_feed(feed_type, feed_title, context)

        max_items = len(elements)
        if self.settings['FEED_MAX_ITEMS']:
            max_items = min(self.settings['FEED_MAX_ITEMS'], max_items)
        for i in range(max_items):
            self._add_item_to_the_feed(feed, elements[i])

        signals.feed_generated.send(context, feed=feed)
        if path:
            complete_path = sanitised_join(self.output_path, path)

            try:
                os.makedirs(os.path.dirname(complete_path))
            except Exception:
                pass

            encoding = 'utf-8' if six.PY3 else None
            with self._open_w(complete_path, encoding, override_output) as fp:
                feed.write(fp, 'utf-8')
                logger.info('Writing %s', complete_path)

            signals.feed_written.send(complete_path,
                                      context=context,
                                      feed=feed)
        return feed
예제 #2
0
    def write_feed(self,
                   elements,
                   context,
                   path=None,
                   feed_type='atom',
                   feed_title=None):
        """Generate a feed with the list of articles provided

        Return the feed. If no path or output_path is specified, just
        return the feed object.

        :param elements: the articles to put on the feed.
        :param context: the context to get the feed metadata.
        :param path: the path to output.
        :param feed_type: the feed type to use (atom or rss)
        :param feed_title: the title of the feed.
        """
        if not is_selected_for_writing(self.settings, path):
            return
        old_locale = locale.setlocale(locale.LC_ALL)
        locale.setlocale(locale.LC_ALL, str('C'))
        try:
            self.site_url = context.get('SITEURL',
                                        path_to_url(get_relative_path(path)))

            self.feed_domain = context.get('FEED_DOMAIN')
            self.feed_url = '{}/{}'.format(self.feed_domain, path)

            feed = self._create_new_feed(feed_type, feed_title, context)

            max_items = len(elements)
            if self.settings['FEED_MAX_ITEMS']:
                max_items = min(self.settings['FEED_MAX_ITEMS'], max_items)
            for i in range(max_items):
                self._add_item_to_the_feed(feed, elements[i])

            if path:
                complete_path = os.path.join(self.output_path, path)
                try:
                    os.makedirs(os.path.dirname(complete_path))
                except Exception:
                    pass

                encoding = 'utf-8' if six.PY3 else None
                with self._open_w(complete_path, encoding) as fp:
                    feed.write(fp, 'utf-8')
                    logger.info('Writing %s', complete_path)

                signals.feed_written.send(complete_path,
                                          context=context,
                                          feed=feed)
            return feed
        finally:
            locale.setlocale(locale.LC_ALL, old_locale)
예제 #3
0
파일: writers.py 프로젝트: Starch/pelican
    def write_feed(self, elements, context, path=None, url=None,
                   feed_type='atom', override_output=False, feed_title=None):
        """Generate a feed with the list of articles provided

        Return the feed. If no path or output_path is specified, just
        return the feed object.

        :param elements: the articles to put on the feed.
        :param context: the context to get the feed metadata.
        :param path: the path to output.
        :param url: the publicly visible feed URL; if None, path is used
            instead
        :param feed_type: the feed type to use (atom or rss)
        :param override_output: boolean telling if we can override previous
            output with the same name (and if next files written with the same
            name should be skipped to keep that one)
        :param feed_title: the title of the feed.o
        """
        if not is_selected_for_writing(self.settings, path):
            return

        self.site_url = context.get(
            'SITEURL', path_to_url(get_relative_path(path)))

        self.feed_domain = context.get('FEED_DOMAIN')
        self.feed_url = self.urljoiner(self.feed_domain, url if url else path)

        feed = self._create_new_feed(feed_type, feed_title, context)

        max_items = len(elements)
        if self.settings['FEED_MAX_ITEMS']:
            max_items = min(self.settings['FEED_MAX_ITEMS'], max_items)
        for i in range(max_items):
            self._add_item_to_the_feed(feed, elements[i])

        signals.feed_generated.send(context, feed=feed)
        if path:
            complete_path = sanitised_join(self.output_path, path)

            try:
                os.makedirs(os.path.dirname(complete_path))
            except Exception:
                pass

            encoding = 'utf-8' if six.PY3 else None
            with self._open_w(complete_path, encoding, override_output) as fp:
                feed.write(fp, 'utf-8')
                logger.info('Writing %s', complete_path)

            signals.feed_written.send(
                complete_path, context=context, feed=feed)
        return feed
예제 #4
0
    def write_feed(self, elements, context, path=None, feed_type='atom',
                   feed_title=None):
        """Generate a feed with the list of articles provided

        Return the feed. If no path or output_path is specified, just
        return the feed object.

        :param elements: the articles to put on the feed.
        :param context: the context to get the feed metadata.
        :param path: the path to output.
        :param feed_type: the feed type to use (atom or rss)
        :param feed_title: the title of the feed.
        """
        if not is_selected_for_writing(self.settings, path):
            return
        old_locale = locale.setlocale(locale.LC_ALL)
        locale.setlocale(locale.LC_ALL, str('C'))
        try:
            self.site_url = context.get(
                'SITEURL', path_to_url(get_relative_path(path)))

            self.feed_domain = context.get('FEED_DOMAIN')
            self.feed_url = '{}/{}'.format(self.feed_domain, path)

            feed = self._create_new_feed(feed_type, feed_title, context)

            max_items = len(elements)
            if self.settings['FEED_MAX_ITEMS']:
                max_items = min(self.settings['FEED_MAX_ITEMS'], max_items)
            for i in range(max_items):
                self._add_item_to_the_feed(feed, elements[i])

            if path:
                complete_path = os.path.join(self.output_path, path)
                try:
                    os.makedirs(os.path.dirname(complete_path))
                except Exception:
                    pass

                encoding = 'utf-8' if six.PY3 else None
                with self._open_w(complete_path, encoding) as fp:
                    feed.write(fp, 'utf-8')
                    logger.info('Writing %s', complete_path)

                signals.feed_written.send(complete_path, context=context, feed=feed)
            return feed
        finally:
            locale.setlocale(locale.LC_ALL, old_locale)
예제 #5
0
    def write_file(self, name, template, context, relative_urls=False,
                   paginated=None, template_name=None, override_output=False,
                   url=None, **kwargs):
        """Render the template and write the file.

        :param name: name of the file to output
        :param template: template to use to generate the content
        :param context: dict to pass to the templates.
        :param relative_urls: use relative urls or absolutes ones
        :param paginated: dict of article list to paginate - must have the
            same length (same list in different orders)
        :param template_name: the template name, for pagination
        :param override_output: boolean telling if we can override previous
            output with the same name (and if next files written with the same
            name should be skipped to keep that one)
        :param url: url of the file (needed by the paginator)
        :param **kwargs: additional variables to pass to the templates
        """

        if name is False or \
           name == "" or \
           not is_selected_for_writing(self.settings,
                                       os.path.join(self.output_path, name)):
            return
        elif not name:
            # other stuff, just return for now
            return

        def _write_file(template, localcontext, output_path, name, override):
            """Render the template write the file."""
            # set localsiteurl for context so that Contents can adjust links
            if localcontext['localsiteurl']:
                context['localsiteurl'] = localcontext['localsiteurl']
            output = template.render(localcontext)
            path = sanitised_join(output_path, name)

            try:
                os.makedirs(os.path.dirname(path))
            except Exception:
                pass

            with self._open_w(path, 'utf-8', override=override) as f:
                f.write(output)
            logger.info('Writing %s', path)

            # Send a signal to say we're writing a file with some specific
            # local context.
            signals.content_written.send(path, context=localcontext)

        def _get_localcontext(context, name, kwargs, relative_urls):
            localcontext = context.copy()
            localcontext['localsiteurl'] = localcontext.get(
                'localsiteurl', None)
            if relative_urls:
                relative_url = path_to_url(get_relative_path(name))
                localcontext['SITEURL'] = relative_url
                localcontext['localsiteurl'] = relative_url
            localcontext['output_file'] = name
            localcontext.update(kwargs)
            return localcontext

        if paginated is None:
            paginated = {key: val for key, val in kwargs.items()
                         if key in {'articles', 'dates'}}

        # pagination
        if paginated and template_name in self.settings['PAGINATED_TEMPLATES']:
            # pagination needed
            per_page = self.settings['PAGINATED_TEMPLATES'][template_name] \
                or self.settings['DEFAULT_PAGINATION']

            # init paginators
            paginators = {key: Paginator(name, url, val, self.settings,
                                         per_page)
                          for key, val in paginated.items()}

            # generated pages, and write
            for page_num in range(list(paginators.values())[0].num_pages):
                paginated_kwargs = kwargs.copy()
                for key in paginators.keys():
                    paginator = paginators[key]
                    previous_page = paginator.page(page_num) \
                        if page_num > 0 else None
                    page = paginator.page(page_num + 1)
                    next_page = paginator.page(page_num + 2) \
                        if page_num + 1 < paginator.num_pages else None
                    paginated_kwargs.update(
                        {'%s_paginator' % key: paginator,
                         '%s_page' % key: page,
                         '%s_previous_page' % key: previous_page,
                         '%s_next_page' % key: next_page})

                localcontext = _get_localcontext(
                    context, page.save_as, paginated_kwargs, relative_urls)
                _write_file(template, localcontext, self.output_path,
                            page.save_as, override_output)
        else:
            # no pagination
            localcontext = _get_localcontext(
                context, name, kwargs, relative_urls)
            _write_file(template, localcontext, self.output_path, name,
                        override_output)
예제 #6
0
파일: writers.py 프로젝트: 52M/pelican
    def write_file(self, name, template, context, relative_urls=False,
                   paginated=None, override_output=False, **kwargs):
        """Render the template and write the file.

        :param name: name of the file to output
        :param template: template to use to generate the content
        :param context: dict to pass to the templates.
        :param relative_urls: use relative urls or absolutes ones
        :param paginated: dict of article list to paginate - must have the
            same length (same list in different orders)
        :param override_output: boolean telling if we can override previous
            output with the same name (and if next files written with the same
            name should be skipped to keep that one)
        :param **kwargs: additional variables to pass to the templates
        """

        if name is False or \
           name == "" or \
           not is_selected_for_writing(self.settings,
                                       os.path.join(self.output_path, name)):
            return
        elif not name:
            # other stuff, just return for now
            return

        def _write_file(template, localcontext, output_path, name, override):
            """Render the template write the file."""
            # set localsiteurl for context so that Contents can adjust links
            if localcontext['localsiteurl']:
                context['localsiteurl'] = localcontext['localsiteurl']
            output = template.render(localcontext)
            path = os.path.join(output_path, name)
            try:
                os.makedirs(os.path.dirname(path))
            except Exception:
                pass

            with self._open_w(path, 'utf-8', override=override) as f:
                f.write(output)
            logger.info('Writing %s', path)

            # Send a signal to say we're writing a file with some specific
            # local context.
            signals.content_written.send(path, context=localcontext)

        def _get_localcontext(context, name, kwargs, relative_urls):
            localcontext = context.copy()
            localcontext['localsiteurl'] = localcontext.get(
                'localsiteurl', None)
            if relative_urls:
                relative_url = path_to_url(get_relative_path(name))
                localcontext['SITEURL'] = relative_url
                localcontext['localsiteurl'] = relative_url
            localcontext['output_file'] = name
            localcontext.update(kwargs)
            return localcontext

        # pagination
        if paginated:

            # pagination needed, init paginators
            paginators = {key: Paginator(name, val, self.settings)
                          for key, val in paginated.items()}

            # generated pages, and write
            for page_num in range(list(paginators.values())[0].num_pages):
                paginated_kwargs = kwargs.copy()
                for key in paginators.keys():
                    paginator = paginators[key]
                    previous_page = paginator.page(page_num) \
                        if page_num > 0 else None
                    page = paginator.page(page_num + 1)
                    next_page = paginator.page(page_num + 2) \
                        if page_num + 1 < paginator.num_pages else None
                    paginated_kwargs.update(
                        {'%s_paginator' % key: paginator,
                         '%s_page' % key: page,
                         '%s_previous_page' % key: previous_page,
                         '%s_next_page' % key: next_page})

                localcontext = _get_localcontext(
                    context, page.save_as, paginated_kwargs, relative_urls)
                _write_file(template, localcontext, self.output_path,
                            page.save_as, override_output)
        else:
            # no pagination
            localcontext = _get_localcontext(
                context, name, kwargs, relative_urls)
            _write_file(template, localcontext, self.output_path, name,
                        override_output)
예제 #7
0
    def write_file(self, name, template, context, relative_urls=False,
                   paginated=None, override_output=False, **kwargs):
        """Render the template and write the file.

        :param name: name of the file to output
        :param template: template to use to generate the content
        :param context: dict to pass to the templates.
        :param relative_urls: use relative urls or absolutes ones
        :param paginated: dict of article list to paginate - must have the
            same length (same list in different orders)
        :param override_output: boolean telling if we can override previous
            output with the same name (and if next files written with the same
            name should be skipped to keep that one)
        :param **kwargs: additional variables to pass to the templates
        """

        if name is False or name == "" or\
           not is_selected_for_writing(self.settings,\
               os.path.join(self.output_path, name)):
            return
        elif not name:
            # other stuff, just return for now
            return

        def _write_file(template, localcontext, output_path, name, override):
            """Render the template write the file."""
            output = template.render(localcontext)
            path = os.path.join(output_path, name)
            try:
                os.makedirs(os.path.dirname(path))
            except Exception:
                pass

            with self._open_w(path, 'utf-8', override=override) as f:
                f.write(output)
            logger.info('writing {}'.format(path))

            # Send a signal to say we're writing a file with some specific
            # local context.
            signals.content_written.send(path, context=localcontext)

        localcontext = context.copy()
        if relative_urls:
            relative_url = path_to_url(get_relative_path(name))
            context['localsiteurl'] = relative_url
            localcontext['SITEURL'] = relative_url

        localcontext['output_file'] = name
        localcontext.update(kwargs)

        # pagination
        if paginated:

            # pagination needed, init paginators
            paginators = {key: Paginator(name, val, self.settings)
                          for key, val in paginated.items()}

            # generated pages, and write
            for page_num in range(list(paginators.values())[0].num_pages):
                paginated_localcontext = localcontext.copy()
                for key in paginators.keys():
                    paginator = paginators[key]
                    previous_page = paginator.page(page_num) \
                        if page_num > 0 else None
                    page = paginator.page(page_num + 1)
                    next_page = paginator.page(page_num + 2) \
                        if page_num + 1 < paginator.num_pages else None
                    paginated_localcontext.update(
                        {'%s_paginator' % key: paginator,
                         '%s_page' % key: page,
                         '%s_previous_page' % key: previous_page,
                         '%s_next_page' % key: next_page})

                _write_file(template, paginated_localcontext, self.output_path,
                            page.save_as, override_output)
        else:
            # no pagination
            _write_file(template, localcontext, self.output_path, name,
                        override_output)
예제 #8
0
    def write_js(self, name, context, override_output=False):
        """Render the template and write the file.

        :param name: name of the index file to output
        :param context: dict to pass to the templates.
        :param override_output: boolean telling if we can override previous
            output with the same name (and if next files written with the same
            name should be skipped to keep that one)
        """

        if (name is False or name == "" or not is_selected_for_writing(
                self.settings, os.path.join(self.output_path, name))):
            return

        if not name:
            return

        def _write_file(output_path, name, override):
            """Write the js file."""

            # output = 'var documents = ' + json.dumps(context['index_data'], indent=2) + ";"
            path = sanitised_join(output_path, name)

            dir = os.path.dirname(path)
            if not os.path.exists(dir):
                os.makedirs(dir)

            idx = lunr(
                ref="ref",
                fields=[
                    {
                        "field_name": "title",
                        "boost": 10
                    },
                    {
                        "field_name": "summary",
                        "boost": 2
                    },
                    "body",
                    "tags",
                ],
                documents=context["index_data"],
            )

            with self._open_w(path, "utf-8", override=override) as handle:
                handle.write("const lunrSerializedIdx = ")
                handle.write(json.dumps(idx.serialize()))
                handle.write(";\n")
                handle.write("const lunrDocuments = ")

                def remove_body():
                    for doc in context["index_data"]:
                        cleaned_doc = dict(doc)
                        del cleaned_doc["body"]
                        yield cleaned_doc

                handle.write(json.dumps([doc for doc in remove_body()]))
                handle.write(";\n")
            logger.info("Writing %s", path)

            # Send a signal to say we're writing a file with some specific
            # local context.
            signals.content_written.send(path, context=context)

        if not context["index_data"]:
            return
        _write_file(self.output_path, name, override_output)