예제 #1
0
 def __remove_old_tracks(self, uris, scan_type):
     """
         Remove non existent tracks from DB
         @param scan_type as ScanType
     """
     if scan_type != ScanType.EXTERNAL and self.__thread is not None:
         # We need to check files are always in collections
         if scan_type == ScanType.FULL:
             collections = App().settings.get_music_uris()
         else:
             collections = None
         for uri in uris:
             # Handle a stop request
             if self.__thread is None:
                 raise Exception("cancelled")
             in_collection = True
             if collections is not None:
                 in_collection = False
                 for collection in collections:
                     if collection in uri:
                         in_collection = True
                         break
             f = Gio.File.new_for_uri(uri)
             if not in_collection:
                 Logger.warning(
                     "Removed, not in collection anymore: %s -> %s", uri,
                     collections)
                 self.del_from_db(uri, True)
             elif not f.query_exists():
                 Logger.warning("Removed, file has been deleted: %s", uri)
                 self.del_from_db(uri, True)
예제 #2
0
 def _get_audiodb_artist_artwork_uri(self, artist, cancellable=None):
     """
         Get artist artwork using AutdioDB
         @param artist as str
         @param cancellable as Gio.Cancellable
         @return uri as str
         @thread safe
     """
     if not get_network_available("AUDIODB"):
         return []
     try:
         artist = GLib.uri_escape_string(artist, None, True)
         uri = "https://theaudiodb.com/api/v1/json/"
         uri += "%s/search.php?s=%s" % (AUDIODB_CLIENT_ID, artist)
         (status, data) = App().task_helper.load_uri_content_sync(
             uri, cancellable)
         if status:
             decode = json.loads(data.decode("utf-8"))
             uri = None
             for item in decode["artists"]:
                 for key in ["strArtistFanart", "strArtistThumb"]:
                     uri = item[key]
                     if uri is not None:
                         return [uri]
     except Exception as e:
         Logger.warning("%s %s", e, artist)
         Logger.warning(
             "DownloaderArt::_get_audiodb_artist_artwork_uri: %s", data)
     return []
예제 #3
0
 def _get_fanarttv_artist_artwork_uri(self, artist, cancellable=None):
     """
         Get artist artwork using FanartTV
         @param artist as str
         @param cancellable as Gio.Cancellable
         @return uri as str
         @thread safe
     """
     if not get_network_available("FANARTTV"):
         return []
     uris = []
     try:
         mbid = self.__get_musicbrainz_mbid("artist", artist, cancellable)
         if mbid is None:
             return []
         uri = "http://webservice.fanart.tv/v3/music/%s?api_key=%s"
         (status, data) = App().task_helper.load_uri_content_sync(
             uri % (mbid, FANARTTV_ID), cancellable)
         if status:
             decode = json.loads(data.decode("utf-8"))
             for item in decode["artistbackground"]:
                 uris.append(item["url"])
     except Exception as e:
         Logger.warning("%s %s", e, artist)
         Logger.warning(
             "DownloaderArt::_get_fanarttv_artist_artwork_uri: %s", data)
     return uris
예제 #4
0
 def __set_popularity(self, pop):
     """
         Set popularity as kid3 is installed
         @param pop as int
     """
     try:
         if App().art.kid3_available:
             if pop == 0:
                 value = 0
             elif pop == 1:
                 value = 1
             elif pop == 2:
                 value = 64
             elif pop == 3:
                 value = 128
             elif pop == 4:
                 value = 196
             else:
                 value = 255
             path = GLib.filename_from_uri(self.__object.uri)[0]
             if GLib.find_program_in_path("flatpak-spawn") is not None:
                 argv = ["flatpak-spawn", "--host", "kid3-cli", "-c",
                         "set POPM %s" % value, path]
             else:
                 argv = ["kid3-cli", "-c", "set POPM %s" % value, path]
             (pid, stdin, stdout, stderr) = GLib.spawn_async(
                 argv, flags=GLib.SpawnFlags.SEARCH_PATH |
                 GLib.SpawnFlags.STDOUT_TO_DEV_NULL,
                 standard_input=False,
                 standard_output=False,
                 standard_error=False
             )
     except Exception as e:
         Logger.error("RatingWidget::__on_can_set_popularity(): %s" % e)
예제 #5
0
 def __get_similar_artists_from_deezer_id(self, deezer_id, cancellable):
     """
        Get similar artists from deezer id
        @param deezer_id as str
        @param cancellable as Gio.Cancellable
        @return [(str, str, str)] : list of (deezer_id, artist, cover_uri)
     """
     artists = []
     try:
         uri = "https://api.deezer.com/artist/%s/related" % deezer_id
         (status,
          data) = App().task_helper.load_uri_content_sync(uri, cancellable)
         if status:
             decode = json.loads(data.decode("utf-8"))
             for artist in decode["data"]:
                 if "picture_xl" in artist.keys():
                     artwork_uri = artist["picture_xl"]
                 elif "picture_big" in artist.keys():
                     artwork_uri = artist["picture_big"]
                 elif "picture_medium" in artist.keys():
                     artwork_uri = artist["picture_medium"]
                 else:
                     artwork_uri = None
                 artists.append((artist["id"], artist["name"], artwork_uri))
     except:
         Logger.error(
             "DeezerSimilars::__get_similar_artists_from_deezer_id(): %s",
             deezer_id)
     return artists
예제 #6
0
 def upgrade(self, db):
     """
         Upgrade db
         @param db as Database
     """
     version = 0
     SqlCursor.add(db)
     with SqlCursor(db, True) as sql:
         result = sql.execute("PRAGMA user_version")
         v = result.fetchone()
         if v is not None:
             version = v[0]
         if version < self.version:
             for i in range(version + 1, self.version + 1):
                 try:
                     if isinstance(self._UPGRADES[i], str):
                         sql.execute(self._UPGRADES[i])
                         SqlCursor.commit(db)
                     else:
                         self._UPGRADES[i](db)
                         SqlCursor.commit(db)
                 except Exception as e:
                     Logger.error("DB upgrade %s failed: %s" % (i, e))
             sql.execute("PRAGMA user_version=%s" % self.version)
     SqlCursor.remove(db)
예제 #7
0
 def load_uri_content_sync(self, uri, cancellable=None):
     """
         Load uri
         @param uri as str
         @param cancellable as Gio.Cancellable
         @return (loaded as bool, content as bytes)
     """
     try:
         session = Soup.Session.new()
         # Post message
         if self.__headers:
             msg = Soup.Message.new("GET", uri)
             headers = msg.get_property("request-headers")
             for header in self.__headers:
                 headers.append(header[0], header[1])
             session.send_message(msg)
             body = msg.get_property("response-body")
             bytes = body.flatten().get_data()
         # Get message
         else:
             request = session.request(uri)
             stream = request.send(cancellable)
             bytes = bytearray(0)
             buf = stream.read_bytes(1024, cancellable).get_data()
             while buf:
                 bytes += buf
                 buf = stream.read_bytes(1024, cancellable).get_data()
             stream.close()
         return (True, bytes)
     except Exception as e:
         Logger.error("TaskHelper::load_uri_content_sync(): %s" % e)
         return (False, b"")
예제 #8
0
 def __listen(self, track, timestamp):
     """
         Scrobble track
         @param track as Track
         @param timestamp as int
     """
     tracks = self.__queue + [(track, timestamp)]
     self.__queue = []
     try:
         for (track, timestamp) in tracks:
             payload = self.__get_payload(track)
             payload[0]["listened_at"] = timestamp
             post_data = {
                 "listen_type": "single",
                 "payload": payload
             }
             body = json.dumps(post_data).encode("utf-8")
             msg = Soup.Message.new("POST", self.__uri)
             msg.set_request("application/json",
                             Soup.MemoryUse.STATIC,
                             body)
             msg.request_headers.append("Accept-Charset", "utf-8")
             msg.request_headers.append("Authorization",
                                        "Token %s" % self.user_token)
             msg.request_headers.append("Content-Type", "application/json")
             data = App().task_helper.send_message_sync(msg,
                                                        self.__cancellable)
             if data is not None:
                 Logger.debug("%s: %s", self.__uri, data)
     except Exception as e:
         Logger.error("ListenBrainzWebService::__listen(): %s" % e)
예제 #9
0
 def __playing_now(self, track):
     """
         Now playing track
         @param track as Track
     """
     try:
         payload = self.__get_payload(track)
         post_data = {
             "listen_type": "playing_now",
             "payload": payload
         }
         body = json.dumps(post_data).encode("utf-8")
         msg = Soup.Message.new("POST", self.__uri)
         msg.set_request("application/json",
                         Soup.MemoryUse.STATIC,
                         body)
         msg.request_headers.append("Accept-Charset", "utf-8")
         msg.request_headers.append("Authorization",
                                    "Token %s" % self.user_token)
         data = App().task_helper.send_message_sync(msg,
                                                    self.__cancellable)
         if data is not None:
             Logger.debug("%s: %s", self.__uri, data)
     except Exception as e:
         Logger.error("ListenBrainzWebService::__playing_now(): %s" % e)
