diff options
Diffstat (limited to 'nikola/nikola.py')
| -rw-r--r-- | nikola/nikola.py | 53 |
1 files changed, 37 insertions, 16 deletions
diff --git a/nikola/nikola.py b/nikola/nikola.py index 59e1b97..6a3fc0d 100644 --- a/nikola/nikola.py +++ b/nikola/nikola.py @@ -25,7 +25,7 @@ # SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. from __future__ import print_function, unicode_literals -import codecs +import io from collections import defaultdict from copy import copy from pkg_resources import resource_filename @@ -34,6 +34,7 @@ import glob import locale import os import sys +import mimetypes try: from urlparse import urlparse, urlsplit, urljoin except ImportError: @@ -133,7 +134,7 @@ LEGAL_VALUES = { 'pt': 'pt_br', 'zh': 'zh_cn' }, - 'RTL_LANGUAGES': ('fa', 'ur'), + 'RTL_LANGUAGES': ('ar', 'fa', 'ur'), 'COLORBOX_LOCALES': defaultdict( str, bg='bg', @@ -163,6 +164,16 @@ LEGAL_VALUES = { } +def _enclosure(post, lang): + '''Default implementation of enclosures''' + enclosure = post.meta('enclosure', lang) + if enclosure: + length = 0 + url = enclosure + mime = mimetypes.guess_type(url)[0] + return url, length, mime + + class Nikola(object): """Class that handles site generation. @@ -319,6 +330,7 @@ class Nikola(object): 'USE_CDN': False, 'USE_FILENAME_AS_TITLE': True, 'USE_OPEN_GRAPH': True, + 'USE_SLUGIFY': True, 'TIMEZONE': 'UTC', 'DEPLOY_DRAFTS': True, 'DEPLOY_FUTURE': False, @@ -389,6 +401,9 @@ class Nikola(object): # We provide the arguments to format in CONTENT_FOOTER_FORMATS. self.config['CONTENT_FOOTER'].langformat(self.config['CONTENT_FOOTER_FORMATS']) + # propagate USE_SLUGIFY + utils.USE_SLUGIFY = self.config['USE_SLUGIFY'] + # Make sure we have pyphen installed if we are using it if self.config.get('HYPHENATE') and pyphen is None: utils.LOGGER.warn('To use the hyphenation, you have to install ' @@ -635,6 +650,7 @@ class Nikola(object): 'SHOW_SOURCELINK') self._GLOBAL_CONTEXT['extra_head_data'] = self.config.get('EXTRA_HEAD_DATA') self._GLOBAL_CONTEXT['colorbox_locales'] = LEGAL_VALUES['COLORBOX_LOCALES'] + self._GLOBAL_CONTEXT['url_replacer'] = self.url_replacer self._GLOBAL_CONTEXT.update(self.config.get('GLOBAL_CONTEXT', {})) @@ -866,6 +882,10 @@ class Nikola(object): if not result: result = "." + # Don't forget the query part of the link + if parsed_dst.query: + result += "?" + parsed_dst.query + # Don't forget the fragment (anchor) part of the link if parsed_dst.fragment: result += "#" + parsed_dst.fragment @@ -875,7 +895,7 @@ class Nikola(object): return result def generic_rss_renderer(self, lang, title, link, description, timeline, output_path, - rss_teasers, rss_plain, feed_length=10, feed_url=None, enclosure=None): + rss_teasers, rss_plain, feed_length=10, feed_url=None, enclosure=_enclosure): """Takes all necessary data, and renders a RSS feed in output_path.""" rss_obj = rss.RSS2( @@ -929,14 +949,11 @@ class Nikola(object): rss_obj.rss_attrs["xmlns:dc"] = "http://purl.org/dc/elements/1.1/" """ Enclosure callback must returns tuple """ - if enclosure: - download_link, download_size, download_type = enclosure(post=post, lang=lang) - - args['enclosure'] = rss.Enclosure( - download_link, - download_size, - download_type, - ) + # enclosure callback returns None if post has no enclosure, or a + # 3-tuple of (url, length (0 is valid), mimetype) + enclosure_details = enclosure(post=post, lang=lang) + if enclosure_details is not None: + args['enclosure'] = rss.Enclosure(*enclosure_details) items.append(utils.ExtendedItem(**args)) @@ -944,7 +961,7 @@ class Nikola(object): dst_dir = os.path.dirname(output_path) utils.makedirs(dst_dir) - with codecs.open(output_path, "wb+", "utf-8") as rss_file: + with io.open(output_path, "w+", encoding="utf-8") as rss_file: data = rss_obj.to_xml(encoding='utf-8') if isinstance(data, utils.bytes_str): data = data.decode('utf-8') @@ -1199,16 +1216,17 @@ class Nikola(object): self.posts_per_month[ '{0}/{1:02d}'.format(post.date.year, post.date.month)].append(post) for tag in post.alltags: - if utils.slugify(tag) in slugged_tags: + _tag_slugified = utils.slugify(tag) + if _tag_slugified in slugged_tags: if tag not in self.posts_per_tag: # Tags that differ only in case - other_tag = [k for k in self.posts_per_tag.keys() if k.lower() == tag.lower()][0] + other_tag = [existing for existing in self.posts_per_tag.keys() if utils.slugify(existing) == _tag_slugified][0] utils.LOGGER.error('You have tags that are too similar: {0} and {1}'.format(tag, other_tag)) utils.LOGGER.error('Tag {0} is used in: {1}'.format(tag, post.source_path)) utils.LOGGER.error('Tag {0} is used in: {1}'.format(other_tag, ', '.join([p.source_path for p in self.posts_per_tag[other_tag]]))) quit = True else: - slugged_tags.add(utils.slugify(tag)) + slugged_tags.add(utils.slugify(tag, force=True)) self.posts_per_tag[tag].append(post) self.posts_per_category[post.meta('category')].append(post) else: @@ -1249,7 +1267,6 @@ class Nikola(object): context['title'] = post.title(lang) context['description'] = post.description(lang) context['permalink'] = post.permalink(lang) - context['page_list'] = self.pages if post.use_in_feeds: context['enable_comments'] = True else: @@ -1274,6 +1291,8 @@ class Nikola(object): for k in self._GLOBAL_CONTEXT_TRANSLATABLE: deps_dict[k] = deps_dict['global'][k](lang) + deps_dict['navigation_links'] = deps_dict['global']['navigation_links'](lang) + if post: deps_dict['post_translations'] = post.translated_to @@ -1315,6 +1334,8 @@ class Nikola(object): for k in self._GLOBAL_CONTEXT_TRANSLATABLE: deps_context[k] = deps_context['global'][k](lang) + deps_context['navigation_links'] = deps_context['global']['navigation_links'](lang) + task = { 'name': os.path.normpath(output_name), 'targets': [output_name], |
