From a3afa1776179d60ce5719248e4b37ef352a321e9 Mon Sep 17 00:00:00 2001 From: David Forrester Date: Tue, 9 Dec 2014 21:12:39 +1100 Subject: [PATCH] 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) --- src/calibre/library/server/content.py | 6 +++++- src/calibre/library/server/mobile.py | 15 ++++++++++++--- 2 files changed, 17 insertions(+), 4 deletions(-) diff --git a/src/calibre/library/server/content.py b/src/calibre/library/server/content.py index 0c0405aa50..c9ffe83f45 100644 --- a/src/calibre/library/server/content.py +++ b/src/calibre/library/server/content.py @@ -252,10 +252,14 @@ class ContentServer(object): cherrypy.response.headers['Content-Length'] = fmt.tell() 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 [_('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('"', '_') cherrypy.response.headers['Content-Disposition'] = \ b'attachment; filename="%s"'%fname diff --git a/src/calibre/library/server/mobile.py b/src/calibre/library/server/mobile.py index 1b6479250e..b4590b2d3d 100644 --- a/src/calibre/library/server/mobile.py +++ b/src/calibre/library/server/mobile.py @@ -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, - prefix): + prefix, have_kobo_browser=False): logo = DIV(IMG(src=prefix+'/static/calibre.png', alt=__appname__), id='logo') 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(','): if not fmt or fmt.lower().startswith('original_'): continue + file_extension = "kepub.epub" if fmt.lower() == "kepub" and have_kobo_browser else fmt a = quote(ascii_filename(book['authors'])) t = quote(ascii_filename(book['title'])) s = SPAN( A( fmt.lower(), href=prefix+'/get/%s/%s-%s_%d.%s' % (fmt, a, t, - book['id'], fmt.lower()) + book['id'], file_extension.lower()) ), CLASS('button')) s.tail = u'' @@ -182,11 +183,16 @@ class MobileServer(object): '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)') + KOBO_UA = re.compile('(?i)(?:Kobo Touch)') def is_mobile_browser(self, ua): match = self.MOBILE_UA.search(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): connect('mobile', '/mobile', self.mobile) 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) 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, start, len(ids), url_base, CKEYS, - self.opts.url_prefix), + self.opts.url_prefix, + have_kobo_browser=have_kobo_browser), encoding='utf-8', pretty_print=True) # tostring's include_meta_content_type is broken