diff -Nru unity-scope-audacious-0.1daily13.04.10ubuntu.unity.experimental.certified/data/audacious.scope.in unity-scope-audacious-0.1daily13.05.07ubuntu.unity.experimental.certified/data/audacious.scope.in --- unity-scope-audacious-0.1daily13.04.10ubuntu.unity.experimental.certified/data/audacious.scope.in 2013-04-10 07:14:42.000000000 +0000 +++ unity-scope-audacious-0.1daily13.05.07ubuntu.unity.experimental.certified/data/audacious.scope.in 2013-05-07 07:00:40.000000000 +0000 @@ -1,16 +1,16 @@ [Scope] DBusName=com.canonical.Unity.Scope.Music.Audacious DBusPath=/com/canonical/unity/scope/music/audacious -Icon= +Icon=/usr/share/unity/icons/lens-nav-music.svg QueryBinary=audacious _Keywords=audacious; RequiredMetadata= -OptionalMetadata= +OptionalMetadata=album[s];artist[s];genre[s];year[i];track_length[i];track_number[i] Loader=/usr/share/unity-scopes/audacious/unity_audacious_daemon.py RemoteContent=false Type=music _Name=Audacious -_Description=Find Audacious items +_Description=This is an Ubuntu search plugin that enables information from Audacious to be searched and displayed in the Dash underneath the Music header. If you do not wish to search this content source, you can disable this search plugin. _SearchHint=Search Audacious [Desktop Entry] diff -Nru unity-scope-audacious-0.1daily13.04.10ubuntu.unity.experimental.certified/debian/changelog unity-scope-audacious-0.1daily13.05.07ubuntu.unity.experimental.certified/debian/changelog --- unity-scope-audacious-0.1daily13.04.10ubuntu.unity.experimental.certified/debian/changelog 2013-05-07 16:48:18.000000000 +0000 +++ unity-scope-audacious-0.1daily13.05.07ubuntu.unity.experimental.certified/debian/changelog 2013-05-07 16:48:18.000000000 +0000 @@ -1,3 +1,10 @@ +unity-scope-audacious (0.1daily13.05.07ubuntu.unity.experimental.certified-0ubuntu1) raring; urgency=low + + * Automatic snapshot from revision 29 (ubuntu-unity/experimental- + certified) + + -- Ubuntu daily release Tue, 07 May 2013 07:00:52 +0000 + unity-scope-audacious (0.1daily13.04.10ubuntu.unity.experimental.certified-0ubuntu1) raring; urgency=low [ Mark Tully ] diff -Nru unity-scope-audacious-0.1daily13.04.10ubuntu.unity.experimental.certified/src/unity_audacious_daemon.py unity-scope-audacious-0.1daily13.05.07ubuntu.unity.experimental.certified/src/unity_audacious_daemon.py --- unity-scope-audacious-0.1daily13.04.10ubuntu.unity.experimental.certified/src/unity_audacious_daemon.py 2013-04-10 07:14:42.000000000 +0000 +++ unity-scope-audacious-0.1daily13.05.07ubuntu.unity.experimental.certified/src/unity_audacious_daemon.py 2013-05-07 07:00:40.000000000 +0000 @@ -70,12 +70,13 @@ m4 = {'id' :'year', 'type' :'i', 'field':Unity.SchemaFieldType.OPTIONAL} -EXTRA_METADATA = [m1, m2, m3, m4] - -REFRESH_TIMEOUT = 300 -PREVIEW_PLAYER_DBUS_NAME = "com.canonical.Unity.Lens.Music.PreviewPlayer" -PREVIEW_PLAYER_DBUS_PATH = "/com/canonical/Unity/Lens/Music/PreviewPlayer" -PREVIEW_PLAYER_DBUS_IFACE = PREVIEW_PLAYER_DBUS_NAME +m5 = {'id': 'track_length', + 'type': 'i', + 'field': Unity.SchemaFieldType.OPTIONAL} +m6 = {'id': 'track_number', + 'type': 'i', + 'field': Unity.SchemaFieldType.OPTIONAL} +EXTRA_METADATA = [m1, m2, m3, m4, m5, m6] tracks = [] @@ -88,10 +89,11 @@ title = "" artist = "" album = "" - year = "" + year = 0 genre = "" - tracknumber = "" - length = "" + tracknumber = 0 + length = 0 + global tracks tracks = [] for collection in os.listdir(AUDACIOUS_DBFILE): dbfile = '%s/%s' % (AUDACIOUS_DBFILE, collection) @@ -126,8 +128,9 @@ tracknumber = line[13:] if line.startswith("length="): length = line[7:] - track = [title, uri, artist, album, "taglib/mp3", year, genre, tracknumber, length] + track = [title, uri, artist, album, "taglib/mp3", int(year), genre, int(tracknumber), int(length) / 1000] tracks.append(track) + tracks.sort(key=lambda track: track[7]) return tracks @@ -171,7 +174,9 @@ Search for help documents matching the search string ''' results = [] - tracks = get_music_from_audacious() + global tracks + if len(tracks) == 0: + tracks = get_music_from_audacious() trackresults = [] albumresults = [] @@ -183,159 +188,75 @@ mimetype = "" if track[4] is None else track[4] albumartist = "" if track[5] is None else track[2] year = 0 if track[5] is None else int(track[5]) - genre = u"" if track[6] is None else track[6] + track_length = 0 if track[8] is None else track[8] + track_number = 0 if track[7] is None else track[7] + genre = "" if track[6] is None else track[6] trackname = title + " - " + album + " - " + artist if search.lower() in trackname.lower(): albumart = get_album_art(track) albumuri = "album://" + albumartist + "/" + album - if track not in trackresults: + if uri not in trackresults: results.append({'uri': uri, 'icon': albumart, 'category': 0, - 'mimetype': mimetype, 'title': title, - 'comment': artist, - 'album':GLib.Variant('s', album), - 'artist':GLib.Variant('s', artist), - 'genre':GLib.Variant('s', genre), - 'year':GLib.Variant('i', year)}) - trackresults.append(track) + 'album': GLib.Variant('s', album), + 'artist': GLib.Variant('s', artist), + 'genre': GLib.Variant('s', genre), + 'year': GLib.Variant('i', year), + 'track_length': GLib.Variant('i', track_length), + 'track_number': GLib.Variant('i', track_number)}) + trackresults.append(uri) - if album not in albumresults: + if albumuri not in albumresults: results.append({'uri': albumuri, 'icon': albumart, 'category': 1, - 'mimetype': mimetype, 'title': album, - 'comment': artist, 'album':GLib.Variant('s', album), 'artist':GLib.Variant('s', artist), 'genre':GLib.Variant('s', genre), - 'year':GLib.Variant('i', year)}) - albumresults.append(album) + 'year':GLib.Variant('i', year), + 'track_length': GLib.Variant('i', track_length), + 'track_number': GLib.Variant('i', track_number)}) + albumresults.append(albumuri) return results -def activate(scope, uri): - import subprocess - albumtracks = [] - albumtracks.append("audacious") - albumtracks.append("-E") - # If uri starts with album:// then we need to play all the songs on it - if uri.startswith("album://"): - for track in tracks: - album = "album://" + track[2] + "/" + track[3] - if not album.find(uri) == -1: - albumtrack = urllib.parse.unquote(str(track[1])) - albumtracks.append(albumtrack) - subprocess.Popen(albumtracks) - else: - albumtracks.append(uri) - subprocess.Popen(albumtracks) - return Unity.ActivationResponse(handled=Unity.HandledType.HIDE_DASH, goto_uri='') - +class Preview(Unity.ResultPreviewer): -def show_in_folder(scope, uri): - """ Shows the folder containing the selected track as requested from the Preview - """ - if uri.startswith("album://"): - for track in tracks: - album = "album://" + track[2] + "/" + track[3] - if not album.find(uri) == -1: - filename = track[1] - continue - else: - filename = uri - dirname = os.path.dirname(filename) - dirname = dirname.replace("%20", "\ ") - os.system("xdg-open '%s'" % str(dirname)) - return Unity.ActivationResponse(handled=Unity.HandledType.HIDE_DASH, goto_uri='') - - -def preview_uri(scope, uri): - """Preview request handler""" - albumtracks = [] - isalbum = False - if uri.startswith("album://"): - isalbum = True - for track in tracks: - album = "album://" + track[2] + "/" + track[3] - if not album.find(uri) == -1: - albumtracks.append(track) - albumtracks.sort(key=lambda track: int(track[7])) - else: - for track in tracks: - album = "file://" + track[1] - if not album.find(uri) == -1: - albumtracks.append(track) - iteration = model.get_first_iter() - end_iter = model.get_last_iter() - while iteration != end_iter: - if model.get_value(iteration, 0) == uri: - title = model.get_value(iteration, 5) - description = model.get_value(iteration, 6) - if model.get_value(iteration, 1) == "musique": - image = "file:///usr/share/icons/hicolor/scalable/apps/audacious.svg" - else: - image = "file://%s" % model.get_value(iteration, 1) + def do_run(self): + global tracks + album = self.result.metadata['album'].get_string() + artist = self.result.metadata['artist'].get_string() + preview = Unity.MusicPreview.new(self.result.title, '', None) + preview.props.image_source_uri = 'file://%s' % self.result.icon_hint + preview.props.subtitle = self.result.metadata['artist'].get_string() + if self.result.uri.startswith("album://"): + for track in tracks: + if album in track[3] and artist in track[2]: + track = Unity.TrackMetadata.full('file://%s' % track[1], + int(track[7]), + track[0], + track[2], + track[3], + track[8]) + preview.add_track(track) + else: + track = Unity.TrackMetadata.full('file://%s' % self.result.uri, + self.result.metadata['track_number'].get_int32(), + self.result.title, + self.result.metadata['artist'].get_string(), + self.result.metadata['album'].get_string(), + self.result.metadata['track_length'].get_int32()) + preview.add_track(track) + + view_action = Unity.PreviewAction.new("play", _("Play"), None) + preview.add_action(view_action) + show_action = Unity.PreviewAction.new("show", _("Show in Folder"), None) + preview.add_action(show_action) + return preview - preview = Unity.MusicPreview.new(title, description, None) - preview.props.image_source_uri = image - for albumtrack in albumtracks: - if isalbum: - track = Unity.TrackMetadata.full("file://" + urllib.parse.unquote(str(albumtrack[1])), # uri - int(albumtrack[7]), # track number - albumtrack[0], # track title - albumtrack[2], # artist - albumtrack[3], # album - int(albumtrack[8]) / 1000) # track length - else: - preview = Unity.MusicPreview.new(albumtrack[0], "", None) - preview.props.image_source_uri = image - track = Unity.TrackMetadata.full("file://" + urllib.parse.unquote(str(albumtrack[1])), - int(albumtrack[7]), - albumtrack[0], - albumtrack[2], - albumtrack[3], - int(albumtrack[8]) / 1000) - preview.add_track(track) - - # Add the "Play" action - play_action = Unity.PreviewAction.new("activate_uri", "Play", None) - play_action.connect("activated", activate) - preview.add_action(play_action) - - # Add the "Show in folder" action - show_action = Unity.PreviewAction.new("show_in_folder", "Show In Folder", None) - show_action.connect("activated", show_in_folder) - preview.add_action(show_action) - - preview.connect("play", play) - preview.connect("pause", pause) - preview.connect("closed", closed) - break - iteration = model.next(iteration) - if preview is None: - print("Couldn't find model row for requested preview uri: '%s'", uri) - return preview - - -def play(preview, uri): - """Plays the selected track as selected in the Preview""" - player = self.bus.get_object(PREVIEW_PLAYER_DBUS_NAME, PREVIEW_PLAYER_DBUS_PATH) - dbus.Interface(player, PREVIEW_PLAYER_DBUS_IFACE).Play(uri) - - -def pause(preview, uri): - """Pauses the selected track as selected in the Preview""" - player = self.bus.get_object(PREVIEW_PLAYER_DBUS_NAME, PREVIEW_PLAYER_DBUS_PATH) - dbus.Interface(player, PREVIEW_PLAYER_DBUS_IFACE).Pause() - - -def closed(preview): - """Stops playing when the previre is closed""" - player = self.bus.get_object(PREVIEW_PLAYER_DBUS_NAME, PREVIEW_PLAYER_DBUS_PATH) - dbus.Interface(player, PREVIEW_PLAYER_DBUS_IFACE).Close() # Classes below this point establish communication # with Unity, you probably shouldn't modify them. @@ -370,19 +291,8 @@ i['comment'] = '' if not 'dnd_uri' in i or not i['dnd_uri'] or i['dnd_uri'] == '': i['dnd_uri'] = i['uri'] - i['metadata'] = {} - if EXTRA_METADATA: - for e in i: - for m in EXTRA_METADATA: - if m['id'] == e: - i['metadata'][e] = i[e] - i['metadata']['provider_credits'] = GLib.Variant('s', PROVIDER_CREDITS) - result = Unity.ScopeResult.create(str(i['uri']), str(i['icon']), - i['category'], i['result_type'], - str(i['mimetype']), str(i['title']), - str(i['comment']), str(i['dnd_uri']), - i['metadata']) - result_set.add_result(result) + i['provider_credits'] = GLib.Variant('s', PROVIDER_CREDITS) + result_set.add_result(**i) except Exception as error: print(error) @@ -438,6 +348,39 @@ se = MySearch(search_context) return se + def do_activate(self, result, metadata, id): + album = result.metadata['album'].get_string() + artist = result.metadata['artist'].get_string() + global tracks + if id == 'show': + if result.uri.startswith("album://"): + for track in tracks: + if album in track[3] and artist in track[2]: + filename = tracks[1] + continue + else: + filename = result.uri + dirname = os.path.dirname(filename) + os.system("xdg-open '%s'" % str(dirname)) + else: + albumtracks = '' + if result.uri.startswith('album://'): + for track in tracks: + if album in track[3] and artist in track[2]: + albumtracks = albumtracks + ' \'%s\'' % (track[1]) + else: + albumtracks = '\'%s\'' % result.uri + print(albumtracks) + os.system('audacious -E %s' % albumtracks) + + return Unity.ActivationResponse(handled=Unity.HandledType.HIDE_DASH, goto_uri=None) + + def do_create_previewer(self, result, metadata): + rp = Preview() + rp.set_scope_result(result) + rp.set_search_metadata(metadata) + return rp + def load_scope(): return Scope() diff -Nru unity-scope-audacious-0.1daily13.04.10ubuntu.unity.experimental.certified/tests/test_audacious.py unity-scope-audacious-0.1daily13.05.07ubuntu.unity.experimental.certified/tests/test_audacious.py --- unity-scope-audacious-0.1daily13.04.10ubuntu.unity.experimental.certified/tests/test_audacious.py 2013-04-10 07:14:42.000000000 +0000 +++ unity-scope-audacious-0.1daily13.05.07ubuntu.unity.experimental.certified/tests/test_audacious.py 2013-05-07 07:00:40.000000000 +0000 @@ -11,17 +11,18 @@ self.results = [] def do_add_result(self, result): - self.results.append({'uri':result.uri, - 'title':result.title, - 'comment':result.comment, - 'icon':result.icon_hint}) + self.results.append({'uri': result.uri, + 'title': result.title, + 'comment': result.comment, + 'icon': result.icon_hint}) + class ScopeTestCase(TestCase): def init_scope(self, scope_path): self.scope_module = imp.load_source('scope', scope_path) self.scope = self.scope_module.load_scope() - def perform_query(self, query, filter_set = Unity.FilterSet.new()): + def perform_query(self, query, filter_set=Unity.FilterSet.new()): result_set = ResultSet() ctx = Unity.SearchContext.create(query, 0, filter_set, None, result_set, None) @@ -30,7 +31,7 @@ return result_set -class TestAskUbuntu(ScopeTestCase): +class TestAudacious(ScopeTestCase): def setUp(self): self.init_scope('src/unity_audacious_daemon.py') @@ -38,7 +39,7 @@ self.scope = None self.scope_module = None - def test_questions_search(self): + def test_search(self): self.scope_module.AUDACIOUS_DBFILE = 'tests/data/mock_audacious_pass' expected_results = ["/home/mark/Music/Bell X1/Flock/04. He Said She Said.mp3", "He Said She Said"] @@ -49,8 +50,7 @@ results.append(result_set.results[0]['title']) self.assertEqual(results, expected_results) - - def test_questions_failing_search(self): + def test_failing_search(self): self.scope_module.AUDACIOUS_DBFILE = 'tests/data/mock_audacious_fail' for s in ['upnriitnyt']: result_set = self.perform_query(s)