filetime_from_git.py 2.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970
  1. #!/usr/bin/env python
  2. # -*- coding: utf-8 -*-
  3. import os
  4. from git import Git, Repo, InvalidGitRepositoryError
  5. from pelican import signals, contents
  6. from datetime import datetime
  7. from time import mktime, altzone
  8. from pelican.utils import strftime
  9. try:
  10. repo = Repo(os.path.abspath('.'))
  11. git = Git(os.path.abspath('.'))
  12. except InvalidGitRepositoryError as e:
  13. repo = None
  14. def filetime_from_git(content):
  15. if isinstance(content, contents.Static) or repo is None:
  16. return
  17. gittime = content.metadata.get('gittime', 'yes').lower()
  18. gittime = gittime.replace("false", "no").replace("off", "no")
  19. if gittime == "no":
  20. return
  21. # 1. file is not managed by git
  22. # date: fs time
  23. # 2. file is staged, but has no commits
  24. # date: fs time
  25. # 3. file is managed, and clean
  26. # date: first commit time, update: last commit time or None
  27. # 4. file is managed, but dirty
  28. # date: first commit time, update: fs time
  29. path = content.source_path
  30. status, stdout, stderr = git.execute(['git', 'ls-files', path, '--error-unmatch'],
  31. with_extended_output=True, with_exceptions=False)
  32. if status != 0:
  33. # file is not managed by git
  34. content.date = datetime.fromtimestamp(os.stat(path).st_ctime)
  35. else:
  36. # file is managed by git
  37. commits = repo.commits(path=path)
  38. if len(commits) == 0:
  39. # never commited, but staged
  40. content.date = datetime.fromtimestamp(os.stat(path).st_ctime)
  41. else:
  42. # has commited
  43. content.date = datetime.fromtimestamp(mktime(commits[-1].committed_date) - altzone)
  44. status, stdout, stderr = git.execute(['git', 'diff', '--quiet', 'HEAD', path],
  45. with_extended_output=True, with_exceptions=False)
  46. if status != 0:
  47. # file has changed
  48. content.modified = datetime.fromtimestamp(os.stat(path).st_ctime)
  49. else:
  50. # file is not changed
  51. if len(commits) > 1:
  52. content.modified = datetime.fromtimestamp(mktime(commits[0].committed_date) - altzone)
  53. if not hasattr(content, 'modified'):
  54. content.modified = content.date
  55. if hasattr(content, 'date'):
  56. content.locale_date = strftime(content.date, content.date_format)
  57. if hasattr(content, 'modified'):
  58. content.locale_modified = strftime(content.modified, content.date_format)
  59. def register():
  60. signals.content_object_init.connect(filetime_from_git)