2
# vim:fileencoding=UTF-8:ts=4:sw=4:sta:et:sts=4:ai
5
__copyright__ = '2010, Kovid Goyal <kovid@kovidgoyal.net>'
6
__docformat__ = 'restructuredtext en'
11
from lxml.builder import ElementMaker
12
from lxml import etree
14
from calibre.library.server.utils import strftime
15
from calibre.ebooks.metadata import fmt_sidx
16
from calibre.constants import preferred_encoding
17
from calibre import isbytestring
21
class XMLServer(object):
22
'Serves XML and the Ajax based HTML frontend'
24
def add_routes(self, connect):
25
connect('xml', '/xml', self.xml)
27
def xml(self, start='0', num='50', sort=None, search=None,
28
_=None, order='ascending'):
30
Serves metadata from the calibre database as XML.
32
:param sort: Sort results by ``sort``. Can be one of `title,author,rating`.
33
:param search: Filter results by ``search`` query. See :class:`SearchQueryParser` for query syntax
34
:param start,num: Return the slice `[start:start+num]` of the sorted and filtered results
35
:param _: Firefox seems to sometimes send this when using XMLHttpRequest with no caching
40
raise cherrypy.HTTPError(400, 'start: %s is not an integer'%start)
44
raise cherrypy.HTTPError(400, 'num: %s is not an integer'%num)
46
order = order.lower().strip() == 'ascending'
48
ids = self.db.data.parse(search) if search and search.strip() else self.db.data.universal_set()
50
FM = self.db.FIELD_MAP
52
items = [r for r in iter(self.db) if r[FM['id']] in ids]
54
self.sort(items, sort, order)
60
if isinstance(x, unicode):
63
return x.decode(preferred_encoding, 'replace')
66
for record in items[start:start+num]:
68
aus = record[FM['authors']] if record[FM['authors']] else __builtin__._('Unknown')
69
authors = '|'.join([i.replace('|', ',') for i in aus.split(',')])
70
kwargs['authors'] = authors
72
kwargs['series_index'] = \
73
fmt_sidx(float(record[FM['series_index']]))
75
for x in ('timestamp', 'pubdate'):
76
kwargs[x] = strftime('%Y/%m/%d %H:%M:%S', record[FM[x]])
78
for x in ('id', 'title', 'sort', 'author_sort', 'rating', 'size'):
79
kwargs[x] = serialize(record[FM[x]])
81
for x in ('isbn', 'formats', 'series', 'tags', 'publisher',
84
kwargs[x] = serialize(y) if y else ''
86
c = kwargs.pop('comments')
87
books.append(E.book(c, **kwargs))
89
updated = self.db.last_modified()
92
updated=updated.strftime('%Y-%m-%dT%H:%M:%S+00:00'),
95
ans = E.library(*books, **kwargs)
97
cherrypy.response.headers['Content-Type'] = 'text/xml'
98
cherrypy.response.headers['Last-Modified'] = self.last_modified(updated)
100
return etree.tostring(ans, encoding='utf-8', pretty_print=True,
101
xml_declaration=True)