f7080a3dc8
Copy from multimedia:apps/picard based on submit request 46222 from user saschpe OBS-URL: https://build.opensuse.org/request/show/46222 OBS-URL: https://build.opensuse.org/package/show/openSUSE:Factory/picard?expand=0&rev=1
158 lines
6.0 KiB
Python
158 lines
6.0 KiB
Python
# -*- coding: utf-8 -*-
|
|
|
|
PLUGIN_NAME = u'Last.fm'
|
|
PLUGIN_AUTHOR = u'Lukáš Lalinský'
|
|
PLUGIN_DESCRIPTION = u'Use tags from Last.fm as genre.'
|
|
PLUGIN_VERSION = "0.2"
|
|
PLUGIN_API_VERSIONS = ["0.9.0", "0.10"]
|
|
|
|
from PyQt4 import QtGui, QtCore
|
|
from picard.metadata import register_album_metadata_processor, register_track_metadata_processor
|
|
from picard.ui.options import register_options_page, OptionsPage
|
|
from picard.config import BoolOption, IntOption, TextOption
|
|
from picard.plugins.lastfm.ui_options_lastfm import Ui_LastfmOptionsPage
|
|
from picard.util import partial
|
|
|
|
_cache = {}
|
|
# TODO: move this to an options page
|
|
TRANSLATE_TAGS = {
|
|
"hip hop": u"Hip-Hop",
|
|
"synth-pop": u"Synthpop",
|
|
"electronica": u"Electronic",
|
|
}
|
|
TITLE_CASE = True
|
|
|
|
|
|
def _tags_finalize(album, metadata, tags, next):
|
|
if next:
|
|
album._requests += 1
|
|
next(tags)
|
|
else:
|
|
tags = list(set(tags))
|
|
if tags:
|
|
join_tags = album.tagger.config.setting["lastfm_join_tags"]
|
|
if join_tags:
|
|
tags = join_tags.join(tags)
|
|
metadata["genre"] = tags
|
|
|
|
|
|
def _tags_downloaded(album, metadata, min_usage, ignore, next, current, data, http, error):
|
|
try:
|
|
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(), 10)
|
|
except ValueError: count = 0
|
|
if count < min_usage:
|
|
break
|
|
try: name = TRANSLATE_TAGS[name]
|
|
except KeyError: pass
|
|
if name.lower() not in ignore:
|
|
tags.append(name.title())
|
|
_cache[str(http.currentRequest().path())] = tags
|
|
_tags_finalize(album, metadata, current + tags, next)
|
|
finally:
|
|
album._requests -= 1
|
|
album._finalize_loading(None)
|
|
|
|
|
|
def get_tags(album, metadata, path, min_usage, ignore, next, current):
|
|
"""Get tags from an URL."""
|
|
try:
|
|
if path in _cache:
|
|
_tags_finalize(album, metadata, current + _cache[path], next)
|
|
else:
|
|
album._requests += 1
|
|
album.tagger.xmlws.get("ws.audioscrobbler.com", 80, path,
|
|
partial(_tags_downloaded, album, metadata, min_usage, ignore, next, current),
|
|
position=1)
|
|
finally:
|
|
album._requests -= 1
|
|
album._finalize_loading(None)
|
|
return False
|
|
|
|
|
|
def encode_str(s):
|
|
# Yes, that's right, Last.fm prefers double URL-encoding
|
|
s = QtCore.QUrl.toPercentEncoding(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))
|
|
return get_tags(album, metadata, path, min_usage, ignore, next, current)
|
|
|
|
|
|
def get_artist_tags(album, metadata, artist, min_usage, ignore, next, current):
|
|
"""Get artist top tags."""
|
|
path = "/1.0/artist/%s/toptags.xml" % (encode_str(artist),)
|
|
return get_tags(album, metadata, path, min_usage, ignore, next, current)
|
|
|
|
|
|
def process_track(album, metadata, release, track):
|
|
tagger = album.tagger
|
|
use_track_tags = tagger.config.setting["lastfm_use_track_tags"]
|
|
use_artist_tags = tagger.config.setting["lastfm_use_artist_tags"]
|
|
min_tag_usage = tagger.config.setting["lastfm_min_tag_usage"]
|
|
ignore_tags = tagger.config.setting["lastfm_ignore_tags"].lower().split(",")
|
|
if use_track_tags or use_artist_tags:
|
|
artist = metadata["artist"]
|
|
title = metadata["title"]
|
|
if artist:
|
|
if use_artist_tags:
|
|
get_artist_tags_func = partial(get_artist_tags, album, metadata, artist, min_tag_usage, ignore_tags, None)
|
|
else:
|
|
get_artist_tags_func = None
|
|
if title and use_track_tags:
|
|
func = partial(get_track_tags, album, metadata, artist, title, min_tag_usage, ignore_tags, get_artist_tags_func, [])
|
|
elif get_artist_tags_func:
|
|
func = partial(get_artist_tags_func, [])
|
|
if func:
|
|
album._requests += 1
|
|
tagger.xmlws.add_task(func, position=1)
|
|
|
|
|
|
class LastfmOptionsPage(OptionsPage):
|
|
|
|
NAME = "lastfm"
|
|
TITLE = "Last.fm"
|
|
PARENT = "plugins"
|
|
|
|
options = [
|
|
BoolOption("setting", "lastfm_use_track_tags", False),
|
|
BoolOption("setting", "lastfm_use_artist_tags", False),
|
|
#BoolOption("setting", "lastfm_use_artist_images", False),
|
|
IntOption("setting", "lastfm_min_tag_usage", 15),
|
|
TextOption("setting", "lastfm_ignore_tags", "seen live,favorites"),
|
|
TextOption("setting", "lastfm_join_tags", ""),
|
|
]
|
|
|
|
def __init__(self, parent=None):
|
|
super(LastfmOptionsPage, self).__init__(parent)
|
|
self.ui = Ui_LastfmOptionsPage()
|
|
self.ui.setupUi(self)
|
|
|
|
def load(self):
|
|
self.ui.use_track_tags.setChecked(self.config.setting["lastfm_use_track_tags"])
|
|
self.ui.use_artist_tags.setChecked(self.config.setting["lastfm_use_artist_tags"])
|
|
#self.ui.use_artist_images.setChecked(self.config.setting["lastfm_use_artist_images"])
|
|
self.ui.min_tag_usage.setValue(self.config.setting["lastfm_min_tag_usage"])
|
|
self.ui.ignore_tags.setText(self.config.setting["lastfm_ignore_tags"])
|
|
self.ui.join_tags.setEditText(self.config.setting["lastfm_join_tags"])
|
|
|
|
def save(self):
|
|
self.config.setting["lastfm_use_track_tags"] = self.ui.use_track_tags.isChecked()
|
|
self.config.setting["lastfm_use_artist_tags"] = self.ui.use_artist_tags.isChecked()
|
|
#self.config.setting["lastfm_use_artist_images"] = self.ui.use_artist_images.isChecked()
|
|
self.config.setting["lastfm_min_tag_usage"] = self.ui.min_tag_usage.value()
|
|
self.config.setting["lastfm_ignore_tags"] = unicode(self.ui.ignore_tags.text())
|
|
self.config.setting["lastfm_join_tags"] = unicode(self.ui.join_tags.currentText())
|
|
|
|
|
|
register_track_metadata_processor(process_track)
|
|
#register_album_metadata_processor(process_album)
|
|
register_options_page(LastfmOptionsPage)
|