예제 #10
0
 def __on_load_uri_content(self, uri, loaded, content, api, uris):
     """
         Add loaded pixbuf
         @param uri as str
         @param loaded as bool
         @param content as bytes
         @param uris as [str]
         @param api as str
         @param last as bool
     """
     try:
         if loaded:
             self.__add_pixbuf(content, api)
         if uris:
             (uri, api) = uris.pop(0)
             App().task_helper.load_uri_content(uri, self._cancellable,
                                                self.__on_load_uri_content,
                                                api, uris)
         else:
             self.__loaders -= 1
     except Exception as e:
         self.__loaders -= 1
         Logger.warning("ArtworkSearchWidget::__on_load_uri_content(): %s",
                        e)
     if self.__loaders == 0:
         self.__spinner.stop()
예제 #11
0
 def populate(self, bytes, art_size):
     """
         Populate images with bytes
         @param bytes as bytes
         @param art_size as int
         @return bool if success
     """
     try:
         scale_factor = self.get_scale_factor()
         gbytes = GLib.Bytes.new(bytes)
         stream = Gio.MemoryInputStream.new_from_bytes(gbytes)
         if stream is not None:
             pixbuf = GdkPixbuf.Pixbuf.new_from_stream(stream, None)
             if self.__api is None:
                 text = "%sx%s" % (pixbuf.get_width(), pixbuf.get_height())
             else:
                 text = "%s: %sx%s" % (self.__api, pixbuf.get_width(),
                                       pixbuf.get_height())
             self.__label.set_text(text)
             pixbuf = App().art.load_behaviour(pixbuf, None,
                                               art_size * scale_factor,
                                               art_size * scale_factor,
                                               ArtBehaviour.CROP)
             stream.close()
             self.__bytes = bytes
             surface = Gdk.cairo_surface_create_from_pixbuf(
                 pixbuf, scale_factor, None)
             del pixbuf
             self.__image.set_from_surface(surface)
             del surface
             return True
     except Exception as e:
         Logger.error("ArtworkSearch::__get_image: %s" % e)
     return False
예제 #12
0
 def populate(self):
     """
         Populate view
     """
     try:
         grid = Gtk.Grid()
         grid.set_orientation(Gtk.Orientation.VERTICAL)
         grid.show()
         grid.set_row_spacing(5)
         image = Gtk.Image.new_from_icon_name("edit-clear-all-symbolic",
                                              Gtk.IconSize.INVALID)
         image.set_pixel_size(self._art_size)
         context = image.get_style_context()
         context.add_class("cover-frame")
         padding = context.get_padding(Gtk.StateFlags.NORMAL)
         border = context.get_border(Gtk.StateFlags.NORMAL)
         image.set_size_request(
             self._art_size + padding.left + padding.right + border.left +
             border.right, self._art_size + padding.top + padding.bottom +
             border.top + border.bottom)
         image.show()
         label = Gtk.Label.new(_("Remove"))
         label.show()
         grid.add(image)
         grid.add(label)
         grid.set_property("valign", Gtk.Align.CENTER)
         grid.set_property("halign", Gtk.Align.CENTER)
         self._flowbox.add(grid)
         self.__search_for_artwork()
     except Exception as e:
         Logger.error("ArtworkSearchWidget::populate(): %s", e)
예제 #13
0
 def __vacuum(self):
     """
         VACUUM DB
     """
     if self.scanner.is_locked():
         self.scanner.stop()
         GLib.idle_add(self.__vacuum)
         return
     self.db.del_tracks(self.tracks.get_non_persistent())
     try:
         from lollypop.radios import Radios
         with SqlCursor(self.db) as sql:
             sql.isolation_level = None
             sql.execute("VACUUM")
             sql.isolation_level = ""
         with SqlCursor(self.playlists) as sql:
             sql.isolation_level = None
             sql.execute("VACUUM")
             sql.isolation_level = ""
         with SqlCursor(Radios()) as sql:
             sql.isolation_level = None
             sql.execute("VACUUM")
             sql.isolation_level = ""
     except Exception as e:
         Logger.error("Application::__vacuum(): %s" % e)
예제 #14
0
 def update(self, scan_type, uris=[]):
     """
         Update database
         @param scan_type as ScanType
         @param uris as [str]
     """
     self.__disable_compilations = not App().settings.get_value(
         "show-compilations")
     App().lookup_action("update_db").set_enabled(False)
     # Stop previous scan
     if self.is_locked() and scan_type != ScanType.EXTERNAL:
         self.stop()
         GLib.timeout_add(250, self.update, scan_type, uris)
     elif App().ws_director.collection_ws is not None and\
             not App().ws_director.collection_ws.stop():
         GLib.timeout_add(250, self.update, scan_type, uris)
     else:
         if scan_type == ScanType.FULL:
             uris = App().settings.get_music_uris()
         if not uris:
             return
         # Register to progressbar
         if scan_type != ScanType.EXTERNAL:
             App().window.container.progress.add(self)
             App().window.container.progress.set_fraction(0, self)
         Logger.info("Scan started")
         # Launch scan in a separate thread
         self.__thread = App().task_helper.run(self.__scan, scan_type, uris)
예제 #15
0
 def __on_filesystem_info(self, source, result):
     """
         Show available space on disk
         @param source as GObject.Object
         @param result as Gio.AsyncResult
     """
     try:
         info = source.query_filesystem_info_finish(result)
         size = info.get_attribute_uint64(FILE_ATTRIBUTE_FILESYSTEM_SIZE)
         free = info.get_attribute_uint64(FILE_ATTRIBUTE_FILESYSTEM_FREE)
         if size == 0:
             return
         used = size - free
         fraction = 1 * used / size
         self.__progressbar.set_fraction(fraction)
         style_context = self.__progressbar.get_style_context()
         style_context.remove_class("usagebar-green")
         style_context.remove_class("usagebar-orange")
         style_context.remove_class("usagebar-red")
         if fraction < 0.6:
             style_context.add_class("usagebar-green")
         elif fraction < 0.8:
             style_context.add_class("usagebar-orange")
         else:
             style_context.add_class("usagebar-red")
     except Exception as e:
         Logger.error("DeviceWiget::__on_filesystem_info(): %s", e)
예제 #16
0
 def get_year(self, tags):
     """
         Return track year for tags
         @param tags as Gst.TagList
         @return year and timestamp (int, int)
     """
     try:
         (exists, date) = tags.get_date_index("date", 0)
         dt = year = timestamp = None
         if exists:
             year = date.get_year()
             d = Gst.DateTime.new_local_time(year, 1, 1, 0, 0, 0)
             dt = d.to_g_date_time()
             timestamp = dt.to_unix()
         else:
             (exists, date) = tags.get_date_time_index("datetime", 0)
             if exists:
                 dt = date.to_g_date_time()
                 if dt is None:
                     year = date.get_year()
                     d = Gst.DateTime.new_local_time(year, 1, 1, 0, 0, 0)
                     dt = d.to_g_date_time()
                 timestamp = dt.to_unix()
         return (year, timestamp)
     except Exception as e:
         error = "" if tags is None else tags.to_string()
         Logger.error("TagReader::get_year(): %s, %s", e, error)
     return (None, None)
예제 #17
0
 def _get_audiodb_artist_info(self, artist):
     """
         Get artist info from audiodb
         @param artist as str
         @return info as bytes
     """
     if not get_network_available("AUDIODB"):
         return None
     try:
         artist = GLib.uri_escape_string(artist, None, True)
         uri = "https://theaudiodb.com/api/v1/json/"
         uri += "%s/search.php?s=%s" % (AUDIODB_CLIENT_ID, artist)
         (status, data) = App().task_helper.load_uri_content_sync(uri, None)
         if status:
             decode = json.loads(data.decode("utf-8"))
             language = getdefaultlocale()[0][-2:]
             for item in decode["artists"]:
                 for key in ["strBiography%s" % language, "strBiographyEN"]:
                     info = item[key]
                     if info is not None:
                         return info.encode("utf-8")
     except Exception as e:
         Logger.error("InfoDownloader::_get_audiodb_artist_info: %s, %s" %
                      (e, artist))
     return None
