~ubuntu-branches/ubuntu/hardy/coherence/hardy

« back to all changes in this revision

Viewing changes to coherence/backends/elisa_storage.py

  • Committer: Bazaar Package Importer
  • Author(s): Arnaud Quette
  • Date: 2007-08-02 10:48:40 UTC
  • Revision ID: james.westby@ubuntu.com-20070802104840-ip4jij6unufqno1p
Tags: upstream-0.4.0
ImportĀ upstreamĀ versionĀ 0.4.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
# Licensed under the MIT license
 
2
# http://opensource.org/licenses/mit-license.php
 
3
 
 
4
# Copyright 2006, Frank Scholz <coherence@beebits.net>
 
5
 
 
6
import re
 
7
 
 
8
from twisted.spread import pb
 
9
from twisted.internet import reactor
 
10
from twisted.python import failure
 
11
 
 
12
from coherence.upnp.core.DIDLLite import classChooser, Container, Resource, DIDLElement
 
13
from coherence.upnp.core.soap_service import errorCode
 
14
 
 
15
import louie
 
16
 
 
17
class ElisaMediaStore:
 
18
 
 
19
    """ this is a backend to the Elisa Media DB
 
20
 
 
21
        Elisa needs to expose two methods
 
22
 
 
23
        get_root_id(media_type)
 
24
            if media_type == '*'
 
25
                this returns the root id of the media collection
 
26
            if media_type == 'audio'
 
27
                this returns the root id of the audio collection
 
28
 
 
29
        get_item_by_id(id)
 
30
            this returns a dict with the following keys:
 
31
            id = id in the media db
 
32
            parent_id = parent_id in the media db
 
33
            name = title, album name or basename
 
34
            mimetype = 'directory' or real mimetype
 
35
            children = list of objects for which this item is the parent
 
36
            location = filesystem path if item is a file
 
37
            cover = url by which the cover image can be retrieved  (OPTIONAL)
 
38
            size = in bytes (OPTIONAL)
 
39
    """
 
40
 
 
41
    implements = ['MediaServer']
 
42
 
 
43
    def __init__(self, server, **kwargs):
 
44
        self.name = kwargs.get('name','Elisa')
 
45
        self.host = kwargs.get('host','127.0.0.1')
 
46
        self.urlbase = kwargs.get('urlbase','')
 
47
        ignore_patterns = kwargs.get('ignore_patterns',[])
 
48
 
 
49
        if self.urlbase[len(self.urlbase)-1] != '/':
 
50
            self.urlbase += '/'
 
51
        self.server = server
 
52
        self.update_id = 0
 
53
        self.root_id = 0
 
54
        self.get_root_id()
 
55
 
 
56
    def __repr__(self):
 
57
        return "Elisa storage"
 
58
 
 
59
    def get_store(self):
 
60
        factory = pb.PBClientFactory()
 
61
        factory.noisy = False
 
62
        reactor.connectTCP(self.host, 8789, factory)
 
63
        return factory.getRootObject()
 
64
 
 
65
    def get_by_id(self,id):
 
66
        try:
 
67
            return self.store[int(id)]
 
68
        except:
 
69
            return None
 
70
 
 
71
    def set_root_id( self, id):
 
72
        self.root_id = id
 
73
        louie.send('Coherence.UPnP.Backend.init_completed', None, backend=self)
 
74
 
 
75
    def get_root_id( self, media_type='audio'):
 
76
        """ ask Elisa to tell us the id of the top item
 
77
            representing the media_type == 'something' collection """
 
78
        store = self.get_store()
 
79
        dfr = store.addCallback(lambda object:
 
80
                                object.callRemote('get_cache_manager'))
 
81
        dfr.addCallback(lambda cache_mgr:
 
82
                        cache_mgr.callRemote("get_media_root_id", media_type))
 
83
        dfr.addCallback(self.set_root_id)
 
84
 
 
85
 
 
86
    def upnp_init(self):
 
87
        if self.server:
 
88
            self.server.connection_manager_server.set_variable(0, 'SourceProtocolInfo',
 
89
                            ['internal:%s:*:*' % self.host,
 
90
                             'http-get:*:audio/mpeg:*'])
 
91
 
 
92
    def upnp_Browse(self, *args, **kwargs):
 
93
        ObjectID = kwargs['ObjectID']
 
94
        BrowseFlag = kwargs['BrowseFlag']
 
95
        Filter = kwargs['Filter']
 
