diff options
Diffstat (limited to 'nikola/plugins/command/new_post.py')
| -rw-r--r-- | nikola/plugins/command/new_post.py | 105 |
1 files changed, 77 insertions, 28 deletions
diff --git a/nikola/plugins/command/new_post.py b/nikola/plugins/command/new_post.py index cd37a75..42f77cc 100644 --- a/nikola/plugins/command/new_post.py +++ b/nikola/plugins/command/new_post.py @@ -29,8 +29,10 @@ import codecs import datetime import os import sys +import subprocess from blinker import signal +import dateutil.tz from nikola.plugin_categories import Command from nikola import utils @@ -82,7 +84,7 @@ def get_default_compiler(is_post, compilers, post_pages): return 'rest' -def get_date(schedule=False, rule=None, last_date=None, force_today=False): +def get_date(schedule=False, rule=None, last_date=None, tz=None, iso8601=False): """Returns a date stamp, given a recurrence rule. schedule - bool: @@ -94,33 +96,45 @@ def get_date(schedule=False, rule=None, last_date=None, force_today=False): last_date - datetime: timestamp of the last post - force_today - bool: - tries to schedule a post to today, if possible, even if the scheduled - time has already passed in the day. + tz - tzinfo: + the timezone used for getting the current time. + + iso8601 - bool: + whether to force ISO 8601 dates (instead of locale-specific ones) + """ - date = now = datetime.datetime.now() + if tz is None: + tz = dateutil.tz.tzlocal() + date = now = datetime.datetime.now(tz) if schedule: try: from dateutil import rrule except ImportError: LOGGER.error('To use the --schedule switch of new_post, ' 'you have to install the "dateutil" package.') - rrule = None + rrule = None # NOQA if schedule and rrule and rule: - if last_date and last_date.tzinfo: - # strip tzinfo for comparisons - last_date = last_date.replace(tzinfo=None) try: rule_ = rrule.rrulestr(rule, dtstart=last_date) except Exception: LOGGER.error('Unable to parse rule string, using current time.') else: - # Try to post today, instead of tomorrow, if no other post today. - if force_today: - now = now.replace(hour=0, minute=0, second=0, microsecond=0) date = rule_.after(max(now, last_date or now), last_date is None) - return date.strftime('%Y/%m/%d %H:%M:%S') + + offset = tz.utcoffset(now) + offset_sec = (offset.days * 24 * 3600 + offset.seconds) + offset_hrs = offset_sec // 3600 + offset_min = offset_sec % 3600 + if iso8601: + tz_str = '{0:+03d}:{1:02d}'.format(offset_hrs, offset_min // 60) + else: + if offset: + tz_str = ' UTC{0:+03d}:{1:02d}'.format(offset_hrs, offset_min // 60) + else: + tz_str = ' UTC' + + return date.strftime('%Y-%m-%d %H:%M:%S') + tz_str class CommandNewPost(Command): @@ -168,6 +182,13 @@ class CommandNewPost(Command): 'help': 'Create the post with separate metadata (two file format)' }, { + 'name': 'edit', + 'short': 'e', + 'type': bool, + 'default': False, + 'help': 'Open the post (and meta file, if any) in $EDITOR after creation.' + }, + { 'name': 'content_format', 'short': 'f', 'long': 'format', @@ -242,31 +263,44 @@ class CommandNewPost(Command): print("Creating New {0}".format(content_type.title())) print("-----------------\n") - if title is None: - print("Enter title: ", end='') - # WHY, PYTHON3???? WHY? - sys.stdout.flush() - title = sys.stdin.readline() - else: + if title is not None: print("Title:", title) + else: + while not title: + title = utils.ask('Title') + if isinstance(title, utils.bytes_str): - title = title.decode(sys.stdin.encoding) + try: + title = title.decode(sys.stdin.encoding) + except AttributeError: # for tests + title = title.decode('utf-8') + title = title.strip() if not path: slug = utils.slugify(title) else: if isinstance(path, utils.bytes_str): - path = path.decode(sys.stdin.encoding) + try: + path = path.decode(sys.stdin.encoding) + except AttributeError: # for tests + path = path.decode('utf-8') slug = utils.slugify(os.path.splitext(os.path.basename(path))[0]) # Calculate the date to use for the content schedule = options['schedule'] or self.site.config['SCHEDULE_ALL'] rule = self.site.config['SCHEDULE_RULE'] - force_today = self.site.config['SCHEDULE_FORCE_TODAY'] self.site.scan_posts() timeline = self.site.timeline last_date = None if not timeline else timeline[0].date - date = get_date(schedule, rule, last_date, force_today) - data = [title, slug, date, tags] + date = get_date(schedule, rule, last_date, self.site.tzinfo, self.site.config['FORCE_ISO8601']) + data = { + 'title': title, + 'slug': slug, + 'date': date, + 'tags': tags, + 'link': '', + 'description': '', + 'type': 'text', + } output_path = os.path.dirname(entry[0]) meta_path = os.path.join(output_path, slug + ".meta") pattern = os.path.basename(entry[0]) @@ -284,19 +318,34 @@ class CommandNewPost(Command): d_name = os.path.dirname(txt_path) utils.makedirs(d_name) metadata = self.site.config['ADDITIONAL_METADATA'] + + # Override onefile if not really supported. + if not compiler_plugin.supports_onefile and onefile: + onefile = False + LOGGER.warn('This compiler does not support one-file posts.') + + content = "Write your {0} here.".format('page' if is_page else 'post') compiler_plugin.create_post( - txt_path, onefile, title=title, + txt_path, content=content, onefile=onefile, title=title, slug=slug, date=date, tags=tags, is_page=is_page, **metadata) event = dict(path=txt_path) if not onefile: # write metadata file with codecs.open(meta_path, "wb+", "utf8") as fd: - fd.write('\n'.join(data)) - with codecs.open(txt_path, "wb+", "utf8") as fd: - fd.write("Write your {0} here.".format(content_type)) + fd.write(utils.write_metadata(data)) LOGGER.info("Your {0}'s metadata is at: {1}".format(content_type, meta_path)) event['meta_path'] = meta_path LOGGER.info("Your {0}'s text is at: {1}".format(content_type, txt_path)) signal('new_' + content_type).send(self, **event) + + if options['edit']: + editor = os.getenv('EDITOR') + to_run = [editor, txt_path] + if not onefile: + to_run.append(meta_path) + if editor: + subprocess.call(to_run) + else: + LOGGER.error('$EDITOR not set, cannot edit the post. Please do it manually.') |