예제 #18
0
 def get_artist_id(self, artist_name, cancellable):
     """
         Get artist id
         @param artist_name as str
         @param cancellable as Gio.Cancellable
         @return str/None
     """
     try:
         artist_name = GLib.uri_escape_string(artist_name, None,
                                              True).replace(" ", "+")
         token = App().ws_director.token_ws.get_token(
             "SPOTIFY", cancellable)
         bearer = "Bearer %s" % token
         headers = [("Authorization", bearer)]
         uri = "https://api.spotify.com/v1/search?q=%s&type=artist" %\
             artist_name
         (status,
          data) = App().task_helper.load_uri_content_sync_with_headers(
              uri, headers, cancellable)
         if status:
             decode = json.loads(data.decode("utf-8"))
             for item in decode["artists"]["items"]:
                 return item["id"]
     except Exception as e:
         Logger.error("SpotifyWebHelper::get_artist_id(): %s", e)
     return None
예제 #19
0
 def load_uri_content(self, uri, cancellable, callback, *args):
     """
         Load uri with libsoup
         @param uri as str
         @param cancellable as Gio.Cancellable
         @param callback as a function
         @callback (uri as str, status as bool, content as bytes, args)
     """
     try:
         session = Soup.Session.new()
         session.set_property('accept-language-auto', True)
         # Post message
         if self.__headers:
             msg = Soup.Message.new("GET", uri)
             headers = msg.get_property("request-headers")
             for header in self.__headers:
                 headers.append(header[0], header[1])
             session.send_async(msg, cancellable,
                                self.__on_load_uri_content, callback,
                                cancellable, uri, *args)
         # Get message
         else:
             request = session.request(uri)
             request.send_async(cancellable, self.__on_request_send_async,
                                callback, cancellable, uri, *args)
     except Exception as e:
         Logger.error("HelperTask::load_uri_content(): %s" % e)
         callback(uri, False, b"", *args)
예제 #20
0
 def get_artist_top_tracks(self, spotify_id, cancellable):
     """
         Get top tracks for spotify id
         @param spotify_id as str
         @param cancellable as Gio.Cancellable
         @return str
     """
     try:
         locale = getdefaultlocale()[0][0:2]
         track_ids = []
         token = App().ws_director.token_ws.get_token(
             "SPOTIFY", cancellable)
         bearer = "Bearer %s" % token
         headers = [("Authorization", bearer)]
         uri = "https://api.spotify.com/v1/artists/%s/top-tracks" %\
             spotify_id
         uri += "?country=%s" % locale
         (status,
          data) = App().task_helper.load_uri_content_sync_with_headers(
              uri, headers, cancellable)
         if status:
             decode = json.loads(data.decode("utf-8"))
             for item in decode["tracks"]:
                 track_ids.append(item["id"])
     except Exception as e:
         Logger.error("SpotifyWebHelper::get_artist_top_tracks(): %s", e)
     return track_ids
예제 #21
0
 def __update_fm_settings(self, name):
     """
         Update *fm settings
         @param name as str (librefm/lastfm)
     """
     if App().lastfm is None:
         return
     from pylast import LastFMNetwork, LibreFMNetwork
     fm = None
     for scrobbler in App().scrobblers:
         if (isinstance(scrobbler, LibreFMNetwork) and
             name == "librefm") or\
                 (isinstance(scrobbler, LastFMNetwork) and
                  name != "librefm"):
             fm = scrobbler
             break
     if name == "librefm":
         callback = self.__test_librefm_connection
         login = self.__librefm_login.get_text()
         password = self.__librefm_password.get_text()
     elif App().lastfm is not None:
         callback = self.__test_lastfm_connection
         login = self.__lastfm_login.get_text()
         password = self.__lastfm_password.get_text()
     try:
         if fm is not None and login and password:
             from lollypop.helper_passwords import PasswordsHelper
             helper = PasswordsHelper()
             helper.clear(name, helper.store, name, login, password,
                          self.__on_password_store, fm, callback)
     except Exception as e:
         Logger.error("SettingsDialog::__update_fm_settings(): %s" % e)
예제 #22
0
def install_youtube_dl():
    try:
        path = GLib.get_user_data_dir() + "/lollypop/python"
        argv = ["pip3", "install", "-t", path, "-U", "youtube-dl"]
        GLib.spawn_sync(None, argv, [], GLib.SpawnFlags.SEARCH_PATH, None)
    except Exception as e:
        Logger.error("install_youtube_dl: %s" % e)
