Пример #1
0
 def _on_map_lyrics(self, widget):
     """
         Load on map
         @param widget as Gtk.Viewport
     """
     self._on_child_unmap(widget)
     Lp().settings.set_value('infoswitch',
                             GLib.Variant('s', 'lyrics'))
     self.__jump_button.hide()
     if self.__current_track.id is None:
         self.__current_track = Lp().player.current_track
     # First try to get lyrics from tags
     from lollypop.tagreader import TagReader
     reader = TagReader()
     try:
         info = reader.get_info(self.__current_track.uri)
     except:
         info = None
     lyrics = ""
     if info is not None:
         tags = info.get_tags()
         lyrics = reader.get_lyrics(tags)
     if lyrics or InfoPopover.WebView is None\
             or not get_network_available():
         label = Gtk.Label()
         label.set_vexpand(True)
         label.set_hexpand(True)
         label.set_margin_top(10)
         label.set_margin_end(10)
         label.show()
         widget.add(label)
         if lyrics:
             label.set_label(lyrics)
         elif not get_network_available():
             string = GLib.markup_escape_text(_("Network access disabled"))
             label.get_style_context().add_class('dim-label')
             label.set_markup(
                    "<span font_weight='bold' size='xx-large'>" +
                    string +
                    "</span>")
         else:
             string = GLib.markup_escape_text(
                    _("No lyrics found, please install gir1.2-webkit2-4.0"))
             label.get_style_context().add_class('dim-label')
             label.set_markup(
                    "<span font_weight='bold' size='xx-large'>" +
                    string +
                    "</span>")
     elif get_network_available():
         artists = ", ".join(Lp().player.current_track.artists)
         title = self.__current_track.name
         search = GLib.uri_escape_string(artists + " " + title, None, True)
         url = "http://genius.com/search?q=%s" % search
         # Delayed load due to WebKit memory loading and Gtk animation
         web = self.WebView(True, True)
         web.add_word('search')
         web.add_word('lyrics')
         web.show()
         widget.add(web)
         GLib.timeout_add(250, web.load, url, OpenLink.OPEN)
Пример #2
0
 def populate(self, track):
     """
         Set lyrics
         @param track as Track
     """
     self.__current_track = track
     self.update_artwork(self.__current_width, self.__current_height)
     self.__lyrics_text = ""
     self.__update_lyrics_style()
     self.__lyrics_label.set_text(_("Loading…"))
     self.__cancellable.cancel()
     self.__cancellable.reset()
     # First try to get lyrics from tags
     from lollypop.tagreader import TagReader
     reader = TagReader()
     try:
         info = reader.get_info(self.__current_track.uri)
     except:
         info = None
     if info is not None:
         tags = info.get_tags()
         self.__lyrics_text = reader.get_lyrics(tags)
     if self.__lyrics_text:
         self.__lyrics_label.set_label(self.__lyrics_text)
     else:
         self.__download_wikia_lyrics()
         self.__download_genius_lyrics()
Пример #3
0
 def __update_for_url(self, url):
     """
         Update charts for url
         @param url as str
     """
     if not get_network_available():
         return
     debug("ItunesCharts::__update_for_url(): %s => %s" %
           (url, self.__LIMIT))
     web = Web()
     ids = self.__get_ids(url)
     position = len(ids)
     while ids:
         sleep(10)
         (itunes_id, itunes_genre) = ids.pop(0)
         album = self.__get_album(itunes_id)
         if self.__stop:
             return
         if album is None or not album.subitems:
             position -= 1
             continue
         album.mtime = self.__time + position
         for item in album.subitems:
             item.mtime = self.__time
         debug("ItunesCharts::__update_for_url(): %s - %s" %
               (album.name, album.artists))
         t = TagReader()
         with SqlCursor(Lp().db) as sql:
             genre_ids = t.add_genres(itunes_genre)
             sql.commit()
         genre_ids.append(Type.ITUNES)
         web.save_album_thread(album, DbPersistent.CHARTS, genre_ids)
         position -= 1
Пример #4
0
 def __update_for_url(self, url):
     """
         Update charts for url
         @param url as str
     """
     if not get_network_available():
             return
     debug("ItunesCharts::__update_for_url(): %s => %s" % (url,
                                                           self.__LIMIT))
     web = Web()
     ids = self.__get_ids(url)
     position = len(ids)
     while ids:
         sleep(10)
         (itunes_id, itunes_genre) = ids.pop(0)
         album = self.__get_album(itunes_id)
         if self.__stop:
             return
         if album is None or not album.subitems:
             position -= 1
             continue
         album.mtime = self.__time + position
         for item in album.subitems:
             item.mtime = self.__time
         debug("ItunesCharts::__update_for_url(): %s - %s" % (
                                                             album.name,
                                                             album.artists))
         t = TagReader()
         with SqlCursor(Lp().db) as sql:
             genre_ids = t.add_genres(itunes_genre)
             sql.commit()
         genre_ids.append(Type.ITUNES)
         web.save_album_thread(album, DbPersistent.CHARTS, genre_ids)
         position -= 1
Пример #5
0
 def _on_bus_message_tag(self, bus, message):
     """
         Read tags from stream
         @param bus as Gst.Bus
         @param message as Gst.Message
     """
     # Some radio streams send message tag every seconds!
     changed = False
     if self._current_track.id >= 0 or self._current_track.duration > 0.0:
         return
     Logger.debug("Player::__on_bus_message_tag(): %s" %
                  self._current_track.uri)
     reader = TagReader()
     tags = message.parse_tag()
     title = reader.get_title(tags, "")
     if title != "" and self._current_track.name != title:
         self._current_track.name = title
         changed = True
     if self._current_track.name == "":
         self._current_track.name = self._current_track.uri
         changed = True
     artists = reader.get_artists(tags)
     if artists != "" and self._current_track.artists != artists:
         self._current_track.artists = artists.split(",")
         changed = True
     if not self._current_track.artists:
         self._current_track.artists = self._current_track.album_artists
         changed = True
     if changed:
         self.emit("current-changed")
Пример #6
0
 def __init__(self):
     BinPlayer.__init__(self)
     QueuePlayer.__init__(self)
     LinearPlayer.__init__(self)
     ShufflePlayer.__init__(self)
     UserPlaylistPlayer.__init__(self)
     TagReader.__init__(self)
Пример #7
0
 def _on_map_lyrics(self, widget):
     """
         Load on map
         @param widget as Gtk.Viewport
     """
     self._on_child_unmap(widget)
     Lp().settings.set_value('infoswitch', GLib.Variant('s', 'lyrics'))
     self.__jump_button.hide()
     if self.__current_track.id is None:
         self.__current_track = Lp().player.current_track
     # First try to get lyrics from tags
     from lollypop.tagreader import TagReader
     reader = TagReader()
     try:
         info = reader.get_info(self.__current_track.uri)
     except:
         info = None
     lyrics = ""
     if info is not None:
         tags = info.get_tags()
         lyrics = reader.get_lyrics(tags)
     if lyrics or InfoPopover.WebView is None\
             or not get_network_available():
         label = Gtk.Label()
         label.set_vexpand(True)
         label.set_hexpand(True)
         label.set_margin_top(10)
         label.set_margin_end(10)
         label.show()
         widget.add(label)
         if lyrics:
             label.set_label(lyrics)
         elif not get_network_available():
             string = GLib.markup_escape_text(_("Network access disabled"))
             label.get_style_context().add_class('dim-label')
             label.set_markup("<span font_weight='bold' size='xx-large'>" +
                              string + "</span>")
         else:
             string = GLib.markup_escape_text(
                 _("No lyrics found, please install gir1.2-webkit2-4.0"))
             label.get_style_context().add_class('dim-label')
             label.set_markup("<span font_weight='bold' size='xx-large'>" +
                              string + "</span>")
     elif get_network_available():
         title = self.__current_track.name
         if self.__current_track.id == Type.RADIOS:
             search = GLib.uri_escape_string(title, None, True)
         else:
             artists = ", ".join(Lp().player.current_track.artists)
             search = GLib.uri_escape_string(artists + " " + title, None,
                                             True)
         url = "http://genius.com/search?q=%s" % search
         # Delayed load due to WebKit memory loading and Gtk animation
         web = self.WebView(True, True)
         web.add_word('search')
         web.add_word('lyrics')
         web.show()
         widget.add(web)
         GLib.timeout_add(250, web.load, url, OpenLink.OPEN)
Пример #8
0
 def __init__(self):
     """
         Init radio art
     """
     BaseArt.__init__(self)
     TagReader.__init__(self)
     self.__favorite = Lp().settings.get_value(
                                             'favorite-cover').get_string()
Пример #9
0
 def __init__(self):
     """
         Init album art
     """
     BaseArt.__init__(self)
     TagReader.__init__(self)
     self.__favorite = Lp().settings.get_value(
                                             "favorite-cover").get_string()
Пример #10
0
 def __init__(self):
     """
         Init radio art
     """
     BaseArt.__init__(self)
     ArtDownloader.__init__(self)
     TagReader.__init__(self)
     self._favorite = Lp().settings.get_value('favorite-cover').get_string()
Пример #11
0
    def __save_track(self, item, persistent, album_artist):
        """
            Save item into collection as track
            @param item as SearchItem
            @param persistent as DbPersistent
            @param album artist as str
            @return (album id as int, track id as int)
        """
        # Get uri from helpers
        for helper in self.__helpers:
            uri = helper.get_uri(item)
            if uri:
                break
        # Don't found anything
        if not uri:
            return (None, None)
        track_id = Lp().tracks.get_id_by_uri(uri)
        # Check if track needs to be updated
        if track_id is not None:
            if Lp().tracks.get_persistent(track_id) == DbPersistent.NONE\
                    and persistent == DbPersistent.EXTERNAL:
                Lp().tracks.set_persistent(track_id, DbPersistent.EXTERNAL)
                return (None, None)
        t = TagReader()
        with SqlCursor(Lp().db) as sql:
            # Happen often with Itunes/Spotify
            if album_artist not in item.artists:
                item.artists.append(album_artist)
            artists = "; ".join(item.artists)
            artist_ids = t.add_artists(artists, album_artist, "")
            album_artist_ids = t.add_album_artists(album_artist, "")
            (album_id, new_album) = t.add_album(item.album,
                                                album_artist_ids, "",
                                                False, 0, 0, int(time()), True)
            # FIXME: Check this, could move this in add_album()
            if new_album:
                Lp().albums.set_synced(album_id, Type.NONE)

            if persistent == DbPersistent.CHARTS:
                genre_ids = [Type.CHARTS]
                new_artist_ids = []
            else:
                new_artist_ids = list(set(artist_ids) | set(album_artist_ids))
                genre_ids = t.add_genres("Web", album_id)

            # Add track to db
            track_id = Lp().tracks.add(item.name, uri, item.duration,
                                       0, item.discnumber, "", album_id,
                                       item.year, 0, 0, 0, persistent)
            t.update_track(track_id, artist_ids, genre_ids)
            t.update_album(album_id, album_artist_ids, genre_ids, None)
            sql.commit()

        for genre_id in genre_ids:
            GLib.idle_add(Lp().scanner.emit, 'genre-updated', genre_id, True)
        for artist_id in new_artist_ids:
            GLib.idle_add(Lp().scanner.emit, 'artist-updated', artist_id, True)
        return (album_id, track_id)
Пример #12
0
 def __init__(self):
     BaseArt.__init__(self)
     TagReader.__init__(self)
     self._favorite = Lp.settings.get_value('favorite-cover').get_string()
     if not os.path.exists(self._CACHE_PATH):
         try:
             os.mkdir(self._CACHE_PATH)
         except:
             print("Can't create %s" % self._CACHE_PATH)
Пример #13
0
    def __on_bus_message_tag(self, bus, message):
        """
            Read tags from stream
            @param bus as Gst.Bus
            @param message as Gst.Message
        """
        # Some radio streams send message tag every seconds!
        changed = False
        if (self.current_track.persistent == DbPersistent.INTERNAL or
            self.current_track.mtime != 0) and\
            (self.current_track.id >= 0 or
             self.current_track.duration > 0.0):
            return
        debug("Player::__on_bus_message_tag(): %s" % self.current_track.uri)
        reader = TagReader()

        # Update duration of non internals
        if self.current_track.persistent != DbPersistent.INTERNAL:
            t = Thread(target=self.__update_current_duration,
                       args=(reader, self.current_track))
            t.daemon = True
            t.start()
            return

        tags = message.parse_tag()
        title = reader.get_title(tags, '')
        if title != '' and self.current_track.name != title:
            self.current_track.name = title
            changed = True
        if self.current_track.name == '':
            self.current_track.name = self.current_track.uri
            changed = True
        artists = reader.get_artists(tags)
        if artists != '' and self.current_track.artists != artists:
            self.current_track.artists = artists.split(',')
            changed = True
        if not self.current_track.artists:
            self.current_track.artists = self.current_track.album_artists
            changed = True

        if self.current_track.id == Type.EXTERNALS:
            (b, duration) = self._playbin.query_duration(Gst.Format.TIME)
            if b:
                self.current_track.duration = duration/1000000000
            # We do not use tagreader as we need to check if value is None
            self.current_track.album_name = tags.get_string_index('album',
                                                                  0)[1]
            if self.current_track.album_name is None:
                self.current_track.album_name = ''
            self.current_track.genres = reader.get_genres(tags).split(',')
            changed = True
        if changed:
            self.emit('current-changed')
Пример #14
0
    def __save_track(self, item, persistent, album_artist):
        """
            Save item into collection as track
            @param item as SearchItem
            @param persistent as DbPersistent
            @param album artist as str
            @return (album id as int, track id as int)
        """
        # Get uri from helpers
        for helper in self.__helpers:
            uri = helper.get_uri(item)
            if uri:
                break
        # Don't found anything
        if not uri:
            return (None, None)
        track_id = Lp().tracks.get_id_by_uri(uri)
        # Check if track needs to be updated
        if track_id is not None:
            if Lp().tracks.get_persistent(track_id) == DbPersistent.NONE\
                    and persistent == DbPersistent.EXTERNAL:
                Lp().tracks.set_persistent(track_id, DbPersistent.EXTERNAL)
                return (None, None)
        t = TagReader()
        with SqlCursor(Lp().db) as sql:
            # Happen often with Itunes/Spotify
            if album_artist not in item.artists:
                item.artists.append(album_artist)
            artists = "; ".join(item.artists)
            artist_ids = t.add_artists(artists, album_artist, "")
            album_artist_ids = t.add_album_artists(album_artist, "")
            (album_id, new_album) = t.add_album(item.album,
                                                album_artist_ids,
                                                "", 0, int(time()), True)
            # FIXME: Check this, could move this in add_album()
            if new_album:
                Lp().albums.set_synced(album_id, Type.NONE)

            if persistent == DbPersistent.CHARTS:
                genre_ids = [Type.CHARTS]
                new_artist_ids = []
            else:
                new_artist_ids = list(set(artist_ids) | set(album_artist_ids))
                genre_ids = t.add_genres("Web", album_id)

            # Add track to db
            track_id = Lp().tracks.add(item.name, uri, item.duration,
                                       0, item.discnumber, "", album_id,
                                       item.year, 0, 0, 0, persistent)
            t.update_track(track_id, artist_ids, genre_ids)
            t.update_album(album_id, album_artist_ids, genre_ids, None)
            sql.commit()

        for genre_id in genre_ids:
            GLib.idle_add(Lp().scanner.emit, 'genre-updated', genre_id, True)
        for artist_id in new_artist_ids:
            GLib.idle_add(Lp().scanner.emit, 'artist-updated', artist_id, True)
        return (album_id, track_id)
Пример #15
0
    def __on_bus_message_tag(self, bus, message):
        """
            Read tags from stream
            @param bus as Gst.Bus
            @param message as Gst.Message
        """
        # Some radio streams send message tag every seconds!
        changed = False
        if (self.current_track.persistent == DbPersistent.INTERNAL or
            self.current_track.mtime != 0) and\
            (self.current_track.id >= 0 or
             self.current_track.duration > 0.0):
            return
        debug("Player::__on_bus_message_tag(): %s" % self.current_track.uri)
        reader = TagReader()

        # Update duration of non internals
        if self.current_track.persistent != DbPersistent.INTERNAL:
            t = Thread(target=self.__update_current_duration,
                       args=(reader, self.current_track))
            t.daemon = True
            t.start()
            return

        tags = message.parse_tag()
        title = reader.get_title(tags, '')
        if title != '' and self.current_track.name != title:
            self.current_track.name = title
            changed = True
        if self.current_track.name == '':
            self.current_track.name = self.current_track.uri
            changed = True
        artists = reader.get_artists(tags)
        if artists != '' and self.current_track.artists != artists:
            self.current_track.artists = artists.split(',')
            changed = True
        if not self.current_track.artists:
            self.current_track.artists = self.current_track.album_artists
            changed = True

        if self.current_track.id == Type.EXTERNALS:
            (b, duration) = self._playbin.query_duration(Gst.Format.TIME)
            if b:
                self.current_track.duration = duration / 1000000000
            # We do not use tagreader as we need to check if value is None
            self.current_track.album_name = tags.get_string_index('album',
                                                                  0)[1]
            if self.current_track.album_name is None:
                self.current_track.album_name = ''
            self.current_track.genres = reader.get_genres(tags).split(',')
            changed = True
        if changed:
            self.emit('current-changed')
Пример #16
0
 def populate(self, track):
     """
         Set lyrics
         @param track as Track
     """
     self.__banner.translate_button.set_sensitive(False)
     if track.id is None:
         self.__lyrics_label.set_text("")
         return
     self.__lyrics_label.set_text(_("Loading…"))
     lyrics = ""
     if isinstance(track, Track):
         self.__lyrics_helper.load(track)
         # First check synced lyrics
         if self.__lyrics_helper.available:
             if self.__lyrics_timeout_id is None:
                 self.__lyrics_timeout_id = GLib.timeout_add(
                     200, self.__show_sync_lyrics)
             return
         else:
             if self.__lyrics_timeout_id is not None:
                 GLib.source_remove(self.__lyrics_timeout_id)
                 self.__lyrics_timeout_id = None
             if track.storage_type & (StorageType.COLLECTION |
                                      StorageType.EXTERNAL):
                 from lollypop.tagreader import TagReader, Discoverer
                 tagreader = TagReader()
                 discoverer = Discoverer()
                 try:
                     info = discoverer.get_info(track.uri)
                 except:
                     info = None
                 if info is not None:
                     tags = info.get_tags()
                     lyrics = tagreader.get_lyrics(tags)
     if lyrics:
         self.__lyrics_label.set_text(lyrics)
         self.__lyrics_text = lyrics
     else:
         name = track.name + track.album.name + ",".join(track.artists)
         content = self.__information_store.get_information(name,
                                                            LYRICS_PATH)
         if content:
             self.__lyrics_label.set_text(content.decode("utf-8"))
         elif not get_network_available():
             self.__lyrics_label.set_text(
                 _("Network unavailable or disabled in settings"))
         else:
             self.__lyrics_helper.get_lyrics_from_web(track,
                                                      self.__on_lyrics,
                                                      False,
                                                      track)
Пример #17
0
 def __init__(self):
     """
         Init radio art
     """
     BaseArt.__init__(self)
     ArtDownloader.__init__(self)
     TagReader.__init__(self)
     self._favorite = Lp.settings.get_value('favorite-cover').get_string()
     if not os.path.exists(self._CACHE_PATH):
         try:
             os.mkdir(self._CACHE_PATH)
         except:
             print("Can't create %s" % self._CACHE_PATH)
Пример #18
0
    def __init__(self):
        """
            Init collection scanner
        """
        GObject.GObject.__init__(self)
        TagReader.__init__(self)

        self.__thread = None
        self.__history = None
        if Lp().settings.get_value('auto-update'):
            self.__inotify = Inotify()
        else:
            self.__inotify = None
Пример #19
0
    def __init__(self):
        """
            Init collection scanner
        """
        GObject.GObject.__init__(self)
        TagReader.__init__(self)

        self.__thread = None
        self.__history = None
        if Lp().settings.get_value('auto-update'):
            self.__inotify = Inotify()
        else:
            self.__inotify = None
        Lp().albums.update_max_count()
Пример #20
0
 def __update_current_duration(self, track, uri):
     """
         Update current track duration
         @param track as Track
         @param uri as str
     """
     try:
         reader = TagReader()
         duration = reader.get_info(uri).get_duration() / 1000000000
         if duration != track.duration and duration > 0:
             App().tracks.set_duration(track.id, int(duration))
             track.reset("duration")
             GLib.idle_add(self.emit, "duration-changed", track.id)
     except Exception as e:
         Logger.error("BinPlayer::__update_current_duration(): %s" % e)
    def __init__(self):
        """
            Init collection scanner
        """
        GObject.GObject.__init__(self)
        TagReader.__init__(self)

        self.__thread = None
        self.__history = None
        self.__disable_compilations = True
        if App().settings.get_value("auto-update"):
            self.__inotify = Inotify()
        else:
            self.__inotify = None
        App().albums.update_max_count()
Пример #22
0
    def __save_track(self, item, persistent, album_artist):
        """
            Save item into collection as track
            @param item as SearchItem
            @param persistent as DbPersistent
            @param album artist as str
            @return (album id as int, track id as int)
        """
        yid = self.__get_youtube_id(item)
        if yid is None:
            return (None, None)
        uri = "https://www.youtube.com/watch?v=%s" % yid
        track_id = Lp().tracks.get_id_by_uri(uri)
        # Check if track needs to be updated
        if track_id is not None:
            if Lp().tracks.get_persistent(track_id) == DbPersistent.NONE\
                    and persistent == DbPersistent.EXTERNAL:
                Lp().tracks.set_persistent(track_id, DbPersistent.EXTERNAL)
                return (None, None)
        t = TagReader()
        with SqlCursor(Lp().db) as sql:
            artists = "; ".join(item.artists)
            (artist_ids,
             new_artist_ids) = t.add_artists(artists, album_artist, "")
            (album_artist_ids,
             new_album_artist_ids) = t.add_album_artists(album_artist, "")
            (album_id, new_album) = t.add_album(item.album, album_artist_ids,
                                                "", 0, 0)

            (genre_ids, new_genre_ids) = t.add_genres(_("Youtube"), album_id)

            # Add track to db
            uri = "https://www.youtube.com/watch?v=%s" % yid
            track_id = Lp().tracks.add(item.name, uri, item.duration, 0,
                                       item.discnumber, "", album_id, None, 0,
                                       0, 0, persistent)
            t.update_track(track_id, artist_ids, genre_ids)
            t.update_album(album_id, album_artist_ids, genre_ids, None)
            sql.commit()
        # Notify about new artists/genres
        if new_genre_ids or new_artist_ids:
            for genre_id in new_genre_ids:
                GLib.idle_add(Lp().scanner.emit, 'genre-updated', genre_id,
                              True)
            for artist_id in new_artist_ids:
                GLib.idle_add(Lp().scanner.emit, 'artist-updated', artist_id,
                              album_id, True)
        return (album_id, track_id)
Пример #23
0
 def _on_bus_message_tag(self, bus, message):
     """
         Read tags from stream
         @param bus as Gst.Bus
         @param message as Gst.Message
     """
     if self._current_track.storage_type != StorageType.EXTERNAL:
         return
     Logger.debug("Player::__on_bus_message_tag(): %s" %
                  self._current_track.uri)
     reader = TagReader()
     tags = message.parse_tag()
     title = reader.get_title(tags, "")
     if len(title) > 1 and self._current_track.title != title:
         self._current_track.set_name(title)
         emit_signal(self, "current-changed")
