mirror of
https://github.com/fergalmoran/picard.git
synced 2026-02-24 16:43:59 +00:00
Improve conformance to PEP8, tidy up.
This commit is contained in:
@@ -31,6 +31,7 @@ HTML_ATTR_ESCAPE = {
|
||||
'"': """
|
||||
}
|
||||
|
||||
|
||||
class AddClusterAsRelease(BaseAction):
|
||||
NAME = "Add Cluster As Release..."
|
||||
|
||||
@@ -45,6 +46,7 @@ class AddClusterAsRelease(BaseAction):
|
||||
def esc(s):
|
||||
return "".join(HTML_ATTR_ESCAPE.get(c, c) for c in s)
|
||||
# add a global (release-level) name-value
|
||||
|
||||
def nv(n, v):
|
||||
f.write(HTML_INPUT % (esc(n), esc(v)))
|
||||
|
||||
@@ -91,6 +93,6 @@ class AddClusterAsRelease(BaseAction):
|
||||
|
||||
f.write(HTML_TAIL)
|
||||
f.close()
|
||||
webbrowser2.open("file://"+fp)
|
||||
webbrowser2.open("file://" + fp)
|
||||
|
||||
register_cluster_action(AddClusterAsRelease())
|
||||
|
||||
@@ -7,6 +7,7 @@ PLUGIN_API_VERSIONS = ["0.15"]
|
||||
from picard.metadata import register_track_metadata_processor
|
||||
import re
|
||||
|
||||
|
||||
def add_discnumbers(tagger, metadata, release, track):
|
||||
if int(metadata["totaldiscs"] or "0") > 1:
|
||||
if "discsubtitle" in metadata:
|
||||
@@ -18,4 +19,3 @@ def add_discnumbers(tagger, metadata, release, track):
|
||||
metadata["album"], metadata["discnumber"])
|
||||
|
||||
register_track_metadata_processor(add_discnumbers)
|
||||
|
||||
|
||||
@@ -20,7 +20,7 @@ _split_re = re.compile('\s*("[^"]*"|[^ ]+)\s*', re.UNICODE)
|
||||
|
||||
def msfToMs(msf):
|
||||
msf = msf.split(":")
|
||||
return ((int(msf[0]) * 60 + int(msf[1])) * 75 + int(msf[2])) * 1000 / 75
|
||||
return ((int(msf[0]) * 60 + int(msf[1])) * 75 + int(msf[2])) * 1000 / 75
|
||||
|
||||
|
||||
class CuesheetTrack(list):
|
||||
@@ -41,10 +41,10 @@ class CuesheetTrack(list):
|
||||
|
||||
def getLength(self):
|
||||
try:
|
||||
nextTrack = self.cuesheet.tracks[self.index+1]
|
||||
index0 = self.find((u"INDEX",u"01"))
|
||||
index1 = nextTrack.find((u"INDEX",u"01"))
|
||||
return msfToMs(index1[0][2]) - msfToMs(index0[0][2])
|
||||
nextTrack = self.cuesheet.tracks[self.index + 1]
|
||||
index0 = self.find((u"INDEX", u"01"))
|
||||
index1 = nextTrack.find((u"INDEX", u"01"))
|
||||
return msfToMs(index1[0][2]) - msfToMs(index0[0][2])
|
||||
except IndexError:
|
||||
return 0
|
||||
|
||||
|
||||
@@ -15,6 +15,7 @@ import re
|
||||
|
||||
_discnumber_re = re.compile(r"\s+\(disc (\d+)(?::\s+([^)]+))?\)")
|
||||
|
||||
|
||||
def remove_discnumbers(tagger, metadata, release):
|
||||
matches = _discnumber_re.search(metadata["album"])
|
||||
if matches:
|
||||
|
||||
@@ -7,6 +7,7 @@ PLUGIN_API_VERSIONS = ["0.9.0", "0.10", "0.15", "0.16"]
|
||||
from picard.metadata import register_track_metadata_processor
|
||||
import re
|
||||
|
||||
|
||||
def remove_featartists(tagger, metadata, release, track):
|
||||
metadata["title"] = re.sub(r"\s+\(feat. [^)]*\)", "", metadata["title"], flags=re.IGNORECASE)
|
||||
|
||||
|
||||
@@ -7,12 +7,14 @@ PLUGIN_API_VERSIONS = ["0.9.0", "0.10", "0.15", "0.16"]
|
||||
from picard.metadata import register_album_metadata_processor, register_track_metadata_processor
|
||||
import re
|
||||
|
||||
|
||||
def move_album_featartists(tagger, metadata, release):
|
||||
match = re.match(r"([\s\S]+) feat.([\s\S]+)", metadata["albumartist"], re.IGNORECASE)
|
||||
if match:
|
||||
metadata["albumartist"] = match.group(1)
|
||||
metadata["album"] += " (feat.%s)" % match.group(2)
|
||||
|
||||
|
||||
def move_track_featartists(tagger, metadata, release, track):
|
||||
match = re.match(r"([\s\S]+) feat.([\s\S]+)", metadata["artist"], re.IGNORECASE)
|
||||
if match:
|
||||
|
||||
@@ -51,17 +51,23 @@ def _tags_finalize(album, metadata, tags, next):
|
||||
|
||||
def _tags_downloaded(album, metadata, min_usage, ignore, next, current, data, reply, error):
|
||||
try:
|
||||
try: intags = data.toptags[0].tag
|
||||
except AttributeError: intags = []
|
||||
try:
|
||||
intags = data.toptags[0].tag
|
||||
except AttributeError:
|
||||
intags = []
|
||||
tags = []
|
||||
for tag in intags:
|
||||
name = tag.name[0].text.strip()
|
||||
try: count = int(tag.count[0].text.strip())
|
||||
except ValueError: count = 0
|
||||
try:
|
||||
count = int(tag.count[0].text.strip())
|
||||
except ValueError:
|
||||
count = 0
|
||||
if count < min_usage:
|
||||
break
|
||||
try: name = TRANSLATE_TAGS[name]
|
||||
except KeyError: pass
|
||||
try:
|
||||
name = TRANSLATE_TAGS[name]
|
||||
except KeyError:
|
||||
pass
|
||||
if name.lower() not in ignore:
|
||||
tags.append(name.title())
|
||||
url = str(reply.url().path())
|
||||
@@ -107,6 +113,7 @@ def encode_str(s):
|
||||
s = QtCore.QUrl.toPercentEncoding(unicode(s))
|
||||
return s
|
||||
|
||||
|
||||
def get_track_tags(album, metadata, artist, track, min_usage, ignore, next, current):
|
||||
"""Get track top tags."""
|
||||
path = "/1.0/track/%s/%s/toptags.xml" % (encode_str(artist), encode_str(track))
|
||||
|
||||
@@ -10,7 +10,9 @@
|
||||
import sys
|
||||
from PyQt4 import QtCore, QtGui
|
||||
|
||||
|
||||
class Ui_LastfmOptionsPage(object):
|
||||
|
||||
def setupUi(self, LastfmOptionsPage):
|
||||
LastfmOptionsPage.setObjectName("LastfmOptionsPage")
|
||||
LastfmOptionsPage.resize(QtCore.QSize(QtCore.QRect(0,0,305,317).size()).expandedTo(LastfmOptionsPage.minimumSizeHint()))
|
||||
@@ -122,4 +124,3 @@ class Ui_LastfmOptionsPage(object):
|
||||
self.join_tags.addItem(_(", "))
|
||||
self.label_4.setText(_("Minimal tag usage:"))
|
||||
self.min_tag_usage.setSuffix(_(" %"))
|
||||
|
||||
|
||||
@@ -60,6 +60,7 @@ GENRE_FILTER["translate"] = {
|
||||
"drum n bass": u"drum and bass"
|
||||
}
|
||||
|
||||
|
||||
def matches_list(s, lst):
|
||||
if s in lst:
|
||||
return True
|
||||
@@ -70,9 +71,15 @@ def matches_list(s, lst):
|
||||
return False
|
||||
|
||||
# Function to sort/compare a 2 Element of Tupel
|
||||
def cmp1(a,b): return cmp(a[1],b[1])*-1
|
||||
|
||||
|
||||
def cmp1(a, b):
|
||||
return cmp(a[1], b[1]) * -1
|
||||
# Special Compare/Sort-Function to sort downloaded Tags
|
||||
def cmptaginfo(a,b): return cmp(a[1][0],b[1][0])*-1
|
||||
|
||||
|
||||
def cmptaginfo(a, b):
|
||||
return cmp(a[1][0], b[1][0]) * -1
|
||||
|
||||
|
||||
def _lazy_load_filters(cfg):
|
||||
@@ -94,8 +101,10 @@ def apply_translations_and_sally(tag_to_count, sally, factor):
|
||||
ret = {}
|
||||
for name, count in tag_to_count.iteritems():
|
||||
# apply translations
|
||||
try: name = GENRE_FILTER["translate"][name.lower()]
|
||||
except KeyError: pass
|
||||
try:
|
||||
name = GENRE_FILTER["translate"][name.lower()]
|
||||
except KeyError:
|
||||
pass
|
||||
|
||||
# make sure it's lowercase
|
||||
lower = name.lower()
|
||||
@@ -113,8 +122,10 @@ def _tags_finalize(album, metadata, tags, next):
|
||||
else:
|
||||
cfg = album.tagger.config.setting
|
||||
|
||||
lastw = {"n":False, "s":False} # last tag-weight for inter-tag comparsion
|
||||
# List: (use sally-tags, use track-tags, use artist-tags, use drop-info,use minweight,searchlist, max_elems
|
||||
# last tag-weight for inter-tag comparsion
|
||||
lastw = {"n": False, "s": False}
|
||||
# List: (use sally-tags, use track-tags, use artist-tags, use
|
||||
# drop-info,use minweight,searchlist, max_elems
|
||||
info = {"major" : [True, True, True, True, True, GENRE_FILTER["major"], cfg["lastfm_max_group_tags"]],
|
||||
"minor" : [True, True, True, True, True, GENRE_FILTER["minor"], cfg["lastfm_max_minor_tags"]],
|
||||
"country" : [True, False, True, False, False, GENRE_FILTER["country"], 1],
|
||||
@@ -127,10 +138,10 @@ def _tags_finalize(album, metadata, tags, next):
|
||||
"occasion": [True, True, True, False, False, GENRE_FILTER["occasion"], cfg["lastfm_max_occasion_tags"]],
|
||||
"category": [True, True, True, False, False, GENRE_FILTER["category"], cfg["lastfm_max_category_tags"]]
|
||||
}
|
||||
hold = { "all/tags" : [] }
|
||||
hold = {"all/tags": []}
|
||||
|
||||
# Init the Album-Informations
|
||||
albid=album.id
|
||||
albid = album.id
|
||||
if cfg["write_id3v23"]:
|
||||
year_tag = '~id3:TORY'
|
||||
else:
|
||||
@@ -142,65 +153,91 @@ def _tags_finalize(album, metadata, tags, next):
|
||||
"year2" : {'metatag' : 'originalyear', 'data' : ALBUM_YEAR},
|
||||
"year3" : {'metatag' : 'date', 'data' : ALBUM_YEAR} }
|
||||
for elem in glb.keys():
|
||||
if not albid in glb[elem]['data']: glb[elem]['data'][albid] = {'count' : 1, 'genres' : {} }
|
||||
else: glb[elem]['data'][albid]['count'] += 1
|
||||
if not albid in glb[elem]['data']:
|
||||
glb[elem]['data'][albid] = {'count': 1, 'genres': {}}
|
||||
else:
|
||||
glb[elem]['data'][albid]['count'] += 1
|
||||
|
||||
if tags:
|
||||
# search for tags
|
||||
tags.sort(cmp=cmptaginfo)
|
||||
for lowered,[weight,stype] in tags:
|
||||
name=lowered.title()
|
||||
s=stype == 1 # if is tag which should only used for extension (if too few tags found)
|
||||
arttag = stype > 0 # if is artist tag
|
||||
if not name in hold["all/tags"]: hold["all/tags"].append(name)
|
||||
for lowered, [weight, stype] in tags:
|
||||
name = lowered.title()
|
||||
# if is tag which should only used for extension (if too few
|
||||
# tags found)
|
||||
s = stype == 1
|
||||
arttag = stype > 0 # if is artist tag
|
||||
if not name in hold["all/tags"]:
|
||||
hold["all/tags"].append(name)
|
||||
|
||||
# Decide if tag should be searched in major and minor fields
|
||||
drop = not (s and (not lastw['s'] or (lastw['s']-weight) < cfg["lastfm_max_artisttag_drop"])) and not (not s and (not lastw['n'] or (lastw['n']-weight) < cfg["lastfm_max_tracktag_drop"]))
|
||||
drop = not (s and (not lastw['s'] or (lastw['s'] - weight) < cfg["lastfm_max_artisttag_drop"])) and not (
|
||||
not s and (not lastw['n'] or (lastw['n'] - weight) < cfg["lastfm_max_tracktag_drop"]))
|
||||
if not drop:
|
||||
if s: lastw['s'] = weight
|
||||
else: lastw['n'] = weight
|
||||
if s:
|
||||
lastw['s'] = weight
|
||||
else:
|
||||
lastw['n'] = weight
|
||||
|
||||
below = (s and weight < cfg["lastfm_min_artisttag_weight"]) or (not s and weight < cfg["lastfm_min_tracktag_weight"])
|
||||
below = (s and weight < cfg["lastfm_min_artisttag_weight"]) or (
|
||||
not s and weight < cfg["lastfm_min_tracktag_weight"])
|
||||
|
||||
for group, ielem in info.items():
|
||||
if matches_list(lowered, ielem[5]):
|
||||
if below and ielem[4]: break # If Should use min-weigh information
|
||||
if drop and ielem[3]: break # If Should use the drop-information
|
||||
if s and not ielem[0]: break # If Sally-Tag and should not be used
|
||||
if arttag and not ielem[2]: break # If Artist-Tag and should not be used
|
||||
if not arttag and not ielem[1]: break # If Track-Tag and should not be used
|
||||
if below and ielem[4]:
|
||||
# If Should use min-weigh information
|
||||
break
|
||||
if drop and ielem[3]:
|
||||
# If Should use the drop-information
|
||||
break
|
||||
if s and not ielem[0]:
|
||||
# If Sally-Tag and should not be used
|
||||
break
|
||||
if arttag and not ielem[2]:
|
||||
break # If Artist-Tag and should not be used
|
||||
if not arttag and not ielem[1]:
|
||||
break # If Track-Tag and should not be used
|
||||
|
||||
# prefer Not-Sally-Tags (so, artist OR track-tags)
|
||||
if not s and group+"/sally" in hold and name in hold[group+"/sally"]:
|
||||
hold[group+"/sally"].remove(name)
|
||||
hold[group+"/tags"].remove(name)
|
||||
if not s and group + "/sally" in hold and name in hold[group + "/sally"]:
|
||||
hold[group + "/sally"].remove(name)
|
||||
hold[group + "/tags"].remove(name)
|
||||
# Insert Tag
|
||||
if not group+"/tags" in hold: hold[group+"/tags"] = []
|
||||
if not name in hold[group+"/tags"]:
|
||||
if not group + "/tags" in hold:
|
||||
hold[group + "/tags"] = []
|
||||
if not name in hold[group + "/tags"]:
|
||||
if s:
|
||||
if not group+"/sally" in hold: hold[group+"/sally"] = []
|
||||
hold[group+"/sally"].append(name)
|
||||
# collect global genre information for special tag-filters
|
||||
if not group + "/sally" in hold:
|
||||
hold[group + "/sally"] = []
|
||||
hold[group + "/sally"].append(name)
|
||||
# collect global genre information for special
|
||||
# tag-filters
|
||||
if not arttag and group in glb:
|
||||
if not name in glb[group]['data'][albid]['genres']:
|
||||
glb[group]['data'][albid]['genres'][name] = weight
|
||||
else: glb[group]['data'][albid]['genres'][name] += weight
|
||||
glb[group]['data'][albid][
|
||||
'genres'][name] = weight
|
||||
else:
|
||||
glb[group]['data'][albid][
|
||||
'genres'][name] += weight
|
||||
# append tag
|
||||
hold[group+"/tags"].append(name)
|
||||
# Break becase every Tag should be faced only by one GENRE_FILTER
|
||||
hold[group + "/tags"].append(name)
|
||||
# Break becase every Tag should be faced only by one
|
||||
# GENRE_FILTER
|
||||
break
|
||||
|
||||
# cut to wanted size
|
||||
for group,ielem in info.items():
|
||||
while group+"/tags" in hold and len(hold[group+"/tags"]) > ielem[6]:
|
||||
for group, ielem in info.items():
|
||||
while group + "/tags" in hold and len(hold[group + "/tags"]) > ielem[6]:
|
||||
# Remove first all Sally-Tags
|
||||
if group+"/sally" in hold and len(hold[group+"/sally"]) > 0:
|
||||
deltag = hold[group+"/sally"].pop()
|
||||
hold[group+"/tags"].remove(deltag)
|
||||
else: hold[group+"/tags"].pop()
|
||||
if group + "/sally" in hold and len(hold[group + "/sally"]) > 0:
|
||||
deltag = hold[group + "/sally"].pop()
|
||||
hold[group + "/tags"].remove(deltag)
|
||||
else:
|
||||
hold[group + "/tags"].pop()
|
||||
|
||||
# join the information
|
||||
join_tags = cfg["lastfm_join_tags_sign"]
|
||||
|
||||
def join_tags_or_not(list):
|
||||
if join_tags:
|
||||
return join_tags.join(list)
|
||||
@@ -209,52 +246,64 @@ def _tags_finalize(album, metadata, tags, next):
|
||||
used = []
|
||||
|
||||
# write the major-tags
|
||||
if "major/tags" in hold and len(hold["major/tags"])>0:
|
||||
if "major/tags" in hold and len(hold["major/tags"]) > 0:
|
||||
metadata["grouping"] = join_tags_or_not(hold["major/tags"])
|
||||
used.extend(hold["major/tags"])
|
||||
|
||||
# write the decade-tags
|
||||
if "decade/tags" in hold and len(hold["decade/tags"])>0 and cfg["lastfm_use_decade_tag"]:
|
||||
metadata["comment:Songs-DB_Custom1"] = join_tags_or_not([item.lower() for item in hold["decade/tags"]])
|
||||
if "decade/tags" in hold and len(hold["decade/tags"]) > 0 and cfg["lastfm_use_decade_tag"]:
|
||||
metadata["comment:Songs-DB_Custom1"] = join_tags_or_not(
|
||||
[item.lower() for item in hold["decade/tags"]])
|
||||
used.extend(hold["decade/tags"])
|
||||
|
||||
# write country tag
|
||||
if "country/tags" in hold and len(hold["country/tags"])>0 and "city/tags" in hold and len(hold["city/tags"])>0 and cfg["lastfm_use_country_tag"] and cfg["lastfm_use_city_tag"]:
|
||||
metadata["comment:Songs-DB_Custom3"] = join_tags_or_not(hold["country/tags"] + hold["city/tags"])
|
||||
if "country/tags" in hold and len(hold["country/tags"]) > 0 and "city/tags" in hold and len(hold["city/tags"]) > 0 and cfg["lastfm_use_country_tag"] and cfg["lastfm_use_city_tag"]:
|
||||
metadata["comment:Songs-DB_Custom3"] = join_tags_or_not(
|
||||
hold["country/tags"] + hold["city/tags"])
|
||||
used.extend(hold["country/tags"])
|
||||
used.extend(hold["city/tags"])
|
||||
elif "country/tags" in hold and len(hold["country/tags"])>0 and cfg["lastfm_use_country_tag"]:
|
||||
metadata["comment:Songs-DB_Custom3"] = join_tags_or_not(hold["country/tags"])
|
||||
elif "country/tags" in hold and len(hold["country/tags"]) > 0 and cfg["lastfm_use_country_tag"]:
|
||||
metadata["comment:Songs-DB_Custom3"] = join_tags_or_not(
|
||||
hold["country/tags"])
|
||||
used.extend(hold["country/tags"])
|
||||
elif "city/tags" in hold and len(hold["city/tags"])>0 and cfg["lastfm_use_city_tag"]:
|
||||
metadata["comment:Songs-DB_Custom3"] = join_tags_or_not(hold["city/tags"])
|
||||
elif "city/tags" in hold and len(hold["city/tags"]) > 0 and cfg["lastfm_use_city_tag"]:
|
||||
metadata["comment:Songs-DB_Custom3"] = join_tags_or_not(
|
||||
hold["city/tags"])
|
||||
used.extend(hold["city/tags"])
|
||||
|
||||
# write the mood-tags
|
||||
if "mood/tags" in hold and len(hold["mood/tags"])>0:
|
||||
if "mood/tags" in hold and len(hold["mood/tags"]) > 0:
|
||||
metadata["mood"] = join_tags_or_not(hold["mood/tags"])
|
||||
used.extend(hold["mood/tags"])
|
||||
|
||||
# write the occasion-tags
|
||||
if "occasion/tags" in hold and len(hold["occasion/tags"])>0:
|
||||
metadata["comment:Songs-DB_Occasion"] = join_tags_or_not(hold["occasion/tags"])
|
||||
if "occasion/tags" in hold and len(hold["occasion/tags"]) > 0:
|
||||
metadata["comment:Songs-DB_Occasion"] = join_tags_or_not(
|
||||
hold["occasion/tags"])
|
||||
used.extend(hold["occasion/tags"])
|
||||
|
||||
# write the category-tags
|
||||
if "category/tags" in hold and len(hold["category/tags"])>0:
|
||||
metadata["comment:Songs-DB_Custom2"] = join_tags_or_not(hold["category/tags"])
|
||||
if "category/tags" in hold and len(hold["category/tags"]) > 0:
|
||||
metadata["comment:Songs-DB_Custom2"] = join_tags_or_not(
|
||||
hold["category/tags"])
|
||||
used.extend(hold["category/tags"])
|
||||
|
||||
# include major tags as minor tags also copy major to minor if no minor genre
|
||||
if cfg["lastfm_app_major2minor_tag"] and "major/tags" in hold and "minor/tags" in hold and len(hold["minor/tags"])>0:
|
||||
# include major tags as minor tags also copy major to minor if
|
||||
# no minor genre
|
||||
if cfg["lastfm_app_major2minor_tag"] and "major/tags" in hold and "minor/tags" in hold and len(hold["minor/tags"]) > 0:
|
||||
used.extend(hold["major/tags"])
|
||||
used.extend(hold["minor/tags"])
|
||||
if len(used) > 0: metadata["genre"] = join_tags_or_not(hold["major/tags"] + hold["minor/tags"])
|
||||
if len(used) > 0:
|
||||
metadata["genre"] = join_tags_or_not(
|
||||
hold["major/tags"] + hold["minor/tags"])
|
||||
elif cfg["lastfm_app_major2minor_tag"] and "major/tags" in hold and "minor/tags" not in hold:
|
||||
used.extend(hold["major/tags"])
|
||||
if len(used) > 0: metadata["genre"] = join_tags_or_not(hold["major/tags"])
|
||||
elif "minor/tags" in hold and len(hold["minor/tags"])>0:
|
||||
metadata["genre"] = join_tags_or_not(hold["minor/tags"])
|
||||
if len(used) > 0:
|
||||
metadata["genre"] = join_tags_or_not(
|
||||
hold["major/tags"])
|
||||
elif "minor/tags" in hold and len(hold["minor/tags"]) > 0:
|
||||
metadata["genre"] = join_tags_or_not(
|
||||
hold["minor/tags"])
|
||||
used.extend(hold["minor/tags"])
|
||||
else:
|
||||
if "minor/tags" not in hold and "major/tags" in hold:
|
||||
@@ -262,7 +311,7 @@ def _tags_finalize(album, metadata, tags, next):
|
||||
|
||||
# replace blank original year with release date
|
||||
if cfg["lastfm_use_year_tag"]:
|
||||
if "year/tags" not in hold and len(metadata["date"])>0:
|
||||
if "year/tags" not in hold and len(metadata["date"]) > 0:
|
||||
metadata["originalyear"] = metadata["date"][:4]
|
||||
if cfg["write_id3v23"]:
|
||||
metadata["~id3:TORY"] = metadata["date"][:4]
|
||||
@@ -288,8 +337,10 @@ def _tags_finalize(album, metadata, tags, next):
|
||||
def _tags_downloaded(album, metadata, sally, factor, next, current, data, reply, error):
|
||||
try:
|
||||
|
||||
try: intags = data.toptags[0].tag
|
||||
except AttributeError: intags = []
|
||||
try:
|
||||
intags = data.toptags[0].tag
|
||||
except AttributeError:
|
||||
intags = []
|
||||
|
||||
# Extract just names and counts from response; apply no parsing at this stage
|
||||
tag_to_count = {}
|
||||
@@ -298,12 +349,13 @@ def _tags_downloaded(album, metadata, sally, factor, next, current, data, reply,
|
||||
name = tag.name[0].text.strip()
|
||||
|
||||
# count of the tag
|
||||
try: count = int(tag.count[0].text.strip())
|
||||
except ValueError: count = 0
|
||||
try:
|
||||
count = int(tag.count[0].text.strip())
|
||||
except ValueError:
|
||||
count = 0
|
||||
|
||||
tag_to_count[name] = count
|
||||
|
||||
|
||||
url = str(reply.url().path())
|
||||
_cache[url] = tag_to_count
|
||||
|
||||
@@ -365,8 +417,9 @@ def get_track_tags(album, metadata, artist, track, next, current):
|
||||
def get_artist_tags(album, metadata, artist, next, current):
|
||||
path = "/1.0/artist/%s/toptags.xml" % encode_str(artist)
|
||||
sally = 2
|
||||
if album.tagger.config.setting["lastfm_artist_tag_us_ex"]: sally = 1
|
||||
factor = album.tagger.config.setting["lastfm_artist_tags_weight"]/100.0
|
||||
if album.tagger.config.setting["lastfm_artist_tag_us_ex"]:
|
||||
sally = 1
|
||||
factor = album.tagger.config.setting["lastfm_artist_tags_weight"] / 100.0
|
||||
return get_tags(album, metadata, path, sally, factor, next, current)
|
||||
|
||||
|
||||
@@ -397,9 +450,9 @@ class LastfmOptionsPage(OptionsPage):
|
||||
options = [
|
||||
IntOption("setting", "lastfm_max_minor_tags", 4),
|
||||
IntOption("setting", "lastfm_max_group_tags", 1),
|
||||
IntOption("setting", "lastfm_max_mood_tags",4),
|
||||
IntOption("setting", "lastfm_max_occasion_tags",4),
|
||||
IntOption("setting", "lastfm_max_category_tags",4),
|
||||
IntOption("setting", "lastfm_max_mood_tags", 4),
|
||||
IntOption("setting", "lastfm_max_occasion_tags", 4),
|
||||
IntOption("setting", "lastfm_max_category_tags", 4),
|
||||
BoolOption("setting", "lastfm_use_country_tag", True),
|
||||
BoolOption("setting", "lastfm_use_city_tag", True),
|
||||
BoolOption("setting", "lastfm_use_decade_tag", True),
|
||||
@@ -433,20 +486,27 @@ class LastfmOptionsPage(OptionsPage):
|
||||
self.ui.setupUi(self)
|
||||
# TODO Not yet implemented properly
|
||||
# self.connect(self.ui.check_translation_list, QtCore.SIGNAL("clicked()"), self.check_translations)
|
||||
self.connect(self.ui.check_word_lists, QtCore.SIGNAL("clicked()"), self.check_words)
|
||||
self.connect(self.ui.load_default_lists, QtCore.SIGNAL("clicked()"), self.load_defaults)
|
||||
self.connect(self.ui.filter_report, QtCore.SIGNAL("clicked()"), self.create_report)
|
||||
self.connect(self.ui.check_word_lists,
|
||||
QtCore.SIGNAL("clicked()"), self.check_words)
|
||||
self.connect(self.ui.load_default_lists,
|
||||
QtCore.SIGNAL("clicked()"), self.load_defaults)
|
||||
self.connect(self.ui.filter_report,
|
||||
QtCore.SIGNAL("clicked()"), self.create_report)
|
||||
|
||||
# function to check all translations and make sure a corresponding word exists in word lists, notify in message translations pointing nowhere.
|
||||
# function to check all translations and make sure a corresponding word
|
||||
# exists in word lists, notify in message translations pointing nowhere.
|
||||
def check_translations(self):
|
||||
cfg = self.config.setting
|
||||
translations = ( cfg["lastfm_genre_translations"].replace("\n", "|") )
|
||||
tr2 = list(item for item in translations.split('|') )
|
||||
wordlists = ( cfg["lastfm_genre_major"] + cfg["lastfm_genre_minor"] + cfg["lastfm_genre_country"] + cfg["lastfm_genre_occasion"] + cfg["lastfm_genre_mood"] + cfg["lastfm_genre_decade"] + cfg["lastfm_genre_year"] + cfg["lastfm_genre_category"] )
|
||||
translations = (cfg["lastfm_genre_translations"].replace("\n", "|"))
|
||||
tr2 = list(item for item in translations.split('|'))
|
||||
wordlists = (cfg["lastfm_genre_major"] + cfg["lastfm_genre_minor"] + cfg["lastfm_genre_country"] + cfg["lastfm_genre_occasion"]
|
||||
+ cfg["lastfm_genre_mood"] + cfg["lastfm_genre_decade"] + cfg["lastfm_genre_year"] + cfg["lastfm_genre_category"])
|
||||
# TODO need to check to see if translations are in wordlists
|
||||
QtGui.QMessageBox.information(self, self.tr("QMessageBox.showInformation()"), ",".join(tr2) )
|
||||
QtGui.QMessageBox.information(
|
||||
self, self.tr("QMessageBox.showInformation()"), ",".join(tr2))
|
||||
|
||||
# function to check that word lists contain no duplicate entries, notify in message duplicates and which lists they appear in
|
||||
# function to check that word lists contain no duplicate entries, notify
|
||||
# in message duplicates and which lists they appear in
|
||||
def check_words(self):
|
||||
cfg = self.config.setting
|
||||
# Create a set for each option cfg option
|
||||
@@ -509,13 +569,14 @@ class LastfmOptionsPage(OptionsPage):
|
||||
lists = {}
|
||||
for line in open(fileName):
|
||||
data = line.rstrip('\r\n').split(",")
|
||||
if not columns: # first line
|
||||
if not columns: # first line
|
||||
columns = tuple(data)
|
||||
for column in columns:
|
||||
lists[column] = []
|
||||
else: # data lines
|
||||
else: # data lines
|
||||
for column, value in zip(columns, data):
|
||||
if value: lists[column].append(value)
|
||||
if value:
|
||||
lists[column].append(value)
|
||||
self.ui.genre_major.setText(', '.join(lists['Major']))
|
||||
self.ui.genre_minor.setText(', '.join(lists['Minor']))
|
||||
self.ui.genre_country.setText(', '.join(lists['Country']))
|
||||
@@ -524,7 +585,9 @@ class LastfmOptionsPage(OptionsPage):
|
||||
self.ui.genre_mood.setText(', '.join(lists['Mood']))
|
||||
self.ui.genre_occasion.setText(', '.join(lists['Occasion']))
|
||||
|
||||
# Function to create simple report window. Could do a count of values in each section and the amount of translations. Total tags being scanned for.
|
||||
# Function to create simple report window. Could do a count of values in
|
||||
# each section and the amount of translations. Total tags being scanned
|
||||
# for.
|
||||
def create_report(self):
|
||||
cfg = self.config.setting
|
||||
options = [
|
||||
|
||||
@@ -9,7 +9,9 @@
|
||||
|
||||
from PyQt4 import QtCore, QtGui
|
||||
|
||||
|
||||
class Ui_LastfmOptionsPage(object):
|
||||
|
||||
def setupUi(self, LastfmOptionsPage):
|
||||
LastfmOptionsPage.setObjectName("LastfmOptionsPage")
|
||||
LastfmOptionsPage.resize(414, 493)
|
||||
|
||||
@@ -14,7 +14,9 @@ from picard.ui.options import register_options_page, OptionsPage
|
||||
from picard.ui.itemviews import BaseAction, register_album_action
|
||||
from picard.config import BoolOption, TextOption
|
||||
|
||||
|
||||
class Ui_NoReleaseOptionsPage(object):
|
||||
|
||||
def setupUi(self, NoReleaseOptionsPage):
|
||||
NoReleaseOptionsPage.setObjectName('NoReleaseOptionsPage')
|
||||
NoReleaseOptionsPage.resize(394, 300)
|
||||
@@ -48,6 +50,7 @@ class Ui_NoReleaseOptionsPage(object):
|
||||
self.norelease_enable.setText(QtGui.QApplication.translate('NoReleaseOptionsPage', _('Enable plugin for all releases by default'), None, QtGui.QApplication.UnicodeUTF8))
|
||||
self.label.setText(QtGui.QApplication.translate('NoReleaseOptionsPage', _('Tags to strip (comma-separated)'), None, QtGui.QApplication.UnicodeUTF8))
|
||||
|
||||
|
||||
def strip_release_specific_metadata(tagger, metadata):
|
||||
strip_tags = tagger.config.setting['norelease_strip_tags']
|
||||
strip_tags = [tag.strip() for tag in strip_tags.split(',')]
|
||||
@@ -55,8 +58,10 @@ def strip_release_specific_metadata(tagger, metadata):
|
||||
if tag in metadata:
|
||||
del metadata[tag]
|
||||
|
||||
|
||||
class NoReleaseAction(BaseAction):
|
||||
NAME = _('Remove specific release information...')
|
||||
|
||||
def callback(self, objs):
|
||||
for album in objs:
|
||||
if isinstance(album, Album):
|
||||
@@ -67,6 +72,7 @@ class NoReleaseAction(BaseAction):
|
||||
track.update_file_metadata(file)
|
||||
album.update()
|
||||
|
||||
|
||||
class NoReleaseOptionsPage(OptionsPage):
|
||||
NAME = 'norelease'
|
||||
TITLE = 'No release'
|
||||
@@ -90,10 +96,12 @@ class NoReleaseOptionsPage(OptionsPage):
|
||||
self.config.setting['norelease_strip_tags'] = unicode(self.ui.norelease_strip_tags.text())
|
||||
self.config.setting['norelease_enable'] = self.ui.norelease_enable.isChecked()
|
||||
|
||||
|
||||
def NoReleaseAlbumProcessor(tagger, metadata, release):
|
||||
if tagger.config.setting['norelease_enable']:
|
||||
strip_release_specific_metadata(tagger, metadata)
|
||||
|
||||
|
||||
def NoReleaseTrackProcessor(tagger, metadata, track, release):
|
||||
if tagger.config.setting['norelease_enable']:
|
||||
strip_release_specific_metadata(tagger, metadata)
|
||||
|
||||
@@ -14,6 +14,7 @@ from picard.util import partial
|
||||
from picard.mbxml import release_to_metadata
|
||||
from PyQt4.QtCore import QUrl
|
||||
|
||||
|
||||
def _earliest_release_downloaded(album, metadata, original_id, document, http, error):
|
||||
try:
|
||||
if error:
|
||||
@@ -34,12 +35,13 @@ def _earliest_release_downloaded(album, metadata, original_id, document, http, e
|
||||
album._requests -= 1
|
||||
album._finalize_loading(None)
|
||||
|
||||
|
||||
def original_release_date(album, metadata, release_node):
|
||||
# First find the earliest release from the release event list
|
||||
get_earliest_release_date(album, metadata)
|
||||
|
||||
|
||||
# Check for earliest release ARs and load those
|
||||
if release_node.children.has_key('relation_list'):
|
||||
if 'relation_list' in release_node.children:
|
||||
for relation_list in release_node.relation_list:
|
||||
if relation_list.target_type == 'Release':
|
||||
for relation in relation_list.relation:
|
||||
@@ -51,7 +53,9 @@ def original_release_date(album, metadata, release_node):
|
||||
album.tagger.xmlws.get_release_by_id(relation.target,
|
||||
partial(_earliest_release_downloaded, album, metadata, relation.target),
|
||||
['release-events'])
|
||||
except AttributeError: pass
|
||||
except AttributeError:
|
||||
pass
|
||||
|
||||
|
||||
def get_earliest_release_date(album, metadata):
|
||||
earliest_date = metadata["originaldate"]
|
||||
|
||||
@@ -7,7 +7,9 @@ PLUGIN_VERSION = "0.1"
|
||||
PLUGIN_API_VERSIONS = ["0.9.0", "0.10", "0.15"]
|
||||
|
||||
|
||||
import subprocess, sys, os
|
||||
import subprocess
|
||||
import sys
|
||||
import os
|
||||
from PyQt4 import QtCore, QtGui
|
||||
from picard.file import File
|
||||
from picard.track import Track
|
||||
|
||||
@@ -13,6 +13,7 @@ import re
|
||||
_SINGLE = " (single)"
|
||||
_EP = " EP"
|
||||
|
||||
|
||||
def add_release_type(tagger, metadata, release):
|
||||
|
||||
# make sure "EP" (or "single", ...) is not already a word in the name
|
||||
@@ -23,9 +24,9 @@ def add_release_type(tagger, metadata, release):
|
||||
|
||||
# check release type
|
||||
if metadata["releasetype"] == "ep":
|
||||
rs = _EP;
|
||||
rs = _EP
|
||||
elif metadata["releasetype"] == "single":
|
||||
rs = _SINGLE;
|
||||
rs = _SINGLE
|
||||
else:
|
||||
rs = ""
|
||||
|
||||
@@ -33,4 +34,3 @@ def add_release_type(tagger, metadata, release):
|
||||
metadata["album"] = metadata["album"] + rs
|
||||
|
||||
register_album_metadata_processor(add_release_type)
|
||||
|
||||
|
||||
@@ -31,18 +31,20 @@ REPLAYGAIN_COMMANDS = {
|
||||
"WavPack": ("replaygain_wvgain_command", "replaygain_wvgain_options"),
|
||||
}
|
||||
|
||||
|
||||
def calculate_replay_gain_for_files(files, format, tagger):
|
||||
"""Calculates the replay gain for a list of files in album mode."""
|
||||
file_list = ['%s' % encode_filename(f.filename) for f in files]
|
||||
|
||||
if REPLAYGAIN_COMMANDS.has_key(format) \
|
||||
if format in REPLAYGAIN_COMMANDS \
|
||||
and tagger.config.setting[REPLAYGAIN_COMMANDS[format][0]]:
|
||||
command = tagger.config.setting[REPLAYGAIN_COMMANDS[format][0]]
|
||||
options = tagger.config.setting[REPLAYGAIN_COMMANDS[format][1]].split(' ')
|
||||
tagger.log.debug('%s %s %s' % (command, ' '.join(options), decode_filename(' '.join(file_list))))
|
||||
check_call([command] + options + file_list)
|
||||
else:
|
||||
raise Exception, 'ReplayGain: Unsupported format %s' % (format)
|
||||
raise Exception('ReplayGain: Unsupported format %s' % (format))
|
||||
|
||||
|
||||
class ReplayGain(BaseAction):
|
||||
NAME = N_("Calculate replay &gain...")
|
||||
@@ -85,7 +87,7 @@ class AlbumGain(BaseAction):
|
||||
files_by_format = {}
|
||||
|
||||
for file in files:
|
||||
if not files_by_format.has_key(file.NAME):
|
||||
if file.NAME not in files_by_format:
|
||||
files_by_format[file.NAME] = [file]
|
||||
else:
|
||||
files_by_format[file.NAME].append(file)
|
||||
|
||||
@@ -14,7 +14,9 @@ try:
|
||||
except AttributeError:
|
||||
_fromUtf8 = lambda s: s
|
||||
|
||||
|
||||
class Ui_ReplayGainOptionsPage(object):
|
||||
|
||||
def setupUi(self, ReplayGainOptionsPage):
|
||||
ReplayGainOptionsPage.setObjectName(_fromUtf8("ReplayGainOptionsPage"))
|
||||
ReplayGainOptionsPage.resize(305, 317)
|
||||
|
||||
@@ -22,6 +22,8 @@ PLUGIN_API_VERSIONS = ["0.15"]
|
||||
from picard.metadata import register_track_metadata_processor
|
||||
|
||||
# Define and register the Track Metadata function
|
||||
|
||||
|
||||
def sort_multivalue_tags(tagger, metadata, track, release):
|
||||
|
||||
for tag in metadata.keys():
|
||||
|
||||
@@ -30,6 +30,7 @@ PLUGIN_API_VERSIONS = ["0.9.0", "0.10", "0.11", "0.12", "0.15"]
|
||||
from picard.script import register_script_function
|
||||
import re
|
||||
|
||||
|
||||
def swapprefix(parser, text, *prefixes):
|
||||
"""
|
||||
Moves the specified prefixes to the end of text.
|
||||
@@ -48,5 +49,3 @@ def swapprefix(parser, text, *prefixes):
|
||||
return text
|
||||
|
||||
register_script_function(swapprefix)
|
||||
|
||||
|
||||
|
||||
@@ -13,12 +13,14 @@ PLUGIN_API_VERSIONS = ["0.9", "0.10", "0.11", "0.15"]
|
||||
|
||||
import unicodedata
|
||||
|
||||
|
||||
def iswbound(char):
|
||||
"""Returns whether the given character is a word boundary."""
|
||||
category = unicodedata.category(char)
|
||||
# If it's a space separator or punctuation
|
||||
return 'Zs' == category or 'Sk' == category or 'P' == category[0]
|
||||
|
||||
|
||||
def utitle(string):
|
||||
"""Title-case a string using a less destructive method than str.title."""
|
||||
new_string = string[0].capitalize()
|
||||
@@ -26,18 +28,23 @@ def utitle(string):
|
||||
for i in xrange(1, len(string)):
|
||||
s = string[i]
|
||||
# Special case apostrophe in the middle of a word.
|
||||
if s in u"’'" and string[i-1].isalpha(): cap = False
|
||||
elif iswbound(s): cap = True
|
||||
if s in u"’'" and string[i - 1].isalpha():
|
||||
cap = False
|
||||
elif iswbound(s):
|
||||
cap = True
|
||||
elif cap and s.isalpha():
|
||||
cap = False
|
||||
s = s.capitalize()
|
||||
else: cap = False
|
||||
else:
|
||||
cap = False
|
||||
new_string += s
|
||||
return new_string
|
||||
|
||||
|
||||
def title(string, locale="utf-8"):
|
||||
"""Title-case a string using a less destructive method than str.title."""
|
||||
if not string: return u""
|
||||
if not string:
|
||||
return u""
|
||||
# if the string is all uppercase, lowercase it - Erich/Javier
|
||||
# Lots of Japanese songs use entirely upper-case English titles,
|
||||
# so I don't like this change... - JoeW
|
||||
@@ -51,6 +58,7 @@ from picard.metadata import (
|
||||
register_album_metadata_processor,
|
||||
)
|
||||
|
||||
|
||||
def title_case(tagger, metadata, release, track=None):
|
||||
for name, value in metadata.rawitems():
|
||||
if name in ["title", "album", "artist"]:
|
||||
|
||||
@@ -49,4 +49,3 @@ class CopyClusterToClipboard(BaseAction):
|
||||
|
||||
|
||||
register_cluster_action(CopyClusterToClipboard())
|
||||
|
||||
|
||||
Reference in New Issue
Block a user