changeset 576:0c74a6c4533d

sources: Add code to support "interactive" metadata acquisition.
author Ludovic Chabant <ludovic@chabant.com>
date Sat, 19 Dec 2015 18:07:21 -0800
parents 657384f08ca3
children ff404adfcf45
files piecrust/sources/default.py piecrust/sources/interfaces.py piecrust/sources/posts.py
diffstat 3 files changed, 43 insertions(+), 9 deletions(-) [+]
line wrap: on
line diff
--- a/piecrust/sources/default.py	Sat Dec 19 18:06:16 2015 -0800
+++ b/piecrust/sources/default.py	Sat Dec 19 18:07:21 2015 -0800
@@ -4,7 +4,9 @@
 from piecrust.sources.base import (
         PageFactory, PageSource, InvalidFileSystemEndpointError,
         MODE_CREATING)
-from piecrust.sources.interfaces import IListableSource, IPreparingSource
+from piecrust.sources.interfaces import (
+        IListableSource, IPreparingSource, IInteractiveSource,
+        InteractiveField)
 from piecrust.sources.mixins import SimplePaginationSourceMixin
 
 
@@ -21,7 +23,8 @@
             f not in ['Thumbs.db'])  # Windows bullshit
 
 
-class DefaultPageSource(PageSource, IListableSource, IPreparingSource,
+class DefaultPageSource(PageSource,
+                        IListableSource, IPreparingSource, IInteractiveSource,
                         SimplePaginationSourceMixin):
     SOURCE_NAME = 'default'
 
@@ -134,6 +137,11 @@
     def buildMetadata(self, args):
         return {'slug': args.uri}
 
+    def getInteractiveFields(self):
+        return [
+                InteractiveField('slug', InteractiveField.TYPE_STRING,
+                                 'new-page')]
+
     def _makeSlug(self, rel_path):
         slug, ext = os.path.splitext(rel_path)
         slug = slug.replace('\\', '/')
--- a/piecrust/sources/interfaces.py	Sat Dec 19 18:06:16 2015 -0800
+++ b/piecrust/sources/interfaces.py	Sat Dec 19 18:07:21 2015 -0800
@@ -23,7 +23,7 @@
         raise NotImplementedError()
 
 
-class IListableSource:
+class IListableSource(object):
     """ Defines the interface for a source that can be iterated on in a
         hierarchical manner, for use with the `family` data endpoint.
     """
@@ -37,7 +37,7 @@
         raise NotImplementedError()
 
 
-class IPreparingSource:
+class IPreparingSource(object):
     """ Defines the interface for a source whose pages can be created by the
         `chef prepare` command.
     """
@@ -48,3 +48,17 @@
         raise NotImplementedError()
 
 
+class InteractiveField(object):
+    TYPE_STRING = 0
+    TYPE_INT = 1
+
+    def __init__(self, name, field_type, default_value):
+        self.name = name
+        self.field_type = field_type
+        self.default_value = default_value
+
+
+class IInteractiveSource(object):
+    def getInteractiveFields(self):
+        raise NotImplementedError()
+
--- a/piecrust/sources/posts.py	Sat Dec 19 18:06:16 2015 -0800
+++ b/piecrust/sources/posts.py	Sat Dec 19 18:07:21 2015 -0800
@@ -7,14 +7,16 @@
 from piecrust.sources.base import (
         PageSource, InvalidFileSystemEndpointError, PageFactory,
         MODE_CREATING, MODE_PARSING)
-from piecrust.sources.interfaces import IPreparingSource
+from piecrust.sources.interfaces import (
+        IPreparingSource, IInteractiveSource, InteractiveField)
 from piecrust.sources.mixins import SimplePaginationSourceMixin
 
 
 logger = logging.getLogger(__name__)
 
 
-class PostsSource(PageSource, IPreparingSource, SimplePaginationSourceMixin):
+class PostsSource(PageSource, IPreparingSource, IInteractiveSource,
+                  SimplePaginationSourceMixin):
     PATH_FORMAT = None
 
     def __init__(self, app, name, config):
@@ -98,7 +100,8 @@
         return PageFactory(self, rel_path, fac_metadata)
 
     def setupPrepareParser(self, parser, app):
-        parser.add_argument('-d', '--date', help="The date of the post, "
+        parser.add_argument(
+                '-d', '--date', help="The date of the post, "
                 "in `year/month/day` format (defaults to today).")
         parser.add_argument('slug', help="The URL slug for the new post.")
 
@@ -106,7 +109,7 @@
         dt = datetime.date.today()
         if args.date:
             if args.date == 'today':
-                pass # Keep the default we had.
+                pass  # Keep the default we had.
             elif args.date == 'tomorrow':
                 dt += datetime.timedelta(days=1)
             elif args.date.startswith('+'):
@@ -118,12 +121,21 @@
                 try:
                     year, month, day = [int(s) for s in args.date.split('/')]
                 except ValueError:
-                    raise Exception("Dates must be of the form: YEAR/MONTH/DAY.")
+                    raise Exception("Dates must be of the form: "
+                                    "YEAR/MONTH/DAY.")
                 dt = datetime.date(year, month, day)
 
         year, month, day = dt.year, dt.month, dt.day
         return {'year': year, 'month': month, 'day': day, 'slug': args.slug}
 
+    def getInteractiveFields(self):
+        dt = datetime.date.today()
+        return [
+            InteractiveField('year', InteractiveField.TYPE_INT, dt.year),
+            InteractiveField('month', InteractiveField.TYPE_INT, dt.month),
+            InteractiveField('day', InteractiveField.TYPE_INT, dt.day),
+            InteractiveField('slug', InteractiveField.TYPE_STRING, 'new-post')]
+
     def _checkFsEndpointPath(self):
         if not os.path.isdir(self.fs_endpoint_path):
             if self.ignore_missing_dir: