PEP8 cleanup
Esse commit está contido em:
+3
-4
@@ -1,4 +1,4 @@
|
||||
coverart-search-providers v1.2.1
|
||||
coverart-search-providers v1.2.2-testing
|
||||
=========================
|
||||
|
||||
Drop in Rhythmbox replacement for the default CoverArt Search plugin to provide new and updated coverart search providers both local and by internet image hosts
|
||||
@@ -52,12 +52,11 @@ v1.1
|
||||
- fix bug to carry on search after binning poor MusicBrainz image download
|
||||
- restructure rate-limits to ensure faster downloads whilst keeping to providers rate-limits
|
||||
|
||||
v1.2
|
||||
v1.2.x
|
||||
- support song-info dialog for Rhythmbox 3.2
|
||||
- use RB's own embedded art search method as well as mutagen for wider embedded-art coverage
|
||||
|
||||
v1.2.1
|
||||
- bug fix - for locales not found, exit the language installer gracefully
|
||||
- PEP8 cleanup; remove odd embedded provider duplicate
|
||||
|
||||
Recommended order for Search Providers
|
||||
|
||||
|
||||
+10
-15
@@ -42,7 +42,6 @@ import discogs_client as discogs
|
||||
import rb
|
||||
from coverart_search_tracks import mutagen_library
|
||||
|
||||
|
||||
ITEMS_PER_NOTIFICATION = 10
|
||||
IGNORED_SCHEMES = ('http', 'cdda', 'daap', 'mms')
|
||||
REPEAT_SEARCH_PERIOD = 86400 * 7
|
||||
@@ -73,7 +72,7 @@ class BaseSearch(object):
|
||||
print("rate_limit")
|
||||
diff = time.time() - self.current_time
|
||||
if diff < (1.0 / per_second_rate):
|
||||
#Gdk.threads_add_timeout(GLib.PRIORITY_DEFAULT_IDLE,
|
||||
# Gdk.threads_add_timeout(GLib.PRIORITY_DEFAULT_IDLE,
|
||||
# int((1.0 / per_second_rate) *100), delay, None)
|
||||
time.sleep((1.0 / per_second_rate) - diff)
|
||||
print("sleeping")
|
||||
@@ -91,14 +90,14 @@ class CoverSearch(object):
|
||||
self.searches = searches
|
||||
|
||||
def next_search(self, continue_search):
|
||||
'''
|
||||
"""
|
||||
main routine that calls the search routine for each search provider
|
||||
unless one of the searches has found something
|
||||
|
||||
outputs - return False means that nothing found
|
||||
inputs - True means continue with searching
|
||||
- False means a search routine recommends no more searching
|
||||
'''
|
||||
"""
|
||||
|
||||
print("next search")
|
||||
print(continue_search)
|
||||
@@ -107,7 +106,7 @@ class CoverSearch(object):
|
||||
album = self.key.get_field("album")
|
||||
if not album:
|
||||
return False
|
||||
|
||||
|
||||
key = RB.ExtDBKey.create_storage("album", album)
|
||||
key.add_field("artist", self.key.get_field("artist"))
|
||||
self.store.store(key, RB.ExtDBSourceType.NONE, None)
|
||||
@@ -151,7 +150,7 @@ class CoverAlbumSearch:
|
||||
try:
|
||||
files = fileenum.next_files_finish(result)
|
||||
if files is None or len(files) == 0:
|
||||
#print "okay, done; got %d files" % len(results)
|
||||
# print "okay, done; got %d files" % len(results)
|
||||
self.finished(results)
|
||||
return
|
||||
|
||||
@@ -163,7 +162,7 @@ class CoverAlbumSearch:
|
||||
readable = f.get_attribute_boolean("access::can-read")
|
||||
|
||||
if ct is not None and ct.startswith("audio/") and readable:
|
||||
#print "_enum_dir_cb %s " % f.get_name()
|
||||
# print "_enum_dir_cb %s " % f.get_name()
|
||||
results.append(f.get_name())
|
||||
|
||||
fileenum.next_files_async(ITEMS_PER_NOTIFICATION, GLib.PRIORITY_DEFAULT, None, self._enum_dir_cb, results)
|
||||
@@ -174,7 +173,6 @@ class CoverAlbumSearch:
|
||||
sys.excepthook(*sys.exc_info())
|
||||
self.finished(results)
|
||||
|
||||
|
||||
def _enum_children_cb(self, parent, result, data):
|
||||
try:
|
||||
enumfiles = parent.enumerate_children_finish(result)
|
||||
@@ -186,7 +184,6 @@ class CoverAlbumSearch:
|
||||
sys.excepthook(*sys.exc_info())
|
||||
self.callback(True)
|
||||
|
||||
|
||||
def search(self, key, last_time, store, callback, args):
|
||||
# ignore last_time
|
||||
print("calling search")
|
||||
@@ -220,7 +217,7 @@ class CoverAlbumSearch:
|
||||
|
||||
if not self.album:
|
||||
return False
|
||||
|
||||
|
||||
key = RB.ExtDBKey.create_storage("album", self.album)
|
||||
key.add_field("artist", self.artists[0])
|
||||
parent = self.file.get_parent()
|
||||
@@ -241,7 +238,7 @@ class CoverAlbumSearch:
|
||||
|
||||
print("possible flac")
|
||||
try:
|
||||
#flac
|
||||
# flac
|
||||
module = mutagen_library('')
|
||||
music = module.File(search)
|
||||
imagefilename.write(music.pictures[0].data)
|
||||
@@ -344,7 +341,7 @@ class DiscogsSearch(object):
|
||||
if album in ("", _("Unknown")):
|
||||
album = None
|
||||
|
||||
if album == None or len(artists) == 0:
|
||||
if album is None or len(artists) == 0:
|
||||
callback(True)
|
||||
return
|
||||
|
||||
@@ -406,7 +403,6 @@ class SpotifySearch(BaseSearch):
|
||||
|
||||
def search_url(self, artist, album):
|
||||
# Remove variants of Disc/CD [1-9] from album title before search
|
||||
orig_album = album
|
||||
for exp in DISC_NUMBER_REGEXS:
|
||||
p = re.compile(exp, re.IGNORECASE)
|
||||
album = p.sub('', album)
|
||||
@@ -422,7 +418,6 @@ class SpotifySearch(BaseSearch):
|
||||
print("spotify query url = %s" % url)
|
||||
return url
|
||||
|
||||
|
||||
def album_info_cb(self, data, album_name):
|
||||
if data is None:
|
||||
print("spotify query returned nothing")
|
||||
@@ -474,7 +469,7 @@ class SpotifySearch(BaseSearch):
|
||||
if album in ("", _("Unknown")):
|
||||
album = None
|
||||
|
||||
if album == None or len(artists) == 0:
|
||||
if album is None or len(artists) == 0:
|
||||
print("can't search: no useful details")
|
||||
callback(True)
|
||||
return
|
||||
|
||||
@@ -35,7 +35,6 @@ import chardet
|
||||
import rb
|
||||
import rb3compat
|
||||
|
||||
|
||||
gettext.install('rhythmbox', RB.locale_dir())
|
||||
|
||||
if rb3compat.PYVER >= 3:
|
||||
@@ -51,6 +50,7 @@ REPEAT_SEARCH_PERIOD = 86400 * 7
|
||||
def file_root(f_name):
|
||||
return os.path.splitext(f_name)[0].lower()
|
||||
|
||||
|
||||
# this API key belongs to foss.freedom@gmail.com
|
||||
# and was generated specifically for this use
|
||||
API_KEY = '844353bce568b93accd9ca47674d6c3e'
|
||||
@@ -79,14 +79,14 @@ class ArtistCoverSearch(object):
|
||||
self.searches = searches
|
||||
|
||||
def next_search(self, continue_search):
|
||||
'''
|
||||
"""
|
||||
main routine that calls the search routine for each search provider
|
||||
unless one of the searches has found something
|
||||
|
||||
outputs - return False means that nothing found
|
||||
inputs - True means continue with searching
|
||||
- False means a search routine recommends no more searching
|
||||
'''
|
||||
"""
|
||||
|
||||
if len(self.searches) == 0 and continue_search:
|
||||
key = RB.ExtDBKey.create_storage("artist", self.key.get_field("artist"))
|
||||
@@ -110,7 +110,7 @@ class LastFMArtistSearch(object):
|
||||
|
||||
def search_url(self, artist):
|
||||
|
||||
print(("searching for (%s)" % (artist)))
|
||||
print("searching for (%s)" % (artist))
|
||||
url = API_URL + "?method=artist.getinfo&"
|
||||
url = url + "artist=%s&" % (rb3compat.quote_plus(artist))
|
||||
url = url + "format=json&"
|
||||
@@ -153,7 +153,7 @@ class LastFMArtistSearch(object):
|
||||
# images tags appear in order of increasing size, and we want the largest. probably.
|
||||
url = image_urls.pop()
|
||||
|
||||
#last check - ensure the size is relatively large to hide false positives
|
||||
# last check - ensure the size is relatively large to hide false positives
|
||||
site = rb3compat.urlopen(url)
|
||||
meta = site.info()
|
||||
|
||||
@@ -180,12 +180,12 @@ class LastFMArtistSearch(object):
|
||||
l.get_url(url, self.artist_info_cb)
|
||||
|
||||
def search(self, key, last_time, store, callback, args):
|
||||
#if last_time > (time.time() - REPEAT_SEARCH_PERIOD):
|
||||
# if last_time > (time.time() - REPEAT_SEARCH_PERIOD):
|
||||
# print("we already tried this one")
|
||||
# callback (True)
|
||||
# return
|
||||
|
||||
if user_has_account() == False:
|
||||
if not user_has_account():
|
||||
print("can't search: no last.fm account details")
|
||||
callback(True)
|
||||
return
|
||||
@@ -193,7 +193,7 @@ class LastFMArtistSearch(object):
|
||||
artist = key.get_field("artist")
|
||||
self.key = key
|
||||
|
||||
if artist == None:
|
||||
if artist is None:
|
||||
print("can't search: no useful details")
|
||||
callback(True)
|
||||
return
|
||||
|
||||
+14
-21
@@ -18,24 +18,19 @@
|
||||
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
|
||||
import time
|
||||
|
||||
from gi.repository import RB
|
||||
from gi.repository import GObject
|
||||
from gi.repository import GdkPixbuf
|
||||
from gi.repository import Gio
|
||||
|
||||
import os
|
||||
import json
|
||||
import rb3compat
|
||||
|
||||
|
||||
if rb3compat.PYVER >= 3:
|
||||
import dbm.gnu as gdbm
|
||||
else:
|
||||
import gdbm
|
||||
|
||||
import os
|
||||
import json
|
||||
|
||||
|
||||
class Queue:
|
||||
def __init__(self):
|
||||
self.items = []
|
||||
@@ -54,7 +49,7 @@ class Queue:
|
||||
|
||||
|
||||
class CoverArtExtDB:
|
||||
'''
|
||||
"""
|
||||
This is a simplified version of the RB.ExtDB capability. This
|
||||
resolves the bugs in the extant capability, primarily around using
|
||||
signals for none "album-art" databases.
|
||||
@@ -67,7 +62,7 @@ class CoverArtExtDB:
|
||||
ported to python3 - this uses the analagous gdbm format.
|
||||
|
||||
:param name: `str` name of the external database.
|
||||
'''
|
||||
"""
|
||||
|
||||
# storage for the instance references
|
||||
__instances = {}
|
||||
@@ -84,7 +79,7 @@ class CoverArtExtDB:
|
||||
}
|
||||
|
||||
# added (ExtDB self, ExtDBKey object, String path, Value pixbuf)
|
||||
#request (ExtDB self, ExtDBKey object, guint64 last_time)
|
||||
# request (ExtDB self, ExtDBKey object, guint64 last_time)
|
||||
|
||||
_callback = {}
|
||||
|
||||
@@ -138,11 +133,11 @@ class CoverArtExtDB:
|
||||
return keyval
|
||||
|
||||
def store(self, key, source_type, data):
|
||||
'''
|
||||
"""
|
||||
:param key: `ExtDBKey`
|
||||
:param source_type: `ExtDBSourceType`
|
||||
:param data: `GdkPixbuf.Pixbuf`
|
||||
'''
|
||||
"""
|
||||
print("store")
|
||||
|
||||
self.store_uri(key, source_type, data)
|
||||
@@ -201,23 +196,23 @@ class CoverArtExtDB:
|
||||
return False
|
||||
|
||||
def store_uri(self, key, source_type, data):
|
||||
'''
|
||||
"""
|
||||
:param key: `ExtDBKey`
|
||||
:param source_type: `ExtDBSourceType`
|
||||
:param data: `str` which is a uri
|
||||
'''
|
||||
"""
|
||||
print("store_uri")
|
||||
|
||||
self.queue.enqueue((key, source_type, data))
|
||||
|
||||
#Gio.io_scheduler_push_job(self.do_store_request, None,
|
||||
# Gio.io_scheduler_push_job(self.do_store_request, None,
|
||||
# GLib.PRIORITY_DEFAULT, None)
|
||||
self.do_store_request()
|
||||
|
||||
def lookup(self, key):
|
||||
'''
|
||||
"""
|
||||
:param key: `ExtDBKey`
|
||||
'''
|
||||
"""
|
||||
lookup = self._construct_key(key)
|
||||
filename = ''
|
||||
if lookup in self.db:
|
||||
@@ -227,16 +222,15 @@ class CoverArtExtDB:
|
||||
|
||||
return str(filename)
|
||||
|
||||
|
||||
def request(self, key, callback, user_data):
|
||||
'''
|
||||
"""
|
||||
:param key: `ExtDBKey`
|
||||
:param callback: `Function` callback
|
||||
:param user_data: `Value`
|
||||
|
||||
where callback is
|
||||
Function (ExtDBKey key, String filename, GdkPixbuf.Pixbuf data, void* user_data) boolean
|
||||
'''
|
||||
"""
|
||||
|
||||
lookup = self._construct_key(key)
|
||||
|
||||
@@ -276,4 +270,3 @@ class CoverArtExtDB:
|
||||
def __setattr__(self, attr, value):
|
||||
""" Delegate access to implementation """
|
||||
return setattr(self.__dict__['_CoverArtExtDB__instance'], attr, value)
|
||||
|
||||
|
||||
@@ -44,16 +44,16 @@ import rb3compat
|
||||
|
||||
|
||||
def lastfm_connected():
|
||||
'''
|
||||
"""
|
||||
returns True/False if connected to lastfm
|
||||
'''
|
||||
"""
|
||||
return user_has_account()
|
||||
|
||||
|
||||
def get_search_providers():
|
||||
'''
|
||||
"""
|
||||
returns an array of search providers
|
||||
'''
|
||||
"""
|
||||
gs = GSetting()
|
||||
setting = gs.get_setting(gs.Path.PLUGIN)
|
||||
current_providers = setting[gs.PluginKey.PROVIDERS]
|
||||
@@ -62,27 +62,27 @@ def get_search_providers():
|
||||
|
||||
|
||||
class CoverArtAlbumSearchPlugin(GObject.Object, Peas.Activatable):
|
||||
'''
|
||||
"""
|
||||
Main class of the plugin. Manages the activation and deactivation of the
|
||||
plugin.
|
||||
'''
|
||||
"""
|
||||
__gtype_name = 'CoverArtAlbumSearchPlugin'
|
||||
object = GObject.property(type=GObject.Object)
|
||||
|
||||
def __init__(self):
|
||||
'''
|
||||
"""
|
||||
Initialises the plugin object.
|
||||
'''
|
||||
"""
|
||||
GObject.Object.__init__(self)
|
||||
if not rb3compat.compare_pygobject_version('3.9'):
|
||||
GObject.threads_init()
|
||||
|
||||
def do_activate(self):
|
||||
'''
|
||||
"""
|
||||
Called by Rhythmbox when the plugin is activated. It creates the
|
||||
plugin's source and connects signals to manage the plugin's
|
||||
preferences.
|
||||
'''
|
||||
"""
|
||||
|
||||
cl = CoverLocale()
|
||||
cl.switch_locale(cl.Locale.LOCALE_DOMAIN)
|
||||
@@ -128,12 +128,11 @@ class CoverArtAlbumSearchPlugin(GObject.Object, Peas.Activatable):
|
||||
dialog.run()
|
||||
dialog.destroy()
|
||||
|
||||
|
||||
def do_deactivate(self):
|
||||
'''
|
||||
"""
|
||||
Called by Rhythmbox when the plugin is deactivated. It makes sure to
|
||||
free all the resources used by the plugin.
|
||||
'''
|
||||
"""
|
||||
print("CoverArtBrowser DEBUG - do_deactivate")
|
||||
|
||||
self.shell.disconnect(self.csi_id)
|
||||
|
||||
@@ -33,9 +33,9 @@ import rb
|
||||
|
||||
|
||||
class CoverLocale:
|
||||
'''
|
||||
"""
|
||||
This class manages the locale
|
||||
'''
|
||||
"""
|
||||
# storage for the instance reference
|
||||
__instance = None
|
||||
|
||||
@@ -43,18 +43,18 @@ class CoverLocale:
|
||||
""" Implementation of the singleton interface """
|
||||
# below public variables and methods that can be called for CoverLocale
|
||||
def __init__(self):
|
||||
'''
|
||||
"""
|
||||
Initializes the singleton interface, assigning all the constants
|
||||
used to access the plugin's settings.
|
||||
'''
|
||||
"""
|
||||
self.Locale = self._enum(
|
||||
RB='rhythmbox',
|
||||
LOCALE_DOMAIN='coverart_search_providers')
|
||||
|
||||
def switch_locale(self, locale_type):
|
||||
'''
|
||||
"""
|
||||
Change the locale
|
||||
'''
|
||||
"""
|
||||
locale.setlocale(locale.LC_ALL, '')
|
||||
locale.bindtextdomain(locale_type, RB.locale_dir())
|
||||
locale.textdomain(locale_type)
|
||||
@@ -63,17 +63,17 @@ class CoverLocale:
|
||||
gettext.install(locale_type)
|
||||
|
||||
def get_locale(self):
|
||||
'''
|
||||
"""
|
||||
return the string representation of the users locale
|
||||
for example
|
||||
en_US
|
||||
'''
|
||||
"""
|
||||
return locale.getdefaultlocale()[0]
|
||||
|
||||
def _enum(self, **enums):
|
||||
'''
|
||||
"""
|
||||
Create an enumn.
|
||||
'''
|
||||
"""
|
||||
return type('Enum', (), enums)
|
||||
|
||||
def __init__(self):
|
||||
@@ -96,10 +96,10 @@ class CoverLocale:
|
||||
|
||||
|
||||
class GSetting:
|
||||
'''
|
||||
"""
|
||||
This class manages the differentes settings that the plugins haves to
|
||||
access to read or write.
|
||||
'''
|
||||
"""
|
||||
# storage for the instance reference
|
||||
__instance = None
|
||||
|
||||
@@ -107,10 +107,10 @@ class GSetting:
|
||||
""" Implementation of the singleton interface """
|
||||
# below public variables and methods that can be called for GSetting
|
||||
def __init__(self):
|
||||
'''
|
||||
"""
|
||||
Initializes the singleton interface, asigning all the constants
|
||||
used to access the plugin's settings.
|
||||
'''
|
||||
"""
|
||||
self.Path = self._enum(
|
||||
PLUGIN='org.gnome.rhythmbox.plugins.coverart_search_providers')
|
||||
|
||||
@@ -120,9 +120,9 @@ class GSetting:
|
||||
self.setting = {}
|
||||
|
||||
def get_setting(self, path):
|
||||
'''
|
||||
"""
|
||||
Return an instance of Gio.Settings pointing at the selected path.
|
||||
'''
|
||||
"""
|
||||
try:
|
||||
setting = self.setting[path]
|
||||
except:
|
||||
@@ -132,21 +132,21 @@ class GSetting:
|
||||
return setting
|
||||
|
||||
def get_value(self, path, key):
|
||||
'''
|
||||
"""
|
||||
Return the value saved on key from the settings path.
|
||||
'''
|
||||
"""
|
||||
return self.get_setting(path)[key]
|
||||
|
||||
def set_value(self, path, key, value):
|
||||
'''
|
||||
"""
|
||||
Set the passed value to key in the settings path.
|
||||
'''
|
||||
"""
|
||||
self.get_setting(path)[key] = value
|
||||
|
||||
def _enum(self, **enums):
|
||||
'''
|
||||
"""
|
||||
Create an enumn.
|
||||
'''
|
||||
"""
|
||||
return type('Enum', (), enums)
|
||||
|
||||
def __init__(self):
|
||||
@@ -169,10 +169,10 @@ class GSetting:
|
||||
|
||||
|
||||
class SearchPreferences(GObject.Object, PeasGtk.Configurable):
|
||||
'''
|
||||
"""
|
||||
Preferences for the CoverArt Browser Plugins. It holds the settings for
|
||||
the plugin and also is the responsible of creating the preferences dialog.
|
||||
'''
|
||||
"""
|
||||
__gtype_name__ = 'CoverArtSearchProvidersPreferences'
|
||||
object = GObject.property(type=GObject.Object)
|
||||
|
||||
@@ -186,17 +186,17 @@ class SearchPreferences(GObject.Object, PeasGtk.Configurable):
|
||||
MUSICBRAINZ_SEARCH = 'musicbrainz-search'
|
||||
|
||||
def __init__(self):
|
||||
'''
|
||||
"""
|
||||
Initialises the preferences, getting an instance of the settings saved
|
||||
by Gio.
|
||||
'''
|
||||
"""
|
||||
GObject.Object.__init__(self)
|
||||
self._first_run = True
|
||||
|
||||
def do_create_configure_widget(self):
|
||||
'''
|
||||
"""
|
||||
Creates the plugin's preferences dialog
|
||||
'''
|
||||
"""
|
||||
return self._create_display_contents(self)
|
||||
|
||||
def display_preferences_dialog(self, plugin):
|
||||
@@ -255,7 +255,9 @@ class SearchPreferences(GObject.Object, PeasGtk.Configurable):
|
||||
current_providers = copy.deepcopy(self.provider)
|
||||
|
||||
current = self.settings[self.gs.PluginKey.PROVIDERS]
|
||||
print (current)
|
||||
current_list = current.split(',')
|
||||
print (current_list)
|
||||
|
||||
# create the ui
|
||||
builder = Gtk.Builder()
|
||||
@@ -283,8 +285,8 @@ class SearchPreferences(GObject.Object, PeasGtk.Configurable):
|
||||
for key, value in list(current_providers.items()):
|
||||
self.provider_liststore.append([value, key])
|
||||
|
||||
if len(self.provider_liststore) == 0:
|
||||
self.provider_liststore.append([self.provider[self.EMBEDDED_SEARCH], self.EMBEDDED_SEARCH])
|
||||
#if len(self.provider_liststore) == 0:
|
||||
# self.provider_liststore.append([self.provider[self.EMBEDDED_SEARCH], self.EMBEDDED_SEARCH])
|
||||
|
||||
# return the dialog
|
||||
return builder.get_object('maingrid')
|
||||
@@ -317,7 +319,7 @@ class SearchPreferences(GObject.Object, PeasGtk.Configurable):
|
||||
item = self.search_liststore.get_iter_first()
|
||||
current_providers = []
|
||||
|
||||
while ( item != None ):
|
||||
while (item is not None):
|
||||
current_providers.append(self.search_liststore.get_value(item, 1))
|
||||
item = self.search_liststore.iter_next(item)
|
||||
|
||||
@@ -326,17 +328,16 @@ class SearchPreferences(GObject.Object, PeasGtk.Configurable):
|
||||
def on_up_button_clicked(self, *args):
|
||||
selection = self.search_list.get_selection()
|
||||
sel = selection.get_selected()
|
||||
if not sel[1] == None:
|
||||
if not sel[1] is None:
|
||||
previous = self.search_liststore.iter_previous(sel[1])
|
||||
if previous:
|
||||
self.search_liststore.swap(sel[1], previous)
|
||||
self._store_search_providers()
|
||||
|
||||
|
||||
def on_down_button_clicked(self, *args):
|
||||
selection = self.search_list.get_selection()
|
||||
sel = selection.get_selected()
|
||||
if not sel[1] == None:
|
||||
if not sel[1] is None:
|
||||
next = self.search_liststore.iter_next(sel[1])
|
||||
if next:
|
||||
self.search_liststore.swap(sel[1], next)
|
||||
|
||||
+14
-14
@@ -49,9 +49,9 @@ IGNORED_SCHEMES = ('http', 'cdda', 'daap', 'mms')
|
||||
|
||||
|
||||
def anyTrue(pred, seq):
|
||||
'''Returns True if a True predicate is found, False
|
||||
"""Returns True if a True predicate is found, False
|
||||
otherwise. Quits as soon as the first True is found
|
||||
'''
|
||||
"""
|
||||
return True in map(pred, seq)
|
||||
|
||||
|
||||
@@ -65,11 +65,11 @@ class CoverArtTracks(object):
|
||||
return mimetype[0]
|
||||
|
||||
def embed_ogg(self, art_location, search, mimetypestr):
|
||||
'''
|
||||
"""
|
||||
:art_location: file path to the picture to embed
|
||||
:search: file path to the music track file
|
||||
:mimetypestr: mimetype of the picture to embed
|
||||
'''
|
||||
"""
|
||||
try:
|
||||
module = mutagen_library('oggvorbis')
|
||||
o = module.OggVorbis(search)
|
||||
@@ -91,7 +91,7 @@ class CoverArtTracks(object):
|
||||
image.mime = mimetypestr
|
||||
image.desc = 'cover description'
|
||||
tags.setdefault("METADATA_BLOCK_PICTURE",
|
||||
[]).append(base64.b64encode(image.write()))
|
||||
[]).append(base64.b64encode(image.write()))
|
||||
|
||||
o.tags.update(tags)
|
||||
o.save()
|
||||
@@ -99,11 +99,11 @@ class CoverArtTracks(object):
|
||||
pass
|
||||
|
||||
def embed_flac(self, art_location, search, mimetypestr):
|
||||
'''
|
||||
"""
|
||||
:art_location: file path to the picture to embed
|
||||
:search: file path to the music track file
|
||||
:mimetypestr: mimetype of the picture to embed
|
||||
'''
|
||||
"""
|
||||
try:
|
||||
module = mutagen_library('')
|
||||
music = module.File(search)
|
||||
@@ -122,11 +122,11 @@ class CoverArtTracks(object):
|
||||
pass
|
||||
|
||||
def embed_mp4(self, art_location, search, mimetypestr):
|
||||
'''
|
||||
"""
|
||||
:art_location: file path to the picture to embed
|
||||
:search: file path to the music track file
|
||||
:mimetypestr: mimetype of the picture to embed
|
||||
'''
|
||||
"""
|
||||
try:
|
||||
module = mutagen_library('mp4')
|
||||
music = module.MP4(search)
|
||||
@@ -145,11 +145,11 @@ class CoverArtTracks(object):
|
||||
pass
|
||||
|
||||
def embed_mp3(self, art_location, search, mimetypestr):
|
||||
'''
|
||||
"""
|
||||
:art_location: file path to the picture to embed
|
||||
:search: file path to the music track file
|
||||
:mimetypestr: mimetype of the picture to embed
|
||||
'''
|
||||
"""
|
||||
try:
|
||||
module = mutagen_library('id3')
|
||||
music = module.ID3(search)
|
||||
@@ -165,7 +165,7 @@ class CoverArtTracks(object):
|
||||
pass
|
||||
|
||||
def embed(self, track_uri, key, resize=-1):
|
||||
'''
|
||||
"""
|
||||
embed tracks with the coverart
|
||||
|
||||
:track_uri: nominally RB.RhythmDBPropType.LOCATION
|
||||
@@ -173,7 +173,7 @@ class CoverArtTracks(object):
|
||||
:resize: int this is the size of the embedded image to resize to
|
||||
|
||||
returns True or False depending if the routine completed successfully
|
||||
'''
|
||||
"""
|
||||
|
||||
the = anyTrue # for readability
|
||||
|
||||
@@ -181,7 +181,7 @@ class CoverArtTracks(object):
|
||||
|
||||
if not isinstance(art_location, str):
|
||||
art_location = art_location[0]
|
||||
|
||||
|
||||
if not art_location:
|
||||
print("not a valid key to a file containing art")
|
||||
return False
|
||||
|
||||
+35
-25
@@ -1,20 +1,22 @@
|
||||
__version_info__ = (1,1,1)
|
||||
__version_info__ = (1, 1, 1)
|
||||
__version__ = '1.1.1'
|
||||
|
||||
import requests
|
||||
import json
|
||||
import rb3compat
|
||||
|
||||
from collections import defaultdict
|
||||
|
||||
import requests
|
||||
|
||||
import rb3compat
|
||||
|
||||
api_uri = 'http://api.discogs.com'
|
||||
user_agent = None
|
||||
|
||||
|
||||
class APIBase(object):
|
||||
def __init__(self):
|
||||
self._cached_response = None
|
||||
self._params = {}
|
||||
self._headers = { 'accept-encoding': 'gzip, deflate' }
|
||||
self._headers = {'accept-encoding': 'gzip, deflate'}
|
||||
|
||||
def __str__(self):
|
||||
return '<%s "%s">' % (self.__class__.__name__, self._id)
|
||||
@@ -36,20 +38,21 @@ class APIBase(object):
|
||||
if not self._check_user_agent():
|
||||
raise DiscogsAPIError('Invalid or no User-Agent set')
|
||||
try:
|
||||
#gs = GSetting()
|
||||
#setting = gs.get_setting(gs.Path.PLUGIN)
|
||||
#type_val = setting[gs.PluginKey.PROXY_TYPE]
|
||||
#if type_val == 0:
|
||||
# gs = GSetting()
|
||||
# setting = gs.get_setting(gs.Path.PLUGIN)
|
||||
# type_val = setting[gs.PluginKey.PROXY_TYPE]
|
||||
# if type_val == 0:
|
||||
# type_name = 'http'
|
||||
#elif type_val == 1:
|
||||
# elif type_val == 1:
|
||||
# type_name = 'https'
|
||||
#elif type_val == 2:
|
||||
# elif type_val == 2:
|
||||
# type_name = 'ftp'
|
||||
|
||||
#proxy_name = setting[gs.PluginKey.PROXY_VALUE]
|
||||
proxydict = {'http':''}
|
||||
#proxydict[type_name] = proxy_name
|
||||
self._cached_response = requests.get(self._uri, params=self._params, headers=self._headers, proxies=proxydict)
|
||||
|
||||
# proxy_name = setting[gs.PluginKey.PROXY_VALUE]
|
||||
proxydict = {'http': ''}
|
||||
# proxydict[type_name] = proxy_name
|
||||
self._cached_response = requests.get(self._uri, params=self._params, headers=self._headers,
|
||||
proxies=proxydict)
|
||||
except:
|
||||
raise DiscogsAPIError('bad response')
|
||||
|
||||
@@ -61,10 +64,9 @@ class APIBase(object):
|
||||
|
||||
@property
|
||||
def _uri(self):
|
||||
import urllib
|
||||
return '%s/%s/%s' % (api_uri, self._uri_name, rb3compat.quote(rb3compat.unicodeencode(self._id, 'utf-8')))
|
||||
#return '%s/%s/%s' % (api_uri, self._uri_name, urllib.quote(unicode(self._id).encode('utf-8')))
|
||||
|
||||
# return '%s/%s/%s' % (api_uri, self._uri_name, urllib.quote(unicode(self._id).encode('utf-8')))
|
||||
|
||||
@property
|
||||
def data(self):
|
||||
if self._response.content and self._response.status_code == 200:
|
||||
@@ -74,9 +76,11 @@ class APIBase(object):
|
||||
status_code = self._response.status_code
|
||||
raise DiscogsAPIError('%s %s' % (status_code, rb3compat.responses()[status_code]))
|
||||
|
||||
|
||||
class DiscogsAPIError(BaseException):
|
||||
pass
|
||||
|
||||
|
||||
def _parse_credits(extraartists):
|
||||
"""
|
||||
Parse release and track level credits
|
||||
@@ -94,16 +98,18 @@ def _parse_credits(extraartists):
|
||||
_credits[role].append(artist_dict)
|
||||
return _credits
|
||||
|
||||
|
||||
def _class_from_string(api_string):
|
||||
class_map = {
|
||||
'master': MasterRelease,
|
||||
'release': Release,
|
||||
'artist': Artist,
|
||||
'label': Label
|
||||
'master': MasterRelease,
|
||||
'release': Release,
|
||||
'artist': Artist,
|
||||
'label': Label
|
||||
}
|
||||
|
||||
return class_map[api_string]
|
||||
|
||||
|
||||
class Artist(APIBase):
|
||||
def __init__(self, name, anv=None):
|
||||
self._id = name
|
||||
@@ -134,7 +140,7 @@ class Artist(APIBase):
|
||||
@property
|
||||
def releases(self):
|
||||
# TODO: Implement fetch many release IDs
|
||||
#return [Release(r.get('id') for r in self.data.get('releases')]
|
||||
# return [Release(r.get('id') for r in self.data.get('releases')]
|
||||
if not self._releases:
|
||||
self._params.update({'releases': '1'})
|
||||
self._clear_cache()
|
||||
@@ -143,6 +149,7 @@ class Artist(APIBase):
|
||||
self._releases.append(_class_from_string(r['type'])(r['id']))
|
||||
return self._releases
|
||||
|
||||
|
||||
class Release(APIBase):
|
||||
def __init__(self, id):
|
||||
self._id = id
|
||||
@@ -168,7 +175,7 @@ class Release(APIBase):
|
||||
@property
|
||||
def labels(self):
|
||||
if not self._labels:
|
||||
self._labels = [Label(l['name']) for l in self.data.get('labels', [])]
|
||||
self._labels = [Label(l['name']) for l in self.data.get('labels', [])]
|
||||
return self._labels
|
||||
|
||||
@property
|
||||
@@ -199,6 +206,7 @@ class Release(APIBase):
|
||||
def title(self):
|
||||
return self.data.get('title')
|
||||
|
||||
|
||||
class MasterRelease(APIBase):
|
||||
def __init__(self, id):
|
||||
self._id = id
|
||||
@@ -240,6 +248,7 @@ class MasterRelease(APIBase):
|
||||
def tracklist(self):
|
||||
return self.key_release.tracklist
|
||||
|
||||
|
||||
class Label(APIBase):
|
||||
def __init__(self, name):
|
||||
self._id = name
|
||||
@@ -266,6 +275,7 @@ class Label(APIBase):
|
||||
self._clear_cache()
|
||||
return self.data.get('releases')
|
||||
|
||||
|
||||
class Search(APIBase):
|
||||
def __init__(self, query, page=1):
|
||||
self._id = query
|
||||
|
||||
+72
-74
@@ -35,10 +35,10 @@ import rb
|
||||
|
||||
|
||||
def pygobject_version():
|
||||
'''
|
||||
"""
|
||||
returns float of the major and minor parts of a pygobject version
|
||||
e.g. version (3, 9, 5) return float(3.9)
|
||||
'''
|
||||
"""
|
||||
to_number = lambda t: ".".join(str(v) for v in t)
|
||||
|
||||
str_version = to_number(GObject.pygobject_version)
|
||||
@@ -47,10 +47,10 @@ def pygobject_version():
|
||||
|
||||
|
||||
def compare_pygobject_version(version):
|
||||
'''
|
||||
"""
|
||||
return True if version is less than pygobject_version
|
||||
i.e. 3.9 < 3.11
|
||||
'''
|
||||
"""
|
||||
to_number = lambda t: ".".join(str(v) for v in t)
|
||||
|
||||
str_version = to_number(GObject.pygobject_version)
|
||||
@@ -172,17 +172,17 @@ def is_rb3(*args):
|
||||
|
||||
|
||||
class Menu(GObject.Object):
|
||||
'''
|
||||
"""
|
||||
Menu object used to create window popup menus
|
||||
'''
|
||||
"""
|
||||
__gsignals__ = {
|
||||
'pre-popup': (GObject.SIGNAL_RUN_LAST, None, ())
|
||||
}
|
||||
|
||||
def __init__(self, plugin, shell):
|
||||
'''
|
||||
"""
|
||||
Initializes the menu.
|
||||
'''
|
||||
"""
|
||||
super(Menu, self).__init__()
|
||||
self.plugin = plugin
|
||||
self.shell = shell
|
||||
@@ -192,22 +192,22 @@ class Menu(GObject.Object):
|
||||
self._rbmenu_objects = {}
|
||||
|
||||
def add_menu_item(self, menubar, section_name, action):
|
||||
'''
|
||||
"""
|
||||
add a new menu item to the popup
|
||||
:param menubar: `str` is the name GtkMenu (or ignored for RB2.99+)
|
||||
:param section_name: `str` is the name of the section to add the item to (RB2.99+)
|
||||
:param action: `Action` to associate with the menu item
|
||||
'''
|
||||
"""
|
||||
return self.insert_menu_item(menubar, section_name, -1, action)
|
||||
|
||||
def insert_menu_item(self, menubar, section_name, position, action):
|
||||
'''
|
||||
"""
|
||||
add a new menu item to the popup
|
||||
:param menubar: `str` is the name GtkMenu (or ignored for RB2.99+)
|
||||
:param section_name: `str` is the name of the section to add the item to (RB2.99+)
|
||||
:param position: `int` position to add to GtkMenu (ignored for RB2.99+)
|
||||
:param action: `Action` to associate with the menu item
|
||||
'''
|
||||
"""
|
||||
label = action.label
|
||||
|
||||
if is_rb3(self.shell):
|
||||
@@ -238,11 +238,11 @@ class Menu(GObject.Object):
|
||||
return item
|
||||
|
||||
def insert_separator(self, menubar, at_position):
|
||||
'''
|
||||
"""
|
||||
add a separator to the popup (only required for RB2.98 and earlier)
|
||||
:param menubar: `str` is the name GtkMenu (or ignored for RB2.99+)
|
||||
:param position: `int` position to add to GtkMenu (ignored for RB2.99+)
|
||||
'''
|
||||
"""
|
||||
if not is_rb3(self.shell):
|
||||
menu_item = Gtk.SeparatorMenuItem().new()
|
||||
menu_item.set_visible(True)
|
||||
@@ -255,11 +255,11 @@ class Menu(GObject.Object):
|
||||
uim.ensure_update()
|
||||
|
||||
def remove_menu_items(self, menubar, section_name):
|
||||
'''
|
||||
"""
|
||||
utility function to remove all menuitems associated with the menu section
|
||||
:param menubar: `str` is the name of the GtkMenu containing the menu items (ignored for RB2.99+)
|
||||
:param section_name: `str` is the name of the section containing the menu items (for RB2.99+ only)
|
||||
'''
|
||||
"""
|
||||
if is_rb3(self.shell):
|
||||
if not section_name in self._rbmenu_items:
|
||||
return
|
||||
@@ -287,11 +287,11 @@ class Menu(GObject.Object):
|
||||
uim.ensure_update()
|
||||
|
||||
def load_from_file(self, rb2_ui_filename, rb3_ui_filename):
|
||||
'''
|
||||
"""
|
||||
utility function to load the menu structure
|
||||
:param rb2_ui_filename: `str` RB2.98 and below UI file
|
||||
:param rb3_ui_filename: `str` RB2.99 and higher UI file
|
||||
'''
|
||||
"""
|
||||
self.builder = Gtk.Builder()
|
||||
try:
|
||||
from coverart_browser_prefs import CoverLocale
|
||||
@@ -331,21 +331,21 @@ class Menu(GObject.Object):
|
||||
_menu_connect(key, value)
|
||||
|
||||
def connect_signals(self, signals):
|
||||
'''
|
||||
"""
|
||||
connect all signal handlers with their menuitem counterparts
|
||||
:param signals: `dict` key is the name of the menuitem
|
||||
and value is the function callback when the menu is activated
|
||||
'''
|
||||
"""
|
||||
if is_rb3(self.shell):
|
||||
self._connect_rb3_signals(signals)
|
||||
else:
|
||||
self._connect_rb2_signals(signals)
|
||||
|
||||
def get_gtkmenu(self, source, popup_name):
|
||||
'''
|
||||
"""
|
||||
utility function to obtain the GtkMenu from the menu UI file
|
||||
:param popup_name: `str` is the name menu-id in the UI file
|
||||
'''
|
||||
"""
|
||||
if popup_name in self._rbmenu_objects:
|
||||
return self._rbmenu_objects[popup_name]
|
||||
item = self.builder.get_object(popup_name)
|
||||
@@ -363,10 +363,10 @@ class Menu(GObject.Object):
|
||||
return popup_menu
|
||||
|
||||
def get_menu_object(self, menu_name_or_link):
|
||||
'''
|
||||
"""
|
||||
utility function returns the GtkMenuItem/Gio.MenuItem
|
||||
:param menu_name_or_link: `str` to search for in the UI file
|
||||
'''
|
||||
"""
|
||||
if menu_name_or_link in self._rbmenu_objects:
|
||||
return self._rbmenu_objects[menu_name_or_link]
|
||||
item = self.builder.get_object(menu_name_or_link)
|
||||
@@ -384,12 +384,12 @@ class Menu(GObject.Object):
|
||||
return popup_menu
|
||||
|
||||
def set_sensitive(self, menu_or_action_item, enable):
|
||||
'''
|
||||
"""
|
||||
utility function to enable/disable a menu-item
|
||||
:param menu_or_action_item: `GtkMenuItem` or `Gio.SimpleAction`
|
||||
that is to be enabled/disabled
|
||||
:param enable: `bool` value to enable/disable
|
||||
'''
|
||||
"""
|
||||
|
||||
if is_rb3(self.shell):
|
||||
item = self.shell.props.window.lookup_action(menu_or_action_item)
|
||||
@@ -399,29 +399,29 @@ class Menu(GObject.Object):
|
||||
item.set_sensitive(enable)
|
||||
|
||||
def popup(self, source, menu_name, button, time):
|
||||
'''
|
||||
"""
|
||||
utility function to show the popup menu
|
||||
'''
|
||||
"""
|
||||
self.emit('pre-popup')
|
||||
menu = self.get_gtkmenu(source, menu_name)
|
||||
menu.popup(None, None, None, None, button, time)
|
||||
|
||||
|
||||
class ActionGroup(object):
|
||||
'''
|
||||
"""
|
||||
container for all Actions used to associate with menu items
|
||||
'''
|
||||
"""
|
||||
|
||||
# action_state
|
||||
STANDARD = 0
|
||||
TOGGLE = 1
|
||||
|
||||
def __init__(self, shell, group_name):
|
||||
'''
|
||||
"""
|
||||
constructor
|
||||
:param shell: `RBShell`
|
||||
:param group_name: `str` unique name for the object to create
|
||||
'''
|
||||
"""
|
||||
self.group_name = group_name
|
||||
self.shell = shell
|
||||
|
||||
@@ -439,22 +439,22 @@ class ActionGroup(object):
|
||||
return self.group_name
|
||||
|
||||
def remove_actions(self):
|
||||
'''
|
||||
"""
|
||||
utility function to remove all actions associated with the ActionGroup
|
||||
'''
|
||||
"""
|
||||
for action in self.actiongroup.list_actions():
|
||||
self.actiongroup.remove_action(action)
|
||||
|
||||
def get_action(self, action_name):
|
||||
'''
|
||||
"""
|
||||
utility function to obtain the Action from the ActionGroup
|
||||
|
||||
:param action_name: `str` is the Action unique name
|
||||
'''
|
||||
"""
|
||||
return self._actions[action_name]
|
||||
|
||||
def add_action_with_accel(self, func, action_name, accel, **args):
|
||||
'''
|
||||
"""
|
||||
Creates an Action with an accelerator and adds it to the ActionGroup
|
||||
|
||||
:param func: function callback used when user activates the action
|
||||
@@ -464,12 +464,12 @@ class ActionGroup(object):
|
||||
|
||||
Notes:
|
||||
see notes for add_action
|
||||
'''
|
||||
"""
|
||||
args['accel'] = accel
|
||||
return self.add_action(func, action_name, **args)
|
||||
|
||||
def add_action(self, func, action_name, **args):
|
||||
'''
|
||||
"""
|
||||
Creates an Action and adds it to the ActionGroup
|
||||
|
||||
:param func: function callback used when user activates the action
|
||||
@@ -481,7 +481,7 @@ class ActionGroup(object):
|
||||
key value of "action_type" is the RB2.99 Gio.Action type ("win" or "app")
|
||||
by default it assumes all actions are "win" type
|
||||
key value of "action_state" determines what action state to create
|
||||
'''
|
||||
"""
|
||||
if 'label' in args:
|
||||
label = args['label']
|
||||
else:
|
||||
@@ -550,9 +550,9 @@ class ActionGroup(object):
|
||||
|
||||
|
||||
class ApplicationShell(object):
|
||||
'''
|
||||
"""
|
||||
Unique class that mirrors RB.Application & RB.Shell menu functionality
|
||||
'''
|
||||
"""
|
||||
# storage for the instance reference
|
||||
__instance = None
|
||||
|
||||
@@ -570,22 +570,22 @@ class ApplicationShell(object):
|
||||
self._action_groups = {}
|
||||
|
||||
def insert_action_group(self, action_group):
|
||||
'''
|
||||
"""
|
||||
Adds an ActionGroup to the ApplicationShell
|
||||
|
||||
:param action_group: `ActionGroup` to add
|
||||
'''
|
||||
"""
|
||||
self._action_groups[action_group.name] = action_group
|
||||
|
||||
def lookup_action(self, action_group_name, action_name, action_type='app'):
|
||||
'''
|
||||
"""
|
||||
looks up (finds) an action created by another plugin. If found returns
|
||||
an Action or None if no matching Action.
|
||||
|
||||
:param action_group_name: `str` is the Gtk.ActionGroup name (ignored for RB2.99+)
|
||||
:param action_name: `str` unique name for the action to look for
|
||||
:param action_type: `str` RB2.99+ action type ("win" or "app")
|
||||
'''
|
||||
"""
|
||||
|
||||
if is_rb3(self.shell):
|
||||
if action_type == "app":
|
||||
@@ -611,7 +611,7 @@ class ApplicationShell(object):
|
||||
return None
|
||||
|
||||
def add_app_menuitems(self, ui_string, group_name, menu='tools'):
|
||||
'''
|
||||
"""
|
||||
utility function to add application menu items.
|
||||
|
||||
For RB2.99 all application menu items are added to the "tools" section of the
|
||||
@@ -627,7 +627,7 @@ class ApplicationShell(object):
|
||||
:param group_name: `str` unique name of the ActionGroup to add menu items to
|
||||
:param menu: `str` RB2.99 menu section to add to - nominally either
|
||||
'tools' or 'view'
|
||||
'''
|
||||
"""
|
||||
if is_rb3(self.shell):
|
||||
root = ET.fromstring(ui_string)
|
||||
for elem in root.findall(".//menuitem"):
|
||||
@@ -652,7 +652,7 @@ class ApplicationShell(object):
|
||||
uim.ensure_update()
|
||||
|
||||
def add_browser_menuitems(self, ui_string, group_name):
|
||||
'''
|
||||
"""
|
||||
utility function to add popup menu items to existing browser popups
|
||||
|
||||
For RB2.99 all menu items are are assumed to be of action_type "win".
|
||||
@@ -665,7 +665,7 @@ class ApplicationShell(object):
|
||||
this string is in XML format
|
||||
|
||||
:param group_name: `str` unique name of the ActionGroup to add menu items to
|
||||
'''
|
||||
"""
|
||||
if is_rb3(self.shell):
|
||||
root = ET.fromstring(ui_string)
|
||||
for elem in root.findall("./popup"):
|
||||
@@ -703,9 +703,9 @@ class ApplicationShell(object):
|
||||
uim.ensure_update()
|
||||
|
||||
def cleanup(self):
|
||||
'''
|
||||
"""
|
||||
utility remove any menuitems created.
|
||||
'''
|
||||
"""
|
||||
if is_rb3(self.shell):
|
||||
for uid in self._uids:
|
||||
Gio.Application.get_default().remove_plugin_menu_item(self._uids[uid],
|
||||
@@ -736,17 +736,17 @@ class ApplicationShell(object):
|
||||
|
||||
|
||||
class Action(object):
|
||||
'''
|
||||
"""
|
||||
class that wraps around either a Gio.Action or a Gtk.Action
|
||||
'''
|
||||
"""
|
||||
|
||||
def __init__(self, shell, action):
|
||||
'''
|
||||
"""
|
||||
constructor.
|
||||
|
||||
:param shell: `RBShell`
|
||||
:param action: `Gio.Action` or `Gtk.Action`
|
||||
'''
|
||||
"""
|
||||
self.shell = shell
|
||||
self.action = action
|
||||
|
||||
@@ -776,12 +776,12 @@ class Action(object):
|
||||
|
||||
@property
|
||||
def label(self):
|
||||
'''
|
||||
"""
|
||||
get the menu label associated with the Action
|
||||
|
||||
for RB2.99+ actions dont have menu labels so this is managed
|
||||
manually
|
||||
'''
|
||||
"""
|
||||
if not is_rb3(self.shell):
|
||||
return self.action.get_label()
|
||||
else:
|
||||
@@ -796,9 +796,9 @@ class Action(object):
|
||||
|
||||
@property
|
||||
def accel(self):
|
||||
'''
|
||||
"""
|
||||
get the accelerator associated with the Action
|
||||
'''
|
||||
"""
|
||||
return self._accel
|
||||
|
||||
@accel.setter
|
||||
@@ -809,41 +809,41 @@ class Action(object):
|
||||
self._accel = ''
|
||||
|
||||
def get_sensitive(self):
|
||||
'''
|
||||
"""
|
||||
get the sensitivity (enabled/disabled) state of the Action
|
||||
|
||||
returns boolean
|
||||
'''
|
||||
"""
|
||||
if is_rb3(self.shell):
|
||||
return self.action.get_enabled()
|
||||
else:
|
||||
return self.action.get_sensitive()
|
||||
|
||||
def set_state(self, value):
|
||||
'''
|
||||
"""
|
||||
set the state of a stateful action - this is applicable only
|
||||
to RB2.99+
|
||||
'''
|
||||
"""
|
||||
if is_rb3(self.shell) and self.action.props.state_type:
|
||||
self.action.change_state(GLib.Variant('b', value))
|
||||
|
||||
def activate(self):
|
||||
'''
|
||||
"""
|
||||
invokes the activate signal for the action
|
||||
'''
|
||||
"""
|
||||
if is_rb3(self.shell):
|
||||
self.action.activate(None)
|
||||
else:
|
||||
self.action.activate()
|
||||
|
||||
def set_active(self, value):
|
||||
'''
|
||||
"""
|
||||
activate or deactivate a stateful action signal
|
||||
For consistency with earlier RB versions, this will fire the
|
||||
activate signal for the action
|
||||
|
||||
:param value: `boolean` state value
|
||||
'''
|
||||
"""
|
||||
|
||||
if is_rb3(self.shell):
|
||||
self.action.change_state(GLib.Variant('b', value))
|
||||
@@ -855,11 +855,11 @@ class Action(object):
|
||||
self.action.set_active(value)
|
||||
|
||||
def get_active(self):
|
||||
'''
|
||||
"""
|
||||
get the state of the action
|
||||
|
||||
returns `boolean` state value
|
||||
'''
|
||||
"""
|
||||
if is_rb3(self.shell):
|
||||
returnval = self._current_state
|
||||
else:
|
||||
@@ -868,13 +868,11 @@ class Action(object):
|
||||
return returnval
|
||||
|
||||
def associate_menuitem(self, menuitem):
|
||||
'''
|
||||
"""
|
||||
links a menu with the action
|
||||
|
||||
'''
|
||||
"""
|
||||
if is_rb3(self.shell):
|
||||
menuitem.set_detailed_action('win.' + self.action.get_name())
|
||||
else:
|
||||
menuitem.set_related_action(self.action)
|
||||
|
||||
|
||||
|
||||
+43
-44
@@ -27,57 +27,56 @@
|
||||
from gi.repository import RB
|
||||
from gi.repository import Gst, GstPbutils
|
||||
|
||||
|
||||
class EmbeddedSearch(object):
|
||||
def finished_cb(self, discoverer):
|
||||
self.callback(True)
|
||||
|
||||
def finished_cb(self, discoverer):
|
||||
self.callback(True)
|
||||
def discovered_cb(self, discoverer, info, error):
|
||||
tags = info.get_tags()
|
||||
if tags is None:
|
||||
return
|
||||
|
||||
def discovered_cb(self, discoverer, info, error):
|
||||
tags = info.get_tags()
|
||||
if tags is None:
|
||||
return
|
||||
for tagname in ('image', 'preview-image'):
|
||||
(found, sample) = tags.get_sample(tagname)
|
||||
if not found:
|
||||
print("no %s" % tagname)
|
||||
continue
|
||||
|
||||
for tagname in ('image', 'preview-image'):
|
||||
(found, sample) = tags.get_sample(tagname)
|
||||
if not found:
|
||||
print("no %s" % tagname)
|
||||
continue
|
||||
pixbuf = RB.gst_process_embedded_image(tags, tagname)
|
||||
if not pixbuf:
|
||||
print("no pixbuf in %s" % tagname)
|
||||
continue
|
||||
|
||||
pixbuf = RB.gst_process_embedded_image(tags, tagname)
|
||||
if not pixbuf:
|
||||
print("no pixbuf in %s" % tagname)
|
||||
continue
|
||||
print("trying to store pixbuf from %s" % tagname)
|
||||
key = RB.ExtDBKey.create_storage("album", self.search_key.get_field("album"))
|
||||
artists = self.search_key.get_field_values("artist")
|
||||
key.add_field("artist", artists[0])
|
||||
self.store.store(key, RB.ExtDBSourceType.EMBEDDED, pixbuf)
|
||||
return
|
||||
|
||||
print("trying to store pixbuf from %s" % tagname)
|
||||
key = RB.ExtDBKey.create_storage("album", self.search_key.get_field("album"))
|
||||
artists = self.search_key.get_field_values("artist")
|
||||
key.add_field("artist", artists[0])
|
||||
self.store.store(key, RB.ExtDBSourceType.EMBEDDED, pixbuf)
|
||||
return
|
||||
def search(self, key, last_time, store, callback, args):
|
||||
location = key.get_info("location")
|
||||
if location is None:
|
||||
print("not searching, we don't have a location")
|
||||
callback(True)
|
||||
return
|
||||
|
||||
if location.startswith("file://") is False:
|
||||
print("not searching in non-local file %s" % location)
|
||||
callback(True)
|
||||
return
|
||||
|
||||
def search (self, key, last_time, store, callback, args):
|
||||
location = key.get_info("location")
|
||||
if location is None:
|
||||
print("not searching, we don't have a location")
|
||||
callback(True)
|
||||
return
|
||||
# should avoid checking the playing entry, since the player already handles that
|
||||
|
||||
if location.startswith("file://") is False:
|
||||
print("not searching in non-local file %s" % location)
|
||||
callback(True)
|
||||
return
|
||||
self.callback = callback
|
||||
self.callback_args = args
|
||||
self.store = store
|
||||
self.search_key = key
|
||||
|
||||
# should avoid checking the playing entry, since the player already handles that
|
||||
|
||||
self.callback = callback
|
||||
self.callback_args = args
|
||||
self.store = store
|
||||
self.search_key = key
|
||||
|
||||
print("discovering %s" % location)
|
||||
self.discoverer = GstPbutils.Discoverer(timeout=Gst.SECOND*5)
|
||||
self.discoverer.connect('finished', self.finished_cb)
|
||||
self.discoverer.connect('discovered', self.discovered_cb)
|
||||
self.discoverer.start()
|
||||
self.discoverer.discover_uri_async(location)
|
||||
print("discovering %s" % location)
|
||||
self.discoverer = GstPbutils.Discoverer(timeout=Gst.SECOND * 5)
|
||||
self.discoverer.connect('finished', self.finished_cb)
|
||||
self.discoverer.connect('discovered', self.discovered_cb)
|
||||
self.discoverer.start()
|
||||
self.discoverer.discover_uri_async(location)
|
||||
|
||||
@@ -30,7 +30,6 @@ import re
|
||||
import rb3compat
|
||||
from coverart_album_search import BaseSearch
|
||||
|
||||
|
||||
if rb3compat.PYVER >= 3:
|
||||
import configparser
|
||||
else:
|
||||
@@ -108,7 +107,6 @@ class LastFMSearch(BaseSearch):
|
||||
print("last.fm query url = %s" % url)
|
||||
return url
|
||||
|
||||
|
||||
def album_info_cb(self, data):
|
||||
if data is None:
|
||||
print("last.fm query returned nothing")
|
||||
@@ -172,7 +170,6 @@ class LastFMSearch(BaseSearch):
|
||||
l = rb.Loader()
|
||||
self.rate_limit(l.get_url, (url, self.album_info_cb), 5)
|
||||
|
||||
|
||||
def search(self, key, last_time, store, callback, args):
|
||||
|
||||
if user_has_account() == False:
|
||||
|
||||
+2
-4
@@ -128,7 +128,6 @@ class LocalSearch:
|
||||
sys.excepthook(*sys.exc_info())
|
||||
self.finished(results)
|
||||
|
||||
|
||||
def _enum_children_cb(self, parent, result, data):
|
||||
try:
|
||||
enumfiles = parent.enumerate_children_finish(result)
|
||||
@@ -140,7 +139,6 @@ class LocalSearch:
|
||||
sys.excepthook(*sys.exc_info())
|
||||
self.callback(True)
|
||||
|
||||
|
||||
def search(self, key, last_time, store, callback, args):
|
||||
# ignore last_time
|
||||
|
||||
@@ -158,10 +156,10 @@ class LocalSearch:
|
||||
|
||||
self.album = key.get_field("album")
|
||||
if not self.album:
|
||||
print ('no album name')
|
||||
print('no album name')
|
||||
callback(args)
|
||||
return
|
||||
|
||||
|
||||
self.artists = key.get_field_values("artist")
|
||||
self.store = store
|
||||
self.callback = callback
|
||||
|
||||
@@ -34,6 +34,7 @@ import rb3compat
|
||||
from coverart_album_search import BaseSearch
|
||||
|
||||
|
||||
|
||||
# musicbrainz URLs
|
||||
MUSICBRAINZ_RELEASE_URL = "http://musicbrainz.org/ws/2/release/%s?inc=artists"
|
||||
MUSICBRAINZ_RELEASE_PREFIX = "http://musicbrainz.org/release/"
|
||||
|
||||
@@ -31,7 +31,6 @@ from gi.repository import RB
|
||||
|
||||
import rb3compat
|
||||
|
||||
|
||||
gettext.install('rhythmbox', RB.locale_dir())
|
||||
|
||||
ART_FOLDER = os.path.expanduser(os.path.join(RB.user_cache_dir(), 'covers'))
|
||||
|
||||
Referência em uma Nova Issue
Bloquear um usuário