Пример #24
0
 def _on_map_lyrics(self, widget):
     """
         Load on map
         @param widget as Gtk.Viewport
     """
     self._on_child_unmap(widget)
     Lp().settings.set_value('infoswitch', GLib.Variant('s', 'lyrics'))
     self.__jump_button.hide()
     if self.__current_track.id is None:
         self.__current_track = Lp().player.current_track
     # First try to get lyrics from tags
     from lollypop.tagreader import TagReader
     reader = TagReader()
     try:
         info = reader.get_info(self.__current_track.uri)
     except:
         info = None
     lyrics = ""
     if info is not None:
         tags = info.get_tags()
         lyrics = reader.get_lyrics(tags)
     if lyrics or InfoPopover.WebView is None:
         label = Gtk.Label()
         label.set_vexpand(True)
         label.set_hexpand(True)
         label.set_margin_top(10)
         label.set_margin_end(10)
         label.show()
         widget.add(label)
         if lyrics:
             label.set_label(lyrics)
         else:
             label.set_label(
                 _("No lyrics found, please install gir1.2-webkit2-4.0"))
     else:
         artists = ", ".join(Lp().player.current_track.artists)
         title = self.__current_track.name
         url = "http://genius.com/search?q=%s" % artists + " " + title
         # Delayed load due to WebKit memory loading and Gtk animation
         web = self.WebView(True, True)
         web.add_word('search')
         web.add_word('lyrics')
         web.show()
         widget.add(web)
         GLib.timeout_add(250, web.load, url, OpenLink.OPEN)
Пример #25
0
 def populate(self, track):
     """
         Set lyrics
         @param track as Track
     """
     self.__current_track = track
     self.update_artwork(self.__size, self.__size)
     self.__lyrics_text = ""
     self.__lyrics_label.set_text(_("Loading…"))
     self.__cancellable.cancel()
     self.__cancellable = Gio.Cancellable()
     self.__sync_lyrics_helper.load(track)
     self.__update_lyrics_style()
     if self.__sync_lyrics_helper.available:
         self.__translate_button.hide()
         if self.__lyrics_timeout_id is None:
             self.__lyrics_timeout_id = GLib.timeout_add(
                 500, self.__show_sync_lyrics)
         return
     else:
         self.__translate_button.show()
         if self.__lyrics_timeout_id is not None:
             GLib.source_remove(self.__lyrics_timeout_id)
             self.__lyrics_timeout_id = None
     # First try to get lyrics from tags
     from lollypop.tagreader import TagReader
     reader = TagReader()
     try:
         info = reader.get_info(self.__current_track.uri)
     except:
         info = None
     if info is not None:
         tags = info.get_tags()
         self.__lyrics_text = reader.get_lyrics(tags)
     if self.__lyrics_text:
         self.__lyrics_label.set_text(self.__lyrics_text)
     else:
         if get_network_available("WIKIA"):
             self.__download_wikia_lyrics()
         if get_network_available("GENIUS"):
             self.__download_genius_lyrics()
         if self.__downloads_running == 0:
             self.__lyrics_label.set_text(
                 _("You have disabled lyrics search in network settings !"))
Пример #26
0
    def __init__(self):
        """
            Init popover
        """
        Gtk.Popover.__init__(self)
        self.set_position(Gtk.PositionType.BOTTOM)
        self.connect('unmap', self.__on_self_unmap)
        builder = Gtk.Builder()
        builder.add_from_resource('/org/gnome/Lollypop/ExternalsPopover.ui')
        builder.connect_signals(self)

        self.__signal_id = None
        self.__view = builder.get_object('view')
        self.__model = builder.get_object('model')
        self.__tagreader = TagReader()

        renderer0 = Gtk.CellRendererPixbuf()
        renderer1 = Gtk.CellRendererText()
        renderer1.set_property('weight', 800)
        renderer1.set_property('weight-set', True)
        renderer1.set_property('ellipsize-set', True)
        renderer1.set_property('ellipsize', Pango.EllipsizeMode.END)
        renderer2 = Gtk.CellRendererText()
        renderer2.set_property('ellipsize-set', True)
        renderer2.set_property('ellipsize', Pango.EllipsizeMode.END)
        renderer3 = Gtk.CellRendererText()
        column = Gtk.TreeViewColumn('')
        column.pack_start(renderer0, True)
        column.pack_start(renderer1, True)
        column.pack_start(renderer2, True)
        column.pack_end(renderer3, False)
        column.add_attribute(renderer0, 'icon-name', 1)
        column.add_attribute(renderer1, 'text', 2)
        column.add_attribute(renderer2, 'text', 3)
        column.add_attribute(renderer3, 'text', 4)
        column.set_expand(True)
        column.set_sizing(Gtk.TreeViewColumnSizing.FIXED)
        self.__view.append_column(column)
        self.add(self.__view)
        self.__signal_id = Lp().player.connect('current-changed',
                                               self.__on_current_changed)
        height = Lp().window.get_size()[1]
        self.set_size_request(400, height*0.7)
Пример #27
0
    def _on_bus_message_tag(self, bus, message):
        """
            Read tags from stream
            @param bus as Gst.Bus
            @param message as Gst.Message
        """
        # Some radio streams send message tag every seconds!
        changed = False
        if self._current_track.id >= 0 or self._current_track.duration > 0.0:
            return
        debug("Player::__on_bus_message_tag(): %s" % self._current_track.uri)
        reader = TagReader()
        tags = message.parse_tag()
        title = reader.get_title(tags, "")
        if title != "" and self._current_track.name != title:
            self._current_track.name = title
            changed = True
        if self._current_track.name == "":
            self._current_track.name = self._current_track.uri
            changed = True
        artists = reader.get_artists(tags)
        if artists != "" and self._current_track.artists != artists:
            self._current_track.artists = artists.split(",")
            changed = True
        if not self._current_track.artists:
            self._current_track.artists = self._current_track.album_artists
            changed = True

        if self._current_track.id == Type.EXTERNALS:
            (b, duration) = self._playbin.query_duration(Gst.Format.TIME)
            if b:
                self._current_track.duration = duration/1000000000
            # We do not use tagreader as we need to check if value is None
            self._current_track.album_name = tags.get_string_index("album",
                                                                   0)[1]
            if self._current_track.album_name is None:
                self._current_track.album_name = ""
            self._current_track.genres = reader.get_genres(tags).split(",")
            changed = True
        if changed:
            self.emit("current-changed")
Пример #28
0
 def load(self, track):
     """
         Load lyrics for track
         @param track as Track
     """
     self.__track = track
     self.__timestamps = {}
     uri_no_ext = ".".join(track.uri.split(".")[:-1])
     self.__lrc_file = Gio.File.new_for_uri(uri_no_ext + ".lrc")
     if self.__lrc_file.query_exists():
         self.__get_timestamps()
     else:
         from lollypop.tagreader import TagReader
         reader = TagReader()
         try:
             info = reader.get_info(track.uri)
         except:
             info = None
         if info is not None:
             tags = info.get_tags()
             for (lyrics, timestamp) in reader.get_synced_lyrics(tags):
                 self.__timestamps[timestamp] = lyrics
Пример #29
0
 def _on_map_lyrics(self, widget):
     """
         Load on map
         @param widget as Gtk.Viewport
     """
     Lp().settings.set_value("infoswitch", GLib.Variant("s", "lyrics"))
     self.__jump_button.hide()
     if self.__current_track.id is None:
         self.__current_track = Lp().player.current_track
     # First try to get lyrics from tags
     from lollypop.tagreader import TagReader
     reader = TagReader()
     try:
         info = reader.get_info(self.__current_track.uri)
     except:
         info = None
     lyrics = ""
     if info is not None:
         tags = info.get_tags()
         lyrics = reader.get_lyrics(tags)
     if lyrics or InfoPopover.WebView is None\
             or not get_network_available():
         # Destroy previous widgets
         self._on_child_unmap(widget)
         label = Gtk.Label()
         label.set_vexpand(True)
         label.set_hexpand(True)
         label.set_margin_top(10)
         label.set_margin_end(10)
         label.show()
         widget.add(label)
         if lyrics:
             label.set_label(lyrics)
         elif not get_network_available():
             string = GLib.markup_escape_text(_("Network access disabled"))
             label.get_style_context().add_class("dim-label")
             label.set_markup('<span font_weight="bold" size="xx-large">' +
                              string + "</span>")
         else:
             string = GLib.markup_escape_text(
                 _("No lyrics found, please install gir1.2-webkit2-4.0"))
             label.get_style_context().add_class("dim-label")
             label.set_markup('<span font_weight="bold" size="xx-large">' +
                              string + "</span>")
     elif get_network_available():
         title = self.__current_track.name
         if self.__current_track.id == Type.RADIOS:
             search = GLib.uri_escape_string(title, None, True)
         else:
             artists = ", ".join(Lp().player.current_track.artists)
             search = GLib.uri_escape_string(artists + " " + title, None,
                                             True)
         url = "http://genius.com/search?q=%s" % search
         # If we do not have a webview in children, create a new one
         # Else load url
         children = widget.get_children()
         if not children or not isinstance(children[0], self.WebView):
             # Destroy previous widgets
             self._on_child_unmap(widget)
             web = self.WebView(True, True)
             web.add_word("search")
             web.add_word("lyrics")
             web.show()
             widget.add(web)
             # Delayed load due to WebKit memory loading and Gtk animation
             GLib.timeout_add(250, web.load, url, OpenLink.NEW)
         elif url != children[0].url:
             children[0].load(url, OpenLink.NEW)
Пример #30
0
class ExternalsPopover(Gtk.Popover):
    """
        Popover for external tracks
    """

    def __init__(self):
        """
            Init popover
        """
        Gtk.Popover.__init__(self)
        self.set_position(Gtk.PositionType.BOTTOM)
        self.connect('unmap', self.__on_self_unmap)
        builder = Gtk.Builder()
        builder.add_from_resource('/org/gnome/Lollypop/ExternalsPopover.ui')
        builder.connect_signals(self)

        self.__signal_id = None
        self.__view = builder.get_object('view')
        self.__model = builder.get_object('model')
        self.__tagreader = TagReader()

        renderer0 = Gtk.CellRendererPixbuf()
        renderer1 = Gtk.CellRendererText()
        renderer1.set_property('weight', 800)
        renderer1.set_property('weight-set', True)
        renderer1.set_property('ellipsize-set', True)
        renderer1.set_property('ellipsize', Pango.EllipsizeMode.END)
        renderer2 = Gtk.CellRendererText()
        renderer2.set_property('ellipsize-set', True)
        renderer2.set_property('ellipsize', Pango.EllipsizeMode.END)
        renderer3 = Gtk.CellRendererText()
        column = Gtk.TreeViewColumn('')
        column.pack_start(renderer0, True)
        column.pack_start(renderer1, True)
        column.pack_start(renderer2, True)
        column.pack_end(renderer3, False)
        column.add_attribute(renderer0, 'icon-name', 1)
        column.add_attribute(renderer1, 'text', 2)
        column.add_attribute(renderer2, 'text', 3)
        column.add_attribute(renderer3, 'text', 4)
        column.set_expand(True)
        column.set_sizing(Gtk.TreeViewColumnSizing.FIXED)
        self.__view.append_column(column)
        self.add(self.__view)
        self.__signal_id = Lp().player.connect('current-changed',
                                               self.__on_current_changed)
        height = Lp().window.get_size()[1]
        self.set_size_request(400, height*0.7)

    def populate(self):
        """
            Populate popover
        """
        self.__model.clear()
        self.__populate(Lp().player.get_externals())

