- gzip api response

- dont parse xml on client
- load xml in thread
This commit is contained in:
j 2012-09-07 13:49:41 +02:00
parent 10694d8d1e
commit 5b97b26692
4 changed files with 77 additions and 13 deletions

View file

@ -10,6 +10,7 @@ def init(backend, site, data):
actions.register(init, cache=False)
def library(backend, site, data):
response = backend.library
response = {}
response['tracks'] = backend.tracks
return json_response(response)
actions.register(library, cache=True)

View file

@ -3,13 +3,21 @@
from __future__ import with_statement, division
import os
import re
from urllib import unquote
from threading import Thread
from plistlib import readPlist
class iTunes(object):
tracks = []
def __init__(self, xml):
self.library = readPlist(xml)
self.xml = xml
t = Thread(target=self.parse_xml, args=[])
t.start()
def parse_xml(self):
self.library = readPlist(self.xml)
for id in self.library['Tracks']:
self.library['Tracks'][id]['Location'] = unquote(self.library['Tracks'][id]['Location'].replace('file://localhost/', '/'))
if self.library['Tracks'][id]['Location'].startswith('//'):
@ -18,6 +26,31 @@ class iTunes(object):
self.library['Music Folder'] = unquote(self.library['Music Folder'].replace('file://localhost/', '/'))
if self.library['Music Folder'].startswith('//'):
self.library['Music Folder'] = self.library['Music Folder'][1:]
self.xml = xml
self.root = self.library['Music Folder']
self.tracks = self.load_tracks()
def load_tracks(self):
tracks = []
keys = [
'id', 'name', 'artist', 'album', 'kind', 'year', 'duration', 'size',
'sortArtist', 'albumArtist', 'sortAlbumArtist', 'compliation',
]
for t in self.library['Tracks']:
track = self.library['Tracks'][t]
item = {}
for key in keys:
item[key] = track.get({
'id': 'Track ID',
'duration': 'Total Time',
}.get(
key,
re.sub(
'^(.)',
lambda m: m.groups(0)[0].capitalize(),
re.sub('([A-Z])', ' \\1', key)
)
), None)
if item[key] == None:
del item[key]
tracks.append(item)
return tracks

View file

@ -14,10 +14,10 @@ from twisted.web.resource import Resource
from twisted.web.static import File
from twisted.web.util import Redirect
from twisted.web.error import NoResource
from twisted.web.server import NOT_DONE_YET
from version import __version__
from gziprequest import GzipFile
from gziprequest import GzipFile, GzipRequest
def trim(docstring):
if not docstring:
return ''
@ -198,7 +198,13 @@ class Server(Resource):
else:
data = {}
action = request.args['action'][0]
return actions.render(self.backend, site, action, data)
accept_encoding = request.getHeader('accept-encoding')
if 'gzip' in accept_encoding:
request = GzipRequest(request)
#FIXME: this should be done async
request.write(actions.render(self.backend, site, action, data))
request.finish()
return NOT_DONE_YET
def render_GET(self, request):
request.headers['Server'] = 'oxcd/%s' % __version__

View file

@ -1,6 +1,11 @@
'use strict';
Ox.load('UI', function() {
window.oxcd = Ox.App({
name: 'oxcd',
url: '/api/'
}).bindEvent({
load: function(data) {
var app = {
$ui: {},
data: {},
@ -82,7 +87,7 @@ Ox.load('UI', function() {
format: function(value) {
return app.utils.formatTime(value);
},
id: 'totalTime',
id: 'duration',
operator: '-',
title: 'Time',
visible: true,
@ -156,8 +161,8 @@ Ox.load('UI', function() {
*/
scrollbarVisible: true,
sort: app.user.sort,
sums: ['size', 'totalTime'],
unique: 'trackID'
sums: ['size', 'duration'],
unique: 'id'
})
.bindEvent({
init: function(data) {
@ -205,10 +210,10 @@ Ox.load('UI', function() {
app.data.status = data;
} else if (data.ids && data.ids.length > 1) {
var items = app.user.music.tracks.filter(function(track) {
return Ox.contains(data.ids, track.trackID);
return Ox.contains(data.ids, track.id);
});
data.selected = data.ids.length;
['size', 'totalTime'].forEach(function(key) {
['size', 'duration'].forEach(function(key) {
data[key] = items.reduce(function(p, c) {
return p + c[key];
}, 0);
@ -219,7 +224,7 @@ Ox.load('UI', function() {
data ? (data.selected ? data.selected + ' of ' : '')
+ Ox.formatNumber(app.data.status.items) + ' item'
+ (app.data.status.items == 1 ? '' : 's') + ', '
+ app.utils.formatTime(data.totalTime || app.data.status.totalTime) + ' total time, '
+ app.utils.formatTime(data.duration || app.data.status.duration) + ' total time, '
+ Ox.formatValue(data.size || app.data.status.size, 'B')
: 'Loading...'
);
@ -237,6 +242,23 @@ Ox.load('UI', function() {
return key[0].toLowerCase() + key.substr(1).replace(/ /g, '');
};
app.utils.parseLibrary = function(callback) {
var data = {playlists: [], tracks: []};
oxcd.api.library(function(result) {
Ox.forEach(result.data.tracks, function(track) {
if (track.kind == 'MPEG audio file' && !track.podcast) {
app.site.columns.map(function(column) {
return column.id;
}).forEach(function(key) {
if (!track[key]) {
track[key] = '';
}
})
data.tracks.push(track);
}
});
callback(data);
});
/*
Ox.get(app.user.library, function(xml) {
var data = {playlists: [], tracks: []},
library = app.utils.parseXML($(xml).children()[0]);
@ -254,6 +276,7 @@ Ox.load('UI', function() {
});
callback(data);
});
*/
};
app.utils.parseXML = function(xml) {
var type = xml.nodeName.toLowerCase(), value;
@ -293,5 +316,6 @@ Ox.load('UI', function() {
}
};
app.load();
window.app = app;
}
});
});