~ubuntu-branches/ubuntu/oneiric/calibre/oneiric

« back to all changes in this revision

Viewing changes to src/calibre/library/server/xml.py

  • Committer: Bazaar Package Importer
  • Author(s): Martin Pitt
  • Date: 2010-06-21 10:18:08 UTC
  • mfrom: (1.3.12 upstream)
  • Revision ID: james.westby@ubuntu.com-20100621101808-aue828f532tmo4zt
Tags: 0.7.2+dfsg-1
* New major upstream version. See http://calibre-ebook.com/new-in/seven for
  details.
* Refresh patches to apply cleanly.
* debian/control: Bump python-cssutils to >= 0.9.7~ to ensure the existence
  of the CSSRuleList.rulesOfType attribute. This makes epub conversion work
  again. (Closes: #584756)
* Add debian/local/calibre-mount-helper: Simple and safe replacement for
  upstream's calibre-mount-helper, using udisks --mount and eject.
  (Closes: #584915, LP: #561958)

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#!/usr/bin/env python
 
2
# vim:fileencoding=UTF-8:ts=4:sw=4:sta:et:sts=4:ai
 
3
 
 
4
__license__   = 'GPL v3'
 
5
__copyright__ = '2010, Kovid Goyal <kovid@kovidgoyal.net>'
 
6
__docformat__ = 'restructuredtext en'
 
7
 
 
8
import __builtin__
 
9
 
 
10
import cherrypy
 
11
from lxml.builder import ElementMaker
 
12
from lxml import etree
 
13
 
 
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
 
18
 
 
19
E = ElementMaker()
 
20
 
 
21
class XMLServer(object):
 
22
    'Serves XML and the Ajax based HTML frontend'
 
23
 
 
24
    def add_routes(self, connect):
 
25
        connect('xml', '/xml', self.xml)
 
26
 
 
27
    def xml(self, start='0', num='50', sort=None, search=None,
 
28
                _=None, order='ascending'):
 
29
        '''
 
30
        Serves metadata from the calibre database as XML.
 
31
 
 
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
 
36
        '''
 
37
        try:
 
38
            start = int(start)
 
39
        except ValueError:
 
40
            raise cherrypy.HTTPError(400, 'start: %s is not an integer'%start)
 
41
        try:
 
42
            num = int(num)
 
43
        except ValueError:
 
44
            raise cherrypy.HTTPError(400, 'num: %s is not an integer'%num)
 
45
 
 
46
        order = order.lower().strip() == 'ascending'
 
47
 
 
48
        ids = self.db.data.parse(search) if search and search.strip() else self.db.data.universal_set()
 
49
 
 
50
        FM = self.db.FIELD_MAP
 
51
 
 
52
        items = [r for r in iter(self.db) if r[FM['id']] in ids]
 
53
        if sort is not None:
 
54
            self.sort(items, sort, order)
 
55
 
 
56
 
 
57
        books = []
 
58
 
 
59
        def serialize(x):
 
60
            if isinstance(x, unicode):
 
61
                return x
 
62
            if isbytestring(x):
 
63
                return x.decode(preferred_encoding, 'replace')
 
64
            return unicode(x)
 
65
 
 
66
        for record in items[start:start+num]:
 
67
            kwargs = {}
 
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
 
71
 
 
72
            kwargs['series_index'] = \
 
73
                fmt_sidx(float(record[FM['series_index']]))
 
74
 
 
75
            for x in ('timestamp', 'pubdate'):
 
76
                kwargs[x] = strftime('%Y/%m/%d %H:%M:%S', record[FM[x]])
 
77
 
 
78
            for x in ('id', 'title', 'sort', 'author_sort', 'rating', 'size'):
 
79
                kwargs[x] = serialize(record[FM[x]])
 
80
 
 
81
            for x in ('isbn', 'formats', 'series', 'tags', 'publisher',
 
82
                    'comments'):
 
83
                y = record[FM[x]]
 
84
                kwargs[x] = serialize(y) if y else ''
 
85
 
 
86
            c = kwargs.pop('comments')
 
87
            books.append(E.book(c, **kwargs))
 
88
 
 
89
        updated = self.db.last_modified()
 
90
        kwargs = dict(
 
91
                start = str(start),
 
92
                updated=updated.strftime('%Y-%m-%dT%H:%M:%S+00:00'),
 
93
                total=str(len(ids)),
 
94
                num=str(len(books)))
 
95
        ans = E.library(*books, **kwargs)
 
96
 
 
97
        cherrypy.response.headers['Content-Type'] = 'text/xml'
 
98
        cherrypy.response.headers['Last-Modified'] = self.last_modified(updated)
 
99
 
 
100
        return etree.tostring(ans, encoding='utf-8', pretty_print=True,
 
101
                xml_declaration=True)
 
102
 
 
103
 
 
104
 
 
105