From f7080a3dc8f8f34be7ca1286aa4b3a10f3b07d944e72ccf4958911d9eebe0832 Mon Sep 17 00:00:00 2001 From: OBS User autobuild Date: Tue, 21 Sep 2010 10:53:13 +0000 Subject: [PATCH] Accepting request 46222 from multimedia:apps 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 --- .gitattributes | 23 +++++ .gitignore | 1 + SearchAMG.py | 44 ++++++++++ SearchAmazon3.py | 86 ++++++++++++++++++ SearchCastAlbums3.py | 24 +++++ SearchDiscogs3.py | 26 ++++++ SearchFilmMusziek3.py | 24 +++++ SearchGMR.py | 23 +++++ SearchGoogle3.py | 39 +++++++++ SearchLortelArchives3.py | 25 ++++++ SearchSoundtrackCollector3.py | 24 +++++ SearchSoundtrackINFO3.py | 23 +++++ __init__.py | 157 +++++++++++++++++++++++++++++++++ addrelease.py | 52 +++++++++++ bonusdisc.py | 30 +++++++ coverart.py | 147 +++++++++++++++++++++++++++++++ discnumber.py | 28 ++++++ featartist.py | 15 ++++ picard-0.12.1+bzr1043.tar.bz2 | 3 + picard.changes | 31 +++++++ picard.spec | 159 ++++++++++++++++++++++++++++++++++ ui_options_lastfm.py | 125 ++++++++++++++++++++++++++ 22 files changed, 1109 insertions(+) create mode 100644 .gitattributes create mode 100644 .gitignore create mode 100644 SearchAMG.py create mode 100644 SearchAmazon3.py create mode 100644 SearchCastAlbums3.py create mode 100644 SearchDiscogs3.py create mode 100644 SearchFilmMusziek3.py create mode 100644 SearchGMR.py create mode 100644 SearchGoogle3.py create mode 100644 SearchLortelArchives3.py create mode 100644 SearchSoundtrackCollector3.py create mode 100644 SearchSoundtrackINFO3.py create mode 100644 __init__.py create mode 100644 addrelease.py create mode 100644 bonusdisc.py create mode 100644 coverart.py create mode 100644 discnumber.py create mode 100644 featartist.py create mode 100644 picard-0.12.1+bzr1043.tar.bz2 create mode 100644 picard.changes create mode 100644 picard.spec create mode 100644 ui_options_lastfm.py diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..9b03811 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,23 @@ +## Default LFS +*.7z filter=lfs diff=lfs merge=lfs -text +*.bsp filter=lfs diff=lfs merge=lfs -text +*.bz2 filter=lfs diff=lfs merge=lfs -text +*.gem filter=lfs diff=lfs merge=lfs -text +*.gz filter=lfs diff=lfs merge=lfs -text +*.jar filter=lfs diff=lfs merge=lfs -text +*.lz filter=lfs diff=lfs merge=lfs -text +*.lzma filter=lfs diff=lfs merge=lfs -text +*.obscpio filter=lfs diff=lfs merge=lfs -text +*.oxt filter=lfs diff=lfs merge=lfs -text +*.pdf filter=lfs diff=lfs merge=lfs -text +*.png filter=lfs diff=lfs merge=lfs -text +*.rpm filter=lfs diff=lfs merge=lfs -text +*.tbz filter=lfs diff=lfs merge=lfs -text +*.tbz2 filter=lfs diff=lfs merge=lfs -text +*.tgz filter=lfs diff=lfs merge=lfs -text +*.ttf filter=lfs diff=lfs merge=lfs -text +*.txz filter=lfs diff=lfs merge=lfs -text +*.whl filter=lfs diff=lfs merge=lfs -text +*.xz filter=lfs diff=lfs merge=lfs -text +*.zip filter=lfs diff=lfs merge=lfs -text +*.zst filter=lfs diff=lfs merge=lfs -text diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..57affb6 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +.osc diff --git a/SearchAMG.py b/SearchAMG.py new file mode 100644 index 0000000..0519e08 --- /dev/null +++ b/SearchAMG.py @@ -0,0 +1,44 @@ +# -*- coding: utf-8 -*- + +PLUGIN_NAME = u"Search AMG" +PLUGIN_AUTHOR = u"Brian Schweitzer" +PLUGIN_DESCRIPTION = "Search AMG" +PLUGIN_VERSION = "0.1" +PLUGIN_API_VERSIONS = ["0.9.0", "0.10"] + +from PyQt4 import QtCore +from picard.cluster import Cluster +from picard.util import webbrowser2 +from picard.ui.itemviews import BaseAction, register_cluster_action +from picard.ui.itemviews import BaseAction, register_album_action +from picard.ui.itemviews import BaseAction, register_file_action +from picard.metadata import register_track_metadata_processor + +class SearchAMGR(BaseAction): + NAME = "Search AMG for Release" + def callback(self, objs): + cluster = objs[0] + url = "http://wc10.allmusic.com/cg/amg.dll?P=amg&opt1=2&sql=" + url += QtCore.QUrl.toPercentEncoding(cluster.metadata["album"]) + webbrowser2.open(url) +register_cluster_action(SearchAMGR()) +register_album_action(SearchAMGR()) + +class SearchAMGA(BaseAction): + NAME = "Search AMG for Artist" + def callback(self, objs): + cluster = objs[0] + url = "http://wc09.allmusic.com/cg/amg.dll?P=amg&opt1=1&sql=" + url += QtCore.QUrl.toPercentEncoding(cluster.metadata["artist"]) + webbrowser2.open(url) +register_cluster_action(SearchAMGA()) +register_album_action(SearchAMGA()) + +class SearchAMGT(BaseAction): + NAME = "Search AMG for Track" + def callback(self, objs): + file = objs[0] + url = "http://wc10.allmusic.com/cg/amg.dll?P=amg&opt1=3&sql=" + url += QtCore.QUrl.toPercentEncoding(file.metadata["title"]) + webbrowser2.open(url) +register_file_action(SearchAMGT()) diff --git a/SearchAmazon3.py b/SearchAmazon3.py new file mode 100644 index 0000000..f311a99 --- /dev/null +++ b/SearchAmazon3.py @@ -0,0 +1,86 @@ +# -*- coding: utf-8 -*- + +PLUGIN_NAME = u"Search Amazon for Release (codebase 4.1)" +PLUGIN_AUTHOR = u"Brian Schweitzer" +PLUGIN_DESCRIPTION = "Search Amazon" +PLUGIN_VERSION = "0.1" +PLUGIN_API_VERSIONS = ["0.9.0", "0.10"] + +from PyQt4 import QtCore +from picard.cluster import Cluster +from picard.util import webbrowser2 +from picard.ui.itemviews import BaseAction, register_album_action +from picard.ui.itemviews import BaseAction, register_cluster_action + +class SearchAmazonCA(BaseAction): + NAME = "Search Amazon.ca" + def callback(self, objs): + cluster = objs[0] + url = "http://www.amazon.ca/s/?url=search-alias%3Dpopular&field-keywords=" + url += QtCore.QUrl.toPercentEncoding(cluster.metadata["artist"]) + url += " " + url += QtCore.QUrl.toPercentEncoding(cluster.metadata["album"]) + webbrowser2.open(url) +register_cluster_action(SearchAmazonCA()) +register_album_action(SearchAmazonCA()) + +class SearchAmazonCOM(BaseAction): + NAME = "Search Amazon.com" + def callback(self, objs): + cluster = objs[0] + url = "http://www.amazon.com/s/?url=search-alias%3Dpopular&field-keywords=" + url += QtCore.QUrl.toPercentEncoding(cluster.metadata["artist"]) + url += " " + url += QtCore.QUrl.toPercentEncoding(cluster.metadata["album"]) + webbrowser2.open(url) +register_cluster_action(SearchAmazonCOM()) +register_album_action(SearchAmazonCOM()) + +class SearchAmazonDE(BaseAction): + NAME = "Search Amazon.de" + def callback(self, objs): + cluster = objs[0] + url = "http://www.amazon.de/s/?url=search-alias%3Dpopular&field-keywords=" + url += QtCore.QUrl.toPercentEncoding(cluster.metadata["artist"]) + url += " " + url += QtCore.QUrl.toPercentEncoding(cluster.metadata["album"]) + webbrowser2.open(url) +register_cluster_action(SearchAmazonDE()) +register_album_action(SearchAmazonDE()) + +class SearchAmazonFR(BaseAction): + NAME = "Search Amazon.fr" + def callback(self, objs): + cluster = objs[0] + url = "http://www.amazon.fr/s/?url=search-alias%3Dpopular&field-keywords=" + url += QtCore.QUrl.toPercentEncoding(cluster.metadata["artist"]) + url += " " + url += QtCore.QUrl.toPercentEncoding(cluster.metadata["album"]) + webbrowser2.open(url) +register_cluster_action(SearchAmazonFR()) +register_album_action(SearchAmazonFR()) + +class SearchAmazonJP(BaseAction): + NAME = "Search Amazon.jp" + def callback(self, objs): + cluster = objs[0] + url = "http://www.amazon.jp/s/?url=search-alias%3Dpopular&field-keywords=" + url += QtCore.QUrl.toPercentEncoding(cluster.metadata["artist"]) + url += " " + url += QtCore.QUrl.toPercentEncoding(cluster.metadata["album"]) + webbrowser2.open(url) +register_cluster_action(SearchAmazonJP()) +register_album_action(SearchAmazonJP()) + +class SearchAmazonUK(BaseAction): + NAME = "Search Amazon.co.uk" + def callback(self, objs): + cluster = objs[0] + url = "http://www.amazon.co.uk/s/?url=search-alias%3Dpopular&field-keywords=" + url += QtCore.QUrl.toPercentEncoding(cluster.metadata["artist"]) + url += " " + url += QtCore.QUrl.toPercentEncoding(cluster.metadata["album"]) + webbrowser2.open(url) +register_cluster_action(SearchAmazonUK()) +register_album_action(SearchAmazonUK()) + diff --git a/SearchCastAlbums3.py b/SearchCastAlbums3.py new file mode 100644 index 0000000..b988319 --- /dev/null +++ b/SearchCastAlbums3.py @@ -0,0 +1,24 @@ +# -*- coding: utf-8 -*- + +PLUGIN_NAME = u"Search CastAlbums.org for Release (codebase 4.1)" +PLUGIN_AUTHOR = u"Brian Schweitzer" +PLUGIN_DESCRIPTION = "Search CastAlbums.org" +PLUGIN_VERSION = "0.1" +PLUGIN_API_VERSIONS = ["0.9.0", "0.10"] + +from PyQt4 import QtCore +from picard.cluster import Cluster +from picard.util import webbrowser2 +from picard.ui.itemviews import BaseAction, register_album_action +from picard.ui.itemviews import BaseAction, register_cluster_action + + +class SearchCastAlbums(BaseAction): + NAME = "Search with CastAlbums.org" + def callback(self, objs): + cluster = objs[0] + url = "http://www.castalbums.org/shows/search/" + url += QtCore.QUrl.toPercentEncoding(cluster.metadata["album"]) + webbrowser2.open(url) +register_cluster_action(SearchCastAlbums()) +register_album_action(SearchCastAlbums()) diff --git a/SearchDiscogs3.py b/SearchDiscogs3.py new file mode 100644 index 0000000..57f7115 --- /dev/null +++ b/SearchDiscogs3.py @@ -0,0 +1,26 @@ +# -*- coding: utf-8 -*- + +PLUGIN_NAME = u"Search Discogs for Release (codebase 4.1)" +PLUGIN_AUTHOR = u"Brian Schweitzer" +PLUGIN_DESCRIPTION = "Search Discogs" +PLUGIN_VERSION = "0.1" +PLUGIN_API_VERSIONS = ["0.9.0", "0.10"] + +from PyQt4 import QtCore +from picard.cluster import Cluster +from picard.util import webbrowser2 +from picard.ui.itemviews import BaseAction, register_cluster_action +from picard.ui.itemviews import BaseAction, register_album_action + +class SearchDiscogs(BaseAction): + NAME = "Search Discogs" + def callback(self, objs): + cluster = objs[0] + url = "http://www.discogs.com/search?type=all&q=" + url += QtCore.QUrl.toPercentEncoding(cluster.metadata["artist"]) + url += "+" + url += QtCore.QUrl.toPercentEncoding(cluster.metadata["album"]) + url += "&btn=Search" + webbrowser2.open(url) +register_cluster_action(SearchDiscogs()) +register_album_action(SearchDiscogs()) diff --git a/SearchFilmMusziek3.py b/SearchFilmMusziek3.py new file mode 100644 index 0000000..ae7552c --- /dev/null +++ b/SearchFilmMusziek3.py @@ -0,0 +1,24 @@ +# -*- coding: utf-8 -*- + +PLUGIN_NAME = u"Search FilmMuziek.be for Release (codebase 4.1)" +PLUGIN_AUTHOR = u"Brian Schweitzer" +PLUGIN_DESCRIPTION = "Search FilmMuziek.be" +PLUGIN_VERSION = "0.1" +PLUGIN_API_VERSIONS = ["0.9.0", "0.10"] + +from PyQt4 import QtCore +from picard.cluster import Cluster +from picard.util import webbrowser2 +from picard.ui.itemviews import BaseAction, register_cluster_action +from picard.ui.itemviews import BaseAction, register_album_action + + +class SearchFilmMusic(BaseAction): + NAME = "Search with FilmMuziek.be" + def callback(self, objs): + cluster = objs[0] + url = "http://www.filmmuziek.be/search.cgi?Match=0&Realm=All&Terms=" + url += QtCore.QUrl.toPercentEncoding(cluster.metadata["album"]) + webbrowser2.open(url) +register_cluster_action(SearchFilmMusic()) +register_album_action(SearchFilmMusic()) diff --git a/SearchGMR.py b/SearchGMR.py new file mode 100644 index 0000000..216d984 --- /dev/null +++ b/SearchGMR.py @@ -0,0 +1,23 @@ +# -*- coding: utf-8 -*- + +PLUGIN_NAME = u"Search Game Music Revolution (codebase 4.1)" +PLUGIN_AUTHOR = u"Brian Schweitzer" +PLUGIN_DESCRIPTION = "Search Game Music Revolution" +PLUGIN_VERSION = "0.1" +PLUGIN_API_VERSIONS = ["0.9.0", "0.10"] + +from PyQt4 import QtCore +from picard.cluster import Cluster +from picard.util import webbrowser2 +from picard.ui.itemviews import BaseAction, register_cluster_action +from picard.ui.itemviews import BaseAction, register_album_action + +class SearchGameMusicRevolution(BaseAction): + NAME = "Search with Game Music Revolution" + def callback(self, objs): + cluster = objs[0] + url = "http://www.gmronline.com/results.asp?display=0&go=Go+Find+It&searchType=Title&browseType=Title&results=25&search=" + url += QtCore.QUrl.toPercentEncoding(cluster.metadata["album"]) + webbrowser2.open(url) +register_cluster_action(SearchGameMusicRevolution()) +register_album_action(SearchGameMusicRevolution()) diff --git a/SearchGoogle3.py b/SearchGoogle3.py new file mode 100644 index 0000000..44cdb6c --- /dev/null +++ b/SearchGoogle3.py @@ -0,0 +1,39 @@ +# -*- coding: utf-8 -*- + +PLUGIN_NAME = u"Search with Google for Release (codebase 4.1)" +PLUGIN_AUTHOR = u"Brian Schweitzer" +PLUGIN_DESCRIPTION = "Search Google. Thanks to Lukas Lalinsky for bug-fix!" +PLUGIN_VERSION = "0.1.1" +PLUGIN_API_VERSIONS = ["0.9.0", "0.10"] + +from PyQt4 import QtCore +from picard.util import webbrowser2 +from picard.ui.itemviews import BaseAction, register_cluster_action +from picard.ui.itemviews import BaseAction, register_album_action +from picard.ui.itemviews import BaseAction, register_file_action +from picard.metadata import register_track_metadata_processor + +class SearchGoogle(BaseAction): + NAME = "Search with Google" + def callback(self, objs): + cluster = objs[0] + url = "http://www.google.com/search?hl=en&q=" + url += QtCore.QUrl.toPercentEncoding(cluster.metadata["artist"]) + url += " " + url += QtCore.QUrl.toPercentEncoding(cluster.metadata["album"]) + webbrowser2.open(url) +register_cluster_action(SearchGoogle()) +register_album_action(SearchGoogle()) + +class SearchGoogleTrack(BaseAction): + NAME = "Search with Google" + def callback(self, objs): + file = objs[0] + url = "http://www.google.com/search?hl=en&q=" + url += QtCore.QUrl.toPercentEncoding(file.metadata["artist"]) + url += " " + url += QtCore.QUrl.toPercentEncoding(file.metadata["album"]) + url += " " + url += QtCore.QUrl.toPercentEncoding(file.metadata["title"]) + webbrowser2.open(url) +register_file_action(SearchGoogleTrack()) diff --git a/SearchLortelArchives3.py b/SearchLortelArchives3.py new file mode 100644 index 0000000..b345578 --- /dev/null +++ b/SearchLortelArchives3.py @@ -0,0 +1,25 @@ +# -*- coding: utf-8 -*- + +PLUGIN_NAME = u"Search the Lortel Archives for Release (codebase 4.1)" +PLUGIN_AUTHOR = u"Brian Schweitzer" +PLUGIN_DESCRIPTION = "Search the Lortel Archives" +PLUGIN_VERSION = "0.1" +PLUGIN_API_VERSIONS = ["0.9.0", "0.10"] + +from PyQt4 import QtCore +from picard.cluster import Cluster +from picard.util import webbrowser2 +from picard.ui.itemviews import BaseAction, register_cluster_action +from picard.ui.itemviews import BaseAction, register_album_action + + +class SearchLortelArchives(BaseAction): + NAME = "Search the Lortel Archives" + def callback(self, objs): + cluster = objs[0] + url = "http://www.lortel.org/LLA_archive/index.cfm?keyword=" + url += QtCore.QUrl.toPercentEncoding(cluster.metadata["album"]) + url += "&COMMITT=YES&search_by=ALL&Go.x=0&Go.y=0" + webbrowser2.open(url) +register_cluster_action(SearchLortelArchives()) +register_album_action(SearchLortelArchives()) diff --git a/SearchSoundtrackCollector3.py b/SearchSoundtrackCollector3.py new file mode 100644 index 0000000..3ff8ca0 --- /dev/null +++ b/SearchSoundtrackCollector3.py @@ -0,0 +1,24 @@ +# -*- coding: utf-8 -*- + +PLUGIN_NAME = u"Search SoundtrackCollector for Release (codebase 4.1)" +PLUGIN_AUTHOR = u"Brian Schweitzer" +PLUGIN_DESCRIPTION = "Search SoundtrackCollector" +PLUGIN_VERSION = "0.1" +PLUGIN_API_VERSIONS = ["0.9.0", "0.10"] + +from PyQt4 import QtCore +from picard.cluster import Cluster +from picard.util import webbrowser2 +from picard.ui.itemviews import BaseAction, register_cluster_action +from picard.ui.itemviews import BaseAction, register_album_action + + +class SearchSoundtrackCollector(BaseAction): + NAME = "Search with SoundtrackCollector" + def callback(self, objs): + cluster = objs[0] + url = "http://www.soundtrackcollector.com/catalog/search.php?searchon=all&searchtext=" + url += QtCore.QUrl.toPercentEncoding(cluster.metadata["album"]) + webbrowser2.open(url) +register_cluster_action(SearchSoundtrackCollector()) +register_album_action(SearchSoundtrackCollector()) diff --git a/SearchSoundtrackINFO3.py b/SearchSoundtrackINFO3.py new file mode 100644 index 0000000..028deb8 --- /dev/null +++ b/SearchSoundtrackINFO3.py @@ -0,0 +1,23 @@ +# -*- coding: utf-8 -*- + +PLUGIN_NAME = u"Search SoundtrackINFO (codebase 4.1)" +PLUGIN_AUTHOR = u"Brian Schweitzer" +PLUGIN_DESCRIPTION = "Search SoundtrackINFO" +PLUGIN_VERSION = "0.1" +PLUGIN_API_VERSIONS = ["0.9.0", "0.10"] + +from PyQt4 import QtCore +from picard.cluster import Cluster +from picard.util import webbrowser2 +from picard.ui.itemviews import BaseAction, register_cluster_action +from picard.ui.itemviews import BaseAction, register_album_action + +class SearchSoundtrackINFO(BaseAction): + NAME = "Search with SoundtrackINFO" + def callback(self, objs): + cluster = objs[0] + url = "http://www.soundtrackinfo.com/search.asp?q=" + url += QtCore.QUrl.toPercentEncoding(cluster.metadata["album"]) + webbrowser2.open(url) +register_cluster_action(SearchSoundtrackINFO()) +register_album_action(SearchSoundtrackINFO()) diff --git a/__init__.py b/__init__.py new file mode 100644 index 0000000..4628763 --- /dev/null +++ b/__init__.py @@ -0,0 +1,157 @@ +# -*- 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) diff --git a/addrelease.py b/addrelease.py new file mode 100644 index 0000000..38b6b11 --- /dev/null +++ b/addrelease.py @@ -0,0 +1,52 @@ +# -*- coding: utf-8 -*- + +PLUGIN_NAME = u"Add Cluster As Release" +PLUGIN_AUTHOR = u"Lukáš Lalinský" +PLUGIN_DESCRIPTION = "" +PLUGIN_VERSION = "0.1" +PLUGIN_API_VERSIONS = ["0.9.0", "0.10"] + + +from PyQt4 import QtCore +from picard.cluster import Cluster +from picard.util import webbrowser2, format_time +from picard.ui.itemviews import BaseAction, register_cluster_action + + +class AddClusterAsRelease(BaseAction): + NAME = "Add Cluster As Release..." + + def callback(self, objs): + if len(objs) != 1 or not isinstance(objs[0], Cluster): + return + cluster = objs[0] + + artists = set() + for i, file in enumerate(cluster.files): + artists.add(file.metadata["artist"]) + + url = "http://musicbrainz.org/cdi/enter.html" + if len(artists) > 1: + url += "?hasmultipletrackartists=1&artistid=1" + else: + url += "?hasmultipletrackartists=0&artistid=2" + url += "&artistedit=1&artistname=%s" % QtCore.QUrl.toPercentEncoding(cluster.metadata["artist"]) + url += "&releasename=%s" % QtCore.QUrl.toPercentEncoding(cluster.metadata["album"]) + tracks = 0 + for i, file in enumerate(cluster.files): + try: + i = int(file.metadata["tracknumber"]) - 1 + except: + pass + tracks = max(tracks, i + 1) + url += "&track%d=%s" % (i, QtCore.QUrl.toPercentEncoding(file.metadata["title"])) + url += "&tracklength%d=%s" % (i, QtCore.QUrl.toPercentEncoding(format_time(file.metadata.length))) + if len(artists) > 1: + url += "&tr%d_artistedit=1" % i + url += "&tr%d_artistname=%s" % (i, QtCore.QUrl.toPercentEncoding(file.metadata["artist"])) + url += "&tracks=%d" % tracks + webbrowser2.open(url) + + +register_cluster_action(AddClusterAsRelease()) + diff --git a/bonusdisc.py b/bonusdisc.py new file mode 100644 index 0000000..e05da13 --- /dev/null +++ b/bonusdisc.py @@ -0,0 +1,30 @@ +# -*- coding: utf-8 -*- + +PLUGIN_NAME = 'Bonus Disc' +PLUGIN_AUTHOR = 'Jan van Thiel' +PLUGIN_DESCRIPTION = '''Based on a script by Lukas Lalinsky.
+
+Moves bonus disc and bonus disc titles from album titles to separate tags. For example:
+"Sleeping With Ghosts (bonus disc: Covers)" +''' +PLUGIN_VERSION = "0.1" +PLUGIN_API_VERSIONS = ["0.9.0", "0.10"] + +from picard.metadata import register_album_metadata_processor +import re + +_bonusdisc_re = re.compile(r"\s+\(bonus disc(?::\s+([^)]+))?\)") + +def remove_bonusdiscs(tagger, metadata, release): + matches = _bonusdisc_re.search(metadata["album"]) + if matches: + metadata["bonusdisc"] = "bonus" + if matches.group(1): + metadata["bonusdisctitle"] = matches.group(1) + metadata["album"] = _bonusdisc_re.sub('', metadata["album"]) + +register_album_metadata_processor(remove_bonusdiscs) diff --git a/coverart.py b/coverart.py new file mode 100644 index 0000000..f1d8191 --- /dev/null +++ b/coverart.py @@ -0,0 +1,147 @@ +# -*- coding: utf-8 -*- + +""" +A small plugin to download cover art for any releseas that have a +CoverArtLink relation. + + +Changelog: + + [2008-04-15] Refactored the code to be similar to the server code (hartzell, phw) + + [2008-03-10] Added CDBaby support (phw) + + [2007-09-06] Added Jamendo support (phw) + + [2007-04-24] Moved parsing code into here + Swapped to QUrl + Moved to a list of urls + + [2007-04-23] Moved it to use the bzr picard + Took the hack out + Added Amazon ASIN support + + [2007-04-23] Initial plugin, uses a hack that relies on Python being + installed and musicbrainz2 for the query. + +""" + +PLUGIN_NAME = 'Cover Art Downloader' +PLUGIN_AUTHOR = 'Oliver Charles, Philipp Wolfer' +PLUGIN_DESCRIPTION = '''Downloads cover artwork for releases that have a +CoverArtLink.''' +PLUGIN_VERSION = "0.4" +PLUGIN_API_VERSIONS = ["0.9.0", "0.10"] + +from picard.metadata import register_album_metadata_processor +from picard.util import partial +from PyQt4.QtCore import QUrl +import re + +# +# data transliterated from the perl stuff used to find cover art for the +# musicbrainz server. +# See mb_server/cgi-bin/MusicBrainz/Server/CoverArt.pm +# hartzell --- Tue Apr 15 15:25:58 PDT 2008 +coverArtSites = [ + # CD-Baby + # tested with http://musicbrainz.org/release/1243cc17-b9f7-48bd-a536-b10d2013c938.html + { + 'regexp': 'http://cdbaby.com/cd/(\w)(\w)(\w*)', + 'imguri': 'http://cdbaby.name/$1/$2/$1$2$3.jpg', + }, + # Jamendo + # tested with http://musicbrainz.org/release/2fe63977-bda9-45da-8184-25a4e7af8da7.html + { + 'regexp': 'http:\/\/(?:www.)?jamendo.com\/(?:[a-z]+\/)?album\/([0-9]+)', + 'imguri': 'http://www.jamendo.com/get/album/id/album/artworkurl/redirect/$1/?artwork_size=0', + }, + ] + +_AMAZON_IMAGE_HOST = 'images.amazon.com' +_AMAZON_IMAGE_PATH = '/images/P/%s.01.LZZZZZZZ.jpg' +_AMAZON_IMAGE_PATH_SMALL = '/images/P/%s.01.MZZZZZZZ.jpg' +_AMAZON_IMAGE_PATH2 = '/images/P/%s.02.LZZZZZZZ.jpg' +_AMAZON_IMAGE_PATH2_SMALL = '/images/P/%s.02.MZZZZZZZ.jpg' + +def _coverart_downloaded(album, metadata, release, try_list, data, http, error): + try: + if error or len(data) < 1000: + if error: + album.log.error(str(http.errorString())) + coverart(album, metadata, release, try_list) + else: + metadata.add_image("image/jpeg", data) + for track in album._new_tracks: + track.metadata.add_image("image/jpeg", data) + finally: + album._requests -= 1 + album._finalize_loading(None) + + +def coverart(album, metadata, release, try_list=None): + """ Gets the CDBaby URL from the metadata, and the attempts to + download the album art. """ + + # try_list will be None for the first call + if try_list is None: + try_list = [] + + try: + for relation_list in release.relation_list: + if relation_list.target_type == 'Url': + for relation in relation_list.relation: + # Search for cover art on special sites + for site in coverArtSites: + # + # this loop transliterated from the perl stuff used to find cover art for the + # musicbrainz server. + # See mb_server/cgi-bin/MusicBrainz/Server/CoverArt.pm + # hartzell --- Tue Apr 15 15:25:58 PDT 2008 + match = re.match(site['regexp'], relation.target) + if match != None: + imgURI = site['imguri'] + for i in range(1, len(match.groups())+1 ): + if match.group(i) != None: + imgURI = imgURI.replace('$' + str(i), match.group(i)) + _try_list_append_image_url(try_list, QUrl(imgURI)) + + # Use the URL of a cover art link directly + if relation.type == 'CoverArtLink': + _try_list_append_image_url(try_list, QUrl(relation.target)) + except AttributeError: + pass + + if metadata['asin']: + try_list.append({'host': _AMAZON_IMAGE_HOST, 'port': 80, + 'path': _AMAZON_IMAGE_PATH % metadata['asin'] + }) + try_list.append({'host': _AMAZON_IMAGE_HOST, 'port': 80, + 'path': _AMAZON_IMAGE_PATH_SMALL % metadata['asin'] + }) + try_list.append({'host': _AMAZON_IMAGE_HOST, 'port': 80, + 'path': _AMAZON_IMAGE_PATH2 % metadata['asin'] + }) + try_list.append({'host': _AMAZON_IMAGE_HOST, 'port': 80, + 'path': _AMAZON_IMAGE_PATH2_SMALL % metadata['asin'] + }) + + if len(try_list) > 0: + # We still have some items to try! + album._requests += 1 + album.tagger.xmlws.download( + try_list[0]['host'], try_list[0]['port'], try_list[0]['path'], + partial(_coverart_downloaded, album, metadata, release, try_list[1:]), + position=1) + +def _try_list_append_image_url(try_list, parsedUrl): + path = parsedUrl.path() + if parsedUrl.hasQuery(): + path += '?'+'&'.join(["%s=%s" % (k,v) for k,v in parsedUrl.queryItems()]) + try_list.append({ + 'host': str(parsedUrl.host()), + 'port': parsedUrl.port(80), + 'path': str(path) + }) + +register_album_metadata_processor(coverart) diff --git a/discnumber.py b/discnumber.py new file mode 100644 index 0000000..d465187 --- /dev/null +++ b/discnumber.py @@ -0,0 +1,28 @@ +# -*- coding: utf-8 -*- + +PLUGIN_NAME = 'Disc Numbers' +PLUGIN_AUTHOR = 'Lukas Lalinsky' +PLUGIN_DESCRIPTION = '''Moves disc numbers and subtitles from album titles to separate tags. For example:
+"Aerial (disc 1: A Sea of Honey)" +''' +PLUGIN_VERSION = "0.1" +PLUGIN_API_VERSIONS = ["0.9.0", "0.10"] + +from picard.metadata import register_album_metadata_processor +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: + metadata["discnumber"] = matches.group(1) + if matches.group(2): + metadata["discsubtitle"] = matches.group(2) + metadata["album"] = _discnumber_re.sub('', metadata["album"]) + +register_album_metadata_processor(remove_discnumbers) diff --git a/featartist.py b/featartist.py new file mode 100644 index 0000000..10b151f --- /dev/null +++ b/featartist.py @@ -0,0 +1,15 @@ +# -*- coding: utf-8 -*- + +PLUGIN_NAME = 'Feat. Artists' +PLUGIN_AUTHOR = 'Lukas Lalinsky' +PLUGIN_DESCRIPTION = 'Removes feat. artists from track titles.' +PLUGIN_VERSION = "0.1" +PLUGIN_API_VERSIONS = ["0.9.0", "0.10"] + +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"]) + +register_track_metadata_processor(remove_featartists) diff --git a/picard-0.12.1+bzr1043.tar.bz2 b/picard-0.12.1+bzr1043.tar.bz2 new file mode 100644 index 0000000..1f38d2b --- /dev/null +++ b/picard-0.12.1+bzr1043.tar.bz2 @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:7b1c2f78ecdc444e8882c2ec6dc6fff4305d90a1fb89ab01076662a8bf85f6e4 +size 1011008 diff --git a/picard.changes b/picard.changes new file mode 100644 index 0000000..df6aa22 --- /dev/null +++ b/picard.changes @@ -0,0 +1,31 @@ +------------------------------------------------------------------- +Wed Aug 25 15:32:27 UTC 2010 - sasch.pe@gmx.de + +- Updated to upstream version 0.12.1+bzr1043 +- Icon license now complies with openSUSE packaging guidelines + +------------------------------------------------------------------- +Mon Apr 19 19:24:13 UTC 2010 - sasch.pe@gmx.de + +- Added several plugins + +------------------------------------------------------------------- +Tue Jan 5 13:18:15 UTC 2010 - masterpatricko@gmail.com + +- Updated to upstream v0.12.1 + +------------------------------------------------------------------- +Fri Jan 23 20:08:16 GMT 2009 - masterpatricko@gmail.com +- Updated to upstream v0.11 + +------------------------------------------------------------------- +Mon Jun 30 00:00:00 GMT 2008 - jfunk@funktronics.ca +- Adapt to non-standard python build + +------------------------------------------------------------------- +Fri Feb 01 00:00:00 GMT 2008 - jfunk@funktronics.ca +- Update to final v0.9 + +------------------------------------------------------------------- +Mon Sep 03 00:00:00 GMT 2007 - jfunk@funktronics.ca +- Initial release diff --git a/picard.spec b/picard.spec new file mode 100644 index 0000000..d993215 --- /dev/null +++ b/picard.spec @@ -0,0 +1,159 @@ +# +# spec file for package picard (Version 0.12.1+bzr1043) +# +# Copyright (c) 2010 SUSE LINUX Products GmbH, Nuernberg, Germany. +# +# All modifications and additions to the file contributed by third parties +# remain the property of their copyright owners, unless otherwise agreed +# upon. The license for this file, and modifications and additions to the +# file, is the same license as for the pristine package itself (unless the +# license for the pristine package is not an Open Source License, in which +# case the license is the MIT License). An "Open Source License" is a +# license that conforms to the Open Source Definition (Version 1.9) +# published by the Open Source Initiative. + +# Please submit bugfixes or comments via http://bugs.opensuse.org/ +# + +# norootforbuild + + +Name: picard +Version: 0.12.1+bzr1043 +Release: 1 +Summary: The Next Generation MusicBrainz Tagger +License: GPLv2+ +Group: Productivity/Multimedia/Sound/Utilities +Url: http://musicbrainz.org/doc/PicardTagger +Source0: %{name}-%{version}.tar.bz2 +Source1: addrelease.py +Source2: bonusdisc.py +Source3: coverart.py +Source4: discnumber.py +Source5: featartist.py +Source6: lastfm/__init__.py +Source7: lastfm/ui_options_lastfm.py +Source8: SearchAmazon3.py +Source9: SearchAMG.py +Source10: SearchCastAlbums3.py +Source11: SearchDiscogs3.py +Source12: SearchFilmMusziek3.py +Source13: SearchGMR.py +Source14: SearchGoogle3.py +Source15: SearchLortelArchives3.py +Source16: SearchSoundtrackCollector3.py +Source17: SearchSoundtrackINFO3.py +BuildRoot: %{_tmppath}/%{name}-%{version}-build + +BuildRequires: desktop-file-utils gcc-c++ libofa-devel python-devel +%if 0%{!?sles_version} +BuildRequires: libdiscid-devel +%endif +%if 0%{?suse_version} +%py_requires +BuildRequires: python-mutagen python-qt4 update-desktop-files +Requires: python-mutagen +%endif +%if 0%{?fedora} +BuildRequires: PyQt4 python-mutagen +Requires: python-mutagen +%endif +%if 0%{?mandriva_version} +BuildRequires: python-qt4 +%endif + +%{!?py_sitedir: %define py_sitedir %(%{__python} -c "from distutils.sysconfig import get_python_lib; print get_python_lib(1)")} +%{!?py_ver_int: %define py_ver_int %(%{__python} -c "import sys; v=sys.version_info[:2]; print '%%d%%d'%%v" 2>/dev/null)} +%if 0%{?py_ver_int} == 24 +Requires: python-ctypes +%endif + +%description +MusicBrainz Picard is a cross-platform MusicBrainz tag editor written in +Python. Picard Tagger is intended to be the next generation of tagger for +MusicBrainz, with a focus on album oriented tagging as opposed to track based +tagging and cross platform compatibility. + + +Authors: +------- + Lukáš Lalinský + Robert Kaye + + +%lang_package +%prep +%setup -q + +%build +export CFLAGS="$RPM_OPT_FLAGS" +%{__python} setup.py config +%{__python} setup.py build + +%install +%{__python} setup.py install --skip-build --prefix=%{_prefix} --root=$RPM_BUILD_ROOT + +# install plugins +PLUGINDIR=$RPM_BUILD_ROOT%{py_sitedir}/picard/plugins/ +install -d ${PLUGINDIR}/lastfm +install -m 0644 %{SOURCE1} ${PLUGINDIR} +install -m 0644 %{SOURCE2} ${PLUGINDIR} +install -m 0644 %{SOURCE3} ${PLUGINDIR} +install -m 0644 %{SOURCE4} ${PLUGINDIR} +install -m 0644 %{SOURCE5} ${PLUGINDIR} +install -m 0644 %{SOURCE6} ${PLUGINDIR}/lastfm +install -m 0644 %{SOURCE7} ${PLUGINDIR}/lastfm +install -m 0644 %{SOURCE8} ${PLUGINDIR} +install -m 0644 %{SOURCE9} ${PLUGINDIR} +install -m 0644 %{SOURCE10} ${PLUGINDIR} +install -m 0644 %{SOURCE11} ${PLUGINDIR} +install -m 0644 %{SOURCE12} ${PLUGINDIR} +install -m 0644 %{SOURCE13} ${PLUGINDIR} +install -m 0644 %{SOURCE14} ${PLUGINDIR} +install -m 0644 %{SOURCE15} ${PLUGINDIR} +install -m 0644 %{SOURCE16} ${PLUGINDIR} +install -m 0644 %{SOURCE17} ${PLUGINDIR} + +%if 0%{?fedora} +desktop-file-install --delete-original --remove-category="Application" \ + --dir=$RPM_BUILD_ROOT%{_datadir}/applications $RPM_BUILD_ROOT%{_datadir}/applications/%{name}.desktop +%endif +%if 0%{?suse_version} +%suse_update_desktop_file -G "Music Tagger" -N "picard" picard +%endif + +%find_lang %{name} + +%clean +rm -rf $RPM_BUILD_ROOT + +%if 0%{?mandriva_version} > 2006 + +%post +%update_menus + +%postun +%clean_menus +%endif + +%if 0%{?suse_version} > 1020 + +%files lang -f %{name}.lang +%defattr(-,root,root) +%lang(sco) %dir %{_datadir}/locale/sco +%lang(sco) %dir %{_datadir}/locale/sco/LC_MESSAGES + +%files +%defattr(-,root,root) +%else + +%files -f %{name}.lang +%defattr(-,root,root) +%endif +%doc AUTHORS.txt COPYING.txt NEWS.txt +%{_bindir}/picard +%{_datadir}/applications/%{name}.desktop +%{py_sitedir}/picard* +%{_datadir}/icons/hicolor* + +%changelog diff --git a/ui_options_lastfm.py b/ui_options_lastfm.py new file mode 100644 index 0000000..073d85d --- /dev/null +++ b/ui_options_lastfm.py @@ -0,0 +1,125 @@ +# -*- coding: utf-8 -*- + +# Form implementation generated from reading ui file 'options_lastfm.ui' +# +# Created: Sun May 13 11:18:12 2007 +# by: PyQt4 UI code generator 4.1 +# +# WARNING! All changes made in this file will be lost! + +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())) + + self.vboxlayout = QtGui.QVBoxLayout(LastfmOptionsPage) + self.vboxlayout.setMargin(9) + self.vboxlayout.setSpacing(6) + self.vboxlayout.setObjectName("vboxlayout") + + self.rename_files = QtGui.QGroupBox(LastfmOptionsPage) + self.rename_files.setObjectName("rename_files") + + self.vboxlayout1 = QtGui.QVBoxLayout(self.rename_files) + self.vboxlayout1.setMargin(9) + self.vboxlayout1.setSpacing(2) + self.vboxlayout1.setObjectName("vboxlayout1") + + self.use_track_tags = QtGui.QCheckBox(self.rename_files) + self.use_track_tags.setObjectName("use_track_tags") + self.vboxlayout1.addWidget(self.use_track_tags) + + self.use_artist_tags = QtGui.QCheckBox(self.rename_files) + self.use_artist_tags.setObjectName("use_artist_tags") + self.vboxlayout1.addWidget(self.use_artist_tags) + self.vboxlayout.addWidget(self.rename_files) + + self.rename_files_2 = QtGui.QGroupBox(LastfmOptionsPage) + self.rename_files_2.setObjectName("rename_files_2") + + self.vboxlayout2 = QtGui.QVBoxLayout(self.rename_files_2) + self.vboxlayout2.setMargin(9) + self.vboxlayout2.setSpacing(2) + self.vboxlayout2.setObjectName("vboxlayout2") + + self.ignore_tags_2 = QtGui.QLabel(self.rename_files_2) + self.ignore_tags_2.setObjectName("ignore_tags_2") + self.vboxlayout2.addWidget(self.ignore_tags_2) + + self.ignore_tags = QtGui.QLineEdit(self.rename_files_2) + self.ignore_tags.setObjectName("ignore_tags") + self.vboxlayout2.addWidget(self.ignore_tags) + + self.hboxlayout = QtGui.QHBoxLayout() + self.hboxlayout.setMargin(0) + self.hboxlayout.setSpacing(6) + self.hboxlayout.setObjectName("hboxlayout") + + self.ignore_tags_4 = QtGui.QLabel(self.rename_files_2) + + sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Policy(5),QtGui.QSizePolicy.Policy(5)) + sizePolicy.setHorizontalStretch(4) + sizePolicy.setVerticalStretch(0) + sizePolicy.setHeightForWidth(self.ignore_tags_4.sizePolicy().hasHeightForWidth()) + self.ignore_tags_4.setSizePolicy(sizePolicy) + self.ignore_tags_4.setObjectName("ignore_tags_4") + self.hboxlayout.addWidget(self.ignore_tags_4) + + self.join_tags = QtGui.QComboBox(self.rename_files_2) + + sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Policy(5),QtGui.QSizePolicy.Policy(0)) + sizePolicy.setHorizontalStretch(1) + sizePolicy.setVerticalStretch(0) + sizePolicy.setHeightForWidth(self.join_tags.sizePolicy().hasHeightForWidth()) + self.join_tags.setSizePolicy(sizePolicy) + self.join_tags.setEditable(True) + self.join_tags.setObjectName("join_tags") + self.join_tags.addItem("") + self.hboxlayout.addWidget(self.join_tags) + self.vboxlayout2.addLayout(self.hboxlayout) + + self.hboxlayout1 = QtGui.QHBoxLayout() + self.hboxlayout1.setMargin(0) + self.hboxlayout1.setSpacing(6) + self.hboxlayout1.setObjectName("hboxlayout1") + + self.label_4 = QtGui.QLabel(self.rename_files_2) + + sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Policy(7),QtGui.QSizePolicy.Policy(5)) + sizePolicy.setHorizontalStretch(0) + sizePolicy.setVerticalStretch(0) + sizePolicy.setHeightForWidth(self.label_4.sizePolicy().hasHeightForWidth()) + self.label_4.setSizePolicy(sizePolicy) + self.label_4.setObjectName("label_4") + self.hboxlayout1.addWidget(self.label_4) + + self.min_tag_usage = QtGui.QSpinBox(self.rename_files_2) + self.min_tag_usage.setMaximum(100) + self.min_tag_usage.setObjectName("min_tag_usage") + self.hboxlayout1.addWidget(self.min_tag_usage) + self.vboxlayout2.addLayout(self.hboxlayout1) + self.vboxlayout.addWidget(self.rename_files_2) + + spacerItem = QtGui.QSpacerItem(263,21,QtGui.QSizePolicy.Minimum,QtGui.QSizePolicy.Expanding) + self.vboxlayout.addItem(spacerItem) + self.label_4.setBuddy(self.min_tag_usage) + + self.retranslateUi(LastfmOptionsPage) + QtCore.QMetaObject.connectSlotsByName(LastfmOptionsPage) + LastfmOptionsPage.setTabOrder(self.use_track_tags,self.ignore_tags) + + def retranslateUi(self, LastfmOptionsPage): + self.rename_files.setTitle(_("Last.fm")) + self.use_track_tags.setText(_("Use track tags")) + self.use_artist_tags.setText(_("Use artist tags")) + self.rename_files_2.setTitle(_("Tags")) + self.ignore_tags_2.setText(_("Ignore tags:")) + self.ignore_tags_4.setText(_("Join multiple tags with:")) + self.join_tags.addItem(_(" / ")) + self.join_tags.addItem(_(", ")) + self.label_4.setText(_("Minimal tag usage:")) + self.min_tag_usage.setSuffix(_(" %")) +