def __init__(self): super(save_and_rewrite_header, self).__init__() register_file_action(self) register_track_action(self) register_album_action(self) register_cluster_action(self) register_clusterlist_action(self)
def __init__(self): super(NiCeFileAction, self).__init__() register_file_action(self) register_track_action(self) register_album_action(self) register_cluster_action(self) register_clusterlist_action(self)
# -*- coding: utf-8 -*- PLUGIN_NAME = u"Search Game Music Revolution" PLUGIN_AUTHOR = u"Brian Schweitzer" PLUGIN_DESCRIPTION = "Search Game Music Revolution" PLUGIN_VERSION = "0.2" PLUGIN_API_VERSIONS = ["0.9.0", "0.10","0.11","0.12","0.13","0.14","0.15","0.16"] 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())
# -*- 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())
# M3U EXTINF row track_length_seconds = int(round(track.metadata.length / 1000.0)) # EXTINF format assumed to be fixed as follows: entry.add(u"#EXTINF:{duration:d},{artist} - {title}".format( duration=track_length_seconds, artist=track.metadata["artist"], title=track.metadata["title"] ) ) # M3U URL row - assumes only one file per track audio_filename = track.linked_files[0].filename if _debug_level > 1: for i, file in enumerate(track.linked_files): log.debug("{}: linked_file {}: {}".format( PLUGIN_NAME, i, str(file))) # If playlist is in same directory as audio files, then use # local (relative) pathname, otherwise use absolute pathname if _debug_level > 1: log.debug("{}: audio_filename: {}, selected dir: {}".format( PLUGIN_NAME, audio_filename, os.path.dirname(filename))) if os.path.dirname(filename) == os.path.dirname(audio_filename): audio_filename = os.path.basename(audio_filename) entry.add(unicode(audio_filename)) playlist.write() register_album_action(GeneratePlaylist())
# -*- coding: utf-8 -*- PLUGIN_NAME = u"Search SoundtrackCollector" PLUGIN_AUTHOR = u"Brian Schweitzer" PLUGIN_DESCRIPTION = "Search SoundtrackCollector" PLUGIN_VERSION = "0.2" PLUGIN_API_VERSIONS = ["0.9.0", "0.10","0.11","0.12","0.13","0.14","0.15","0.16"] 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())
def update_list(self, current_item=None): current_row = -1 self.ui.list_providers.clear() for counter, provider_id in enumerate(self.providers): item = QtWidgets.QListWidgetItem() item.setFlags(item.flags() | QtCore.Qt.ItemIsUserCheckable) item.setText(self.providers[provider_id]['name']) item.setCheckState(QtCore.Qt.Checked if provider_id == self.provider else QtCore.Qt.Unchecked) item.setData(QtCore.Qt.UserRole, provider_id) self.ui.list_providers.addItem(item) if current_item and provider_id == current_item: current_row = counter current_row = max(current_row, 0) self.ui.list_providers.setCurrentRow(current_row) self.ui.list_providers.sortItems() def save(self): self._set_settings(config.setting) def _set_settings(self, settings): settings[KEY_PROVIDER] = self.provider.strip() settings[KEY_EXTRA] = self.additional_words.strip() settings[KEY_PROVIDERS] = self.providers or DEFAULT_PROVIDERS.copy() register_cluster_action(SearchEngineLookupTest()) register_options_page(SearchEngineLookupOptionsPage) register_album_action(AlbumCoverArtLookup()) register_track_action(TrackCoverArtLookup())
# -*- coding: utf-8 -*- PLUGIN_NAME = u"Search the Lortel Archives" PLUGIN_AUTHOR = u"Brian Schweitzer" PLUGIN_DESCRIPTION = "Search the Lortel Archives" PLUGIN_VERSION = "0.2" PLUGIN_API_VERSIONS = ["0.9.0", "0.10","0.11","0.12","0.13","0.14","0.15","0.16"] 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())
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)
class Foobar2000ReplayGainRemove(BaseAction): NAME = _("Foobar2000: &Remove ReplayGain information from files...") def callback(self, objs): run_foobar2000('remove', get_files(objs), self.tagger) class Foobar2000ReplayGainOptionsPage(OptionsPage): NAME = "f2k_rgscan" TITLE = "Foobar2000 ReplayGain" PARENT = "plugins" options = [ TextOption('setting', 'f2k_rgscan_foobar2000_path', get_foobar2000_path()), ] def __init__(self, parent=None): super(Foobar2000ReplayGainOptionsPage, self).__init__(parent) self.ui = Ui_Foobar2000ReplayGainOptionsPage() self.ui.setupUi(self) def load(self): self.ui.foobar2000_path.setText(self.config.setting['f2k_rgscan_foobar2000_path']) def save(self): self.config.setting['f2k_rgscan_foobar2000_path'] = unicode(self.ui.foobar2000_path.text()) register_file_action(Foobar2000ReplayGainScanTrack()) register_file_action(Foobar2000ReplayGainRemove()) register_album_action(Foobar2000ReplayGainScanAlbumByTags()) register_album_action(Foobar2000ReplayGainRemove()) register_options_page(Foobar2000ReplayGainOptionsPage)
PLUGIN_NAME = 'Remove Perfect Albums' PLUGIN_AUTHOR = 'ichneumon, hrglgrmpf' PLUGIN_DESCRIPTION = '''Remove all perfectly matched albums from the selection.''' PLUGIN_VERSION = '0.3' PLUGIN_API_VERSIONS = ['2.0', '2.1', '2.2', '2.3'] PLUGIN_LICENSE = "GPL-2.0" PLUGIN_LICENSE_URL = "https://www.gnu.org/licenses/gpl-2.0.html" from PyQt5.QtCore import QCoreApplication from picard.album import Album from picard.ui.itemviews import BaseAction, register_album_action class RemovePerfectAlbums(BaseAction): NAME = 'Remove perfect albums' def callback(self, objs): for album in objs: if (isinstance(album, Album) and album.loaded and album.is_complete() and album.get_num_unsaved_files() == 0): self.tagger.remove_album(album) QCoreApplication.processEvents() register_album_action(RemovePerfectAlbums())
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]
# Delete all the albums from the AlbumTreeView. We only have to # manipulate the display and not the actual album data. Use the # temp list as the album reference to avoid iterator related problems. for album in albums: self.tagger.window.panel.views[1].remove_album(album) # Sort the list. albums.sort(key=lambda album: (album.metadata["artist"], album.metadata[u"album"])) # Copy all the data back to the AlbumTreeView for album in albums: self.tagger.window.panel.views[1].add_album(album) self.tagger.window.panel.views[1].update_album(album) register_album_action(SortAlbumsByArtist()) class SortAlbumsByTitle(BaseAction): NAME = "Sort Albums by Title" def callback(self, objs): if len(objs) != 1 or not isinstance(objs[0], Album): return album = objs[0] # Temporary list for sorting. albums = [] # Make a copy of all the data in the albums
from PyQt4 import QtCore, QtGui from picard.cluster import Cluster from picard.util import webbrowser2 from picard.ui.itemviews import BaseAction, register_cluster_action, register_album_action, register_file_action, BaseTreeView 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://www.allmusic.com/search/album/" 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://www.allmusic.com/search/artist/" url += QtCore.QUrl.toPercentEncoding(cluster.metadata["albumartist"]) webbrowser2.open(url) register_cluster_action(SearchAMGA()) register_album_action(SearchAMGA()) class SearchAMGTc(BaseAction): NAME = "Search AMG (non-classical music) for Track" def callback(self, objs): file = objs[0]
urlencode(textencoding.asciipunct(artist))) url_query.addQueryItem('title', urlencode(textencoding.asciipunct(album))) i = 1 for track in tracks: url_query.addQueryItem('track' + str(i), urlencode(textencoding.asciipunct(track))) i += 1 url.setQuery(url_query) return url.toString(QUrl.FullyEncoded) class PaperCdCase(BaseAction): NAME = 'Create paper CD case' def callback(self, objs): for obj in objs: if isinstance(obj, Album) or isinstance(obj, Cluster): artist = obj.metadata['albumartist'] album = obj.metadata['album'] if isinstance(obj, Album): tracks = [track.metadata['title'] for track in obj.tracks] else: tracks = [file.metadata['title'] for file in obj.files] url = build_papercdcase_url(artist, album, tracks) webbrowser2.open(url) paperCdCase = PaperCdCase() register_album_action(paperCdCase) register_cluster_action(paperCdCase)
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())
# -*- coding: utf-8 -*- PLUGIN_NAME = u'Remove Perfect Albums' PLUGIN_AUTHOR = u'ichneumon, hrglgrmpf' PLUGIN_DESCRIPTION = u'''Remove all perfectly matched albums from the selection.''' PLUGIN_VERSION = '0.2' PLUGIN_API_VERSIONS = ['0.15'] # heavily based on code from 'The Sorting Plugin' by Aaron Lambers # see http://forums.musicbrainz.org/viewtopic.php?id=2489 # Updated to Picard 0.15 and simplified by hrglgrmpf from picard.album import Album from picard.ui.itemviews import BaseAction, register_album_action class RemovePerfectAlbums(BaseAction): NAME = 'Remove perfect albums' def callback(self, objs): for album in objs: if isinstance(album, Album) and album.is_complete() and album.get_num_unmatched_files() == 0\ and album.get_num_matched_tracks() == len(list(album.iterfiles()))\ and album.get_num_unsaved_files() == 0 and album.loaded == True: self.tagger.remove_album(album) register_album_action(RemovePerfectAlbums())
res = True log.info('beet import "{}"'.format(album)) album_filenames = album.tagger.get_files_from_objects([album]) albumpaths = set() for track in album.tracks: trackno = track.metadata['tracknumber'] discno = track.metadata['discnumber'] track_file = None for album_file in album_filenames: if (str(album_file.tracknumber) == trackno and str(album_file.discnumber) == discno): track_file = album_file.filename break # log.info(u' track "{}"'.format(track_file)) path = os.path.dirname(track_file) # log.info(u' path "{}"'.format(path)) albumpaths.add(os.path.abspath(path)) for path in albumpaths: log.info(u'album path: {}'.format(path)) commandlist = [u'gnome-terminal', u'--', u'beet', 'import', path] log.info(u'Launching: {}'.format(u" ".join(commandlist))) try: res = res and (subprocess.run(commandlist) == 0) except AttributeError: # Python2 res = res and (subprocess.call(commandlist) == 0) log.info(u'Resultado: {}'.format(res)) return res register_album_action(BeetImport())
# -*- coding: utf-8 -*- PLUGIN_NAME = u"Search the Lortel Archives" PLUGIN_AUTHOR = u"Brian Schweitzer" PLUGIN_DESCRIPTION = "Search the Lortel Archives" PLUGIN_VERSION = "0.2" PLUGIN_API_VERSIONS = [ "0.9.0", "0.10", "0.11", "0.12", "0.13", "0.14", "0.15", "0.16" ] 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())
for track in album.tracks: if "artists" in track.metadata: artists = track.metadata.getall("artists") elif "artist" in track.metadata: artists = track.metadata.getall("artist") else: continue for artist in artists: if artist not in trackartists: trackartists.append(artist) if len(trackartists) >= 2: albumartist = (", ").join(trackartists[:-1]) + ' & ' + trackartists[-1] elif len(trackartists) == 1: albumartist = trackartists[0] else: self.tagger.window.set_statusbar_message("Could not find any artists for the album: \"" + album.metadata['album'] + "\"") continue album.metadata.set("albumartist", albumartist) for track in album.tracks: track.metadata.set("albumartist", albumartist) for files in track.linked_files: track.update_file_metadata(files) album.update() register_album_action(CollectArtists())
# -*- 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())
# -*- coding: utf-8 -*- PLUGIN_NAME = u"Search SoundtrackINFO" PLUGIN_AUTHOR = u"Brian Schweitzer" PLUGIN_DESCRIPTION = "Search SoundtrackINFO" PLUGIN_VERSION = "0.2" PLUGIN_API_VERSIONS = ["0.9.0", "0.10","0.11","0.12","0.13","0.14","0.15","0.16"] 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())
t.set("PERFORMER", album.metadata["albumartist"]) t.set("TITLE", album.metadata["album"]) t.set("REM", "MUSICBRAINZ_ALBUM_ID", album.metadata["musicbrainz_albumid"]) t.set("REM", "MUSICBRAINZ_ALBUM_ARTIST_ID", album.metadata["musicbrainz_albumartistid"]) if "date" in album.metadata: t.set("REM", "DATE", album.metadata["date"]) index = 0.0 for i, track in enumerate(album.tracks): mm = index / 60.0 ss = (mm - int(mm)) * 60.0 ff = (ss - int(ss)) * 75.0 index += track.metadata.length / 1000.0 t = cuesheet.tracks[i + 1] t.set("TRACK", "%02d" % (i + 1), "AUDIO") t.set("PERFORMER", track.metadata["artist"]) t.set("TITLE", track.metadata["title"]) t.set("REM", "MUSICBRAINZ_TRACK_ID", track.metadata["musicbrainz_trackid"]) t.set("REM", "MUSICBRAINZ_ARTIST_ID", track.metadata["musicbrainz_artistid"]) t.set("INDEX", "01", "%02d:%02d:%02d" % (mm, ss, ff)) for file in track.linked_files: audio_filename = file.filename if os.path.dirname(filename) == os.path.dirname(audio_filename): audio_filename = os.path.basename(audio_filename) cuesheet.tracks[i].set("FILE", audio_filename, "MP3") cuesheet.write() action = GenerateCuesheet() register_album_action(action)
# -*- 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())
# -*- coding: utf-8 -*- PLUGIN_NAME = u"Search SoundtrackINFO" PLUGIN_AUTHOR = u"Brian Schweitzer" PLUGIN_DESCRIPTION = "Search SoundtrackINFO" PLUGIN_VERSION = "0.2" PLUGIN_API_VERSIONS = [ "0.9.0", "0.10", "0.11", "0.12", "0.13", "0.14", "0.15", "0.16" ] 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())
PLUGIN_NAME = u"Search Discogs for Release" PLUGIN_AUTHOR = u"Brian Schweitzer" PLUGIN_DESCRIPTION = "Search Discogs" PLUGIN_VERSION = "0.2" PLUGIN_API_VERSIONS = [ "0.9.0", "0.10", "0.11", "0.12", "0.13", "0.14", "0.15", "0.16" ] 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())
# -*- coding: utf-8 -*- PLUGIN_NAME = u"Search FilmMuziek.be" PLUGIN_AUTHOR = u"Brian Schweitzer" PLUGIN_DESCRIPTION = "Search FilmMuziek.be" PLUGIN_VERSION = "0.2" PLUGIN_API_VERSIONS = ["0.9.0", "0.10","0.11","0.12","0.13","0.14","0.15","0.16"] 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())
'url' : u"http://www.ebay.co.uk/sch/i.html?_nkw="}, 'us' : { 'name' : u"United States", 'url' : u"http://www.ebay.com/sch/i.html?_nkw="}, 'uy' : { 'name' : u"Uruguay (Mercado Libre)", 'url' : u"http://listado.mercadolibre.com.uy/"}, 've' : { 'name' : u"Venezuela (Mercado Libre)", 'url' : u"http://listado.mercadolibre.com.ve/"}, 'vn' : { 'name' : u"Vietnam", 'url' : u"http://chodientu.vn/ebay-browse-keyword-"} } for tld in ['ar','au','at','be1','be2','br','ca1','ca2','cl','co','cr','cz','dk','do','ec','fi','fr','de','gr','hk','hu','in','ie','it','my','mx','nl','no','pa','pe','ph','pl','pt1','pt2','ru','sg','kr','es','se','ch','tw','th','tr','uk','us','uy','ve','vn']: class SearcheBay(BaseAction): NAME = "Search eBay " + urls[tld]['name'] def callback(self, objs, tld=tld): cluster = objs[0] url = urls[tld]['url'] url += QtCore.QUrl.toPercentEncoding(cluster.metadata["album"]) if tld == 'es': url += '.htm' if tld == 'vn': url += '.html' webbrowser2.open(url) register_cluster_action(SearcheBay()) register_album_action(SearcheBay())
# -*- 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())
#get dictionary of file extension counts extDict = {} for file in album.iterfiles(): _, ext = os.path.splitext(file.filename) extCount = 0 if ext in extDict: extCount = extDict.get(ext) extCount += 1 extDict[ext] = extCount #check each extension has the correct number of files incorrectExtensionCount = False for ext, extCount in extDict.items(): if (extCount != numberOfTracks): log.info( 'The number of %s files in album %s is not equal to the number of tracks %s', ext, extCount, numberOfTracks) incorrectExtensionCount = True break if (incorrectExtensionCount == True): continue log.info('Removing perfect album: %s', title) self.tagger.remove_album(album) register_album_action(RemovePerfectAlbums()) register_album_action(RemovePerfectAlbumsAllowingMultipleFileExtensions())
self.log.debug('Track %s not similar enough', track.metadata['title']) return False return True def save_album_files(self, album): def next_action(result=None, error=None): if error is not None: self.log.info("Error! %s", self.error) return file, old_filename, new_filename = result # mimic tagger._file_saved for the case the album will not # be removed at last del self.tagger.files[old_filename] self.tagger.files[new_filename] = file # Remove processed file from the file. When the list is # empty, we are done with the album and it can be removed. files_to_save.remove(file) if not files_to_save: self.tagger.remove_album(album) self.log.info('Album complete: %s', album.metadata['album']) files_to_save = list(album.iterfiles(save=True)) # Work on a copy of `files_to_save` to be thread-safe. for file in files_to_save[:]: file.save(next_action, self.config.setting) register_album_action(SaveMatches())
# -*- coding: utf-8 -*- PLUGIN_NAME = u"Search CastAlbums.org for Release" PLUGIN_AUTHOR = u"Brian Schweitzer" PLUGIN_DESCRIPTION = "Search CastAlbums.org" PLUGIN_VERSION = "0.2" PLUGIN_API_VERSIONS = ["0.9.0", "0.10","0.11","0.12","0.13","0.14","0.15","0.16"] 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())
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())
class MetaFlacReplayGainRemove(BaseAction): NAME = _("MetaFlac:: &Remove ReplayGain information from files...") def callback(self, objs): run_MetaFlac('--remove-replay-gain', get_files(objs), self.tagger) class MetaFlacReplayGainOptionsPage(OptionsPage): NAME = "metaflac_rgscan" TITLE = "MetaFlac ReplayGain" PARENT = "plugins" options = [ TextOption('setting', 'metaflac_rgscan_metaflac_path', get_metaflac_path()), ] def __init__(self, parent=None): super(MetaFlacReplayGainOptionsPage, self).__init__(parent) self.ui = Ui_MetaFlacReplayGainOptionsPage() self.ui.setupUi(self) def load(self): self.ui.metaflac_path.setText(self.config.setting['metaflac_rgscan_metaflac_path']) def save(self): self.config.setting['metaflac_rgscan_metaflac_path'] = unicode(self.ui.metaflac_path.text()) register_file_action(MetaFlacReplayGainScanTrack()) register_file_action(MetaFlacReplayGainRemove()) register_album_action(MetaFlacReplayGainScanAlbumByTags()) register_album_action(MetaFlacReplayGainRemove()) register_options_page(MetaFlacReplayGainOptionsPage)
album.metadata["musicbrainz_albumartistid"]) if "date" in album.metadata: t.set("REM", "DATE", album.metadata["date"]) index = 0.0 for i, track in enumerate(album.tracks): mm = index / 60.0 ss = (mm - int(mm)) * 60.0 ff = (ss - int(ss)) * 75.0 index += track.metadata.length / 1000.0 t = cuesheet.tracks[i + 1] t.set("TRACK", "%02d" % (i + 1), "AUDIO") t.set("PERFORMER", track.metadata["artist"]) t.set("TITLE", track.metadata["title"]) t.set("REM", "MUSICBRAINZ_TRACK_ID", track.metadata["musicbrainz_trackid"]) t.set("REM", "MUSICBRAINZ_ARTIST_ID", track.metadata["musicbrainz_artistid"]) t.set("INDEX", "01", "%02d:%02d:%02d" % (mm, ss, ff)) for file in track.linked_files: audio_filename = file.filename if os.path.dirname(filename) == os.path.dirname( audio_filename): audio_filename = os.path.basename(audio_filename) cuesheet.tracks[i].set("FILE", audio_filename, "MP3") cuesheet.write() action = GenerateCuesheet() register_album_action(action)
TextOption("setting", "replaygain_vorbisgain_command", "vorbisgain"), TextOption("setting", "replaygain_vorbisgain_options", "-asf"), TextOption("setting", "replaygain_mp3gain_command", "mp3gain"), TextOption("setting", "replaygain_mp3gain_options", "-a -s i"), TextOption("setting", "replaygain_metaflac_command", "metaflac"), TextOption("setting", "replaygain_metaflac_options", "--add-replay-gain"), TextOption("setting", "replaygain_wvgain_command", "wvgain"), TextOption("setting", "replaygain_wvgain_options", "-a") ] def __init__(self, parent=None): super(ReplayGainOptionsPage, self).__init__(parent) self.ui = Ui_ReplayGainOptionsPage() self.ui.setupUi(self) def load(self): self.ui.vorbisgain_command.setText(self.config.setting["replaygain_vorbisgain_command"]) self.ui.mp3gain_command.setText(self.config.setting["replaygain_mp3gain_command"]) self.ui.metaflac_command.setText(self.config.setting["replaygain_metaflac_command"]) self.ui.wvgain_command.setText(self.config.setting["replaygain_wvgain_command"]) def save(self): self.config.setting["replaygain_vorbisgain_command"] = unicode(self.ui.vorbisgain_command.text()) self.config.setting["replaygain_mp3gain_command"] = unicode(self.ui.mp3gain_command.text()) self.config.setting["replaygain_metaflac_command"] = unicode(self.ui.metaflac_command.text()) self.config.setting["replaygain_wvgain_command"] = unicode(self.ui.wvgain_command.text()) register_file_action(ReplayGain()) register_album_action(AlbumGain()) register_options_page(ReplayGainOptionsPage)
round(track.metadata.length / 1000.0)) # EXTINF format assumed to be fixed as follows: entry.add( u"#EXTINF:{duration:d},{artist} - {title}".format( duration=track_length_seconds, artist=track.metadata["artist"], title=track.metadata["title"])) # M3U URL row - assumes only one file per track audio_filename = track.linked_files[0].filename if _debug_level > 1: for i, file in enumerate(track.linked_files): log.debug("{}: linked_file {}: {}".format( PLUGIN_NAME, i, str(file))) # If playlist is in same directory as audio files, then use # local (relative) pathname, otherwise use absolute pathname if _debug_level > 1: log.debug( "{}: audio_filename: {}, selected dir: {}". format(PLUGIN_NAME, audio_filename, os.path.dirname(filename))) if os.path.dirname(filename) == os.path.dirname( audio_filename): audio_filename = os.path.basename(audio_filename) entry.add(unicode(audio_filename)) playlist.write() register_album_action(GeneratePlaylist())
queryargs=params, parse_response_type="xml", request_mimetype="application/xml; charset=utf-8") def submission_handler(self, document, reply, error): if not error: show_popup('Success', 'Successfully submitted {0} ISRC{1}.'.format( self.isrc_count, '' if self.isrc_count == 1 else 's', )) return # Decode response if necessary. xml_text = str(document, 'UTF-8') if isinstance(document, (bytes, bytearray, QtCore.QByteArray)) else str(document) # Build error text message from returned xml payload err_text = '' matches = re.findall(r'<text>(.*?)</text>', xml_text) if matches: err_text = '\n'.join(matches) else: err_text = '' # Use standard QNetworkReply error messages if no message was provided in the xml payload if not err_text: err_text = Q_ERROR_CODES[error] if error in Q_ERROR_CODES else 'There was no error message provided.' show_popup('Error', "There was an error processing the ISRC submission. Please try again.\n\nError Code: {0}\n\n{1}".format(error, err_text)) register_album_action(SubmitAlbumISRCs())
super(NoReleaseOptionsPage, self).__init__(parent) self.ui = Ui_NoReleaseOptionsPage() self.ui.setupUi(self) def load(self): self.ui.norelease_strip_tags.setText( config.setting['norelease_strip_tags']) self.ui.norelease_enable.setChecked(config.setting['norelease_enable']) def save(self): config.setting['norelease_strip_tags'] = str( self.ui.norelease_strip_tags.text()) config.setting[ 'norelease_enable'] = self.ui.norelease_enable.isChecked() def NoReleaseAlbumProcessor(tagger, metadata, release): if config.setting['norelease_enable']: strip_release_specific_metadata(metadata) def NoReleaseTrackProcessor(tagger, metadata, track, release): if config.setting['norelease_enable']: strip_release_specific_metadata(metadata) register_album_metadata_processor(NoReleaseAlbumProcessor) register_track_metadata_processor(NoReleaseTrackProcessor) register_album_action(NoReleaseAction()) register_options_page(NoReleaseOptionsPage)
}, 'vn': { 'name': u"Vietnam", 'url': u"http://chodientu.vn/ebay-browse-keyword-" } } for tld in [ 'ar', 'au', 'at', 'be1', 'be2', 'br', 'ca1', 'ca2', 'cl', 'co', 'cr', 'cz', 'dk', 'do', 'ec', 'fi', 'fr', 'de', 'gr', 'hk', 'hu', 'in', 'ie', 'it', 'my', 'mx', 'nl', 'no', 'pa', 'pe', 'ph', 'pl', 'pt1', 'pt2', 'ru', 'sg', 'kr', 'es', 'se', 'ch', 'tw', 'th', 'tr', 'uk', 'us', 'uy', 've', 'vn' ]: class SearcheBay(BaseAction): NAME = "Search eBay " + urls[tld]['name'] def callback(self, objs, tld=tld): cluster = objs[0] url = urls[tld]['url'] url += QtCore.QUrl.toPercentEncoding(cluster.metadata["album"]) if tld == 'es': url += '.htm' if tld == 'vn': url += '.html' webbrowser2.open(url) register_cluster_action(SearcheBay()) register_album_action(SearcheBay())
options = [ BoolOption('setting', 'norelease_enable', False), TextOption('setting', 'norelease_strip_tags', 'asin,barcode,catalognumber,date,label,media,releasecountry,releasestatus'), ] def __init__(self, parent=None): super(NoReleaseOptionsPage, self).__init__(parent) self.ui = Ui_NoReleaseOptionsPage() self.ui.setupUi(self) def load(self): self.ui.norelease_strip_tags.setText(self.config.setting['norelease_strip_tags']) self.ui.norelease_enable.setChecked(self.config.setting['norelease_enable']) def save(self): 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) register_album_metadata_processor(NoReleaseAlbumProcessor) register_track_metadata_processor(NoReleaseTrackProcessor) register_album_action(NoReleaseAction()) register_options_page(NoReleaseOptionsPage)
# manipulate the display and not the actual album data. Use the # temp list as the album reference to avoid iterator related problems. for album in albums: self.tagger.window.panel.views[1].remove_album(album) # Sort the list. albums.sort(key=lambda album: (album.metadata["artist"], album.metadata[u"album"])) # Copy all the data back to the AlbumTreeView for album in albums: self.tagger.window.panel.views[1].add_album(album) self.tagger.window.panel.views[1].update_album(album) register_album_action(SortAlbumsByArtist()) class SortAlbumsByTitle(BaseAction): NAME = "Sort Albums by Title" def callback(self, objs): if len(objs) != 1 or not isinstance(objs[0], Album): return album = objs[0] # Temporary list for sorting. albums = [] # Make a copy of all the data in the albums for album in self.tagger.albums: