send library.xml gzip encoded

This commit is contained in:
j 2012-09-06 16:33:00 +02:00
parent a31e2bd546
commit 10694d8d1e
3 changed files with 80 additions and 3 deletions

View file

@ -24,10 +24,11 @@ def itunes_path():
def main(port, itunes): def main(port, itunes):
base = os.path.abspath(os.path.dirname(__file__)) base = os.path.abspath(os.path.dirname(__file__))
print 'loading', itunes
backend = iTunes(itunes) backend = iTunes(itunes)
root = Server(base, backend) root = Server(base, backend)
site = Site(root) site = Site(root)
reactor.listenTCP(port, site) reactor.listenTCP(port, site)
reactor.callLater(1, lambda: webbrowser.open_new_tab('http://127.0.0.1:%s/' % port)) #reactor.callLater(1, lambda: webbrowser.open_new_tab('http://127.0.0.1:%s/' % port))
print 'opening browser at http://127.0.0.1:%s/ ...' % port print 'listening for browsers at http://127.0.0.1:%s/ ...' % port
reactor.run() reactor.run()

68
oxcd/gziprequest.py Normal file
View file

@ -0,0 +1,68 @@
import struct
import zlib
from twisted.web.static import File
class GzipFile(File):
def render_GET(self, request):
request = GzipRequest(request)
return File.render_GET(self, request)
class GzipRequest(object):
"""Wrapper for a request that applies a gzip content encoding"""
def __init__(self, request, compressLevel=6):
self.request = request
self.request.setHeader('Content-Encoding', 'gzip')
# Borrowed from twisted.web2 gzip filter
self.compress = zlib.compressobj(compressLevel, zlib.DEFLATED,
-zlib.MAX_WBITS, zlib.DEF_MEM_LEVEL,0)
def __getattr__(self, attr):
if 'request' in self.__dict__:
return getattr(self.request, attr)
else:
raise AttributeError, attr
def __setattr__(self, attr, value):
if 'request' in self.__dict__:
return setattr(self.request, attr, value)
else:
self.__dict__[attr] = value
def write(self, data):
if not self.request.startedWriting:
#print 'GzipRequest: Initializing'
self.crc = zlib.crc32('')
self.size = self.csize = 0
# XXX: Zap any length for now since we don't know final size
if 'content-length' in self.request.headers:
del self.request.headers['content-length']
# Borrow header information from twisted.web2 gzip filter
self.request.write('\037\213\010\000' '\0\0\0\0' '\002\377')
self.crc = zlib.crc32(data, self.crc)
self.size += len(data)
cdata = self.compress.compress(data)
self.csize += len(cdata)
'''
print 'GzipRequest: ' \
'Writing %d bytes, %d total (%d compressed, %d total)' % \
(len(data),self.size,len(cdata),self.csize)
'''
if cdata:
self.request.write(cdata)
elif self.request.producer:
# Simulate another pull even though it hasn't really made it
# out to the consumer yet.
self.request.producer.resumeProducing()
def finish(self):
remain = self.compress.flush()
self.csize += len(remain)
#print 'GzipRequest: Finishing (size %d, compressed %d)' % (self.size, self.csize)
if remain:
self.request.write(remain)
self.request.write(struct.pack('<LL',
self.crc & 0xFFFFFFFFL,
self.size & 0xFFFFFFFFL))
self.request.finish()

View file

@ -8,6 +8,7 @@ import os
import json import json
from urlparse import urlparse from urlparse import urlparse
import datetime import datetime
import zlib
from twisted.web.resource import Resource from twisted.web.resource import Resource
from twisted.web.static import File from twisted.web.static import File
@ -15,6 +16,7 @@ from twisted.web.util import Redirect
from twisted.web.error import NoResource from twisted.web.error import NoResource
from version import __version__ from version import __version__
from gziprequest import GzipFile
def trim(docstring): def trim(docstring):
if not docstring: if not docstring:
@ -156,9 +158,15 @@ class Server(Resource):
if request.path == '/api/': if request.path == '/api/':
return self return self
if request.path == '/library.xml': if request.path == '/library.xml':
f = File(self.backend.xml) accept_encoding = request.getHeader('accept-encoding')
if 'gzip' in accept_encoding:
f = GzipFile(self.backend.xml, 'application/xml')
else:
f = File(self.backend.xml, 'application/xml')
f.isLeaf = True f.isLeaf = True
return f return f
if request.path.startswith('/track/'): if request.path.startswith('/track/'):
track_id = request.path.split('/')[-1].split('.')[0] track_id = request.path.split('/')[-1].split('.')[0]
track = self.backend.library['Tracks'].get(track_id) track = self.backend.library['Tracks'].get(track_id)