changeset 825:c30574f0dadc

Merge pull request #38 from GitHub.
author Ludovic Chabant <ludovic@chabant.com>
date Sun, 05 Feb 2017 22:37:25 -0800
parents ad12a942cadd (diff) e01473c3ea7e (current diff)
children cb39c0dbe5f0
files piecrust/sources/base.py
diffstat 19 files changed, 179 insertions(+), 146 deletions(-) [+]
line wrap: on
line diff
--- a/docs/docs/01_tutorial/01_your-first-blog.md	Tue Dec 27 04:09:38 2016 -0500
+++ b/docs/docs/01_tutorial/01_your-first-blog.md	Sun Feb 05 22:37:25 2017 -0800
@@ -226,7 +226,7 @@
 adjusted with the `site/post_url` setting. By default, it is:
 
     site:
-        post_url: "%year%/%month%/%day%/%slug%
+        post_url: "%year%/%month%/%day%/%slug%"
 
 The post URL format is defined using some keywords surrounded by percent signs,
 as you can see above. The `%year%`, `%month%` and `%day%` keywords should be
@@ -269,7 +269,7 @@
 [yaml]: https://en.wikipedia.org/wiki/YAML
 [slug]: http://en.wikipedia.org/wiki/Semantic_URL#Slug
 [pageconfref]: {{pcurl('docs/reference/page-config')}}
-[siteconfref]: {{pcurl('docs/reference/site-config')}}
+[siteconfref]: {{pcurl('docs/reference/website-config')}}
 [part2]: {{pcurl('docs/tutorial/making-things-pretty')}}
 [routes]: {{docurl('content-model/routes')}}
 [tpl]: {{docurl('content/templating')}}
--- a/docs/docs/01_tutorial/02_making-things-pretty.md	Tue Dec 27 04:09:38 2016 -0500
+++ b/docs/docs/01_tutorial/02_making-things-pretty.md	Sun Feb 05 22:37:25 2017 -0800
@@ -28,7 +28,7 @@
     templates/post.html
 
 All of those files have been copied into your website's directory -- and it will
-warn you if it was every going to overwrite some of your own files.
+warn you if it was ever going to overwrite some of your own files.
 
 There are a few files we'll be editing here:
 
--- a/docs/docs/02_general/01_chef.md	Tue Dec 27 04:09:38 2016 -0500
+++ b/docs/docs/02_general/01_chef.md	Sun Feb 05 22:37:25 2017 -0800
@@ -64,7 +64,7 @@
 * `--config-set <name> <value>` lets you override _a specific configuration
   setting_.
 
-[3]: {{docurl('general/website-config')}}
+[3]: {{docurl('general/website-configuration')}}
 
 
 ### Logging
--- a/docs/docs/03_content.md	Tue Dec 27 04:09:38 2016 -0500
+++ b/docs/docs/03_content.md	Sun Feb 05 22:37:25 2017 -0800
@@ -3,7 +3,7 @@
 ---
 
 This section of the documentation explains how to write, or otherwise create and
-us, content for PieCrust websites -- pages, layouts, assets, etc. If however you
+use, content for PieCrust websites -- pages, layouts, assets, etc. If however you
 want to *define* what *types* of content your website will have in the first
 place, you may want to read up on the [content model documentation][cm].
 
--- a/docs/docs/03_content/01_creating-pages.md	Tue Dec 27 04:09:38 2016 -0500
+++ b/docs/docs/03_content/01_creating-pages.md	Sun Feb 05 22:37:25 2017 -0800
@@ -4,8 +4,8 @@
 
 In PieCrust, creating pages is a matter of creating a text file in the correct
 place with the correct name. This mostly depends on the [page sources][src]
-you're using, but we can go over how it works for the sources involved in the
-[default content model][dcm].
+you're using, but we can go over how it works for the sources involved in
+the [default content model][dcm].
 
 We will also mention the `chef prepare` command, which semi-automates the
 process of creating pages by letting you type a lot less than what would be
--- a/docs/docs/03_content/03_formatters.md	Tue Dec 27 04:09:38 2016 -0500
+++ b/docs/docs/03_content/03_formatters.md	Sun Feb 05 22:37:25 2017 -0800
@@ -6,8 +6,8 @@
 contents that you write go through a _formatter_ before the page is rendered or
 baked. PieCrust ships with 2 standard formatters: [Markdown][] and [Textile][].
 
-The formatter used on a page is determined by the `format` setting in the page's
-[configuration header][pageconf]:
+The formatter used on a page is determined by the `format` setting in the
+page's [configuration header][pageconf]:
 
     * `markdown` for Markdown
     * `textile` for Textile
@@ -25,7 +25,7 @@
 
 [how]: {{docurl('general/how-it-works')}}
 [pageconf]: {{docurl('content/page-configuration')}}
-[siteconf]: {{docurl('general/site-configuration')}}
+[siteconf]: {{docurl('general/website-configuration')}}
 [markdown]: https://en.wikipedia.org/wiki/Markdown
 [textile]: https://en.wikipedia.org/wiki/Textile_(markup_language)
 
--- a/docs/docs/03_content/04_templating.md	Tue Dec 27 04:09:38 2016 -0500
+++ b/docs/docs/03_content/04_templating.md	Sun Feb 05 22:37:25 2017 -0800
@@ -5,7 +5,7 @@
 As explained in the documentation about [how PieCrust works][how], the page
 contents that you write go through a _templating_ phase, which is when a page
 can execute some logic, insert reusable bits of markup, or reference other
-pieces of content or metadata from elsewhere in you website.
+pieces of content or metadata from elsewhere in your website.
 
 PieCrust uses [Jinja][] for templating. There's too much data exposed to it to
 go over on this page, but check out the [templating data reference][dataref] for
@@ -55,7 +55,7 @@
 
 [how]: {{docurl('general/how-it-works')}}
 [pageconf]: {{docurl('content/page-configuration')}}
-[siteconf]: {{docurl('general/site-configuration')}}
+[siteconf]: {{docurl('general/website-configuration')}}
 [dataref]: {{docurl('reference/templating-data')}}
 [assets]: {{docurl('content/assets')}}
 [jinja]: http://jinja.pocoo.org/docs/dev/templates/
--- a/docs/docs/03_content/05_content-segments.md	Tue Dec 27 04:09:38 2016 -0500
+++ b/docs/docs/03_content/05_content-segments.md	Sun Feb 05 22:37:25 2017 -0800
@@ -39,7 +39,7 @@
     ---sidebar---
     Sidebar goes here
 
-You can them use, the page's layout, both the `content` and `sidebar` segments
+You can then use, the page's layout, both the `content` and `sidebar` segments
 to put each piece of text in its appropriate place.
 
 You can also specify a [formatter][] for a given segment, by adding `:formatter`
--- a/docs/docs/03_content/08_iterators.md	Tue Dec 27 04:09:38 2016 -0500
+++ b/docs/docs/03_content/08_iterators.md	Sun Feb 05 22:37:25 2017 -0800
@@ -4,8 +4,8 @@
 ---
 
 PieCrust returns _iterator objects_ as template data in several cases:
-`pagination.posts`, `assets`, `site.pages`, etc. Any time there's a list of
-_stuff_, you can bet it's returned as an _iterator object_.
+`pagination.posts`, `assets`, `site.pages`, etc. Any time there's a list
+of _stuff_, you can bet it's returned as an _iterator object_.
 
 At first glance, there's not much difference with a simple list:
 
--- a/docs/docs/04_content-model/03_generators.md	Tue Dec 27 04:09:38 2016 -0500
+++ b/docs/docs/04_content-model/03_generators.md	Sun Feb 05 22:37:25 2017 -0800
@@ -16,8 +16,8 @@
   generators:
     my_archives:
       type: blog_archives
-        source: posts
-        page: 'page:_year.md'
+      source: posts
+      page: 'page:_year.md'
 ```
 
 The only required setting for a generator is the `type` setting, which specifies
--- a/docs/docs/05_asset-pipeline.md	Tue Dec 27 04:09:38 2016 -0500
+++ b/docs/docs/05_asset-pipeline.md	Sun Feb 05 22:37:25 2017 -0800
@@ -27,7 +27,7 @@
 * Process it, if it matches any of the active asset processors. The output of
   the processing phase will be put in the output directory.
 
-* Copy it as is, if not asset processor was found. Just like for processing, the
+* Copy it as is, if no asset processor was found. Just like for processing, the
   relative path of the asset is preserved in the output directory.
 
 
@@ -45,7 +45,7 @@
 processors match and the `copy` processor copies the result to the output(s)
 directory.
 
-So for instance, you if you have a LessCSS file, it will be processed like so:
+So for instance, if you have a LessCSS file, it will be processed like so:
 
     foo.less    ->    foo.css    ->    foo.min.css
 
--- a/docs/docs/06_themes.md	Tue Dec 27 04:09:38 2016 -0500
+++ b/docs/docs/06_themes.md	Sun Feb 05 22:37:25 2017 -0800
@@ -3,7 +3,7 @@
 ---
 
 Themes let you change your website's appearance easily by applying a new set of
-templates, layouts, and styles over you content. You're probably already
+templates, layouts, and styles over your content. You're probably already
 familiar with this concept if you're coming from some other CMS like WordPress.
 
 In PieCrust, themes work better if you don't have any templates -- otherwise,
--- a/docs/pages/getting-started.md	Tue Dec 27 04:09:38 2016 -0500
+++ b/docs/pages/getting-started.md	Sun Feb 05 22:37:25 2017 -0800
@@ -152,8 +152,7 @@
 website being served from there.
 
 
-That's it! This is an extremely quick tour of PieCrust. Read the
-[documentation][doc] to learn more.
+That's it! This is an extremely quick tour of PieCrust. Read the [documentation][doc] to learn more.
 
 
 [1]: https://www.python.org/downloads/
--- a/piecrust/baking/worker.py	Tue Dec 27 04:09:38 2016 -0500
+++ b/piecrust/baking/worker.py	Sun Feb 05 22:37:25 2017 -0800
@@ -231,7 +231,7 @@
                     qp, previous_entry, dirty_source_names, gen_name)
             result['sub_entries'] = sub_entries
 
-        except BakingError as ex:
+        except Exception as ex:
             logger.debug("Got baking error. Sending it to master.")
             result['errors'] = _get_errors(ex)
             if self.ctx.app.debug:
--- a/piecrust/data/provider.py	Tue Dec 27 04:09:38 2016 -0500
+++ b/piecrust/data/provider.py	Sun Feb 05 22:37:25 2017 -0800
@@ -1,10 +1,21 @@
 import time
 import collections.abc
+from piecrust.configuration import ConfigurationError
 from piecrust.data.iterators import PageIterator
 from piecrust.generation.taxonomy import Taxonomy
 from piecrust.sources.array import ArraySource
 
 
+def get_data_provider_class(app, provider_type):
+    if not provider_type:
+        raise Exception("No data provider type specified.")
+    for prov in app.plugin_loader.getDataProviders():
+        if prov.PROVIDER_NAME == provider_type:
+            return prov
+    raise ConfigurationError(
+        "Unknown data provider type: %s" % provider_type)
+
+
 class DataProvider(object):
     debug_render_dynamic = []
     debug_render_invoke_dynamic = []
--- a/piecrust/data/providersdata.py	Tue Dec 27 04:09:38 2016 -0500
+++ b/piecrust/data/providersdata.py	Sun Feb 05 22:37:25 2017 -0800
@@ -27,13 +27,14 @@
             return
 
         self._dict = {}
-        for source in self._page.app.sources:
-            endpoint_bits = re_endpoint_sep.split(source.data_endpoint)
-            endpoint = self._dict
-            for e in endpoint_bits[:-1]:
-                if e not in endpoint:
-                    endpoint[e] = {}
-                endpoint = endpoint[e]
-            override = endpoint.get(endpoint_bits[-1])
-            provider = source.buildDataProvider(self._page, override)
-            endpoint[endpoint_bits[-1]] = provider
+        for source in self._page.app.sources + self._page.app.generators:
+            if source.data_endpoint:
+                endpoint_bits = re_endpoint_sep.split(source.data_endpoint)
+                endpoint = self._dict
+                for e in endpoint_bits[:-1]:
+                    if e not in endpoint:
+                        endpoint[e] = {}
+                    endpoint = endpoint[e]
+                override = endpoint.get(endpoint_bits[-1])
+                provider = source.buildDataProvider(self._page, override)
+                endpoint[endpoint_bits[-1]] = provider
--- a/piecrust/generation/base.py	Tue Dec 27 04:09:38 2016 -0500
+++ b/piecrust/generation/base.py	Sun Feb 05 22:37:25 2017 -0800
@@ -125,6 +125,15 @@
                     "Generator '%s' requires a listing page ref." % name)
         self.page_ref = PageRef(app, page_ref)
 
+        self.data_endpoint = config.get('data_endpoint')
+        self.data_type = config.get('data_type')
+        if self.data_endpoint and not self.data_type:
+            raise ConfigurationError(
+                "Generator '%s' requires a data type because it has "
+                "a data endpoint." % name)
+
+        self._provider_type = None
+
     @cached_property
     def source(self):
         for src in self.app.sources:
@@ -146,3 +155,9 @@
     def onRouteFunctionUsed(self, route, route_metadata):
         pass
 
+    def buildDataProvider(self, page, override):
+        if not self._provider_type:
+            from piecrust.data.provider import get_data_provider_class
+            self._provider_type = get_data_provider_class(self.app,
+                                                          self.data_type)
+        return self._provider_type(self, page, override)
--- a/piecrust/plugins/builtin.py	Tue Dec 27 04:09:38 2016 -0500
+++ b/piecrust/plugins/builtin.py	Sun Feb 05 22:37:25 2017 -0800
@@ -1,139 +1,152 @@
-from piecrust.commands.base import HelpCommand
-from piecrust.commands.builtin.admin import AdministrationPanelCommand
-from piecrust.commands.builtin.baking import (
-        BakeCommand, ShowRecordCommand)
-from piecrust.commands.builtin.info import (
-        RootCommand, ShowConfigCommand,
-        FindCommand, ShowSourcesCommand, ShowRoutesCommand, ShowPathsCommand)
-from piecrust.commands.builtin.plugins import PluginsCommand
-from piecrust.commands.builtin.publishing import PublishCommand
-from piecrust.commands.builtin.scaffolding import (
-        PrepareCommand,
-        DefaultPrepareTemplatesCommandExtension,
-        UserDefinedPrepareTemplatesCommandExtension,
-        DefaultPrepareTemplatesHelpTopic)
-from piecrust.commands.builtin.serving import (ServeCommand)
-from piecrust.commands.builtin.themes import (ThemesCommand)
-from piecrust.commands.builtin.util import (
-        InitCommand, PurgeCommand, ImportCommand)
-from piecrust.data.provider import (IteratorDataProvider, BlogDataProvider)
-from piecrust.formatting.hoedownformatter import HoedownFormatter
-from piecrust.formatting.markdownformatter import MarkdownFormatter
-from piecrust.formatting.textileformatter import TextileFormatter
-from piecrust.formatting.smartypantsformatter import SmartyPantsFormatter
-from piecrust.generation.blogarchives import BlogArchivesPageGenerator
-from piecrust.generation.taxonomy import TaxonomyPageGenerator
-from piecrust.importing.jekyll import JekyllImporter
-from piecrust.importing.piecrust import PieCrust1Importer
-from piecrust.importing.wordpress import WordpressXmlImporter
 from piecrust.plugins.base import PieCrustPlugin
-from piecrust.processing.base import CopyFileProcessor
-from piecrust.processing.compass import CompassProcessor
-from piecrust.processing.compressors import (
-        CleanCssProcessor, UglifyJSProcessor)
-from piecrust.processing.less import LessProcessor
-from piecrust.processing.pygments_style import PygmentsStyleProcessor
-from piecrust.processing.requirejs import RequireJSProcessor
-from piecrust.processing.sass import SassProcessor
-from piecrust.processing.sitemap import SitemapProcessor
-from piecrust.processing.util import ConcatProcessor
-from piecrust.publishing.sftp import SftpPublisher
-from piecrust.publishing.shell import ShellCommandPublisher
-from piecrust.publishing.rsync import RsyncPublisher
-from piecrust.sources.default import DefaultPageSource
-from piecrust.sources.posts import (
-        FlatPostsSource, ShallowPostsSource, HierarchyPostsSource)
-from piecrust.sources.autoconfig import (
-        AutoConfigSource, OrderedPageSource)
-from piecrust.sources.prose import ProseSource
-from piecrust.templating.jinjaengine import JinjaTemplateEngine
-from piecrust.templating.pystacheengine import PystacheTemplateEngine
 
 
 class BuiltInPlugin(PieCrustPlugin):
     name = '__builtin__'
 
     def getCommands(self):
+        from piecrust.commands.base import HelpCommand
+        from piecrust.commands.builtin.admin import AdministrationPanelCommand
+        from piecrust.commands.builtin.baking import (
+            BakeCommand, ShowRecordCommand)
+        from piecrust.commands.builtin.info import (
+            RootCommand, ShowConfigCommand,
+            FindCommand, ShowSourcesCommand, ShowRoutesCommand,
+            ShowPathsCommand)
+        from piecrust.commands.builtin.plugins import PluginsCommand
+        from piecrust.commands.builtin.publishing import PublishCommand
+        from piecrust.commands.builtin.scaffolding import PrepareCommand
+        from piecrust.commands.builtin.serving import (ServeCommand)
+        from piecrust.commands.builtin.themes import (ThemesCommand)
+        from piecrust.commands.builtin.util import (
+            InitCommand, PurgeCommand, ImportCommand)
+
         return [
-                InitCommand(),
-                ImportCommand(),
-                HelpCommand(),
-                RootCommand(),
-                PurgeCommand(),
-                ShowConfigCommand(),
-                FindCommand(),
-                PrepareCommand(),
-                ShowSourcesCommand(),
-                ShowRoutesCommand(),
-                ShowPathsCommand(),
-                ThemesCommand(),
-                PluginsCommand(),
-                BakeCommand(),
-                ShowRecordCommand(),
-                ServeCommand(),
-                AdministrationPanelCommand(),
-                PublishCommand()]
+            InitCommand(),
+            ImportCommand(),
+            HelpCommand(),
+            RootCommand(),
+            PurgeCommand(),
+            ShowConfigCommand(),
+            FindCommand(),
+            PrepareCommand(),
+            ShowSourcesCommand(),
+            ShowRoutesCommand(),
+            ShowPathsCommand(),
+            ThemesCommand(),
+            PluginsCommand(),
+            BakeCommand(),
+            ShowRecordCommand(),
+            ServeCommand(),
+            AdministrationPanelCommand(),
+            PublishCommand()]
 
     def getCommandExtensions(self):
+        from piecrust.commands.builtin.scaffolding import (
+            DefaultPrepareTemplatesCommandExtension,
+            UserDefinedPrepareTemplatesCommandExtension,
+            DefaultPrepareTemplatesHelpTopic)
+
         return [
-                DefaultPrepareTemplatesCommandExtension(),
-                UserDefinedPrepareTemplatesCommandExtension(),
-                DefaultPrepareTemplatesHelpTopic()]
+            DefaultPrepareTemplatesCommandExtension(),
+            UserDefinedPrepareTemplatesCommandExtension(),
+            DefaultPrepareTemplatesHelpTopic()]
 
     def getSources(self):
+        from piecrust.sources.default import DefaultPageSource
+        from piecrust.sources.posts import (
+                FlatPostsSource, ShallowPostsSource, HierarchyPostsSource)
+        from piecrust.sources.autoconfig import (
+                AutoConfigSource, OrderedPageSource)
+        from piecrust.sources.prose import ProseSource
+
         return [
-                DefaultPageSource,
-                FlatPostsSource,
-                ShallowPostsSource,
-                HierarchyPostsSource,
-                AutoConfigSource,
-                OrderedPageSource,
-                ProseSource]
+            DefaultPageSource,
+            FlatPostsSource,
+            ShallowPostsSource,
+            HierarchyPostsSource,
+            AutoConfigSource,
+            OrderedPageSource,
+            ProseSource]
 
     def getPageGenerators(self):
+        from piecrust.generation.blogarchives import BlogArchivesPageGenerator
+        from piecrust.generation.taxonomy import TaxonomyPageGenerator
+
         return [
-                TaxonomyPageGenerator,
-                BlogArchivesPageGenerator]
+            TaxonomyPageGenerator,
+            BlogArchivesPageGenerator]
 
     def getDataProviders(self):
+        from piecrust.data.provider import (
+            IteratorDataProvider, BlogDataProvider)
+
         return [
-                IteratorDataProvider,
-                BlogDataProvider]
+            IteratorDataProvider,
+            BlogDataProvider]
 
     def getTemplateEngines(self):
+        from piecrust.templating.jinjaengine import JinjaTemplateEngine
+        from piecrust.templating.pystacheengine import PystacheTemplateEngine
+
         return [
-                JinjaTemplateEngine(),
-                PystacheTemplateEngine()]
+            JinjaTemplateEngine(),
+            PystacheTemplateEngine()]
 
     def getFormatters(self):
+        from piecrust.formatting.hoedownformatter import HoedownFormatter
+        from piecrust.formatting.markdownformatter import MarkdownFormatter
+        from piecrust.formatting.textileformatter import TextileFormatter
+        from piecrust.formatting.smartypantsformatter import (
+            SmartyPantsFormatter)
+
         return [
-                HoedownFormatter(),
-                MarkdownFormatter(),
-                SmartyPantsFormatter(),
-                TextileFormatter()]
+            HoedownFormatter(),
+            MarkdownFormatter(),
+            SmartyPantsFormatter(),
+            TextileFormatter()]
 
     def getProcessors(self):
+        from piecrust.processing.base import CopyFileProcessor
+        from piecrust.processing.compass import CompassProcessor
+        from piecrust.processing.compressors import (
+            CleanCssProcessor, UglifyJSProcessor)
+        from piecrust.processing.less import LessProcessor
+        from piecrust.processing.pygments_style import PygmentsStyleProcessor
+        from piecrust.processing.requirejs import RequireJSProcessor
+        from piecrust.processing.sass import SassProcessor
+        from piecrust.processing.sitemap import SitemapProcessor
+        from piecrust.processing.util import ConcatProcessor
+
         return [
-                CopyFileProcessor(),
-                ConcatProcessor(),
-                PygmentsStyleProcessor(),
-                CompassProcessor(),
-                LessProcessor(),
-                SassProcessor(),
-                RequireJSProcessor(),
-                SitemapProcessor(),
-                CleanCssProcessor(),
-                UglifyJSProcessor()]
+            CopyFileProcessor(),
+            ConcatProcessor(),
+            PygmentsStyleProcessor(),
+            CompassProcessor(),
+            LessProcessor(),
+            SassProcessor(),
+            RequireJSProcessor(),
+            SitemapProcessor(),
+            CleanCssProcessor(),
+            UglifyJSProcessor()]
 
     def getImporters(self):
+        from piecrust.importing.jekyll import JekyllImporter
+        from piecrust.importing.piecrust import PieCrust1Importer
+        from piecrust.importing.wordpress import WordpressXmlImporter
+
         return [
-                PieCrust1Importer(),
-                JekyllImporter(),
-                WordpressXmlImporter()]
+            PieCrust1Importer(),
+            JekyllImporter(),
+            WordpressXmlImporter()]
 
     def getPublishers(self):
+        from piecrust.publishing.sftp import SftpPublisher
+        from piecrust.publishing.shell import ShellCommandPublisher
+        from piecrust.publishing.rsync import RsyncPublisher
+
         return [
-                ShellCommandPublisher,
-                SftpPublisher,
-                RsyncPublisher]
+            ShellCommandPublisher,
+            SftpPublisher,
+            RsyncPublisher]
 
--- a/piecrust/sources/base.py	Tue Dec 27 04:09:38 2016 -0500
+++ b/piecrust/sources/base.py	Sun Feb 05 22:37:25 2017 -0800
@@ -1,7 +1,6 @@
 import copy
 import logging
 from werkzeug.utils import cached_property
-from piecrust.configuration import ConfigurationError
 from piecrust.page import Page
 
 
@@ -125,15 +124,10 @@
         raise NotImplementedError()
 
     def buildDataProvider(self, page, override):
-        if self._provider_type is None:
-            cls = next((pt for pt in self.app.plugin_loader.getDataProviders()
-                        if pt.PROVIDER_NAME == self.data_type),
-                       None)
-            if cls is None:
-                raise ConfigurationError(
-                        "Unknown data provider type: %s" % self.data_type)
-            self._provider_type = cls
-
+        if not self._provider_type:
+            from piecrust.data.provider import get_data_provider_class
+            self._provider_type = get_data_provider_class(self.app,
+                                                          self.data_type)
         return self._provider_type(self, page, override)
     
     def finalizeConfig(self, page):