mirror of
https://github.com/fergalmoran/picard.git
synced 2026-01-08 09:33:59 +00:00
Merge pull request #254 from zas/cover_art_types
Use attributes.pot from musicbrainz server to generate up-to-date cover art types and medium formats lists
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@@ -11,3 +11,4 @@ locale
|
||||
*.exe
|
||||
.DS_Store
|
||||
po/countries/countries.pot
|
||||
po/attributes/attributes.pot
|
||||
|
||||
@@ -12,3 +12,9 @@ file_filter = po/countries/<lang>.po
|
||||
source_file = po/countries/countries.pot
|
||||
source_lang = en
|
||||
type = PO
|
||||
|
||||
[musicbrainz.attributes]
|
||||
file_filter = po/attributes/<lang>.po
|
||||
source_file = po/attributes/attributes.pot
|
||||
source_lang = en
|
||||
type = PO
|
||||
|
||||
4
NEWS.txt
4
NEWS.txt
@@ -24,7 +24,6 @@
|
||||
* Added "_artists_sort", "_albumartists", "_albumartists_sort" variables for scripts and plugins.
|
||||
* Made Picard use the country names also used on the MusicBrainz website (PICARD-205)
|
||||
* New setup.py command `get_po_files` (Retrieve po files from transifex)
|
||||
* New setup.py command `update_countries` (Regenerate countries.py)
|
||||
* New setup.py command `regen_pot_file` (Regenerate po/picard.pot)
|
||||
* New Work tag (which for Classical music is often different from the track title) saved as ID3 TOAL tag.
|
||||
* New Composer Sort Order tag (variable %composersort%).
|
||||
@@ -38,6 +37,9 @@
|
||||
* Show the ID3 version of the file in the Info... dialog (Ctrl-I) (PICARD-218)
|
||||
* Fixed a bug where Picard crashed if a MP3 file had malformed TRCK or TPOS tags (PICARD-112)
|
||||
* Add --files option to setup.py build_ui, used to force .ui to .py regeneration (PICARD-566)
|
||||
* New setup.py command `update_constants` (Regenerate countries.py and attributes.py)
|
||||
* Made Picard use release groups, medium formats and cover art types also used on the MusicBrainz website
|
||||
* Use MusicBrainz Server translations for release groups, medium formats and cover art types
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -22,7 +22,7 @@ import re
|
||||
|
||||
PICARD_APP_NAME = "Picard"
|
||||
PICARD_ORG_NAME = "MusicBrainz"
|
||||
PICARD_VERSION = (1, 3, 0, 'dev', 3)
|
||||
PICARD_VERSION = (1, 3, 0, 'dev', 4)
|
||||
|
||||
|
||||
class VersionError(Exception):
|
||||
|
||||
73
picard/attributes.py
Normal file
73
picard/attributes.py
Normal file
@@ -0,0 +1,73 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Automatically generated - don't edit.
|
||||
# Use `python setup.py update_constants` to update it.
|
||||
|
||||
MB_ATTRIBUTES = {
|
||||
u'DB:cover_art_archive.art_type/name:001': u'Front',
|
||||
u'DB:cover_art_archive.art_type/name:002': u'Back',
|
||||
u'DB:cover_art_archive.art_type/name:003': u'Booklet',
|
||||
u'DB:cover_art_archive.art_type/name:004': u'Medium',
|
||||
u'DB:cover_art_archive.art_type/name:005': u'Obi',
|
||||
u'DB:cover_art_archive.art_type/name:006': u'Spine',
|
||||
u'DB:cover_art_archive.art_type/name:007': u'Track',
|
||||
u'DB:cover_art_archive.art_type/name:008': u'Other',
|
||||
u'DB:cover_art_archive.art_type/name:009': u'Tray',
|
||||
u'DB:cover_art_archive.art_type/name:010': u'Sticker',
|
||||
u'DB:cover_art_archive.art_type/name:011': u'Poster',
|
||||
u'DB:cover_art_archive.art_type/name:012': u'Liner',
|
||||
u'DB:cover_art_archive.art_type/name:013': u'Watermark',
|
||||
u'DB:medium_format/name:001': u'CD',
|
||||
u'DB:medium_format/name:002': u'DVD',
|
||||
u'DB:medium_format/name:003': u'SACD',
|
||||
u'DB:medium_format/name:004': u'DualDisc',
|
||||
u'DB:medium_format/name:005': u'LaserDisc',
|
||||
u'DB:medium_format/name:006': u'MiniDisc',
|
||||
u'DB:medium_format/name:007': u'Vinyl',
|
||||
u'DB:medium_format/name:008': u'Cassette',
|
||||
u'DB:medium_format/name:009': u'Cartridge',
|
||||
u'DB:medium_format/name:010': u'Reel-to-reel',
|
||||
u'DB:medium_format/name:011': u'DAT',
|
||||
u'DB:medium_format/name:012': u'Digital Media',
|
||||
u'DB:medium_format/name:013': u'Other',
|
||||
u'DB:medium_format/name:014': u'Wax Cylinder',
|
||||
u'DB:medium_format/name:015': u'Piano Roll',
|
||||
u'DB:medium_format/name:016': u'DCC',
|
||||
u'DB:medium_format/name:017': u'HD-DVD',
|
||||
u'DB:medium_format/name:018': u'DVD-Audio',
|
||||
u'DB:medium_format/name:019': u'DVD-Video',
|
||||
u'DB:medium_format/name:020': u'Blu-ray',
|
||||
u'DB:medium_format/name:021': u'VHS',
|
||||
u'DB:medium_format/name:022': u'VCD',
|
||||
u'DB:medium_format/name:023': u'SVCD',
|
||||
u'DB:medium_format/name:024': u'Betamax',
|
||||
u'DB:medium_format/name:025': u'HDCD',
|
||||
u'DB:medium_format/name:026': u'USB Flash Drive',
|
||||
u'DB:medium_format/name:027': u'slotMusic',
|
||||
u'DB:medium_format/name:028': u'UMD',
|
||||
u'DB:medium_format/name:029': u'7" Vinyl',
|
||||
u'DB:medium_format/name:030': u'10" Vinyl',
|
||||
u'DB:medium_format/name:031': u'12" Vinyl',
|
||||
u'DB:medium_format/name:032': u'Videotape',
|
||||
u'DB:medium_format/name:033': u'CD-R',
|
||||
u'DB:medium_format/name:034': u'8cm CD',
|
||||
u'DB:medium_format/name:035': u'Blu-spec CD',
|
||||
u'DB:medium_format/name:036': u'SHM-CD',
|
||||
u'DB:medium_format/name:037': u'HQCD',
|
||||
u'DB:medium_format/name:038': u'Hybrid SACD',
|
||||
u'DB:medium_format/name:039': u'CD+G',
|
||||
u'DB:medium_format/name:040': u'8cm CD+G',
|
||||
u'DB:release_group_primary_type/name:001': u'Album',
|
||||
u'DB:release_group_primary_type/name:002': u'Single',
|
||||
u'DB:release_group_primary_type/name:003': u'EP',
|
||||
u'DB:release_group_primary_type/name:011': u'Other',
|
||||
u'DB:release_group_primary_type/name:012': u'Broadcast',
|
||||
u'DB:release_group_secondary_type/name:001': u'Compilation',
|
||||
u'DB:release_group_secondary_type/name:002': u'Soundtrack',
|
||||
u'DB:release_group_secondary_type/name:003': u'Spokenword',
|
||||
u'DB:release_group_secondary_type/name:004': u'Interview',
|
||||
u'DB:release_group_secondary_type/name:005': u'Audiobook',
|
||||
u'DB:release_group_secondary_type/name:006': u'Live',
|
||||
u'DB:release_group_secondary_type/name:007': u'Remix',
|
||||
u'DB:release_group_secondary_type/name:008': u'DJ-mix',
|
||||
u'DB:release_group_secondary_type/name:009': u'Mixtape/Street',
|
||||
}
|
||||
@@ -118,10 +118,29 @@ def upgrade_to_v1_3_0_dev_3():
|
||||
_s[opt] = _s.raw_value(opt).split(sep)
|
||||
|
||||
|
||||
def upgrade_to_v1_3_0_dev_4():
|
||||
"""Option "release_type_scores" is now a list of tuples
|
||||
"""
|
||||
def load_release_type_scores(setting):
|
||||
scores = []
|
||||
values = setting.split()
|
||||
for i in range(0, len(values), 2):
|
||||
try:
|
||||
score = float(values[i + 1])
|
||||
except IndexError:
|
||||
score = 0.0
|
||||
scores.append((values[i], score))
|
||||
return scores
|
||||
|
||||
opt = "release_type_scores"
|
||||
_s[opt] = load_release_type_scores(_s.raw_value(opt))
|
||||
|
||||
|
||||
def upgrade_config():
|
||||
cfg = config._config
|
||||
cfg.register_upgrade_hook(upgrade_to_v1_0_0_final_0)
|
||||
cfg.register_upgrade_hook(upgrade_to_v1_3_0_dev_1)
|
||||
cfg.register_upgrade_hook(upgrade_to_v1_3_0_dev_2)
|
||||
cfg.register_upgrade_hook(upgrade_to_v1_3_0_dev_3)
|
||||
cfg.register_upgrade_hook(upgrade_to_v1_3_0_dev_4)
|
||||
cfg.run_upgrade_hooks(log.debug)
|
||||
|
||||
@@ -63,42 +63,17 @@ PICARD_URLS = {
|
||||
VARIOUS_ARTISTS_ID = '89ad4ac3-39f7-470e-963a-56509c546377'
|
||||
|
||||
# Release formats
|
||||
RELEASE_FORMATS = {
|
||||
u'CD': N_('CD'),
|
||||
u'CD-R': N_('CD-R'),
|
||||
u'HDCD': N_('HDCD'),
|
||||
u'8cm CD': N_('8cm CD'),
|
||||
u'Vinyl': N_('Vinyl'),
|
||||
u'7" Vinyl': N_('7" Vinyl'),
|
||||
u'10" Vinyl': N_('10" Vinyl'),
|
||||
u'12" Vinyl': N_('12" Vinyl'),
|
||||
u'Digital Media': N_('Digital Media'),
|
||||
u'USB Flash Drive': N_('USB Flash Drive'),
|
||||
u'slotMusic': N_('slotMusic'),
|
||||
u'Cassette': N_('Cassette'),
|
||||
u'DVD': N_('DVD'),
|
||||
u'DVD-Audio': N_('DVD-Audio'),
|
||||
u'DVD-Video': N_('DVD-Video'),
|
||||
u'SACD': N_('SACD'),
|
||||
u'DualDisc': N_('DualDisc'),
|
||||
u'MiniDisc': N_('MiniDisc'),
|
||||
u'Blu-ray': N_('Blu-ray'),
|
||||
u'HD-DVD': N_('HD-DVD'),
|
||||
u'Videotape': N_('Videotape'),
|
||||
u'VHS': N_('VHS'),
|
||||
u'Betamax': N_('Betamax'),
|
||||
u'VCD': N_('VCD'),
|
||||
u'SVCD': N_('SVCD'),
|
||||
u'UMD': N_('UMD'),
|
||||
u'Other': N_('Other'),
|
||||
u'LaserDisc': N_('LaserDisc'),
|
||||
u'Cartridge': N_('Cartridge'),
|
||||
u'Reel-to-reel': N_('Reel-to-reel'),
|
||||
u'DAT': N_('DAT'),
|
||||
u'Wax Cylinder': N_('Wax Cylinder'),
|
||||
u'Piano Roll': N_('Piano Roll'),
|
||||
u'DCC': N_('DCC')
|
||||
}
|
||||
from picard.attributes import MB_ATTRIBUTES
|
||||
RELEASE_FORMATS = {}
|
||||
RELEASE_PRIMARY_GROUPS = {}
|
||||
RELEASE_SECONDARY_GROUPS = {}
|
||||
for k, v in MB_ATTRIBUTES.iteritems():
|
||||
if k.startswith(u'DB:medium_format/name:'):
|
||||
RELEASE_FORMATS[v] = v
|
||||
elif k.startswith(u'DB:release_group_primary_type/name:'):
|
||||
RELEASE_PRIMARY_GROUPS[v] = v
|
||||
elif k.startswith(u'DB:release_group_secondary_type/name:'):
|
||||
RELEASE_SECONDARY_GROUPS[v] = v
|
||||
|
||||
# Release countries
|
||||
from picard.countries import RELEASE_COUNTRIES
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Automatically generated - don't edit.
|
||||
# Use `python setup.py update_countries` to update it.
|
||||
# Use `python setup.py update_constants` to update it.
|
||||
|
||||
RELEASE_COUNTRIES = {
|
||||
u'AD': u'Andorra',
|
||||
|
||||
@@ -17,19 +17,14 @@
|
||||
# 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.attributes import MB_ATTRIBUTES
|
||||
|
||||
# list of types from http://musicbrainz.org/doc/Cover_Art/Types
|
||||
# order of declaration is preserved in selection box
|
||||
CAA_TYPES = [
|
||||
{'name': "front", 'title': N_("Front")},
|
||||
{'name': "back", 'title': N_("Back")},
|
||||
{'name': "booklet", 'title': N_("Booklet")},
|
||||
{'name': "medium", 'title': N_("Medium")},
|
||||
{'name': "tray", 'title': N_("Tray")},
|
||||
{'name': "obi", 'title': N_("Obi")},
|
||||
{'name': "spine", 'title': N_("Spine")},
|
||||
{'name': "track", 'title': N_("Track")},
|
||||
{'name': "sticker", 'title': N_("Sticker")},
|
||||
{'name': "other", 'title': N_("Other")},
|
||||
{'name': "unknown", 'title': N_("Unknown")}, # pseudo type, used for the no type case
|
||||
]
|
||||
CAA_TYPES = []
|
||||
for k, v in sorted(MB_ATTRIBUTES.items(), key=lambda (k,v): k):
|
||||
if k.startswith(u'DB:cover_art_archive.art_type/name:'):
|
||||
CAA_TYPES.append({'name': v.lower(), 'title': v})
|
||||
|
||||
# pseudo type, used for the no type case
|
||||
CAA_TYPES.append({'name': "unknown", 'title': N_(u"Unknown")})
|
||||
|
||||
@@ -72,6 +72,9 @@ def setup_gettext(localedir, ui_language=None, logger=None):
|
||||
logger("Loading gettext translation (picard-countries), localedir=%r", localedir)
|
||||
trans_countries = gettext.translation("picard-countries", localedir)
|
||||
_ugettext_countries = trans_countries.ugettext
|
||||
logger("Loading gettext translation (picard-attributes), localedir=%r", localedir)
|
||||
trans_attributes = gettext.translation("picard-attributes", localedir)
|
||||
_ugettext_attributes = trans_attributes.ugettext
|
||||
except IOError as e:
|
||||
logger(e)
|
||||
__builtin__.__dict__['_'] = lambda a: a
|
||||
@@ -85,10 +88,38 @@ def setup_gettext(localedir, ui_language=None, logger=None):
|
||||
def _ugettext_countries(msg):
|
||||
return msg
|
||||
|
||||
def _ugettext_attributes(msg):
|
||||
return msg
|
||||
|
||||
__builtin__.__dict__['ungettext'] = _ungettext
|
||||
__builtin__.__dict__['ugettext_countries'] = _ugettext_countries
|
||||
__builtin__.__dict__['ugettext_attributes'] = _ugettext_attributes
|
||||
|
||||
logger("_ = %r", _)
|
||||
logger("N_ = %r", N_)
|
||||
logger("ungettext = %r", ungettext)
|
||||
logger("ugettext_countries = %r", ugettext_countries)
|
||||
logger("ugettext_attributes = %r", ugettext_attributes)
|
||||
|
||||
|
||||
# Workaround for po files with msgctxt which isn't supported by current python
|
||||
# gettext
|
||||
# msgctxt are used within attributes.po, and ugettext is failing to translate
|
||||
# strings due to that
|
||||
# This workaround is a hack until we get proper msgctxt support
|
||||
_CONTEXT_SEPARATOR = "\x04"
|
||||
def ugettext_ctxt(ugettext_, message, context=None):
|
||||
if context is None:
|
||||
return ugettext_(message)
|
||||
|
||||
msg_with_ctxt = u"%s%s%s" % (context, _CONTEXT_SEPARATOR, message)
|
||||
translated = ugettext_(msg_with_ctxt)
|
||||
if _CONTEXT_SEPARATOR in translated:
|
||||
# no translation found, return original message
|
||||
return message
|
||||
return translated
|
||||
|
||||
|
||||
def ugettext_attr(message, context=None):
|
||||
"""Translate MB attributes, depending on context"""
|
||||
return ugettext_ctxt(ugettext_attributes, message, context)
|
||||
|
||||
@@ -32,7 +32,6 @@ from picard.plugin import ExtensionPoint
|
||||
from picard.similarity import similarity2
|
||||
from picard.util import (
|
||||
encode_filename,
|
||||
load_release_type_scores,
|
||||
mimetype as mime,
|
||||
replace_non_ascii,
|
||||
replace_win32_incompat,
|
||||
@@ -288,7 +287,7 @@ class Metadata(dict):
|
||||
parts.append((score, weights["format"]))
|
||||
|
||||
if "releasetype" in weights:
|
||||
type_scores = load_release_type_scores(config.setting["release_type_scores"])
|
||||
type_scores = dict(config.setting["release_type_scores"])
|
||||
if 'release_group' in release.children and 'type' in release.release_group[0].attribs:
|
||||
release_type = release.release_group[0].type
|
||||
score = type_scores.get(release_type, type_scores.get('Other', 0.5))
|
||||
|
||||
@@ -22,6 +22,7 @@ from picard import config
|
||||
from picard.ui.options import OptionsPage, register_options_page
|
||||
from picard.ui.ui_options_cover import Ui_CoverOptionsPage
|
||||
from picard.coverartarchive import CAA_TYPES
|
||||
from picard.i18n import ugettext_attr
|
||||
|
||||
|
||||
class CAATypesSelector(object):
|
||||
@@ -39,7 +40,11 @@ class CAATypesSelector(object):
|
||||
|
||||
def _add_item(self, typ, enabled=False):
|
||||
item = QtGui.QListWidgetItem(self.widget)
|
||||
item.setText(typ['title'])
|
||||
if typ['name'] == 'unknown':
|
||||
title = _(typ['title'])
|
||||
else:
|
||||
title = ugettext_attr(typ['title'], u"cover_art_type")
|
||||
item.setText(title)
|
||||
tooltip = u"CAA: %(name)s" % typ
|
||||
item.setToolTip(tooltip)
|
||||
if enabled:
|
||||
|
||||
@@ -21,10 +21,64 @@ from operator import itemgetter
|
||||
from locale import strcoll
|
||||
from PyQt4 import QtCore, QtGui
|
||||
from picard import config
|
||||
from picard.util import load_release_type_scores, save_release_type_scores
|
||||
from picard.ui.options import OptionsPage, register_options_page
|
||||
from picard.ui.ui_options_releases import Ui_ReleasesOptionsPage
|
||||
from picard.const import RELEASE_COUNTRIES, RELEASE_FORMATS
|
||||
from picard.const import (RELEASE_COUNTRIES,
|
||||
RELEASE_FORMATS,
|
||||
RELEASE_PRIMARY_GROUPS,
|
||||
RELEASE_SECONDARY_GROUPS)
|
||||
from picard.i18n import ugettext_attr
|
||||
|
||||
|
||||
_DEFAULT_SCORE = 0.5
|
||||
_release_type_scores = [(g, _DEFAULT_SCORE) for g in RELEASE_PRIMARY_GROUPS.keys() + RELEASE_SECONDARY_GROUPS.keys()]
|
||||
|
||||
|
||||
class ReleaseTypeScore:
|
||||
|
||||
def __init__(self, group, layout, label, cell):
|
||||
row, column = cell # it uses 2 cells (r,c and r,c+1)
|
||||
self.group = group
|
||||
self.layout = layout
|
||||
self.label = QtGui.QLabel(self.group)
|
||||
self.label.setText(label)
|
||||
self.layout.addWidget(self.label, row, column, 1, 1)
|
||||
self.slider = QtGui.QSlider(self.group)
|
||||
self.slider.setMaximum(100)
|
||||
self.slider.setOrientation(QtCore.Qt.Horizontal)
|
||||
self.layout.addWidget(self.slider, row, column + 1, 1, 1)
|
||||
self.reset()
|
||||
|
||||
def setValue(self, value):
|
||||
self.slider.setValue(int(value * 100))
|
||||
|
||||
def value(self):
|
||||
return float(self.slider.value()) / 100.0
|
||||
|
||||
def reset(self):
|
||||
self.setValue(_DEFAULT_SCORE)
|
||||
|
||||
|
||||
class RowColIter:
|
||||
|
||||
def __init__(self, max_cells, max_cols=6, step=2):
|
||||
assert(max_cols % step == 0)
|
||||
self.step = step
|
||||
self.cols = max_cols
|
||||
self.rows = int((max_cells - 1) / (self.cols / step)) + 1
|
||||
self.current = (-1, 0)
|
||||
|
||||
def __iter__(self):
|
||||
return self
|
||||
|
||||
def next(self):
|
||||
row, col = self.current
|
||||
row += 1
|
||||
if row == self.rows:
|
||||
col += self.step
|
||||
row = 0
|
||||
self.current = (row, col)
|
||||
return self.current
|
||||
|
||||
|
||||
class ReleasesOptionsPage(OptionsPage):
|
||||
@@ -36,29 +90,43 @@ class ReleasesOptionsPage(OptionsPage):
|
||||
ACTIVE = True
|
||||
|
||||
options = [
|
||||
config.TextOption("setting", "release_type_scores", "Album 0.5 Single 0.5 EP 0.5 Compilation 0.5 Soundtrack 0.5 Spokenword 0.5 Interview 0.5 Audiobook 0.5 Live 0.5 Remix 0.5 Other 0.5"),
|
||||
config.ListOption("setting", "release_type_scores", _release_type_scores),
|
||||
config.ListOption("setting", "preferred_release_countries", []),
|
||||
config.ListOption("setting", "preferred_release_formats", []),
|
||||
]
|
||||
|
||||
_release_type_sliders = {}
|
||||
|
||||
def __init__(self, parent=None):
|
||||
super(ReleasesOptionsPage, self).__init__(parent)
|
||||
self.ui = Ui_ReleasesOptionsPage()
|
||||
self.ui.setupUi(self)
|
||||
self.ui.reset_preferred_types_btn.clicked.connect(self.reset_preferred_types)
|
||||
self._release_type_sliders["Album"] = self.ui.prefer_album_score
|
||||
self._release_type_sliders["Single"] = self.ui.prefer_single_score
|
||||
self._release_type_sliders["EP"] = self.ui.prefer_ep_score
|
||||
self._release_type_sliders["Compilation"] = self.ui.prefer_compilation_score
|
||||
self._release_type_sliders["Soundtrack"] = self.ui.prefer_soundtrack_score
|
||||
self._release_type_sliders["Spokenword"] = self.ui.prefer_spokenword_score
|
||||
self._release_type_sliders["Interview"] = self.ui.prefer_interview_score
|
||||
self._release_type_sliders["Audiobook"] = self.ui.prefer_audiobook_score
|
||||
self._release_type_sliders["Live"] = self.ui.prefer_live_score
|
||||
self._release_type_sliders["Remix"] = self.ui.prefer_remix_score
|
||||
self._release_type_sliders["Other"] = self.ui.prefer_other_score
|
||||
|
||||
self._release_type_sliders = {}
|
||||
|
||||
def add_slider(name, griditer, context):
|
||||
label = ugettext_attr(name, context)
|
||||
self._release_type_sliders[name] = \
|
||||
ReleaseTypeScore(self.ui.type_group,
|
||||
self.ui.gridLayout,
|
||||
label,
|
||||
griditer.next())
|
||||
|
||||
griditer = RowColIter(len(RELEASE_PRIMARY_GROUPS) +
|
||||
len(RELEASE_SECONDARY_GROUPS) + 1) # +1 for Reset button
|
||||
for name in RELEASE_PRIMARY_GROUPS:
|
||||
add_slider(name, griditer, context=u'release_group_primary_type')
|
||||
for name in RELEASE_SECONDARY_GROUPS:
|
||||
add_slider(name, griditer, context=u'release_group_secondary_type')
|
||||
|
||||
self.reset_preferred_types_btn = QtGui.QPushButton(self.ui.type_group)
|
||||
self.reset_preferred_types_btn.setText(_("Reset all"))
|
||||
sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Fixed)
|
||||
sizePolicy.setHorizontalStretch(0)
|
||||
sizePolicy.setVerticalStretch(0)
|
||||
sizePolicy.setHeightForWidth(self.reset_preferred_types_btn.sizePolicy().hasHeightForWidth())
|
||||
self.reset_preferred_types_btn.setSizePolicy(sizePolicy)
|
||||
r, c = griditer.next()
|
||||
self.ui.gridLayout.addWidget(self.reset_preferred_types_btn, r, c, 1, 2)
|
||||
self.reset_preferred_types_btn.clicked.connect(self.reset_preferred_types)
|
||||
|
||||
self.ui.add_countries.clicked.connect(self.add_preferred_countries)
|
||||
self.ui.remove_countries.clicked.connect(self.remove_preferred_countries)
|
||||
@@ -70,9 +138,10 @@ class ReleasesOptionsPage(OptionsPage):
|
||||
self.ui.preferred_format_list.setSelectionMode(QtGui.QAbstractItemView.ExtendedSelection)
|
||||
|
||||
def load(self):
|
||||
scores = load_release_type_scores(config.setting["release_type_scores"])
|
||||
scores = dict(config.setting["release_type_scores"])
|
||||
for (release_type, release_type_slider) in self._release_type_sliders.iteritems():
|
||||
release_type_slider.setValue(int(scores.get(release_type, 0.5) * 100))
|
||||
release_type_slider.setValue(scores.get(release_type,
|
||||
_DEFAULT_SCORE))
|
||||
|
||||
self._load_list_items("preferred_release_countries", RELEASE_COUNTRIES,
|
||||
self.ui.country_list, self.ui.preferred_country_list)
|
||||
@@ -80,17 +149,17 @@ class ReleasesOptionsPage(OptionsPage):
|
||||
self.ui.format_list, self.ui.preferred_format_list)
|
||||
|
||||
def save(self):
|
||||
scores = {}
|
||||
scores = []
|
||||
for (release_type, release_type_slider) in self._release_type_sliders.iteritems():
|
||||
scores[release_type] = float(release_type_slider.value()) / 100.0
|
||||
config.setting["release_type_scores"] = save_release_type_scores(scores)
|
||||
scores.append((release_type, release_type_slider.value()))
|
||||
config.setting["release_type_scores"] = scores
|
||||
|
||||
self._save_list_items("preferred_release_countries", self.ui.preferred_country_list)
|
||||
self._save_list_items("preferred_release_formats", self.ui.preferred_format_list)
|
||||
|
||||
def reset_preferred_types(self):
|
||||
for release_type_slider in self._release_type_sliders.values():
|
||||
release_type_slider.setValue(50)
|
||||
release_type_slider.reset()
|
||||
|
||||
def add_preferred_countries(self):
|
||||
self._move_selected_items(self.ui.country_list, self.ui.preferred_country_list)
|
||||
@@ -114,7 +183,11 @@ class ReleasesOptionsPage(OptionsPage):
|
||||
|
||||
def _load_list_items(self, setting, source, list1, list2):
|
||||
if setting == "preferred_release_countries":
|
||||
source_list = [(c[0], ugettext_countries(c[1])) for c in source.items()]
|
||||
source_list = [(c[0], ugettext_countries(c[1])) for c in
|
||||
source.items()]
|
||||
elif setting == "preferred_release_formats":
|
||||
source_list = [(c[0], ugettext_attr(c[1], u"medium_format")) for c
|
||||
in source.items()]
|
||||
else:
|
||||
source_list = [(c[0], _(c[1])) for c in source.items()]
|
||||
source_list.sort(key=itemgetter(1), cmp=strcoll)
|
||||
|
||||
@@ -83,12 +83,11 @@ class Ui_CoverOptionsPage(object):
|
||||
self.label_2.setObjectName(_fromUtf8("label_2"))
|
||||
self.verticalLayout_3.addWidget(self.label_2)
|
||||
self.caa_types_selector_1 = QtGui.QListWidget(self.gb_caa)
|
||||
sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.MinimumExpanding, QtGui.QSizePolicy.Preferred)
|
||||
sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Expanding)
|
||||
sizePolicy.setHorizontalStretch(0)
|
||||
sizePolicy.setVerticalStretch(0)
|
||||
sizePolicy.setHeightForWidth(self.caa_types_selector_1.sizePolicy().hasHeightForWidth())
|
||||
self.caa_types_selector_1.setSizePolicy(sizePolicy)
|
||||
self.caa_types_selector_1.setMaximumSize(QtCore.QSize(16777215, 80))
|
||||
self.caa_types_selector_1.setHorizontalScrollBarPolicy(QtCore.Qt.ScrollBarAsNeeded)
|
||||
self.caa_types_selector_1.setTabKeyNavigation(True)
|
||||
self.caa_types_selector_1.setProperty("showDropIndicator", False)
|
||||
|
||||
@@ -21,113 +21,6 @@ class Ui_ReleasesOptionsPage(object):
|
||||
self.gridLayout = QtGui.QGridLayout(self.type_group)
|
||||
self.gridLayout.setVerticalSpacing(6)
|
||||
self.gridLayout.setObjectName(_fromUtf8("gridLayout"))
|
||||
self.label = QtGui.QLabel(self.type_group)
|
||||
self.label.setObjectName(_fromUtf8("label"))
|
||||
self.gridLayout.addWidget(self.label, 0, 0, 1, 1)
|
||||
self.prefer_album_score = QtGui.QSlider(self.type_group)
|
||||
self.prefer_album_score.setMaximum(100)
|
||||
self.prefer_album_score.setProperty("value", 50)
|
||||
self.prefer_album_score.setOrientation(QtCore.Qt.Horizontal)
|
||||
self.prefer_album_score.setObjectName(_fromUtf8("prefer_album_score"))
|
||||
self.gridLayout.addWidget(self.prefer_album_score, 0, 1, 1, 1)
|
||||
self.label_2 = QtGui.QLabel(self.type_group)
|
||||
self.label_2.setObjectName(_fromUtf8("label_2"))
|
||||
self.gridLayout.addWidget(self.label_2, 0, 2, 1, 1)
|
||||
self.prefer_single_score = QtGui.QSlider(self.type_group)
|
||||
self.prefer_single_score.setMaximum(100)
|
||||
self.prefer_single_score.setProperty("value", 50)
|
||||
self.prefer_single_score.setOrientation(QtCore.Qt.Horizontal)
|
||||
self.prefer_single_score.setObjectName(_fromUtf8("prefer_single_score"))
|
||||
self.gridLayout.addWidget(self.prefer_single_score, 0, 3, 1, 1)
|
||||
self.label_3 = QtGui.QLabel(self.type_group)
|
||||
self.label_3.setObjectName(_fromUtf8("label_3"))
|
||||
self.gridLayout.addWidget(self.label_3, 0, 4, 1, 1)
|
||||
self.prefer_ep_score = QtGui.QSlider(self.type_group)
|
||||
self.prefer_ep_score.setMaximum(100)
|
||||
self.prefer_ep_score.setProperty("value", 50)
|
||||
self.prefer_ep_score.setOrientation(QtCore.Qt.Horizontal)
|
||||
self.prefer_ep_score.setObjectName(_fromUtf8("prefer_ep_score"))
|
||||
self.gridLayout.addWidget(self.prefer_ep_score, 0, 5, 1, 1)
|
||||
self.label_7 = QtGui.QLabel(self.type_group)
|
||||
self.label_7.setObjectName(_fromUtf8("label_7"))
|
||||
self.gridLayout.addWidget(self.label_7, 1, 0, 1, 1)
|
||||
self.prefer_compilation_score = QtGui.QSlider(self.type_group)
|
||||
self.prefer_compilation_score.setMaximum(100)
|
||||
self.prefer_compilation_score.setProperty("value", 50)
|
||||
self.prefer_compilation_score.setOrientation(QtCore.Qt.Horizontal)
|
||||
self.prefer_compilation_score.setObjectName(_fromUtf8("prefer_compilation_score"))
|
||||
self.gridLayout.addWidget(self.prefer_compilation_score, 1, 1, 1, 1)
|
||||
self.label_8 = QtGui.QLabel(self.type_group)
|
||||
self.label_8.setObjectName(_fromUtf8("label_8"))
|
||||
self.gridLayout.addWidget(self.label_8, 1, 2, 1, 1)
|
||||
self.prefer_soundtrack_score = QtGui.QSlider(self.type_group)
|
||||
self.prefer_soundtrack_score.setMaximum(100)
|
||||
self.prefer_soundtrack_score.setProperty("value", 50)
|
||||
self.prefer_soundtrack_score.setOrientation(QtCore.Qt.Horizontal)
|
||||
self.prefer_soundtrack_score.setObjectName(_fromUtf8("prefer_soundtrack_score"))
|
||||
self.gridLayout.addWidget(self.prefer_soundtrack_score, 1, 3, 1, 1)
|
||||
self.label_9 = QtGui.QLabel(self.type_group)
|
||||
self.label_9.setObjectName(_fromUtf8("label_9"))
|
||||
self.gridLayout.addWidget(self.label_9, 1, 4, 1, 1)
|
||||
self.prefer_spokenword_score = QtGui.QSlider(self.type_group)
|
||||
self.prefer_spokenword_score.setMaximum(100)
|
||||
self.prefer_spokenword_score.setProperty("value", 50)
|
||||
self.prefer_spokenword_score.setOrientation(QtCore.Qt.Horizontal)
|
||||
self.prefer_spokenword_score.setObjectName(_fromUtf8("prefer_spokenword_score"))
|
||||
self.gridLayout.addWidget(self.prefer_spokenword_score, 1, 5, 1, 1)
|
||||
self.label_10 = QtGui.QLabel(self.type_group)
|
||||
self.label_10.setObjectName(_fromUtf8("label_10"))
|
||||
self.gridLayout.addWidget(self.label_10, 2, 0, 1, 1)
|
||||
self.prefer_interview_score = QtGui.QSlider(self.type_group)
|
||||
self.prefer_interview_score.setMaximum(100)
|
||||
self.prefer_interview_score.setProperty("value", 50)
|
||||
self.prefer_interview_score.setOrientation(QtCore.Qt.Horizontal)
|
||||
self.prefer_interview_score.setObjectName(_fromUtf8("prefer_interview_score"))
|
||||
self.gridLayout.addWidget(self.prefer_interview_score, 2, 1, 1, 1)
|
||||
self.label_11 = QtGui.QLabel(self.type_group)
|
||||
self.label_11.setObjectName(_fromUtf8("label_11"))
|
||||
self.gridLayout.addWidget(self.label_11, 2, 2, 1, 1)
|
||||
self.prefer_audiobook_score = QtGui.QSlider(self.type_group)
|
||||
self.prefer_audiobook_score.setMaximum(100)
|
||||
self.prefer_audiobook_score.setProperty("value", 50)
|
||||
self.prefer_audiobook_score.setOrientation(QtCore.Qt.Horizontal)
|
||||
self.prefer_audiobook_score.setObjectName(_fromUtf8("prefer_audiobook_score"))
|
||||
self.gridLayout.addWidget(self.prefer_audiobook_score, 2, 3, 1, 1)
|
||||
self.label_12 = QtGui.QLabel(self.type_group)
|
||||
self.label_12.setObjectName(_fromUtf8("label_12"))
|
||||
self.gridLayout.addWidget(self.label_12, 2, 4, 1, 1)
|
||||
self.prefer_live_score = QtGui.QSlider(self.type_group)
|
||||
self.prefer_live_score.setMaximum(100)
|
||||
self.prefer_live_score.setProperty("value", 50)
|
||||
self.prefer_live_score.setOrientation(QtCore.Qt.Horizontal)
|
||||
self.prefer_live_score.setObjectName(_fromUtf8("prefer_live_score"))
|
||||
self.gridLayout.addWidget(self.prefer_live_score, 2, 5, 1, 1)
|
||||
self.label_13 = QtGui.QLabel(self.type_group)
|
||||
self.label_13.setObjectName(_fromUtf8("label_13"))
|
||||
self.gridLayout.addWidget(self.label_13, 3, 0, 1, 1)
|
||||
self.prefer_remix_score = QtGui.QSlider(self.type_group)
|
||||
self.prefer_remix_score.setMaximum(100)
|
||||
self.prefer_remix_score.setProperty("value", 50)
|
||||
self.prefer_remix_score.setOrientation(QtCore.Qt.Horizontal)
|
||||
self.prefer_remix_score.setObjectName(_fromUtf8("prefer_remix_score"))
|
||||
self.gridLayout.addWidget(self.prefer_remix_score, 3, 1, 1, 1)
|
||||
self.label_14 = QtGui.QLabel(self.type_group)
|
||||
self.label_14.setObjectName(_fromUtf8("label_14"))
|
||||
self.gridLayout.addWidget(self.label_14, 3, 2, 1, 1)
|
||||
self.prefer_other_score = QtGui.QSlider(self.type_group)
|
||||
self.prefer_other_score.setMaximum(100)
|
||||
self.prefer_other_score.setSliderPosition(50)
|
||||
self.prefer_other_score.setOrientation(QtCore.Qt.Horizontal)
|
||||
self.prefer_other_score.setObjectName(_fromUtf8("prefer_other_score"))
|
||||
self.gridLayout.addWidget(self.prefer_other_score, 3, 3, 1, 1)
|
||||
self.reset_preferred_types_btn = QtGui.QPushButton(self.type_group)
|
||||
sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Fixed)
|
||||
sizePolicy.setHorizontalStretch(0)
|
||||
sizePolicy.setVerticalStretch(0)
|
||||
sizePolicy.setHeightForWidth(self.reset_preferred_types_btn.sizePolicy().hasHeightForWidth())
|
||||
self.reset_preferred_types_btn.setSizePolicy(sizePolicy)
|
||||
self.reset_preferred_types_btn.setObjectName(_fromUtf8("reset_preferred_types_btn"))
|
||||
self.gridLayout.addWidget(self.reset_preferred_types_btn, 4, 5, 1, 1)
|
||||
self.verticalLayout_3.addWidget(self.type_group)
|
||||
self.country_group = QtGui.QGroupBox(ReleasesOptionsPage)
|
||||
self.country_group.setObjectName(_fromUtf8("country_group"))
|
||||
@@ -209,18 +102,6 @@ class Ui_ReleasesOptionsPage(object):
|
||||
|
||||
def retranslateUi(self, ReleasesOptionsPage):
|
||||
self.type_group.setTitle(_("Preferred release types"))
|
||||
self.label.setText(_("Album"))
|
||||
self.label_2.setText(_("Single"))
|
||||
self.label_3.setText(_("EP"))
|
||||
self.label_7.setText(_("Compilation"))
|
||||
self.label_8.setText(_("Soundtrack"))
|
||||
self.label_9.setText(_("Spokenword"))
|
||||
self.label_10.setText(_("Interview"))
|
||||
self.label_11.setText(_("Audiobook"))
|
||||
self.label_12.setText(_("Live"))
|
||||
self.label_13.setText(_("Remix"))
|
||||
self.label_14.setText(_("Other"))
|
||||
self.reset_preferred_types_btn.setText(_("Reset all"))
|
||||
self.country_group.setTitle(_("Preferred release countries"))
|
||||
self.add_countries.setText(_(">"))
|
||||
self.remove_countries.setText(_("<"))
|
||||
|
||||
@@ -267,22 +267,6 @@ def rot13(input):
|
||||
return u''.join(unichr(rot_13.encoding_map.get(ord(c), ord(c))) for c in input)
|
||||
|
||||
|
||||
def load_release_type_scores(setting):
|
||||
scores = {}
|
||||
values = setting.split()
|
||||
for i in range(0, len(values), 2):
|
||||
try:
|
||||
score = float(values[i + 1])
|
||||
except IndexError:
|
||||
score = 0.0
|
||||
scores[values[i]] = score
|
||||
return scores
|
||||
|
||||
|
||||
def save_release_type_scores(scores):
|
||||
return " ".join(["%s %.2f" % v for v in scores.iteritems()])
|
||||
|
||||
|
||||
def parse_amazon_url(url):
|
||||
"""Extract host and asin from an amazon url.
|
||||
It returns a dict with host and asin keys on success, None else
|
||||
|
||||
0
po/attributes/.gitignore
vendored
Normal file
0
po/attributes/.gitignore
vendored
Normal file
59
setup.py
59
setup.py
@@ -424,8 +424,8 @@ def _get_option_name(obj):
|
||||
raise Exception("No such command class")
|
||||
|
||||
|
||||
class picard_update_countries(Command):
|
||||
description = "Regenerate countries.py"
|
||||
class picard_update_constants(Command):
|
||||
description = "Regenerate attributes.py and countries.py"
|
||||
user_options = [
|
||||
('skip-pull', None, "skip the tx pull steps"),
|
||||
]
|
||||
@@ -443,22 +443,22 @@ class picard_update_countries(Command):
|
||||
|
||||
from babel.messages import pofile
|
||||
|
||||
countries = dict()
|
||||
if not self.skip_pull:
|
||||
txpull_cmd = [
|
||||
tx_executable,
|
||||
'pull',
|
||||
'--force',
|
||||
'--resource=musicbrainz.countries',
|
||||
'--resource=musicbrainz.attributes,musicbrainz.countries',
|
||||
'--source',
|
||||
'--language=none',
|
||||
]
|
||||
self.spawn(txpull_cmd)
|
||||
|
||||
potfile = os.path.join('po', 'countries', 'countries.pot')
|
||||
countries = dict()
|
||||
countries_potfile = os.path.join('po', 'countries', 'countries.pot')
|
||||
isocode_comment = u'iso.code:'
|
||||
with open(potfile, 'rb') as f:
|
||||
log.info('Parsing %s' % potfile)
|
||||
with open(countries_potfile, 'rb') as f:
|
||||
log.info('Parsing %s' % countries_potfile)
|
||||
po = pofile.read_po(f)
|
||||
for message in po:
|
||||
if not message.id or not isinstance(message.id, unicode):
|
||||
@@ -472,6 +472,28 @@ class picard_update_countries(Command):
|
||||
else:
|
||||
sys.exit('Failed to extract any country code/name !')
|
||||
|
||||
attributes = dict()
|
||||
attributes_potfile = os.path.join('po', 'attributes', 'attributes.pot')
|
||||
extract_attributes = (
|
||||
u'DB:cover_art_archive.art_type/name',
|
||||
u'DB:medium_format/name',
|
||||
u'DB:release_group_primary_type/name',
|
||||
u'DB:release_group_secondary_type/name',
|
||||
)
|
||||
with open(attributes_potfile, 'rb') as f:
|
||||
log.info('Parsing %s' % attributes_potfile)
|
||||
po = pofile.read_po(f)
|
||||
for message in po:
|
||||
if not message.id or not isinstance(message.id, unicode):
|
||||
continue
|
||||
for loc, pos in message.locations:
|
||||
if loc in extract_attributes:
|
||||
attributes[u"%s:%03d" % (loc, pos)] = message.id
|
||||
if attributes:
|
||||
self.attributes_py_file(attributes)
|
||||
else:
|
||||
sys.exit('Failed to extract any attribute !')
|
||||
|
||||
def countries_py_file(self, countries):
|
||||
header = (u"# -*- coding: utf-8 -*-\n"
|
||||
u"# Automatically generated - don't edit.\n"
|
||||
@@ -492,6 +514,26 @@ class picard_update_countries(Command):
|
||||
log.info("%s was rewritten (%d countries)" % (filename,
|
||||
len(countries)))
|
||||
|
||||
def attributes_py_file(self, attributes):
|
||||
header = (u"# -*- coding: utf-8 -*-\n"
|
||||
u"# Automatically generated - don't edit.\n"
|
||||
u"# Use `python setup.py {option}` to update it.\n"
|
||||
u"\n"
|
||||
u"MB_ATTRIBUTES = {{\n")
|
||||
line = u" u'{key}': u'{value}',\n"
|
||||
footer = u"}}\n"
|
||||
filename = os.path.join('picard', 'attributes.py')
|
||||
with open(filename, 'w') as attributes_py:
|
||||
def write_utf8(s, **kwargs):
|
||||
attributes_py.write(s.format(**kwargs).encode('utf-8'))
|
||||
|
||||
write_utf8(header, option=_get_option_name(self))
|
||||
for key, value in sorted(attributes.items(), key=lambda (k,v): k):
|
||||
write_utf8(line, key=key, value=value.replace("'", "\\'"))
|
||||
write_utf8(footer)
|
||||
log.info("%s was rewritten (%d attributes)" % (filename,
|
||||
len(attributes)))
|
||||
|
||||
|
||||
def cflags_to_include_dirs(cflags):
|
||||
cflags = cflags.split()
|
||||
@@ -507,6 +549,7 @@ def _picard_get_locale_files():
|
||||
path_domain = {
|
||||
'po': 'picard',
|
||||
os.path.join('po', 'countries'): 'picard-countries',
|
||||
os.path.join('po', 'attributes'): 'picard-attributes',
|
||||
}
|
||||
for path, domain in path_domain.iteritems():
|
||||
for filepath in glob.glob(os.path.join(path, '*.po')):
|
||||
@@ -537,7 +580,7 @@ args2 = {
|
||||
'clean_ui': picard_clean_ui,
|
||||
'install': picard_install,
|
||||
'install_locales': picard_install_locales,
|
||||
'update_countries': picard_update_countries,
|
||||
'update_constants': picard_update_constants,
|
||||
'get_po_files': picard_get_po_files,
|
||||
'regen_pot_file': picard_regen_pot_file,
|
||||
},
|
||||
|
||||
@@ -92,36 +92,6 @@ class FormatTimeTest(unittest.TestCase):
|
||||
self.assertEqual("2:59", util.format_time(179499))
|
||||
|
||||
|
||||
class LoadReleaseTypeScoresTest(unittest.TestCase):
|
||||
|
||||
def test_valid(self):
|
||||
release_type_score_config = "Album 1.0 Single 0.5 EP 0.5 Compilation 0.5 Soundtrack 0.5 Spokenword 0.5 Interview 0.2 Audiobook 0.0 Live 0.5 Remix 0.4 Other 0.0"
|
||||
release_type_scores = util.load_release_type_scores(release_type_score_config)
|
||||
self.assertEqual(1.0, release_type_scores["Album"])
|
||||
self.assertEqual(0.5, release_type_scores["Single"])
|
||||
self.assertEqual(0.2, release_type_scores["Interview"])
|
||||
self.assertEqual(0.0, release_type_scores["Audiobook"])
|
||||
self.assertEqual(0.4, release_type_scores["Remix"])
|
||||
|
||||
def test_invalid(self):
|
||||
release_type_score_config = "Album 1.0 Other"
|
||||
release_type_scores = util.load_release_type_scores(release_type_score_config)
|
||||
self.assertEqual(1.0, release_type_scores["Album"])
|
||||
self.assertEqual(0.0, release_type_scores["Other"])
|
||||
|
||||
|
||||
class SaveReleaseTypeScoresTest(unittest.TestCase):
|
||||
|
||||
def test(self):
|
||||
expected = "Album 1.00 Single 0.50 Other 0.00"
|
||||
scores = {"Album": 1.0, "Single": 0.5, "Other": 0.0}
|
||||
saved_scores = util.save_release_type_scores(scores)
|
||||
self.assertTrue("Album 1.00" in saved_scores)
|
||||
self.assertTrue("Single 0.50" in saved_scores)
|
||||
self.assertTrue("Other 0.00" in saved_scores)
|
||||
self.assertEqual(6, len(saved_scores.split()))
|
||||
|
||||
|
||||
class HiddenPathTest(unittest.TestCase):
|
||||
|
||||
def test(self):
|
||||
|
||||
@@ -162,17 +162,11 @@
|
||||
<item>
|
||||
<widget class="QListWidget" name="caa_types_selector_1">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Preferred">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>16777215</width>
|
||||
<height>80</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="horizontalScrollBarPolicy">
|
||||
<enum>Qt::ScrollBarAsNeeded</enum>
|
||||
</property>
|
||||
|
||||
@@ -20,239 +20,6 @@
|
||||
<property name="verticalSpacing">
|
||||
<number>6</number>
|
||||
</property>
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="label">
|
||||
<property name="text">
|
||||
<string>Album</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QSlider" name="prefer_album_score">
|
||||
<property name="maximum">
|
||||
<number>100</number>
|
||||
</property>
|
||||
<property name="value">
|
||||
<number>50</number>
|
||||
</property>
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="2">
|
||||
<widget class="QLabel" name="label_2">
|
||||
<property name="text">
|
||||
<string>Single</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="3">
|
||||
<widget class="QSlider" name="prefer_single_score">
|
||||
<property name="maximum">
|
||||
<number>100</number>
|
||||
</property>
|
||||
<property name="value">
|
||||
<number>50</number>
|
||||
</property>
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="4">
|
||||
<widget class="QLabel" name="label_3">
|
||||
<property name="text">
|
||||
<string>EP</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="5">
|
||||
<widget class="QSlider" name="prefer_ep_score">
|
||||
<property name="maximum">
|
||||
<number>100</number>
|
||||
</property>
|
||||
<property name="value">
|
||||
<number>50</number>
|
||||
</property>
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="label_7">
|
||||
<property name="text">
|
||||
<string>Compilation</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QSlider" name="prefer_compilation_score">
|
||||
<property name="maximum">
|
||||
<number>100</number>
|
||||
</property>
|
||||
<property name="value">
|
||||
<number>50</number>
|
||||
</property>
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="2">
|
||||
<widget class="QLabel" name="label_8">
|
||||
<property name="text">
|
||||
<string>Soundtrack</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="3">
|
||||
<widget class="QSlider" name="prefer_soundtrack_score">
|
||||
<property name="maximum">
|
||||
<number>100</number>
|
||||
</property>
|
||||
<property name="value">
|
||||
<number>50</number>
|
||||
</property>
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="4">
|
||||
<widget class="QLabel" name="label_9">
|
||||
<property name="text">
|
||||
<string>Spokenword</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="5">
|
||||
<widget class="QSlider" name="prefer_spokenword_score">
|
||||
<property name="maximum">
|
||||
<number>100</number>
|
||||
</property>
|
||||
<property name="value">
|
||||
<number>50</number>
|
||||
</property>
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QLabel" name="label_10">
|
||||
<property name="text">
|
||||
<string>Interview</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<widget class="QSlider" name="prefer_interview_score">
|
||||
<property name="maximum">
|
||||
<number>100</number>
|
||||
</property>
|
||||
<property name="value">
|
||||
<number>50</number>
|
||||
</property>
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="2">
|
||||
<widget class="QLabel" name="label_11">
|
||||
<property name="text">
|
||||
<string>Audiobook</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="3">
|
||||
<widget class="QSlider" name="prefer_audiobook_score">
|
||||
<property name="maximum">
|
||||
<number>100</number>
|
||||
</property>
|
||||
<property name="value">
|
||||
<number>50</number>
|
||||
</property>
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="4">
|
||||
<widget class="QLabel" name="label_12">
|
||||
<property name="text">
|
||||
<string>Live</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="5">
|
||||
<widget class="QSlider" name="prefer_live_score">
|
||||
<property name="maximum">
|
||||
<number>100</number>
|
||||
</property>
|
||||
<property name="value">
|
||||
<number>50</number>
|
||||
</property>
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="0">
|
||||
<widget class="QLabel" name="label_13">
|
||||
<property name="text">
|
||||
<string>Remix</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="1">
|
||||
<widget class="QSlider" name="prefer_remix_score">
|
||||
<property name="maximum">
|
||||
<number>100</number>
|
||||
</property>
|
||||
<property name="value">
|
||||
<number>50</number>
|
||||
</property>
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="2">
|
||||
<widget class="QLabel" name="label_14">
|
||||
<property name="text">
|
||||
<string>Other</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="3">
|
||||
<widget class="QSlider" name="prefer_other_score">
|
||||
<property name="maximum">
|
||||
<number>100</number>
|
||||
</property>
|
||||
<property name="sliderPosition">
|
||||
<number>50</number>
|
||||
</property>
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="5">
|
||||
<widget class="QPushButton" name="reset_preferred_types_btn">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Minimum" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Reset all</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
|
||||
Reference in New Issue
Block a user