Sync to trunk.

This commit is contained in:
John Schember 2011-11-02 07:30:44 -04:00
commit 4f611b3abd
32 changed files with 619 additions and 159 deletions

View File

@ -19,6 +19,55 @@
# new recipes: # new recipes:
# - title: # - title:
- version: 0.8.24
date: 2011-10-27
new features:
- title: "Kobo: Add support for fetching annotations from the kobo reader."
description: "Right click the send to device button in calibre with your kobo connected and choose fetch annotations. The annotations are placed into the comments of the corresponding books in the calibre library. This feature is still experimental."
type: major
- title: "Preserve the set of selected books in the library view when a device is connected, fixing a long standing annoyance"
bug fixes:
- title: "Prevent changing of device metadata management option while a device is connected."
tickets: [874118]
- title: "Book details panel: Show tooltip only when hovering over cover, not the rest of the book information, as it makes it hard to read."
tickets: [876454]
- title: "MOBI Output: Fix use of list elements as link anchors caused links to always point to start of list."
tickets: [879391]
- title: "RB Output: Fix calibre generated rb files not being opened by the RocketBook."
tickets: [880930]
- title: "FB2 Input: Dont choke on FB2 files that have empty embedded content tags."
tickets: [880904]
- title: "ODT Input: CSS rationalization should not fail with non ascii class names"
- title: "Fix creating new library using the copy structure option incorrectly setting all text type columns to be like the tags column"
- title: "E-book viewer: Don't choke on windows installs with a non UTF-8 filesystem encoding."
tickets: [879740]
improved recipes:
- Novaya Gazeta
- El Universal (Venezuela)
- The Australian (subscription enabled)
- Metro NL
- The Scotsman
- Japan Times
new recipes:
- title: Silicon Republic
author: Neil Grogan
- title: Calibre Blog
author: Krittika Goyal
- version: 0.8.23 - version: 0.8.23
date: 2011-10-21 date: 2011-10-21

35
recipes/capital_gr.recipe Normal file
View File

@ -0,0 +1,35 @@
from calibre.web.feeds.recipes import BasicNewsRecipe
class Capital(BasicNewsRecipe):
title = 'Capital.gr'
__author__ ='Stelios'
description = 'Financial News from Greece'
#max_articles_per_feed = 100
oldest_article = 3
publisher = 'Capital.gr'
category = 'news, GR'
language = 'el'
encoding = 'windows-1253'
cover_url = 'http://files.capital.gr/images/caplogo.gif'
no_stylesheets = True
use_embedded_content = False
remove_empty_feeds = True
keep_only_tags = [
dict(name='h1'),
dict(name='p'),
dict(name='span', attrs={'id' : ["textbody"]})
]
#3 posts seemed to have utf8 encoding
feeds = [
(u'\u039F\u039B\u0395\u03A3 \u039F\u0399 \u0395\u0399\u0394\u0397\u03A3\u0395\u0399\u03A3', 'http://www.capital.gr/news/newsrss.asp?s=-1'),
(u'\u0395\u03A0\u0399\u03A7\u0395\u0399\u03A1\u0397\u03A3\u0395\u0399\u03A3', 'http://www.capital.gr/news/newsrss.asp?s=-2'),
(u'\u0391\u0393\u039F\u03A1\u0395\u03A3', 'http://www.capital.gr/news/newsrss.asp?s=-3'),
(u'\u039F\u0399\u039A\u039F\u039D\u039F\u039C\u0399\u0391', 'http://www.capital.gr/news/newsrss.asp?s=-4'),
(u'\u03A7\u03A1\u0397\u039C. \u0391\u039D\u0391\u039A\u039F\u0399\u039D\u03A9\u03A3\u0395\u0399\u03A3', 'http://www.capital.gr/news/newsrss.asp?s=-6'),
(u'\u039C\u03CC\u03BD\u03B9\u03BC\u03B5\u03C2 \u03C3\u03C4\u03AE\u03BB\u03B5\u03C2: \u039C\u0395 \u0391\u03A0\u039F\u03A8\u0397', 'http://www.capital.gr/articles/articlesrss.asp?catid=4'),
(u'\u039C\u03CC\u03BD\u03B9\u03BC\u03B5\u03C2 \u03C3\u03C4\u03AE\u03BB\u03B5\u03C2: \u03A3\u0399\u03A9\u03A0\u0397\u03A4\u0397\u03A1\u0399\u039F', 'http://www.capital.gr/articles/articlesrss.asp?catid=6'),
(u'\u039C\u03CC\u03BD\u03B9\u03BC\u03B5\u03C2 \u03C3\u03C4\u03AE\u03BB\u03B5\u03C2: \u03A0\u0399\u03A3\u03A9 \u0391\u03A0\u039F \u03A4\u0399\u03A3 \u0393\u03A1\u0391\u039C\u039C\u0395\u03A3', 'http://www.capital.gr/articles/articlesrss.asp?catid=8'),
#(u'\u039C\u03CC\u03BD\u03B9\u03BC\u03B5\u03C2 \u03C3\u03C4\u03AE\u03BB\u03B5\u03C2: \u03A4\u0395\u03A7\u039D\u039F\u039B\u039F\u0393\u0399\u0391', 'http://www.capital.gr/news/newsrss.asp?s=-8') not working for now
]

View File

@ -1,10 +1,11 @@
from calibre.web.feeds.news import BasicNewsRecipe from calibre.web.feeds.news import BasicNewsRecipe
import re
class AdvancedUserRecipe1306061239(BasicNewsRecipe): class AdvancedUserRecipe1306061239(BasicNewsRecipe):
title = u'The Daily Mirror' title = u'The Daily Mirror'
description = 'News as provide by The Daily Mirror -UK' description = 'News as provide by The Daily Mirror -UK'
__author__ = 'Dave Asbury' __author__ = 'Dave Asbury'
# last updated 30/10/11
language = 'en_GB' language = 'en_GB'
cover_url = 'http://yookeo.com/screens/m/i/mirror.co.uk.jpg' cover_url = 'http://yookeo.com/screens/m/i/mirror.co.uk.jpg'
@ -12,26 +13,30 @@ class AdvancedUserRecipe1306061239(BasicNewsRecipe):
masthead_url = 'http://www.nmauk.co.uk/nma/images/daily_mirror.gif' masthead_url = 'http://www.nmauk.co.uk/nma/images/daily_mirror.gif'
oldest_article = 1 oldest_article = 2
max_articles_per_feed = 100 max_articles_per_feed = 30
remove_empty_feeds = True remove_empty_feeds = True
remove_javascript = True remove_javascript = True
no_stylesheets = True no_stylesheets = True
extra_css = '''
body{ text-align: justify; font-family:Arial,Helvetica,sans-serif; font-size:11px; font-size-adjust:none; font-stretch:normal; font-style:normal; font-variant:normal; font-weight:normal;}
'''
keep_only_tags = [ keep_only_tags = [
dict(name='h1'), dict(name='div',attrs={'id' : 'body-content'})
dict(attrs={'class':['article-attr']}), ]
dict(name='div', attrs={'class' : [ 'article-body', 'crosshead']})
remove_tags_after = [dict (name='div',attrs={'class' : 'related'})]
]
remove_tags = [ remove_tags = [
dict(name='div', attrs={'class' : ['caption', 'article-resize']}), dict(name='div',attrs={'id' : ['sidebar','menu','search-box','roffers-top']}),
dict( attrs={'class':'append-html'}) dict(name='div',attrs={'class' :['inline-ad span-16 last','article-resize','related','list teasers']}),
] dict(attrs={'class' : ['channellink','article-tags','replace','append-html']}),
dict(name='div',attrs={'class' : 'span-12 last sl-others addthis_toolbox addthis_default_style'})
]
preprocess_regexps = [
(re.compile(r'<dl class="q-search">.*?</dl>', re.IGNORECASE | re.DOTALL), lambda match: '')]
feeds = [ feeds = [
@ -43,10 +48,10 @@ class AdvancedUserRecipe1306061239(BasicNewsRecipe):
,(u'Music News','http://www.mirror.co.uk/celebs/music/rss.xml') ,(u'Music News','http://www.mirror.co.uk/celebs/music/rss.xml')
,(u'Celebs and Tv Gossip','http://www.mirror.co.uk/celebs/tv/rss.xml') ,(u'Celebs and Tv Gossip','http://www.mirror.co.uk/celebs/tv/rss.xml')
,(u'Sport','http://www.mirror.co.uk/sport/rss.xml') ,(u'Sport','http://www.mirror.co.uk/sport/rss.xml')
,(u'Life Style','http://www.mirror.co.uk/life-style/rss.xml') ,(u'Life Style','http://www.mirror.co.uk/life-style/rss.xml')
,(u'Advice','http://www.mirror.co.uk/advice/rss.xml') ,(u'Advice','http://www.mirror.co.uk/advice/rss.xml')
,(u'Travel','http://www.mirror.co.uk/advice/travel/rss.xml') ,(u'Travel','http://www.mirror.co.uk/advice/travel/rss.xml')
# example of commented out feed not needed ,(u'Travel','http://www.mirror.co.uk/advice/travel/rss.xml') # example of commented out feed not needed ,(u'Travel','http://www.mirror.co.uk/advice/travel/rss.xml')
]
]

View File

@ -16,7 +16,7 @@ class DeutscheWelle_es(BasicNewsRecipe):
max_articles_per_feed = 100 max_articles_per_feed = 100
use_embedded_content = False use_embedded_content = False
no_stylesheets = True no_stylesheets = True
language = 'de_ES' language = 'de'
publication_type = 'newsportal' publication_type = 'newsportal'
remove_empty_feeds = True remove_empty_feeds = True
masthead_url = 'http://www.dw-world.de/skins/std/channel1/pics/dw_logo1024.gif' masthead_url = 'http://www.dw-world.de/skins/std/channel1/pics/dw_logo1024.gif'

34
recipes/in_gr.recipe Normal file
View File

@ -0,0 +1,34 @@
from calibre.web.feeds.recipes import BasicNewsRecipe
class ingr(BasicNewsRecipe):
title = 'in.gr'
__author__ = 'Stelios'
description = 'News from Greece'
# max_articles_per_feed = 100
oldest_article = 4
publisher = 'in.gr'
category = 'news, GR'
language = 'el'
encoding = 'utf8'
no_stylesheets = True
use_embedded_content = False
remove_empty_feeds = True
encoding = 'utf8'
keep_only_tags = [
dict(name='h1'),
dict(name='div', attrs={'id' : ['in-news-article']})
]
remove_tags = [
dict(name='em', attrs={'class' : ['credits']}),
dict(name='div', attrs={'class' : ['article-tools-hor', 'promo-banners gAds', 'main', 'article-listen-player', 'article-tools-hor-bttm', 'tools-sec', 'article-tools', 'article-listen-player-ver']})
]
feeds = [
(u'\u0395\u03BB\u03BB\u03AC\u03B4\u03B1', 'http://rss.in.gr/feed/news/greece'),
(u'\u0395\u03B9\u03B4\u03AE\u03C3\u03B5\u03B9\u03C2', 'http://rss.in.gr/feed/news'),
(u'\u039A\u03CC\u03C3\u03BC\u03BF\u03C2', 'http://rss.in.gr/feed/news/world'),
(u'\u0395\u03C0\u03B9\u03C3\u03C4\u03AE\u03BC\u03B7', 'http://rss.in.gr/feed/news/science'),
(u'\u03A0\u03BF\u03BB\u03B9\u03C4\u03B9\u03C3\u03BC\u03CC\u03C2', 'http://rss.in.gr/feed/news/culture')
]

43
recipes/men24_gr.recipe Normal file
View File

