Merge lp:~chipaca/rhythmbox-ubuntuone/brown-paper-bags into lp:rhythmbox-ubuntuone
- brown-paper-bags
- Merge into trunk
Proposed by
John Lenton
Status: | Merged |
---|---|
Merge reported by: | Rodrigo Moya |
Merged at revision: | not available |
Proposed branch: | lp:~chipaca/rhythmbox-ubuntuone/brown-paper-bags |
Merge into: | lp:rhythmbox-ubuntuone |
Diff against target: |
424 lines (+6/-400) 1 file modified
umusicstore/__init__.py (+6/-400) |
To merge this branch: | bzr merge lp:~chipaca/rhythmbox-ubuntuone/brown-paper-bags |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Ubuntu One Control Tower | Pending | ||
Review via email: mp+30575@code.launchpad.net |
Commit message
Description of the change
resolved the conflict
To post a comment you must log in.
Revision history for this message
Rodrigo Moya (rodrigo-moya) wrote : | # |
Preview Diff
[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1 | === modified file 'umusicstore/__init__.py' | |||
2 | --- umusicstore/__init__.py 2010-06-08 15:19:02 +0000 | |||
3 | +++ umusicstore/__init__.py 2010-07-21 20:25:57 +0000 | |||
4 | @@ -16,29 +16,14 @@ | |||
5 | 16 | # | 16 | # |
6 | 17 | # Authored by Stuart Langridge <stuart.langridge@canonical.com> | 17 | # Authored by Stuart Langridge <stuart.langridge@canonical.com> |
7 | 18 | 18 | ||
16 | 19 | import gtk, gobject, os, urllib, gconf, stat, urlparse, gio | 19 | |
17 | 20 | import gst, gst.pbutils | 20 | import gconf |
10 | 21 | import aptdaemon.client | ||
11 | 22 | from aptdaemon.enums import * | ||
12 | 23 | from aptdaemon.gtkwidgets import AptErrorDialog, \ | ||
13 | 24 | AptProgressBar | ||
14 | 25 | import rb, rhythmdb | ||
15 | 26 | from ubuntuone.gtkwidgets import MusicStore as U1MusicStore | ||
18 | 27 | from MusicStoreWidget import U1MusicStoreWidget | 21 | from MusicStoreWidget import U1MusicStoreWidget |
19 | 28 | from U1MSLinks import U1MSLinkProvider | 22 | from U1MSLinks import U1MSLinkProvider |
33 | 29 | import xdg.BaseDirectory | 23 | |
34 | 30 | import dbus.exceptions | 24 | U1_FIRST_TIME_FLAG_ENTRY = "/apps/rhythmbox/plugins/umusicstore/first_time_flag" |
35 | 31 | 25 | ||
36 | 32 | import gettext | 26 | import rb |
24 | 33 | from gettext import lgettext as _ | ||
25 | 34 | gettext.bindtextdomain("rhythmbox-ubuntuone-music-store", "/usr/share/locale") | ||
26 | 35 | gettext.textdomain("rhythmbox-ubuntuone-music-store") | ||
27 | 36 | |||
28 | 37 | MUSIC_STORE_WIDGET = U1MusicStore() # keep this around for later | ||
29 | 38 | U1LIBRARYPATH = MUSIC_STORE_WIDGET.get_library_location() | ||
30 | 39 | RB_LIBRARY_LOCATIONS = "/apps/rhythmbox/library_locations" | ||
31 | 40 | U1_CONFIG_PATH = "/apps/rhythmbox/plugins/umusicstore" | ||
32 | 41 | U1_FIRST_TIME_FLAG_ENTRY = U1_CONFIG_PATH + "/first_time_flag" | ||
37 | 42 | 27 | ||
38 | 43 | class U1MusicStorePlugin (rb.Plugin): | 28 | class U1MusicStorePlugin (rb.Plugin): |
39 | 44 | """The Ubuntu One Music Store.""" | 29 | """The Ubuntu One Music Store.""" |
40 | @@ -67,384 +52,5 @@ | |||
41 | 67 | 52 | ||
42 | 68 | def deactivate(self, shell): | 53 | def deactivate(self, shell): |
43 | 69 | """Plugin shutdown.""" | 54 | """Plugin shutdown.""" |
44 | 70 | <<<<<<< TREE | ||
45 | 71 | # remove source | ||
46 | 72 | self.source.delete_thyself() | ||
47 | 73 | # remove the library, if it's empty | ||
48 | 74 | try: | ||
49 | 75 | filecount = len(os.listdir(self.U1_LIBRARY_SYMLINK)) | ||
50 | 76 | except OSError: | ||
51 | 77 | # symlink is dangling | ||
52 | 78 | # so they never downloaded anything | ||
53 | 79 | filecount = 0 | ||
54 | 80 | if filecount == 0: | ||
55 | 81 | client = gconf.client_get_default() | ||
56 | 82 | libraries = client.get_list(RB_LIBRARY_LOCATIONS, gconf.VALUE_STRING) | ||
57 | 83 | if self.u1_library_path_url in libraries: | ||
58 | 84 | client.notify_remove(self.library_adder) | ||
59 | 85 | libraries.remove(self.u1_library_path_url) | ||
60 | 86 | client.set_list(RB_LIBRARY_LOCATIONS, gconf.VALUE_STRING, libraries) | ||
61 | 87 | # delete held references | ||
62 | 88 | del self.db | ||
63 | 89 | del self.source | ||
64 | 90 | del self.shell | ||
65 | 91 | |||
66 | 92 | def url_loaded(self, source, url): | ||
67 | 93 | """A URL is loaded in the plugin""" | ||
68 | 94 | print "URL loaded:", url | ||
69 | 95 | if urlparse.urlparse(url).scheme == "https": | ||
70 | 96 | pass | ||
71 | 97 | else: | ||
72 | 98 | pass | ||
73 | 99 | |||
74 | 100 | def _udf_path_to_library_uri(self, path): | ||
75 | 101 | """Calculate the path in the library. | ||
76 | 102 | Since the library is accessed via the created symlink, but the path | ||
77 | 103 | passed to us is to a file in the actual music store UDF, we need to | ||
78 | 104 | work out the path inside the library, i.e., what the path to that file | ||
79 | 105 | is via the symlink.""" | ||
80 | 106 | |||
81 | 107 | if path.startswith(U1LIBRARYPATH): | ||
82 | 108 | subpath = path[len(U1LIBRARYPATH):] | ||
83 | 109 | else: | ||
84 | 110 | subpath = path | ||
85 | 111 | if subpath.startswith("/"): subpath = subpath[1:] | ||
86 | 112 | library_path = os.path.join(self.U1_LIBRARY_SYMLINK, subpath) | ||
87 | 113 | # convert path to URI. Don't use urllib for this; Python and | ||
88 | 114 | # glib escape URLs differently. gio does it the glib way. | ||
89 | 115 | library_uri = gio.File(library_path).get_uri() | ||
90 | 116 | return library_uri | ||
91 | 117 | |||
92 | 118 | def download_finished(self, source, path): | ||
93 | 119 | """A file is finished downloading""" | ||
94 | 120 | library_uri = self._udf_path_to_library_uri(path) | ||
95 | 121 | # Import the URI | ||
96 | 122 | if not self.shell.props.db.entry_lookup_by_location(library_uri): | ||
97 | 123 | self.db.add_uri(library_uri) | ||
98 | 124 | |||
99 | 125 | def play_library(self, source, path): | ||
100 | 126 | """Switch to and start playing a song from the library""" | ||
101 | 127 | uri = self._udf_path_to_library_uri(path) | ||
102 | 128 | entry = self.shell.props.db.entry_lookup_by_location(uri) | ||
103 | 129 | if not entry: | ||
104 | 130 | print "couldn't find entry", uri | ||
105 | 131 | return | ||
106 | 132 | libsrc = self.shell.props.library_source | ||
107 | 133 | genre_view, artist_view, album_view = libsrc.get_property_views() | ||
108 | 134 | song_view = libsrc.get_entry_view() | ||
109 | 135 | artist = self.shell.props.db.entry_get(entry, rhythmdb.PROP_ARTIST) | ||
110 | 136 | album = self.shell.props.db.entry_get(entry, rhythmdb.PROP_ALBUM) | ||
111 | 137 | self.shell.props.sourcelist.select(libsrc) | ||
112 | 138 | artist_view.set_selection([artist]) | ||
113 | 139 | album_view.set_selection([album]) | ||
114 | 140 | song_view.scroll_to_entry(entry) | ||
115 | 141 | player = self.shell.get_player() | ||
116 | 142 | player.stop() | ||
117 | 143 | player.play() | ||
118 | 144 | player.play_entry(entry, libsrc) | ||
119 | 145 | |||
120 | 146 | def play_preview_mp3(self, source, url, title): | ||
121 | 147 | """Play a passed mp3; signal handler for preview-mp3 signal.""" | ||
122 | 148 | # create an entry, don't save it, and play it | ||
123 | 149 | entry = self.shell.props.db.entry_lookup_by_location(url) | ||
124 | 150 | if entry is None: | ||
125 | 151 | entry = self.shell.props.db.entry_new(self.entry_type, url) | ||
126 | 152 | self.shell.props.db.set(entry, rhythmdb.PROP_TITLE, title) | ||
127 | 153 | player = self.shell.get_player() | ||
128 | 154 | player.stop() | ||
129 | 155 | player.play() | ||
130 | 156 | player.play_entry(entry, self.source) | ||
131 | 157 | # FIXME delete this entry when it finishes playing. Don't know how yet. | ||
132 | 158 | |||
133 | 159 | def add_u1_library(self): | ||
134 | 160 | """Add the U1 library if not listed in RB and re-add if changed.""" | ||
135 | 161 | u1_library_path_folder = xdg.BaseDirectory.save_data_path("ubuntuone") | ||
136 | 162 | # Ensure that we can write to the folder, because syncdaemon creates it | ||
137 | 163 | # with no write permissions | ||
138 | 164 | os.chmod(u1_library_path_folder, | ||
139 | 165 | os.stat(u1_library_path_folder)[stat.ST_MODE] | stat.S_IWUSR) | ||
140 | 166 | # Translators: this is the name under Music for U1 music in Rhythmbox | ||
141 | 167 | u1_library_path = os.path.join(u1_library_path_folder, _("Purchased from Ubuntu One")) | ||
142 | 168 | if not os.path.islink(u1_library_path): | ||
143 | 169 | if not os.path.exists(u1_library_path): | ||
144 | 170 | print "Attempting to symlink %s to %s" % (U1LIBRARYPATH, | ||
145 | 171 | u1_library_path) | ||
146 | 172 | os.symlink(U1LIBRARYPATH, u1_library_path) | ||
147 | 173 | else: | ||
148 | 174 | # something that isn't a symlink already exists. That's not | ||
149 | 175 | # supposed to happen. | ||
150 | 176 | # Write a warning and carry on. | ||
151 | 177 | print ("Warning: library location %s existed. It should have " | ||
152 | 178 | "been a symlink to %s, and it wasn't. This isn't supposed " | ||
153 | 179 | "to happen. Carrying on anyway, on the assumption that " | ||
154 | 180 | "you know what you're doing. If this is a problem, then " | ||
155 | 181 | "delete or rename %s.") % (u1_library_path, U1LIBRARYPATH, | ||
156 | 182 | u1_library_path) | ||
157 | 183 | self.u1_library_path_url = "file://%s" % urllib.quote(u1_library_path) | ||
158 | 184 | self.U1_LIBRARY_SYMLINK = u1_library_path | ||
159 | 185 | client = gconf.client_get_default() | ||
160 | 186 | self._add_u1_library_if_not_present(client) | ||
161 | 187 | self._remove_old_u1_library_if_present(client) | ||
162 | 188 | # Watch for changes to the gconf key and re-add the library | ||
163 | 189 | self.library_adder = client.notify_add(RB_LIBRARY_LOCATIONS, | ||
164 | 190 | self._add_u1_library_if_not_present) | ||
165 | 191 | |||
166 | 192 | def _add_u1_library_if_not_present(self, client, *args, **kwargs): | ||
167 | 193 | """Check for the U1 library and add to libraries list.""" | ||
168 | 194 | libraries = client.get_list(RB_LIBRARY_LOCATIONS, gconf.VALUE_STRING) | ||
169 | 195 | if self.u1_library_path_url not in libraries: | ||
170 | 196 | libraries.append(self.u1_library_path_url) | ||
171 | 197 | client.set_list(RB_LIBRARY_LOCATIONS, gconf.VALUE_STRING, libraries) | ||
172 | 198 | |||
173 | 199 | def _remove_old_u1_library_if_present(self, client, *args, **kwargs): | ||
174 | 200 | """Check for the old U1 library and remove it from libraries list.""" | ||
175 | 201 | libraries = client.get_list(RB_LIBRARY_LOCATIONS, gconf.VALUE_STRING) | ||
176 | 202 | removed = False | ||
177 | 203 | # originally, this was the library path. Someone might have this. | ||
178 | 204 | old_path = "file://%s" % os.path.expanduser("~/.ubuntuone/musicstore") | ||
179 | 205 | if old_path in libraries: | ||
180 | 206 | libraries.remove(old_path) | ||
181 | 207 | removed = True | ||
182 | 208 | # Then, this was the library path, which we put into gconf unescaped | ||
183 | 209 | actual_udf_path_unescaped = "file://%s" % U1LIBRARYPATH | ||
184 | 210 | if actual_udf_path_unescaped in libraries: | ||
185 | 211 | libraries.remove(actual_udf_path_unescaped) | ||
186 | 212 | removed = True | ||
187 | 213 | # In theory, no-one should have the escaped path, but let's check | ||
188 | 214 | actual_udf_path_escaped = "file://%s" % U1LIBRARYPATH | ||
189 | 215 | if actual_udf_path_escaped in libraries: | ||
190 | 216 | libraries.remove(actual_udf_path_escaped) | ||
191 | 217 | removed = True | ||
192 | 218 | # Also, remove any library which is in .local/share and *isn't* | ||
193 | 219 | # the current library. This caters for people who got the library | ||
194 | 220 | # created under one name (say, English) and then had it created | ||
195 | 221 | # under another (say, after a translation to Dutch) | ||
196 | 222 | u1_library_path_folder = xdg.BaseDirectory.save_data_path("ubuntuone") | ||
197 | 223 | u1_library_path_folder_url = "file://%s" % urllib.quote(u1_library_path_folder) | ||
198 | 224 | symlink_url = "file://" + urllib.quote(self.U1_LIBRARY_SYMLINK) | ||
199 | 225 | for l in libraries: | ||
200 | 226 | if l.startswith(u1_library_path_folder_url) and l != symlink_url: | ||
201 | 227 | libraries.remove(l) | ||
202 | 228 | # and delete the symlink itself | ||
203 | 229 | symlink_to_remove = urllib.unquote(l[7:]) | ||
204 | 230 | os.unlink(symlink_to_remove) | ||
205 | 231 | removed = True | ||
206 | 232 | if removed: | ||
207 | 233 | client.set_list(RB_LIBRARY_LOCATIONS, gconf.VALUE_STRING, libraries) | ||
208 | 234 | |||
209 | 235 | class U1Source(rb.Source): | ||
210 | 236 | """A Rhythmbox source widget for the U1 Music Store.""" | ||
211 | 237 | # gproperties required so that rb.Source is instantiable | ||
212 | 238 | __gproperties__ = { | ||
213 | 239 | 'plugin': (rb.Plugin, 'plugin', 'plugin', | ||
214 | 240 | gobject.PARAM_WRITABLE|gobject.PARAM_CONSTRUCT_ONLY), | ||
215 | 241 | } | ||
216 | 242 | # we have the preview-mp3 signal; we receive it from the widget, and re-emit | ||
217 | 243 | # it so that the plugin gets it, because the plugin actually plays the mp3 | ||
218 | 244 | __gsignals__ = { | ||
219 | 245 | "preview-mp3": (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE, (str, str)), | ||
220 | 246 | "play-library": (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE, (str,)), | ||
221 | 247 | "download-finished": (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE, (str,)), | ||
222 | 248 | "url-loaded": (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE, (str,)), | ||
223 | 249 | } | ||
224 | 250 | |||
225 | 251 | def __init__(self): | ||
226 | 252 | rb.Source.__init__(self, name=_("Ubuntu One")) | ||
227 | 253 | self.__activated = False | ||
228 | 254 | |||
229 | 255 | def do_impl_activate(self): | ||
230 | 256 | """Source startup.""" | ||
231 | 257 | if self.__activated: return | ||
232 | 258 | self.__activated = True | ||
233 | 259 | self.test_can_play_mp3() | ||
234 | 260 | rb.Source.do_impl_activate (self) | ||
235 | 261 | |||
236 | 262 | def test_can_play_mp3(self): | ||
237 | 263 | """Can the user play mp3s? Start a GStreamer pipeline to check.""" | ||
238 | 264 | mp3pth = os.path.realpath(os.path.join( | ||
239 | 265 | os.path.split(__file__)[0], "empty.mp3")) | ||
240 | 266 | uri = "file://%s" % urllib.quote("%s" % mp3pth) | ||
241 | 267 | self.install_pipeline = gst.parse_launch( | ||
242 | 268 | 'uridecodebin uri=%s ! fakesink' % uri) | ||
243 | 269 | bus = self.install_pipeline.get_bus() | ||
244 | 270 | bus.add_signal_watch() | ||
245 | 271 | bus.connect("message::element", self._got_element_msg) | ||
246 | 272 | bus.connect("message::eos", self._got_end_of_stream) | ||
247 | 273 | self.install_pipeline.set_state(gst.STATE_PLAYING) | ||
248 | 274 | |||
249 | 275 | def _got_element_msg(self, bus, msg): | ||
250 | 276 | """Handler for element messages from the check-mp3 pipeline. | ||
251 | 277 | GStreamer throws a "plugin-missing" element message if the | ||
252 | 278 | user does not have the right codecs to play a file.""" | ||
253 | 279 | plugin_missing = gst.pbutils.is_missing_plugin_message(msg) | ||
254 | 280 | if plugin_missing: | ||
255 | 281 | self.install_pipeline.set_state(gst.STATE_NULL) | ||
256 | 282 | self.install_mp3_playback() | ||
257 | 283 | |||
258 | 284 | def _got_end_of_stream(self, bus, msg): | ||
259 | 285 | """Handler for end of stream from the check-mp3 pipeline. | ||
260 | 286 | If we reach the end of the stream, mp3 playback is enabled.""" | ||
261 | 287 | self.install_pipeline.set_state(gst.STATE_NULL) | ||
262 | 288 | if os.environ.has_key("U1INSTALLMP3ANYWAY"): | ||
263 | 289 | # override the decision not to install the package | ||
264 | 290 | self.install_mp3_playback() | ||
265 | 291 | else: | ||
266 | 292 | self.add_music_store_widget() | ||
267 | 293 | |||
268 | 294 | def install_mp3_playback(self): | ||
269 | 295 | """Use aptdaemon to install the Fluendo mp3 playback codec package.""" | ||
270 | 296 | self.install_box = gtk.Alignment(xscale=0.0, yscale=0.0, xalign=0.5, | ||
271 | 297 | yalign=0.5) | ||
272 | 298 | self.install_vbox = gtk.VBox() | ||
273 | 299 | self.install_label_head = gtk.Label() | ||
274 | 300 | self.install_label_head.set_use_markup(True) | ||
275 | 301 | not_installed = _("MP3 plugins are not installed") | ||
276 | 302 | self.install_label_head.set_markup('<span weight="bold" size="larger">' | ||
277 | 303 | '%s</span>' % not_installed) | ||
278 | 304 | self.install_label_head.set_alignment(0.0, 0.5) | ||
279 | 305 | self.install_label_body = gtk.Label() | ||
280 | 306 | self.install_label_body.set_text(_('To listen to your purchased songs' | ||
281 | 307 | ', you need to install MP3 plugins. Click below to install them.')) | ||
282 | 308 | self.install_label_body.set_alignment(0.0, 0.5) | ||
283 | 309 | self.install_label_eula = gtk.Label() | ||
284 | 310 | # EULA text copied from /var/lib/dpkg/info/gstreamer0.10-fluendo-plugins-mp3-partner.templates | ||
285 | 311 | # The partner package shows the EULA itself on installations, but | ||
286 | 312 | # aptdaemon installations work like DEBIAN_FRONTEND=noninteractive | ||
287 | 313 | # so we show the EULA here. (This also avoids a popup window.) | ||
288 | 314 | # EULA text is not translatable; do not wrap it with gettext! | ||
289 | 315 | self.install_label_eula.set_markup( | ||
290 | 316 | "<small>MPEG Layer-3 audio decoding technology notice\n" | ||
291 | 317 | "MPEG Layer-3 audio decoding technology licensed " | ||
292 | 318 | "from Fraunhofer IIS and Thomson\n" | ||
293 | 319 | "This product cannot be installed in product other than Personal " | ||
294 | 320 | "Computers sold for general purpose usage, and not for set-top " | ||
295 | 321 | "boxes, embedded PC, PC which are sold and customized for " | ||
296 | 322 | "mainly audio or multimedia playback and/or registration, " | ||
297 | 323 | "unless the seller has received a license by Fraunhofer IIS" | ||
298 | 324 | "and Thomson and pay the relevant royalties to them.</small>") | ||
299 | 325 | self.install_label_eula.set_alignment(0.0, 0.5) | ||
300 | 326 | self.install_label_eula.set_size_request(400,200) | ||
301 | 327 | self.install_label_eula.set_line_wrap(True) | ||
302 | 328 | self.install_hbtn = gtk.HButtonBox() | ||
303 | 329 | self.install_hbtn.set_layout(gtk.BUTTONBOX_END) | ||
304 | 330 | self.install_button = gtk.Button(label=_("Install MP3 plugins")) | ||
305 | 331 | self.install_button.connect("clicked", self._start_mp3_install) | ||
306 | 332 | self.install_hbtn.add(self.install_button) | ||
307 | 333 | self.install_vbox.pack_start(self.install_label_head, expand=False) | ||
308 | 334 | self.install_vbox.pack_start(self.install_label_body, expand=False, | ||
309 | 335 | padding=12) | ||
310 | 336 | self.install_vbox.pack_start(self.install_hbtn, expand=False) | ||
311 | 337 | self.install_vbox.pack_start(self.install_label_eula, expand=False, | ||
312 | 338 | padding=12) | ||
313 | 339 | self.install_box.add(self.install_vbox) | ||
314 | 340 | self.install_box.show_all() | ||
315 | 341 | self.add(self.install_box) | ||
316 | 342 | |||
317 | 343 | def _start_mp3_install(self, btn): | ||
318 | 344 | """Add the 'partner' repository and update the package list from it.""" | ||
319 | 345 | self.ac = aptdaemon.client.AptClient() | ||
320 | 346 | try: | ||
321 | 347 | self.ac.add_repository("deb","http://archive.canonical.com/", "lucid", ["partner"]) | ||
322 | 348 | except dbus.exceptions.DBusException, e: | ||
323 | 349 | if e.get_dbus_name() == "org.freedesktop.PolicyKit.Error.NotAuthorized": | ||
324 | 350 | # user cancelled, so exit from here so they can press the button again | ||
325 | 351 | return | ||
326 | 352 | self.ac.update_cache(reply_handler=self._finish_updating_packages, | ||
327 | 353 | error_handler=self._on_error) | ||
328 | 354 | |||
329 | 355 | def _finish_updating_packages(self, transaction): | ||
330 | 356 | """Now that partner is added, install our mp3 codec package.""" | ||
331 | 357 | self.update_progress = AptProgressBar(transaction) | ||
332 | 358 | self.update_progress.show() | ||
333 | 359 | self.install_label_head.set_text("") | ||
334 | 360 | self.install_label_body.set_text(_("Finding MP3 plugins")) | ||
335 | 361 | self.install_label_eula.hide() | ||
336 | 362 | self.install_hbtn.hide() | ||
337 | 363 | self.install_vbox.pack_start(self.update_progress, expand=False) | ||
338 | 364 | transaction.run(reply_handler=lambda: True, | ||
339 | 365 | error_handler=self._on_error) | ||
340 | 366 | self.ac.install_packages(["gstreamer0.10-fluendo-plugins-mp3-partner"], | ||
341 | 367 | reply_handler=self._run_transaction, | ||
342 | 368 | error_handler=self._on_error) | ||
343 | 369 | |||
344 | 370 | def _run_transaction(self, transaction): | ||
345 | 371 | """Show progress of aptdaemon package installation.""" | ||
346 | 372 | self.update_progress.hide() | ||
347 | 373 | self.install_progress = AptProgressBar(transaction) | ||
348 | 374 | self.install_progress.show() | ||
349 | 375 | self.install_label_head.set_text("") | ||
350 | 376 | self.install_label_body.set_text(_("Installing MP3 plugins")) | ||
351 | 377 | self.install_label_eula.hide() | ||
352 | 378 | self.install_hbtn.hide() | ||
353 | 379 | self.install_vbox.pack_start(self.install_progress, expand=False) | ||
354 | 380 | transaction.run(reply_handler=lambda: True, | ||
355 | 381 | error_handler=self._on_error) | ||
356 | 382 | transaction.connect("finished", self._finished) | ||
357 | 383 | |||
358 | 384 | def _finished(self, trans, exit_code): | ||
359 | 385 | """Aptdaemon package installation finished; show music store.""" | ||
360 | 386 | if exit_code == 0 or exit_code == 2: # 0: success, 2: already installed | ||
361 | 387 | self.remove(self.install_box) | ||
362 | 388 | gst.update_registry() | ||
363 | 389 | self.add_music_store_widget() | ||
364 | 390 | else: | ||
365 | 391 | self._on_error("Could not find the " | ||
366 | 392 | "gstreamer0.10-fluendo-plugins-mp3-partner package.") | ||
367 | 393 | |||
368 | 394 | def _on_error(self, error): | ||
369 | 395 | """Error handler for aptdaemon.""" | ||
370 | 396 | print error | ||
371 | 397 | problem_installing = _("There was a problem installing, sorry") | ||
372 | 398 | self.install_label_head.set_markup('<span weight="bold" size="larger">' | ||
373 | 399 | '%s</span>' % problem_installing) | ||
374 | 400 | self.install_label_body.set_text(_('Check your internet connection and ' | ||
375 | 401 | 'try again.')) | ||
376 | 402 | if getattr(self, "install_progress"): | ||
377 | 403 | self.install_progress.hide() | ||
378 | 404 | self.install_hbtn.show() | ||
379 | 405 | |||
380 | 406 | def add_music_store_widget(self): | ||
381 | 407 | """Display the music store widget in Rhythmbox.""" | ||
382 | 408 | self.browser = MUSIC_STORE_WIDGET | ||
383 | 409 | self.add(self.browser) | ||
384 | 410 | self.show_all() | ||
385 | 411 | self.browser.set_no_show_all(True) | ||
386 | 412 | self.browser.set_property("visible", True) | ||
387 | 413 | self.browser.connect("preview-mp3", self.re_emit_preview) | ||
388 | 414 | self.browser.connect("play-library", self.re_emit_playlibrary) | ||
389 | 415 | self.browser.connect("download-finished", self.re_emit_downloadfinished) | ||
390 | 416 | self.browser.connect("url-loaded", self.re_emit_urlloaded) | ||
391 | 417 | |||
392 | 418 | def do_impl_can_pause(self): | ||
393 | 419 | """Implementation can pause. | ||
394 | 420 | If we don't handle this, Rhythmbox segfaults.""" | ||
395 | 421 | return True # so we can pause, else we segfault | ||
396 | 422 | |||
397 | 423 | def re_emit_preview(self, widget, url, title): | ||
398 | 424 | """Handle the preview-mp3 signal and re-emit it to the rb.Plugin.""" | ||
399 | 425 | self.emit("preview-mp3", url, title) | ||
400 | 426 | |||
401 | 427 | def re_emit_playlibrary(self, widget, path): | ||
402 | 428 | """Handle the play-library signal and re-emit it to the rb.Plugin.""" | ||
403 | 429 | self.emit("play-library", path) | ||
404 | 430 | |||
405 | 431 | def re_emit_downloadfinished(self, widget, path): | ||
406 | 432 | """Handle the download-finished signal and re-emit it to the rb.Plugin.""" | ||
407 | 433 | self.emit("download-finished", path) | ||
408 | 434 | |||
409 | 435 | def re_emit_urlloaded(self, widget, url): | ||
410 | 436 | """Handle the url-loaded signal and re-emit it to the rb.Plugin.""" | ||
411 | 437 | self.emit("url-loaded", url) | ||
412 | 438 | |||
413 | 439 | def do_set_property(self, property, value): | ||
414 | 440 | """Allow property settings to handle the plugin call.""" | ||
415 | 441 | if property.name == 'plugin': | ||
416 | 442 | self.__plugin = value | ||
417 | 443 | else: | ||
418 | 444 | raise AttributeError, 'unknown property %s' % property.name | ||
419 | 445 | |||
420 | 446 | ======= | ||
421 | 447 | self.music_store_widget.deactivate(shell) | 55 | self.music_store_widget.deactivate(shell) |
422 | 448 | self.music_store_links_provider.deactivate(shell) | 56 | self.music_store_links_provider.deactivate(shell) |
423 | 449 | >>>>>>> MERGE-SOURCE | ||
424 | 450 |
Sorry, didn't see this branch last night, so applied it manually to trunk and did a new release, so marking this as merged