96
        StartingIndex = int(kwargs['StartingIndex'])
 
97
        RequestedCount = int(kwargs['RequestedCount'])
 
98
        SortCriteria = kwargs['SortCriteria']
 
99
 
 
100
        def build_upnp_item(elisa_item):
 
101
            UPnPClass = classChooser(elisa_item['mimetype'])
 
102
            upnp_item = None
 
103
            if UPnPClass:
 
104
                upnp_item = UPnPClass(elisa_item['id'],
 
105
                                      elisa_item['parent_id'],
 
106
                                      elisa_item['name'])
 
107
                if isinstance(upnp_item, Container):
 
108
                    upnp_item.childCount = len(elisa_item.get('children',[]))
 
109
                    if len(Filter) > 0:
 
110
                        upnp_item.searchable = True
 
111
                        upnp_item.searchClass = ('object',)
 
112
                else:
 
113
                    internal_url = elisa_item['location'].get('internal')
 
114
                    external_url = elisa_item['location'].get('external')
 
115
                    try:
 
116
                        size = elisa_item['size']
 
117
                    except:
 
118
                        size = None
 
119
                    try:
 
120
                        cover = elisa_item['cover']
 
121
                        if cover != '':
 
122
                            upnp_item.albumArtURI = cover
 
123
                    except:
 
124
                        pass
 
125
                    upnp_item.res = []
 
126
                    res = Resource(internal_url,
 
127
                                   'internal:%s:*:*' %self.host)
 
128
                    res.size = size
 
129
                    upnp_item.res.append(res)
 
130
                    res = Resource(external_url,
 
131
                                   'http-get:*:%s:*' % elisa_item['mimetype'])
 
132
                    res.size = size
 
133
                    upnp_item.res.append(res)
 
134
 
 
135
            return upnp_item
 
136
 
 
137
        def got_result(elisa_item):
 
138
            didl = DIDLElement()
 
139
            children = elisa_item.get('children',[])
 
140
            if BrowseFlag == 'BrowseDirectChildren':
 
141
                if RequestedCount == 0:
 
142
                    childs = children[StartingIndex:]
 
143
                else:
 
144
                    childs = children[StartingIndex:StartingIndex+RequestedCount]
 
145
                for child in childs:
 
146
                    if child is not None:
 
147
                        item = build_upnp_item(child)
 
148
                        if item:
 
149
                            didl.addItem(item)
 
150
                total = len(children)
 
151
            elif elisa_item:
 
152
                item = build_upnp_item(elisa_item)
 
153
                if item:
 
154
                    didl.addItem(item)
 
155
                total = 1
 
156
 
 
157
            r = { 'Result': didl.toString(), 'TotalMatches': total,
 
158
                  'NumberReturned': didl.numItems()}
 
159
 
 
160
            if hasattr(elisa_item, 'update_id'):
 
161
                r['UpdateID'] = item.update_id
 
162
            else:
 
163
                r['UpdateID'] = self.update_id
 
164
 
 
165
            return r
 
166
 
 
167
        def errback(r):
 
168
            return failure.Failure(errorCode(701))
 
169
 
 
170
        id = ObjectID
 
171
        if id == 0:
 
172
            id = self.root_id
 
173
 
 
174
        store = self.get_store()
 
175
        dfr = store.addCallback(lambda object:
 
176
                                object.callRemote('get_cache_manager'))
 
177
        dfr.addErrback(errback)
 
178
        dfr.addCallback(lambda cache_mgr:
 
179
                        cache_mgr.callRemote("get_media_node_with_id", id))
 
180
        dfr.addCallback(got_result)
 
181
        return dfr
 
182
 
 
183
 
 
184
 
 
185
if __name__ == '__main__':
 
186
    def main():
 
187
 
 
188
        p = 'localhost'
 
189
 
 
190
        def got_result(result):
 
191
            print result
 
192
 
 
193
        f = MediaStore(None,'my media',p, 'http://localhost/',())
 
194
 
 
195
        dfr = f.upnp_Browse(BrowseFlag='BrowseDirectChildren',
 
196
                            RequestedCount=0,
 
197
                            StartingIndex=0,
 
198
                            ObjectID=23,
 
199
                            SortCriteria='*',
 
200
                            Filter='')
 
201
        dfr.addCallback(got_result)
 
202
        dfr.addCallback(lambda _: reactor.stop())
 
203
 
 
204
    reactor.callLater(0.1, main)
 
205
    reactor.run()