1
# -*- Mode: python; coding: utf-8; tab-width: 8; indent-tabs-mode: t; -*-
3
# Copyright (C) 2006 Adam Zimmerman <adam_zimmerman@sfu.ca>
4
# Copyright (C) 2006 James Livingston <doclivingston@gmail.com>
6
# This program is free software; you can redistribute it and/or modify
7
# it under the terms of the GNU General Public License as published by
8
# the Free Software Foundation; either version 2, or (at your option)
11
# The Rhythmbox authors hereby grant permission for non-GPL compatible
12
# GStreamer plugins to be used and distributed together with GStreamer
13
# and Rhythmbox. This permission is above and beyond the permissions granted
14
# by the GPL license by which Rhythmbox is covered. If you modify this code
15
# you may extend this exception to your version of the code, but you are not
16
# obligated to do so. If you do not wish to do so, delete this exception
17
# statement from your version.
19
# This program is distributed in the hope that it will be useful,
20
# but WITHOUT ANY WARRANTY; without even the implied warranty of
21
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22
# GNU General Public License for more details.
24
# You should have received a copy of the GNU General Public License
25
# along with this program; if not, write to the Free Software
26
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
36
import gnomekeyring as keyring
39
from gi.repository import RB
40
from gi.repository import Gtk, Gio, Peas, PeasGtk
41
# XXX use GnomeKeyring when available
43
from MagnatuneSource import MagnatuneSource
47
<popup name="MagnatuneSourceViewPopup">
48
<menuitem name="AddToQueueLibraryPopup" action="AddToQueue"/>
49
<menuitem name="MagnatuneDownloadAlbum" action="MagnatuneDownloadAlbum"/>
50
<menuitem name="MagnatuneArtistInfo" action="MagnatuneArtistInfo"/>
51
<menuitem name="MagnatuneCancelDownload" action="MagnatuneCancelDownload"/>
53
<menuitem name="BrowseGenreLibraryPopup" action="BrowserSrcChooseGenre"/>
54
<menuitem name="BrowseArtistLibraryPopup" action="BrowserSrcChooseArtist"/>
55
<menuitem name="BrowseAlbumLibraryPopup" action="BrowserSrcChooseAlbum"/>
57
<menuitem name="PropertiesLibraryPopup" action="MusicProperties"/>
62
class MagnatuneEntryType(RB.RhythmDBEntryType):
64
RB.RhythmDBEntryType.__init__(self, name='magnatune')
66
def can_sync_metadata(self, entry):
69
def sync_metadata(self, entry, changes):
72
class Magnatune(gobject.GObject, Peas.Activatable):
73
__gtype_name__ = 'Magnatune'
74
object = gobject.property(type=gobject.GObject)
76
format_list = ['ogg', 'flac', 'wav', 'mp3-vbr', 'mp3-cbr']
79
gobject.GObject.__init__(self)
81
def do_activate(self):
83
self.db = shell.props.db
85
self.entry_type = MagnatuneEntryType()
86
self.db.register_entry_type(self.entry_type)
88
self.settings = Gio.Settings("org.gnome.rhythmbox.plugins.magnatune")
90
theme = Gtk.IconTheme.get_default()
91
rb.append_plugin_source_path(theme, "/icons")
93
what, width, height = Gtk.icon_size_lookup(Gtk.IconSize.LARGE_TOOLBAR)
94
icon = rb.try_load_icon(theme, "magnatune", width, 0)
96
group = RB.DisplayPageGroup.get_by_id ("stores")
97
settings = Gio.Settings("org.gnome.rhythmbox.plugins.magnatune")
98
self.source = gobject.new(MagnatuneSource,
100
entry_type=self.entry_type,
103
settings=settings.get_child("source"),
106
shell.register_entry_type_for_source(self.source, self.entry_type)
107
shell.append_display_page(self.source, group)
109
manager = shell.props.ui_manager
110
# Add the popup menu actions
111
self.action_group = Gtk.ActionGroup(name='MagnatunePluginActions')
113
action = Gtk.Action(name='MagnatuneDownloadAlbum', label=_('Download Album'),
114
tooltip=_("Download this album from Magnatune"),
116
action.connect('activate', lambda a: shell.props.selected_page.download_album())
117
self.action_group.add_action(action)
118
action = Gtk.Action(name='MagnatuneArtistInfo', label=_('Artist Information'),
119
tooltip=_("Get information about this artist"),
121
action.connect('activate', lambda a: shell.props.selected_page.display_artist_info())
122
self.action_group.add_action(action)
123
action = Gtk.Action(name='MagnatuneCancelDownload', label=_('Cancel Downloads'),
124
tooltip=_("Stop downloading purchased albums"),
126
action.connect('activate', lambda a: shell.props.selected_page.cancel_downloads())
127
action.set_sensitive(False)
128
self.action_group.add_action(action)
130
manager.insert_action_group(self.action_group, 0)
131
self.ui_id = manager.add_ui_from_string(popup_ui)
133
self.pec_id = shell.props.shell_player.connect('playing-song-changed', self.playing_entry_changed)
134
manager.ensure_update()
136
def do_deactivate(self):
138
manager = shell.props.ui_manager
139
manager.remove_ui(self.ui_id)
140
manager.remove_action_group(self.action_group)
141
self.action_group = None
143
shell.props.shell_player.disconnect(self.pec_id)
145
self.db.entry_delete_by_type(self.entry_type)
148
self.entry_type = None
149
self.source.delete_thyself()
152
def playing_entry_changed (self, sp, entry):
153
self.source.playing_entry_changed(entry)
156
class MagnatuneConfig(gobject.GObject, PeasGtk.Configurable):
157
__gtype_name__ = 'MagnatuneConfig'
158
object = gobject.property(type=gobject.GObject)
161
gobject.GObject.__init__(self)
163
def do_create_configure_widget(self):
164
# We use a dictionary so we can modify these values from within inner functions
170
def got_items(result, items):
171
def created_item(result, id):
172
if result is None: # Item successfully created
173
keyring_data['id'] = id
174
keyring.item_get_info(None, id, got_item)
176
print "Couldn't create keyring item: " + str(result)
177
fill_account_details()
179
def got_item(result, item):
180
if result is None: # Item retrieved successfully
181
keyring_data['item'] = item
183
print "Couldn't retrieve keyring item: " + str(result)
184
fill_account_details()
188
if result is None and len(items) != 0: # Got list of search results
189
keyring_data['id'] = items[0].item_id
190
keyring.item_get_info(None, keyring_data['id'], got_item)
191
elif result == keyring.NoMatchError or len(items) == 0: # No items were found, so we'll create one
192
keyring.item_create(None,
193
keyring.ITEM_GENERIC_SECRET,
194
"Rhythmbox: Magnatune account information",
195
{'rhythmbox-plugin': 'magnatune'},
196
"", # Empty secret for now
199
else: # Some other error occurred
200
print "Couldn't access keyring: " + str(result)
201
fill_account_details()
205
def fill_account_details():
206
account_type = self.settings['account_type']
207
builder.get_object("no_account_radio").set_active(account_type == "none")
208
builder.get_object("stream_account_radio").set_active(account_type == "stream")
209
builder.get_object("download_account_radio").set_active(account_type == "download")
214
if keyring_data['item']:
215
username, password = keyring_data['item'].get_secret().split('\n')
216
except ValueError: # Couldn't parse the secret, probably because it's empty
218
builder.get_object("username_entry").set_text(username)
219
builder.get_object("password_entry").set_text(password)
221
has_account = account_type != "none"
222
builder.get_object("username_entry").set_sensitive(has_account)
223
builder.get_object("password_entry").set_sensitive(has_account)
224
builder.get_object("username_label").set_sensitive(has_account)
225
builder.get_object("password_label").set_sensitive(has_account)
227
builder.get_object("account_changed_label").hide()
229
def account_type_toggled (button):
230
print "account type radiobutton toggled: " + button.get_name()
231
account_type = {"no_account_radio": "none", "stream_account_radio": "stream", "download_account_radio": "download"}
232
if button.get_active():
233
self.settings['account_type'] = account_type[button.get_name()]
234
if account_type[button.get_name()] == 'none':
235
builder.get_object("username_label").set_sensitive(False)
236
builder.get_object("username_entry").set_sensitive(False)
237
builder.get_object("password_label").set_sensitive(False)
238
builder.get_object("password_entry").set_sensitive(False)
240
builder.get_object("username_label").set_sensitive(True)
241
builder.get_object("username_entry").set_sensitive(True)
242
builder.get_object("password_label").set_sensitive(True)
243
builder.get_object("password_entry").set_sensitive(True)
244
builder.get_object("account_changed_label").show()
246
def account_details_changed(entry):
247
username = builder.get_object("username_entry").get_text()
248
password = builder.get_object("password_entry").get_text()
249
if keyring_data['item']:
250
keyring_data['item'].set_secret('\n'.join((username, password)))
252
builder.get_object("account_changed_label").show()
254
def close_button_pressed(x, y):
256
if keyring_data['id'] and keyring_data['item']:
257
# The async version is not in the python bindings, grr...
258
keyring.item_set_info_sync(None, keyring_data['id'], keyring_data['item'])
260
RB.error_dialog(title = _("Couldn't store account information"),
261
message = _("There was a problem accessing the keyring. Check the debug output for more information."))
263
RB.error_dialog(title = _("Couldn't store account information"),
267
def format_selection_changed(self, button):
268
self.settings['format'] = self.format_list[button.get_active()]
270
self.configure_callback_dic = {
271
"rb_magnatune_audio_combobox_changed_cb" : self.format_selection_changed,
272
"rb_magnatune_radio_account_toggled_cb" : account_type_toggled,
273
"rb_magnatune_username_changed_cb" : account_details_changed,
274
"rb_magnatune_password_changed_cb" : account_details_changed
277
builder = Gtk.Builder()
278
builder.add_from_file(rb.find_plugin_file(self, "magnatune-prefs.ui"))
280
dialog = builder.get_object('preferences_dialog')
282
# Set the names of the radio buttons so we can tell which one has been clicked
283
for name in ("no_account_radio", "stream_account_radio", "download_account_radio"):
284
builder.get_object(name).set_name(name)
286
builder.get_object("audio_combobox").set_active(self.format_list.index(self.settings['format']))
288
builder.connect_signals(self.configure_callback_dic)
289
dialog.connect("response", close_button_pressed)
291
keyring.find_items(keyring.ITEM_GENERIC_SECRET, {'rhythmbox-plugin': 'magnatune'}, got_items)