Commit 5b70e4af authored by Jean-Francois Dockes's avatar Jean-Francois Dockes
Browse files

embedded images basic working

parent 68c628e5
......@@ -73,17 +73,16 @@ def _rcl2folders(docs, confdir, httphp, pathprefix):
for docidx in range(len(docs)):
doc = docs[docidx]
arturi = docarturi(doc, httphp, pathprefix)
if arturi:
# The uri is quoted, so it's ascii and we can just store
# it as a doc attribute
doc.albumarturi = arturi
# No need to include non-audio types in the visible tree.
if doc.mtype not in audiomtypes:
continue
if doc.mtype != 'inode/directory':
arturi = docarturi(doc, httphp, pathprefix)
if arturi:
# The uri is quoted, so it's ascii and we can just store
# it as a doc attribute
doc.albumarturi = arturi
url = doc.getbinurl()
url = url[7:]
try:
......@@ -128,6 +127,7 @@ def _rcl2folders(docs, confdir, httphp, pathprefix):
# intermediate elements without a Doc).
if idx == len(path) -1:
dirvec[fathidx][elt] = (dirvec[fathidx][elt][0], docidx)
#uplog("updating docidx for %s" % decoded)
# Update fathidx for next iteration
fathidx = dirvec[fathidx][elt][0]
else:
......@@ -141,6 +141,7 @@ def _rcl2folders(docs, confdir, httphp, pathprefix):
# Last element. If directory, needs a dirvec entry
if doc.mtype == 'inode/directory':
fathidx = _createdir(dirvec, fathidx, docidx, elt)
#uplog("Setting docidx for %s" % decoded)
else:
dirvec[fathidx][elt] = (-1, docidx)
......@@ -242,17 +243,26 @@ def browse(pid, flag, httphp, pathprefix):
# The basename call is just for diridx==0 (topdirs). Remove it if
# this proves a performance issue
for nm,ids in g_dirvec[diridx].iteritems():
#uplog("folders:browse: got nm %s" % nm.decode('utf-8'))
uplog("folders:browse: got nm %s" % printable(nm))
if nm == "..":
continue
thisdiridx = ids[0]
thisdocidx = ids[1]
if thisdocidx >= 0:
doc = g_alldocs[thisdocidx]
else:
uplog("No doc for %s" % pid)
doc = None
if thisdiridx >= 0:
# Skip empty directories
if len(dirvec[thisdiridx]) == 1:
continue
id = g_myprefix + '$' + 'd' + str(thisdiridx)
arturi = arturifordir(thisdiridx)
if doc and doc.albumarturi:
arturi = doc.albumarturi
else:
arturi = arturifordir(thisdiridx)
entries.append(rcldirentry(id, pid, os.path.basename(nm),
arturi=arturi))
else:
......
......@@ -23,23 +23,22 @@ from __future__ import print_function
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 @@ class RangeHTTPRequestHandler(BaseHTTPServer.BaseHTTPRequestHandler):
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 @@ class RangeHTTPRequestHandler(BaseHTTPServer.BaseHTTPRequestHandler):
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 @@ class RangeHTTPRequestHandler(BaseHTTPServer.BaseHTTPRequestHandler):
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 @@ class RangeHTTPRequestHandler(BaseHTTPServer.BaseHTTPRequestHandler):
'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 @@ class RangeHTTPRequestHandler(BaseHTTPServer.BaseHTTPRequestHandler):
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.
......
......@@ -26,6 +26,7 @@ audiomtypes = frozenset([
'application/ogg',
'audio/aac',
'audio/mp4',
'video/mp4',
'audio/x-aiff',
'audio/x-wav',
'inode/directory'
......@@ -142,15 +143,44 @@ def rcldoctoentry(id, pid, httphp, pathprefix, doc):
def docfolder(doc):
path = doc.getbinurl()
path = path[7:]
return os.path.dirname(path)
if doc.mtype == 'inode/directory':
return path
else:
return os.path.dirname(path)
def embdimgurl(doc, httphp, pathprefix):
if doc.embdimg == 'jpg':
ext = '.jpg'
elif doc.embdimg == '.png':
ext = 'png'
else:
return None
path = doc.getbinurl()
path = path[7:]
path = urllib.quote(os.path.join(pathprefix, path+ext))
path += "?embed=1"
return "http://%s%s" % (httphp, path)
def printable(s):
return s.decode('utf-8', errors='replace') if s else ""
# Find cover art for directory. We are usually called repeatedly for
# the same dir, so we cache one result
# Find cover art for doc. We return both a value for the directory
# cover art (if there is a cover.jpg or equiv, and a file own uri if
# there is embedded img data.
#
# We are usually called repeatedly for the same directory, so we cache
# one result
_foldercache = {}
_artnames = ('folder.jpg', 'folder.png', 'cover.jpg', 'cover.png')
def docarturi(doc, httphp, pathprefix):
global _foldercache, _artnames
if doc.embdimg:
arturi = embdimgurl(doc, httphp, pathprefix)
if arturi:
#uplog("docarturi: embedded: %s"%printable(arturi))
return arturi
folder = docfolder(doc)
if folder not in _foldercache:
......@@ -173,7 +203,13 @@ def docarturi(doc, httphp, pathprefix):
_foldercache[folder] = "http://%s%s" % (httphp, path)
break
return _foldercache[folder]
arturi = _foldercache[folder]
if arturi:
if doc.mtype == 'inode/directory':
#uplog("docarturi: external: %s->%s" %
# (printable(folder), printable(arturi)))
pass
return arturi
def cmpentries(e1, e2):
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment