comparison piecrust/sources/posts.py @ 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 bab91fcef741
children ff404adfcf45
comparison
equal deleted inserted replaced
575:657384f08ca3 576:0c74a6c4533d
5 import datetime 5 import datetime
6 from piecrust import osutil 6 from piecrust import osutil
7 from piecrust.sources.base import ( 7 from piecrust.sources.base import (
8 PageSource, InvalidFileSystemEndpointError, PageFactory, 8 PageSource, InvalidFileSystemEndpointError, PageFactory,
9 MODE_CREATING, MODE_PARSING) 9 MODE_CREATING, MODE_PARSING)
10 from piecrust.sources.interfaces import IPreparingSource 10 from piecrust.sources.interfaces import (
11 IPreparingSource, IInteractiveSource, InteractiveField)
11 from piecrust.sources.mixins import SimplePaginationSourceMixin 12 from piecrust.sources.mixins import SimplePaginationSourceMixin
12 13
13 14
14 logger = logging.getLogger(__name__) 15 logger = logging.getLogger(__name__)
15 16
16 17
17 class PostsSource(PageSource, IPreparingSource, SimplePaginationSourceMixin): 18 class PostsSource(PageSource, IPreparingSource, IInteractiveSource,
19 SimplePaginationSourceMixin):
18 PATH_FORMAT = None 20 PATH_FORMAT = None
19 21
20 def __init__(self, app, name, config): 22 def __init__(self, app, name, config):
21 super(PostsSource, self).__init__(app, name, config) 23 super(PostsSource, self).__init__(app, name, config)
22 self.fs_endpoint = config.get('fs_endpoint', name) 24 self.fs_endpoint = config.get('fs_endpoint', name)
96 rel_path = rel_path.replace('\\', '/') 98 rel_path = rel_path.replace('\\', '/')
97 fac_metadata = self._parseMetadataFromPath(rel_path) 99 fac_metadata = self._parseMetadataFromPath(rel_path)
98 return PageFactory(self, rel_path, fac_metadata) 100 return PageFactory(self, rel_path, fac_metadata)
99 101
100 def setupPrepareParser(self, parser, app): 102 def setupPrepareParser(self, parser, app):
101 parser.add_argument('-d', '--date', help="The date of the post, " 103 parser.add_argument(
104 '-d', '--date', help="The date of the post, "
102 "in `year/month/day` format (defaults to today).") 105 "in `year/month/day` format (defaults to today).")
103 parser.add_argument('slug', help="The URL slug for the new post.") 106 parser.add_argument('slug', help="The URL slug for the new post.")
104 107
105 def buildMetadata(self, args): 108 def buildMetadata(self, args):
106 dt = datetime.date.today() 109 dt = datetime.date.today()
107 if args.date: 110 if args.date:
108 if args.date == 'today': 111 if args.date == 'today':
109 pass # Keep the default we had. 112 pass # Keep the default we had.
110 elif args.date == 'tomorrow': 113 elif args.date == 'tomorrow':
111 dt += datetime.timedelta(days=1) 114 dt += datetime.timedelta(days=1)
112 elif args.date.startswith('+'): 115 elif args.date.startswith('+'):
113 try: 116 try:
114 dt += datetime.timedelta(days=int(args.date.lstrip('+'))) 117 dt += datetime.timedelta(days=int(args.date.lstrip('+')))
116 raise Exception("Date offsets must be numbers.") 119 raise Exception("Date offsets must be numbers.")
117 else: 120 else:
118 try: 121 try:
119 year, month, day = [int(s) for s in args.date.split('/')] 122 year, month, day = [int(s) for s in args.date.split('/')]
120 except ValueError: 123 except ValueError:
121 raise Exception("Dates must be of the form: YEAR/MONTH/DAY.") 124 raise Exception("Dates must be of the form: "
125 "YEAR/MONTH/DAY.")
122 dt = datetime.date(year, month, day) 126 dt = datetime.date(year, month, day)
123 127
124 year, month, day = dt.year, dt.month, dt.day 128 year, month, day = dt.year, dt.month, dt.day
125 return {'year': year, 'month': month, 'day': day, 'slug': args.slug} 129 return {'year': year, 'month': month, 'day': day, 'slug': args.slug}
130
131 def getInteractiveFields(self):
132 dt = datetime.date.today()
133 return [
134 InteractiveField('year', InteractiveField.TYPE_INT, dt.year),
135 InteractiveField('month', InteractiveField.TYPE_INT, dt.month),
136 InteractiveField('day', InteractiveField.TYPE_INT, dt.day),
137 InteractiveField('slug', InteractiveField.TYPE_STRING, 'new-post')]
126 138
127 def _checkFsEndpointPath(self): 139 def _checkFsEndpointPath(self):
128 if not os.path.isdir(self.fs_endpoint_path): 140 if not os.path.isdir(self.fs_endpoint_path):
129 if self.ignore_missing_dir: 141 if self.ignore_missing_dir:
130 return False 142 return False