~cahr-gr/covergloobus/ui

« back to all changes in this revision

Viewing changes to src/players/Exaile3.py

  • Committer: Alexandr Grigorcea
  • Date: 2010-10-17 10:18:21 UTC
  • Revision ID: cahr.gr@gmail.com-20101017101821-9y1dz81ijj25fraf
fixed all players, added CliPlayer interface with moc and deadbeef using it

Show diffs side-by-side

added added

removed removed

Lines of Context:
17
17
import os
18
18
import dbus
19
19
import urllib
 
20
 
 
21
from common import _
 
22
from common import c
 
23
from common import State
 
24
from common import Track
 
25
from common import TRACK, STATE
20
26
from GenericPlayer import GenericPlayer
21
 
from common import Track
22
 
from common import c
23
 
from common import _
24
27
 
25
28
class Exaile3Player(GenericPlayer):
26
29
    """
34
37
    DBUS_NAME   = 'org.exaile.Exaile'
35
38
    DBUS_OBJECT = '/org/exaile/Exaile'
36
39
 
37
 
    dbus_object = None;
 
40
    iface = None
38
41
 
39
 
    def is_active(self):
40
 
        """
41
 
            Initializes class, begins dbus listening if DBUS_NAME is provided
42
 
            @param d: dbus.Interface
43
 
        """
44
 
        if self.DBUS_NAME in self.dbus.ListNames():
45
 
            return True
46
 
        else:
47
 
            return False
 
42
    capabilities = ('rating', 'time', 'seek', 'volume')
48
43
 
49
44
    def connect(self):
50
 
        """
51
 
            Connects player
 
45
        """Connects player
52
46
            @return: boolean, True if successful, False if not
53
47
        """
54
 
        self.session_bus = dbus.SessionBus()
55
 
        self.dbus_object = self.session_bus.get_object(self.DBUS_NAME,
56
 
            self.DBUS_OBJECT)
 
48
        session_bus = dbus.SessionBus()
 
49
        self.iface = session_bus.get_object(self.DBUS_NAME, self.DBUS_OBJECT)
57
50
        if not self.connected:
58
 
            # this is for MPRIS plugin:
59
 
            #self.session_bus.add_signal_receiver(self.playing_changed_handler,
60
 
            #    "StatusChange", 'org.freedesktop.MediaPlayer',
61
 
            #    self.DBUS_NAME, '/Player')
62
 
            #self.session_bus.add_signal_receiver(self.song_changed_handler,
63
 
            #    "TrackChange", 'org.freedesktop.MediaPlayer',
64
 
            #    self.DBUS_NAME, '/Player')
65
 
            # and this is for latest changes in Exaile  dbus:
66
 
            self.session_bus.add_signal_receiver(self.state_changed_handler,
67
 
                "StateChanged", self.DBUS_NAME,
68
 
                self.DBUS_NAME, self.DBUS_OBJECT)
69
 
            self.session_bus.add_signal_receiver(self.track_changed_handler,
70
 
                "TrackChanged", self.DBUS_NAME,
71
 
                self.DBUS_NAME, self.DBUS_OBJECT)
 
51
            session_bus.add_signal_receiver(self.state_changed_handler,
 
52
                "StateChanged", self.DBUS_NAME, self.DBUS_NAME, self.DBUS_OBJECT)
 
53
            session_bus.add_signal_receiver(self.track_changed_handler,
 
54
                "TrackChanged", self.DBUS_NAME, self.DBUS_NAME, self.DBUS_OBJECT)
72
55
            self.connected = True
73
56
        return True
74
57
 
75
58
    def disconnect(self):
76
 
        """
77
 
            Disconnects player
 
59
        """Disconnects player
78
60
        """
79
61
        if self.connected:
80
 
            #self.session_bus.remove_signal_receiver(self.playing_changed_handler,
81
 
            #    "StatusChange", 'org.freedesktop.MediaPlayer',
82
 
            #    self.DBUS_NAME, '/Player')
83
 
            #self.session_bus.remove_signal_receiver(self.song_changed_handler,
84
 
            #    "TrackChange", 'org.freedesktop.MediaPlayer',
85
 
            #    self.DBUS_NAME, '/Player')
86
 
            #self.connected = False
87
 
            self.session_bus.remove_signal_receiver(self.playing_changed_handler,
88
 
                "StatusChange", self.DBUS_NAME,
89
 
                self.DBUS_NAME, self.DBUS_OBJECT)
90
 
            self.session_bus.remove_signal_receiver(self.song_changed_handler,
91
 
                "TrackChange", self.DBUS_NAME,
92
 
                self.DBUS_NAME, self.DBUS_OBJECT)
 
62
            session_bus = dbus.SessionBus()
 
63
            session_bus.remove_signal_receiver(self.state_changed_handler,
 
64
                "StatusChange", self.DBUS_NAME, self.DBUS_NAME, self.DBUS_OBJECT)
 
65
            session_bus.remove_signal_receiver(self.track_changed_handler,
 
66
                "TrackChange", self.DBUS_NAME, self.DBUS_NAME, self.DBUS_OBJECT)
93
67
            self.connected = False
94
68
 
95
 
    def get_title(self):
96
 
        """
