diff options
| author | 2015-07-08 07:35:06 -0300 | |
|---|---|---|
| committer | 2015-07-08 07:35:06 -0300 | |
| commit | 055d72d76b44b0e627c8a17c48dbecd62e44197b (patch) | |
| tree | e2c8d5475477c46115461fe9547c1ee797873635 /nikola/plugins/task/archive.py | |
| parent | 61f3aad02cd6492cb38e41b66f2ed8ec56e98981 (diff) | |
| parent | b0b24795b24ee6809397fbbadf42f31f310a219f (diff) | |
Merge tag 'upstream/7.6.0'
Upstream version 7.6.0
Diffstat (limited to 'nikola/plugins/task/archive.py')
| -rw-r--r-- | nikola/plugins/task/archive.py | 248 |
1 files changed, 154 insertions, 94 deletions
diff --git a/nikola/plugins/task/archive.py b/nikola/plugins/task/archive.py index 4f1ab19..533be69 100644 --- a/nikola/plugins/task/archive.py +++ b/nikola/plugins/task/archive.py @@ -1,6 +1,6 @@ # -*- coding: utf-8 -*- -# Copyright © 2012-2014 Roberto Alsina and others. +# Copyright © 2012-2015 Roberto Alsina and others. # Permission is hereby granted, free of charge, to any # person obtaining a copy of this software and associated @@ -24,12 +24,14 @@ # OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE # SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +import copy import os # for tearDown with _reload we cannot use 'import from' to access LocaleBorg import nikola.utils +import datetime from nikola.plugin_categories import Task -from nikola.utils import config_changed +from nikola.utils import config_changed, adjust_name_for_index_path, adjust_name_for_index_link class Archive(Task): @@ -39,133 +41,191 @@ class Archive(Task): def set_site(self, site): site.register_path_handler('archive', self.archive_path) + site.register_path_handler('archive_atom', self.archive_atom_path) return super(Archive, self).set_site(site) + def _prepare_task(self, kw, name, lang, posts, items, template_name, + title, deps_translatable=None): + # name: used to build permalink and destination + # posts, items: posts or items; only one of them should be used, + # the other be None + # template_name: name of the template to use + # title: the (translated) title for the generated page + # deps_translatable: dependencies (None if not added) + assert posts is not None or items is not None + + context = {} + context["lang"] = lang + context["title"] = title + context["permalink"] = self.site.link("archive", name, lang) + if posts is not None: + context["posts"] = posts + n = len(posts) + else: + context["items"] = items + n = len(items) + task = self.site.generic_post_list_renderer( + lang, + [], + os.path.join(kw['output_folder'], self.site.path("archive", name, lang)), + template_name, + kw['filters'], + context, + ) + + task_cfg = {1: copy.copy(kw), 2: n} + if deps_translatable is not None: + task_cfg[3] = deps_translatable + task['uptodate'] = task['uptodate'] + [config_changed(task_cfg, 'nikola.plugins.task.archive')] + task['basename'] = self.name + return task + + def _generate_posts_task(self, kw, name, lang, posts, title, deps_translatable=None): + posts = sorted(posts, key=lambda a: a.date) + posts.reverse() + if kw['archives_are_indexes']: + def page_link(i, displayed_i, num_pages, force_addition, extension=None): + feed = "_atom" if extension == ".atom" else "" + return adjust_name_for_index_link(self.site.link("archive" + feed, name, lang), i, displayed_i, + lang, self.site, force_addition, extension) + + def page_path(i, displayed_i, num_pages, force_addition, extension=None): + feed = "_atom" if extension == ".atom" else "" + return adjust_name_for_index_path(self.site.path("archive" + feed, name, lang), i, displayed_i, + lang, self.site, force_addition, extension) + + uptodate = [] + if deps_translatable is not None: + uptodate += [config_changed(deps_translatable, 'nikola.plugins.task.archive')] + yield self.site.generic_index_renderer( + lang, + posts, + title, + "archiveindex.tmpl", + {"archive_name": name, + "is_feed_stale": kw["is_feed_stale"]}, + kw, + str(self.name), + page_link, + page_path, + uptodate) + else: + yield self._prepare_task(kw, name, lang, posts, None, "list_post.tmpl", title, deps_translatable) + def gen_tasks(self): kw = { "messages": self.site.MESSAGES, "translations": self.site.config['TRANSLATIONS'], "output_folder": self.site.config['OUTPUT_FOLDER'], "filters": self.site.config['FILTERS'], + "archives_are_indexes": self.site.config['ARCHIVES_ARE_INDEXES'], "create_monthly_archive": self.site.config['CREATE_MONTHLY_ARCHIVE'], "create_single_archive": self.site.config['CREATE_SINGLE_ARCHIVE'], + "show_untranslated_posts": self.site.config['SHOW_UNTRANSLATED_POSTS'], + "create_full_archives": self.site.config['CREATE_FULL_ARCHIVES'], + "create_daily_archive": self.site.config['CREATE_DAILY_ARCHIVE'], + "pretty_urls": self.site.config['PRETTY_URLS'], + "strip_indexes": self.site.config['STRIP_INDEXES'], + "index_file": self.site.config['INDEX_FILE'], + "generate_atom": self.site.config["GENERATE_ATOM"], } self.site.scan_posts() yield self.group_task() # TODO add next/prev links for years - if kw['create_monthly_archive'] and kw['create_single_archive']: + if (kw['create_monthly_archive'] and kw['create_single_archive']) and not kw['create_full_archives']: raise Exception('Cannot create monthly and single archives at the same time.') for lang in kw["translations"]: - archdata = self.site.posts_per_year - # A bit of a hack. - if kw['create_single_archive']: - archdata = {None: self.site.posts} + if kw['create_single_archive'] and not kw['create_full_archives']: + # if we are creating one single archive + archdata = {} + else: + # if we are not creating one single archive, start with all years + archdata = self.site.posts_per_year.copy() + if kw['create_single_archive'] or kw['create_full_archives']: + # if we are creating one single archive, or full archives + archdata[None] = self.site.posts # for create_single_archive for year, posts in archdata.items(): - output_name = os.path.join( - kw['output_folder'], self.site.path("archive", year, lang)) - context = {} - context["lang"] = lang + # Filter untranslated posts (Issue #1360) + if not kw["show_untranslated_posts"]: + posts = [p for p in posts if lang in p.translated_to] + + # Add archive per year or total archive if year: - context["title"] = kw["messages"][lang]["Posts for year %s"] % year + title = kw["messages"][lang]["Posts for year %s"] % year + kw["is_feed_stale"] = (datetime.datetime.utcnow().strftime("%Y") != year) else: - context["title"] = kw["messages"][lang]["Archive"] - context["permalink"] = self.site.link("archive", year, lang) - if not kw["create_monthly_archive"]: - template_name = "list_post.tmpl" - post_list = sorted(posts, key=lambda a: a.date) - post_list.reverse() - context["posts"] = post_list - else: # Monthly archives, just list the months - months = set([(m.split('/')[1], self.site.link("archive", m, lang)) for m in self.site.posts_per_month.keys() if m.startswith(str(year))]) - months = sorted(list(months)) - months.reverse() - template_name = "list.tmpl" - context["items"] = [[nikola.utils.LocaleBorg().get_month_name(int(month), lang), link] for month, link in months] - post_list = [] - task = self.site.generic_post_list_renderer( - lang, - [], - output_name, - template_name, - kw['filters'], - context, - ) - n = len(post_list) if 'posts' in context else len(months) - + title = kw["messages"][lang]["Archive"] + kw["is_feed_stale"] = False deps_translatable = {} for k in self.site._GLOBAL_CONTEXT_TRANSLATABLE: deps_translatable[k] = self.site.GLOBAL_CONTEXT[k](lang) + if not kw["create_monthly_archive"] or kw["create_full_archives"]: + yield self._generate_posts_task(kw, year, lang, posts, title, deps_translatable) + else: + months = set([(m.split('/')[1], self.site.link("archive", m, lang)) for m in self.site.posts_per_month.keys() if m.startswith(str(year))]) + months = sorted(list(months)) + months.reverse() + items = [[nikola.utils.LocaleBorg().get_month_name(int(month), lang), link] for month, link in months] + yield self._prepare_task(kw, year, lang, None, items, "list.tmpl", title, deps_translatable) - task_cfg = {1: task['uptodate'][0].config, 2: kw, 3: n, 4: deps_translatable} - task['uptodate'] = [config_changed(task_cfg)] - task['basename'] = self.name - yield task - - if not kw["create_monthly_archive"]: + if not kw["create_monthly_archive"] and not kw["create_full_archives"] and not kw["create_daily_archive"]: continue # Just to avoid nesting the other loop in this if - template_name = "list_post.tmpl" for yearmonth, posts in self.site.posts_per_month.items(): - output_name = os.path.join( - kw['output_folder'], self.site.path("archive", yearmonth, - lang)) + # Add archive per month year, month = yearmonth.split('/') - post_list = sorted(posts, key=lambda a: a.date) - post_list.reverse() - context = {} - context["lang"] = lang - context["posts"] = post_list - context["permalink"] = self.site.link("archive", year, lang) - - context["title"] = kw["messages"][lang]["Posts for {month} {year}"].format( - year=year, month=nikola.utils.LocaleBorg().get_month_name(int(month), lang)) - task = self.site.generic_post_list_renderer( - lang, - post_list, - output_name, - template_name, - kw['filters'], - context, - ) - task_cfg = {1: task['uptodate'][0].config, 2: kw, 3: len(post_list)} - task['uptodate'] = [config_changed(task_cfg)] - task['basename'] = self.name - yield task - - if not kw['create_single_archive']: + + kw["is_feed_stale"] = (datetime.datetime.utcnow().strftime("%Y/%m") != yearmonth) + + # Filter untranslated posts (via Issue #1360) + if not kw["show_untranslated_posts"]: + posts = [p for p in posts if lang in p.translated_to] + + if kw["create_monthly_archive"] or kw["create_full_archives"]: + title = kw["messages"][lang]["Posts for {month} {year}"].format( + year=year, month=nikola.utils.LocaleBorg().get_month_name(int(month), lang)) + yield self._generate_posts_task(kw, yearmonth, lang, posts, title) + + if not kw["create_full_archives"] and not kw["create_daily_archive"]: + continue # Just to avoid nesting the other loop in this if + # Add archive per day + days = dict() + for p in posts: + if p.date.day not in days: + days[p.date.day] = list() + days[p.date.day].append(p) + for day, posts in days.items(): + title = kw["messages"][lang]["Posts for {month} {day}, {year}"].format( + year=year, month=nikola.utils.LocaleBorg().get_month_name(int(month), lang), day=day) + yield self._generate_posts_task(kw, yearmonth + '/{0:02d}'.format(day), lang, posts, title) + + if not kw['create_single_archive'] and not kw['create_full_archives']: # And an "all your years" page for yearly and monthly archives + if "is_feed_stale" in kw: + del kw["is_feed_stale"] years = list(self.site.posts_per_year.keys()) years.sort(reverse=True) - template_name = "list.tmpl" kw['years'] = years for lang in kw["translations"]: - context = {} - output_name = os.path.join( - kw['output_folder'], self.site.path("archive", None, - lang)) - context["title"] = kw["messages"][lang]["Archive"] - context["items"] = [(y, self.site.link("archive", y, lang)) - for y in years] - context["permalink"] = self.site.link("archive", None, lang) - task = self.site.generic_post_list_renderer( - lang, - [], - output_name, - template_name, - kw['filters'], - context, - ) - task_cfg = {1: task['uptodate'][0].config, 2: kw, 3: len(years)} - task['uptodate'] = [config_changed(task_cfg)] - task['basename'] = self.name - yield task - - def archive_path(self, name, lang): + items = [(y, self.site.link("archive", y, lang)) for y in years] + yield self._prepare_task(kw, None, lang, None, items, "list.tmpl", kw["messages"][lang]["Archive"]) + + def archive_path(self, name, lang, is_feed=False): + if is_feed: + extension = ".atom" + archive_file = os.path.splitext(self.site.config['ARCHIVE_FILENAME'])[0] + extension + index_file = os.path.splitext(self.site.config['INDEX_FILE'])[0] + extension + else: + archive_file = self.site.config['ARCHIVE_FILENAME'] + index_file = self.site.config['INDEX_FILE'] if name: return [_f for _f in [self.site.config['TRANSLATIONS'][lang], self.site.config['ARCHIVE_PATH'], name, - self.site.config['INDEX_FILE']] if _f] + index_file] if _f] else: return [_f for _f in [self.site.config['TRANSLATIONS'][lang], self.site.config['ARCHIVE_PATH'], - self.site.config['ARCHIVE_FILENAME']] if _f] + archive_file] if _f] + + def archive_atom_path(self, name, lang): + return self.archive_path(name, lang, is_feed=True) |
