Parent: [15332e] (diff)

Child: [1c22b6] (diff)

Download this file

upmplgutils.py    175 lines (146 with data), 5.8 kB

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
# Copyright (C) 2016 J.F.Dockes
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the
# Free Software Foundation, Inc.,
# 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#
#
"""
Shared code for the tidal, qobuz, gmusic plugins.
- Uses the interface for the entity objects (track, album...)
concretely defined in models.py, but duck-typed.
- Defines and uses the format for the permanent URLs
The module implements utility functions for translating to/from what
our parent expects or sends on the pipe.
"""
from __future__ import print_function, unicode_literals
import posixpath
import re
import sys
default_mime = "audio/mpeg"
default_samplerate = "44100"
# This is only used for log messages
_idprefix = '0$UNKNOWN'
def setidprefix(idprefix):
global _idprefix
_idprefix = idprefix
# Bogus class instanciated as global object for helping with reusing
# kodi addon code
class XbmcPlugin:
SORT_METHOD_TRACKNUM = 1
def __init__(self, idprefix):
self.entries = []
self.objid = ''
self.idprefix = idprefix
setidprefix(idprefix)
def addDirectoryItem(self, hdl, endpoint, title, isend):
self.entries.append(direntry(self.idprefix + endpoint, self.objid,
title))
def endOfDirectory(self, h):
return
def setContent(self, a, b):
return
def addSortMethod(self, a, b):
return
# For now, we pretend that all tracks have the same format (for the
# resource record). For some services this may not be true, we'll see
# if it can stay this way.
def setMimeAndSamplerate(m, s):
global default_mime, default_samplerate
default_mime = m
default_samplerate = s
def trackentries(httphp, pathprefix, objid, tracks):
"""
Transform a list of Track objects to the format expected by the parent
Args:
objid (str): objid for the browsed object (the parent container)
tracks is the array of Track objects to be translated
tracks: a list of Track objects.
Returns:
A list of dicts, each representing an UPnP item, with the
keys as expected in the plgwithslave.cxx resultToEntries() function.
The permanent URIs, are of the following form, based on the
configured host:port and pathprefix arguments and track Id:
http://host:port/pathprefix/track?version=1&trackId=<trackid>
"""
global default_mime, default_samplerate
entries = []
for track in tracks:
if not track.available:
if 1:
uplog("NOT AVAILABLE")
try:
uplog("%s by %s" % (track.name, track.artist.name))
except:
pass
continue
li = {}
li['pid'] = objid
li['id'] = objid + '$' + "%s" % track.id
li['tt'] = track.name
li['uri'] = 'http://%s' % httphp + \
posixpath.join(pathprefix,
'track?version=1&trackId=%s' % track.id)
li['tp'] = 'it'
if track.album:
li['upnp:album'] = track.album.name
if track.album.image:
li['upnp:albumArtURI'] = track.album.image
if track.album.release_date:
li['releasedate'] = track.album.release_date
li['upnp:originalTrackNumber'] = str(track.track_num)
li['upnp:artist'] = track.artist.name
li['dc:title'] = track.name
li['discnumber'] = str(track.disc_num)
li['duration'] = str(track.duration)
li['upnp:class'] = track.upnpclass
li['res:mime'] = default_mime
li['res:samplefreq'] = default_samplerate
entries.append(li)
return entries
def trackid_from_urlpath(pathprefix, a):
"""
Extract track id from a permanent URL path part.
This supposes that the input URL has the format produced by the
trackentries() method: <pathprefix>/track?version=1&trackId=<trackid>
Args:
pathprefix (str): our configured path prefix (e.g. /qobuz/)
a (dict): the argument dict out of cmdtalk with a 'path' key
Returns:
str: the track Id.
"""
if 'path' not in a:
raise Exception("trackuri: no 'path' in args")
path = a['path']
# pathprefix + 'track?version=1&trackId=trackid
exp = posixpath.join(pathprefix, '''track\?version=1&trackId=(.+)$''')
m = re.match(exp, path)
if m is None:
raise Exception("trackuri: path [%s] does not match [%s]" % (path, exp))
trackid = m.group(1)
return trackid
def direntry(id, pid, title, arturi=None, artist=None, upnpclass=None):
""" Create container entry in format expected by parent """
ret = {'id':id, 'pid':pid, 'tt':title, 'tp':'ct', 'searchable':'1'}
if arturi:
ret['upnp:albumArtURI'] = arturi
if artist:
ret['upnp:artist'] = artist
if upnpclass:
ret['upnp:class'] = upnpclass
return ret
def uplog(s):
if not type(s) == type(u''):
s = s.decode('utf-8', errors='replace')
print(("%s: %s" % (_idprefix, s)).encode('utf-8',errors='replace'),
file=sys.stderr)