97
 
            @return: string, title of current playing song
98
 
        """
99
 
        try:
100
 
            return self.dbus_object.GetTrackAttr('title')
101
 
        except:
102
 
            return ""
103
 
 
104
 
    def get_album(self):
105
 
        """
106
 
            @return: string, album name of current playing song
107
 
        """
108
 
        try:
109
 
            return self.dbus_object.GetTrackAttr('album')
110
 
        except:
111
 
            return ""
112
 
 
113
 
    def get_artist(self):
114
 
        """
115
 
            @return: string, artist name of current playing song
116
 
        """
117
 
        try:
118
 
            return self.dbus_object.GetTrackAttr('artist')
119
 
        except:
120
 
            return ""
121
 
 
122
69
    def get_rating(self):
123
70
        """
124
71
            @return: integer, [0-5] value, representing rating of current
129
76
        #    so 3 out of 5 starts returns "60.0"
130
77
        #this code works assuming that the rating that get_rating should return is "number of stars out of 5"
131
78
        try:
132
 
            return int((float(self.dbus_object.GetTrackAttr('__rating')) * 5) / 100)
 
79
            return int((float(self.iface.GetTrackAttr('__rating')) * 5) / 100)
133
80
        except:
134
81
            return 0
135
82
 
136
 
    def get_cover_path(self, data=None):
137
 
        """
138
 
            @param data: dictionary, contains info about current playing song.
139
 
                optional
140
 
            @return: string, path to the album art image of current playing
141
 
                songm, (not URI)
142
 
        """
143
 
        return '' #GetCoverData() send real image data and not cover path
144
 
        try:
145
 
            cover = str(self.dbus_object.GetCoverData())
146
 
            if cover:
147
 
                cover = urllib.unquote(cover.encode('utf-8'))
148
 
                if cover[:7] == "file://":
149
 
                    cover = cover[7:]
150
 
                return cover
151
 
        except:
152
 
            pass
153
 
        return ''
154
 
 
155
 
    def get_state(self,data=None):
156
 
        """
157
 
            Returns players actual state.
158
 
            @return: string - playing, paused, stopped
159
 
        """
160
 
        #this is bad, uses MPRIS :(
161
 
        #if not data:
162
 
        #    data = self.dbus_object.GetStatus()
163
 
        #if data[0] == 0:
164
 
        #    return 'playing'
165
 
        #if data[0] == 1:
166
 
        #    return 'paused'
167
 
        #if data[0] == 2:
168
 
        #    return 'stopped'
169
 
 
170
 
        #this is good uses core dbus methods
171
 
        return str(self.dbus_object.GetState())
172
 
 
173
 
    def is_playing(self):
174
 
        """
175
 
            @return: boolean, True if player is playing, False if not
176
 
        """
177
 
        return self.dbus_object.IsPlaying()
178
 
 
179
 
    def previous(self, widget, event):
180
 
        """
181
 
            Changes song to previous
182
 
        """
183
 
        if self.active:
184
 
            self.dbus_object.Prev()
185
 
 
186
 
    def play(self, widget, event):
187
 
        """
188
 
            Plays or pauses the player
189
 
        """
190
 
        if self.active:
191
 
            self.dbus_object.PlayPause()
192
 
 
193
 
    def next(self, widget, event):
194
 
        """
195
 
            Changes song to next
196
 
        """
197
 
        if self.active:
198
 
            self.dbus_object.Next()
199
 
 
200
 
    def get_track(self, data=None):
201
 
        """
202
 
            Prepares a Track object with current playing song data
203
 
 
204
 
            @param data: dictionary, contains info about current playing song.
205
 
                optional
206
 
            @return: Track, object with current playing song data
207
 
        """
208
 
        if not data:
209
 
            data = {
210
 
                'title' : self.get_title(),
211
 
                'album' : self.get_album(),
212
 
                'artist': self.get_artist(),
 
83
    def get_state(self):
 
84
        return State.get(self.iface.GetState())
 
85
 
 
86
    def get_track(self):
 
87
        data = {
 
88
                'title' : self.iface.GetTrackAttr('title'),
 
89
                'album' : self.iface.GetTrackAttr('album'),
 
90
                'artist': self.iface.GetTrackAttr('artist'),
213
91
                'rating': self.get_rating(),
214
 
                'genre' : self.dbus_object.GetTrackAttr('genre'),
215
 
                'tracknumber' : self.dbus_object.GetTrackAttr('tracknumber'),
216
 
                'year'  : self.dbus_object.GetTrackAttr('date'),
217
 
                'location'    : self.dbus_object.GetTrackAttr('__loc')
 
92
                'genre' : self.iface.GetTrackAttr('genre'),
 
93
                'tracknumber' : self.iface.GetTrackAttr('tracknumber'),
 
94
                'year' : self.iface.GetTrackAttr('date'),
 
95
                'location' : urllib.unquote(self.iface.GetTrackAttr('__loc').encode('utf-8')),
 
96
                'rating' : self.get_rating(),
 
97
                'length' : int(float(self.iface.GetTrackAttr('__length')))
218
98
            }
219
 
        else:
220
 
            data['rating'] = self.get_rating()
221
 
 
222
 
        #vals = ('title','album','artist', 'genre', 'year', 'tracknumber',
223
 
        #    'location', 'rating')
224
 
        #for key in [key for key in vals if key not in data]:
225
 
        #    c.warning('EXAILE3: '+ key +' not found in current track')
226
 
        #    data[key] = ''
227
 
 
228
 
        track = Track(
229
 
            title       = data['title'],
230
 
            album       = data['album'],
231
 
            artist      = data['artist'],
232
 
            genre       = data['genre'],
233
 
            year        = data['year'],
234
 
            rating      = data['rating'],
235
 
            tracknumber = data['tracknumber'],
236
 
            location    = urllib.unquote(data['location'].encode('utf-8')),
237
 
            cover       = self.get_cover_path()
238
 
        )
239
 
        return track
240
 
 
241
 
    def can_set_rating(self):
242
 
        """
243
 
            Returns True if players D-Bus interface supports setting rating,
244
 
            return False otherwise
245
 
        """
246
 
        return True
247
 
 
248
 
    def set_rating(self,rating):
 
99
        return Track(**data)
 
100
 
 
101
    def set_rating(self, rating):
249
102
        if 0 <= rating and rating <= 5:
250
103
            rating *= 20.0
251
 
            self.dbus_object.SetTrackAttr('__rating', rating)
 
104
            self.iface.SetTrackAttr('__rating', rating)
 
105
 
 
106
    def get_position(self):
 
107
        data = str(self.iface.CurrentPosition()).split(':')
 
108
        time = 0
 
109
        for t in data:
 
110
            time = time * 60 + int(t)
 
111
        return time
 
112
 
 
113
    def set_position(self, time):
 
114
        self.iface.Seek(float(time))
 
115
 
 
116
    def get_volume(self):
 
117
        return int(float(self.iface.GetVolume()))
 
118
 
 
119
    def set_volume(self, volume):
 
120
        self.iface.ChangeVolume(volume)
 
121
 
 
122
    def previous(self):
 
123
        """
 
124
            Changes song to previous
 
125
        """
 
126
        if self.active:
 
127
            self.iface.Prev()
 
128
 
 
129
    def play(self):
 
130
        """
 
131
            Plays or pauses the player
 
132
        """
 
133
        if self.active:
 
134
            self.iface.PlayPause()
 
135
 
 
136
    def next(self):
 
137
        """
 
138
            Changes song to next
 
139
        """
 
140
        if self.active:
 
141
            self.iface.Next()
252
142
 
253
143
# ================================= HANDLERS ================================= #
254
144
 
255
 
    def playing_changed_handler(self, message):
256
 
        """
257
 
            for MPRIS plugin
258
 
            Handles StatusChanged dbus signal, calls state_handler()
259
 
 
260
 
            @param message: list
261
 
        """
262
 
        self.state_handler(state=self.get_state(message))
263
 
 
264
 
    def song_changed_handler(self, message):
265
 
        """
266
 
            for MPRIS plugin
267
 
            Handles TrackChanged dbus signal, calls state_handler()
268
 
 
269
 
            @param message: dictionary with current playing song stats
270
 
        """
271
 
        track = self.get_track(message)
272
 
        self.state_handler(track=track)
273
 
 
274
145
    def state_changed_handler(self):
275
 
        """
276
 
            Handles StateChanged dbus signal, calls state_handler()
277
 
        """
278
 
        self.state_handler(state=self.get_state())
 
146
        self.cg.update(STATE, self.get_state())
279
147
 
280
148
    def track_changed_handler(self):
281
 
        """
282
 
            Handles TrackChanged dbus signal, calls state_handler()
283
 
        """
284
 
        track = self.get_track()
285
 
        self.state_handler(track=track)
 
149
        self.cg.update(TRACK, self.get_track())