Merge lp:~dobey/ubuntu/natty/rhythmbox-ubuntuone-music-store/use-defer into lp:ubuntu/natty/rhythmbox-ubuntuone-music-store

Proposed by dobey
Status: Merged
Merged at revision: 56
Proposed branch: lp:~dobey/ubuntu/natty/rhythmbox-ubuntuone-music-store/use-defer
Merge into: lp:ubuntu/natty/rhythmbox-ubuntuone-music-store
Diff against target: 1180 lines (+377/-305)
15 files modified
MANIFEST (+0/-36)
MANIFEST.in (+5/-10)
PKG-INFO (+6/-4)
debian/changelog (+7/-0)
gst/__init__.py (+14/-0)
gst/pbutils.py (+6/-0)
po/rhythmbox-ubuntuone-music-store.pot (+0/-60)
rb.py (+36/-0)
rhythmdb.py (+12/-0)
run-tests (+24/-0)
setup.py (+12/-8)
umusicstore/MusicStoreWidget.py (+137/-100)
umusicstore/U1MSLinks.py (+107/-68)
umusicstore/__init__.py (+11/-9)
umusicstore/umusicstore.rb-plugin (+0/-10)
To merge this branch: bzr merge lp:~dobey/ubuntu/natty/rhythmbox-ubuntuone-music-store/use-defer
Reviewer Review Type Date Requested Status
Ubuntu branches Pending
Review via email: mp+44358@code.launchpad.net
To post a comment you must log in.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== removed file 'MANIFEST'
2--- MANIFEST 2010-08-26 01:47:45 +0000
3+++ MANIFEST 1970-01-01 00:00:00 +0000
4@@ -1,36 +0,0 @@
5-COPYING
6-MANIFEST
7-MANIFEST.in
8-README
9-setup.cfg
10-setup.py
11-po/POTFILES.in
12-po/ca.po
13-po/cs.po
14-po/da.po
15-po/de.po
16-po/el.po
17-po/en_GB.po
18-po/es.po
19-po/eu.po
20-po/fi.po
21-po/fr.po
22-po/fy.po
23-po/gl.po
24-po/he.po
25-po/hr.po
26-po/ka.po
27-po/nl.po
28-po/pl.po
29-po/rhythmbox-ubuntuone-music-store.pot
30-po/ro.po
31-po/ru.po
32-po/sv.po
33-po/uk.po
34-umusicstore/MusicStoreWidget.py
35-umusicstore/U1MSLinks.py
36-umusicstore/__init__.py
37-umusicstore/empty.mp3
38-umusicstore/u1msurl.glade
39-umusicstore/umusicstore.rb-plugin
40-umusicstore/umusicstore.rb-plugin.in
41
42=== modified file 'MANIFEST.in'
43--- MANIFEST.in 2010-07-21 16:03:11 +0000
44+++ MANIFEST.in 2010-12-21 15:44:57 +0000
45@@ -1,10 +1,5 @@
46-include COPYING README
47-include MANIFEST.in MANIFEST
48-include po/*
49-include umusicstore/umusicstore.rb-plugin*
50-include umusicstore/empty.mp3
51-include umusicstore/musicstore_icon.png
52-include umusicstore/__init__.py
53-include umusicstore/MusicStoreWidget.py
54-include umusicstore/U1MSLinks.py
55-include umusicstore/u1msurl.glade
56+include COPYING MANIFEST.in README
57+include run-tests rb.py rhythmdb.py
58+recursive-include gst *.py
59+recursive-include po *.po POTFILES.in
60+recursive-include umusicstore *.py *.glade *.mp3 *.rb-plugin.in
61
62=== modified file 'PKG-INFO'
63--- PKG-INFO 2010-10-07 13:09:46 +0000
64+++ PKG-INFO 2010-12-21 15:44:57 +0000
65@@ -1,11 +1,13 @@
66 Metadata-Version: 1.1
67 Name: rhythmbox-ubuntuone-music-store
68-Version: 0.1.9
69-Summary: Ubuntu One Music Store Rhythmbox plugin
70+Version: 0.1.10
71+Summary: Ubuntu One Music Store Rhythmbox plug-in
72 Home-page: https://launchpad.net/rhythmbox-ubuntuone-music-store
73 Author: Stuart Langridge
74 Author-email: stuart.langridge@canonical.com
75 License: LGPL v3
76-Description: A Rhythmbox plugin that makes the Ubuntu Music Store available in Rhythmbox.
77+Description: A plug-in to access the Ubuntu One Music Store in Rhythmbox.
78 Platform: UNKNOWN
79-Requires: DistUtilsExtra.auto
80+Provides: gst
81+Provides: rb
82+Provides: rhythmdb
83
84=== modified file 'debian/changelog'
85--- debian/changelog 2010-12-21 10:32:15 +0000
86+++ debian/changelog 2010-12-21 15:44:57 +0000
87@@ -1,3 +1,10 @@
88+rhythmbox-ubuntuone-music-store (0.1.10-0ubuntu1) natty; urgency=low
89+
90+ * New upstream release.
91+ - Handle the defer API being split out from aptdaemon. (LP: #691647)
92+
93+ -- Rodney Dawes <rodney.dawes@ubuntu.com> Tue, 21 Dec 2010 10:37:55 -0500
94+
95 rhythmbox-ubuntuone-music-store (0.1.9-0ubuntu2) natty; urgency=low
96
97 * debian/control: add Depends on python-defer (LP: #691647)
98
99=== added directory 'gst'
100=== added file 'gst/__init__.py'
101--- gst/__init__.py 1970-01-01 00:00:00 +0000
102+++ gst/__init__.py 2010-12-21 15:44:57 +0000
103@@ -0,0 +1,14 @@
104+"""Fake gst.py module for testing."""
105+
106+STATE_NULL = 0
107+STATE_PLAYING = 1
108+
109+
110+def parse_launch(*args, **kwargs):
111+ """Fake parse_launch."""
112+ return
113+
114+
115+def update_registry(*args, **kwargs):
116+ """Fake update_registry."""
117+ return
118
119=== added file 'gst/pbutils.py'
120--- gst/pbutils.py 1970-01-01 00:00:00 +0000
121+++ gst/pbutils.py 2010-12-21 15:44:57 +0000
122@@ -0,0 +1,6 @@
123+"""Fake pbutils module for testing."""
124+
125+
126+def is_missing_plugin_message(*args, **kwargs):
127+ """Fake is_missing_plugin_message."""
128+ return
129
130=== removed file 'po/rhythmbox-ubuntuone-music-store.pot'
131--- po/rhythmbox-ubuntuone-music-store.pot 2010-04-01 17:30:54 +0000
132+++ po/rhythmbox-ubuntuone-music-store.pot 1970-01-01 00:00:00 +0000
133@@ -1,60 +0,0 @@
134-# SOME DESCRIPTIVE TITLE.
135-# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
136-# This file is distributed under the same license as the PACKAGE package.
137-# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
138-#
139-#, fuzzy
140-msgid ""
141-msgstr ""
142-"Project-Id-Version: PACKAGE VERSION\n"
143-"Report-Msgid-Bugs-To: \n"
144-"POT-Creation-Date: 2010-03-25 10:30+0100\n"
145-"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
146-"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
147-"Language-Team: LANGUAGE <LL@li.org>\n"
148-"MIME-Version: 1.0\n"
149-"Content-Type: text/plain; charset=CHARSET\n"
150-"Content-Transfer-Encoding: 8bit\n"
151-
152-#. Translators: this is the name under Music for U1 music in Rhythmbox
153-#: ../umusicstore/__init__.py:172
154-msgid "Purchased from Ubuntu One"
155-msgstr ""
156-
157-#: ../umusicstore/__init__.py:243
158-msgid "Ubuntu One"
159-msgstr ""
160-
161-#: ../umusicstore/__init__.py:288
162-msgid "MP3 plugins are not installed"
163-msgstr ""
164-
165-#: ../umusicstore/__init__.py:293
166-msgid ""
167-"To listen to your purchased songs, you need to install MP3 plugins. Click "
168-"below to install them."
169-msgstr ""
170-
171-#: ../umusicstore/__init__.py:298
172-msgid "Install MP3 plugins"
173-msgstr ""
174-
175-#: ../umusicstore/__init__.py:320
176-msgid "Installing MP3 plugins"
177-msgstr ""
178-
179-#: ../umusicstore/__init__.py:340
180-msgid "There was a problem installing, sorry"
181-msgstr ""
182-
183-#: ../umusicstore/__init__.py:343
184-msgid "Check your internet connection and try again."
185-msgstr ""
186-
187-#: ../umusicstore/umusicstore.rb-plugin.in.h:1
188-msgid "The Ubuntu One Music Store"
189-msgstr ""
190-
191-#: ../umusicstore/umusicstore.rb-plugin.in.h:2
192-msgid "Ubuntu One Music Store"
193-msgstr ""
194
195=== added file 'rb.py'
196--- rb.py 1970-01-01 00:00:00 +0000
197+++ rb.py 2010-12-21 15:44:57 +0000
198@@ -0,0 +1,36 @@
199+"""Fake rb.py for use in testing."""
200+
201+SOURCE_GROUP_CATEGORY_FIXED = 0
202+
203+
204+class Plugin(object):
205+ """Fake Plugin class for testing."""
206+
207+ def __init__(self, *args, **kwargs):
208+ super(Plugin, self).__init__()
209+
210+ def find_file(self, *args, **kwargs):
211+ """Fake find_file method."""
212+ pass
213+
214+
215+class Source(object):
216+ """Fake Source class for testing."""
217+
218+ add = __fake_it
219+ remove = __fake_it
220+ show_all = __fake_it
221+ do_impl_activate = __fake_it
222+
223+ def __fake_it(self, *args, **kwargs):
224+ """Fake method."""
225+
226+
227+def rb_source_group_get_by_name(*args, **kwargs):
228+ """Fake method."""
229+ return
230+
231+
232+def rb_source_group_register(*args, **kwargs):
233+ """Fake method."""
234+ return
235
236=== added file 'rhythmdb.py'
237--- rhythmdb.py 1970-01-01 00:00:00 +0000
238+++ rhythmdb.py 2010-12-21 15:44:57 +0000
239@@ -0,0 +1,12 @@
240+"""Fake rhythmdb.py for use in testing."""
241+
242+PROP_ARTIST = 0
243+PROP_TITLE = 1
244+PROP_ALBUM = 2
245+
246+
247+class EntryType(object):
248+ """Fake EntryType object."""
249+
250+ def __init__(self, *args, **kwargs):
251+ super(EntryType, self).__init__()
252
253=== added file 'run-tests'
254--- run-tests 1970-01-01 00:00:00 +0000
255+++ run-tests 2010-12-21 15:44:57 +0000
256@@ -0,0 +1,24 @@
257+#!/bin/bash
258+# Author: Natalia Bidart <natalia.bidart@canonical.com>
259+#
260+# Copyright 2010 Canonical Ltd.
261+#
262+# This program is free software: you can redistribute it and/or modify it
263+# under the terms of the GNU General Public License version 3, as published
264+# by the Free Software Foundation.
265+#
266+# This program is distributed in the hope that it will be useful, but
267+# WITHOUT ANY WARRANTY; without even the implied warranties of
268+# MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
269+# PURPOSE. See the GNU General Public License for more details.
270+#
271+# You should have received a copy of the GNU General Public License along
272+# with this program. If not, see <http://www.gnu.org/licenses/>.
273+export PYTHONPATH=umusicstore
274+u1lint .
275+if [ -x `which pep8` ]; then
276+ pep8 --repeat .
277+else
278+ echo "Please install the 'pep8' package."
279+fi
280+rm -rf _trial_temp
281
282=== modified file 'setup.py' (properties changed: -x to +x)
283--- setup.py 2010-10-07 13:09:46 +0000
284+++ setup.py 2010-12-21 15:44:57 +0000
285@@ -1,18 +1,22 @@
286+#!/usr/bin/python
287+"""Setup script for Ubuntu One Music Store plug-in for Rhythmbox."""
288
289 import DistUtilsExtra.auto
290
291 DistUtilsExtra.auto.setup(
292 name='rhythmbox-ubuntuone-music-store',
293- version='0.1.9',
294+ version='0.1.10',
295 license='LGPL v3',
296 author='Stuart Langridge',
297 author_email='stuart.langridge@canonical.com',
298- description='Ubuntu One Music Store Rhythmbox plugin',
299- long_description='A Rhythmbox plugin that makes the Ubuntu Music Store available in Rhythmbox.',
300+ description='Ubuntu One Music Store Rhythmbox plug-in',
301+ long_description=('A plug-in to access the Ubuntu One Music Store '
302+ 'in Rhythmbox.'),
303 url='https://launchpad.net/rhythmbox-ubuntuone-music-store',
304- data_files = [('/usr/lib/rhythmbox/plugins/umusicstore', ['umusicstore/__init__.py',
305- 'umusicstore/empty.mp3',
306- 'umusicstore/MusicStoreWidget.py',
307- 'umusicstore/U1MSLinks.py',
308- 'umusicstore/u1msurl.glade'])],
309+ data_files=[('/usr/lib/rhythmbox/plugins/umusicstore',
310+ ['umusicstore/__init__.py',
311+ 'umusicstore/empty.mp3',
312+ 'umusicstore/MusicStoreWidget.py',
313+ 'umusicstore/U1MSLinks.py',
314+ 'umusicstore/u1msurl.glade'])],
315 )
316
317=== modified file 'umusicstore/MusicStoreWidget.py'
318--- umusicstore/MusicStoreWidget.py 2010-10-07 13:09:46 +0000
319+++ umusicstore/MusicStoreWidget.py 2010-12-21 15:44:57 +0000
320@@ -16,39 +16,59 @@
321 #
322 # Authored by Stuart Langridge <stuart.langridge@canonical.com>
323
324-
325-import gtk, gobject, os, urllib, gconf, stat, urlparse, gio
326-import gst, gst.pbutils
327+# pylint: disable=W0201
328+
329+# Import these here as gtk/gio import ordering seems to matter
330+import gobject
331+import gtk
332+import gio
333+
334 import aptdaemon.client
335-from aptdaemon import policykit1
336-from aptdaemon.defer import inline_callbacks
337-from aptdaemon.enums import *
338-from aptdaemon.gtkwidgets import AptErrorDialog, \
339- AptProgressBar
340-from commands import getstatusoutput
341-import rb, rhythmdb
342-from ubuntuone.gtkwidgets import MusicStore as U1MusicStore
343-import xdg.BaseDirectory
344 import dbus
345 import dbus.exceptions
346-
347+import gconf
348 import gettext
349+import gst
350+import gst.pbutils
351+import os
352+# pylint: disable=F0401
353+import rb
354+import rhythmdb
355+# pylint: enable=F0401
356+import stat
357+import urllib
358+import urlparse
359+import xdg.BaseDirectory
360+
361+from aptdaemon import policykit1
362+try:
363+ from aptdaemon.defer import inline_callbacks
364+except ImportError:
365+ from defer import inline_callbacks
366+from aptdaemon.enums import EXIT_SUCCESS
367+from aptdaemon.gtkwidgets import AptProgressBar
368 from gettext import lgettext as _
369+from ubuntuone.gtkwidgets import MusicStore as U1MusicStore
370+
371 gettext.bindtextdomain("rhythmbox-ubuntuone-music-store", "/usr/share/locale")
372 gettext.textdomain("rhythmbox-ubuntuone-music-store")
373
374-MUSIC_STORE_WIDGET = U1MusicStore() # keep this around for later
375+MUSIC_STORE_WIDGET = U1MusicStore() # keep this around for later
376 U1LIBRARYPATH = MUSIC_STORE_WIDGET.get_library_location()
377 RB_LIBRARY_LOCATIONS = "/apps/rhythmbox/library_locations"
378 PARTNER_LIST = "canonical-partner-maverick.list"
379 SOURCES_DIR = "/etc/apt/sources.list.d/"
380 PLUGIN_PACKAGENAME = "gstreamer0.10-fluendo-plugins-mp3-partner"
381
382+
383 class U1EntryType(rhythmdb.EntryType):
384+ """Entry type for the Ubuntu One Music Store source."""
385+
386 def __init__(self):
387 rhythmdb.EntryType.__init__(self, name='ubuntuone')
388
389 def can_sync_metadata(self, entry):
390+ """Not a real source, so we can't sync metadata."""
391 return False
392
393
394@@ -57,37 +77,37 @@
395 def __init__(self, plugin, find_file):
396 self.plugin = plugin
397 self.find_file = find_file
398-
399+
400 def activate(self, shell):
401 """Plugin startup."""
402 self.db = shell.get_property("db")
403- group = rb.rb_source_group_get_by_name ("stores")
404+ group = rb.rb_source_group_get_by_name("stores")
405 if not group:
406- group = rb.rb_source_group_register ("stores",
407- "Stores",
408- rb.SOURCE_GROUP_CATEGORY_FIXED)
409-
410+ group = rb.rb_source_group_register("stores",
411+ "Stores",
412+ rb.SOURCE_GROUP_CATEGORY_FIXED)
413+
414 icon = gtk.IconTheme().load_icon(
415 "ubuntuone", gtk.icon_size_lookup(gtk.ICON_SIZE_MENU)[0], 0)
416
417 self.entry_type = U1EntryType()
418 self.db.register_entry_type(self.entry_type)
419
420- self.source = gobject.new (U1Source,
421- shell=shell,
422- entry_type=self.entry_type,
423- source_group=group,
424- icon=icon,
425- plugin=self.plugin)
426+ self.source = gobject.new(U1Source,
427+ shell=shell,
428+ entry_type=self.entry_type,
429+ source_group=group,
430+ icon=icon,
431+ plugin=self.plugin)
432 shell.register_entry_type_for_source(self.source, self.entry_type)
433 self.shell = shell
434 self.source.connect("preview-mp3", self.play_preview_mp3)
435 self.source.connect("play-library", self.play_library)
436 self.source.connect("download-finished", self.download_finished)
437 self.source.connect("url-loaded", self.url_loaded)
438-
439+
440 # Do these every time
441- shell.append_source(self.source, None) # Add the source to the list
442+ shell.append_source(self.source, None) # Add the source to the list
443 self.add_u1_library()
444
445 def deactivate(self, shell):
446@@ -96,18 +116,20 @@
447 self.source.delete_thyself()
448 # remove the library, if it's empty
449 try:
450- filecount = len(os.listdir(self.U1_LIBRARY_SYMLINK))
451+ filecount = len(os.listdir(self.u1_library_symlink))
452 except OSError:
453 # symlink is dangling
454 # so they never downloaded anything
455 filecount = 0
456 if filecount == 0:
457 client = gconf.client_get_default()
458- libraries = client.get_list(RB_LIBRARY_LOCATIONS, gconf.VALUE_STRING)
459+ libraries = client.get_list(RB_LIBRARY_LOCATIONS,
460+ gconf.VALUE_STRING)
461 if self.u1_library_path_url in libraries:
462 client.notify_remove(self.library_adder)
463 libraries.remove(self.u1_library_path_url)
464- client.set_list(RB_LIBRARY_LOCATIONS, gconf.VALUE_STRING, libraries)
465+ client.set_list(RB_LIBRARY_LOCATIONS,
466+ gconf.VALUE_STRING, libraries)
467 # delete held references
468 del self.db
469 del self.source
470@@ -116,24 +138,24 @@
471 def url_loaded(self, source, url):
472 """A URL is loaded in the plugin"""
473 print "URL loaded:", url
474- if urlparse.urlparse(url).scheme == "https":
475+ if urlparse.urlparse(url)[2] == "https":
476 pass
477 else:
478 pass
479-
480+
481 def _udf_path_to_library_uri(self, path):
482- """Calculate the path in the library.
483- Since the library is accessed via the created symlink, but the path
484- passed to us is to a file in the actual music store UDF, we need to
485+ """Calculate the path in the library.
486+ Since the library is accessed via the created symlink, but the path
487+ passed to us is to a file in the actual music store UDF, we need to
488 work out the path inside the library, i.e., what the path to that file
489 is via the symlink."""
490-
491 if path.startswith(U1LIBRARYPATH):
492 subpath = path[len(U1LIBRARYPATH):]
493 else:
494 subpath = path
495- if subpath.startswith("/"): subpath = subpath[1:]
496- library_path = os.path.join(self.U1_LIBRARY_SYMLINK, subpath)
497+ if subpath.startswith("/"):
498+ subpath = subpath[1:]
499+ library_path = os.path.join(self.u1_library_symlink, subpath)
500 # convert path to URI. Don't use urllib for this; Python and
501 # glib escape URLs differently. gio does it the glib way.
502 library_uri = gio.File(library_path).get_uri()
503@@ -150,11 +172,11 @@
504 """Switch to and start playing a song from the library"""
505 uri = self._udf_path_to_library_uri(path)
506 entry = self.shell.props.db.entry_lookup_by_location(uri)
507- if not entry:
508+ if not entry:
509 print "couldn't find entry", uri
510 return
511 libsrc = self.shell.props.library_source
512- genre_view, artist_view, album_view = libsrc.get_property_views()
513+ artist_view, album_view = libsrc.get_property_views()[0:]
514 song_view = libsrc.get_entry_view()
515 artist = self.shell.props.db.entry_get(entry, rhythmdb.PROP_ARTIST)
516 album = self.shell.props.db.entry_get(entry, rhythmdb.PROP_ALBUM)
517@@ -177,7 +199,7 @@
518 player = self.shell.get_player()
519 player.stop()
520 player.play_entry(entry, self.source)
521- # FIXME delete this entry when it finishes playing. Don't know how yet.
522+ # delete this entry when it finishes playing. Don't know how yet.
523
524 def add_u1_library(self):
525 """Add the U1 library if not listed in RB and re-add if changed."""
526@@ -187,11 +209,12 @@
527 os.chmod(u1_library_path_folder,
528 os.stat(u1_library_path_folder)[stat.ST_MODE] | stat.S_IWUSR)
529 # Translators: this is the name under Music for U1 music in Rhythmbox
530- u1_library_path = os.path.join(u1_library_path_folder, _("Purchased from Ubuntu One"))
531+ u1_library_path = os.path.join(u1_library_path_folder,
532+ _("Purchased from Ubuntu One"))
533 if not os.path.islink(u1_library_path):
534 if not os.path.exists(u1_library_path):
535- print "Attempting to symlink %s to %s" % (U1LIBRARYPATH,
536- u1_library_path)
537+ print "Attempting to symlink %s to %s" % (U1LIBRARYPATH,
538+ u1_library_path)
539 os.symlink(U1LIBRARYPATH, u1_library_path)
540 else:
541 # something that isn't a symlink already exists. That's not
542@@ -204,12 +227,13 @@
543 "delete or rename %s.") % (u1_library_path, U1LIBRARYPATH,
544 u1_library_path)
545 self.u1_library_path_url = "file://%s" % urllib.quote(u1_library_path)
546- self.U1_LIBRARY_SYMLINK = u1_library_path
547+ self.u1_library_symlink = u1_library_path
548 client = gconf.client_get_default()
549 self._add_u1_library_if_not_present(client)
550 self._remove_old_u1_library_if_present(client)
551 # Watch for changes to the gconf key and re-add the library
552- self.library_adder = client.notify_add(RB_LIBRARY_LOCATIONS,
553+ self.library_adder = client.notify_add(
554+ RB_LIBRARY_LOCATIONS,
555 self._add_u1_library_if_not_present)
556
557 def _add_u1_library_if_not_present(self, client, *args, **kwargs):
558@@ -217,7 +241,8 @@
559 libraries = client.get_list(RB_LIBRARY_LOCATIONS, gconf.VALUE_STRING)
560 if self.u1_library_path_url not in libraries:
561 libraries.append(self.u1_library_path_url)
562- client.set_list(RB_LIBRARY_LOCATIONS, gconf.VALUE_STRING, libraries)
563+ client.set_list(RB_LIBRARY_LOCATIONS,
564+ gconf.VALUE_STRING, libraries)
565
566 def _remove_old_u1_library_if_present(self, client, *args, **kwargs):
567 """Check for the old U1 library and remove it from libraries list."""
568@@ -243,46 +268,57 @@
569 # created under one name (say, English) and then had it created
570 # under another (say, after a translation to Dutch)
571 u1_library_path_folder = xdg.BaseDirectory.save_data_path("ubuntuone")
572- u1_library_path_folder_url = "file://%s" % urllib.quote(u1_library_path_folder)
573- symlink_url = "file://" + urllib.quote(self.U1_LIBRARY_SYMLINK)
574- for l in libraries:
575- if l.startswith(u1_library_path_folder_url) and l != symlink_url:
576- libraries.remove(l)
577+ u1_library_path_folder_url = "file://%s" % urllib.quote(
578+ u1_library_path_folder)
579+ symlink_url = "file://" + urllib.quote(self.u1_library_symlink)
580+ for lib in libraries:
581+ if lib.startswith(u1_library_path_folder_url) and \
582+ lib != symlink_url:
583+ libraries.remove(lib)
584 # and delete the symlink itself
585- symlink_to_remove = urllib.unquote(l[7:])
586+ symlink_to_remove = urllib.unquote(lib[7:])
587 os.unlink(symlink_to_remove)
588 removed = True
589 if removed:
590- client.set_list(RB_LIBRARY_LOCATIONS, gconf.VALUE_STRING, libraries)
591-
592-class U1Source(rb.Source):
593+ client.set_list(RB_LIBRARY_LOCATIONS,
594+ gconf.VALUE_STRING, libraries)
595+
596+
597+class U1Source(rb.Source, gobject.GObject):
598 """A Rhythmbox source widget for the U1 Music Store."""
599 # gproperties required so that rb.Source is instantiable
600 __gproperties__ = {
601- 'plugin': (rb.Plugin, 'plugin', 'plugin',
602- gobject.PARAM_WRITABLE|gobject.PARAM_CONSTRUCT_ONLY),
603- }
604- # we have the preview-mp3 signal; we receive it from the widget, and re-emit
605- # it so that the plugin gets it, because the plugin actually plays the mp3
606+ 'plugin': (rb.Plugin, 'plugin', 'plugin',
607+ gobject.PARAM_WRITABLE | gobject.PARAM_CONSTRUCT_ONLY),
608+ }
609+ # we have the preview-mp3 signal; we receive it from the widget, and
610+ # re-emit it so that the plugin gets it, because the plugin actually
611+ # plays the mp3
612 __gsignals__ = {
613- "preview-mp3": (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE, (str, str)),
614- "play-library": (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE, (str,)),
615- "download-finished": (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE, (str,)),
616- "url-loaded": (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE, (str,)),
617+ "preview-mp3": (gobject.SIGNAL_RUN_FIRST,
618+ gobject.TYPE_NONE, (str, str)),
619+ "play-library": (gobject.SIGNAL_RUN_FIRST,
620+ gobject.TYPE_NONE, (str,)),
621+ "download-finished": (gobject.SIGNAL_RUN_FIRST,
622+ gobject.TYPE_NONE, (str,)),
623+ "url-loaded": (gobject.SIGNAL_RUN_FIRST,
624+ gobject.TYPE_NONE, (str,)),
625 }
626-
627+
628 def __init__(self):
629 rb.Source.__init__(self, name=_("Ubuntu One"))
630+ gobject.GObject.__init__(self)
631 self.browser = MUSIC_STORE_WIDGET
632 self.__activated = False
633
634 def do_impl_activate(self):
635 """Source startup."""
636- if self.__activated: return
637+ if self.__activated:
638+ return
639 self.__activated = True
640 self.test_can_play_mp3()
641- rb.Source.do_impl_activate (self)
642-
643+ rb.Source.do_impl_activate(self)
644+
645 def do_impl_want_uri(self, uri):
646 """I want to handle u1ms URLs"""
647 if uri.startswith("u1ms://"):
648@@ -326,7 +362,7 @@
649 """Handler for end of stream from the check-mp3 pipeline.
650 If we reach the end of the stream, mp3 playback is enabled."""
651 self.install_pipeline.set_state(gst.STATE_NULL)
652- if os.environ.has_key("U1INSTALLMP3ANYWAY"):
653+ if os.environ.get("U1INSTALLMP3ANYWAY", None) is not None:
654 # override the decision not to install the package
655 self.install_mp3_playback()
656 else:
657@@ -349,7 +385,7 @@
658 self.install_label_body.set_alignment(0.0, 0.5)
659 self.install_label_eula = gtk.Label()
660 # EULA text copied from
661- # /var/lib/dpkg/info/gstreamer0.10-fluendo-plugins-mp3-partner.templates
662+ # gstreamer0.10-fluendo-plugins-mp3-partner.templates
663 # The partner package shows the EULA itself on installations, but
664 # aptdaemon installations work like DEBIAN_FRONTEND=noninteractive
665 # so we show the EULA here. (This also avoids a popup window.)
666@@ -365,7 +401,7 @@
667 "unless the seller has received a license by Fraunhofer IIS"
668 "and Thomson and pay the relevant royalties to them.</small>")
669 self.install_label_eula.set_alignment(0.0, 0.5)
670- self.install_label_eula.set_size_request(400,200)
671+ self.install_label_eula.set_size_request(400, 200)
672 self.install_label_eula.set_line_wrap(True)
673 self.install_hbtn = gtk.HButtonBox()
674 self.install_hbtn.set_layout(gtk.BUTTONBOX_END)
675@@ -403,11 +439,10 @@
676 dist="maverick",
677 comps=["partner"],
678 comment="added by U1MusicStoreWidget",
679- sourcesfile=PARTNER_LIST, defer=True)
680+ sourcesfile=PARTNER_LIST)
681 yield trans.run(defer=True)
682 trans = yield self.ac.update_cache(sources_list=SOURCES_DIR
683- + PARTNER_LIST,
684- defer=True)
685+ + PARTNER_LIST)
686 self.update_progress = AptProgressBar(trans)
687 self.update_progress.show()
688 self.install_label_head.set_text("")
689@@ -417,7 +452,7 @@
690 self.install_vbox.pack_start(self.update_progress, expand=False)
691 trans.connect("finished", self._package_update_finished)
692 yield trans.run(defer=True)
693- except Exception, e:
694+ except Exception, e: # pylint: disable=W0703
695 self._on_error(e)
696
697 @inline_callbacks
698@@ -428,8 +463,7 @@
699 self._on_error(transaction)
700 return
701 try:
702- trans = yield self.ac.install_packages([PLUGIN_PACKAGENAME],
703- defer=True)
704+ trans = yield self.ac.install_packages([PLUGIN_PACKAGENAME])
705 self.install_progress = AptProgressBar(transaction)
706 self.install_progress.show()
707 self.install_label_head.set_text("")
708@@ -439,7 +473,7 @@
709 self.install_vbox.pack_start(self.install_progress, expand=False)
710 trans.connect("finished", self._package_install_finished)
711 yield trans.run(defer=True)
712- except Exception, e:
713+ except Exception, e: # pylint: disable=W0703
714 self._on_error(e)
715
716 def _package_install_finished(self, trans, exit_code):
717@@ -449,7 +483,8 @@
718 gst.update_registry()
719 self.add_music_store_widget()
720 else:
721- self._on_error("Could not find the %r package" % PLUGIN_PACKAGENAME)
722+ self._on_error(
723+ "Could not find the %r package" % PLUGIN_PACKAGENAME)
724
725 def _on_error(self, error):
726 """Error handler for aptdaemon."""
727@@ -457,10 +492,10 @@
728 problem_installing = _("There was a problem installing, sorry")
729 self.install_label_head.set_markup('<span weight="bold" size="larger">'
730 '%s</span>' % problem_installing)
731- self.install_label_body.set_text(_('Check your internet connection and '
732- 'try again.'))
733- for widget in ("install_progress", "update_progress"):
734- widget = getattr(self, widget, None)
735+ self.install_label_body.set_text(_('Check your internet connection '
736+ 'and try again.'))
737+ for widget_name in ("install_progress", "update_progress"):
738+ widget = getattr(self, widget_name, None)
739 if widget is not None:
740 widget.hide()
741 self.install_hbtn.show()
742@@ -471,37 +506,39 @@
743 self.show_all()
744 self.browser.set_no_show_all(True)
745 self.browser.set_property("visible", True)
746- self.browser.connect("preview-mp3", self.re_emit_preview)
747- self.browser.connect("play-library", self.re_emit_playlibrary)
748- self.browser.connect("download-finished", self.re_emit_downloadfinished)
749- self.browser.connect("url-loaded", self.re_emit_urlloaded)
750+ self.browser.connect("preview-mp3",
751+ self.re_emit_preview)
752+ self.browser.connect("play-library",
753+ self.re_emit_playlibrary)
754+ self.browser.connect("download-finished",
755+ self.re_emit_downloadfinished)
756+ self.browser.connect("url-loaded",
757+ self.re_emit_urlloaded)
758
759- def do_impl_can_pause(self):
760+ def do_impl_can_pause(self):
761 """Implementation can pause.
762 If we don't handle this, Rhythmbox segfaults."""
763- return True # so we can pause, else we segfault
764+ return True # so we can pause, else we segfault
765
766 def re_emit_preview(self, widget, url, title):
767- """Handle the preview-mp3 signal and re-emit it to the rb.Plugin."""
768+ """Handle the preview-mp3 signal and re-emit it to rb.Plugin."""
769 self.emit("preview-mp3", url, title)
770
771 def re_emit_playlibrary(self, widget, path):
772- """Handle the play-library signal and re-emit it to the rb.Plugin."""
773+ """Handle the play-library signal and re-emit it to rb.Plugin."""
774 self.emit("play-library", path)
775
776 def re_emit_downloadfinished(self, widget, path):
777- """Handle the download-finished signal and re-emit it to the rb.Plugin."""
778+ """Handle the download-finished signal and re-emit it to rb.Plugin."""
779 self.emit("download-finished", path)
780
781 def re_emit_urlloaded(self, widget, url):
782- """Handle the url-loaded signal and re-emit it to the rb.Plugin."""
783+ """Handle the url-loaded signal and re-emit it to rb.Plugin."""
784 self.emit("url-loaded", url)
785
786- def do_set_property(self, property, value):
787+ def do_set_property(self, prop, value):
788 """Allow property settings to handle the plugin call."""
789- if property.name == 'plugin':
790+ if prop.name == 'plugin':
791 self.__plugin = value
792 else:
793- raise AttributeError, 'unknown property %s' % property.name
794-
795-
796+ raise AttributeError('unknown property %s' % prop.name)
797
798=== modified file 'umusicstore/U1MSLinks.py'
799--- umusicstore/U1MSLinks.py 2010-09-20 18:02:02 +0000
800+++ umusicstore/U1MSLinks.py 2010-12-21 15:44:57 +0000
801@@ -16,22 +16,35 @@
802 #
803 # Authored by Stuart Langridge <stuart.langridge@canonical.com>
804
805-import urllib, xml.parsers, cgi, os, locale, operator, re, unicodedata
806-import gtk, gio, glib
807-import rb, rhythmdb
808+# Import gtk+/gio bits here because order matters for some unknown reason
809+import glib
810+import gtk
811+import gio
812+
813+import cgi
814+import gettext
815+import locale
816+import operator
817+import os
818+import re
819+import rhythmdb
820+import unicodedata
821+import urllib
822+import xml.parsers
823+
824+from gettext import lgettext as _
825 from xml.dom import minidom
826+
827 try:
828 import gwibber.lib.gtk.widgets
829- gwibber_available = True
830+ GWIBBER_AVAILABLE = True
831 except ImportError:
832- gwibber_available = False
833+ GWIBBER_AVAILABLE = False
834
835-import gettext
836-from gettext import lgettext as _
837 gettext.bindtextdomain("U1MSURL", "/usr/share/locale")
838 gettext.textdomain("U1MSURL")
839
840-ui_str = \
841+UI_STR = \
842 """<ui>
843 <menubar name="MenuBar">
844 <menu name="ViewMenu" action="View">
845@@ -53,12 +66,10 @@
846 "the song in the Ubuntu One Music Store."),
847 "could-not-find": _("Unable to automatically find the song that is "
848 "currently playing in the Ubuntu One Music Store. "
849- "Please try searching manually."
850- ),
851+ "Please try searching manually."),
852 "could-not-connect": _("Unable to look up the song (couldn't connect "
853 "to Ubuntu One). Please check your internet "
854- "connection, or try again shortly.")
855-}
856+ "connection, or try again shortly.")}
857
858 BASE_URL = os.environ.get("U1MSLINK_BASE_URL", "https://one.ubuntu.com")
859 # getpreferredencoding isn't threadsafe, but we should be OK
860@@ -66,10 +77,11 @@
861 SCRUBBING_RE = re.compile(r"[\W\s]+", re.UNICODE)
862 CLEANING_RE = re.compile(r"\s+", re.UNICODE)
863
864-def normalize(a):
865+
866+def normalize(string):
867 """Normalize the given string, to increase the chances of a match"""
868 # rule #0 of unicode mangling: first, normalize
869- na = unicodedata.normalize('NFKD', a)
870+ na = unicodedata.normalize('NFKD', string)
871 # then, strip everything that's not alphanumeric
872 na = re.sub(SCRUBBING_RE, "", na)
873 # \w leaves _s
874@@ -79,39 +91,52 @@
875 # finally, lowercase
876 na = na.lower()
877 # if there's anything left, go with that, otherwise rollback
878- return na if na else a
879-
880-def modified_levenshtein(a,b):
881- """Calculates the Levenshtein distance between a and b, but counts added
882- characters as worth 0 (thus meaning that 'Foo' will match
883- 'Foo (Radio Edit)' with a high degree of accuracy.)"""
884- a = normalize(a)
885- b = normalize(b)
886- n, m = len(a), len(b)
887- if n > m:
888- # Make sure n <= m, to use O(min(n,m)) space
889- a,b = b,a
890- n,m = m,n
891-
892- current = range(n+1)
893- for i in range(1,m+1):
894- previous, current = current, [i]+[0]*n
895- for j in range(1,n+1):
896- add, delete = previous[j]+1, current[j-1]+1
897- change = previous[j-1]
898- if a[j-1] != b[i-1]:
899+ return na if na else string
900+
901+
902+def modified_levenshtein(start, end):
903+ """Calculates the Levenshtein distance between start and end,
904+ but counts added characters as worth 0 (thus meaning that 'Foo' will match
905+ 'Foo (Radio Edit)' with a high degree of accuracy.)"""
906+ start = normalize(start)
907+ end = normalize(end)
908+ ls, le = len(start), len(end)
909+ if ls > le:
910+ # Make sure ls <= le, to use O(min(ls, le)) space
911+ start, end = end, start
912+ ls, le = le, ls
913+
914+ current = range(ls + 1)
915+ for pose in range(1, le + 1):
916+ previous, current = current, [pose] + [0] * ls
917+ for poss in range(1, ls + 1):
918+ delete = current[poss - 1] + 1
919+ change = previous[poss - 1]
920+ if start[poss - 1] != end[pose - 1]:
921 change = change + 1
922 # replace add with 10000 to not count adds
923- current[j] = min(10000, delete, change)
924-
925- return current[n]
926+ current[poss] = min(10000, delete, change)
927+
928+ return current[ls]
929+
930
931 class U1MSLinkProvider(object):
932- """Get a public link for any playing song to buy it in
933+ """Get a public link for any playing song to buy it in
934 the Ubuntu One Music Store."""
935
936 def __init__(self, find_file):
937 self.find_file = find_file
938+ self.track_fetch = None
939+ self.artist_fetch = None
940+ self.win = None
941+ self.button = None
942+ self.action_group = None
943+ self.builder = None
944+ self.pvb = None
945+ self.tweet_button = None
946+ self.message = None
947+ self.ui_id = None
948+ self.image = None
949
950 def activate(self, shell):
951 """Plugin startup."""
952@@ -125,7 +150,7 @@
953 self.action_group = gtk.ActionGroup('U1MSLinkPluginActions')
954 self.action_group.add_action(action)
955 manager.insert_action_group(self.action_group, 0)
956- self.ui_id = manager.add_ui_from_string(ui_str)
957+ self.ui_id = manager.add_ui_from_string(UI_STR)
958 manager.ensure_update()
959
960 def deactivate(self, shell):
961@@ -136,6 +161,7 @@
962 manager.ensure_update()
963
964 def dialog_response_cb(self, dialog, response_id):
965+ """Destroy the window."""
966 self.win.destroy()
967 self.win = None
968
969@@ -173,8 +199,9 @@
970 _("Looking up <i>%s</i> by <i>%s</i> from <i>%s</i>") % (
971 cgi.escape(title), cgi.escape(artist), cgi.escape(album)))
972 self.lookup_artist(title, artist, album)
973-
974+
975 def display_error(self, messagename):
976+ """Display error text and a warning icon."""
977 self.builder.get_object("lblProgress").set_markup(ERRORS[messagename])
978 self.image.set_from_icon_name("dialog-warning",
979 gtk.ICON_SIZE_DIALOG)
980@@ -184,12 +211,13 @@
981 base_url = "http://api.7digital.com/1.2/artist/search"
982 params = {"q": artist.encode("utf-8", "replace"),
983 "oauth_consumer_key": "canonical",
984- "country":"GB"}
985+ "country": "GB"}
986 url = "%s?%s" % (base_url, urllib.urlencode(params))
987 self.artist_fetch = gio.File(url)
988- self.artist_fetch.read_async(self.artist_fetched,
989+ self.artist_fetch.read_async(
990+ self.artist_fetched,
991 user_data=(title, artist, album))
992-
993+
994 def artist_fetched(self, gdaemonfile, result, user_data):
995 """Artist query is complete"""
996 title, artist, album = user_data
997@@ -217,8 +245,7 @@
998 possibles.append((
999 anode.getAttribute("id"),
1000 modified_levenshtein(name, artist),
1001- name
1002- ))
1003+ name))
1004 possibles.sort(key=operator.itemgetter(1))
1005 if not possibles:
1006 self.display_error('could-not-find')
1007@@ -227,7 +254,7 @@
1008 artist_id = possibles[0][0]
1009 print "got artist %s" % possibles[0][2]
1010 self.lookup_track(title, artist, album, artist_id)
1011-
1012+
1013 def lookup_track(self, title, artist, album, artist_id):
1014 """Use the 7digital public API to look up the song."""
1015 # There is no way of searching the 7digital API and saying
1016@@ -238,7 +265,7 @@
1017 params = {"q": "%s %s" % (artist.encode("utf-8", "replace"),
1018 title.encode("utf-8", "replace")),
1019 "oauth_consumer_key": "canonical",
1020- "country":"GB", "pagesize": 50}
1021+ "country": "GB", "pagesize": 50}
1022 url = "%s?%s" % (base_url, urllib.urlencode(params))
1023 self.track_fetch = gio.File(url)
1024 self.track_fetch.read_async(self.track_fetched,
1025@@ -263,27 +290,35 @@
1026 possibles = []
1027 for tnode in tracknodes:
1028 anodes = tnode.getElementsByTagName("artist")
1029- if not anodes: continue
1030+ if not anodes:
1031+ continue
1032 aid = anodes[0].getAttribute("id")
1033 if aid == artist_id:
1034 artist_score = 0
1035 artist_name = artist
1036 else:
1037 atnodes = anodes[0].getElementsByTagName("name")
1038- if not atnodes: continue
1039- if not atnodes[0].hasChildNodes(): continue
1040+ if not atnodes:
1041+ continue
1042+ if not atnodes[0].hasChildNodes():
1043+ continue
1044 # a +100 penalty for not being the right artist
1045 artist_score = 100 + modified_levenshtein(
1046 atnodes[0].firstChild.nodeValue, artist)
1047 artist_name = atnodes[0].firstChild.nodeValue
1048 nnodes = tnode.getElementsByTagName("title")
1049- if not nnodes: continue
1050- if not nnodes[0].hasChildNodes(): continue
1051+ if not nnodes:
1052+ continue
1053+ if not nnodes[0].hasChildNodes():
1054+ continue
1055 rnodes = tnode.getElementsByTagName("release")
1056- if not rnodes: continue
1057+ if not rnodes:
1058+ continue
1059 rtnodes = rnodes[0].getElementsByTagName("title")
1060- if not rtnodes: continue
1061- if not rtnodes[0].hasChildNodes(): continue
1062+ if not rtnodes:
1063+ continue
1064+ if not rtnodes[0].hasChildNodes():
1065+ continue
1066 track_score = modified_levenshtein(
1067 nnodes[0].firstChild.nodeValue, title)
1068 album_score = modified_levenshtein(
1069@@ -310,32 +345,36 @@
1070 match = possibles[0]
1071 print "got a match", match
1072 dest_url = "%s/music/l/%s/%s" % (
1073- BASE_URL, match["trackid"], "0") # this 0 should be userid
1074- self.builder.get_object("lblProgress").set_markup(_("Found <i>%s</i> by <i>%s</i> from <i>%s</i>") % (
1075- cgi.escape(match["track"]), cgi.escape(match["artist"]),
1076- cgi.escape(match["album"])))
1077- self.builder.get_object("lblURL").set_markup("<big><b>%s</b></big>" % dest_url)
1078+ BASE_URL, match["trackid"], "0") # this 0 should be userid
1079+ self.builder.get_object("lblProgress").set_markup(
1080+ _("Found <i>%s</i> by <i>%s</i> from <i>%s</i>") % (
1081+ cgi.escape(match["track"]), cgi.escape(match["artist"]),
1082+ cgi.escape(match["album"])))
1083+ self.builder.get_object("lblURL").set_markup(
1084+ "<big><b>%s</b></big>" % dest_url)
1085 clipboard = gtk.Clipboard(
1086 gtk.gdk.display_manager_get().get_default_display(), "CLIPBOARD")
1087 clipboard.set_text(dest_url)
1088
1089- if gwibber_available:
1090+ if GWIBBER_AVAILABLE:
1091 self.tweet_button = gtk.Button("Tweet this link")
1092- self.tweet_button.connect("clicked", self.gwibber, dest_url,
1093+ self.tweet_button.connect("clicked", self.gwibber, dest_url,
1094 artist, album, title)
1095 self.win.get_content_area().pack_end(self.tweet_button)
1096 self.tweet_button.show()
1097-
1098+
1099 def gwibber(self, button, url, artist, album, title):
1100+ """Show the Gwibber posting widget."""
1101 self.pvb = gwibber.lib.gtk.widgets.GwibberPosterVBox()
1102- self.message = "Currently listening to %s by %s %s" % (title, artist, url)
1103- self.pvb.input.connect("expose-event", self.gwibber_input_text)
1104- self.pvb.button_send.connect("clicked",
1105+ self.message = "Currently listening to %s by %s %s" % (
1106+ title, artist, url)
1107+ self.pvb.input.connect("expose-event", self.gwibber_input_text)
1108+ self.pvb.button_send.connect("clicked",
1109 lambda x: self.builder.get_object("winMain").destroy())
1110 self.pvb.show_all()
1111 self.builder.get_object("vbMain").pack_end(self.pvb)
1112 self.tweet_button.hide()
1113
1114 def gwibber_input_text(self, *args):
1115+ """Set the Gwibber text input."""
1116 self.pvb.input.set_text(self.message)
1117-
1118
1119=== modified file 'umusicstore/__init__.py'
1120--- umusicstore/__init__.py 2010-09-23 16:36:08 +0000
1121+++ umusicstore/__init__.py 2010-12-21 15:44:57 +0000
1122@@ -17,23 +17,25 @@
1123 # Authored by Stuart Langridge <stuart.langridge@canonical.com>
1124
1125 import gconf
1126-from MusicStoreWidget import U1MusicStoreWidget
1127-from U1MSLinks import U1MSLinkProvider
1128-
1129-U1_FIRST_TIME_FLAG_ENTRY = "/apps/rhythmbox/plugins/umusicstore/first_time_flag"
1130-
1131 import rb
1132
1133+from .MusicStoreWidget import U1MusicStoreWidget
1134+from .U1MSLinks import U1MSLinkProvider
1135+
1136+U1_FIRST_TIME_FLAG_ENTRY = \
1137+ "/apps/rhythmbox/plugins/umusicstore/first_time_flag"
1138+
1139+
1140 class U1MusicStorePlugin (rb.Plugin):
1141 """The Ubuntu One Music Store."""
1142
1143 def __init__(self):
1144 rb.Plugin.__init__(self)
1145-
1146+
1147 # The Music Store itself
1148 self.music_store_widget = U1MusicStoreWidget(
1149 plugin=self, find_file=self.find_file)
1150-
1151+
1152 # The Links button
1153 self.music_store_links_provider = U1MSLinkProvider(
1154 find_file=self.find_file)
1155@@ -43,8 +45,8 @@
1156 self.music_store_widget.activate(shell)
1157 self.music_store_links_provider.activate(shell)
1158
1159- # Select the source if it's the first time
1160- conf_client = gconf.client_get_default ()
1161+ # Select the source if it's the first time
1162+ conf_client = gconf.client_get_default()
1163 if not conf_client.get_bool(U1_FIRST_TIME_FLAG_ENTRY):
1164 shell.props.sourcelist.select(self.music_store_widget.source)
1165 conf_client.set_bool(U1_FIRST_TIME_FLAG_ENTRY, True)
1166
1167=== removed file 'umusicstore/umusicstore.rb-plugin'
1168--- umusicstore/umusicstore.rb-plugin 2010-07-21 16:03:11 +0000
1169+++ umusicstore/umusicstore.rb-plugin 1970-01-01 00:00:00 +0000
1170@@ -1,10 +0,0 @@
1171-[RB Plugin]
1172-Loader=python
1173-Module=umusicstore
1174-IAge=1
1175-Name=Ubuntu One Music Store
1176-Description=The Ubuntu One Music Store
1177-Authors=Stuart Langridge <stuart.langridge@canonical.com>, Rodrigo Moya <rodrigo.moya@canonical.com>
1178-Copyright=Copyright © 2009 Canonical
1179-Website=http://one.ubuntu.com/
1180-

Subscribers

People subscribed via source and target branches

to all changes: