Skip to content

Commit 1fa16b2

Browse files
committed
About: Support new changelog format
- Rework parsing into reusable function - Add second parser for alternate changelog format - Simplify initial detection, only check if file exists - Hide tabs for any missing/unreadable changelogs
1 parent 73490de commit 1fa16b2

File tree

1 file changed

+104
-76
lines changed

1 file changed

+104
-76
lines changed

src/windows/about.py

+104-76
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828

2929
import os
3030
import codecs
31+
import re
3132
from functools import partial
3233

3334
from PyQt5.QtCore import *
@@ -43,6 +44,54 @@
4344
import json
4445
import datetime
4546

47+
48+
def parse_changelog(changelog_path):
49+
"""Read changelog entries from provided file path."""
50+
changelog_list = []
51+
if not os.path.exists(changelog_path):
52+
return None
53+
# Attempt to open changelog with utf-8, and then utf-16 (for unix / windows support)
54+
for encoding_name in ('utf_8', 'utf_16'):
55+
try:
56+
with codecs.open(changelog_path, 'r', encoding=encoding_name) as changelog_file:
57+
for line in changelog_file:
58+
changelog_list.append({'hash': line[:9].strip(),
59+
'date': line[9:20].strip(),
60+
'author': line[20:45].strip(),
61+
'subject': line[45:].strip() })
62+
break
63+
except:
64+
log.warning('Failed to parse log file %s with encoding %s' % (changelog_path, encoding_name))
65+
return changelog_list
66+
67+
68+
def parse_new_changelog(changelog_path):
69+
"""Parse changelog data from specified new-format file."""
70+
if not os.path.exists(changelog_path):
71+
return None
72+
changelog_list = None
73+
for encoding_name in ('utf_8', 'utf_16'):
74+
try:
75+
with codecs.open(changelog_path, 'r', encoding=encoding_name) as changelog_file:
76+
# Generate match object with fields from all matching lines
77+
matches = re.findall(
78+
r"^-\s?([0-9a-f]{40})\s(\d{4,4}-\d{2,2}-\d{2,2})\s(.*)\s\[(.*)\]\s*$",
79+
changelog_file.read(), re.MULTILINE)
80+
log.debug("Parsed {} changelog lines from {}".format(len(matches), changelog_file))
81+
changelog_list = [{
82+
"hash": entry[0],
83+
"date": entry[1],
84+
"subject": entry[2],
85+
"author": entry[3],
86+
} for entry in matches]
87+
except UnicodeError:
88+
log.debug('Failed to parse log file %s with encoding %s' % (changelog_path, encoding_name))
89+
continue
90+
except Exception:
91+
log.warning("Parse error reading {}".format(changelog_path), exc_info=1)
92+
return None
93+
return changelog_list
94+
4695
class About(QDialog):
4796
""" About Dialog """
4897

@@ -64,18 +113,15 @@ def __init__(self):
64113

65114
# Hide chnagelog button by default
66115
self.btnchangelog.setVisible(False)
67-
for project in ['openshot-qt', 'libopenshot', 'libopenshot-audio']:
68-
changelog_path = os.path.join(info.PATH, 'settings', '%s.log' % project)
69-
if os.path.exists(changelog_path):
70-
# Attempt to open changelog with utf-8, and then utf-16-le (for unix / windows support)
71-
for encoding_name in ('utf_8', 'utf_16'):
72-
try:
73-
with codecs.open(changelog_path, 'r', encoding=encoding_name) as changelog_file:
74-
if changelog_file.read():
75-
self.btnchangelog.setVisible(True)
76-
break
77-
except:
78-
log.warning('Failed to parse log file %s with encoding %s' % (changelog_path, encoding_name))
116+
projects = ['openshot-qt', 'libopenshot', 'libopenshot-audio']
117+
# Old paths
118+
paths = [os.path.join(info.PATH, 'settings', '{}.log'.format(p)) for p in projects]
119+
# New paths
120+
paths.extend([os.path.join(info.PATH, 'resources', '{}.log'.format(p)) for p in projects])
121+
if any([os.path.exists(path) for path in paths]):
122+
self.btnchangelog.setVisible(True)
123+
else:
124+
log.warn("No changelog files found, disabling button")
79125

80126
create_text = _('Create & Edit Amazing Videos and Movies')
81127
description_text = _('OpenShot Video Editor 2.x is the next generation of the award-winning <br/>OpenShot video editing platform.')
@@ -222,7 +268,7 @@ def __init__(self):
222268
self.supportersListView = CreditsTreeView(supporter_list, columns=["website"])
223269
self.vboxSupporters.addWidget(self.supportersListView)
224270
self.txtSupporterFilter.textChanged.connect(partial(self.Filter_Triggered, self.txtSupporterFilter, self.supportersListView))
225-
271+
7
226272

227273
class Changelog(QDialog):
228274
""" Changelog Dialog """
@@ -246,72 +292,54 @@ def __init__(self):
246292
ui_util.init_ui(self)
247293

248294
# get translations
249-
self.app = get_app()
250-
_ = self.app._tr
295+
_ = get_app()._tr
296+
297+
# Connections to objects imported from .ui file
298+
tab = {
299+
"openshot-qt": self.tab_openshot_qt,
300+
"libopenshot": self.tab_libopenshot,
301+
"libopenshot-audio": self.tab_libopenshot_audio,
302+
}
303+
vbox = {
304+
"openshot-qt": self.vbox_openshot_qt,
305+
"libopenshot": self.vbox_libopenshot,
306+
"libopenshot-audio": self.vbox_libopenshot_audio,
307+
}
308+
filter = {
309+
"openshot-qt": self.txtChangeLogFilter_openshot_qt,
310+
"libopenshot": self.txtChangeLogFilter_libopenshot,
311+
"libopenshot-audio": self.txtChangeLogFilter_libopenshot_audio,
312+
}
251313

252314
# Update github link button
253315
github_text = _("OpenShot on GitHub")
254316
github_html = '<html><head/><body><p align="center"><a href="https://github.com/OpenShot/"><span style=" text-decoration: underline; color:#55aaff;">%s</span></a></p></body></html>' % (github_text)
255317
self.lblGitHubLink.setText(github_html)
256318

