--- a/src/mediaserver/cdplugins/uprcl/uprclhttp.py
+++ b/src/mediaserver/cdplugins/uprcl/uprclhttp.py
@@ -23,23 +23,22 @@
import SocketServer
import BaseHTTPServer
-import SimpleHTTPServer
import os
import posixpath
-import BaseHTTPServer
import urllib
-import cgi
+import urlparse
import shutil
import mimetypes
import sys
+
+import mutagen
try:
from cStringIO import StringIO
except ImportError:
from StringIO import StringIO
-from uprclutils import uplog
-
+from uprclutils import uplog,printable
__version__ = "0.1"
@@ -95,9 +94,11 @@
None, in which case the caller has nothing further to do.
"""
- uplog("HTTP: path: %s" % self.path)
- path = self.translate_path(self.path)
- uplog("HTTP: translated path: %s" % urllib.quote(path))
+
+ path,embedded = self.translate_path(self.path)
+ #uplog("HTTP: translated: embedded %s path: %s" %
+ # (embedded, printable(path)))
+
if not path or not os.path.exists(path):
self.send_error(404)
return (None, 0, 0)
@@ -107,10 +108,17 @@
return (None, 0, 0)
f = None
- ctype = self.guess_type(path)
try:
- f = open(path, 'rb')
- except:
+ if embedded:
+ ctype, size, f = self.embedded_open(path)
+ fs = os.stat(path)
+ #uplog("embedded, got ctype %s size %s" %(ctype, size))
+ else:
+ ctype = self.guess_type(path)
+ f = open(path, 'rb')
+ fs = os.fstat(f.fileno())
+ size = int(fs[6])
+ except Exception as err:
self.send_error(404, "File not found")
return (None, 0, 0)
@@ -119,9 +127,8 @@
else:
self.send_response(200)
+ self.send_header("Last-Modified", self.date_time_string(fs.st_mtime))
self.send_header("Content-type", ctype)
- fs = os.fstat(f.fileno())
- size = int(fs[6])
start_range = 0
end_range = size
self.send_header("Accept-Ranges", "bytes")
@@ -141,7 +148,6 @@
'bytes ' + str(start_range) + '-' +
str(end_range - 1) + '/' + str(size))
self.send_header("Content-Length", end_range - start_range)
- self.send_header("Last-Modified", self.date_time_string(fs.st_mtime))
self.end_headers()
#uplog("Sending Bytes %d to %d" % (start_range, end_range))
return (f, start_range, end_range)
@@ -150,12 +156,66 @@
def translate_path(self, opath):
path = urllib.unquote(opath)
path = path.replace(self.uprclpathprefix, '', 1)
+
+ q = urlparse.urlparse(path)
+ path = q.path
+ embedded = False
+ pq = urlparse.parse_qs(q.query)
+ if 'embed' in pq:
+ embedded = True
+
for fsp,htp in self.uprclpathmap.iteritems():
if path.startswith(fsp):
- return path.replace(fsp, htp, 1)
-
+ path = path.replace(fsp, htp, 1)
+ if embedded:
+ # Embedded image urls have had a .jpg or .png
+ # appended. Remove it to restore the track path
+ # name.
+ i = path.rfind('.')
+ path = path[:i]
+ return path, embedded
+
+ # Security feature here: never allow access to anything not in
+ # the path map
uplog("HTTP: translate_path: %s not found in path map" % opath)
- return None
+ return None, None
+
+
+ # Open embedded image. Returns mtype, size, f
+ def embedded_open(self, path):
+ try:
+ mutf = mutagen.File(path)
+ except Exception as err:
+ raise err
+
+ f = None
+ size = 0
+ if 'audio/mp3' in mutf.mime:
+ for tagname in mutf.iterkeys():
+ if tagname.startswith('APIC:'):
+ #self.em.rclog("mp3 img: %s" % mutf[tagname].mime)
+ mtype = mutf[tagname].mime
+ s = mutf[tagname].data
+ size = len(s)
+ f = StringIO(s)
+ elif 'audio/x-flac' in mutf.mime:
+ if mutf.pictures:
+ mtype = mutf.pictures[0].mime
+ size = len(mutf.pictures[0].data)
+ f = StringIO(mutf.pictures[0].data)
+ elif 'audio/mp4' in mutf.mime:
+ if 'covr' in mutf.iterkeys():
+ format = mutf['covr'][0].imageformat
+ if format == mutagen.mp4.AtomDataType.JPEG:
+ mtype = 'image/jpeg'
+ else:
+ mtype = 'image/png'
+ size = len(mutf['covr'][0])
+ f = StringIO(mutf['covr'][0])
+ if f is None:
+ raise Exception("can't open embedded image")
+ else:
+ return mtype, size, f
def guess_type(self, path):
"""Guess the type of a file.