#######################
# PROTECTED           #
#######################
    def _on_row_activated(self, view, path, column):
        """
            Play selected track
            @param view as Gtk.TreeView
            @param path as Gtk.TreePath
            @param column as Gtk.TreeViewColumn
        """
        if path is not None:
            iterator = self.__model.get_iter(path)
            if iterator is not None:
                uri = self.__model.get_value(iterator, 0)
                Lp().player.play_this_external(uri)

#######################
# PRIVATE             #
#######################
    def __populate(self, tracks):
        """
            Populate popover
            @param tracks as [Track]
            @thread safe
        """
        for track in tracks:
            if track.duration == 0.0:
                try:
                    info = self.__tagreader.get_info(track.uri)
                    track_name = GLib.path_get_basename(
                                        GLib.filename_from_uri(track.uri)[0])
                    if info is not None:
                        tags = info.get_tags()
                        track.duration = info.get_duration()/1000000000
                        track.name = self.__tagreader.get_title(tags,
                                                                track_name)
                        track.artist_names = self.__tagreader.get_artists(tags)
                    else:
                        track.name = track_name
                except Exception as e:
                    print("ExternalsPopover::__populate(): %s" % e)
                    track.name = track_name
            GLib.idle_add(self.__add_track, track)

    def __add_track(self, track):
        """
            Add track to model
            @param track as Track
            @param filepath as string
        """
        if track.uri == Lp().player.current_track.uri:
            self.__model.append((track.uri, 'media-playback-start-symbolic',
                                track.artist, track.title,
                                seconds_to_string(track.duration)))
        else:
            self.__model.append((track.uri, '', track.artist, track.title,
                                seconds_to_string(track.duration)))

    def __on_self_unmap(self, widget):
        """
            Disconnect signals and destroy
            @param widget as Gtk.Widget
        """
        if self.__signal_id is not None:
            Lp().player.disconnect(self.__signal_id)
        GLib.idle_add(self.destroy)

    def __on_current_changed(self, player):
        """
            Update play symbol
            @param player as Player
        """
        for item in self.__model:
            if item[0] == player.current_track.uri:
                item[1] = 'media-playback-start-symbolic'
            else:
                item[1] = ''
class CollectionImporter:
    """
        Import files to main collection (as files)
    """
    def __init__(self):
        """
            Init collection scanner
        """
        self.__tag_reader = TagReader()

    def add(self, uris):
        """
            Add uris to collection
        """
        GLib.idle_add(App().window.container.progress.pulse, True)
        walk_uris = list(uris)
        while walk_uris:
            uri = walk_uris.pop(0)
            if not uri:
                continue
            try:
                f = Gio.File.new_for_uri(uri)
                file_type = f.query_file_type(Gio.FileQueryInfoFlags.NONE,
                                              None)
                if file_type == Gio.FileType.DIRECTORY:
                    infos = f.enumerate_children(
                        "standard::name,standard::type,standard::is-hidden",
                        Gio.FileQueryInfoFlags.NONE, None)
                    for info in infos:
                        f = infos.get_child(info)
                        child_uri = f.get_uri()
                        if info.get_is_hidden():
                            continue
                        elif info.get_file_type() == Gio.FileType.DIRECTORY:
                            walk_uris.append(child_uri)
                        else:
                            if is_audio(f):
                                self.__add_file(f)
                elif is_audio(f):
                    self.__add_file(f)
                else:
                    Logger.info("Not an audio file %s" % uri)
            except Exception as e:
                Logger.error("CollectionImporter::add(): %s" % e)
        GLib.idle_add(App().window.container.progress.pulse, False)

#######################
# PRIVATE             #
#######################

    def __add_file(self, f):
        """
            Add file to collection
            @param f as Gio.File
        """
        try:
            # We only import to primary collection
            music_uris = App().settings.get_music_uris()
            if music_uris:
                music_uri = music_uris[0]
            else:
                Logger.error("CollectionImporter::__add_file(): No collection")
                return
            info = self.__tag_reader.get_info(f.get_uri())
            tags = info.get_tags()
            name = f.get_basename()
            title = self.__tag_reader.get_title(tags, name)
            artists = self.__tag_reader.get_artists(tags)
            album_artists = self.__tag_reader.get_album_artist(tags)
            album_name = self.__tag_reader.get_album_name(tags)
            tracknumber = self.__tag_reader.get_tracknumber(tags, name)
            # If no artists tag, use album artist
            if album_artists == "":
                album_artists = artists
            if album_artists == "":
                album_artists = _("Unknown")
            extension = f.get_uri().split(".")[-1]
            dest_dir_uri = "%s/%s/%s" % (music_uri, album_artists, album_name)
            dest_dir = Gio.File.new_for_uri(dest_dir_uri)
            if not dest_dir.query_exists():
                dest_dir.make_directory_with_parents(None)
            if tracknumber == 0:
                dest_uri = "%s/%s.%s" % (dest_dir_uri, title, extension)
            else:
                dest_uri = "%s/%02d_%s.%s" % (dest_dir_uri, tracknumber, title,
                                              extension)
            dest = Gio.File.new_for_uri(dest_uri)
            f.copy(dest, Gio.FileCopyFlags.NONE, None, None, None)
        except Exception as e:
            Logger.error("CollectionImporter::__add_file(): %s" % e)
Пример #32
0
    def __save_track(self, item, persistent, album_artist, genre_ids):
        """
            Save item into collection as track
            @param item as SearchItem
            @param persistent as DbPersistent
            @param album artist as str
            @param genre ids as [int]
            @return (album id as int, track id as int)
        """
        t = TagReader()
        # Get uri from helpers
        for helper in self.__helpers:
            uri = helper.get_uri(item)
            if uri:
                break

        # Don"t found anything
        if not uri:
            return (None, None)

        # If album exists, is not in charts and we want to save
        # a charts track to this album, abort!
        # User already saved this album to collection,
        # may have removed some tracks, do not add them again!
        (exists, album_id) = item.album.exists_in_db()
        if exists:
            album_genre_ids = Lp().albums.get_genre_ids(album_id)
            if Type.CHARTS not in album_genre_ids and\
                    persistent == DbPersistent.CHARTS:
                return (None, None)

        # Check if track needs to be updated
        (exists, track_id) = item.exists_in_db()
        if exists:
            if Lp().tracks.get_persistent(track_id) == DbPersistent.NONE\
                    and persistent == DbPersistent.EXTERNAL:
                Lp().tracks.set_persistent(track_id, DbPersistent.EXTERNAL)
                return (None, None)
            # Do not mark as charts any local/web track
            track_genre_ids = Lp().tracks.get_genre_ids(track_id)
            if Type.CHARTS in track_genre_ids:
                album_id = Lp().tracks.get_album_id(track_id)
                with SqlCursor(Lp().db) as sql:
                    t.update_track(track_id, [], genre_ids, item.mtime)
                    t.update_album(album_id, [], genre_ids, item.album.mtime,
                                   None)
                    sql.commit()
                return (None, None)

        with SqlCursor(Lp().db) as sql:
            # Happen often with Itunes/Spotify
            if album_artist not in item.artists:
                item.artists.append(album_artist)
            artists = "; ".join(item.artists)
            artist_ids = t.add_artists(artists, album_artist, "")
            album_artist_ids = t.add_album_artists(album_artist, "")
            (album_id, new_album) = t.add_album(item.album.name,
                                                album_artist_ids, "", False, 0,
                                                0, True)
            # FIXME: Check this, could move this in add_album()
            if new_album:
                Lp().albums.set_synced(album_id, Type.NONE)

            if persistent == DbPersistent.CHARTS:
                genre_ids.append(Type.CHARTS)
                new_artist_ids = []
            else:
                new_artist_ids = list(set(artist_ids) | set(album_artist_ids))

            # Default genre id if missing
            if not genre_ids:
                genre_ids = t.add_genres("Web")

            # Add track to db
            track_id = Lp().tracks.add(item.name, uri, item.duration,
                                       item.tracknumber, item.discnumber, "",
                                       album_id, item.year, 0, 0, 0,
                                       persistent)
            t.update_track(track_id, artist_ids, genre_ids, item.mtime)
            t.update_album(album_id, album_artist_ids, genre_ids, item.mtime,
                           None)
            sql.commit()

        if persistent != DbPersistent.CHARTS:
            for genre_id in genre_ids:
                GLib.idle_add(Lp().scanner.emit, "genre-updated", genre_id,
                              True)
            for artist_id in new_artist_ids:
                GLib.idle_add(Lp().scanner.emit, "artist-updated", artist_id,
                              True)
        return (album_id, track_id)
 def __init__(self):
     """
         Init collection scanner
     """
     self.__tag_reader = TagReader()
Пример #34
0
    def __save_track(self, item, persistent, album_artist, genre_ids):
        """
            Save item into collection as track
            @param item as SearchItem
            @param persistent as DbPersistent
            @param album artist as str
            @param genre ids as [int]
            @return (album id as int, track id as int)
        """
        t = TagReader()
        # Get uri from helpers
        for helper in self.__helpers:
            uri = helper.get_uri(item)
            if uri:
                break

        # Don't found anything
        if not uri:
            return (None, None)

        # If album exists, is not in charts and we want to save
        # a charts track to this album, abort!
        # User already saved this album to collection,
        # may have removed some tracks, do not add them again!
        (exists, album_id) = item.album.exists_in_db()
        if exists:
            album_genre_ids = Lp().albums.get_genre_ids(album_id)
            if Type.CHARTS not in album_genre_ids and\
                    persistent == DbPersistent.CHARTS:
                        return (None, None)

        # Check if track needs to be updated
        (exists, track_id) = item.exists_in_db()
        if exists:
            if Lp().tracks.get_persistent(track_id) == DbPersistent.NONE\
                    and persistent == DbPersistent.EXTERNAL:
                Lp().tracks.set_persistent(track_id, DbPersistent.EXTERNAL)
                return (None, None)
            # Do not mark as charts any local/web track
            track_genre_ids = Lp().tracks.get_genre_ids(track_id)
            if Type.CHARTS in track_genre_ids:
                album_id = Lp().tracks.get_album_id(track_id)
                with SqlCursor(Lp().db) as sql:
                    t.update_track(track_id, [], genre_ids, item.mtime)
                    t.update_album(album_id, [], genre_ids, item.album.mtime,
                                   None)
                    sql.commit()
                return (None, None)

        with SqlCursor(Lp().db) as sql:
            # Happen often with Itunes/Spotify
            if album_artist not in item.artists:
                item.artists.append(album_artist)
            artists = "; ".join(item.artists)
            artist_ids = t.add_artists(artists, album_artist, "")
            album_artist_ids = t.add_album_artists(album_artist, "")
            (album_id, new_album) = t.add_album(item.album.name,
                                                album_artist_ids, "",
                                                False, 0,
                                                0, True)
            # FIXME: Check this, could move this in add_album()
            if new_album:
                Lp().albums.set_synced(album_id, Type.NONE)

            if persistent == DbPersistent.CHARTS:
                genre_ids.append(Type.CHARTS)
                new_artist_ids = []
            else:
                new_artist_ids = list(set(artist_ids) | set(album_artist_ids))

            # Default genre id if missing
            if not genre_ids:
                genre_ids = t.add_genres("Web")

            # Add track to db
            track_id = Lp().tracks.add(item.name, uri, item.duration,
                                       item.tracknumber, item.discnumber,
                                       "", album_id,
                                       item.year, 0,
                                       0, 0, persistent)
            t.update_track(track_id, artist_ids, genre_ids, item.mtime)
            t.update_album(album_id, album_artist_ids,
                           genre_ids, item.mtime, None)
            sql.commit()

        if persistent != DbPersistent.CHARTS:
            for genre_id in genre_ids:
                GLib.idle_add(Lp().scanner.emit,
                              'genre-updated', genre_id, True)
            for artist_id in new_artist_ids:
                GLib.idle_add(Lp().scanner.emit,
                              'artist-updated', artist_id, True)
        return (album_id, track_id)