Gentoo Websites Logo
Go to: Gentoo Home Documentation Forums Lists Bugs Planet Store Wiki Get Gentoo!
View | Details | Raw Unified | Return to bug 246168
Collapse All | Expand All

(-)plugins-old/coherence/upnp_coherence/MediaPlayer.py (-23 / +57 lines)
Lines 10-16 Link Here
10
from coherence.upnp.core.soap_service import errorCode
10
from coherence.upnp.core.soap_service import errorCode
11
from coherence.upnp.core import DIDLLite
11
from coherence.upnp.core import DIDLLite
12
12
13
import louie
13
import coherence.extern.louie as louie
14
14
15
from coherence.extern.simple_plugin import Plugin
15
from coherence.extern.simple_plugin import Plugin
16
16
Lines 26-32 Link Here
26
    logCategory = 'rb_media_renderer'
26
    logCategory = 'rb_media_renderer'
27
27
28
    implements = ['MediaRenderer']
28
    implements = ['MediaRenderer']
29
    vendor_value_defaults = {'RenderingControl': {'A_ARG_TYPE_Channel':'Master'}}
29
    vendor_value_defaults = {'RenderingControl': {'A_ARG_TYPE_Channel':'Master'},
30
                             'AVTransport': {'A_ARG_TYPE_SeekMode':('ABS_TIME','REL_TIME')}}
30
    vendor_range_defaults = {'RenderingControl': {'Volume': {'maximum':100}}}
31
    vendor_range_defaults = {'RenderingControl': {'Volume': {'maximum':100}}}
31
32
32
    def __init__(self, device, **kwargs):
33
    def __init__(self, device, **kwargs):
Lines 36-52 Link Here
36
37
37
        self.player = None
38
        self.player = None
38
        self.metadata = None
39
        self.metadata = None
39
        self.host = '127.0.0.1'
40
        self.name = "Rhythmbox on %s" % self.server.coherence.hostname
40
        self.name = "Rhythmbox on %s" % self.server.coherence.hostname
41
41
42
        self.player = self.shell.get_player()
42
        self.player = self.shell.get_player()
43
        self.player.connect ('playing-song-changed',
44
                                 self.playing_song_changed),
45
        self.player.connect ('playing-changed',
46
                                 self.playing_changed)
47
        self.player.connect ('elapsed-changed',
48
                                 self.elapsed_changed)
49
        self.player.connect("notify::volume", self.volume_changed)
50
        louie.send('Coherence.UPnP.Backend.init_completed', None, backend=self)
43
        louie.send('Coherence.UPnP.Backend.init_completed', None, backend=self)
51
44
52
        self.playing = False
45
        self.playing = False
Lines 226-249 Link Here
226
        self.metadata = metadata
219
        self.metadata = metadata
227
        self.tags = {}
220
        self.tags = {}
228
221
229
        if len(self.metadata)>0:
222
        was_playing = self.playing
230
            elt = DIDLLite.DIDLElement.fromString(self.metadata)
223
224
        if was_playing == True:
225
            self.stop()
226
227
        if len(metadata)>0:
228
            elt = DIDLLite.DIDLElement.fromString(metadata)
231
            if elt.numItems() == 1:
229
            if elt.numItems() == 1:
232
                item = elt.getItems()[0]
230
                item = elt.getItems()[0]
233
231
234
                self.entry = self.shell.props.db.entry_lookup_by_location(uri)
232
                if uri.startswith('track-'):
235
                self.warning("check for entry %r %r", self.entry, item.server_uuid)
233
                    self.entry = self.shell.props.db.entry_lookup_by_id(int(uri[6:]))
234
                else:
235
                    self.entry = self.shell.props.db.entry_lookup_by_location(uri)
236
                self.warning("check for entry %r %r %r", self.entry,item.server_uuid,uri)
236
                if self.entry == None:
237
                if self.entry == None:
237
                    if item.server_uuid is not None:
238
                    if item.server_uuid is not None:
238
                        entry_type = self.shell.props.db.entry_register_type("CoherenceUpnp:" + item.server_uuid)
239
                        entry_type = self.shell.props.db.entry_register_type("CoherenceUpnp:" + item.server_uuid)
239
                        self.entry = self.shell.props.db.entry_new(entry_type, uri)
240
                        self.entry = self.shell.props.db.entry_new(entry_type, uri)
240
                        self.warning("create new entry %r", self.entry)
241
                        self.warning("create new entry %r", self.entry)
241
                    else:
242
                    else:
242
                        self.shell.load_uri(uri,play=False)
243
                        entry_type = self.shell.props.db.entry_register_type("CoherencePlayer")
243
                        self.entry = self.shell.props.db.entry_lookup_by_location(uri)
244
                        self.entry = self.shell.props.db.entry_new(entry_type, uri)
244
                        self.warning("load and check for entry %r", self.entry)
245
                        self.warning("load and check for entry %r", self.entry)
245
246
246
247
                duration = None
247
                duration = None
248
                size = None
248
                size = None
249
                bitrate = None
249
                bitrate = None
Lines 283-295 Link Here
283
                    self.shell.props.db.set(self.entry, rhythmdb.PROP_FILE_SIZE,int(size))
283
                    self.shell.props.db.set(self.entry, rhythmdb.PROP_FILE_SIZE,int(size))
284
284
285
        else:
285
        else:
286
            self.shell.load_uri(uri,play=False)
286
            if uri.startswith('track-'):
287
            self.entry = self.shell.props.db.entry_lookup_by_location(uri)
287
                self.entry = self.shell.props.db.entry_lookup_by_id(int(uri[6:]))
288
            else:
289
                #self.shell.load_uri(uri,play=False)
290
                #self.entry = self.shell.props.db.entry_lookup_by_location(uri)
291
                entry_type = self.shell.props.db.entry_register_type("CoherencePlayer")
292
                self.entry = self.shell.props.db.entry_new(entry_type, uri)
293
288
294
289
        self.playing = False
295
        self.playing = False
296
        self.metadata = metadata
290
297
291
        connection_id = self.server.connection_manager_server.lookup_avt_id(self.current_connection_id)
298
        connection_id = self.server.connection_manager_server.lookup_avt_id(self.current_connection_id)
292
        self.server.av_transport_server.set_variable(connection_id, 'CurrentTransportActions','Play,Stop,Pause')
299
        self.server.av_transport_server.set_variable(connection_id, 'CurrentTransportActions','Play,Stop,Pause,Seek')
293
        self.server.av_transport_server.set_variable(connection_id, 'NumberOfTracks',1)
300
        self.server.av_transport_server.set_variable(connection_id, 'NumberOfTracks',1)
294
        self.server.av_transport_server.set_variable(connection_id, 'CurrentTrackURI',uri)
301
        self.server.av_transport_server.set_variable(connection_id, 'CurrentTrackURI',uri)
295
        self.server.av_transport_server.set_variable(connection_id, 'AVTransportURI',uri)
302
        self.server.av_transport_server.set_variable(connection_id, 'AVTransportURI',uri)
Lines 297-302 Link Here
297
        self.server.av_transport_server.set_variable(connection_id, 'CurrentTrackURI',uri)
304
        self.server.av_transport_server.set_variable(connection_id, 'CurrentTrackURI',uri)
298
        self.server.av_transport_server.set_variable(connection_id, 'CurrentTrackMetaData',metadata)
305
        self.server.av_transport_server.set_variable(connection_id, 'CurrentTrackMetaData',metadata)
299
306
307
        if was_playing == True:
308
            self.play()
309
300
    def start(self, uri):
310
    def start(self, uri):
301
        self.load(uri)
311
        self.load(uri)
302
        self.play()
312
        self.play()
Lines 328-339 Link Here
328
        #    self.server.connection_manager_server.lookup_avt_id(self.current_connection_id),\
338
        #    self.server.connection_manager_server.lookup_avt_id(self.current_connection_id),\
329
        #                     'TransportState', 'PAUSED_PLAYBACK')
339
        #                     'TransportState', 'PAUSED_PLAYBACK')
330
340
331
    def seek(self, location):
341
    def seek(self, location, old_state):
332
        """
342
        """
333
        @param location:    simple number = time to seek to, in seconds
343
        @param location:    simple number = time to seek to, in seconds
334
                            +nL = relative seek forward n seconds
344
                            +nL = relative seek forward n seconds
335
                            -nL = relative seek backwards n seconds
345
                            -nL = relative seek backwards n seconds
336
        """
346
        """
347
        self.warning("player seek %r", location)
348
        self.player.seek(location)
349
        self.server.av_transport_server.set_variable(0, 'TransportState', old_state)
337
350
338
    def mute(self):
351
    def mute(self):
339
        self.muted_volume = self.volume
352
        self.muted_volume = self.volume
Lines 368-376 Link Here
368
        self.player.set_volume(float(volume/100.0))
381
        self.player.set_volume(float(volume/100.0))
369
382
370
    def upnp_init(self):
383
    def upnp_init(self):
384
        self.player.connect ('playing-song-changed',
385
                                 self.playing_song_changed),
386
        self.player.connect ('playing-changed',
387
                                 self.playing_changed)
388
        self.player.connect ('elapsed-changed',
389
                                 self.elapsed_changed)
390
        self.player.connect("notify::volume", self.volume_changed)
391
371
        self.current_connection_id = None
392
        self.current_connection_id = None
372
        self.server.connection_manager_server.set_variable(0, 'SinkProtocolInfo',
393
        self.server.connection_manager_server.set_variable(0, 'SinkProtocolInfo',
373
                            ['internal:%s:*:*' % self.host,
394
                            ['rhythmbox:%s:audio/mpeg:*' % self.server.coherence.hostname,
374
                             'http-get:*:audio/mpeg:*'],
395
                             'http-get:*:audio/mpeg:*'],
375
                            default=True)
396
                            default=True)
376
        self.server.av_transport_server.set_variable(0, 'TransportState', 'NO_MEDIA_PRESENT', default=True)
397
        self.server.av_transport_server.set_variable(0, 'TransportState', 'NO_MEDIA_PRESENT', default=True)
Lines 396-401 Link Here
396
        self.stop()
417
        self.stop()
397
        return {}
418
        return {}
398
419
420
    def upnp_Seek(self, *args, **kwargs):
421
        InstanceID = int(kwargs['InstanceID'])
422
        Unit = kwargs['Unit']
423
        Target = kwargs['Target']
424
        if Unit in ['ABS_TIME','REL_TIME']:
425
            old_state = self.server.av_transport_server.get_variable(0, 'TransportState')
426
            self.server.av_transport_server.set_variable(0, 'TransportState', 'TRANSITIONING')
427
            h,m,s = Target.split(':')
428
            seconds = int(h)*3600 + int(m)*60 + int(s)
429
            self.seek(seconds, old_state)
430
        return {}
431
399
    def upnp_SetAVTransportURI(self, *args, **kwargs):
432
    def upnp_SetAVTransportURI(self, *args, **kwargs):
400
        InstanceID = int(kwargs['InstanceID'])
433
        InstanceID = int(kwargs['InstanceID'])
401
        CurrentURI = kwargs['CurrentURI']
434
        CurrentURI = kwargs['CurrentURI']
Lines 404-415 Link Here
404
        #print '>>>', local_protocol_infos
437
        #print '>>>', local_protocol_infos
405
        if len(CurrentURIMetaData)==0:
438
        if len(CurrentURIMetaData)==0:
406
            self.load(CurrentURI,CurrentURIMetaData)
439
            self.load(CurrentURI,CurrentURIMetaData)
440
            return {}
407
        else:
441
        else:
408
            elt = DIDLLite.DIDLElement.fromString(CurrentURIMetaData)
442
            elt = DIDLLite.DIDLElement.fromString(CurrentURIMetaData)
409
            #import pdb; pdb.set_trace()
443
            #import pdb; pdb.set_trace()
410
            if elt.numItems() == 1:
444
            if elt.numItems() == 1:
411
                item = elt.getItems()[0]
445
                item = elt.getItems()[0]
412
                res = item.res.get_matching(local_protocol_infos, protocol_type='internal')
446
                res = item.res.get_matching(local_protocol_infos, protocol_type='rhythmbox')
413
                if len(res) == 0:
447
                if len(res) == 0:
414
                    res = item.res.get_matching(local_protocol_infos)
448
                    res = item.res.get_matching(local_protocol_infos)
415
                if len(res) > 0:
449
                if len(res) > 0:
(-)plugins-old/coherence/upnp_coherence/MediaStore.py (-49 / +69 lines)
Lines 5-21 Link Here
5
# Copyright 2007, Frank Scholz <coherence@beebits.net>
5
# Copyright 2007, Frank Scholz <coherence@beebits.net>
6
6
7
import rhythmdb
7
import rhythmdb
8
import louie
8
import coherence.extern.louie as louie
9
import urllib
9
import urllib
10
from coherence.upnp.core import DIDLLite
10
from coherence.upnp.core import DIDLLite
11
11
12
from coherence import log
12
from coherence.backend import BackendItem, BackendStore
13
13
14
ROOT_CONTAINER_ID = 0
14
ROOT_CONTAINER_ID = 0
15
AUDIO_CONTAINER = 10
15
AUDIO_CONTAINER = 100
16
AUDIO_ALL_CONTAINER_ID = 11
16
AUDIO_ALL_CONTAINER_ID = 101
17
AUDIO_ARTIST_CONTAINER_ID = 12
17
AUDIO_ARTIST_CONTAINER_ID = 102
18
AUDIO_ALBUM_CONTAINER_ID = 13
18
AUDIO_ALBUM_CONTAINER_ID = 103
19
19
20
CONTAINER_COUNT = 10000
20
CONTAINER_COUNT = 10000
21
21
Lines 23-29 Link Here
23
23
24
# most of this class is from Coherence, originally under the MIT licence
24
# most of this class is from Coherence, originally under the MIT licence
25
25
26
class Container(log.Loggable):
26
class Container(BackendItem):
27
27
28
    logCategory = 'rb_media_store'
28
    logCategory = 'rb_media_store'
29
29
Lines 46-52 Link Here
46
46
47
    def get_children(self,start=0,request_count=0):
47
    def get_children(self,start=0,request_count=0):
48
        if callable(self.children):
48
        if callable(self.children):
49
            children = self.children()
49
            children = self.children(self.id)
50
        else:
50
        else:
51
            children = self.children
51
            children = self.children
52
52
Lines 57-69 Link Here
57
            return children[start:request_count]
57
            return children[start:request_count]
58
58
59
    def get_child_count(self):
59
    def get_child_count(self):
60
        return len(self.get_children())
60
61
61
        if callable(self.children):
62
    def get_item(self, parent_id=None):
62
            return len(self.children())
63
        else:
64
            return len(self.children)
65
66
    def get_item(self):
67
        self.item.childCount = self.get_child_count()
63
        self.item.childCount = self.get_child_count()
68
        return self.item
64
        return self.item
69
65
Lines 74-84 Link Here
74
        return self.id
70
        return self.id
75
71
76
72
77
class Album(log.Loggable):
73
class Album(BackendItem):
78
74
79
    logCategory = 'rb_media_store'
75
    logCategory = 'rb_media_store'
80
76
81
    def __init__(self, store, title, id):
77
    def __init__(self, store, title, id, parent_id):
82
        self.id = id
78
        self.id = id
83
        self.title = title
79
        self.title = title
84
        self.store = store
80
        self.store = store
Lines 103-109 Link Here
103
        def collate (model, path, iter):
99
        def collate (model, path, iter):
104
            self.info("Album get_children %r %r %r" %(model, path, iter))
100
            self.info("Album get_children %r %r %r" %(model, path, iter))
105
            id = model.get(iter, 0)[0]
101
            id = model.get(iter, 0)[0]
106
            children.append(Track(self.store,id))
102
            children.append(Track(self.store,id,self.id))
107
103
108
        self.tracks_per_album_query.foreach(collate)
104
        self.tracks_per_album_query.foreach(collate)
109
105
Lines 117-124 Link Here
117
    def get_child_count(self):
113
    def get_child_count(self):
118
        return len(self.get_children())
114
        return len(self.get_children())
119
115
120
    def get_item(self):
116
    def get_item(self, parent_id = AUDIO_ALBUM_CONTAINER_ID):
121
        item = DIDLLite.MusicAlbum(self.id, AUDIO_ALBUM_CONTAINER_ID, self.title)
117
        item = DIDLLite.MusicAlbum(self.id, parent_id, self.title)
122
        return item
118
        return item
123
119
124
    def get_id(self):
120
    def get_id(self):
Lines 131-141 Link Here
131
        return self.cover
127
        return self.cover
132
128
133
129
134
class Artist(log.Loggable):
130
class Artist(BackendItem):
135
131
136
    logCategory = 'rb_media_store'
132
    logCategory = 'rb_media_store'
137
133
138
    def __init__(self, store, name, id):
134
    def __init__(self, store, name, id, parent_id):
139
        self.id = id
135
        self.id = id
140
        self.name = name
136
        self.name = name
141
        self.store = store
137
        self.store = store
Lines 173-180 Link Here
173
    def get_child_count(self):
169
    def get_child_count(self):
174
        return len(self.get_children())
170
        return len(self.get_children())
175
171
176
    def get_item(self):
172
    def get_item(self, parent_id = AUDIO_ARTIST_CONTAINER_ID):
177
        item = DIDLLite.MusicArtist(self.id, AUDIO_ARTIST_CONTAINER_ID, self.name)
173
        item = DIDLLite.MusicArtist(self.id, parent_id, self.name)
178
        return item
174
        return item
179
175
180
    def get_id(self):
176
    def get_id(self):
Lines 184-199 Link Here
184
        return self.name
180
        return self.name
185
181
186
182
187
class Track(log.Loggable):
183
class Track(BackendItem):
188
184
189
    logCategory = 'rb_media_store'
185
    logCategory = 'rb_media_store'
190
186
191
    def __init__(self, store, id):
187
    def __init__(self, store, id, parent_id):
192
        self.store = store
188
        self.store = store
193
        if type(id) == int:
189
        if type(id) == int:
194
            self.id = id
190
            self.id = id
195
        else:
191
        else:
196
            self.id = self.store.db.entry_get (id, rhythmdb.PROP_ENTRY_ID)
192
            self.id = self.store.db.entry_get (id, rhythmdb.PROP_ENTRY_ID)
193
        self.parent_id = parent_id
197
194
198
    def get_children(self, start=0, request_count=0):
195
    def get_children(self, start=0, request_count=0):
199
        return []
196
        return []
Lines 201-209 Link Here
201
    def get_child_count(self):
198
    def get_child_count(self):
202
        return 0
199
        return 0
203
200
204
    def get_item(self):
201
    def get_item(self, parent_id=None):
205
202
206
        self.info("Track get_item %r" %(self.id))
203
        self.info("Track get_item %r @ %r" %(self.id,self.parent_id))
207
204
208
        host = ""
205
        host = ""
209
206
Lines 226-234 Link Here
226
            mimetype = "audio/mpeg"
223
            mimetype = "audio/mpeg"
227
        size = self.store.db.entry_get(entry, rhythmdb.PROP_FILE_SIZE)
224
        size = self.store.db.entry_get(entry, rhythmdb.PROP_FILE_SIZE)
228
225
226
        album = self.store.db.entry_get(entry, rhythmdb.PROP_ALBUM)
227
        if self.parent_id == None:
228
            try:
229
                self.parent_id = self.store.albums[album].id
230
            except:
231
                pass
232
229
        # create item
233
        # create item
230
        item = DIDLLite.MusicTrack(self.id + TRACK_COUNT)
234
        item = DIDLLite.MusicTrack(self.id + TRACK_COUNT,self.parent_id)
231
        item.album = self.store.db.entry_get(entry, rhythmdb.PROP_ALBUM)
235
        item.album = album
236
232
        item.artist = self.store.db.entry_get(entry, rhythmdb.PROP_ARTIST)
237
        item.artist = self.store.db.entry_get(entry, rhythmdb.PROP_ARTIST)
233
        #item.date =
238
        #item.date =
234
        item.genre = self.store.db.entry_get(entry, rhythmdb.PROP_GENRE)
239
        item.genre = self.store.db.entry_get(entry, rhythmdb.PROP_GENRE)
Lines 239-251 Link Here
239
        #self.warning("cover for %r is %r", item.title, cover)
244
        #self.warning("cover for %r is %r", item.title, cover)
240
        #item.albumArtURI = ## can we somehow store art in the upnp share??
245
        #item.albumArtURI = ## can we somehow store art in the upnp share??
241
246
242
        # add internal resource
243
        #res = DIDLLite.Resource(location, 'internal:%s:%s:*' % (host, mimetype))
244
        #res.size = size
245
        #res.duration = duration
246
        #res.bitrate = bitrate
247
        #item.res.append(res)
248
249
        # add http resource
247
        # add http resource
250
        res = DIDLLite.Resource(self.get_url(), 'http-get:*:%s:*' % mimetype)
248
        res = DIDLLite.Resource(self.get_url(), 'http-get:*:%s:*' % mimetype)
