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