@ -0,0 +1,43 @@
from calibre.web.feeds.recipes import BasicNewsRecipe
class Men24(BasicNewsRecipe):
title = 'Men24.gr'
__author__ = 'Stelios'
description = 'Greek Mens portal'
oldest_article = 14
max_articles_per_feed = 100
language = 'el'
cover_url = 'http://www.men24.gr/ast/img/men24Logo.jpg'
category = 'magazines, GR'
language = 'el'
encoding = 'windows-1253'
no_stylesheets = True
use_embedded_content = False
remove_empty_feeds = True
extra_css = '''
.artPrintTitle{font-family :Arial,Helvetica,sans-serif; font-weight: bold; font-size:large;}
.artPrintSubtitle{font-family :Arial,Helvetica,sans-serif; font-size:x-small;}
'''
remove_tags = [
dict(name='td', attrs={'class':['artPrintCategory']}),
dict(name='table', attrs={'class':['footer']}),
dict(name='img')
]
feeds = [
(u'\u038C\u03BB\u03B5\u03C2 \u03BF\u03B9 \u03B5\u03B9\u03B4\u03AE\u03C3\u03B5\u03B9\u03C2', 'http://www.men24.gr/svc/rss/lastNews/'),
(u'\u03A3\u03C4\u03C5\u03BB', 'http://www.men24.gr/svc/rss/categoryNews/?category=style'),
(u'Fitness', 'http://www.men24.gr/svc/rss/categoryNews/?category=fitness'),
(u'Gadgets', 'http://www.men24.gr/svc/rss/categoryNews/?category=gadgets'),
(u'\u0394\u03B9\u03B1\u03C3\u03BA\u03AD\u03B4\u03B1\u03C3\u03B7', 'http://www.men24.gr/svc/rss/categoryNews/?category=fun'),
(u'\u03A7\u03C1\u03AE\u03BC\u03B1 \u03BA\u03B1\u03B9 \u039A\u03B1\u03C1\u03B9\u03AD\u03C1\u03B1', 'http://www.men24.gr/svc/rss/categoryNews/?category=money'),
(u'Special Edition', 'http://www.men24.gr/svc/rss/categoryNews/?category=special'),
(u'\u0388\u03C1\u03C9\u03C4\u03B1\u03C2 \u03BA\u03B1\u03B9 Sex', 'http://www.men24.gr/svc/rss/categoryNews/?category=love'),
(u'\u0386\u03BD\u03C4\u03C1\u03B5\u03C2 \u03C4\u03BF\u03C5 24', 'http://www.men24.gr/svc/rss/categoryNews/?category=men'),
(u'\u0393\u03C5\u03BD\u03B1\u03AF\u03BA\u03B5\u03C2', 'http://www.men24.gr/svc/rss/categoryNews/?category=women'),
(u'\u039F\u03B4\u03B7\u03B3\u03BF\u03AF', 'http://www.men24.gr/svc/rss/categoryNews/?category=guides'),
(u'\u03A4\u03B6\u03CC\u03B3\u03BF\u03C2', 'http://www.men24.gr/svc/rss/categoryNews/?category=gamble')
]
def print_version(self, url):
return url.replace('.asp', '.print.asp')

48
recipes/newsbeast.recipe Normal file
View File

@ -0,0 +1,48 @@
from calibre.web.feeds.recipes import BasicNewsRecipe
class newsbeast(BasicNewsRecipe):
title = 'Newsbeast'
__author__ = 'Stelios'
description = 'News from Greece'
oldest_article = 2
max_articles_per_feed = 100
publisher = 'newsbeast'
category = 'news, GR'
language = 'el'
encoding = 'utf8'
no_stylesheets = True
use_embedded_content = False
remove_empty_feeds = True
encoding = 'utf8'
keep_only_tags = [
dict(name='div', attrs={'class' : ['article-title']}),
# dict(name='img', attrs={'class' : ['article_photo']}),
#If enabled feeds exceede 15MB
dict(name='div', attrs={'class' : ['txt']})
]
remove_tags = [
dict(name='table', attrs={'id':['artFoot']}),
dict(name='img'),
#If removed feeds exceede 15MB
dict(name='p', attrs={'class':['article-details']})
]
feeds = [
(u'\u0395\u03BB\u03BB\u03AC\u03B4\u03B1', 'http://www.newsbeast.gr/feeds/greece'),
(u'\u039A\u03CC\u03C3\u03BC\u03BF\u03C2', 'http://www.newsbeast.gr/feeds/world'),
(u'\u03A0\u03BF\u03BB\u03B9\u03C4\u03B9\u03BA\u03AE', 'http://www.newsbeast.gr/feeds/politiki'),
(u'\u039F\u03B9\u03BA\u03BF\u03BD\u03BF\u03BC\u03AF\u03B1', 'http://www.newsbeast.gr/feeds/financial'),
(u'\u0391\u03B8\u03BB\u03B7\u03C4\u03B9\u03BA\u03AC', 'http://www.newsbeast.gr/feeds/sports'),
(u'\u039A\u03BF\u03B9\u03BD\u03C9\u03BD\u03AF\u03B1', 'http://www.newsbeast.gr/feeds/society'),
(u'\u03A0\u03B5\u03C1\u03B9\u03B2\u03AC\u03BB\u03BB\u03BF\u03BD', 'http://www.newsbeast.gr/feeds/environment'),
(u'Media', 'http://www.newsbeast.gr/feeds/media'),
(u'\u0394\u03B9\u03B1\u03C3\u03BA\u03AD\u03B4\u03B1\u03C3\u03B7', 'http://www.newsbeast.gr/feeds/entertainment'),
(u'Lifestyle', 'http://www.newsbeast.gr/feeds/lifestyle'),
(u'\u03A4\u03B5\u03C7\u03BD\u03BF\u03BB\u03BF\u03B3\u03AF\u03B1', 'http://www.newsbeast.gr/feeds/technology'),
(u'\u0391\u03C5\u03C4\u03BF\u03BA\u03AF\u03BD\u03B7\u03C4\u03BF', 'http://www.newsbeast.gr/feeds/car'),
(u'\u0393\u03C5\u03BD\u03B1\u03AF\u03BA\u03B1', 'http://www.newsbeast.gr/feeds/woman'),
(u'\u03A5\u03B3\u03B5\u03AF\u03B1', 'http://www.newsbeast.gr/feeds/health'),
(u'\u03A0\u03BF\u03BB\u03B9\u03C4\u03B9\u03C3\u03BC\u03CC\u03C2', 'http://www.newsbeast.gr/feeds/culture'),
(u'\u038C,\u03C4\u03B9 \u03BD\u03B1 \u03BD\u03B1\u03B9', 'http://www.newsbeast.gr/feeds/weird')
]

View File

@ -1,6 +1,6 @@
__license__ = 'GPL v3' __license__ = 'GPL v3'
__copyright__ = '2008-2010, Darko Miletic <darko.miletic at gmail.com>' __copyright__ = '2008-2011, Darko Miletic <darko.miletic at gmail.com>'
''' '''
www.nin.co.rs www.nin.co.rs
''' '''
@ -29,6 +29,7 @@ class Nin(BasicNewsRecipe):
use_embedded_content = False use_embedded_content = False
language = 'sr' language = 'sr'
publication_type = 'magazine' publication_type = 'magazine'
masthead_url = 'http://www.nin.co.rs/img/head/logo.jpg'
extra_css = """ extra_css = """
@font-face {font-family: "sans1";src:url(res:///opt/sony/ebook/FONT/tt0003m_.ttf)} @font-face {font-family: "sans1";src:url(res:///opt/sony/ebook/FONT/tt0003m_.ttf)}
body{font-family: Verdana, Lucida, sans1, sans-serif} body{font-family: Verdana, Lucida, sans1, sans-serif}
@ -72,9 +73,11 @@ class Nin(BasicNewsRecipe):
def get_cover_url(self): def get_cover_url(self):
cover_url = None cover_url = None
soup = self.index_to_soup(self.INDEX) soup = self.index_to_soup(self.INDEX)
link_item = soup.find('img',attrs={'width':'100','border':'0'}) for item in soup.findAll('a', href=True):
if link_item: if item['href'].startswith('/pages/issue.php?id='):
cover_url = self.PREFIX + link_item['src'] simg = item.find('img')
if simg:
return self.PREFIX + item.img['src']
return cover_url return cover_url
def parse_index(self): def parse_index(self):

26
recipes/protagon.recipe Normal file
View File

@ -0,0 +1,26 @@
from calibre.web.feeds.recipes import BasicNewsRecipe
class protagon(BasicNewsRecipe):
title = 'Protagon'
__author__ = 'Stelios'
description = 'Opinion articles in Greek'
oldest_article = 7
max_articles_per_feed = 100
publisher = 'Various'
category = 'GR'
language = 'el'
encoding = 'utf8'
no_stylesheets = True
use_embedded_content = False
remove_empty_feeds = True
keep_only_tags = [
dict(name='h1', attrs={'id' : ['title']}),
dict(name='div', attrs={'class' : ['freetext']})
]
feeds = [
(u'\u0398\u03AD\u03BC\u03B1\u03C4\u03B1', 'http://www.protagon.gr/rss?i=protagon.el.8emata')
]

View File

@ -0,0 +1,19 @@
from calibre.web.feeds.news import BasicNewsRecipe
class Real_world_economics_review(BasicNewsRecipe):
title = u'Real-world economis review blog'
oldest_article = 7
max_articles_per_feed = 100
use_embedded_content = False
__author__ = 'Julio Map'
language = 'en'
no_stylesheets = True
keep_only_tags = dict(name='div', attrs={'id':'main'})
remove_tags = [dict(name='div', attrs={'id':'postpath'}),
dict(name='div', attrs={'class':'robots-nocontent sd-block sd-social sd-social-icon-text sd-sharing'}),
dict(name='div', attrs={'class':'sharedaddy sd-sharing-enabled'})
]
feeds = [(u'Real-World Economics Review Blog', u'http://rwer.wordpress.com/feed/')]

View File

@ -27,12 +27,12 @@ class ScienceAAS(BasicNewsRecipe):
br = BasicNewsRecipe.get_browser() br = BasicNewsRecipe.get_browser()
if self.username is not None and self.password is not None: if self.username is not None and self.password is not None:
br.open(self.LOGIN) br.open(self.LOGIN)
br.select_form(name='registered_users_form') br.select_form(nr=1)
br['username'] = self.username br['username'] = self.username
br['code' ] = self.password br['code' ] = self.password
br.submit() br.submit()
return br return br
keep_only_tags = [ dict(name='div', attrs={'id':'LegacyContent'}) ] keep_only_tags = [ dict(name='div', attrs={'id':'content-block'}) ]
feeds = [(u"Science: Current Issue", u'http://www.sciencemag.org/rss/current.xml')] feeds = [(u"Science: Current Issue", u'http://www.sciencemag.org/rss/current.xml')]

View File

@ -40,7 +40,7 @@ class Sciencenews(BasicNewsRecipe):
,dict(name='div', attrs={'class': 'embiggen'}) ,dict(name='div', attrs={'class': 'embiggen'})
] ]
feeds = [(u"Science News / News Items", u'http://sciencenews.org/view/feed/type/news/name/news.rss')] feeds = [(u"Science News / News Items", u'http://sciencenews.org/index.php/feed/type/news/name/news.rss/view/feed/name/all.rss')]
def get_cover_url(self): def get_cover_url(self):
cover_url = None cover_url = None

37
recipes/skai.recipe Normal file
View File

@ -0,0 +1,37 @@
from calibre.web.feeds.recipes import BasicNewsRecipe
class SKAI(BasicNewsRecipe):
title = 'SKAI'
__author__ = 'Stelios'
description = 'News from Greece'
oldest_article = 2
max_articles_per_feed = 100
publisher = 'skai.gr'
category = 'news, GR'
language = 'el'
encoding = 'utf8'
no_stylesheets = True
use_embedded_content = False
remove_empty_feeds = True
encoding = 'utf8'
keep_only_tags = [
dict(name='h1'),
dict(name='div', attrs={'class' : ['articleText']})
]
feeds = [
(u'\u039A\u03C5\u03C1\u03B9\u03CC\u03C4\u03B5\u03C1\u03B5\u03C2 \u0395\u03B9\u03B4\u03AE\u03C3\u03B5\u03B9\u03C2', 'http://feeds.feedburner.com/skai/Uulu'),
(u'\u0395\u03BB\u03BB\u03AC\u03B4\u03B1', 'http://feeds.feedburner.com/skai/PLwa'),
(u'\u039A\u03CC\u03C3\u03BC\u03BF\u03C2', 'http://feeds.feedburner.com/skai/aqOL'),
(u'\u03A0\u03BF\u03BB\u03B9\u03C4\u03B9\u03BA\u03AE','http://feeds.feedburner.com/skai/yinm'),
(u'\u039F\u03B9\u03BA\u03BF\u03BD\u03BF\u03BC\u03AF\u03B1', 'http://feeds.feedburner.com/skai/oPUt'),
(u'\u03A4\u03B5\u03C7\u03BD\u03BF\u03BB\u03BF\u03B3\u03AF\u03B1', 'http://feeds.feedburner.com/skai/fqsg'),
(u'\u0391\u03B8\u03BB\u03B7\u03C4\u03B9\u03C3\u03BC\u03CC\u03C2', 'http://feeds.feedburner.com/skai/TfmK'),
(u'\u03A5\u03B3\u03B5\u03AF\u03B1', 'http://feeds.feedburner.com/skai/TABn'),
(u'\u03A0\u03BF\u03BB\u03B9\u03C4\u03B9\u03C3\u03BC\u03CC\u03C2', 'http://feeds.feedburner.com/skai/ppGl'),
(u'\u0391\u03C5\u03C4\u03BF\u03BA\u03AF\u03BD\u03B7\u03C3\u03B7', 'http://feeds.feedburner.com/skai/HCCc'),
(u'\u03A0\u03B5\u03C1\u03B9\u03B2\u03AC\u03BB\u03BB\u03BF\u03BD', 'http://feeds.feedburner.com/skai/jVWs'),
(u'\u03A0\u03B1\u03C1\u03AC\u03BE\u03B5\u03BD\u03B1', 'http://feeds.feedburner.com/skai/bpAR')
]