251
        if size > 0:
249
        if size > 0:
Lines 256-261 Link Here
256
            res.bitrate = str(bitrate)
254
            res.bitrate = str(bitrate)
257
        item.res.append(res)
255
        item.res.append(res)
258
256
257
        # add internal resource
258
        res = DIDLLite.Resource('track-%d' % self.id, 'rhythmbox:%s:%s:*' % (self.store.server.coherence.hostname, mimetype))
259
        if size > 0:
260
            res.size = size
261
        if duration > 0:
262
            res.duration = str(duration)
263
        if bitrate > 0:
264
            res.bitrate = str(bitrate)
265
        item.res.append(res)
266
259
        return item
267
        return item
260
268
261
    def get_id(self):
269
    def get_id(self):
Lines 280-296 Link Here
280
288
281
        return location
289
        return location
282
290
283
class MediaStore(log.Loggable):
291
class MediaStore(BackendStore):
284
292
285
    logCategory = 'rb_media_store'
293
    logCategory = 'rb_media_store'
286
    implements = ['MediaServer']
294
    implements = ['MediaServer']
287
295
288
    def __init__(self, server, **kwargs):
296
    def __init__(self, server, **kwargs):
289
        print "creating UPnP MediaStore"
297
        self.warning("__init__ MediaStore %r", kwargs)
290
        self.server = server
298
        self.server = server
291
        self.db = kwargs['db']
299
        self.db = kwargs['db']
292
        self.plugin = kwargs['plugin']
300
        self.plugin = kwargs['plugin']
293
301
302
        self.wmc_mapping.update({'4': lambda : self.get_by_id(AUDIO_ALL_CONTAINER_ID),    # all tracks
303
                                 '7': lambda : self.get_by_id(AUDIO_ALBUM_CONTAINER_ID),    # all albums
304
                                 '6': lambda : self.get_by_id(AUDIO_ARTIST_CONTAINER_ID),    # all artists
305
                                })
306
294
        self.update_id = 0
307
        self.update_id = 0
295
308
296
        self.next_id = CONTAINER_COUNT
309
        self.next_id = CONTAINER_COUNT
Lines 340-350 Link Here
340
    def get_by_id(self,id):
353
    def get_by_id(self,id):
341
354
342
        self.info("looking for id %r", id)
355
        self.info("looking for id %r", id)
343
        id = int(id)
356
        id = id.split('@',1)
344
        if id < TRACK_COUNT:
357
        item_id = id[0]
345
            item = self.containers[id]
358
        item_id = int(item_id)
359
        if item_id < TRACK_COUNT:
360
            try:
361
                item = self.containers[item_id]
362
            except KeyError:
363
                item = None
346
        else:
364
        else:
347
            item = Track(self, (id - TRACK_COUNT))
365
            item = Track(self, (item_id - TRACK_COUNT),None)
348
366
349
        return item
367
        return item
350
368
Lines 356-379 Link Here
356
    def upnp_init(self):
374
    def upnp_init(self):
357
        if self.server:
375
        if self.server:
358
            self.server.connection_manager_server.set_variable(0, 'SourceProtocolInfo', [
376
            self.server.connection_manager_server.set_variable(0, 'SourceProtocolInfo', [
359
                #'internal:%s:*:*' % self.name,
377
                'rhythmbox:%s:*:*' % self.server.coherence.hostname,
360
                'http-get:*:audio/mpeg:*',
378
                'http-get:*:audio/mpeg:*',
361
            ])
379
            ])
380
        self.warning("__init__ MediaStore initialized")
381
362
382
363
    def children_tracks(self):
383
    def children_tracks(self, parent_id):
364
        tracks = []
384
        tracks = []
365
385
366
        def track_cb (entry):
386
        def track_cb (entry):
367
            if self.db.entry_get (entry, rhythmdb.PROP_HIDDEN):
387
            if self.db.entry_get (entry, rhythmdb.PROP_HIDDEN):
368
                return
388
                return
369
            id = self.db.entry_get (entry, rhythmdb.PROP_ENTRY_ID)
389
            id = self.db.entry_get (entry, rhythmdb.PROP_ENTRY_ID)
370
            track = Track(self, id)
390
            track = Track(self, id, parent_id)
371
            tracks.append(track)
391
            tracks.append(track)