예제 #23
0
 def load_similars(self, artist_ids, storage_type, cancellable):
     """
         Load similar artists for artist ids
         @param artist_ids as int
         @param storage_type as StorageType
         @param cancellable as Gio.Cancellable
     """
     for artist_id in artist_ids:
         artist_name = App().artists.get_name(artist_id)
         deezer_id = self.get_artist_id(artist_name, cancellable)
         try:
             uri = "https://api.deezer.com/artist/%s/radio" % deezer_id
             (status, data) = App().task_helper.load_uri_content_sync(
                 uri, cancellable)
             if status:
                 decode = json.loads(data.decode("utf-8"))
                 for payload in decode["data"]:
                     track_payload = self.get_track_payload(
                         payload["id"], cancellable)
                     album_payload = self.get_album_payload(
                         payload["album"]["id"], cancellable)
                     lollypop_payload = self.lollypop_album_payload(
                         album_payload)
                     item = self.save_album_payload_to_db(
                         lollypop_payload, storage_type, True, cancellable)
                     lollypop_payload = self.lollypop_track_payload(
                         track_payload)
                     self.save_track_payload_to_db(lollypop_payload, item,
                                                   storage_type, True,
                                                   cancellable)
         except Exception as e:
             Logger.error("DeezerSimilars::load_similars(): %s", e)
     emit_signal(self, "finished")
예제 #24
0
 def __init__(self):
     """
         Create database tables or manage update if needed
     """
     self.thread_lock = MyLock()
     f = Gio.File.new_for_path(self.DB_PATH)
     upgrade = DatabaseAlbumsUpgrade()
     if not f.query_exists():
         try:
             d = Gio.File.new_for_path(self.__LOCAL_PATH)
             if not d.query_exists():
                 d.make_directory_with_parents()
             # Create db schema
             with SqlCursor(self, True) as sql:
                 sql.execute(self.__create_albums)
                 sql.execute(self.__create_artists)
                 sql.execute(self.__create_genres)
                 sql.execute(self.__create_album_genres)
                 sql.execute(self.__create_album_artists)
                 sql.execute(self.__create_tracks)
                 sql.execute(self.__create_track_artists)
                 sql.execute(self.__create_track_genres)
                 sql.execute(self.__create_album_artists_idx)
                 sql.execute(self.__create_track_artists_idx)
                 sql.execute(self.__create_album_genres_idx)
                 sql.execute(self.__create_track_genres_idx)
                 sql.execute("PRAGMA user_version=%s" % upgrade.version)
         except Exception as e:
             Logger.error("Database::__init__(): %s" % e)
     else:
         upgrade.upgrade(self)
예제 #25
0
 def __on_get_youtube_id(self, uri, status, content, track, cancellable,
                         methods):
     """
         Get youtube id or run another method if not found
         @param uri as str
         @param status as bool
         @param content as bytes
         @param track as Track
         @param cancellable as Gio.Cancellable
         @param methods as [function]
     """
     try:
         youtube_id = None
         if status:
             decode = json.loads(content.decode("utf-8"))
             dic = {}
             best = self.__BAD_SCORE
             for i in decode["items"]:
                 score = get_page_score(i["snippet"]["title"], track.name,
                                        track.artists[0], track.album.name)
                 if score == -1 or score == best:
                     continue
                 elif score < best:
                     best = score
                 dic[score] = i["id"]["videoId"]
             # Return url from first dic item
             if best != self.__BAD_SCORE:
                 youtube_id = dic[best]
     except:
         Logger.warning("BaseWebHelper::__on_get_youtube_id(): %s", content)
     self.__emit_uri_loaded(youtube_id, track, cancellable, methods)
예제 #26
0
 def __request(self, listen_type, payload, retry=0):
     """
         Submit payload to service
         @param listen_type as str
         @param payload as []
         @param retry as int (internal)
     """
     self.__wait_for_ratelimit()
     Logger.debug("ListenBrainz %s: %r" % (listen_type, payload))
     data = {
         "listen_type": listen_type,
         "payload": payload
     }
     body = json.dumps(data).encode("utf-8")
     session = Soup.Session.new()
     uri = "https://%s%s" % (HOST_NAME, PATH_SUBMIT)
     msg = Soup.Message.new("POST", uri)
     msg.set_request("application/json",
                     Soup.MemoryUse.STATIC,
                     body)
     msg.request_headers.append("Authorization",
                                "Token %s" % self.user_token)
     try:
         status = session.send_message(msg)
         response_headers = msg.get_property("response-headers")
         self.__handle_ratelimit(response_headers)
         # Too Many Requests
         if status == 429 and retry < 5:
             self.__request(listen_type, payload, retry + 1)
     except Exception as e:
         print("ListenBrainz::__submit():", e)
