~ubuntu-branches/debian/squeeze/elisa/squeeze

« back to all changes in this revision

Viewing changes to elisa/core/plugins/lastfm.py

  • Committer: Bazaar Package Importer
  • Author(s): Loic Minier
  • Date: 2007-06-25 14:08:21 UTC
  • Revision ID: james.westby@ubuntu.com-20070625140821-nq0yskdi51xc9ogj
Tags: upstream-0.1.7
ImportĀ upstreamĀ versionĀ 0.1.7

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
# -*- coding: utf-8 -*-
 
2
# Licensed under the MIT license
 
3
# http://opensource.org/licenses/mit-license.php
 
4
 
 
5
# Copyright 2007, Philippe Normand <phil at base-art dot net>
 
6
 
 
7
from elisa.core.base_plugins import DataAccessPlugin, PlayerPlugin, DataAccessFile
 
8
from elisa.core.base_plugins import TreePlugin
 
9
from elisa.core.interfaces import IDataAccess, IMediaPlayer
 
10
from elisa.core import media_uri, common, menu
 
11
from elisa.core.signals.application import application_started
 
12
from elisa.core.gst.lastfm_src import LastFMSource
 
13
import gst
 
14
 
 
15
class DummyFD:
 
16
 
 
17
    def close(self):
 
18
        pass
 
19
 
 
20
class LastFMPlayer(DataAccessPlugin, PlayerPlugin):
 
21
 
 
22
    __implements__ = (IMediaPlayer, IDataAccess)
 
23
 
 
24
    singleton = True
 
25
    name = 'lastfm'
 
26
    menu_name = _('Last.FM radios')
 
27
    
 
28
    parent = 'music'
 
29
    provides = ['audio',]
 
30
 
 
31
    default_config = {'locations': ['lastfm://globaltags/rock',
 
32
                                    'lastfm://globaltags/jazz']}
 
33
    
 
34
    folder_icon_path = 'folder-radios.png'
 
35
    item_icon_path = 'radio.png'
 
36
 
 
37
    folder_action = None
 
38
 
 
39
    icons = ['lastfm_love', 'lastfm_ban'] + PlayerPlugin.icons
 
40
 
 
41
    provides = [ "uri:lastfm" ]
 
42
    uncacheable_uri_schemes = ['lastfm']
 
43
 
 
44
 
 
45
    def __init__(self):
 
46
        DataAccessPlugin.__init__(self)
 
47
        PlayerPlugin.__init__(self)
 
48
        #self.set_icon_path('radios.png')
 
49
        self.login, self.password = '', ''
 
50
        self.lastfmsrc = None
 
51
        self.gst_pipeline = None
 
52
        application_started.connect(self._application_started)
 
53
        
 
54
    def _application_started(self):
 
55
        plugin_manager = common.get_plugin_manager()
 
56
        audioscrobbler = plugin_manager.get_plugin_with_name('audioscrobbler')
 
57
        if audioscrobbler and audioscrobbler.enabled:
 
58
            config = audioscrobbler.get_config()
 
59
            self.login = config.get('user')
 
60
            self.password = config.get('password')
 
61
        else:
 
62
            self.unload("Audioscrobbler plugin is required by the LastFM plugin")
 
63
 
 
64
    def get_parent(self):
 
65
        return PlayerPlugin.get_parent(self)
 
66
            
 
67
    def add_wizard_shortcuts(self):
 
68
        pass
 
69
 
 
70
    def play_item(self, menu_item):
 
71
        if not self.lock():
 
72
            return
 
73
        
 
74
        music_file = str(media_uri.Uri(location=menu_item.get_target_path()))
 
75
        player = self.get_player()
 
76
 
 
77
        def launch(r):
 
78
            self.logger.info('Playing radio %s' % music_file)
 
79
            player.play(start=True)
 
80
            player.un_mute()
 
81
            PlayerPlugin.play_item(self, menu_item)
 
82
            self.unlock()
 
83
            
 
84
        dfr = player.set_uri(music_file)
 
85
        if dfr:
 
86
            dfr.addCallback(launch)
 
87
        else:
 
88
            self.unlock()
 
89
            
 
90
    item_action = play_item
 
91
 
 
92
    def item_action_menu(self, menu_item):        
 
93
        play_pause = menu.MenuItem(short_name=_("Play"))
 
94
        play_pause.set_target_path("play/pause")
 
95
        play_pause.set_icon_path(self.play_icon)
 
96
        play_pause.set_action_callback(self.play_parent_item)
 
97
 
 
98
        love = menu.MenuItem(short_name=_("Love"))
 
99
        love.set_target_path("love")
 
100
        love.set_icon_path(self.lastfm_love_icon)
 
101
        love.set_action_callback(self.love_parent_item)
 
102
        love.disable()
 
103
 
 
104
        ban = menu.MenuItem(short_name=_("Ban"))
 
105
        ban.set_target_path("ban")
 
106
        ban.set_icon_path(self.lastfm_ban_icon)
 
107
        ban.set_action_callback(self.ban_parent_item)
 
108
        ban.disable()
 
109
 
 
110
        skip = menu.MenuItem(short_name=_("Skip"))
 
111
        skip.set_target_path("skip")
 
112
        skip.set_icon_path(self.seekf_icon)
 
113
        skip.set_action_callback(self.skip_parent_item)
 
114
        skip.disable()
 
115
 
 
116
        stop = menu.MenuItem(short_name=_("Stop"))
 
117
        stop.set_target_path("stop")
 
118
        stop.set_icon_path(self.stop_icon)
 
119
        stop.set_action_callback(self.stop_parent_item)
 
120
        stop.disable()
 
121
 
 
122
        volp = menu.MenuItem(short_name=_("Volume+"))
 
123
        volp.set_target_path("vol+")
 
124
        volp.set_icon_path(self.volume_up_icon)
 
125
        volp.set_action_callback(self.volp_parent_item)
 
126
        volp.disable()
 
127
 
 
128
        volm = menu.MenuItem(short_name=_("Volume-"))
 
129
        volm.set_target_path("vol-")
 
130
        volm.set_icon_path(self.volume_down_icon)
 
131
        volm.set_action_callback(self.volm_parent_item)
 
132
        volm.disable()
 
133
 
 
134
        menu_item.add_item(stop)
 
135
        menu_item.add_item(love)
 
136
        menu_item.add_item(ban)
 
137
        menu_item.add_item(play_pause)
 
138
        menu_item.add_item(skip)        
 
139
        menu_item.add_item(volm)
 
140
        menu_item.add_item(volp)
 
141
        
 
142
        TreePlugin.item_action_menu(self, menu_item)
 
143
        
 
144
        player = self.get_player()
 
145
        if player and str(menu_item.get_target_path()) == \
 
146
               str(player.get_playing_uri()):
 
147
            self.playing(menu_item)
 
148
 
 
149
    def playing(self, menu_item):
 
150
        PlayerPlugin.playing(self, menu_item)
 
151
        for target in ("love", "ban", "skip"):
 
152
            item = menu_item.get_item_with_target(target)
 
153
            if item:
 
154
                item.enable()
 
155
                
 
156
        #common.get_application().get_task_manager().add_task(task.Task(menu_item))
 
157
        
 
158
    def love_parent_item(self, menu_item):
 
159
        if self.lastfmsrc:
 
160
            self.lastfmsrc.love()
 
161
            
 
162
    def ban_parent_item(self, menu_item):
 
163
        if self.lastfmsrc:
 
164
            self.lastfmsrc.ban()
 
165
 
 
166
    def skip_parent_item(self, menu_item):
 
167
        if self.lastfmsrc:
 
168
            self.lastfmsrc.skip()
 
169
 
 
170
    # IDataAccess implementation
 
171
 
 
172
    def is_dir(self, uri):
 
173
        return False
 
174
 
 
175
    def get_direct_children(self, uri):
 
176
        children = {}
 
177
        return children
 
178
 
 
179
    def has_children(self, uri):
 
180
        return False
 
181
 
 
182
    def next_location(self, from_uri, item_filter=None, root=None):
 
183
        """
 
184
        Return the uri just next to `from_uri`.
 
185
        """
 
186
        next_uri = None
 
187
        short_name = None
 
188
        return (next_uri, short_name)
 
189
 
 
190
    def open(self, uri, mode=None):
 
191
        """
 
192
        """
 
193
        handle = DataAccessFile(self, DummyFD())
 
194
        return handle
 
195
 
 
196
    def remove_location(self, uri):
 
197
        """
 
198
        Unimplemented.
 
199
        """
 
200
        return None
 
201
 
 
202
    def get_gst_pipeline(self):
 
203
        if not self.gst_pipeline:            
 
204
            self.gst_pipeline = gst.Pipeline('pipeline')
 
205
 
 
206
            self.lastfmsrc = LastFMSource('src', self.login, self.password)
 
207
            decoder = gst.element_factory_make('decodebin')
 
208
            queue = gst.element_factory_make('queue')
 
209
            convert = gst.element_factory_make('audioconvert')
 
210
 
 
211
            def on_new_decoded_pad(element, pad, last):
 
212
                caps = pad.get_caps()
 
213
                name = caps[0].get_name()
 
214
                apad = convert.get_pad('sink')
 
215
                if 'audio' in name:
 
216
                    if not apad.is_linked(): # Only link once
 
217
                        pad.link(apad)
 
218
 
 
219
            decoder.connect('new-decoded-pad', on_new_decoded_pad)
 
220
            
 
221
            volume = gst.element_factory_make('volume', 'vlm')
 
222
            sink = gst.element_factory_make('autoaudiosink', 'audio-sink')
 
223
 
 
224
            self.gst_pipeline.add(self.lastfmsrc, decoder, queue, convert,
 
225
                                  volume, sink)
 
226
 
 
227
            self.lastfmsrc.link(decoder)
 
228
            convert.link(volume)
 
229
            volume.link(sink)
 
230
            
 
231
        return self.gst_pipeline