372
392
373
        self.db.entry_foreach_by_type (self.db.entry_type_get_by_name('song'), track_cb)
393
        self.db.entry_foreach_by_type (self.db.entry_type_get_by_name('song'), track_cb)
374
        return tracks
394
        return tracks
375
395
376
    def children_albums(self):
396
    def children_albums(self,parent_id):
377
        albums =  {}
397
        albums =  {}
378
398
379
        self.info('children_albums')
399
        self.info('children_albums')
Lines 389-395 Link Here
389
            self.info("children_albums collate %r %r", name, priority)
409
            self.info("children_albums collate %r %r", name, priority)
390
            if priority is False:
410
            if priority is False:
391
                id = self.get_next_container_id()
411
                id = self.get_next_container_id()
392
                album = Album(self, name, id)
412
                album = Album(self, name, id,parent_id)
393
                self.containers[id] = album
413
                self.containers[id] = album
394
                albums[name] = album
414
                albums[name] = album
395
415
Lines 401-407 Link Here
401
        albums.sort(cmp=album_sort)
421
        albums.sort(cmp=album_sort)
402
        return albums
422
        return albums
403
423
404
    def children_artists(self,killbug=False):
424
    def children_artists(self,parent_id):
405
        artists = []
425
        artists = []
406
426
407
        self.info('children_artists')
427
        self.info('children_artists')
Lines 411-417 Link Here
411
            priority = model.get(iter, 1)[0]
431
            priority = model.get(iter, 1)[0]
412
            if priority is False:
432
            if priority is False:
413
                id = self.get_next_container_id()
433
                id = self.get_next_container_id()
414
                artist = Artist(self,name, id)
434
                artist = Artist(self,name, id,parent_id)
415
                self.containers[id] = artist
435
                self.containers[id] = artist
416
                artists.append(artist)
436
                artists.append(artist)
417
437
(-)plugins-old/coherence/upnp_coherence/UpnpSource.py (-49 / +13 lines)
Lines 2-8 Link Here
2
# http://opensource.org/licenses/mit-license.php
2
# http://opensource.org/licenses/mit-license.php
3
#
3
#
4
# Copyright 2007, James Livingston  <doclivingston@gmail.com>
4
# Copyright 2007, James Livingston  <doclivingston@gmail.com>
5
# Copyright 2007, Frank Scholz <coherence@beebits.net>
5
# Copyright 2007,2008 Frank Scholz <coherence@beebits.net>
6
6
7
import rb, rhythmdb
7
import rb, rhythmdb
8
import gobject, gtk
8
import gobject, gtk
Lines 10-15 Link Here
10
from coherence import __version_info__ as coherence_version
10
from coherence import __version_info__ as coherence_version
11
11
12
from coherence import log
12
from coherence import log
13
from coherence.upnp.core import DIDLLite
13
14
14
class UpnpSource(rb.BrowserSource,log.Loggable):
15
class UpnpSource(rb.BrowserSource,log.Loggable):
15
16
Lines 18-24 Link Here
18
    __gproperties__ = {
19
    __gproperties__ = {
19
        'plugin': (rb.Plugin, 'plugin', 'plugin', gobject.PARAM_WRITABLE|gobject.PARAM_CONSTRUCT_ONLY),
20
        'plugin': (rb.Plugin, 'plugin', 'plugin', gobject.PARAM_WRITABLE|gobject.PARAM_CONSTRUCT_ONLY),
20
        'client': (gobject.TYPE_PYOBJECT, 'client', 'client', gobject.PARAM_WRITABLE|gobject.PARAM_CONSTRUCT_ONLY),
21
        'client': (gobject.TYPE_PYOBJECT, 'client', 'client', gobject.PARAM_WRITABLE|gobject.PARAM_CONSTRUCT_ONLY),
21
        'usn': (gobject.TYPE_PYOBJECT, 'usn', 'usn', gobject.PARAM_WRITABLE|gobject.PARAM_CONSTRUCT_ONLY),
22
        'udn': (gobject.TYPE_PYOBJECT, 'udn', 'udn', gobject.PARAM_WRITABLE|gobject.PARAM_CONSTRUCT_ONLY),
22
    }
23
    }
23
24
24
    def __init__(self):
25
    def __init__(self):
Lines 37-44 Link Here
37
        elif property.name == 'client':
38
        elif property.name == 'client':
