Skip to content
This repository was archived by the owner on May 22, 2025. It is now read-only.

Commit d2de91a

Browse files
committed
Update ss13_genchangelog.py
1 parent 16e6afe commit d2de91a

File tree

1 file changed

+47
-126
lines changed

1 file changed

+47
-126
lines changed

tools/ss13_genchangelog.py

Lines changed: 47 additions & 126 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
'''
22
Usage:
3-
$ python ss13_genchangelog.py [--dry-run] html/changelog.html html/changelogs/
3+
$ python ss13_genchangelog.py html/changelogs/
44
55
ss13_genchangelog.py - Generate changelog from YAML.
66
@@ -32,31 +32,29 @@
3232

3333
today = date.today()
3434

35-
dateformat = "%d %B %Y"
35+
fileDateFormat = "%Y-%m"
3636

3737
opt = argparse.ArgumentParser()
38-
opt.add_argument('-d', '--dry-run', dest='dryRun', default=False, action='store_true', help='Only parse changelogs and, if needed, the targetFile. (A .dry_changelog.yml will be output for debugging purposes.)')
39-
opt.add_argument('-t', '--time-period', dest='timePeriod', default=13, type=int, help='Define how many weeks back the changelog should display')
40-
opt.add_argument('targetFile', help='The HTML changelog we wish to update.')
4138
opt.add_argument('ymlDir', help='The directory of YAML changelogs we will use.')
4239

4340
args = opt.parse_args()
41+
archiveDir = os.path.join(args.ymlDir, 'archive')
4442

4543
all_changelog_entries = {}
4644

45+
# Do not change the order, add to the bottom of the array if necessary
4746
validPrefixes = [
4847
'bugfix',
4948
'wip',
50-
'tweak',
49+
'qol',
5150
'soundadd',
5251
'sounddel',
53-
'rscdel',
5452
'rscadd',
53+
'rscdel',
5554
'imageadd',
5655
'imagedel',
5756
'spellcheck',
5857
'experiment',
59-
'tgs',
6058
'balance',
6159
'code_imp',
6260
'refactor',
@@ -68,87 +66,61 @@
6866
def dictToTuples(inp):
6967
return [(k, v) for k, v in inp.items()]
7068

71-
changelog_cache = os.path.join(args.ymlDir, '.all_changelog.yml')
69+
old_changelog_cache = os.path.join(args.ymlDir, '.all_changelog.yml')
7270

73-
failed_cache_read = True
74-
if os.path.isfile(changelog_cache):
71+
if os.path.isfile(old_changelog_cache):
7572
try:
76-
with open(changelog_cache,encoding='utf-8') as f:
73+
print('Reading old changelog cache...')
74+
data = {}
75+
with open(old_changelog_cache,encoding='utf-8') as f:
7776
(_, all_changelog_entries) = yaml.load_all(f, Loader=yaml.SafeLoader)
78-
failed_cache_read = False
7977

80-
# Convert old timestamps to newer format.
81-
new_entries = {}
78+
# Categorize changes by year and month
8279
for _date in all_changelog_entries.keys():
8380
ty = type(_date).__name__
84-
# print(ty)
85-
if ty in ['str', 'unicode']:
86-
temp_data = all_changelog_entries[_date]
87-
_date = datetime.strptime(_date, dateformat).date()
88-
new_entries[_date] = temp_data
89-
else:
90-
new_entries[_date] = all_changelog_entries[_date]
91-
all_changelog_entries = new_entries
81+
formattedDate = _date.strftime(fileDateFormat)
82+
if not formattedDate in data:
83+
data[formattedDate] = {}
84+
data[formattedDate][_date] = all_changelog_entries[_date]
85+
# Write files with changes by year and month
86+
for month in data.keys():
87+
print("Writing " + month + ".yml...")
88+
if not os.path.exists(archiveDir):
89+
os.makedirs(archiveDir)
90+
currentFile = os.path.join(archiveDir, month + '.yml')
91+
with open(currentFile, 'w', encoding='utf-8') as f:
92+
yaml.dump(data[month], f, default_flow_style=False)
93+
# Remove the old changelog cache, as we won't use it anymore
94+
print("Removing old changelog cache...")
95+
os.remove(old_changelog_cache)
96+
old_changelog_html = os.path.join(args.ymlDir, '..', 'changelog.html')
97+
if os.path.isfile(old_changelog_html):
98+
print("Removing old changelog html...")
99+
os.remove(old_changelog_html)
92100
except Exception as e:
93-
print("Failed to read cache:")
101+
print("Failed to read old changelog cache:")
94102
print(e, file=sys.stderr)
95103

96-
if args.dryRun:
97-
changelog_cache = os.path.join(args.ymlDir, '.dry_changelog.yml')
98-
99-
if failed_cache_read and os.path.isfile(args.targetFile):
100-
from bs4 import BeautifulSoup
101-
from bs4.element import NavigableString
102-
print(' Generating cache...')
103-
with open(args.targetFile, 'r', encoding='utf-8') as f:
104-
soup = BeautifulSoup(f)
105-
for e in soup.find_all('div', {'class':'commit'}):
106-
entry = {}
107-
date = datetime.strptime(e.h2.string.strip(), dateformat).date() # key
108-
for authorT in e.find_all('h3', {'class':'author'}):
109-
author = authorT.string
110-
# Strip suffix
111-
if author.endswith('updated:'):
112-
author = author[:-8]
113-
author = author.strip()
114-
115-
# Find <ul>
116-
ulT = authorT.next_sibling
117-
while(ulT.name != 'ul'):
118-
ulT = ulT.next_sibling
119-
changes = []
120-
121-
for changeT in ulT.children:
122-
if changeT.name != 'li': continue
123-
val = changeT.decode_contents(formatter="html")
124-
newdat = {changeT['class'][0] + '': val + ''}
125-
if newdat not in changes:
126-
changes += [newdat]
127-
128-
if len(changes) > 0:
129-
130-
entry[author] = changes
131-
if date in all_changelog_entries:
132-
all_changelog_entries[date].update(entry)
133-
else:
134-
all_changelog_entries[date] = entry
135-
136-
del_after = []
137104
print('Reading changelogs...')
138105
for fileName in glob.glob(os.path.join(args.ymlDir, "*.yml")):
139106
name, ext = os.path.splitext(os.path.basename(fileName))
140107
if name.startswith('.'): continue
141108
if name == 'example': continue
142109
fileName = os.path.abspath(fileName)
110+
formattedDate = today.strftime(fileDateFormat)
111+
monthFile = os.path.join(archiveDir, formattedDate + '.yml')
143112
print(' Reading {}...'.format(fileName))
144113
cl = {}
145114
with open(fileName, 'r',encoding='utf-8') as f:
146115
cl = yaml.load(f, Loader=yaml.SafeLoader)
147-
f.close()
148-
if today not in all_changelog_entries:
149-
all_changelog_entries[today] = {}
150-
author_entries = all_changelog_entries[today].get(cl['author'], [])
151-
if cl['changes']:
116+
currentEntries = {}
117+
if os.path.exists(monthFile):
118+
with open(monthFile,'r',encoding='utf-8') as f:
119+
currentEntries = yaml.load(f, Loader=yaml.SafeLoader)
120+
if today not in currentEntries:
121+
currentEntries[today] = {}
122+
author_entries = currentEntries[today].get(cl['author'], [])
123+
if len(cl['changes']):
152124
new = 0
153125
for change in cl['changes']:
154126
if change not in author_entries:
@@ -157,65 +129,14 @@ def dictToTuples(inp):
157129
print(' {0}: Invalid prefix {1}'.format(fileName, change_type), file=sys.stderr)
158130
author_entries += [change]
159131
new += 1
160-
all_changelog_entries[today][cl['author']] = author_entries
132+
currentEntries[today][cl['author']] = author_entries
161133
if new > 0:
162134
print(' Added {0} new changelog entries.'.format(new))
163135

164136
if cl.get('delete-after', False):
165137
if os.path.isfile(fileName):
166-
if args.dryRun:
167-
print(' Would delete {0} (delete-after set)...'.format(fileName))
168-
else:
169-
del_after += [fileName]
170-
171-
if args.dryRun: continue
172-
173-
cl['changes'] = []
174-
with open(fileName, 'w', encoding='utf-8') as f:
175-
yaml.dump(cl, f, default_flow_style=False)
176-
177-
targetDir = os.path.dirname(args.targetFile)
178-
179-
with open(args.targetFile.replace('.htm', '.dry.htm') if args.dryRun else args.targetFile, 'w', encoding='utf-8') as changelog:
180-
with open(os.path.join(targetDir, 'templates', 'header.html'), 'r', encoding='utf-8') as h:
181-
for line in h:
182-
changelog.write(line)
183-
184-
weekstoshow = timedelta(weeks=args.timePeriod)
185-
for _date in reversed(sorted(all_changelog_entries.keys())):
186-
if not (today - _date < weekstoshow):
187-
continue
188-
entry_htm = '\n'
189-
entry_htm += '\t\t\t<h2 class="date">{date}</h2>\n'.format(date=_date.strftime(dateformat))
190-
write_entry = False
191-
for author in sorted(all_changelog_entries[_date].keys()):
192-
if not all_changelog_entries[_date]: continue
193-
author_htm = '\t\t\t<h3 class="author">{author} updated:</h3>\n'.format(author=author)
194-
author_htm += '\t\t\t<ul class="changes bgimages16">\n'
195-
changes_added = []
196-
for (css_class, change) in (dictToTuples(e)[0] for e in all_changelog_entries[_date][author]):
197-
if change in changes_added: continue
198-
write_entry = True
199-
changes_added += [change]
200-
author_htm += '\t\t\t\t<li class="{css_class}">{change}</li>\n'.format(css_class=css_class, change=change.strip())
201-
author_htm += '\t\t\t</ul>\n'
202-
if changes_added:
203-
entry_htm += author_htm
204-
if write_entry:
205-
changelog.write(entry_htm)
206-
207-
with open(os.path.join(targetDir, 'templates', 'footer.html'), 'r', encoding='utf-8') as h:
208-
for line in h:
209-
changelog.write(line)
210-
211-
212-
with open(changelog_cache, 'w') as f:
213-
cache_head = 'DO NOT EDIT THIS FILE BY HAND! AUTOMATICALLY GENERATED BY ss13_genchangelog.py.'
214-
yaml.dump_all([cache_head, all_changelog_entries], f, default_flow_style=False)
215-
216-
if del_after:
217-
print('Cleaning up...')
218-
for fileName in del_after:
219-
if os.path.isfile(fileName):
220-
print(' Deleting {0} (delete-after set)...'.format(fileName))
138+
print(' Deleting {0} (delete-after set)...'.format(fileName))
221139
os.remove(fileName)
140+
141+
with open(monthFile, 'w', encoding='utf-8') as f:
142+
yaml.dump(currentEntries, f, default_flow_style=False)

0 commit comments

Comments
 (0)