39
recipes/tovima.recipe Normal file
View File

@ -0,0 +1,39 @@
from calibre.web.feeds.recipes import BasicNewsRecipe
class Tovima(BasicNewsRecipe):
title = 'To Vima'
__author__ = 'Stelios'
description = ' News from Greece'
#max_articles_per_feed = 100
oldest_article = 3
publisher = 'To Vima'
category = 'news, GR'
language = 'el'
encoding = 'utf8'
cover_url = 'http://www.tovima.gr/Themes/1/Default/Media/Home//small-n-short-logo.jpg'
no_stylesheets = True
use_embedded_content = False
remove_empty_feeds = True
extra_css = '''
.article_title{font-family :Arial,Helvetica,sans-serif; font-weight: bold; font-size:large;}
.article_text{font-family :Arial,Helvetica,sans-serif; font-size:x-small;}
'''
keep_only_tags = [
dict(name='div', attrs={'class' : ['article_title']}),
dict(name='div', attrs={'class' : ['article_text']})
]
remove_tags = [
dict(name='div', attrs={'class' : ['article_cat']})
]
feeds = [
(u'\u03C0\u03BF\u03BB\u03B9\u03C4\u03B9\u03BA\u03AE', 'http://www.tovima.gr/feed/politics/'),
(u'\u03BF\u03B9\u03BA\u03BF\u03BD\u03BF\u03BC\u03AF\u03B1', 'http://www.tovima.gr/feed/finance/'),
(u'\u03B3\u03BD\u03CE\u03BC\u03B5\u03C2', 'http://www.tovima.gr/feed/opinions/'),
(u'blogs', 'http://www.tovima.gr/feed/blogs/'),
(u'\u03BA\u03CC\u03C3\u03BC\u03BF\u03C2','http://www.tovima.gr/feed/world/'),
(u'science', 'http://www.tovima.gr/feed/science/'),
(u'\u03BA\u03BF\u03B9\u03BD\u03C9\u03BD\u03AF\u03B1', 'http://www.tovima.gr/feed/society/'),
(u'\u03C0\u03BF\u03BB\u03B9\u03C4\u03B9\u03C3\u03BC\u03CC\u03C2', 'http://www.tovima.gr/feed/culture/'),
(u'\u03B1\u03B8\u03BB\u03B7\u03C4\u03B9\u03C3\u03BC\u03CC\u03C2', 'http://www.tovima.gr/feed/sports/')
]

View File

@ -4,7 +4,7 @@ __license__ = 'GPL v3'
__copyright__ = '2008, Kovid Goyal kovid@kovidgoyal.net' __copyright__ = '2008, Kovid Goyal kovid@kovidgoyal.net'
__docformat__ = 'restructuredtext en' __docformat__ = 'restructuredtext en'
__appname__ = u'calibre' __appname__ = u'calibre'
numeric_version = (0, 8, 23) numeric_version = (0, 8, 24)
__version__ = u'.'.join(map(unicode, numeric_version)) __version__ = u'.'.join(map(unicode, numeric_version))
__author__ = u"Kovid Goyal <kovid@kovidgoyal.net>" __author__ = u"Kovid Goyal <kovid@kovidgoyal.net>"

View File

@ -1465,7 +1465,7 @@ class StoreVirtualoStore(StoreBase):
actual_plugin = 'calibre.gui2.store.stores.virtualo_plugin:VirtualoStore' actual_plugin = 'calibre.gui2.store.stores.virtualo_plugin:VirtualoStore'
headquarters = 'PL' headquarters = 'PL'
formats = ['EPUB', 'PDF'] formats = ['EPUB', 'MOBI', 'PDF']
class StoreWaterstonesUKStore(StoreBase): class StoreWaterstonesUKStore(StoreBase):
name = 'Waterstones UK' name = 'Waterstones UK'

View File

@ -36,7 +36,8 @@ class ANDROID(USBMS):
0xca2 : [0x100, 0x0227, 0x0226, 0x222], 0xca2 : [0x100, 0x0227, 0x0226, 0x222],
0xca3 : [0x100, 0x0227, 0x0226, 0x222], 0xca3 : [0x100, 0x0227, 0x0226, 0x222],
0xca4 : [0x100, 0x0227, 0x0226, 0x222], 0xca4 : [0x100, 0x0227, 0x0226, 0x222],
0xca9 : [0x100, 0x0227, 0x0226, 0x222] 0xca9 : [0x100, 0x0227, 0x0226, 0x222],
0xcac : [0x100, 0x0227, 0x0226, 0x222],
}, },
# Eken # Eken
@ -138,8 +139,12 @@ class ANDROID(USBMS):
# Advent # Advent
0x0955 : { 0x7100 : [0x9999] }, # This is the same as the Notion Ink Adam 0x0955 : { 0x7100 : [0x9999] }, # This is the same as the Notion Ink Adam
# Kobo
0x2237: { 0x2208 : [0x0226] },
} }
EBOOK_DIR_MAIN = ['eBooks/import', 'wordplayer/calibretransfer', 'Books'] EBOOK_DIR_MAIN = ['eBooks/import', 'wordplayer/calibretransfer', 'Books',
'sdcard/ebooks']
EXTRA_CUSTOMIZATION_MESSAGE = _('Comma separated list of directories to ' EXTRA_CUSTOMIZATION_MESSAGE = _('Comma separated list of directories to '
'send e-books to on the device. The first one that exists will ' 'send e-books to on the device. The first one that exists will '
'be used') 'be used')
@ -149,7 +154,7 @@ class ANDROID(USBMS):
'GT-I5700', 'SAMSUNG', 'DELL', 'LINUX', 'GOOGLE', 'ARCHOS', 'GT-I5700', 'SAMSUNG', 'DELL', 'LINUX', 'GOOGLE', 'ARCHOS',
'TELECHIP', 'HUAWEI', 'T-MOBILE', 'SEMC', 'LGE', 'NVIDIA', 'TELECHIP', 'HUAWEI', 'T-MOBILE', 'SEMC', 'LGE', 'NVIDIA',
'GENERIC-', 'ZTE', 'MID', 'QUALCOMM', 'PANDIGIT', 'HYSTON', 'GENERIC-', 'ZTE', 'MID', 'QUALCOMM', 'PANDIGIT', 'HYSTON',
'VIZIO', 'GOOGLE', 'FREESCAL'] 'VIZIO', 'GOOGLE', 'FREESCAL', 'KOBO_INC']
WINDOWS_MAIN_MEM = ['ANDROID_PHONE', 'A855', 'A853', 'INC.NEXUS_ONE', WINDOWS_MAIN_MEM = ['ANDROID_PHONE', 'A855', 'A853', 'INC.NEXUS_ONE',
'__UMS_COMPOSITE', '_MB200', 'MASS_STORAGE', '_-_CARD', 'SGH-I897', '__UMS_COMPOSITE', '_MB200', 'MASS_STORAGE', '_-_CARD', 'SGH-I897',
'GT-I9000', 'FILE-STOR_GADGET', 'SGH-T959', 'SAMSUNG_ANDROID', 'GT-I9000', 'FILE-STOR_GADGET', 'SGH-T959', 'SAMSUNG_ANDROID',
@ -160,7 +165,8 @@ class ANDROID(USBMS):
'MB860', 'MULTI-CARD', 'MID7015A', 'INCREDIBLE', 'A7EB', 'STREAK', 'MB860', 'MULTI-CARD', 'MID7015A', 'INCREDIBLE', 'A7EB', 'STREAK',
'MB525', 'ANDROID2.3', 'SGH-I997', 'GT-I5800_CARD', 'MB612', 'MB525', 'ANDROID2.3', 'SGH-I997', 'GT-I5800_CARD', 'MB612',
'GT-S5830_CARD', 'GT-S5570_CARD', 'MB870', 'MID7015A', 'GT-S5830_CARD', 'GT-S5570_CARD', 'MB870', 'MID7015A',
'ALPANDIGITAL', 'ANDROID_MID', 'VTAB1008', 'EMX51_BBG_ANDROI'] 'ALPANDIGITAL', 'ANDROID_MID', 'VTAB1008', 'EMX51_BBG_ANDROI',
'UMS', '.K080']
WINDOWS_CARD_A_MEM = ['ANDROID_PHONE', 'GT-I9000_CARD', 'SGH-I897', WINDOWS_CARD_A_MEM = ['ANDROID_PHONE', 'GT-I9000_CARD', 'SGH-I897',
'FILE-STOR_GADGET', 'SGH-T959', 'SAMSUNG_ANDROID', 'GT-P1000_CARD', 'FILE-STOR_GADGET', 'SGH-T959', 'SAMSUNG_ANDROID', 'GT-P1000_CARD',
'A70S', 'A101IT', '7', 'INCREDIBLE', 'A7EB', 'SGH-T849_CARD', 'A70S', 'A101IT', '7', 'INCREDIBLE', 'A7EB', 'SGH-T849_CARD',

View File

@ -61,18 +61,25 @@ class KOBO(USBMS):
' ebook file itself. With this option, calibre will send a ' ' ebook file itself. With this option, calibre will send a '
'separate cover image to the reader, useful if you ' 'separate cover image to the reader, useful if you '
'have modified the cover.'), 'have modified the cover.'),
_('Upload Black and White Covers') _('Upload Black and White Covers'),
_('Show expired books') +
':::'+_('A bug in an earlier version left non kepubs book records'
' in the datbase. With this option Calibre will show the '
'expired records and allow you to delete them with '
'the new delete logic.'),
] ]
EXTRA_CUSTOMIZATION_DEFAULT = [ EXTRA_CUSTOMIZATION_DEFAULT = [
', '.join(['tags']), ', '.join(['tags']),
True, True,
True,
True True
] ]
OPT_COLLECTIONS = 0 OPT_COLLECTIONS = 0
OPT_UPLOAD_COVERS = 1 OPT_UPLOAD_COVERS = 1
OPT_UPLOAD_GRAYSCALE_COVERS = 2 OPT_UPLOAD_GRAYSCALE_COVERS = 2
OPT_SHOW_EXPIRED_BOOK_RECORDS = 3
def initialize(self): def initialize(self):
USBMS.initialize(self) USBMS.initialize(self)
@ -232,18 +239,23 @@ class KOBO(USBMS):
self.dbversion = result[0] self.dbversion = result[0]
debug_print("Database Version: ", self.dbversion) debug_print("Database Version: ", self.dbversion)
opts = self.settings()
if self.dbversion >= 16: if self.dbversion >= 16:
query= 'select Title, Attribution, DateCreated, ContentID, MimeType, ContentType, ' \ query= ('select Title, Attribution, DateCreated, ContentID, MimeType, ContentType, ' \
'ImageID, ReadStatus, ___ExpirationStatus, FavouritesIndex, Accessibility from content where ' \ 'ImageID, ReadStatus, ___ExpirationStatus, FavouritesIndex, Accessibility from content where ' \
'BookID is Null and ( ___ExpirationStatus <> "3" or ___ExpirationStatus is Null)' 'BookID is Null and not ((___ExpirationStatus=3 or ___ExpirationStatus is Null) %(expiry)s') % dict(expiry=' and ContentType = 6)' \
if opts.extra_customization[self.OPT_SHOW_EXPIRED_BOOK_RECORDS] else ')')
elif self.dbversion < 16 and self.dbversion >= 14: elif self.dbversion < 16 and self.dbversion >= 14:
query= 'select Title, Attribution, DateCreated, ContentID, MimeType, ContentType, ' \ query= ('select Title, Attribution, DateCreated, ContentID, MimeType, ContentType, ' \
'ImageID, ReadStatus, ___ExpirationStatus, FavouritesIndex, "-1" as Accessibility from content where ' \ 'ImageID, ReadStatus, ___ExpirationStatus, FavouritesIndex, "-1" as Accessibility from content where ' \
'BookID is Null and ( ___ExpirationStatus <> "3" or ___ExpirationStatus is Null)' 'BookID is Null and not ((___ExpirationStatus=3 or ___ExpirationStatus is Null) %(expiry)s') % dict(expiry=' and ContentType = 6)' \
if opts.extra_customization[self.OPT_SHOW_EXPIRED_BOOK_RECORDS] else ')')
elif self.dbversion < 14 and self.dbversion >= 8: elif self.dbversion < 14 and self.dbversion >= 8:
query= 'select Title, Attribution, DateCreated, ContentID, MimeType, ContentType, ' \ query= ('select Title, Attribution, DateCreated, ContentID, MimeType, ContentType, ' \
'ImageID, ReadStatus, ___ExpirationStatus, "-1" as FavouritesIndex, "-1" as Accessibility from content where ' \ 'ImageID, ReadStatus, ___ExpirationStatus, "-1" as FavouritesIndex, "-1" as Accessibility from content where ' \
'BookID is Null and ( ___ExpirationStatus <> "3" or ___ExpirationStatus is Null)' 'BookID is Null and not ((___ExpirationStatus=3 or ___ExpirationStatus is Null) %(expiry)s') % dict(expiry=' and ContentType = 6)' \
if opts.extra_customization[self.OPT_SHOW_EXPIRED_BOOK_RECORDS] else ')')
else: else:
query= 'select Title, Attribution, DateCreated, ContentID, MimeType, ContentType, ' \ query= 'select Title, Attribution, DateCreated, ContentID, MimeType, ContentType, ' \
'ImageID, ReadStatus, "-1" as ___ExpirationStatus, "-1" as FavouritesIndex, "-1" as Accessibility from content where BookID is Null' 'ImageID, ReadStatus, "-1" as ___ExpirationStatus, "-1" as FavouritesIndex, "-1" as Accessibility from content where BookID is Null'
@ -343,21 +355,23 @@ class KOBO(USBMS):
# Kobo does not delete the Book row (ie the row where the BookID is Null) # Kobo does not delete the Book row (ie the row where the BookID is Null)
# The next server sync should remove the row # The next server sync should remove the row
cursor.execute('delete from content where BookID = ?', t) cursor.execute('delete from content where BookID = ?', t)
try: if ContentType == 6:
cursor.execute('update content set ReadStatus=0, FirstTimeReading = \'true\', ___PercentRead=0, ___ExpirationStatus=3 ' \
'where BookID is Null and ContentID =?',t)
except Exception as e:
if 'no such column' not in str(e):
raise
try: try:
cursor.execute('update content set ReadStatus=0, FirstTimeReading = \'true\', ___PercentRead=0 ' \ cursor.execute('update content set ReadStatus=0, FirstTimeReading = \'true\', ___PercentRead=0, ___ExpirationStatus=3 ' \
'where BookID is Null and ContentID =?',t) 'where BookID is Null and ContentID =?',t)
except Exception as e: except Exception as e:
if 'no such column' not in str(e): if 'no such column' not in str(e):
raise raise
cursor.execute('update content set ReadStatus=0, FirstTimeReading = \'true\' ' \ try:
'where BookID is Null and ContentID =?',t) cursor.execute('update content set ReadStatus=0, FirstTimeReading = \'true\', ___PercentRead=0 ' \
'where BookID is Null and ContentID =?',t)
except Exception as e:
if 'no such column' not in str(e):
raise
cursor.execute('update content set ReadStatus=0, FirstTimeReading = \'true\' ' \
'where BookID is Null and ContentID =?',t)
else:
cursor.execute('delete from content where BookID is Null and ContentID =?',t)
connection.commit() connection.commit()

View File

@ -211,6 +211,15 @@ int main(int argc, char** argv)
} }
action = argv[1]; dev = argv[2]; mp = argv[3]; action = argv[1]; dev = argv[2]; mp = argv[3];
/* Ensure that PATH only contains system directories to prevent execution of
arbitrary executables as root */
if (setenv("PATH",
"/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin\0",
1) != 0) {
fprintf(stderr, "Failed to restrict PATH env var, aborting.\n");
exit(EXIT_FAILURE);
}
if (strncmp(action, "mount", 5) == 0) { if (strncmp(action, "mount", 5) == 0) {
status = do_mount(dev, mp); status = do_mount(dev, mp);
} else if (strncmp(action, "eject", 5) == 0) { } else if (strncmp(action, "eject", 5) == 0) {

View File

@ -224,7 +224,7 @@ class TREKSTOR(USBMS):
FORMATS = ['epub', 'txt', 'pdf'] FORMATS = ['epub', 'txt', 'pdf']
VENDOR_ID = [0x1e68] VENDOR_ID = [0x1e68]
PRODUCT_ID = [0x0041, 0x0042, PRODUCT_ID = [0x0041, 0x0042, 0x0052,
0x003e # This is for the EBOOK_PLAYER_5M https://bugs.launchpad.net/bugs/792091 0x003e # This is for the EBOOK_PLAYER_5M https://bugs.launchpad.net/bugs/792091
] ]
BCD = [0x0002] BCD = [0x0002]

View File

@ -112,8 +112,10 @@ class PRST1(USBMS):
def post_open_callback(self): def post_open_callback(self):
# Set the thumbnail width to the theoretical max if the user has asked # Set the thumbnail width to the theoretical max if the user has asked
# that we do not preserve aspect ratio # that we do not preserve aspect ratio
if not self.settings().extra_customization[self.OPT_PRESERVE_ASPECT_RATIO]: ec = self.settings().extra_customization
if not ec[self.OPT_PRESERVE_ASPECT_RATIO]:
self.THUMBNAIL_WIDTH = 108 self.THUMBNAIL_WIDTH = 108
self.WANTS_UPDATED_THUMBNAILS = ec[self.OPT_REFRESH_COVERS]
# Make sure the date offset is set to none, we'll calculate it in books. # Make sure the date offset is set to none, we'll calculate it in books.
self.device_offset = None self.device_offset = None
@ -558,14 +560,21 @@ class PRST1(USBMS):
cursor = connection.cursor() cursor = connection.cursor()
periodical_schema = \
"'http://xmlns.sony.net/e-book/prs/periodicals/1.0/newspaper/1.0'"
# Setting this to the SONY periodical schema apparently causes errors
# with some periodicals, therefore set it to null, since the special
# periodical navigation doesn't work anyway.
periodical_schema = 'null'
query = ''' query = '''
UPDATE books UPDATE books
SET conforms_to = 'http://xmlns.sony.net/e-book/prs/periodicals/1.0/newspaper/1.0', SET conforms_to = %s,
periodical_name = ?, periodical_name = ?,
description = ?, description = ?,
publication_date = ? publication_date = ?
WHERE _id = ? WHERE _id = ?
''' '''%periodical_schema
t = (name, None, pubdate, book.bookId,) t = (name, None, pubdate, book.bookId,)
cursor.execute(query, t) cursor.execute(query, t)

View File

@ -109,14 +109,16 @@ class HTMLFile(object):
try: try:
with open(self.path, 'rb') as f: with open(self.path, 'rb') as f:
src = f.read() src = f.read(4096)
self.is_binary = level > 0 and not bool(self.HTML_PAT.search(src))
if not self.is_binary:
src += f.read()
except IOError as err: except IOError as err:
msg = 'Could not read from file: %s with error: %s'%(self.path, as_unicode(err)) msg = 'Could not read from file: %s with error: %s'%(self.path, as_unicode(err))
if level == 0: if level == 0:
raise IOError(msg) raise IOError(msg)
raise IgnoreFile(msg, err.errno) raise IgnoreFile(msg, err.errno)
self.is_binary = level > 0 and not bool(self.HTML_PAT.search(src[:4096]))
if not self.is_binary: if not self.is_binary:
if not encoding: if not encoding:
encoding = xml_to_unicode(src[:4096], verbose=verbose)[-1] encoding = xml_to_unicode(src[:4096], verbose=verbose)[-1]

View File

@ -15,7 +15,6 @@ from calibre.customize.conversion import OutputFormatPlugin, \
OptionRecommendation OptionRecommendation
from calibre.ebooks.metadata.opf2 import OPF from calibre.ebooks.metadata.opf2 import OPF
from calibre.ptempfile import TemporaryDirectory from calibre.ptempfile import TemporaryDirectory
from calibre.ebooks.pdf.writer import PDFWriter, ImagePDFWriter, PDFMetadata
from calibre.ebooks.pdf.pageoptions import UNITS, PAPER_SIZES, \ from calibre.ebooks.pdf.pageoptions import UNITS, PAPER_SIZES, \
ORIENTATIONS ORIENTATIONS
@ -90,6 +89,7 @@ class PDFOutput(OutputFormatPlugin):
self.convert_text(oeb_book) self.convert_text(oeb_book)
def convert_images(self, images): def convert_images(self, images):
from calibre.ebooks.pdf.writer import ImagePDFWriter
self.write(ImagePDFWriter, images) self.write(ImagePDFWriter, images)
def get_cover_data(self): def get_cover_data(self):
@ -105,6 +105,7 @@ class PDFOutput(OutputFormatPlugin):
self.cover_data = None self.cover_data = None
def convert_text(self, oeb_book): def convert_text(self, oeb_book):
from calibre.ebooks.pdf.writer import PDFWriter
self.log.debug('Serializing oeb input to disk for processing...') self.log.debug('Serializing oeb input to disk for processing...')
self.get_cover_data() self.get_cover_data()
@ -119,6 +120,7 @@ class PDFOutput(OutputFormatPlugin):
self.write(PDFWriter, [s.path for s in opf.spine]) self.write(PDFWriter, [s.path for s in opf.spine])
def write(self, Writer, items): def write(self, Writer, items):
from calibre.ebooks.pdf.writer import PDFMetadata
writer = Writer(self.opts, self.log, cover_data=self.cover_data) writer = Writer(self.opts, self.log, cover_data=self.cover_data)
close = False close = False

View File

@ -587,7 +587,6 @@ class CoversModel(QAbstractListModel): # {{{
return 1 return 1
return pmap.width()*pmap.height() return pmap.width()*pmap.height()
def clear_failed(self): def clear_failed(self):
good = [] good = []
pmap = {} pmap = {}
@ -729,7 +728,8 @@ class CoversWidget(QWidget): # {{{
except Empty: except Empty:
break break
self.covers_view.clear_failed() if self.continue_processing:
self.covers_view.clear_failed()
if self.worker.error is not None: if self.worker.error is not None:
error_dialog(self, _('Download failed'), error_dialog(self, _('Download failed'),
@ -759,7 +759,7 @@ class CoversWidget(QWidget): # {{{
self.continue_processing = False self.continue_processing = False
def cancel(self): def cancel(self):
self.continue_processing = False self.cleanup()
self.abort.set() self.abort.set()
def cover_pixmap(self): def cover_pixmap(self):

View File

@ -34,10 +34,11 @@ class VirtualoStore(BasicStoreConfig, StorePlugin):
d.set_tags(self.config.get('tags', '')) d.set_tags(self.config.get('tags', ''))
d.exec_() d.exec_()
def search(self, query, max_results=10, timeout=60): def search(self, query, max_results=12, timeout=60):
url = 'http://virtualo.pl/c2/?q=' + urllib.quote(query) url = 'http://virtualo.pl/?q=' + urllib.quote(query) + '&f=format_id:4,6,3'
br = browser() br = browser()
drm_pattern = re.compile("ADE")
counter = max_results counter = max_results
with closing(br.open(url, timeout=timeout)) as f: with closing(br.open(url, timeout=timeout)) as f:
@ -46,26 +47,28 @@ class VirtualoStore(BasicStoreConfig, StorePlugin):
if counter <= 0: if counter <= 0:
break break
id = ''.join(data.xpath('.//table/tr[2]/td[1]/a/@href')) id = ''.join(data.xpath('.//table/tr[1]/td[1]/a/@href'))
if not id: if not id:
continue continue
price = ''.join(data.xpath('.//span[@class="price"]/text() | .//span[@class="price abbr"]/text()')) price = ''.join(data.xpath('.//span[@class="price"]/text() | .//span[@class="price abbr"]/text()'))
cover_url = ''.join(data.xpath('.//table/tr[2]/td[1]/a/img/@src')) cover_url = ''.join(data.xpath('.//table/tr[1]/td[1]/a/img/@src'))
title = ''.join(data.xpath('.//div[@class="title"]/a/text()')) title = ''.join(data.xpath('.//div[@class="title"]/a/text()'))
author = ', '.join(data.xpath('.//div[@class="authors"]/a/text()')) author = ', '.join(data.xpath('.//div[@class="authors"]/a/text()'))
formats = ', '.join(data.xpath('.//span[@class="format"]/a/text()')) formats = ', '.join(data.xpath('.//span[@class="format"]/a/text()'))
formats = re.sub(r'(, )?ONLINE(, )?', '', formats) formats = re.sub(r'(, )?ONLINE(, )?', '', formats)
drm = drm_pattern.search(formats)
formats = re.sub(r'(, )?ADE(, )?', '', formats)
counter -= 1 counter -= 1
s = SearchResult() s = SearchResult()
s.cover_url = cover_url s.cover_url = cover_url.split('.jpg')[0] + '.jpg'
s.title = title.strip() + ' ' + formats s.title = title.strip() + ' ' + formats
s.author = author.strip() s.author = author.strip()
s.price = price + '' s.price = price + ''
s.detail_item = 'http://virtualo.pl' + id.strip() s.detail_item = 'http://virtualo.pl' + id.strip().split('http://')[0]
s.formats = formats.upper().strip() s.formats = formats.upper().strip()
s.drm = SearchResult.DRM_UNKNOWN s.drm = SearchResult.DRM_LOCKED if drm else SearchResult.DRM_UNLOCKED
yield s yield s

View File

@ -14,7 +14,7 @@ from calibre.constants import iswindows
import cherrypy import cherrypy
def start_threaded_server(db, opts): def start_threaded_server(db, opts):
server = LibraryServer(db, opts, embedded=True) server = LibraryServer(db, opts, embedded=True, show_tracebacks=False)
server.thread = Thread(target=server.start) server.thread = Thread(target=server.start)
server.thread.setDaemon(True) server.thread.setDaemon(True)
server.thread.start() server.thread.start()
@ -112,7 +112,7 @@ def main(args=sys.argv):
if opts.with_library is None: if opts.with_library is None:
opts.with_library = prefs['library_path'] opts.with_library = prefs['library_path']
db = LibraryDatabase2(opts.with_library) db = LibraryDatabase2(opts.with_library)
server = LibraryServer(db, opts) server = LibraryServer(db, opts, show_tracebacks=opts.develop)
server.start() server.start()
return 0 return 0

View File

@ -243,7 +243,7 @@ Replace ``192.168.1.2`` with the local IP address of the computer running |app|.
If you get timeout errors while browsing the calibre catalog in Stanza, try increasing the connection timeout value in the stanza settings. Go to Info->Settings and increase the value of Download Timeout. If you get timeout errors while browsing the calibre catalog in Stanza, try increasing the connection timeout value in the stanza settings. Go to Info->Settings and increase the value of Download Timeout.
.. note:: .. note::
As of iOS version 5 Stanza no longer works on Apple devices. Alternatives to Stanza are discussed `here <http://www.mobileread.com/forums/showthread.php?t=152789>`_. As of iOS version 5 Stanza no longer works on Apple devices. Alternatives to Stanza are discussed `in this forum <http://www.mobileread.com/forums/showthread.php?t=152789>`_.
Using iBooks Using iBooks

View File

@ -258,6 +258,14 @@ The following functions are available in addition to those described in single-f
MMMM : the long localized month name (e.g. "January" to "December"). MMMM : the long localized month name (e.g. "January" to "December").
yy : the year as two digit number (00 to 99). yy : the year as two digit number (00 to 99).
yyyy : the year as four digit number. yyyy : the year as four digit number.
h : the hours without a leading 0 (0 to 11 or 0 to 23, depending on am/pm)
hh : the hours with a leading 0 (00 to 11 or 00 to 23, depending on am/pm)
m : the minutes without a leading 0 (0 to 59)
mm : the minutes with a leading 0 (00 to 59)
s : the seconds without a leading 0 (0 to 59)
ss : the seconds with a leading 0 (00 to 59)
ap : use a 12-hour clock instead of a 24-hour clock, with 'ap' replaced by the localized string for am or pm.
AP : use a 12-hour clock instead of a 24-hour clock, with 'AP' replaced by the localized string for AM or PM.
iso : the date with time and timezone. Must be the only format present. iso : the date with time and timezone. Must be the only format present.
* ``eval(string)`` -- evaluates the string as a program, passing the local variables (those ``assign`` ed to). This permits using the template processor to construct complex results from local variables. * ``eval(string)`` -- evaluates the string as a program, passing the local variables (those ``assign`` ed to). This permits using the template processor to construct complex results from local variables.

View File

@ -4,9 +4,9 @@
# #
msgid "" msgid ""
msgstr "" msgstr ""
"Project-Id-Version: calibre 0.8.23\n" "Project-Id-Version: calibre 0.8.24\n"
"POT-Creation-Date: 2011-10-20 22:00+IST\n" "POT-Creation-Date: 2011-10-27 14:45+IST\n"
"PO-Revision-Date: 2011-10-20 22:00+IST\n" "PO-Revision-Date: 2011-10-27 14:45+IST\n"
"Last-Translator: Automatically generated\n" "Last-Translator: Automatically generated\n"
"Language-Team: LANGUAGE\n" "Language-Team: LANGUAGE\n"
"MIME-Version: 1.0\n" "MIME-Version: 1.0\n"
@ -31,13 +31,13 @@ msgstr ""
#: /home/kovid/work/calibre/src/calibre/devices/jetbook/driver.py:74 #: /home/kovid/work/calibre/src/calibre/devices/jetbook/driver.py:74
#: /home/kovid/work/calibre/src/calibre/devices/kindle/driver.py:79 #: /home/kovid/work/calibre/src/calibre/devices/kindle/driver.py:79
#: /home/kovid/work/calibre/src/calibre/devices/kobo/books.py:24 #: /home/kovid/work/calibre/src/calibre/devices/kobo/books.py:24
#: /home/kovid/work/calibre/src/calibre/devices/kobo/driver.py:581 #: /home/kovid/work/calibre/src/calibre/devices/kobo/driver.py:579
#: /home/kovid/work/calibre/src/calibre/devices/nook/driver.py:70 #: /home/kovid/work/calibre/src/calibre/devices/nook/driver.py:70
#: /home/kovid/work/calibre/src/calibre/devices/nook/driver.py:71 #: /home/kovid/work/calibre/src/calibre/devices/nook/driver.py:71
#: /home/kovid/work/calibre/src/calibre/devices/prs500/books.py:267 #: /home/kovid/work/calibre/src/calibre/devices/prs500/books.py:267
#: /home/kovid/work/calibre/src/calibre/devices/prs505/sony_cache.py:660 #: /home/kovid/work/calibre/src/calibre/devices/prs505/sony_cache.py:660
#: /home/kovid/work/calibre/src/calibre/devices/prst1/driver.py:308
#: /home/kovid/work/calibre/src/calibre/devices/prst1/driver.py:309 #: /home/kovid/work/calibre/src/calibre/devices/prst1/driver.py:309
#: /home/kovid/work/calibre/src/calibre/devices/prst1/driver.py:310
#: /home/kovid/work/calibre/src/calibre/devices/usbms/driver.py:485 #: /home/kovid/work/calibre/src/calibre/devices/usbms/driver.py:485
#: /home/kovid/work/calibre/src/calibre/ebooks/chm/input.py:106 #: /home/kovid/work/calibre/src/calibre/ebooks/chm/input.py:106
#: /home/kovid/work/calibre/src/calibre/ebooks/chm/input.py:109 #: /home/kovid/work/calibre/src/calibre/ebooks/chm/input.py:109
@ -80,7 +80,7 @@ msgstr ""
#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/rtf.py:101 #: /home/kovid/work/calibre/src/calibre/ebooks/metadata/rtf.py:101
#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/snb.py:16 #: /home/kovid/work/calibre/src/calibre/ebooks/metadata/snb.py:16
#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/sources/base.py:49 #: /home/kovid/work/calibre/src/calibre/ebooks/metadata/sources/base.py:49
#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/sources/base.py:301 #: /home/kovid/work/calibre/src/calibre/ebooks/metadata/sources/base.py:302
#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/sources/covers.py:79 #: /home/kovid/work/calibre/src/calibre/ebooks/metadata/sources/covers.py:79
#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/sources/covers.py:81 #: /home/kovid/work/calibre/src/calibre/ebooks/metadata/sources/covers.py:81
#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/sources/douban.py:80 #: /home/kovid/work/calibre/src/calibre/ebooks/metadata/sources/douban.py:80
@ -101,8 +101,8 @@ msgstr ""
#: /home/kovid/work/calibre/src/calibre/ebooks/mobi/reader.py:1006 #: /home/kovid/work/calibre/src/calibre/ebooks/mobi/reader.py:1006
#: /home/kovid/work/calibre/src/calibre/ebooks/mobi/utils.py:299 #: /home/kovid/work/calibre/src/calibre/ebooks/mobi/utils.py:299
#: /home/kovid/work/calibre/src/calibre/ebooks/mobi/writer2/indexer.py:496 #: /home/kovid/work/calibre/src/calibre/ebooks/mobi/writer2/indexer.py:496
#: /home/kovid/work/calibre/src/calibre/ebooks/odt/input.py:138 #: /home/kovid/work/calibre/src/calibre/ebooks/odt/input.py:141
#: /home/kovid/work/calibre/src/calibre/ebooks/odt/input.py:140 #: /home/kovid/work/calibre/src/calibre/ebooks/odt/input.py:143
#: /home/kovid/work/calibre/src/calibre/ebooks/oeb/base.py:1002 #: /home/kovid/work/calibre/src/calibre/ebooks/oeb/base.py:1002
#: /home/kovid/work/calibre/src/calibre/ebooks/oeb/base.py:1007 #: /home/kovid/work/calibre/src/calibre/ebooks/oeb/base.py:1007
#: /home/kovid/work/calibre/src/calibre/ebooks/oeb/base.py:1079 #: /home/kovid/work/calibre/src/calibre/ebooks/oeb/base.py:1079
@ -142,7 +142,7 @@ msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/actions/edit_metadata.py:380 #: /home/kovid/work/calibre/src/calibre/gui2/actions/edit_metadata.py:380
#: /home/kovid/work/calibre/src/calibre/gui2/add.py:161 #: /home/kovid/work/calibre/src/calibre/gui2/add.py:161
#: /home/kovid/work/calibre/src/calibre/gui2/add.py:168 #: /home/kovid/work/calibre/src/calibre/gui2/add.py:168
#: /home/kovid/work/calibre/src/calibre/gui2/book_details.py:576 #: /home/kovid/work/calibre/src/calibre/gui2/book_details.py:579
#: /home/kovid/work/calibre/src/calibre/gui2/convert/__init__.py:42 #: /home/kovid/work/calibre/src/calibre/gui2/convert/__init__.py:42
#: /home/kovid/work/calibre/src/calibre/gui2/convert/metadata.py:122 #: /home/kovid/work/calibre/src/calibre/gui2/convert/metadata.py:122
#: /home/kovid/work/calibre/src/calibre/gui2/convert/metadata.py:151 #: /home/kovid/work/calibre/src/calibre/gui2/convert/metadata.py:151
@ -175,14 +175,14 @@ msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/viewer/main.py:200 #: /home/kovid/work/calibre/src/calibre/gui2/viewer/main.py:200
#: /home/kovid/work/calibre/src/calibre/library/cli.py:220 #: /home/kovid/work/calibre/src/calibre/library/cli.py:220
#: /home/kovid/work/calibre/src/calibre/library/database.py:914 #: /home/kovid/work/calibre/src/calibre/library/database.py:914
#: /home/kovid/work/calibre/src/calibre/library/database2.py:543 #: /home/kovid/work/calibre/src/calibre/library/database2.py:544
#: /home/kovid/work/calibre/src/calibre/library/database2.py:551 #: /home/kovid/work/calibre/src/calibre/library/database2.py:552
#: /home/kovid/work/calibre/src/calibre/library/database2.py:562 #: /home/kovid/work/calibre/src/calibre/library/database2.py:563
#: /home/kovid/work/calibre/src/calibre/library/database2.py:2039 #: /home/kovid/work/calibre/src/calibre/library/database2.py:2040
#: /home/kovid/work/calibre/src/calibre/library/database2.py:2191 #: /home/kovid/work/calibre/src/calibre/library/database2.py:2192
#: /home/kovid/work/calibre/src/calibre/library/database2.py:3246 #: /home/kovid/work/calibre/src/calibre/library/database2.py:3247
#: /home/kovid/work/calibre/src/calibre/library/database2.py:3248 #: /home/kovid/work/calibre/src/calibre/library/database2.py:3249
#: /home/kovid/work/calibre/src/calibre/library/database2.py:3381 #: /home/kovid/work/calibre/src/calibre/library/database2.py:3382
#: /home/kovid/work/calibre/src/calibre/library/server/content.py:227 #: /home/kovid/work/calibre/src/calibre/library/server/content.py:227
#: /home/kovid/work/calibre/src/calibre/library/server/content.py:228 #: /home/kovid/work/calibre/src/calibre/library/server/content.py:228
#: /home/kovid/work/calibre/src/calibre/library/server/mobile.py:243 #: /home/kovid/work/calibre/src/calibre/library/server/mobile.py:243
@ -449,7 +449,7 @@ msgid "Change the way calibre behaves"
msgstr "" msgstr ""
#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:919 #: /home/kovid/work/calibre/src/calibre/customize/builtins.py:919
#: /home/kovid/work/calibre/src/calibre/gui2/library/views.py:233 #: /home/kovid/work/calibre/src/calibre/gui2/library/views.py:252
msgid "Add your own columns" msgid "Add your own columns"
msgstr "" msgstr ""
@ -852,26 +852,26 @@ msgstr ""
#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/book/base.py:647 #: /home/kovid/work/calibre/src/calibre/ebooks/metadata/book/base.py:647
#: /home/kovid/work/calibre/src/calibre/gui2/custom_column_widgets.py:66 #: /home/kovid/work/calibre/src/calibre/gui2/custom_column_widgets.py:66
#: /home/kovid/work/calibre/src/calibre/gui2/custom_column_widgets.py:563 #: /home/kovid/work/calibre/src/calibre/gui2/custom_column_widgets.py:563
#: /home/kovid/work/calibre/src/calibre/library/database2.py:989 #: /home/kovid/work/calibre/src/calibre/library/database2.py:990
#: /home/kovid/work/calibre/src/calibre/utils/formatter_functions.py:820 #: /home/kovid/work/calibre/src/calibre/utils/formatter_functions.py:820
#: /home/kovid/work/calibre/src/calibre/utils/formatter_functions.py:832 #: /home/kovid/work/calibre/src/calibre/utils/formatter_functions.py:832
msgid "Yes" msgid "Yes"
msgstr "" msgstr ""
#: /home/kovid/work/calibre/src/calibre/db/fields.py:163 #: /home/kovid/work/calibre/src/calibre/db/fields.py:163
#: /home/kovid/work/calibre/src/calibre/library/database2.py:1103 #: /home/kovid/work/calibre/src/calibre/library/database2.py:1104
msgid "Main" msgid "Main"
msgstr "" msgstr ""
#: /home/kovid/work/calibre/src/calibre/db/fields.py:165 #: /home/kovid/work/calibre/src/calibre/db/fields.py:165
#: /home/kovid/work/calibre/src/calibre/gui2/layout.py:72 #: /home/kovid/work/calibre/src/calibre/gui2/layout.py:72
#: /home/kovid/work/calibre/src/calibre/library/database2.py:1105 #: /home/kovid/work/calibre/src/calibre/library/database2.py:1106
msgid "Card A" msgid "Card A"
msgstr "" msgstr ""
#: /home/kovid/work/calibre/src/calibre/db/fields.py:167 #: /home/kovid/work/calibre/src/calibre/db/fields.py:167
#: /home/kovid/work/calibre/src/calibre/gui2/layout.py:74 #: /home/kovid/work/calibre/src/calibre/gui2/layout.py:74
#: /home/kovid/work/calibre/src/calibre/library/database2.py:1107 #: /home/kovid/work/calibre/src/calibre/library/database2.py:1108
msgid "Card B" msgid "Card B"
msgstr "" msgstr ""
@ -987,8 +987,8 @@ msgstr ""
#: /home/kovid/work/calibre/src/calibre/devices/nook/driver.py:102 #: /home/kovid/work/calibre/src/calibre/devices/nook/driver.py:102
#: /home/kovid/work/calibre/src/calibre/devices/prs505/sony_cache.py:447 #: /home/kovid/work/calibre/src/calibre/devices/prs505/sony_cache.py:447
#: /home/kovid/work/calibre/src/calibre/devices/prs505/sony_cache.py:470 #: /home/kovid/work/calibre/src/calibre/devices/prs505/sony_cache.py:470
#: /home/kovid/work/calibre/src/calibre/devices/prst1/driver.py:526 #: /home/kovid/work/calibre/src/calibre/devices/prst1/driver.py:527
#: /home/kovid/work/calibre/src/calibre/devices/prst1/driver.py:545 #: /home/kovid/work/calibre/src/calibre/devices/prst1/driver.py:546
#: /home/kovid/work/calibre/src/calibre/devices/usbms/device.py:1084 #: /home/kovid/work/calibre/src/calibre/devices/usbms/device.py:1084
#: /home/kovid/work/calibre/src/calibre/devices/usbms/device.py:1090 #: /home/kovid/work/calibre/src/calibre/devices/usbms/device.py:1090
#: /home/kovid/work/calibre/src/calibre/devices/usbms/device.py:1125 #: /home/kovid/work/calibre/src/calibre/devices/usbms/device.py:1125
@ -996,9 +996,9 @@ msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/scheduler.py:453 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/scheduler.py:453
#: /home/kovid/work/calibre/src/calibre/gui2/tag_browser/model.py:1148 #: /home/kovid/work/calibre/src/calibre/gui2/tag_browser/model.py:1148
#: /home/kovid/work/calibre/src/calibre/gui2/tag_browser/model.py:1150 #: /home/kovid/work/calibre/src/calibre/gui2/tag_browser/model.py:1150
#: /home/kovid/work/calibre/src/calibre/library/database2.py:336 #: /home/kovid/work/calibre/src/calibre/library/database2.py:337
#: /home/kovid/work/calibre/src/calibre/library/database2.py:349 #: /home/kovid/work/calibre/src/calibre/library/database2.py:350
#: /home/kovid/work/calibre/src/calibre/library/database2.py:3107 #: /home/kovid/work/calibre/src/calibre/library/database2.py:3108
#: /home/kovid/work/calibre/src/calibre/library/field_metadata.py:187 #: /home/kovid/work/calibre/src/calibre/library/field_metadata.py:187
msgid "News" msgid "News"
msgstr "" msgstr ""
@ -1006,8 +1006,8 @@ msgstr ""
#: /home/kovid/work/calibre/src/calibre/devices/apple/driver.py:2685 #: /home/kovid/work/calibre/src/calibre/devices/apple/driver.py:2685
#: /home/kovid/work/calibre/src/calibre/gui2/catalog/catalog_epub_mobi.py:65 #: /home/kovid/work/calibre/src/calibre/gui2/catalog/catalog_epub_mobi.py:65
#: /home/kovid/work/calibre/src/calibre/library/catalog.py:662 #: /home/kovid/work/calibre/src/calibre/library/catalog.py:662
#: /home/kovid/work/calibre/src/calibre/library/database2.py:3066 #: /home/kovid/work/calibre/src/calibre/library/database2.py:3067
#: /home/kovid/work/calibre/src/calibre/library/database2.py:3084 #: /home/kovid/work/calibre/src/calibre/library/database2.py:3085
msgid "Catalog" msgid "Catalog"
msgstr "" msgstr ""
@ -1047,11 +1047,11 @@ msgstr ""
#: /home/kovid/work/calibre/src/calibre/devices/bambook/driver.py:218 #: /home/kovid/work/calibre/src/calibre/devices/bambook/driver.py:218
#: /home/kovid/work/calibre/src/calibre/devices/bambook/driver.py:234 #: /home/kovid/work/calibre/src/calibre/devices/bambook/driver.py:234
#: /home/kovid/work/calibre/src/calibre/devices/kobo/driver.py:88
#: /home/kovid/work/calibre/src/calibre/devices/kobo/driver.py:91 #: /home/kovid/work/calibre/src/calibre/devices/kobo/driver.py:91
#: /home/kovid/work/calibre/src/calibre/devices/kobo/driver.py:94 #: /home/kovid/work/calibre/src/calibre/devices/kobo/driver.py:94
#: /home/kovid/work/calibre/src/calibre/devices/kobo/driver.py:97 #: /home/kovid/work/calibre/src/calibre/devices/kobo/driver.py:303
#: /home/kovid/work/calibre/src/calibre/devices/kobo/driver.py:305 #: /home/kovid/work/calibre/src/calibre/devices/prst1/driver.py:151
#: /home/kovid/work/calibre/src/calibre/devices/prst1/driver.py:150
#: /home/kovid/work/calibre/src/calibre/devices/usbms/driver.py:140 #: /home/kovid/work/calibre/src/calibre/devices/usbms/driver.py:140
#: /home/kovid/work/calibre/src/calibre/devices/usbms/driver.py:143 #: /home/kovid/work/calibre/src/calibre/devices/usbms/driver.py:143
#: /home/kovid/work/calibre/src/calibre/devices/usbms/driver.py:146 #: /home/kovid/work/calibre/src/calibre/devices/usbms/driver.py:146
@ -1071,8 +1071,8 @@ msgstr ""
#: /home/kovid/work/calibre/src/calibre/devices/bambook/driver.py:330 #: /home/kovid/work/calibre/src/calibre/devices/bambook/driver.py:330
#: /home/kovid/work/calibre/src/calibre/devices/bambook/driver.py:344 #: /home/kovid/work/calibre/src/calibre/devices/bambook/driver.py:344
#: /home/kovid/work/calibre/src/calibre/devices/kobo/driver.py:439 #: /home/kovid/work/calibre/src/calibre/devices/kobo/driver.py:437
#: /home/kovid/work/calibre/src/calibre/devices/kobo/driver.py:474 #: /home/kovid/work/calibre/src/calibre/devices/kobo/driver.py:472
#: /home/kovid/work/calibre/src/calibre/devices/usbms/driver.py:297 #: /home/kovid/work/calibre/src/calibre/devices/usbms/driver.py:297
#: /home/kovid/work/calibre/src/calibre/devices/usbms/driver.py:328 #: /home/kovid/work/calibre/src/calibre/devices/usbms/driver.py:328
msgid "Adding books to device metadata listing..." msgid "Adding books to device metadata listing..."
@ -1082,8 +1082,8 @@ msgstr ""
#: /home/kovid/work/calibre/src/calibre/devices/bambook/driver.py:354 #: /home/kovid/work/calibre/src/calibre/devices/bambook/driver.py:354
#: /home/kovid/work/calibre/src/calibre/devices/hanvon/driver.py:114 #: /home/kovid/work/calibre/src/calibre/devices/hanvon/driver.py:114
#: /home/kovid/work/calibre/src/calibre/devices/hanvon/driver.py:125 #: /home/kovid/work/calibre/src/calibre/devices/hanvon/driver.py:125
#: /home/kovid/work/calibre/src/calibre/devices/kobo/driver.py:391 #: /home/kovid/work/calibre/src/calibre/devices/kobo/driver.py:389
#: /home/kovid/work/calibre/src/calibre/devices/kobo/driver.py:423 #: /home/kovid/work/calibre/src/calibre/devices/kobo/driver.py:421
#: /home/kovid/work/calibre/src/calibre/devices/usbms/driver.py:334 #: /home/kovid/work/calibre/src/calibre/devices/usbms/driver.py:334
#: /home/kovid/work/calibre/src/calibre/devices/usbms/driver.py:352 #: /home/kovid/work/calibre/src/calibre/devices/usbms/driver.py:352
msgid "Removing books from device..." msgid "Removing books from device..."
@ -1091,8 +1091,8 @@ msgstr ""
#: /home/kovid/work/calibre/src/calibre/devices/bambook/driver.py:369 #: /home/kovid/work/calibre/src/calibre/devices/bambook/driver.py:369
#: /home/kovid/work/calibre/src/calibre/devices/bambook/driver.py:374 #: /home/kovid/work/calibre/src/calibre/devices/bambook/driver.py:374
#: /home/kovid/work/calibre/src/calibre/devices/kobo/driver.py:427 #: /home/kovid/work/calibre/src/calibre/devices/kobo/driver.py:425
#: /home/kovid/work/calibre/src/calibre/devices/kobo/driver.py:434 #: /home/kovid/work/calibre/src/calibre/devices/kobo/driver.py:432
#: /home/kovid/work/calibre/src/calibre/devices/usbms/driver.py:359 #: /home/kovid/work/calibre/src/calibre/devices/usbms/driver.py:359
#: /home/kovid/work/calibre/src/calibre/devices/usbms/driver.py:364 #: /home/kovid/work/calibre/src/calibre/devices/usbms/driver.py:364
msgid "Removing books from device metadata listing..." msgid "Removing books from device metadata listing..."
@ -1328,39 +1328,61 @@ msgstr ""
msgid "Communicate with the Kindle DX eBook reader." msgid "Communicate with the Kindle DX eBook reader."
msgstr "" msgstr ""
#: /home/kovid/work/calibre/src/calibre/devices/kobo/driver.py:25 #: /home/kovid/work/calibre/src/calibre/devices/kobo/driver.py:26
msgid "Communicate with the Kobo Reader" msgid "Communicate with the Kobo Reader"
msgstr "" msgstr ""
#: /home/kovid/work/calibre/src/calibre/devices/kobo/driver.py:54 #: /home/kovid/work/calibre/src/calibre/devices/kobo/driver.py:56
msgid "The Kobo supports several collections including " msgid "The Kobo supports several collections including "
msgstr "" msgstr ""
#: /home/kovid/work/calibre/src/calibre/devices/kobo/driver.py:56 #: /home/kovid/work/calibre/src/calibre/devices/kobo/driver.py:58
msgid "Create tags for automatic management" msgid "Create tags for automatic management"
msgstr "" msgstr ""
#: /home/kovid/work/calibre/src/calibre/devices/kobo/driver.py:57 #: /home/kovid/work/calibre/src/calibre/devices/kobo/driver.py:59
msgid "Upload covers for books (newer readers)" msgid "Upload covers for books (newer readers)"
msgstr "" msgstr ""
#: /home/kovid/work/calibre/src/calibre/devices/kobo/driver.py:58 #: /home/kovid/work/calibre/src/calibre/devices/kobo/driver.py:60
msgid "Normally, the KOBO readers get the cover image from the ebook file itself. With this option, calibre will send a separate cover image to the reader, useful if you have modified the cover." msgid "Normally, the KOBO readers get the cover image from the ebook file itself. With this option, calibre will send a separate cover image to the reader, useful if you have modified the cover."
msgstr "" msgstr ""
#: /home/kovid/work/calibre/src/calibre/devices/kobo/driver.py:62 #: /home/kovid/work/calibre/src/calibre/devices/kobo/driver.py:64
msgid "Upload Black and White Covers" msgid "Upload Black and White Covers"
msgstr "" msgstr ""
#: /home/kovid/work/calibre/src/calibre/devices/kobo/driver.py:561 #: /home/kovid/work/calibre/src/calibre/devices/kobo/driver.py:559
#: /home/kovid/work/calibre/src/calibre/gui2/actions/add.py:390 #: /home/kovid/work/calibre/src/calibre/gui2/actions/add.py:390
msgid "Not Implemented" msgid "Not Implemented"
msgstr "" msgstr ""
#: /home/kovid/work/calibre/src/calibre/devices/kobo/driver.py:562 #: /home/kovid/work/calibre/src/calibre/devices/kobo/driver.py:560
msgid "\".kobo\" files do not exist on the device as books instead, they are rows in the sqlite database. Currently they cannot be exported or viewed." msgid "\".kobo\" files do not exist on the device as books instead, they are rows in the sqlite database. Currently they cannot be exported or viewed."
msgstr "" msgstr ""
#: /home/kovid/work/calibre/src/calibre/devices/kobo/driver.py:989
#: /home/kovid/work/calibre/src/calibre/devices/kobo/driver.py:995
#, python-format
msgid "<hr /><b>Book Last Read:</b> %(time)s<br /><b>Percentage Read:</b> %(pr)d%%<hr />"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/devices/kobo/driver.py:1013
#, python-format
msgid "<b>Chapter %(chapter)d:</b> %(chapter_title)s<br /><b>%(typ)s</b><br /><b>Chapter Progress:</b> %(chapter_progress)s%%<br />%(annotation)s<br /><hr />"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/devices/kobo/driver.py:1022
#, python-format
msgid "<b>Chapter %(chapter)d:</b> %(chapter_title)s<br /><b>%(typ)s</b><br /><b>Chapter Progress:</b> %(chapter_progress)s%%<br /><b>Highlight:</b> %(text)s<br /><hr />"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/devices/kobo/driver.py:1031
#: /home/kovid/work/calibre/src/calibre/devices/kobo/driver.py:1041
#, python-format
msgid "<b>Chapter %(chapter)d:</b> %(chapter_title)s<br /><b>%(typ)s</b><br /><b>Chapter Progress:</b> %(chapter_progress)s%%<br /><b>Highlight:</b> %(text)s<br /><b>Notes:</b> %(annotation)s<br /><hr />"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/devices/misc.py:19 #: /home/kovid/work/calibre/src/calibre/devices/misc.py:19
msgid "Communicate with the Palm Pre" msgid "Communicate with the Palm Pre"
msgstr "" msgstr ""
@ -1471,7 +1493,7 @@ msgid "All by author"
msgstr "" msgstr ""
#: /home/kovid/work/calibre/src/calibre/devices/prs505/driver.py:70 #: /home/kovid/work/calibre/src/calibre/devices/prs505/driver.py:70
#: /home/kovid/work/calibre/src/calibre/devices/prst1/driver.py:67 #: /home/kovid/work/calibre/src/calibre/devices/prst1/driver.py:68
msgid "Comma separated list of metadata fields to turn into collections on the device. Possibilities include: " msgid "Comma separated list of metadata fields to turn into collections on the device. Possibilities include: "
msgstr "" msgstr ""
@ -1493,17 +1515,17 @@ msgid "Refresh separate covers when using automatic management (newer readers)"
msgstr "" msgstr ""
#: /home/kovid/work/calibre/src/calibre/devices/prs505/driver.py:86 #: /home/kovid/work/calibre/src/calibre/devices/prs505/driver.py:86
#: /home/kovid/work/calibre/src/calibre/devices/prst1/driver.py:77 #: /home/kovid/work/calibre/src/calibre/devices/prst1/driver.py:78
msgid "Set this option to have separate book covers uploaded every time you connect your device. Unset this option if you have so many books on the reader that performance is unacceptable." msgid "Set this option to have separate book covers uploaded every time you connect your device. Unset this option if you have so many books on the reader that performance is unacceptable."
msgstr "" msgstr ""
#: /home/kovid/work/calibre/src/calibre/devices/prs505/driver.py:90 #: /home/kovid/work/calibre/src/calibre/devices/prs505/driver.py:90
#: /home/kovid/work/calibre/src/calibre/devices/prst1/driver.py:81 #: /home/kovid/work/calibre/src/calibre/devices/prst1/driver.py:82
msgid "Preserve cover aspect ratio when building thumbnails" msgid "Preserve cover aspect ratio when building thumbnails"
msgstr "" msgstr ""
#: /home/kovid/work/calibre/src/calibre/devices/prs505/driver.py:92 #: /home/kovid/work/calibre/src/calibre/devices/prs505/driver.py:92
#: /home/kovid/work/calibre/src/calibre/devices/prst1/driver.py:83 #: /home/kovid/work/calibre/src/calibre/devices/prst1/driver.py:84
msgid "Set this option if you want the cover thumbnails to have the same aspect ratio (width to height) as the cover. Unset it if you want the thumbnail to be the maximum size, ignoring aspect ratio." msgid "Set this option if you want the cover thumbnails to have the same aspect ratio (width to height) as the cover. Unset it if you want the thumbnail to be the maximum size, ignoring aspect ratio."
msgstr "" msgstr ""
@ -1524,23 +1546,23 @@ msgstr ""
msgid "Communicate with the PRST1 and newer SONY eBook readers" msgid "Communicate with the PRST1 and newer SONY eBook readers"
msgstr "" msgstr ""
#: /home/kovid/work/calibre/src/calibre/devices/prst1/driver.py:70 #: /home/kovid/work/calibre/src/calibre/devices/prst1/driver.py:71
msgid "Upload separate cover thumbnails for books" msgid "Upload separate cover thumbnails for books"
msgstr "" msgstr ""
#: /home/kovid/work/calibre/src/calibre/devices/prst1/driver.py:71 #: /home/kovid/work/calibre/src/calibre/devices/prst1/driver.py:72
msgid "Normally, the SONY readers get the cover image from the ebook file itself. With this option, calibre will send a separate cover image to the reader, useful if you are sending DRMed books in which you cannot change the cover." msgid "Normally, the SONY readers get the cover image from the ebook file itself. With this option, calibre will send a separate cover image to the reader, useful if you are sending DRMed books in which you cannot change the cover."
msgstr "" msgstr ""
#: /home/kovid/work/calibre/src/calibre/devices/prst1/driver.py:75 #: /home/kovid/work/calibre/src/calibre/devices/prst1/driver.py:76
msgid "Refresh separate covers when using automatic management" msgid "Refresh separate covers when using automatic management"
msgstr "" msgstr ""
#: /home/kovid/work/calibre/src/calibre/devices/prst1/driver.py:87 #: /home/kovid/work/calibre/src/calibre/devices/prst1/driver.py:88
msgid "Use SONY Author Format (First Author Only)" msgid "Use SONY Author Format (First Author Only)"
msgstr "" msgstr ""
#: /home/kovid/work/calibre/src/calibre/devices/prst1/driver.py:89 #: /home/kovid/work/calibre/src/calibre/devices/prst1/driver.py:90
msgid "Set this option if you want the author on the Sony to appear the same way the T1 sets it. This means it will only show the first author for books with multiple authors. Leave this disabled if you use Metadata Plugboards." msgid "Set this option if you want the author on the Sony to appear the same way the T1 sets it. This means it will only show the first author for books with multiple authors. Leave this disabled if you use Metadata Plugboards."
msgstr "" msgstr ""
@ -3100,7 +3122,7 @@ msgstr ""
msgid "Main Text" msgid "Main Text"
msgstr "" msgstr ""
#: /home/kovid/work/calibre/src/calibre/ebooks/oeb/iterator.py:41 #: /home/kovid/work/calibre/src/calibre/ebooks/oeb/iterator.py:42
#, python-format #, python-format
msgid "%s format books are not supported" msgid "%s format books are not supported"
msgstr "" msgstr ""
@ -4097,7 +4119,7 @@ msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/actions/choose_library.py:471 #: /home/kovid/work/calibre/src/calibre/gui2/actions/choose_library.py:471
#: /home/kovid/work/calibre/src/calibre/gui2/actions/copy_to_library.py:212 #: /home/kovid/work/calibre/src/calibre/gui2/actions/copy_to_library.py:212
#: /home/kovid/work/calibre/src/calibre/gui2/actions/save_to_disk.py:100 #: /home/kovid/work/calibre/src/calibre/gui2/actions/save_to_disk.py:100
#: /home/kovid/work/calibre/src/calibre/gui2/library/views.py:898 #: /home/kovid/work/calibre/src/calibre/gui2/library/views.py:934
msgid "Not allowed" msgid "Not allowed"
msgstr "" msgstr ""
@ -5166,17 +5188,17 @@ msgstr ""
msgid "Remove Cover" msgid "Remove Cover"
msgstr "" msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/book_details.py:569 #: /home/kovid/work/calibre/src/calibre/gui2/book_details.py:335
msgid "Double-click to open Book Details window" msgid "Double-click to open Book Details window"
msgstr "" msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/book_details.py:570 #: /home/kovid/work/calibre/src/calibre/gui2/book_details.py:336
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/delete_matching_from_device.py:76 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/delete_matching_from_device.py:76
#: /home/kovid/work/calibre/src/calibre/library/field_metadata.py:295 #: /home/kovid/work/calibre/src/calibre/library/field_metadata.py:295
msgid "Path" msgid "Path"
msgstr "" msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/book_details.py:571 #: /home/kovid/work/calibre/src/calibre/gui2/book_details.py:337
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/book_info.py:109 #: /home/kovid/work/calibre/src/calibre/gui2/dialogs/book_info.py:109
#, python-format #, python-format
msgid "Cover size: %(width)d x %(height)d" msgid "Cover size: %(width)d x %(height)d"
@ -5275,7 +5297,7 @@ msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/preferences/save_template_ui.py:56 #: /home/kovid/work/calibre/src/calibre/gui2/preferences/save_template_ui.py:56
#: /home/kovid/work/calibre/src/calibre/gui2/preferences/saving_ui.py:21 #: /home/kovid/work/calibre/src/calibre/gui2/preferences/saving_ui.py:21
#: /home/kovid/work/calibre/src/calibre/gui2/preferences/search_ui.py:109 #: /home/kovid/work/calibre/src/calibre/gui2/preferences/search_ui.py:109
#: /home/kovid/work/calibre/src/calibre/gui2/preferences/sending_ui.py:68 #: /home/kovid/work/calibre/src/calibre/gui2/preferences/sending_ui.py:21
#: /home/kovid/work/calibre/src/calibre/gui2/preferences/server_ui.py:21 #: /home/kovid/work/calibre/src/calibre/gui2/preferences/server_ui.py:21
#: /home/kovid/work/calibre/src/calibre/gui2/preferences/template_functions_ui.py:95 #: /home/kovid/work/calibre/src/calibre/gui2/preferences/template_functions_ui.py:95
#: /home/kovid/work/calibre/src/calibre/gui2/preferences/toolbar_ui.py:21 #: /home/kovid/work/calibre/src/calibre/gui2/preferences/toolbar_ui.py:21
@ -10064,54 +10086,54 @@ msgstr ""
msgid "Double click to <b>edit</b> me<br><br>" msgid "Double click to <b>edit</b> me<br><br>"
msgstr "" msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/library/views.py:168 #: /home/kovid/work/calibre/src/calibre/gui2/library/views.py:187
#, python-format #, python-format
msgid "Hide column %s" msgid "Hide column %s"
msgstr "" msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/library/views.py:173 #: /home/kovid/work/calibre/src/calibre/gui2/library/views.py:192
#, python-format #, python-format
msgid "Sort on %s" msgid "Sort on %s"
msgstr "" msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/library/views.py:174 #: /home/kovid/work/calibre/src/calibre/gui2/library/views.py:193
msgid "Ascending" msgid "Ascending"
msgstr "" msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/library/views.py:177 #: /home/kovid/work/calibre/src/calibre/gui2/library/views.py:196
msgid "Descending" msgid "Descending"
msgstr "" msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/library/views.py:189 #: /home/kovid/work/calibre/src/calibre/gui2/library/views.py:208
#, python-format #, python-format
msgid "Change text alignment for %s" msgid "Change text alignment for %s"
msgstr "" msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/library/views.py:191 #: /home/kovid/work/calibre/src/calibre/gui2/library/views.py:210
msgid "Left" msgid "Left"
msgstr "" msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/library/views.py:191 #: /home/kovid/work/calibre/src/calibre/gui2/library/views.py:210
msgid "Right" msgid "Right"
msgstr "" msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/library/views.py:192 #: /home/kovid/work/calibre/src/calibre/gui2/library/views.py:211
msgid "Center" msgid "Center"
msgstr "" msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/library/views.py:211 #: /home/kovid/work/calibre/src/calibre/gui2/library/views.py:230
msgid "Show column" msgid "Show column"
msgstr "" msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/library/views.py:223 #: /home/kovid/work/calibre/src/calibre/gui2/library/views.py:242
msgid "Shrink column if it is too wide to fit" msgid "Shrink column if it is too wide to fit"
msgstr "" msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/library/views.py:226 #: /home/kovid/work/calibre/src/calibre/gui2/library/views.py:245
msgid "Restore default layout" msgid "Restore default layout"
msgstr "" msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/library/views.py:899 #: /home/kovid/work/calibre/src/calibre/gui2/library/views.py:935
msgid "Dropping onto a device is not supported. First add the book to the calibre library." msgid "Dropping onto a device is not supported. First add the book to the calibre library."
msgstr "" msgstr ""
@ -12292,7 +12314,7 @@ msgid "Change paths to &lowercase"
msgstr "" msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/preferences/saving_ui.py:46 #: /home/kovid/work/calibre/src/calibre/gui2/preferences/saving_ui.py:46
#: /home/kovid/work/calibre/src/calibre/gui2/preferences/sending_ui.py:76 #: /home/kovid/work/calibre/src/calibre/gui2/preferences/sending_ui.py:57
msgid "Format &dates as:" msgid "Format &dates as:"
msgstr "" msgstr ""
@ -12421,32 +12443,36 @@ msgid ""
msgstr "" msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/preferences/sending.py:28 #: /home/kovid/work/calibre/src/calibre/gui2/preferences/sending.py:28
#: /home/kovid/work/calibre/src/calibre/gui2/preferences/sending_ui.py:70 #: /home/kovid/work/calibre/src/calibre/gui2/preferences/sending_ui.py:41
msgid "Manual management" msgid "Manual management"
msgstr "" msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/preferences/sending.py:29 #: /home/kovid/work/calibre/src/calibre/gui2/preferences/sending.py:29
#: /home/kovid/work/calibre/src/calibre/gui2/preferences/sending_ui.py:71 #: /home/kovid/work/calibre/src/calibre/gui2/preferences/sending_ui.py:43
msgid "Only on send" msgid "Only on send"
msgstr "" msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/preferences/sending.py:30 #: /home/kovid/work/calibre/src/calibre/gui2/preferences/sending.py:30
#: /home/kovid/work/calibre/src/calibre/gui2/preferences/sending_ui.py:72 #: /home/kovid/work/calibre/src/calibre/gui2/preferences/sending_ui.py:45
msgid "Automatic management" msgid "Automatic management"
msgstr "" msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/preferences/sending_ui.py:69 #: /home/kovid/work/calibre/src/calibre/gui2/preferences/sending.py:36
msgid "Cannot change metadata management while a device is connected"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/preferences/sending_ui.py:30
msgid "Metadata &management:" msgid "Metadata &management:"
msgstr "" msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/preferences/sending_ui.py:73 #: /home/kovid/work/calibre/src/calibre/gui2/preferences/sending_ui.py:50
msgid "" msgid ""
"<li><b>Manual management</b>: Calibre updates the metadata and adds collections only when a book is sent. With this option, calibre will never remove a collection.</li>\n" "<li><b>Manual management</b>: Calibre updates the metadata and adds collections only when a book is sent. With this option, calibre will never remove a collection.</li>\n"
"<li><b>Only on send</b>: Calibre updates metadata and adds/removes collections for a book only when it is sent to the device. </li>\n" "<li><b>Only on send</b>: Calibre updates metadata and adds/removes collections for a book only when it is sent to the device. </li>\n"
"<li><b>Automatic management</b>: Calibre automatically keeps metadata on the device in sync with the calibre library, on every connect</li></ul>" "<li><b>Automatic management</b>: Calibre automatically keeps metadata on the device in sync with the calibre library, on every connect</li></ul>"
msgstr "" msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/preferences/sending_ui.py:77 #: /home/kovid/work/calibre/src/calibre/gui2/preferences/sending_ui.py:64
msgid "Here you can control how calibre will save your books when you click the Send to Device button. This setting can be overriden for individual devices by customizing the device interface plugins in Preferences->Advanced->Plugins" msgid "Here you can control how calibre will save your books when you click the Send to Device button. This setting can be overriden for individual devices by customizing the device interface plugins in Preferences->Advanced->Plugins"
msgstr "" msgstr ""
@ -13283,7 +13309,7 @@ msgid "Changing the metadata for that many books can take a while. Are you sure?
msgstr "" msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/tag_browser/model.py:823 #: /home/kovid/work/calibre/src/calibre/gui2/tag_browser/model.py:823
#: /home/kovid/work/calibre/src/calibre/library/database2.py:457 #: /home/kovid/work/calibre/src/calibre/library/database2.py:458
msgid "Searches" msgid "Searches"
msgstr "" msgstr ""
@ -15365,17 +15391,17 @@ msgstr ""
msgid "%(tt)sAverage rating is %(rating)3.1f" msgid "%(tt)sAverage rating is %(rating)3.1f"
msgstr "" msgstr ""
#: /home/kovid/work/calibre/src/calibre/library/database2.py:3407 #: /home/kovid/work/calibre/src/calibre/library/database2.py:3408
#, python-format #, python-format
msgid "<p>Migrating old database to ebook library in %s<br><center>" msgid "<p>Migrating old database to ebook library in %s<br><center>"
msgstr "" msgstr ""
#: /home/kovid/work/calibre/src/calibre/library/database2.py:3436 #: /home/kovid/work/calibre/src/calibre/library/database2.py:3437
#, python-format #, python-format
msgid "Copying <b>%s</b>" msgid "Copying <b>%s</b>"
msgstr "" msgstr ""
#: /home/kovid/work/calibre/src/calibre/library/database2.py:3453 #: /home/kovid/work/calibre/src/calibre/library/database2.py:3454
msgid "Compacting database" msgid "Compacting database"
msgstr "" msgstr ""

View File

@ -170,11 +170,37 @@ def format_date(dt, format, assume_utc=False, as_utc=False):
if format == 'iso': if format == 'iso':
return isoformat(dt, assume_utc=assume_utc, as_utc=as_utc) return isoformat(dt, assume_utc=assume_utc, as_utc=as_utc)
ampm = 'ap' in format.lower()
if dt == UNDEFINED_DATE: if dt == UNDEFINED_DATE:
return '' return ''
strf = partial(strftime, t=dt.timetuple()) strf = partial(strftime, t=dt.timetuple())
def format_hour(hr):
l = len(hr)
h = dt.hour
if ampm:
h = h%12
if l == 1: return '%d'%h
return '%02d'%h
def format_minute(min):
l = len(min)
if l == 1: return '%d'%dt.minute
return '%02d'%dt.minute
def format_second(min):
l = len(min)
if l == 1: return '%d'%dt.second
return '%02d'%dt.second
def format_ampm(ap):
res = strf('%p')
if ap == 'AP':
return res
return res.lower()
def format_day(dy): def format_day(dy):
l = len(dy) l = len(dy)
if l == 1: return '%d'%dt.day if l == 1: return '%d'%dt.day
@ -193,17 +219,25 @@ def format_date(dt, format, assume_utc=False, as_utc=False):
if len(yr) == 2: return '%02d'%(dt.year % 100) if len(yr) == 2: return '%02d'%(dt.year % 100)
return '%04d'%dt.year return '%04d'%dt.year
function_index = {
'd': format_day,
'M': format_month,
'y': format_year,
'h': format_hour,
'm': format_minute,
's': format_second,
'a': format_ampm,
'A': format_ampm,
}
def repl_func(mo): def repl_func(mo):
s = mo.group(0) s = mo.group(0)
if s is None: if s is None:
return '' return ''
if s[0] == 'd': return function_index[s[0]](s)
return format_day(s)
if s[0] == 'M':
return format_month(s)
return format_year(s)
return re.sub('(d{1,4}|M{1,4}|(?:yyyy|yy))', repl_func, format) return re.sub(
'(s{1,2})|(m{1,2})|(h{1,2})|(ap)|(AP)|(d{1,4}|M{1,4}|(?:yyyy|yy))',
repl_func, format)
def replace_months(datestr, clang): def replace_months(datestr, clang):
# Replace months by english equivalent for parse_date # Replace months by english equivalent for parse_date

View File

@ -598,8 +598,9 @@ class BuiltinFormatsModtimes(BuiltinFormatterFunction):
def evaluate(self, formatter, kwargs, mi, locals, fmt): def evaluate(self, formatter, kwargs, mi, locals, fmt):
fmt_data = mi.get('format_metadata', {}) fmt_data = mi.get('format_metadata', {})
data = sorted(fmt_data.items(), key=lambda x:x[1]['mtime'], reverse=True)
return ','.join(k.upper()+':'+format_date(v['mtime'], fmt) return ','.join(k.upper()+':'+format_date(v['mtime'], fmt)
for k,v in fmt_data.iteritems()) for k,v in data)
class BuiltinFormatsSizes(BuiltinFormatterFunction): class BuiltinFormatsSizes(BuiltinFormatterFunction):
name = 'formats_sizes' name = 'formats_sizes'
@ -746,6 +747,14 @@ class BuiltinFormatDate(BuiltinFormatterFunction):
'MMMM : the long localized month name (e.g. "January" to "December"). ' 'MMMM : the long localized month name (e.g. "January" to "December"). '
'yy : the year as two digit number (00 to 99). ' 'yy : the year as two digit number (00 to 99). '
'yyyy : the year as four digit number. ' 'yyyy : the year as four digit number. '
'h : the hours without a leading 0 (0 to 11 or 0 to 23, depending on am/pm) '
'hh : the hours with a leading 0 (00 to 11 or 00 to 23, depending on am/pm) '
'm : the minutes without a leading 0 (0 to 59) '
'mm : the minutes with a leading 0 (00 to 59) '
's : the seconds without a leading 0 (0 to 59) '
'ss : the seconds with a leading 0 (00 to 59) '
'ap : use a 12-hour clock instead of a 24-hour clock, with "ap" replaced by the localized string for am or pm '
'AP : use a 12-hour clock instead of a 24-hour clock, with "AP" replaced by the localized string for AM or PM '
'iso : the date with time and timezone. Must be the only format present') 'iso : the date with time and timezone. Must be the only format present')
def evaluate(self, formatter, kwargs, mi, locals, val, format_string): def evaluate(self, formatter, kwargs, mi, locals, val, format_string):

View File

@ -121,7 +121,7 @@ _extra_lang_codes = {
'en_TH' : _('English (Thailand)'), 'en_TH' : _('English (Thailand)'),
'en_TR' : _('English (Turkey)'), 'en_TR' : _('English (Turkey)'),
'en_CY' : _('English (Cyprus)'), 'en_CY' : _('English (Cyprus)'),
'en_CZ' : _('English (Czechoslovakia)'), 'en_CZ' : _('English (Czech Republic)'),
'en_PK' : _('English (Pakistan)'), 'en_PK' : _('English (Pakistan)'),
'en_HR' : _('English (Croatia)'), 'en_HR' : _('English (Croatia)'),
'en_ID' : _('English (Indonesia)'), 'en_ID' : _('English (Indonesia)'),