38
            self.__client = value
39
            self.__client = value
39
            self.props.name = self.__client.device.get_friendly_name()
40
            self.props.name = self.__client.device.get_friendly_name()
40
        elif property.name == 'usn':
41
        elif property.name == 'udn':
41
            self.__usn = value
42
            self.__udn = value
42
        else:
43
        else:
43
            raise AttributeError, 'unknown property %s' % property.name
44
            raise AttributeError, 'unknown property %s' % property.name
44
45
Lines 59-73 Link Here
59
60
60
61
61
    def load_db(self, id):
62
    def load_db(self, id):
62
        if coherence_version < (0,5,1):
63
        d = self.__client.content_directory.browse(id, browse_flag='BrowseDirectChildren', process_result=False, backward_compatibility=False)
63
            d = self.__client.content_directory.browse(id, browse_flag='BrowseDirectChildren', backward_compatibility=False)
64
        d.addCallback(self.process_media_server_browse, self.__udn)
64
        else:
65
            d = self.__client.content_directory.browse(id, browse_flag='BrowseDirectChildren', process_result=False, backward_compatibility=False)
66
        d.addCallback(self.process_media_server_browse, self.__usn)
67
65
68
66
69
    def state_variable_change(self, variable, usn=None):
67
    def state_variable_change(self, variable, udn=None):
70
        print "%s changed from %s to %s" % (variable.name, variable.old_value, variable.value)
68
        self.info("%s changed from >%s< to >%s<", variable.name, variable.old_value, variable.value)
71
        if variable.old_value == '':
69
        if variable.old_value == '':
72
            return
70
            return
73
71
Lines 79-90 Link Here
79
                container = changes.pop(0).strip()
77
                container = changes.pop(0).strip()
80
                update_id = changes.pop(0).strip()
78
                update_id = changes.pop(0).strip()
81
                if container in self.container_watch:
79
                if container in self.container_watch:
82
                    print "we have a change in %s, container needs a reload" % container
80
                    self.info("we have a change in %r, container needs a reload", container)
83
                    self.load_db(container)
81
                    self.load_db(container)
84
82
85
83
86
    def new_process_media_server_browse(self, results, usn):
84
    def new_process_media_server_browse(self, results, udn):
87
        for item in results:
85
        didl = DIDLLite.DIDLElement.fromString(results['Result'])
86
        for item in didl.getItems():
88
            self.info("process_media_server_browse %r %r", item.id, item)
87
            self.info("process_media_server_browse %r %r", item.id, item)
89
            if item.upnp_class.startswith('object.container'):
88
            if item.upnp_class.startswith('object.container'):
90
                self.load_db(item.id)
89
                self.load_db(item.id)
Lines 142-180 Link Here
142
141
143
                    self.__db.commit()
142
                    self.__db.commit()
144
143
145
146
    def old_process_media_server_browse(self, results, usn):
147
        for k,v in results.iteritems():
148
            if k == 'items':
149
                for id, values in v.iteritems():
150
                    if values['upnp_class'].startswith('object.container'):
151
                        self.load_db(id)
152
                    if values['upnp_class'].startswith('object.item.audioItem'):
153
                        # (url, [method, something which is in asterix,  format, semicolon delimited key=value map of something])
154
                        resources = [(k, v.split(':')) for (k, v) in values['resources'].iteritems()]
155
                        # break data into map
156
                        for r in resources:
157
                            if r[1][3] is not '*':
158
                                r[1][3] = dict([v.split('=') for v in r[1][3].split(';')])
159
                            else:
160
                                r[1][3] = dict()
161
162
                        url = None
163
                        for r in resources:
164
                            if r[1][3].has_key('DLNA.ORG_CI') and r[1][3]['DLNA.ORG_CI'] is not '1':
165
                                url = r[0]
166
                                break
167
168
                        if url is None:
169
                            # use transcoded format, since we can't find a normal one
170
                            url = resources[0][0]
171
172
                        entry = self.__db.entry_lookup_by_location (url)
173
                        if entry == None:
174
                            entry = self.__db.entry_new(self.__entry_type, url)
175
176
                        self.__db.set(entry, rhythmdb.PROP_TITLE, values['title'])
177
178
                        self.__db.commit()
179
180
gobject.type_register(UpnpSource)
144
gobject.type_register(UpnpSource)

Return to bug 246168