githublog.py 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122
  1. #!/usr/bin/env python
  2. """
  3. File: githublog.py
  4. This is a quick&dirty tool helping you generating a TOC file for blog repo based on Hugo.
  5. Usage:
  6. python githublog.py
  7. IMPORTANT
  8. Before starting, you should check that the working-directory is right at the root of
  9. the hugo blog and managed by git (is preferred)
  10. """
  11. import os
  12. import string
  13. import subprocess
  14. from posixpath import join as urljoin
  15. INTRO_NAME = '简介'
  16. INTRO_DESC = '''本站所有原创、翻译、引用都会随着时间进行更新'''
  17. POSTS_ROOT = 'content' # hugo root dir of posts.
  18. EXTS = ['.md', '.rst'] # post file extensions. (should be in lowercase)
  19. README = 'README.md' # filename to be generated.
  20. GITREPO = 'https://git.wenlabs.org/joe/blog' # repo address of blog code.
  21. BRANCH = 'master' # publish branch
  22. def get_git_remote():
  23. """ Get git remote url
  24. should be executed in git directory and with git installed.
  25. """
  26. proc = subprocess.Popen(['git', 'remote', '-v'], stdout=subprocess.PIPE, shell=True)
  27. (out, err) = proc.communicate()
  28. if err:
  29. return None
  30. lines = out.decode('utf-8').split('\n')
  31. if len(lines) < 2:
  32. return None
  33. parts = lines[1].split('\t')
  34. if len(parts) < 2:
  35. return None
  36. values = parts[1].split(' ')
  37. return None if len(values) < 1 else values[0]
  38. def get_git_branch():
  39. """ Get current git branch """
  40. pass
  41. def get_category(dir):
  42. '''
  43. Get blog category by directory strucure
  44. '''
  45. parts = dir.split(os.sep)
  46. return os.sep.join(parts[1:])
  47. # repo remote
  48. remote = get_git_remote() if not GITREPO else GITREPO
  49. if not remote:
  50. print('not a git repo, quit')
  51. exit(1)
  52. # current git branch
  53. branch = get_git_branch() if not BRANCH else BRANCH
  54. if not branch:
  55. print('no branch?')
  56. exit(1)
  57. # all posts, searching result
  58. # map[str][list]
  59. posts = {}
  60. ## find out all non-draft posts
  61. for r, dl, fl in os.walk(POSTS_ROOT):
  62. if fl:
  63. cate = get_category(r)
  64. posts[cate] = []
  65. for f in fl:
  66. _, ext = os.path.splitext(f)
  67. if ext.lower() not in EXTS:
  68. continue
  69. fullname = os.path.join(r, f)
  70. meta_started = False
  71. metas = {} # hugo post meta-info map[str]str
  72. with open(fullname, 'r', encoding='utf-8') as h:
  73. line = h.readline().strip()
  74. while line:
  75. if line == '---':
  76. if not meta_started:
  77. meta_started = True
  78. else:
  79. break # from while
  80. else:
  81. parts = line.split(': ')
  82. if len(parts) != 2:
  83. break # from while
  84. metas[parts[0].strip().lower()] = parts[1].strip().lower()
  85. line = h.readline().strip()
  86. if metas.get('draft') == 'false':
  87. metas['file'] = f
  88. posts[cate].append(metas)
  89. ## generate README.md
  90. with open(README, 'wt', encoding='utf-8') as h:
  91. h.write(f'## {INTRO_NAME}\n\n')
  92. h.write(f'{INTRO_DESC}\n\n')
  93. for cate, metalist in posts.items():
  94. h.write('## {}\n\n'.format(cate))
  95. # sortint posts by published date.
  96. metalist = sorted(metalist, key=lambda metas: metas.get('date'), reverse=True)
  97. for metas in metalist:
  98. h.write('- [{}]({})\n'.format(metas.get('title').strip('"'), urljoin(remote, 'src', branch, POSTS_ROOT, cate, metas.get('file'))))
  99. h.write('\n')
  100. print('done.')