예제 #27
0
 def _get_deezer_artist_artwork_uri(self, artist, cancellable=None):
     """
         Get artist artwork using Deezer
         @param artist as str
         @param cancellable as Gio.Cancellable
         @return uri as str
         @tread safe
     """
     if not get_network_available("DEEZER"):
         return []
     try:
         artist_formated = GLib.uri_escape_string(
             artist, None, True).replace(" ", "+")
         uri = "https://api.deezer.com/search/artist/?" +\
               "q=%s&output=json&index=0&limit=1" % artist_formated
         (status, data) = App().task_helper.load_uri_content_sync(
             uri, cancellable)
         if status:
             uri = None
             decode = json.loads(data.decode("utf-8"))
             uri = decode["data"][0]["picture_xl"]
             return [uri]
     except Exception as e:
         Logger.warning("%s %s", e, artist)
         Logger.warning(
             "DownloaderArt::_get_deezer_artist_artwork_uri(): %s", data)
     return []
예제 #28
0
    def __get_basename_for_sync(self):
        """
            Get basename base on device content
            @return str
        """
        names = []
        try:
            if not self.__uri.startswith("mtp://") and\
                    self.__name != "Librem phone":
                return None

            # Search for previous sync
            d = Gio.File.new_for_uri(self.__uri)
            infos = d.enumerate_children("standard::name,standard::type",
                                         Gio.FileQueryInfoFlags.NONE, None)

            for info in infos:
                if info.get_file_type() != Gio.FileType.DIRECTORY:
                    continue
                f = infos.get_child(info)
                uri = f.get_uri() + "/Music"
                previous_sync = Gio.File.new_for_uri("%s/unsync" % uri)
                if previous_sync.query_exists():
                    names.insert(0, info.get_name())
                else:
                    names.append(info.get_name())
            infos.close(None)
        except Exception as e:
            Logger.error("DeviceWidget::__get_best_uri_for_sync: %s: %s" %
                         (self.__uri, e))
        return names
예제 #29
0
 def _get_spotify_artist_artwork_uri(self, artist, cancellable=None):
     """
         Get artist artwork using Spotify
         @param artist as str
         @param cancellable as Gio.Cancellable
         @return uri as str
         @tread safe
     """
     if not get_network_available("SPOTIFY"):
         return []
     try:
         artist_formated = GLib.uri_escape_string(
             artist, None, True).replace(" ", "+")
         uri = "https://api.spotify.com/v1/search?q=%s" % artist_formated +\
               "&type=artist"
         token = App().ws_director.token_ws.get_token("SPOTIFY",
                                                      cancellable)
         bearer = "Bearer %s" % token
         headers = [("Authorization", bearer)]
         (status,
          data) = App().task_helper.load_uri_content_sync_with_headers(
                 uri, headers, cancellable)
         if status:
             uri = None
             decode = json.loads(data.decode("utf-8"))
             for item in decode["artists"]["items"]:
                 if noaccents(item["name"].lower()) ==\
                         noaccents(artist.lower()):
                     uri = item["images"][0]["url"]
                     return [uri]
     except Exception as e:
         Logger.warning("%s %s", e, artist)
         Logger.warning(
             "DownloaderArt::_get_spotify_artist_artwork_uri(): %s", data)
     return []
예제 #30
0
 def __save_in_db(self, storage_type):
     """
         Save current tags into DB
         @param storage_type as StorageType
         @return [CollectionItem]
     """
     items = []
     notify_index = 0
     previous_album_id = None
     for uri in list(self.__tags.keys()):
         # Handle a stop request
         if self.__thread is None:
             raise Exception("cancelled")
         Logger.debug("Adding file: %s" % uri)
         tags = self.__tags[uri]
         item = self.__add2db(uri, *tags, storage_type)
         items.append(item)
         self.__progress_count += 1
         self.__update_progress(self.__progress_count,
                                self.__progress_total, 0.001)
         if previous_album_id != item.album_id:
             self.__notify_ui(items[notify_index:])
             notify_index = len(items)
             previous_album_id = item.album_id
         del self.__tags[uri]
     # Handle a stop request
     if self.__thread is None:
         raise Exception("cancelled")
     self.__notify_ui(items)
     return items