aboutsummaryrefslogtreecommitdiffstats
path: root/nikola/post.py
diff options
context:
space:
mode:
Diffstat (limited to 'nikola/post.py')
-rw-r--r--nikola/post.py99
1 files changed, 57 insertions, 42 deletions
diff --git a/nikola/post.py b/nikola/post.py
index a41901d..810474b 100644
--- a/nikola/post.py
+++ b/nikola/post.py
@@ -1,6 +1,6 @@
# -*- coding: utf-8 -*-
-# Copyright © 2012-2013 Roberto Alsina and others.
+# Copyright © 2012-2014 Roberto Alsina and others.
# Permission is hereby granted, free of charge, to any
# person obtaining a copy of this software and associated
@@ -54,6 +54,8 @@ from .utils import (
slugify,
to_datetime,
unicode_str,
+ demote_headers,
+ get_translation_candidate,
)
from .rc4 import rc4
@@ -83,11 +85,11 @@ class Post(object):
the meta file, as well as any translations available, and
the .html fragment file path.
"""
- self.compiler = compiler
self.config = config
- tzinfo = None
- if self.config['TIMEZONE'] is not None:
- tzinfo = pytz.timezone(self.config['TIMEZONE'])
+ self.compiler = compiler
+ self.compile_html = self.compiler.compile_html
+ self.demote_headers = self.compiler.demote_headers and self.config['DEMOTE_HEADERS']
+ tzinfo = pytz.timezone(self.config['TIMEZONE'])
if self.config['FUTURE_IS_NOW']:
self.current_time = None
else:
@@ -127,7 +129,7 @@ class Post(object):
# Load internationalized metadata
for lang in self.translations:
if lang != self.default_lang:
- if os.path.isfile(self.source_path + "." + lang):
+ if os.path.isfile(get_translation_candidate(self.config, self.source_path, lang)):
self.translated_to.add(lang)
meta = defaultdict(lambda: '')
@@ -146,11 +148,7 @@ class Post(object):
if 'date' not in default_metadata and not use_in_feeds:
# For stories we don't *really* need a date
default_metadata['date'] = datetime.datetime.utcfromtimestamp(
- os.stat(self.source_path).st_ctime)
-
- if tzinfo:
- default_metadata['date'] = default_metadata['date'].replace(
- tzinfo=pytz.UTC).astimezone(tzinfo)
+ os.stat(self.source_path).st_ctime).replace(tzinfo=pytz.UTC).astimezone(tzinfo)
if 'title' not in default_metadata or 'slug' not in default_metadata \
or 'date' not in default_metadata:
@@ -161,7 +159,11 @@ class Post(object):
default_metadata.get('date', None),
source_path))
- # If timezone is set, build localized datetime.
+ if 'type' not in default_metadata:
+ # default value is 'text'
+ default_metadata['type'] = 'text'
+
+ # If time zone is set, build localized datetime.
self.date = to_datetime(self.meta[self.default_lang]['date'], tzinfo)
self.publish_later = False if self.current_time is None else self.date >= self.current_time
@@ -185,6 +187,7 @@ class Post(object):
# While draft comes from the tags, it's not really a tag
self.is_draft = is_draft
self.is_retired = is_retired
+ self.is_post = use_in_feeds
self.use_in_feeds = use_in_feeds and not is_draft and not is_retired \
and not self.publish_later
@@ -253,15 +256,6 @@ class Post(object):
def template_name(self):
return self.meta('template') or self._template_name
- def _add_old_metadata(self):
- # Compatibility for themes up to Nikola 5.4.1
- # TODO: remove before Nikola 6
- self.pagenames = {}
- self.titles = {}
- for lang in self.translations:
- self.pagenames[lang] = self.meta[lang]['slug']
- self.titles[lang] = self.meta[lang]['title']
-
def formatted_date(self, date_format):
"""Return the formatted date, as unicode."""
fmt_date = self.date.strftime(date_format)
@@ -292,7 +286,7 @@ class Post(object):
if self.default_lang in self.translated_to:
deps.append(self.base_path)
if lang != self.default_lang:
- deps += [self.base_path + "." + lang]
+ deps += [get_translation_candidate(self.config, self.base_path, lang)]
deps += self.fragment_deps(lang)
return deps
@@ -312,7 +306,7 @@ class Post(object):
if not self.is_translation_available(lang) and self.config['HIDE_UNTRANSLATED_POSTS']:
return
else:
- self.compiler(
+ self.compile_html(
self.translated_source_path(lang),
dest,
self.is_two_file),
@@ -333,11 +327,11 @@ class Post(object):
if os.path.isfile(dep_path):
with codecs.open(dep_path, 'rb+', 'utf8') as depf:
deps.extend([l.strip() for l in depf.readlines()])
+ lang_deps = []
if lang != self.default_lang:
- lang_deps = list(filter(os.path.exists, [x + "." + lang for x in
- deps]))
+ lang_deps = [get_translation_candidate(self.config, d, lang) for d in deps]
deps += lang_deps
- return deps
+ return [d for d in deps if os.path.exists(d)]
def is_translation_available(self, lang):
"""Return true if the translation actually exists."""
@@ -349,18 +343,18 @@ class Post(object):
if lang == self.default_lang:
return self.source_path
else:
- return '.'.join((self.source_path, lang))
+ return get_translation_candidate(self.config, self.source_path, lang)
elif lang != self.default_lang:
return self.source_path
else:
- return '.'.join((self.source_path, sorted(self.translated_to)[0]))
+ return get_translation_candidate(self.config, self.source_path, sorted(self.translated_to)[0])
def translated_base_path(self, lang):
"""Return path to the translation's base_path file."""
if lang == self.default_lang:
return self.base_path
else:
- return '.'.join((self.base_path, lang))
+ return get_translation_candidate(self.config, self.base_path, lang)
def _translated_file_path(self, lang):
"""Return path to the translation's file, or to the original."""
@@ -368,11 +362,11 @@ class Post(object):
if lang == self.default_lang:
return self.base_path
else:
- return '.'.join((self.base_path, lang))
+ return get_translation_candidate(self.config, self.base_path, lang)
elif lang != self.default_lang:
return self.base_path
else:
- return '.'.join((self.base_path, sorted(self.translated_to)[0]))
+ return get_translation_candidate(self.config, self.base_path, sorted(self.translated_to)[0])
def text(self, lang=None, teaser_only=False, strip_html=False, really_absolute=False):
"""Read the post file for that language and return its contents.
@@ -438,6 +432,16 @@ class Post(object):
data = content.text_content().strip() # No whitespace wanted.
except lxml.etree.ParserError:
data = ""
+ elif data:
+ if self.demote_headers:
+ # see above
+ try:
+ document = lxml.html.fromstring(data)
+ demote_headers(document, self.demote_headers)
+ data = lxml.html.tostring(document, encoding='unicode')
+ except lxml.etree.ParserError:
+ pass
+
return data
@property
@@ -536,11 +540,13 @@ def _get_metadata_from_filename_by_regex(filename, metadata_regexp):
return meta
-def get_metadata_from_file(source_path, lang=None):
+def get_metadata_from_file(source_path, config=None, lang=None):
"""Extracts metadata from the file itself, by parsing contents."""
try:
- if lang:
- source_path = "{0}.{1}".format(source_path, lang)
+ if lang and config:
+ source_path = get_translation_candidate(config, source_path, lang)
+ elif lang:
+ source_path += '.' + lang
with codecs.open(source_path, "r", "utf8") as meta_file:
meta_data = [x.strip() for x in meta_file.readlines()]
return _get_metadata_from_file(meta_data)
@@ -601,18 +607,20 @@ def _get_metadata_from_file(meta_data):
return meta
-def get_metadata_from_meta_file(path, lang=None):
+def get_metadata_from_meta_file(path, config=None, lang=None):
"""Takes a post path, and gets data from a matching .meta file."""
meta_path = os.path.splitext(path)[0] + '.meta'
- if lang:
+ if lang and config:
+ meta_path = get_translation_candidate(config, meta_path, lang)
+ elif lang:
meta_path += '.' + lang
if os.path.isfile(meta_path):
with codecs.open(meta_path, "r", "utf8") as meta_file:
meta_data = meta_file.readlines()
- while len(meta_data) < 6:
+ while len(meta_data) < 7:
meta_data.append("")
- (title, slug, date, tags, link, description) = [
- x.strip() for x in meta_data][:6]
+ (title, slug, date, tags, link, description, _type) = [
+ x.strip() for x in meta_data][:7]
meta = {}
@@ -628,6 +636,8 @@ def get_metadata_from_meta_file(path, lang=None):
meta['link'] = link
if description:
meta['description'] = description
+ if _type:
+ meta['type'] = _type
return meta
@@ -635,7 +645,7 @@ def get_metadata_from_meta_file(path, lang=None):
# Metadata file doesn't exist, but not default language,
# So, if default language metadata exists, return that.
# This makes the 2-file format detection more reliable (Issue #525)
- return get_metadata_from_meta_file(path, lang=None)
+ return get_metadata_from_meta_file(path, config, lang=None)
else:
return {}
@@ -650,7 +660,12 @@ def get_meta(post, file_metadata_regexp=None, lang=None):
"""
meta = defaultdict(lambda: '')
- meta.update(get_metadata_from_meta_file(post.metadata_path, lang))
+ try:
+ config = post.config
+ except AttributeError:
+ config = None
+
+ meta.update(get_metadata_from_meta_file(post.metadata_path, config, lang))
if meta:
return meta
@@ -660,7 +675,7 @@ def get_meta(post, file_metadata_regexp=None, lang=None):
meta.update(_get_metadata_from_filename_by_regex(post.source_path,
file_metadata_regexp))
- meta.update(get_metadata_from_file(post.source_path, lang))
+ meta.update(get_metadata_from_file(post.source_path, config, lang))
if lang is None:
# Only perform these checks for the default language