Hello community, here is the log from the commit of package lollypop for openSUSE:Factory checked in at 2017-10-17 01:53:11 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/lollypop (Old) and /work/SRC/openSUSE:Factory/.lollypop.new (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "lollypop" Tue Oct 17 01:53:11 2017 rev:30 rq:534157 version:0.9.304 Changes: -------- --- /work/SRC/openSUSE:Factory/lollypop/lollypop.changes 2017-10-09 19:48:23.999112323 +0200 +++ /work/SRC/openSUSE:Factory/.lollypop.new/lollypop.changes 2017-10-17 01:53:14.544398696 +0200 @@ -1,0 +2,8 @@ +Mon Oct 16 08:32:43 UTC 2017 - [email protected] + +- Update to version 0.9.303: + + Make lollypop-cli working again + + Do not remove tracks if collection does not exist +- Drop lollypop-libexecdir-location.patch, fixed upstream. + +------------------------------------------------------------------- Old: ---- lollypop-0.9.303.tar.xz lollypop-libexecdir-location.patch New: ---- lollypop-0.9.304.tar.xz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ lollypop.spec ++++++ --- /var/tmp/diff_new_pack.QPM668/_old 2017-10-17 01:53:15.532352422 +0200 +++ /var/tmp/diff_new_pack.QPM668/_new 2017-10-17 01:53:15.536352234 +0200 @@ -19,15 +19,13 @@ %global gobject_introspection_version 1.35.9 %global gtk3_version 3.14 Name: lollypop -Version: 0.9.303 +Version: 0.9.304 Release: 0 Summary: GNOME music playing application License: GPL-3.0+ Group: Productivity/Multimedia/Sound/Players Url: http://gnumdk.github.io/lollypop-web/ Source0: https://github.com/gnumdk/lollypop/releases/download/%{version}/%{name}-%{version}.tar.xz -# PATCH-FIX-UPSTREAM lollypop-libexecdir-location.patch [email protected] -- Pick up libexecdir from option passed to meson instead of harcoding $prefix/libexecdir (we don't even use /usr/libexecdir) -Patch0: lollypop-libexecdir-location.patch BuildRequires: fdupes BuildRequires: gettext-runtime >= 0.19.7 BuildRequires: git-core @@ -102,7 +100,6 @@ %prep %setup -q -%patch0 -p1 %build %meson ++++++ lollypop-0.9.303.tar.xz -> lollypop-0.9.304.tar.xz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/lollypop-0.9.303/lollypop/application.py new/lollypop-0.9.304/lollypop/application.py --- old/lollypop-0.9.303/lollypop/application.py 2017-10-05 16:27:17.000000000 +0200 +++ new/lollypop-0.9.304/lollypop/application.py 2017-10-15 15:32:41.000000000 +0200 @@ -34,7 +34,7 @@ LastFM = None from lollypop.utils import is_gnome, is_unity -from lollypop.define import Type, DataPath +from lollypop.define import Type, LOLLYPOP_DATA_PATH from lollypop.window import Window from lollypop.database import Database from lollypop.player import Player @@ -284,17 +284,17 @@ # Save albums context try: dump(self.player.context.genre_ids, - open(DataPath + "/genre_ids.bin", "wb")) + open(LOLLYPOP_DATA_PATH + "/genre_ids.bin", "wb")) dump(self.player.context.artist_ids, - open(DataPath + "/artist_ids.bin", "wb")) + open(LOLLYPOP_DATA_PATH + "/artist_ids.bin", "wb")) self.player.shuffle_albums(False) dump(self.player.get_albums(), - open(DataPath + "/albums.bin", "wb")) + open(LOLLYPOP_DATA_PATH + "/albums.bin", "wb")) except Exception as e: print("Application::__save_state()", e) - dump(track_id, open(DataPath + "/track_id.bin", "wb")) + dump(track_id, open(LOLLYPOP_DATA_PATH + "/track_id.bin", "wb")) dump([self.player.is_playing, self.player.is_party], - open(DataPath + "/player.bin", "wb")) + open(LOLLYPOP_DATA_PATH + "/player.bin", "wb")) # Save current playlist if self.player.current_track.id == Type.RADIOS: playlist_ids = [Type.RADIOS] @@ -303,12 +303,12 @@ else: playlist_ids = self.player.get_user_playlist_ids() dump(playlist_ids, - open(DataPath + "/playlist_ids.bin", "wb")) + open(LOLLYPOP_DATA_PATH + "/playlist_ids.bin", "wb")) if self.player.current_track.id is not None: position = self.player.position else: position = 0 - dump(position, open(DataPath + "/position.bin", "wb")) + dump(position, open(LOLLYPOP_DATA_PATH + "/position.bin", "wb")) self.player.stop_all() self.window.stop_all() diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/lollypop-0.9.303/lollypop/collectionscanner.py new/lollypop-0.9.304/lollypop/collectionscanner.py --- old/lollypop-0.9.303/lollypop/collectionscanner.py 2017-10-05 16:27:17.000000000 +0200 +++ new/lollypop-0.9.304/lollypop/collectionscanner.py 2017-10-15 15:32:41.000000000 +0200 @@ -103,6 +103,7 @@ None) except Exception as e: print("CollectionScanner::__get_objects_for_uris():", e) + ignore_dirs.append(uri) continue for info in infos: f = infos.get_child(info) @@ -249,7 +250,7 @@ performers = self.get_performers(tags) a_sortnames = self.get_artist_sortnames(tags) aa_sortnames = self.get_album_artist_sortnames(tags) - album_artists = self.get_album_artist(tags) + album_artists = self.get_album_artists(tags) album_name = self.get_album_name(tags) genres = self.get_genres(tags) discnumber = self.get_discnumber(tags) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/lollypop-0.9.303/lollypop/database_artists.py new/lollypop-0.9.304/lollypop/database_artists.py --- old/lollypop-0.9.303/lollypop/database_artists.py 2017-10-05 16:27:17.000000000 +0200 +++ new/lollypop-0.9.304/lollypop/database_artists.py 2017-10-15 15:32:41.000000000 +0200 @@ -78,9 +78,15 @@ @param Artist name as string @return Artist id as int """ + # Special case, id name is fully uppercase, do not use NOCASE + # We want to have a different artist with SqlCursor(Lp().db) as sql: - result = sql.execute("SELECT rowid from artists\ - WHERE name=? COLLATE NOCASE", (name,)) + if name.isupper(): + result = sql.execute("SELECT rowid from artists\ + WHERE name=?", (name,)) + else: + result = sql.execute("SELECT rowid from artists\ + WHERE name=? COLLATE NOCASE", (name,)) v = result.fetchone() if v is not None: return v[0] diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/lollypop-0.9.303/lollypop/define.py new/lollypop-0.9.304/lollypop/define.py --- old/lollypop-0.9.303/lollypop/define.py 2017-10-05 16:27:17.000000000 +0200 +++ new/lollypop-0.9.304/lollypop/define.py 2017-10-15 15:32:41.000000000 +0200 @@ -13,11 +13,9 @@ # This is global object initialised at lollypop start # member init order is important! -from gi.repository import Gio +from gi.repository import Gio, GLib -from os import path - -DataPath = path.expanduser("~") + "/.local/share/lollypop" +LOLLYPOP_DATA_PATH = GLib.get_user_data_dir() + "/lollypop" Lp = Gio.Application.get_default diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/lollypop-0.9.303/lollypop/player.py new/lollypop-0.9.304/lollypop/player.py --- old/lollypop-0.9.303/lollypop/player.py 2017-10-05 16:27:17.000000000 +0200 +++ new/lollypop-0.9.304/lollypop/player.py 2017-10-15 15:32:41.000000000 +0200 @@ -24,7 +24,7 @@ from lollypop.player_userplaylist import UserPlaylistPlayer from lollypop.radios import Radios from lollypop.objects import Track, Album -from lollypop.define import Lp, Type, NextContext, DataPath, Shuffle +from lollypop.define import Lp, Type, NextContext, LOLLYPOP_DATA_PATH, Shuffle class Player(BinPlayer, QueuePlayer, UserPlaylistPlayer, RadioPlayer, @@ -362,10 +362,14 @@ """ try: if Lp().settings.get_value("save-state"): - track_id = load(open(DataPath + "/track_id.bin", "rb")) - playlist_ids = load(open(DataPath + "/playlist_ids.bin", - "rb")) - (is_playing, was_party) = load(open(DataPath + "/player.bin", + track_id = load(open(LOLLYPOP_DATA_PATH + + "/track_id.bin", + "rb")) + playlist_ids = load(open(LOLLYPOP_DATA_PATH + + "/playlist_ids.bin", + "rb")) + (is_playing, was_party) = load(open(LOLLYPOP_DATA_PATH + + "/player.bin", "rb")) if playlist_ids and playlist_ids[0] == Type.RADIOS: radios = Radios() @@ -409,14 +413,17 @@ self.emit("party-changed", True) else: self._albums = load(open( - DataPath + "/albums.bin", + LOLLYPOP_DATA_PATH + + "/albums.bin", "rb")) self.shuffle_albums(True) self._context.genre_ids = load(open( - DataPath + "/genre_ids.bin", + LOLLYPOP_DATA_PATH + + "/genre_ids.bin", "rb")) self._context.artist_ids = load(open( - DataPath + "/artist_ids.bin", + LOLLYPOP_DATA_PATH + + "/artist_ids.bin", "rb")) self.set_next() self.set_prev() diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/lollypop-0.9.303/lollypop/tagreader.py new/lollypop-0.9.304/lollypop/tagreader.py --- old/lollypop-0.9.303/lollypop/tagreader.py 2017-10-05 16:27:17.000000000 +0200 +++ new/lollypop-0.9.304/lollypop/tagreader.py 2017-10-15 15:32:41.000000000 +0200 @@ -16,8 +16,8 @@ from gettext import gettext as _ -from lollypop.define import Lp -from lollypop.utils import format_artist_name, decode_all +from lollypop.define import Lp, ENCODING +from lollypop.utils import format_artist_name class Discoverer: @@ -155,9 +155,9 @@ sortnames.append(read) return "; ".join(sortnames) - def get_album_artist(self, tags): + def get_album_artists(self, tags): """ - Return album artist for tags + Return album artists for tags @param tags as Gst.TagList @return album artist as string or None """ @@ -325,6 +325,27 @@ @parma tags as Gst.TagList @return lyrics as str """ + def decode_lyrics(bytes): + try: + lyrics = b"" + if bytes[0:4] == b"TXXX": + if bytes[13:24] == b"L\x00y\x00r\x00i\x00c\x00s": + lyrics = bytes[29:].replace(b"\x00", b"") + else: + return None + elif bytes[0:4] == b"USLT": + lyrics = bytes.split(b"\xff\xfe")[2].replace(b"\x00", b"") + else: + return None + for encoding in ENCODING: + try: + return lyrics.decode(encoding) + except: + pass + except: + pass + return None + def get_mp4(): try: (exists, sample) = tags.get_string_index("lyrics", 0) @@ -346,10 +367,9 @@ (exists, m) = sample.get_buffer().map(Gst.MapFlags.READ) if not exists: continue - string = decode_all(m.data) - if string.startswith("USLT"): - split = string.split("\x00") - return "".join(split[5:-1]) + string = decode_lyrics(m.data) + if string is not None: + return string except Exception as e: print("TagReader::get_id3()", e) return "" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/lollypop-0.9.303/lollypop/toolbar.py new/lollypop-0.9.304/lollypop/toolbar.py --- old/lollypop-0.9.303/lollypop/toolbar.py 2017-10-05 16:27:17.000000000 +0200 +++ new/lollypop-0.9.304/lollypop/toolbar.py 2017-10-15 15:32:41.000000000 +0200 @@ -12,7 +12,7 @@ from gi.repository import Gtk, Gst -from lollypop.define import Lp, WindowSize, DataPath +from lollypop.define import Lp, WindowSize, LOLLYPOP_DATA_PATH from lollypop.toolbar_playback import ToolbarPlayback from lollypop.toolbar_info import ToolbarInfo from lollypop.toolbar_title import ToolbarTitle @@ -122,7 +122,8 @@ try: if Lp().settings.get_value("save-state"): from pickle import load - position = load(open(DataPath + "/position.bin", "rb")) + position = load(open(LOLLYPOP_DATA_PATH + "/position.bin", + "rb")) self.__toolbar_title.add_mark(position / Gst.SECOND) except Exception as e: print("Toolbar::restore_state():", e) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/lollypop-0.9.303/lollypop/utils.py new/lollypop-0.9.304/lollypop/utils.py --- old/lollypop-0.9.303/lollypop/utils.py 2017-10-05 16:27:17.000000000 +0200 +++ new/lollypop-0.9.304/lollypop/utils.py 2017-10-15 15:32:41.000000000 +0200 @@ -16,21 +16,17 @@ import unicodedata from lollypop.helper_task import TaskHelper -from lollypop.define import Lp, Type, ENCODING +from lollypop.define import Lp, Type from lollypop.objects import Track -def decode_all(bytes): +def debug(str): + """ + Print debug + @param debug as str """ - Decode bytes trying all encodings - @param bytes as bytes - @return str - """ - for encoding in ENCODING: - try: - return bytes.decode(encoding) - except Exception as e: - print("decode_all():", e) + if Lp().debug is True: + print(str) def get_network_available(): @@ -63,15 +59,6 @@ c.isdigit() or c in ignore]).rstrip() -def debug(str): - """ - Print debug - @param debug as str - """ - if Lp().debug is True: - print(str) - - def is_unity(): """ Return True if desktop is Unity diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/lollypop-0.9.303/lollypop/widgets_rating.py new/lollypop-0.9.304/lollypop/widgets_rating.py --- old/lollypop-0.9.303/lollypop/widgets_rating.py 2017-10-05 16:27:17.000000000 +0200 +++ new/lollypop-0.9.304/lollypop/widgets_rating.py 2017-10-15 15:32:41.000000000 +0200 @@ -80,61 +80,29 @@ @param event as Gdk.Event (can be None) """ user_rating = True - stars = self.__object.get_rate() + rate = self.__object.get_rate() # -1 for compatiblity with previous release - if stars in [0, -1]: - stars = self.__object.get_popularity() + if rate in [0, -1]: + rate = self.__object.get_popularity() user_rating = False - if stars < 1: + if rate < 1: for i in range(5): self._stars[i].set_opacity(0.2) self._stars[i].get_style_context().remove_class("selected") else: - if stars >= 1: + star = self.__star_from_rate(rate) + # Select wanted star + for idx in range(0, star): + widget = self._stars[idx] if user_rating: - self._stars[0].get_style_context().add_class("selected") + widget.get_style_context().add_class("selected") else: - self._stars[0].get_style_context().remove_class("selected") - self._stars[0].set_opacity(0.8) - else: - self._stars[0].set_opacity(0.2) - self._stars[0].get_style_context().remove_class("selected") - if stars >= 2: - if user_rating: - self._stars[1].get_style_context().add_class("selected") - else: - self._stars[1].get_style_context().remove_class("selected") - self._stars[1].set_opacity(0.8) - else: - self._stars[1].set_opacity(0.2) - self._stars[1].get_style_context().remove_class("selected") - if stars >= 3: - if user_rating: - self._stars[2].get_style_context().add_class("selected") - else: - self._stars[2].get_style_context().remove_class("selected") - self._stars[2].set_opacity(0.8) - else: - self._stars[2].set_opacity(0.2) - self._stars[2].get_style_context().remove_class("selected") - if stars >= 4: - if user_rating: - self._stars[3].get_style_context().add_class("selected") - else: - self._stars[3].get_style_context().remove_class("selected") - self._stars[3].set_opacity(0.8) - else: - self._stars[3].set_opacity(0.2) - self._stars[3].get_style_context().remove_class("selected") - if stars >= 4.75: - if user_rating: - self._stars[4].get_style_context().add_class("selected") - else: - self._stars[4].get_style_context().remove_class("selected") - self._stars[4].set_opacity(0.8) - else: - self._stars[4].set_opacity(0.2) - self._stars[4].get_style_context().remove_class("selected") + widget.get_style_context().remove_class("selected") + widget.set_opacity(0.8) + # Unselect others + for idx in range(star, 5): + self._stars[idx].set_opacity(0.2) + self._stars[idx].get_style_context().remove_class("selected") def _on_button_press(self, widget, event): """ @@ -144,30 +112,61 @@ """ if Lp().scanner.is_locked(): return + user_rating = True + rate = self.__object.get_rate() # -1 for compatiblity with previous release - user_rating = self.__object.get_rate() not in [0, -1] + if rate in [0, -1]: + rate = self.__object.get_popularity() + user_rating = False + max_star = self.__star_from_rate(rate) event_star = widget.get_children()[0] if event_star in self._stars: position = self._stars.index(event_star) else: position = -1 pop = position + 1 - if pop == 0: + if pop == 0 or pop == max_star: if user_rating: self.__object.set_rate(Type.NONE) else: self.__object.set_popularity(0) + self._on_leave_notify(None, None) elif event.button == 1: self.__object.set_rate(pop) else: self.__object.set_popularity(pop) # Save to tags if needed - # FIXME We really need a radio object - # FIXME We look to kid3-cli here! if Lp().settings.get_value("save-to-tags") and\ - GLib.find_program_in_path("kid3-cli") is not None and\ isinstance(self.__object, Track) and\ self.__object.id >= 0: + dbus_helper = DBusHelper() + dbus_helper.call("CanSetCover", None, self.__on_can_set_cover, pop) + return True + +####################### +# PRIVATE # +####################### + def __star_from_rate(self, rate): + """ + Calculate stars from rate + @param rate as double + @return int + """ + star = min(5, int(rate)) + return star + + def __on_can_set_cover(self, source, result, pop): + """ + Remove album image from tags + @param source as GObject.Object + @param result as Gio.AsyncResult + @param pop as int + """ + try: + can_set_cover = source.call_finish(result) + except: + can_set_cover = False + if can_set_cover: if pop == 0: value = 0 elif pop == 1: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/lollypop-0.9.303/lollypop-cli.in new/lollypop-0.9.304/lollypop-cli.in --- old/lollypop-0.9.303/lollypop-cli.in 2017-10-05 16:27:17.000000000 +0200 +++ new/lollypop-0.9.304/lollypop-cli.in 2017-10-15 15:32:41.000000000 +0200 @@ -32,7 +32,7 @@ from lollypop.sqlcursor import SqlCursor from lollypop.tagreader import TagReader from lollypop.settings import Settings -from lollypop.define import Type, DbPersistent +from lollypop.define import Type from lollypop.playlists import Playlists import xml.etree.ElementTree as etree @@ -71,48 +71,12 @@ """ Show usage """ - print("usage: lollypop-cli youtube artist album track uri") - print("Allow user to add youtube tracks not available in search") - print("") print("usage: lollypop-cli export-playlists") print("Export playlists to m3u format in current directory") print("") print("usage: lollypop-cli import-rhythmbox") print("Import Rhythmbox stats") - def add_youtube(self, argv): - """ - Add youtube track - @param argv as [app, artist, album, title, url] - """ - artists = album_artist = sys.argv[2] - album = sys.argv[3] - title = sys.argv[4] - uri = sys.argv[5] - - t = TagReader() - with SqlCursor(self.db) as sql: - (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(album, - album_artist_ids, - "", 0, int(time())) - if new_album: - self.albums.set_synced(album_id, Type.NONE) - - (genre_ids, new_genre_ids) = t.add_genres("Youtube", album_id) - - track_id = self.tracks.add(title, uri, 0, - 0, 0, "", album_id, - None, 0, 0, 0, DbPersistent.EXTERNAL) - t.update_track(track_id, artist_ids, genre_ids) - t.update_album(album_id, album_artist_ids, genre_ids, None) - sql.commit() - def import_rhythmbox(self): """ Import rhythmbox stats diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/lollypop-0.9.303/meson.build new/lollypop-0.9.304/meson.build --- old/lollypop-0.9.303/meson.build 2017-10-05 16:27:17.000000000 +0200 +++ new/lollypop-0.9.304/meson.build 2017-10-15 15:32:41.000000000 +0200 @@ -1,5 +1,5 @@ project('lollypop', - version: '0.9.303', + version: '0.9.304', meson_version: '>= 0.40.0' ) i18n = import('i18n') diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/lollypop-0.9.303/subprojects/help/LINGUAS new/lollypop-0.9.304/subprojects/help/LINGUAS --- old/lollypop-0.9.303/subprojects/help/LINGUAS 1970-01-01 01:00:00.000000000 +0100 +++ new/lollypop-0.9.304/subprojects/help/LINGUAS 2017-10-15 15:32:45.000000000 +0200 @@ -0,0 +1,30 @@ +ca +cs +da +de +el +en_IE +eo +es +es_EC +fi +fr +ga +he +hu +id +it +ka +lt +nl +pl +pt_BR +pt_PT +ro +ru +sk +sr +sv +tr +tr_TR +uk diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/lollypop-0.9.303/subprojects/help/meson.build new/lollypop-0.9.304/subprojects/help/meson.build --- old/lollypop-0.9.303/subprojects/help/meson.build 2017-10-05 16:27:20.000000000 +0200 +++ new/lollypop-0.9.304/subprojects/help/meson.build 2017-10-15 15:32:45.000000000 +0200 @@ -13,22 +13,4 @@ ], media: 'figures/lollypop-logo.png', symlink_media: false, - languages: [ - 'ca', - 'cs', - 'de', - 'es', - 'fi', - 'fr', - 'he', - 'it', - 'nl', - 'pl', - 'pt_BR', - 'ru', - 'sk', - 'sr', - 'uk', - 'sv' - ], )
