|
a/src/mediaserver/cdplugins/uprcl/uprclutils.py |
|
b/src/mediaserver/cdplugins/uprcl/uprclutils.py |
1 |
from __future__ import print_function
|
1 |
from __future__ import print_function
|
2 |
|
2 |
|
3 |
import sys
|
3 |
import sys
|
|
|
4 |
import posixpath
|
|
|
5 |
import urllib
|
4 |
|
6 |
|
|
|
7 |
audiomtypes = frozenset([
|
|
|
8 |
'audio/mpeg',
|
|
|
9 |
'application/x-flac',
|
|
|
10 |
'application/ogg',
|
|
|
11 |
'audio/aac',
|
|
|
12 |
'audio/mp4',
|
|
|
13 |
'audio/x-aiff',
|
|
|
14 |
'audio/x-wav'
|
|
|
15 |
])
|
|
|
16 |
|
5 |
def rcldocs2entries(httphp, pathprefix, objid, docs):
|
17 |
def rcldoctoentry(id, pid, httphp, pathprefix, doc):
|
6 |
"""
|
18 |
"""
|
7 |
Transform a list of Doc objects into the format expected by the parent
|
19 |
Transform a Doc objects into the format expected by the parent
|
8 |
|
20 |
|
9 |
Args:
|
21 |
Args:
|
|
|
22 |
id (str): objid for the entry
|
|
|
23 |
pid (str): objid for the browsed object (the parent container)
|
10 |
httphp: the hostport part of the generated track urls
|
24 |
httphp: the hostport part of the generated track urls
|
11 |
pathprefix: is provided by our parent process (it's used to
|
25 |
pathprefix: is provided by our parent process (it's used to
|
12 |
what plugin an url belongs too when needed for
|
26 |
what plugin an url belongs too when needed for
|
13 |
translating the internal into the real url (for plugins
|
27 |
translating the internal into the real url (for plugins
|
14 |
based on external-services)
|
28 |
based on external-services)
|
15 |
objid (str): objid for the browsed object (the parent container)
|
|
|
16 |
docs is the array of Doc objects to be translated
|
29 |
doc is the Doc object to be translated
|
17 |
|
30 |
|
18 |
Returns:
|
31 |
Returns:
|
19 |
A list of dicts, each representing an UPnP item, with the
|
32 |
A dict representing an UPnP item, with the
|
20 |
keys as expected in the plgwithslave.cxx resultToEntries() function.
|
33 |
keys as expected in the plgwithslave.cxx resultToEntries() function.
|
21 |
|
34 |
|
22 |
The permanent URIs, are of the following form, based on the
|
35 |
The permanent URIs, are of the following form, based on the
|
23 |
configured host:port and pathprefix arguments and track Id:
|
36 |
configured host:port and pathprefix arguments and track Id:
|
24 |
|
37 |
TBD
|
25 |
http://host:port/pathprefix/track?version=1&trackId=<trackid>
|
38 |
http://host:port/pathprefix/track?version=1&trackId=<trackid>
|
26 |
|
39 |
|
27 |
"""
|
40 |
"""
|
28 |
global default_mime, default_samplerate
|
41 |
uplog("rcldoctoentry: pid %s id %s httphp %s pathprefix %s" %
|
|
|
42 |
(pid, id, httphp, pathprefix))
|
29 |
|
43 |
|
30 |
entries = []
|
|
|
31 |
for doc in docs:
|
|
|
32 |
li = {}
|
44 |
li = {}
|
33 |
li['pid'] = objid
|
45 |
if doc.mtype not in audiomtypes:
|
34 |
li['id'] = objid + '$' + "%s" % track.id
|
46 |
return li
|
35 |
li['tt'] = doc.title
|
|
|
36 |
|
47 |
|
37 |
# URL: we need transformation rules from the file:// recoll url to an http
|
48 |
li['pid'] = pid
|
38 |
# one appropriate for our media server
|
49 |
li['id'] = id
|
39 |
li['uri'] = 'http://%s' % httphp + \
|
|
|
40 |
posixpath.join(pathprefix,
|
|
|
41 |
'track?version=1&trackId=%s' % track.id)
|
|
|
42 |
li['tp'] = 'it'
|
50 |
li['tp'] = 'it'
|
43 |
if doc.album:
|
51 |
# Why no dc.title??
|
44 |
li['upnp:album'] = doc.album
|
|
|
45 |
# !! Albumart will have to come from somewhere else !
|
|
|
46 |
### #if doc.albumarturi:
|
|
|
47 |
### #li['upnp:albumArtURI'] = track.album.image
|
|
|
48 |
# Date format ?
|
|
|
49 |
if doc.date:
|
|
|
50 |
li['releasedate'] = doc.date
|
|
|
51 |
li['upnp:originalTrackNumber'] = str(doc.tracknumber)
|
|
|
52 |
li['upnp:artist'] = doc.artist
|
|
|
53 |
li['upnp:genre'] = doc.genre
|
|
|
54 |
li['dc:title'] = doc.title
|
52 |
li['tt'] = doc.title
|
55 |
li['upnp:class'] = track.upnpclass
|
|
|
56 |
li['res:mime'] = doc.mtype
|
|
|
57 |
### li['discnumber'] = str(track.disc_num)
|
|
|
58 |
### Need to extract the audio params from mutagen output !
|
|
|
59 |
#li['duration'] = track.duration
|
|
|
60 |
#li['res:samplefreq'] = default_samplerate
|
|
|
61 |
#albumartist=
|
|
|
62 |
#comment=
|
|
|
63 |
#composer=
|
|
|
64 |
#conductor=
|
|
|
65 |
#discnumber=
|
|
|
66 |
#genre=
|
|
|
67 |
#lyricist=
|
|
|
68 |
#lyrics=
|
|
|
69 |
|
|
|
70 |
entries.append(li)
|
|
|
71 |
return entries
|
|
|
72 |
|
53 |
|
|
|
54 |
# TBD
|
|
|
55 |
li['upnp:class'] = 'object.item.audioItem.musicTrack'
|
|
|
56 |
|
|
|
57 |
# TBD Date format ?
|
|
|
58 |
# !! Albumart will have to come from somewhere else !
|
|
|
59 |
# li['upnp:class'] = doc.upnpclass
|
|
|
60 |
#li['res:channels'] =
|
|
|
61 |
#li['res:size'] =
|
|
|
62 |
#li['res:bitrate'] =
|
|
|
63 |
### #if doc.albumarturi:
|
|
|
64 |
### #li['upnp:albumArtURI'] = track.album.image
|
|
|
65 |
### li['discnumber'] = str(track.disc_num)
|
|
|
66 |
#albumartist=
|
|
|
67 |
#comment=
|
|
|
68 |
#composer=
|
|
|
69 |
#conductor=
|
|
|
70 |
#discnumber=
|
|
|
71 |
#genre=
|
|
|
72 |
#lyricist=
|
|
|
73 |
#lyrics=
|
|
|
74 |
|
|
|
75 |
for oname,dname in [('upnp:album', 'album'), ('releasedate','date'),
|
|
|
76 |
('upnp:originalTrackNumber', 'tracknumber'),
|
|
|
77 |
('upnp:artist', 'artist'), ('upnp:genre', 'genre'),
|
|
|
78 |
('res:mime', 'mtype'), ('duration', 'duration'),
|
|
|
79 |
('res:samplefreq', 'sample_rate')]:
|
|
|
80 |
val = getattr(doc, dname)
|
|
|
81 |
if val:
|
|
|
82 |
li[oname] = val
|
|
|
83 |
|
|
|
84 |
try:
|
|
|
85 |
val = li['upnp:originalTrackNumber']
|
|
|
86 |
l = val.split('/')
|
|
|
87 |
li['upnp:originalTrackNumber'] = l[0]
|
|
|
88 |
except:
|
|
|
89 |
pass
|
|
|
90 |
|
|
|
91 |
# Compute the url. We use the URL from recoll, stripped of file://
|
|
|
92 |
# and with the pathprefix prepended (the pathprefix is used by our
|
|
|
93 |
# parent process to match urls to plugins)
|
|
|
94 |
path = doc.getbinurl()
|
|
|
95 |
path = path[7:]
|
|
|
96 |
path = pathprefix + path
|
|
|
97 |
li['uri'] = "http://%s%s" % (httphp, urllib.quote(path))
|
|
|
98 |
uplog("rcldoctoentry: uri: %s" % li['uri'])
|
|
|
99 |
return li
|
|
|
100 |
|
|
|
101 |
def rclpathtoreal(path, pathprefix, httphp, pathmap):
|
|
|
102 |
path = path.replace(pathprefix, '', 1)
|
|
|
103 |
found = False
|
|
|
104 |
for fsp,htp in pathmap.iteritems():
|
|
|
105 |
if path.startswith(fsp):
|
|
|
106 |
path = path.replace(fsp, htp, 1)
|
|
|
107 |
found = True
|
|
|
108 |
if not found:
|
|
|
109 |
return None
|
|
|
110 |
return "http://" + httphp + path
|
73 |
|
111 |
|
74 |
def rcldirentry(id, pid, title, arturi=None, artist=None, upnpclass=None):
|
112 |
def rcldirentry(id, pid, title, arturi=None, artist=None, upnpclass=None):
|
75 |
""" Create container entry in format expected by parent """
|
113 |
""" Create container entry in format expected by parent """
|
76 |
ret = {'id':id, 'pid':pid, 'tt':title, 'tp':'ct', 'searchable':'1'}
|
114 |
ret = {'id':id, 'pid':pid, 'tt':title, 'tp':'ct', 'searchable':'1'}
|
77 |
if arturi:
|
115 |
if arturi:
|