Serve kepubs with extension "kepub.epub"

Change the extension of kepuns to "kepub.epub" so that the browser on
the Kobo ereaders will download them from the server. This checks the
useragent so that only Kobo browser is affected.

Fixes #1400029 [Serve kepubs with extension "kepub.epub"](https://bugs.launchpad.net/calibre/+bug/1400029)
This commit is contained in:
David Forrester 2014-12-09 21:12:39 +11:00 committed by Kovid Goyal
parent 871a54b5a6
commit a3afa17761
2 changed files with 17 additions and 4 deletions

View File

@ -252,10 +252,14 @@ class ContentServer(object):
cherrypy.response.headers['Content-Length'] = fmt.tell() cherrypy.response.headers['Content-Length'] = fmt.tell()
fmt.seek(0) fmt.seek(0)
ua = cherrypy.request.headers.get('User-Agent', '').strip()
have_kobo_browser = self.is_kobo_browser(ua)
file_extension = "kepub.epub" if format.lower() == "kepub" and have_kobo_browser else format
au = authors_to_string(newmi.authors if newmi.authors else au = authors_to_string(newmi.authors if newmi.authors else
[_('Unknown')]) [_('Unknown')])
title = newmi.title if newmi.title else _('Unknown') title = newmi.title if newmi.title else _('Unknown')
fname = u'%s - %s_%s.%s'%(title[:30], au[:30], id, format.lower()) fname = u'%s - %s_%s.%s'%(title[:30], au[:30], id, file_extension.lower())
fname = ascii_filename(fname).replace('"', '_') fname = ascii_filename(fname).replace('"', '_')
cherrypy.response.headers['Content-Disposition'] = \ cherrypy.response.headers['Content-Disposition'] = \
b'attachment; filename="%s"'%fname b'attachment; filename="%s"'%fname

View File

@ -92,7 +92,7 @@ def build_navigation(start, num, total, url_base): # {{{
# }}} # }}}
def build_index(books, num, search, sort, order, start, total, url_base, CKEYS, def build_index(books, num, search, sort, order, start, total, url_base, CKEYS,
prefix): prefix, have_kobo_browser=False):
logo = DIV(IMG(src=prefix+'/static/calibre.png', alt=__appname__), id='logo') logo = DIV(IMG(src=prefix+'/static/calibre.png', alt=__appname__), id='logo')
search_box = build_search_box(num, search, sort, order, prefix) search_box = build_search_box(num, search, sort, order, prefix)
@ -122,13 +122,14 @@ def build_index(books, num, search, sort, order, start, total, url_base, CKEYS,
for fmt in book['formats'].split(','): for fmt in book['formats'].split(','):
if not fmt or fmt.lower().startswith('original_'): if not fmt or fmt.lower().startswith('original_'):
continue continue
file_extension = "kepub.epub" if fmt.lower() == "kepub" and have_kobo_browser else fmt
a = quote(ascii_filename(book['authors'])) a = quote(ascii_filename(book['authors']))
t = quote(ascii_filename(book['title'])) t = quote(ascii_filename(book['title']))
s = SPAN( s = SPAN(
A( A(
fmt.lower(), fmt.lower(),
href=prefix+'/get/%s/%s-%s_%d.%s' % (fmt, a, t, href=prefix+'/get/%s/%s-%s_%d.%s' % (fmt, a, t,
book['id'], fmt.lower()) book['id'], file_extension.lower())
), ),
CLASS('button')) CLASS('button'))
s.tail = u'' s.tail = u''
@ -182,11 +183,16 @@ class MobileServer(object):
'A view optimized for browsers in mobile devices' 'A view optimized for browsers in mobile devices'
MOBILE_UA = re.compile('(?i)(?:iPhone|Opera Mini|NetFront|webOS|Mobile|Android|imode|DoCoMo|Minimo|Blackberry|MIDP|Symbian|HD2|Kindle)') MOBILE_UA = re.compile('(?i)(?:iPhone|Opera Mini|NetFront|webOS|Mobile|Android|imode|DoCoMo|Minimo|Blackberry|MIDP|Symbian|HD2|Kindle)')
KOBO_UA = re.compile('(?i)(?:Kobo Touch)')
def is_mobile_browser(self, ua): def is_mobile_browser(self, ua):
match = self.MOBILE_UA.search(ua) match = self.MOBILE_UA.search(ua)
return match is not None and 'iPad' not in ua return match is not None and 'iPad' not in ua
def is_kobo_browser(self, ua):
match = self.KOBO_UA.search(ua)
return match is not None
def add_routes(self, connect): def add_routes(self, connect):
connect('mobile', '/mobile', self.mobile) connect('mobile', '/mobile', self.mobile)
connect('mobile_css', '/mobile/style.css', self.mobile_css) connect('mobile_css', '/mobile/style.css', self.mobile_css)
@ -282,10 +288,13 @@ class MobileServer(object):
cherrypy.response.headers['Last-Modified'] = self.last_modified(updated) cherrypy.response.headers['Last-Modified'] = self.last_modified(updated)
url_base = "/mobile?search=" + search+";order="+order+";sort="+sort+";num="+str(num) url_base = "/mobile?search=" + search+";order="+order+";sort="+sort+";num="+str(num)
ua = cherrypy.request.headers.get('User-Agent', '').strip()
have_kobo_browser = self.is_kobo_browser(ua)
raw = html.tostring(build_index(books, num, search, sort, order, raw = html.tostring(build_index(books, num, search, sort, order,
start, len(ids), url_base, CKEYS, start, len(ids), url_base, CKEYS,
self.opts.url_prefix), self.opts.url_prefix,
have_kobo_browser=have_kobo_browser),
encoding='utf-8', encoding='utf-8',
pretty_print=True) pretty_print=True)
# tostring's include_meta_content_type is broken # tostring's include_meta_content_type is broken