From e14213b2e97423c96c747fd4da91c30705bcbbce Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rn=20Schumacher?= Date: Sun, 9 Jun 2013 17:30:58 +0200 Subject: [PATCH] Add DEFAULT_DATE hooks to use git modification times as date metadata. The DEFAULT_DATE options 'git-last-modified' and 'git-creation' were added. 'git log' is called in order to retrieve a list of modification times. Implementation of git-last-modified and git-creation --- pelican/generators.py | 8 +++++++- pelican/utils.py | 28 ++++++++++++++++++++++++++++ 2 files changed, 35 insertions(+), 1 deletion(-) diff --git a/pelican/generators.py b/pelican/generators.py index 75b61df2..026d4207 100644 --- a/pelican/generators.py +++ b/pelican/generators.py @@ -23,7 +23,9 @@ from pelican.contents import ( Article, Page, Category, Static, is_valid_content ) from pelican.readers import read_file -from pelican.utils import copy, process_translations, mkdir_p, DateFormatter +from pelican.utils import ( + copy, process_translations, mkdir_p, DateFormatter, git_mtime +) from pelican import signals import pelican.utils @@ -407,6 +409,10 @@ class ArticlesGenerator(Generator): if self.settings['DEFAULT_DATE'] == 'fs': metadata['date'] = datetime.datetime.fromtimestamp( os.stat(f).st_ctime) + elif self.settings['DEFAULT_DATE'] == 'git-last-modified': + metadata['date'] = git_mtime(f, True) + elif self.settings['DEFAULT_DATE'] == 'git-creation': + metadata['date'] = git_mtime(f, False) else: metadata['date'] = datetime.datetime( *self.settings['DEFAULT_DATE']) diff --git a/pelican/utils.py b/pelican/utils.py index 4e7bdbd1..c335f5bd 100644 --- a/pelican/utils.py +++ b/pelican/utils.py @@ -11,6 +11,7 @@ import logging import errno import locale import fnmatch +import subprocess from collections import Hashable from functools import partial @@ -549,3 +550,30 @@ def split_all(path): break path = head return components + + +def git_mtime(filename, use_last_modification=True, git_binary="git"): + + """Determines the git modification time of a file and returns it as a + datetime.datetime object. + + If use_last_modification is True, then the date and time of the last + modification will be returned. Otherwise the date and time of the first + commit containing the file will be returned. + + The optional argument 'git_binary' can be used to specify the git binary to + use. + """ + + call = [git_binary, "log", "--pretty=format:%at ", filename] + repository= os.path.dirname(filename) + try: + output = subprocess.check_output(call, cwd=repository).decode('utf-8').splitlines() + except Exception as e: + print("ERROR: Could not get git time information for {0}: {1}".format(filename, str(e))) + return None + + dates = [ datetime.fromtimestamp(int(x)) for x in output ] + sorted_dates = sorted(dates) + + return sorted_dates[-1] if use_last_modification else sorted_dates[0]