filetime_from_hg.py 2.8 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182
  1. # -*- coding: utf-8 -*-
  2. """
  3. This plugin is mostly a copy of the filetime_from_git plugin
  4. by Zhang Cheng <StephenPCG@gmail.com> and others.
  5. Copyright (c) David Douard <david.douard@sdfa3.org>
  6. Compute Date and Modified metadata from Mercurial revisions.
  7. """
  8. import os
  9. from pelican import signals, contents
  10. from pelican.utils import strftime, set_date_tzinfo
  11. from datetime import datetime
  12. import hglib
  13. def datetime_from_timestamp(timestamp, content):
  14. """
  15. Helper function to add timezone information to datetime,
  16. so that datetime is comparable to other datetime objects in recent versions
  17. that now also have timezone information.
  18. """
  19. return set_date_tzinfo(
  20. datetime.fromtimestamp(timestamp),
  21. tz_name=content.settings.get('TIMEZONE', None))
  22. def filetime_from_hg(content):
  23. if isinstance(content, contents.Static):
  24. return
  25. if 'date' in content.metadata:
  26. # if user did explicitely set a date, do not overwrite it
  27. return
  28. repo = hglib.open('.')
  29. tz_name = content.settings.get('TIMEZONE', None)
  30. hgtime = content.metadata.get('hgtime', 'yes').lower()
  31. if hgtime in ('no', 'off', 'false', '0'):
  32. return
  33. # 1. file is not managed by hg
  34. # date: fs time
  35. # 2. file is staged, but has no commits
  36. # date: fs time
  37. # 3. file is managed, and clean
  38. # date: first commit time, update: last commit time or None
  39. # 4. file is managed, but dirty
  40. # date: first commit time, update: fs time
  41. path = content.source_path
  42. root = repo.root()
  43. filelog = repo.log(revrange='.:0', files=[path,],
  44. follow=content.settings.get('HG_FILETIME_FOLLOW', False))
  45. if filelog:
  46. # has commited
  47. content.date = set_date_tzinfo(filelog[-1][6], tz_name)
  48. if path in [os.path.join(root, mfile) for flag, mfile in repo.status(modified=True)]:
  49. # file is modified in the wd
  50. content.modified = datetime_from_timestamp(
  51. os.stat(path).st_ctime, content)
  52. else:
  53. # file is not changed
  54. if len(filelog) > 1:
  55. content.modified = set_date_tzinfo(filelog[0][6], tz_name)
  56. else:
  57. # file is not managed by hg
  58. content.date = datetime_from_timestamp(os.stat(path).st_ctime, content)
  59. if not hasattr(content, 'modified'):
  60. content.modified = content.date
  61. content.locale_date = strftime(content.date, content.date_format)
  62. content.locale_modified = strftime(content.modified, content.date_format)
  63. # ensure the metadata directory is synchronized. Might be used by
  64. # some other plugin (eg. series)
  65. content.metadata['modified'] = content.modified
  66. content.metadata['date'] = content.date
  67. def register():
  68. signals.content_object_init.connect(filetime_from_hg)