mirror of
https://github.com/fergalmoran/picard.git
synced 2026-01-06 16:44:06 +00:00
Move PROGRAM_UPDATE_LEVELS to picard.constants
- Move PROGRAM_UPDATE_LEVELS to picard.constants - Logging changes - Formatting and translation clean-up - Change picard.const.PROGRAM_UPDATE_LEVELS to numeric keys - Add releases endpoint to picard.const.PLUGINS_API - Refactor to remove duplicated code in mainwindow.py - General cleanup of debug log translations - Use intermediate variables to cache config information
This commit is contained in:
@@ -24,26 +24,12 @@ PICARD_ORG_NAME = "MusicBrainz"
|
||||
PICARD_APP_NAME = "Picard"
|
||||
PICARD_VERSION = (2, 0, 4, 'dev', 1)
|
||||
|
||||
|
||||
# optional build version
|
||||
# it should be in the form '<platform>_<YYMMDDHHMMSS>'
|
||||
# ie. win32_20140415091256
|
||||
PICARD_BUILD_VERSION_STR = ""
|
||||
|
||||
PROGRAM_UPDATE_LEVELS = {
|
||||
'stable': {
|
||||
'level': 0,
|
||||
'title': 'Stable releases only',
|
||||
},
|
||||
'beta': {
|
||||
'level': 1,
|
||||
'title': 'Stable and Beta releases',
|
||||
},
|
||||
'dev': {
|
||||
'level': 2,
|
||||
'title': 'Stable, Beta and Dev releases',
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
class VersionError(Exception):
|
||||
pass
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
|
||||
from collections import OrderedDict
|
||||
import os
|
||||
import sys
|
||||
|
||||
@@ -101,13 +102,14 @@ MUSICBRAINZ_SERVERS = [
|
||||
'beta.musicbrainz.org',
|
||||
]
|
||||
|
||||
# Plugins API
|
||||
# Plugins and Release Versions API
|
||||
PLUGINS_API = {
|
||||
'host': 'picard.musicbrainz.org',
|
||||
'port': 443,
|
||||
'endpoint': {
|
||||
'plugins': '/api/v2/plugins/',
|
||||
'download': '/api/v2/download/'
|
||||
'download': '/api/v2/download/',
|
||||
'releases': '/api/releases',
|
||||
}
|
||||
}
|
||||
|
||||
@@ -116,3 +118,27 @@ QUERY_LIMIT = 25
|
||||
|
||||
# Maximum number of covers to draw in a stack in CoverArtThumbnail
|
||||
MAX_COVERS_TO_STACK = 4
|
||||
|
||||
# Update levels available for automatic checking
|
||||
PROGRAM_UPDATE_LEVELS = OrderedDict(
|
||||
[
|
||||
(
|
||||
0, {
|
||||
'name': 'stable',
|
||||
'title': N_('Stable releases only'),
|
||||
}
|
||||
),
|
||||
(
|
||||
1, {
|
||||
'name': 'beta',
|
||||
'title': N_('Stable and Beta releases'),
|
||||
}
|
||||
),
|
||||
(
|
||||
2, {
|
||||
'name': 'dev',
|
||||
'title': N_('Stable, Beta and Dev releases'),
|
||||
}
|
||||
),
|
||||
]
|
||||
)
|
||||
|
||||
@@ -83,6 +83,7 @@ from picard.util import (
|
||||
uniqify,
|
||||
versions,
|
||||
)
|
||||
from picard.util.checkupdate import UpdateCheckManager
|
||||
from picard.webservice import WebService
|
||||
from picard.webservice.api_helpers import (
|
||||
AcoustIdAPIHelper,
|
||||
@@ -97,8 +98,6 @@ from picard.ui.searchdialog.album import AlbumSearchDialog
|
||||
from picard.ui.searchdialog.artist import ArtistSearchDialog
|
||||
from picard.ui.searchdialog.track import TrackSearchDialog
|
||||
|
||||
from picard.util.checkupdate import UpdateCheckManager
|
||||
|
||||
|
||||
# A "fix" for https://bugs.python.org/issue1438480
|
||||
def _patched_shutil_copystat(src, dst, *, follow_symlinks=True):
|
||||
|
||||
@@ -31,10 +31,10 @@ from PyQt5 import (
|
||||
from picard import (
|
||||
config,
|
||||
log,
|
||||
PROGRAM_UPDATE_LEVELS,
|
||||
)
|
||||
from picard.album import Album
|
||||
from picard.cluster import Cluster
|
||||
from picard.const import PROGRAM_UPDATE_LEVELS
|
||||
from picard.file import File
|
||||
from picard.formats import supported_formats
|
||||
from picard.plugin import ExtensionPoint
|
||||
@@ -176,19 +176,7 @@ class MainWindow(QtWidgets.QMainWindow, PreserveGeometry):
|
||||
def show(self):
|
||||
self.restoreWindowState()
|
||||
super().show()
|
||||
for key in PROGRAM_UPDATE_LEVELS.keys():
|
||||
if PROGRAM_UPDATE_LEVELS[key]['level'] == config.setting["update_level"]:
|
||||
update_level_text = key
|
||||
do_auto_update_check = config.setting['check_for_updates'] and config.setting['update_check_days'] > 0 and datetime.date.today().toordinal() >= config.persist['last_update_check'] + config.setting['update_check_days']
|
||||
log.debug(_("{check_status} start-up check for program updates. Today: {today_date}, Last check: {last_check} (Check interval: {check_interval} days), Update level: {update_level}".format(
|
||||
check_status='Initiating' if do_auto_update_check else 'Skipping',
|
||||
today_date=datetime.date.today(),
|
||||
last_check=str(datetime.date.fromordinal(config.persist['last_update_check'])) if config.persist['last_update_check'] > 0 else 'never',
|
||||
check_interval=config.setting['update_check_days'],
|
||||
update_level=update_level_text if update_level_text else 'unknown',
|
||||
)))
|
||||
if do_auto_update_check:
|
||||
self.tagger.updatecheckmanager.check_update(show_always=False, update_level=config.setting["update_level"], callback=update_last_check_date)
|
||||
self.auto_update_check()
|
||||
self.metadata_box.restore_state()
|
||||
|
||||
def closeEvent(self, event):
|
||||
@@ -551,7 +539,7 @@ class MainWindow(QtWidgets.QMainWindow, PreserveGeometry):
|
||||
self.open_folder_action.triggered.connect(self.open_folder)
|
||||
|
||||
self.check_update_action = QtWidgets.QAction(_("&Check for Update"), self)
|
||||
self.check_update_action.triggered.connect(self.check_for_update)
|
||||
self.check_update_action.triggered.connect(self.do_update_check)
|
||||
|
||||
def toggle_rename_files(self, checked):
|
||||
config.setting["rename_files"] = checked
|
||||
@@ -1108,10 +1096,36 @@ class MainWindow(QtWidgets.QMainWindow, PreserveGeometry):
|
||||
self.tagger.paste_files(target)
|
||||
self.paste_action.setEnabled(False)
|
||||
|
||||
def check_for_update(self):
|
||||
self.tagger.updatecheckmanager.check_update(show_always=True, update_level=config.setting["update_level"], callback=update_last_check_date)
|
||||
def do_update_check(self):
|
||||
self.check_for_update(True)
|
||||
|
||||
def auto_update_check(self):
|
||||
check_for_updates = config.setting['check_for_updates']
|
||||
update_check_days = config.setting['update_check_days']
|
||||
last_update_check = config.persist['last_update_check']
|
||||
update_level = config.setting['update_level']
|
||||
today = datetime.date.today().toordinal()
|
||||
do_auto_update_check = check_for_updates and update_check_days > 0 and today >= last_update_check + update_check_days
|
||||
log.debug('{check_status} start-up check for program updates. Today: {today_date}, Last check: {last_check} (Check interval: {check_interval} days), Update level: {update_level} ({update_level_name})'.format(
|
||||
check_status='Initiating' if do_auto_update_check else 'Skipping',
|
||||
today_date=datetime.date.today(),
|
||||
last_check=str(datetime.date.fromordinal(last_update_check)) if last_update_check > 0 else 'never',
|
||||
check_interval=update_check_days,
|
||||
update_level=update_level,
|
||||
update_level_name=PROGRAM_UPDATE_LEVELS[update_level]['name'] if update_level in PROGRAM_UPDATE_LEVELS else 'unknown',
|
||||
))
|
||||
if do_auto_update_check:
|
||||
self.check_for_update(False)
|
||||
|
||||
def check_for_update(self, show_always):
|
||||
self.tagger.updatecheckmanager.check_update(
|
||||
show_always=show_always,
|
||||
update_level=config.setting['update_level'],
|
||||
callback=update_last_check_date
|
||||
)
|
||||
|
||||
def update_last_check_date(is_success):
|
||||
log.debug('Processing update_last_check_date callback with argument: %s' % (is_success,))
|
||||
if is_success:
|
||||
config.persist['last_update_check'] = datetime.date.today().toordinal()
|
||||
else:
|
||||
log.debug('The update check was unsuccessful. The last update date will not be changed.')
|
||||
|
||||
@@ -20,12 +20,12 @@
|
||||
from PyQt5 import QtCore
|
||||
from PyQt5.QtWidgets import QInputDialog
|
||||
|
||||
from picard import (
|
||||
config,
|
||||
from picard import config
|
||||
from picard.collection import load_user_collections
|
||||
from picard.const import (
|
||||
MUSICBRAINZ_SERVERS,
|
||||
PROGRAM_UPDATE_LEVELS,
|
||||
)
|
||||
from picard.collection import load_user_collections
|
||||
from picard.const import MUSICBRAINZ_SERVERS
|
||||
from picard.util import webbrowser2
|
||||
|
||||
from picard.ui.options import (
|
||||
@@ -76,14 +76,9 @@ class GeneralOptionsPage(OptionsPage):
|
||||
self.ui.ignore_file_mbids.setChecked(config.setting["ignore_file_mbids"])
|
||||
self.ui.check_for_updates.setChecked(config.setting["check_for_updates"])
|
||||
self.ui.update_level.clear()
|
||||
index = 0
|
||||
for key in PROGRAM_UPDATE_LEVELS.keys():
|
||||
self.ui.update_level.addItem(
|
||||
_(PROGRAM_UPDATE_LEVELS[key]['title']),
|
||||
PROGRAM_UPDATE_LEVELS[key]['level'])
|
||||
if PROGRAM_UPDATE_LEVELS[key]['level'] == config.setting["update_level"]:
|
||||
self.ui.update_level.setCurrentIndex(index)
|
||||
index += 1
|
||||
for level, description in PROGRAM_UPDATE_LEVELS.items():
|
||||
self.ui.update_level.addItem(_(description['title']), level)
|
||||
self.ui.update_level.setCurrentIndex(self.ui.update_level.findData(config.setting["update_level"]))
|
||||
self.ui.update_check_days.setValue(config.setting["update_check_days"])
|
||||
|
||||
def save(self):
|
||||
|
||||
@@ -8,7 +8,7 @@ from PyQt5 import QtCore, QtGui, QtWidgets
|
||||
class Ui_GeneralOptionsPage(object):
|
||||
def setupUi(self, GeneralOptionsPage):
|
||||
GeneralOptionsPage.setObjectName("GeneralOptionsPage")
|
||||
GeneralOptionsPage.resize(304, 435)
|
||||
GeneralOptionsPage.resize(283, 435)
|
||||
self.vboxlayout = QtWidgets.QVBoxLayout(GeneralOptionsPage)
|
||||
self.vboxlayout.setObjectName("vboxlayout")
|
||||
self.groupBox = QtWidgets.QGroupBox(GeneralOptionsPage)
|
||||
@@ -116,9 +116,6 @@ class Ui_GeneralOptionsPage(object):
|
||||
self.update_level.setSizePolicy(sizePolicy)
|
||||
self.update_level.setEditable(False)
|
||||
self.update_level.setObjectName("update_level")
|
||||
self.update_level.addItem("")
|
||||
self.update_level.addItem("")
|
||||
self.update_level.addItem("")
|
||||
self.gridLayout_2.addWidget(self.update_level, 0, 1, 1, 1)
|
||||
self.verticalLayout_2.addLayout(self.gridLayout_2)
|
||||
self.vboxlayout.addWidget(self.groupBox_3)
|
||||
@@ -126,7 +123,6 @@ class Ui_GeneralOptionsPage(object):
|
||||
self.vboxlayout.addItem(spacerItem1)
|
||||
|
||||
self.retranslateUi(GeneralOptionsPage)
|
||||
self.update_level.setCurrentIndex(0)
|
||||
QtCore.QMetaObject.connectSlotsByName(GeneralOptionsPage)
|
||||
GeneralOptionsPage.setTabOrder(self.server_host, self.server_port)
|
||||
|
||||
@@ -145,7 +141,4 @@ class Ui_GeneralOptionsPage(object):
|
||||
self.check_for_updates.setText(_("Check for updates during start-up"))
|
||||
self.label_2.setText(_("Days between checks:"))
|
||||
self.label_3.setText(_("Updates to check:"))
|
||||
self.update_level.setItemText(0, _("Stable releases only"))
|
||||
self.update_level.setItemText(1, _("Stable and Beta releases"))
|
||||
self.update_level.setItemText(2, _("Stable, Beta and Dev releases"))
|
||||
|
||||
|
||||
@@ -17,25 +17,25 @@
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
|
||||
from picard import (PICARD_VERSION, PICARD_FANCY_VERSION_STR, PROGRAM_UPDATE_LEVELS, log)
|
||||
import picard.util.webbrowser2 as wb2
|
||||
from functools import partial
|
||||
|
||||
from PyQt5 import QtCore
|
||||
from PyQt5.QtWidgets import QMessageBox
|
||||
from picard.util import load_json, compare_version_tuples
|
||||
from functools import partial
|
||||
import re
|
||||
|
||||
|
||||
# Used to strip leading and trailing text from version string.
|
||||
_RE_CLEAN_VERSION = re.compile('^[^0-9]*(.*)[^0-9]*$', re.IGNORECASE)
|
||||
|
||||
|
||||
# GitHub API information
|
||||
VERSIONS_API = {
|
||||
'host': 'picard.musicbrainz.org',
|
||||
'port': 443,
|
||||
'endpoint': '/api/releases'
|
||||
}
|
||||
from picard import (
|
||||
PICARD_FANCY_VERSION_STR,
|
||||
PICARD_VERSION,
|
||||
log,
|
||||
)
|
||||
from picard.const import (
|
||||
PLUGINS_API,
|
||||
PROGRAM_UPDATE_LEVELS,
|
||||
)
|
||||
from picard.util import (
|
||||
compare_version_tuples,
|
||||
load_json,
|
||||
webbrowser2,
|
||||
)
|
||||
|
||||
|
||||
class UpdateCheckManager(QtCore.QObject):
|
||||
@@ -43,21 +43,7 @@ class UpdateCheckManager(QtCore.QObject):
|
||||
def __init__(self, parent=None):
|
||||
super().__init__(parent=parent)
|
||||
self._parent = parent
|
||||
|
||||
# PICARD_VERSIONS dictionary valid keys are: 'stable', 'beta' and 'dev'.
|
||||
# Each of these keys contains a dictionary with the keys: 'tag' (string),
|
||||
# 'version' (tuple) and 'urls' (dictionary). The 'version' tuple comprises
|
||||
# major (int), minor (int), micro (int), type (str) and development (int)
|
||||
# as defined in PEP-440. The Picard developers have standardized on using
|
||||
# only 'dev' or 'final' as the str_type segment of the version tuple. Each
|
||||
# key in the 'urls' dictionary contains a string with the specified url.
|
||||
# Valid keys include: 'download' and 'changelog'. The only required key in
|
||||
# the 'urls' dictionary is 'download'.
|
||||
|
||||
# Initialize empty dictionary for 'stable' key
|
||||
self._available_versions = {
|
||||
'stable': { 'tag': '', 'version': (0, 0, 0, 'dev', 0), 'urls': {'download': ''} },
|
||||
}
|
||||
self._available_versions = {}
|
||||
self._show_always = False
|
||||
self._update_level = 0
|
||||
|
||||
@@ -88,25 +74,20 @@ class UpdateCheckManager(QtCore.QObject):
|
||||
self._show_always = show_always
|
||||
self._update_level = update_level
|
||||
|
||||
if self._available_versions['stable']['tag']:
|
||||
if self._available_versions:
|
||||
# Release information already acquired from specified website api.
|
||||
self._display_results()
|
||||
else:
|
||||
# Gets list of releases from specified website api.
|
||||
self._query_available_updates(callback=callback)
|
||||
|
||||
@property
|
||||
def available_versions(self):
|
||||
'''Provide a list of the latest version tuples for each update type.'''
|
||||
return self._available_versions
|
||||
|
||||
def _query_available_updates(self, callback=None):
|
||||
'''Gets list of releases from specified website api.'''
|
||||
log.debug(_("Getting release information from {host_url}.".format(host_url=VERSIONS_API['host'],)))
|
||||
log.debug("Getting Picard release information from {host_url}".format(host_url=PLUGINS_API['host'],))
|
||||
self.tagger.webservice.get(
|
||||
VERSIONS_API['host'],
|
||||
VERSIONS_API['port'],
|
||||
VERSIONS_API['endpoint'],
|
||||
PLUGINS_API['host'],
|
||||
PLUGINS_API['port'],
|
||||
PLUGINS_API['endpoint']['releases'],
|
||||
partial(self._releases_json_loaded, callback=callback),
|
||||
parse_response_type=None,
|
||||
priority=True,
|
||||
@@ -116,16 +97,19 @@ class UpdateCheckManager(QtCore.QObject):
|
||||
def _releases_json_loaded(self, response, reply, error, callback=None):
|
||||
'''Processes response from specified website api query.'''
|
||||
if error:
|
||||
log.error(N_("Error loading releases list: {error_message}".format(error_message=reply.errorString(),)))
|
||||
log.error(_("Error loading Picard releases list: {error_message}").format(error_message=reply.errorString(),))
|
||||
if self._show_always:
|
||||
QMessageBox.information(
|
||||
self._parent,
|
||||
_("Picard Update"),
|
||||
_("Unable to retrieve the latest version information."),
|
||||
_("Unable to retrieve the latest version information from the website.\n(https://{url}{endpoint})").format(
|
||||
url=PLUGINS_API['host'],
|
||||
endpoint=PLUGINS_API['endpoint']['releases'],
|
||||
),
|
||||
QMessageBox.Ok, QMessageBox.Ok)
|
||||
else:
|
||||
self._available_versions = load_json(response)['versions']
|
||||
for key in self._available_versions.keys():
|
||||
for key in self._available_versions:
|
||||
log.debug("Version key '{version_key}' --> {version_information}".format(
|
||||
version_key=key, version_information=self._available_versions[key],))
|
||||
self._display_results()
|
||||
@@ -136,16 +120,17 @@ class UpdateCheckManager(QtCore.QObject):
|
||||
# Display results to user.
|
||||
key = ''
|
||||
high_version = PICARD_VERSION
|
||||
for test_key in PROGRAM_UPDATE_LEVELS.keys():
|
||||
if self._update_level >= PROGRAM_UPDATE_LEVELS[test_key]['level'] and compare_version_tuples(high_version, self._available_versions[test_key]['version']) > 0:
|
||||
key = test_key
|
||||
high_version = self._available_versions[test_key]['version']
|
||||
for test_key in PROGRAM_UPDATE_LEVELS:
|
||||
test_version = self._available_versions[PROGRAM_UPDATE_LEVELS[test_key]['name']]['version']
|
||||
if self._update_level >= test_key and compare_version_tuples(high_version, test_version) > 0:
|
||||
key = PROGRAM_UPDATE_LEVELS[test_key]['name']
|
||||
high_version = test_version
|
||||
if key:
|
||||
if QMessageBox.information(
|
||||
self._parent,
|
||||
_("Picard Update"),
|
||||
_("A new version of Picard is available.\n\n"
|
||||
"Old version: {picard_old_version}\n"
|
||||
"This version: {picard_old_version}\n"
|
||||
"New version: {picard_new_version}\n\n"
|
||||
"Would you like to download the new version?").format(
|
||||
picard_old_version=PICARD_FANCY_VERSION_STR,
|
||||
@@ -154,18 +139,15 @@ class UpdateCheckManager(QtCore.QObject):
|
||||
QMessageBox.Ok | QMessageBox.Cancel,
|
||||
QMessageBox.Cancel
|
||||
) == QMessageBox.Ok:
|
||||
wb2.open(self._available_versions[key]['urls']['download'])
|
||||
webbrowser2.open(self._available_versions[key]['urls']['download'])
|
||||
else:
|
||||
if self._show_always:
|
||||
for key in PROGRAM_UPDATE_LEVELS.keys():
|
||||
if self._update_level == PROGRAM_UPDATE_LEVELS[key]['level']:
|
||||
update_level_text = PROGRAM_UPDATE_LEVELS[key]['title']
|
||||
QMessageBox.information(
|
||||
self._parent,
|
||||
_("Picard Update"),
|
||||
_("There is no update currently available for your subscribed update level: {update_level}\n\n"
|
||||
"Your version: {picard_old_version}\n").format(
|
||||
update_level=_(update_level_text if update_level_text else 'unknown'),
|
||||
update_level=_(PROGRAM_UPDATE_LEVELS[self._update_level]['title']) if self._update_level in PROGRAM_UPDATE_LEVELS else _('unknown'),
|
||||
picard_old_version=PICARD_FANCY_VERSION_STR,
|
||||
),
|
||||
QMessageBox.Ok, QMessageBox.Ok
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>304</width>
|
||||
<width>283</width>
|
||||
<height>435</height>
|
||||
</rect>
|
||||
</property>
|
||||
@@ -213,24 +213,6 @@
|
||||
<property name="editable">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="currentIndex">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Stable releases only</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Stable and Beta releases</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Stable, Beta and Dev releases</string>
|
||||
</property>
|
||||
</item>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
|
||||
Reference in New Issue
Block a user