def _generate(self, title, masthead, datefmt, feeds, extra_css=None, style=None): self.IS_HTML = False date = '%s, %s %s, %s' % (strftime('%A'), strftime('%B'), strftime('%d').lstrip('0'), strftime('%Y')) masthead_p = etree.Element("p") masthead_p.set("style","text-align:center") masthead_img = etree.Element("img") masthead_img.set("src",masthead) masthead_img.set("alt","masthead") masthead_p.append(masthead_img) head = HEAD(TITLE(title)) if style: head.append(STYLE(style, type='text/css')) if extra_css: head.append(STYLE(extra_css, type='text/css')) toc = TABLE(CLASS('toc'),width="100%",border="0",cellpadding="3px") for i, feed in enumerate(feeds): if feed: tr = TR() tr.append(TD(CLASS('calibre_rescale_120'), A(feed.title, href='feed_%d/index.html'%i))) tr.append(TD('%s' % len(feed.articles), style="text-align:right")) toc.append(tr) div = DIV( masthead_p, H3(CLASS('publish_date'),date), DIV(CLASS('divider')), toc) self.root = HTML(head, BODY(div)) if self.html_lang: self.root.set('lang', self.html_lang)
def apply_markup(self, rmap, parent=None): table = TABLE('\n\t\t') if parent is None: try: first_para = rmap[next(iter(self))] except StopIteration: return parent = first_para.getparent() idx = parent.index(first_para) parent.insert(idx, table) else: parent.append(table) for row in XPath('./w:tr')(self.tbl): tr = TR('\n\t\t\t') tr.tail = '\n\t\t' table.append(tr) for tc in XPath('./w:tc')(row): td = TD() td.tail = '\n\t\t\t' tr.append(td) for x in XPath('./w:p|./w:tbl')(tc): if x.tag.endswith('}p'): td.append(rmap[x]) else: self.sub_tables[x].apply_markup(rmap, parent=td) if len(tr): tr[-1].tail = '\n\t\t' if len(table): table[-1].tail = '\n\t'
def td_hours(seconds, bgcolor=None): if bgcolor is None: return TD('%.2f' % (seconds / seconds_per_hour), CLASS='numeric') else: return TD('%.2f' % (seconds / seconds_per_hour), CLASS='numeric', bgcolor=bgcolor)
def _generate(self, bottom, feed, art, number_of_articles_in_feed, two_levels, url, __appname__, prefix='', center=True, extra_css=None, style=None): head = HEAD(TITLE('navbar')) if style: head.append(STYLE(style, type='text/css')) if extra_css: head.append(STYLE(extra_css, type='text/css')) navbar = DIV() navbar_t = TABLE(CLASS('touchscreen_navbar')) navbar_tr = TR() # | Previous if art > 0: link = A(CLASS('article_link'), _('Previous'), href='%s../article_%d/index.html' % (prefix, art - 1)) navbar_tr.append(TD(CLASS('article_prev'), link)) else: navbar_tr.append(TD(CLASS('article_prev'), '')) # | Articles | Sections | link = A(CLASS('articles_link'), _('Articles'), href='%s../index.html#article_%d' % (prefix, art)) navbar_tr.append(TD(CLASS('article_articles_list'), link)) link = A(CLASS('sections_link'), _('Sections'), href='%s../../index.html#feed_%d' % (prefix, feed)) navbar_tr.append(TD(CLASS('article_sections_list'), link)) # | Next next = 'feed_%d'%(feed+1) if art == number_of_articles_in_feed - 1 \ else 'article_%d'%(art+1) up = '../..' if art == number_of_articles_in_feed - 1 else '..' link = A(CLASS('article_link'), _('Next'), href='%s%s/%s/index.html' % (prefix, up, next)) navbar_tr.append(TD(CLASS('article_next'), link)) navbar_t.append(navbar_tr) navbar.append(navbar_t) #print "\n%s\n" % etree.tostring(navbar, pretty_print=True) self.root = HTML(head, BODY(navbar))
def _generate(self, bottom, feed, art, number_of_articles_in_feed, two_levels, url, __appname__, prefix='', center=True, extra_css=None, style=None): head = HEAD(TITLE('navbar')) if style: head.append(STYLE(style, type='text/css')) if extra_css: head.append(STYLE(extra_css, type='text/css')) navbar = DIV() navbar_t = TABLE(CLASS('touchscreen_navbar')) navbar_tr = TR() if bottom and not url.startswith('file://'): navbar.append(HR()) text = 'This article was downloaded by ' p = PT(text, STRONG(__appname__), A(url, href=url, rel='calibre-downloaded-from'), style='text-align:left; max-width: 100%; overflow: hidden;') p[0].tail = ' from ' navbar.append(p) navbar.append(BR()) # | Previous if art > 0: link = A(CLASS('article_link'),_('Previous'),href='%s../article_%d/index.html'%(prefix, art-1)) navbar_tr.append(TD(CLASS('article_prev'),link)) else: navbar_tr.append(TD(CLASS('article_prev'),'')) # | Articles | Sections | link = A(CLASS('articles_link'),_('Articles'), href='%s../index.html#article_%d'%(prefix, art)) navbar_tr.append(TD(CLASS('article_articles_list'),link)) link = A(CLASS('sections_link'),_('Sections'), href='%s../../index.html#feed_%d'%(prefix, feed)) navbar_tr.append(TD(CLASS('article_sections_list'),link)) # | Next next = 'feed_%d'%(feed+1) if art == number_of_articles_in_feed - 1 \ else 'article_%d'%(art+1) up = '../..' if art == number_of_articles_in_feed - 1 else '..' link = A(CLASS('article_link'), _('Next'), href='%s%s/%s/index.html'%(prefix, up, next)) navbar_tr.append(TD(CLASS('article_next'),link)) navbar_t.append(navbar_tr) navbar.append(navbar_t) # print "\n%s\n" % etree.tostring(navbar, pretty_print=True) self.root = HTML(head, BODY(navbar))
def convert_node(toc, table, level, pdf): tr = TR( TD(toc.text or _('Unknown')), TD(), ) tr.set('class', 'level-%d' % level) anchors = pdf.links.anchors path = toc.abspath or None frag = toc.fragment or None if path is None: return path = os.path.normcase(os.path.abspath(path)) if path not in anchors: return None a = anchors[path] dest = a.get(frag, a[None]) num = pdf.page_tree.obj.get_num(dest[0]) tr[1].text = type('')(num) table.append(tr)
def apply_markup(self, rmap, page, parent=None): table = TABLE('\n\t\t') if self.bidi: table.set('dir', 'rtl') self.table_style.page = page style_map = {} if parent is None: try: first_para = rmap[next(iter(self))] except StopIteration: return parent = first_para.getparent() idx = parent.index(first_para) parent.insert(idx, table) else: parent.append(table) for row in self.namespace.XPath('./w:tr')(self.tbl): tr = TR('\n\t\t\t') style_map[tr] = self.style_map[row] tr.tail = '\n\t\t' table.append(tr) for tc in self.namespace.XPath('./w:tc')(row): td = TD() style_map[td] = s = self.style_map[tc] if s.col_span is not inherit: td.set('colspan', type('')(s.col_span)) if s.row_span is not inherit: td.set('rowspan', type('')(s.row_span)) td.tail = '\n\t\t\t' tr.append(td) for x in self.namespace.XPath('./w:p|./w:tbl')(tc): if x.tag.endswith('}p'): td.append(rmap[x]) else: self.sub_tables[x].apply_markup(rmap, page, parent=td) if len(tr): tr[-1].tail = '\n\t\t' if len(table): table[-1].tail = '\n\t' table_style = self.table_style.css if table_style: table.set('class', self.styles.register(table_style, 'table')) for elem, style in style_map.iteritems(): css = style.css if css: elem.set('class', self.styles.register(css, elem.tag))
def apply_markup(self, rmap, page, parent=None): table = TABLE('\n\t\t') if self.bidi: table.set('dir', 'rtl') self.table_style.page = page style_map = {} if parent is None: try: first_para = rmap[next(iter(self))] except StopIteration: return parent = first_para.getparent() idx = parent.index(first_para) parent.insert(idx, table) else: parent.append(table) for row in self.namespace.XPath('./w:tr')(self.tbl): tr = TR('\n\t\t\t') style_map[tr] = self.style_map[row] tr.tail = '\n\t\t' table.append(tr) for tc in self.namespace.XPath('./w:tc')(row): td = TD() style_map[td] = s = self.style_map[tc] if s.col_span is not inherit: td.set('colspan', type('')(s.col_span)) if s.row_span is not inherit: td.set('rowspan', type('')(s.row_span)) td.tail = '\n\t\t\t' tr.append(td) for x in self.namespace.XPath('./w:p|./w:tbl')(tc): if x.tag.endswith('}p'): td.append(rmap[x]) else: self.sub_tables[x].apply_markup(rmap, page, parent=td) if len(tr): tr[-1].tail = '\n\t\t' if len(table): table[-1].tail = '\n\t' table_style = self.table_style.css if table_style: table.set('class', self.styles.register(table_style, 'table')) for elem, style in iteritems(style_map): css = style.css if css: elem.set('class', self.styles.register(css, elem.tag))
def apply_markup(self, object_map): rmap = {v:k for k, v in object_map.iteritems()} for tbl, blocks in self.tables.iteritems(): if not blocks: continue parent = rmap[blocks[0]].getparent() table = TABLE('\n\t\t') idx = parent.index(rmap[blocks[0]]) parent.insert(idx, table) for row in XPath('./w:tr')(tbl): tr = TR('\n\t\t\t') tr.tail = '\n\t\t' table.append(tr) for tc in XPath('./w:tc')(row): td = TD() td.tail = '\n\t\t\t' tr.append(td) for p in XPath('./w:p')(tc): block = rmap[p] td.append(block) if len(tr): tr[-1].tail = '\n\t\t' if len(table): table[-1].tail = '\n\t'
def build_navigation(start, num, total, url_base): # {{{ end = min((start + num - 1), total) tagline = SPAN('Books %d to %d of %d' % (start, end, total), style='display: block; text-align: center;') left_buttons = TD(CLASS('button', style='text-align:left')) right_buttons = TD(CLASS('button', style='text-align:right')) if start > 1: for t, s in [('First', 1), ('Previous', max(start - num, 1))]: left_buttons.append(A(t, href='%s;start=%d' % (url_base, s))) if total > start + num: for t, s in [('Next', start + num), ('Last', total - num + 1)]: right_buttons.append(A(t, href='%s;start=%d' % (url_base, s))) buttons = TABLE(TR(left_buttons, right_buttons), CLASS('buttons')) return DIV(tagline, buttons, CLASS('navigation'))
def apply_markup(self, rmap, page, parent=None): table = TABLE("\n\t\t") self.table_style.page = page style_map = {} if parent is None: try: first_para = rmap[next(iter(self))] except StopIteration: return parent = first_para.getparent() idx = parent.index(first_para) parent.insert(idx, table) else: parent.append(table) for row in self.namespace.XPath("./w:tr")(self.tbl): tr = TR("\n\t\t\t") style_map[tr] = self.style_map[row] tr.tail = "\n\t\t" table.append(tr) for tc in self.namespace.XPath("./w:tc")(row): td = TD() style_map[td] = s = self.style_map[tc] if s.col_span is not inherit: td.set("colspan", type("")(s.col_span)) if s.row_span is not inherit: td.set("rowspan", type("")(s.row_span)) td.tail = "\n\t\t\t" tr.append(td) for x in self.namespace.XPath("./w:p|./w:tbl")(tc): if x.tag.endswith("}p"): td.append(rmap[x]) else: self.sub_tables[x].apply_markup(rmap, page, parent=td) if len(tr): tr[-1].tail = "\n\t\t" if len(table): table[-1].tail = "\n\t" table_style = self.table_style.css if table_style: table.set("class", self.styles.register(table_style, "table")) for elem, style in style_map.iteritems(): css = style.css if css: elem.set("class", self.styles.register(css, elem.tag))
def build_navigation(start, num, total, url_base): # {{{ end = min((start + num - 1), total) tagline = SPAN("Books %d to %d of %d" % (start, end, total), style="display: block; text-align: center;") left_buttons = TD(CLASS("button", style="text-align:left")) right_buttons = TD(CLASS("button", style="text-align:right")) if start > 1: for t, s in [("First", 1), ("Previous", max(start - num, 1))]: left_buttons.append(A(t, href="%s&start=%d" % (url_base, s))) if total > start + num: for t, s in [("Next", start + num), ("Last", total - num + 1)]: right_buttons.append(A(t, href="%s&start=%d" % (url_base, s))) buttons = TABLE(TR(left_buttons, right_buttons), CLASS("buttons")) return DIV(tagline, buttons, CLASS("navigation"))
def createTable(tableTrlist,cols,casetype): table = TABLE(border="1", cellspacing="0", cellpadding="4", id=casetype, style="border: 1px solid black; \ border-collapse: \ collapse;empty-cells: show;margin: 0px 1px; ") tr = TR() for col in cols: tr.append(TH(col, style="border: 1px solid black;\ padding: 1px 4px;\ margin: 0px;")) table.append(tr) for trlist in tableTrlist: if len(trlist)==0:continue tr = TR() for td in trlist: tr.append(TD(td)) table.append(tr) return table
def build_navigation(start, num, total, url_base): # {{{ end = min((start+num-1), total) tagline = SPAN('Books %d to %d of %d'%(start, end, total), style='display: block; text-align: center;') left_buttons = TD(CLASS('button', style='text-align:left')) right_buttons = TD(CLASS('button', style='text-align:right')) if start > 1: for t,s in [('First', 1), ('Previous', max(start-num,1))]: left_buttons.append(A(t, href='%s;start=%d'%(url_base, s))) if total > start + num: for t,s in [('Next', start+num), ('Last', total-num+1)]: right_buttons.append(A(t, href='%s;start=%d'%(url_base, s))) buttons = TABLE( TR(left_buttons, right_buttons), CLASS('buttons')) return DIV(tagline, buttons, CLASS('navigation'))
def build_index(books, num, search, sort, order, start, total, url_base, CKEYS, prefix): logo = DIV(IMG(src=prefix+'/static/calibre.png', alt=__appname__), id='logo') search_box = build_search_box(num, search, sort, order, prefix) navigation = build_navigation(start, num, total, prefix+url_base) navigation2 = build_navigation(start, num, total, prefix+url_base) bookt = TABLE(id='listing') body = BODY( logo, search_box, navigation, HR(CLASS('spacer')), bookt, HR(CLASS('spacer')), navigation2 ) # Book list {{{ for book in books: thumbnail = TD( IMG(type='image/jpeg', border='0', src=prefix+'/get/thumb/%s' % book['id']), CLASS('thumbnail')) data = TD() for fmt in book['formats'].split(','): if not fmt or fmt.lower().startswith('original_'): continue 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()) ), CLASS('button')) s.tail = u'' data.append(s) div = DIV(CLASS('data-container')) data.append(div) series = u'[%s - %s]'%(book['series'], book['series_index']) \ if book['series'] else '' tags = u'Tags=[%s]'%book['tags'] if book['tags'] else '' ctext = '' for key in CKEYS: val = book.get(key, None) if val: ctext += '%s=[%s] '%tuple(val.split(':#:')) first = SPAN(u'\u202f%s %s by %s' % (book['title'], series, book['authors']), CLASS('first-line')) div.append(first) second = SPAN(u'%s - %s %s %s' % ( book['size'], book['timestamp'], tags, ctext), CLASS('second-line')) div.append(second) bookt.append(TR(thumbnail, data)) # }}} body.append(DIV( A(_('Switch to the full interface (non-mobile interface)'), href=prefix+"/browse", style="text-decoration: none; color: blue", title=_('The full interface gives you many more features, ' 'but it may not work well on a small screen')), style="text-align:center")) return HTML( HEAD( TITLE(__appname__ + ' Library'), LINK(rel='icon', href='http://calibre-ebook.com/favicon.ico', type='image/x-icon'), LINK(rel='stylesheet', type='text/css', href=prefix+'/mobile/style.css'), LINK(rel='apple-touch-icon', href="/static/calibre.png") ), # End head body ) # End html
def td_percent(pct, bgcolor=None): if bgcolor is None: return TD('%.2f%%' % pct, CLASS='numeric') else: return TD('%.2f%%' % pct, bgcolor=bgcolor, CLASS='numeric')
def td(x, atts=None): if atts is None: atts = {} atts.setdefault('style', dfstyle) return TD(x, **atts)
def build_index(books, num, search, sort, order, start, total, url_base, CKEYS, prefix): logo = DIV(IMG(src=prefix + '/static/calibre.png', alt=__appname__), id='logo') search_box = build_search_box(num, search, sort, order, prefix) navigation = build_navigation(start, num, total, prefix + url_base) navigation2 = build_navigation(start, num, total, prefix + url_base) bookt = TABLE(id='listing') body = BODY(logo, search_box, navigation, HR(CLASS('spacer')), bookt, HR(CLASS('spacer')), navigation2) # Book list {{{ for book in books: thumbnail = TD( IMG(type='image/jpeg', border='0', src=prefix + '/get/thumb/%s' % book['id']), CLASS('thumbnail')) data = TD() for fmt in book['formats'].split(','): if not fmt or fmt.lower().startswith('original_'): continue 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())), CLASS('button')) s.tail = u'' data.append(s) div = DIV(CLASS('data-container')) data.append(div) series = u'[%s - %s]'%(book['series'], book['series_index']) \ if book['series'] else '' tags = u'Tags=[%s]' % book['tags'] if book['tags'] else '' ctext = '' for key in CKEYS: val = book.get(key, None) if val: ctext += '%s=[%s] ' % tuple(val.split(':#:')) first = SPAN( u'\u202f%s %s by %s' % (book['title'], series, book['authors']), CLASS('first-line')) div.append(first) second = SPAN( u'%s - %s %s %s' % (book['size'], book['timestamp'], tags, ctext), CLASS('second-line')) div.append(second) bookt.append(TR(thumbnail, data)) # }}} body.append( DIV(A(_('Switch to the full interface (non-mobile interface)'), href=prefix + "/browse", style="text-decoration: none; color: blue", title=_('The full interface gives you many more features, ' 'but it may not work well on a small screen')), style="text-align:center")) return HTML( HEAD( TITLE(__appname__ + ' Library'), LINK(rel='icon', href='http://calibre-ebook.com/favicon.ico', type='image/x-icon'), LINK(rel='stylesheet', type='text/css', href=prefix + '/mobile/style.css'), LINK(rel='apple-touch-icon', href="/static/calibre.png")), # End head body) # End html
def print_table(filename, table, job_names, metric): table = calc_gain(table, job_names) baseline = job_names[0] with open(filename, 'w') as out: top_headers = TR(TH('')) headers = TR(TH('Steps')) # Build the header row for j in job_names: colspan = 1 headers.append(TH('chunks')) colspan += 2 headers.append(TH('hours', colspan='2')) # All jobs except the baseline get "hours gained" and # "percent hours gained" columns if j != baseline: colspan += 2 headers.append(TH('improvement', colspan='2')) top_headers.append(TH(j, colspan=str(colspan))) data_rows = [] for row in table: tr = TR(TD(str(row['step']))) for j in job_names: tr.append(TD(str(row['%s_chunks' % j]), CLASS='numeric')) intensity = row['%s_%s_intensity' % (j, metric)] bgcolor = '#ffff%02x' % intensity tr.append(td_hours(row['%s_%s' % (j, metric)], bgcolor)) tr.append(td_percent(row['%s_%s_pct' % (j, metric)], bgcolor)) if j != baseline: hours = row['%s_%s_gain' % (j, metric)] pct = row['%s_%s_pct_gain' % (j, metric)] intensity = 255 * (pct / 100.) bgcolor = gain_pct_to_bgcolor(pct) tr.append(td_hours(hours, bgcolor=bgcolor)) tr.append(td_percent(pct, bgcolor=bgcolor)) data_rows.append(tr) summary = [TD('Totals')] for j in job_names: summary.append(TD('')) summary.extend([ td_hours(sum(table['%s_%s' % (j, metric)])), td_percent(sum(table['%s_%s_pct' % (j, metric)])) ]) if j != baseline: hours = sum(table['%s_%s_gain' % (j, metric)]) pct = sum(table['%s_%s_pct_gain' % (j, metric)]) bgcolor = gain_pct_to_bgcolor(pct) summary.extend( [td_hours(hours, bgcolor), td_percent(pct, bgcolor)]) rows = [top_headers, headers] rows.extend(data_rows) rows.append(TR(*summary)) html = template(metric, E.DIV(E.TABLE(*rows))) out.write(lxml.html.tostring(html))
def _generate(self, f, feeds, cutoff, extra_css=None, style=None): from calibre.utils.cleantext import clean_xml_chars def trim_title(title,clip=18): if len(title)>clip: tokens = title.split(' ') new_title_tokens = [] new_title_len = 0 if len(tokens[0]) > clip: return tokens[0][:clip] + '...' for token in tokens: if len(token) + new_title_len < clip: new_title_tokens.append(token) new_title_len += len(token) else: new_title_tokens.append('...') title = ' '.join(new_title_tokens) break return title self.IS_HTML = False feed = feeds[f] # Construct the navbar navbar_t = TABLE(CLASS('touchscreen_navbar')) navbar_tr = TR() # Previous Section link = '' if f > 0: link = A(CLASS('feed_link'), trim_title(feeds[f-1].title), href='../feed_%d/index.html' % int(f-1)) navbar_tr.append(TD(CLASS('feed_prev'),link)) # Up to Sections link = A(_('Sections'), href="../index.html") navbar_tr.append(TD(CLASS('feed_up'),link)) # Next Section link = '' if f < len(feeds)-1: link = A(CLASS('feed_link'), trim_title(feeds[f+1].title), href='../feed_%d/index.html' % int(f+1)) navbar_tr.append(TD(CLASS('feed_next'),link)) navbar_t.append(navbar_tr) top_navbar = navbar_t bottom_navbar = copy.copy(navbar_t) # print "\n%s\n" % etree.tostring(navbar_t, pretty_print=True) # Build the page head = HEAD(TITLE(feed.title)) if style: head.append(STYLE(style, type='text/css')) if extra_css: head.append(STYLE(extra_css, type='text/css')) body = BODY() div = DIV( top_navbar, H2(feed.title, CLASS('feed_title')) ) body.append(div) if getattr(feed, 'image', None): div.append(DIV(IMG( alt=feed.image_alt if feed.image_alt else '', src=feed.image_url ), CLASS('calibre_feed_image'))) if getattr(feed, 'description', None): d = DIV(clean_xml_chars(feed.description), CLASS('calibre_feed_description', 'calibre_rescale_80')) d.append(BR()) div.append(d) for i, article in enumerate(feed.articles): if not getattr(article, 'downloaded', False): continue div_td = DIV(CLASS('article_summary'), A(article.title, CLASS('summary_headline','calibre_rescale_120', href=article.url))) if article.author: div_td.append(DIV(article.author, CLASS('summary_byline', 'calibre_rescale_100'))) if article.summary: div_td.append(DIV(cutoff(article.text_summary), CLASS('summary_text', 'calibre_rescale_100'))) div.append(div_td) div.append(bottom_navbar) self.root = HTML(head, body) if self.html_lang: self.root.set('lang', self.html_lang)
def build_index(books, num, search, sort, order, start, total, url_base, CKEYS, 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) navigation = build_navigation(start, num, total, prefix + url_base) navigation2 = build_navigation(start, num, total, prefix + url_base) bookt = TABLE(id="listing") body = BODY(logo, search_box, navigation, HR(CLASS("spacer")), bookt, HR(CLASS("spacer")), navigation2) # Book list {{{ for book in books: thumbnail = TD( IMG(type="image/jpeg", border="0", src=prefix + "/get/thumb/%s" % book["id"]), CLASS("thumbnail") ) data = TD() for fmt in book["formats"].split(","): if not fmt or fmt.lower().startswith("original_"): continue file_extension = "kepub.epub" if have_kobo_browser and fmt.lower() == "kepub" 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"], file_extension.lower())), CLASS("button"), ) s.tail = u"" data.append(s) div = DIV(CLASS("data-container")) data.append(div) series = u"[%s - %s]" % (book["series"], book["series_index"]) if book["series"] else "" tags = u"Tags=[%s]" % book["tags"] if book["tags"] else "" ctext = "" for key in CKEYS: val = book.get(key, None) if val: ctext += "%s=[%s] " % tuple(val.split(":#:")) first = SPAN( u"\u202f%s %s by %s" % (clean_xml_chars(book["title"]), clean_xml_chars(series), clean_xml_chars(book["authors"])), CLASS("first-line"), ) div.append(first) second = SPAN(u"%s - %s %s %s" % (book["size"], book["timestamp"], tags, ctext), CLASS("second-line")) div.append(second) bookt.append(TR(thumbnail, data)) # }}} body.append( DIV( A( _("Switch to the full interface (non-mobile interface)"), href=prefix + "/browse", style="text-decoration: none; color: blue", title=_( "The full interface gives you many more features, " "but it may not work well on a small screen" ), ), style="text-align:center", ) ) return HTML( HEAD( TITLE(__appname__ + " Library"), LINK(rel="icon", href="//calibre-ebook.com/favicon.ico", type="image/x-icon"), LINK(rel="stylesheet", type="text/css", href=prefix + "/mobile/style.css"), LINK(rel="apple-touch-icon", href="/static/calibre.png"), META(name="robots", content="noindex"), ), # End head body, ) # End html