257-
# Get changelog for openshot-qt (if any)
258-
changelog_list = []
259-
changelog_path = os.path.join(info.PATH, 'settings', 'openshot-qt.log')
260-
if os.path.exists(changelog_path):
261-
# Attempt to open changelog with utf-8, and then utf-16-le (for unix / windows support)
262-
for encoding_name in ('utf_8', 'utf_16'):
263-
try:
264-
with codecs.open(changelog_path, 'r', encoding=encoding_name) as changelog_file:
265-
for line in changelog_file:
266-
changelog_list.append({'hash': line[:9].strip(),
267-
'date': line[9:20].strip(),
268-
'author': line[20:45].strip(),
269-
'subject': line[45:].strip() })
270-
break
271-
except:
272-
log.warning('Failed to parse log file %s with encoding %s' % (changelog_path, encoding_name))
273-
self.openshot_qt_ListView = ChangelogTreeView(commits=changelog_list, commit_url="https://github.com/OpenShot/openshot-qt/commit/%s/")
274-
self.vbox_openshot_qt.addWidget(self.openshot_qt_ListView)
275-
self.txtChangeLogFilter_openshot_qt.textChanged.connect(partial(self.Filter_Triggered, self.txtChangeLogFilter_openshot_qt, self.openshot_qt_ListView))
276-
277-
# Get changelog for libopenshot (if any)
278-
changelog_list = []
279-
changelog_path = os.path.join(info.PATH, 'settings', 'libopenshot.log')
280-
if os.path.exists(changelog_path):
281-
# Attempt to open changelog with utf-8, and then utf-16-le (for unix / windows support)
282-
for encoding_name in ('utf_8', 'utf_16'):
283-
try:
284-
with codecs.open(changelog_path, 'r', encoding=encoding_name) as changelog_file:
285-
for line in changelog_file:
286-
changelog_list.append({'hash': line[:9].strip(),
287-
'date': line[9:20].strip(),
288-
'author': line[20:45].strip(),
289-
'subject': line[45:].strip() })
290-
break
291-
except:
292-
log.warning('Failed to parse log file %s with encoding %s' % (changelog_path, encoding_name))
293-
self.libopenshot_ListView = ChangelogTreeView(commits=changelog_list, commit_url="https://github.com/OpenShot/libopenshot/commit/%s/")
294-
self.vbox_libopenshot.addWidget(self.libopenshot_ListView)
295-
self.txtChangeLogFilter_libopenshot.textChanged.connect(partial(self.Filter_Triggered, self.txtChangeLogFilter_libopenshot, self.libopenshot_ListView))
296-
297-
# Get changelog for libopenshot-audio (if any)
298-
changelog_list = []
299-
changelog_path = os.path.join(info.PATH, 'settings', 'libopenshot-audio.log')
300-
if os.path.exists(changelog_path):
301-
# Attempt to support Linux- and Windows-encoded files by opening
302-
# changelog with utf-8, then utf-16 (endianness via the BOM, which
303-
# gets filtered out automatically by the decoder)
304-
for encoding_name in ('utf_8', 'utf_16'):
305-
try:
306-
with codecs.open(changelog_path, 'r', encoding=encoding_name) as changelog_file:
307-
for line in changelog_file:
308-
changelog_list.append({'hash': line[:9].strip(),
309-
'date': line[9:20].strip(),
310-
'author': line[20:45].strip(),
311-
'subject': line[45:].strip() })
312-
break
313-
except:
314-
log.warning('Failed to parse log file %s with encoding %s' % (changelog_path, encoding_name))
315-
self.libopenshot_audio_ListView = ChangelogTreeView(commits=changelog_list, commit_url="https://github.com/OpenShot/libopenshot-audio/commit/%s/")
316-
self.vbox_libopenshot_audio.addWidget(self.libopenshot_audio_ListView)
317-
self.txtChangeLogFilter_libopenshot_audio.textChanged.connect(partial(self.Filter_Triggered, self.txtChangeLogFilter_libopenshot_audio, self.libopenshot_audio_ListView))
319+
# Read changelog file for each project
320+
for project in ['openshot-qt', 'libopenshot', 'libopenshot-audio']:
321+
new_changelog_path = os.path.join(info.PATH, 'resources', '{}.log'.format(project))
322+
old_changelog_path = os.path.join(info.PATH, 'settings', '{}.log'.format(project))
323+
if os.path.exists(new_changelog_path):
324+
log.debug("Reading changelog file: {}".format(new_changelog_path))
325+
changelog_list = parse_new_changelog(new_changelog_path)
326+
elif os.path.isfile(old_changelog_path):
327+
log.debug("Reading legacy changelog file: {}".format(old_changelog_path))
328+
changelog_list = parse_changelog(old_changelog_path)
329+
else:
330+
changelog_list = None
331+
# Hopefully we found ONE of the two
332+
if changelog_list is None:
333+
log.warn("Could not load changelog for {}".format(project))
334+
# Hide the tab for this changelog
335+
tabindex = self.tabChangelog.indexOf(tab[project])
336+
if tabindex >= 0:
337+
self.tabChangelog.removeTab(tabindex)
338+
continue
339+
# Populate listview widget with changelog data
340+
cl_treeview = ChangelogTreeView(
341+
commits=changelog_list,
342+
commit_url="https://github.com/OpenShot/{}/commit/%s/".format(project))
343+
vbox[project].addWidget(cl_treeview)
344+
filter[project].textChanged.connect(
345+
partial(self.Filter_Triggered, filter[project], cl_treeview))

0 commit comments

Comments
 (0)