Sync to trunk.

This commit is contained in:
John Schember 2011-11-19 09:49:43 -05:00
commit fe8d56f4fd
95 changed files with 41863 additions and 34697 deletions

View File

@ -19,6 +19,60 @@
# new recipes: # new recipes:
# - title: # - title:
- version: 0.8.27
date: 2011-11-18
new features:
- title: "Drivers for the Kindle Fire and the Nook Tablet"
tickets: [890918]
- title: "Conversion: Add an option under Look & Feel to remove specified style information (CSS) from the document during conversion."
tickets: [871384]
- title: "Add an option in the bulk metadata edit dialog to restore the pre-conversion files for many books with a single click."
tickets: [886116]
- title: "Jobs list: Add the ability to search for and to hide jobs, useful if you have run a lot of jobs and the list is getting crowded."
tickets: [883734]
- title: "Book jacket generation: Add ability to customize the book jacket template and add custom columns into the jacket."
tickets: [889912]
- title: "MOBI Input: Performance improvement when viewing/converting a file with a lot of links"
bug fixes:
- title: "Fix regression in 0.8.26 that broke disabling the update of particular fields during a bulk metadata download."
tickets: [889696]
- title: "Get Books: Fix DRM status for legimi"
- title: "When parsing for lxml via BeatifulSoup, use the calibre modified copy of BeautifulSoup (more robust)."
tickets: [889890]
- title: "HTML Input: Handle double encoded URLs in img tags"
tickets: [889323]
improved recipes:
- Various Polish recipes
- Academia Catavencu
- El Periodico de Aragon
- Weblogs SL
- Folha de Sao Paolo (subscription)
new recipes:
- title: News on Japan
author: Krittika Goyal
- title: Formula AS
author: Silviu Cotoara
- title: Various Turkish news sources
author: Osman Kaysan
- title: Infra.pl and Spider's Web
author: fenuks
- version: 0.8.26 - version: 0.8.26
date: 2011-11-12 date: 2011-11-12

View File

@ -12,7 +12,6 @@ class GN(BasicNewsRecipe):
EDITION = 0 EDITION = 0
__author__ = 'Piotr Kontek' __author__ = 'Piotr Kontek'
title = u'Gość niedzielny'
description = 'Weekly magazine' description = 'Weekly magazine'
encoding = 'utf-8' encoding = 'utf-8'
no_stylesheets = True no_stylesheets = True
@ -20,6 +19,8 @@ class GN(BasicNewsRecipe):
remove_javascript = True remove_javascript = True
temp_files = [] temp_files = []
simultaneous_downloads = 1 simultaneous_downloads = 1
masthead_url = 'http://gosc.pl/files/11/03/12/949089_top.gif'
title = u'Gość niedzielny'
articles_are_obfuscated = True articles_are_obfuscated = True
@ -64,7 +65,6 @@ class GN(BasicNewsRecipe):
if img != None: if img != None:
a = img.parent a = img.parent
self.EDITION = a['href'] self.EDITION = a['href']
self.title = img['alt']
self.cover_url = 'http://www.gosc.pl' + img['src'] self.cover_url = 'http://www.gosc.pl' + img['src']
if not first: if not first:
break break

View File

@ -1,11 +1,11 @@
from calibre.web.feeds.news import BasicNewsRecipe from calibre.web.feeds.news import BasicNewsRecipe
import re
class AdvancedUserRecipe(BasicNewsRecipe): class AdvancedUserRecipe(BasicNewsRecipe):
title = 'heise online' title = 'Heise-online'
description = 'News vom Heise-Verlag' description = 'News vom Heise-Verlag'
__author__ = 'schuster' __author__ = 'schuster'
masthead_url = 'http://www.heise.de/icons/ho/heise_online_logo.gif'
publisher = 'Heise Zeitschriften Verlag GmbH & Co. KG'
use_embedded_content = False use_embedded_content = False
language = 'de' language = 'de'
oldest_article = 2 oldest_article = 2
@ -14,11 +14,10 @@ class AdvancedUserRecipe(BasicNewsRecipe):
remove_empty_feeds = True remove_empty_feeds = True
timeout = 5 timeout = 5
no_stylesheets = True no_stylesheets = True
encoding = 'utf-8'
remove_tags_after = dict(name ='p', attrs={'class':'editor'}) remove_tags_after = dict(name ='p', attrs={'class':'editor'})
remove_tags = [{'class':'navi_top_container'}, remove_tags = [dict(id='navi_top_container'),
dict(id='navi_bottom'), dict(id='navi_bottom'),
dict(id='mitte_rechts'), dict(id='mitte_rechts'),
dict(id='navigation'), dict(id='navigation'),
@ -29,27 +28,31 @@ class AdvancedUserRecipe(BasicNewsRecipe):
dict(id='seiten_navi'), dict(id='seiten_navi'),
dict(id='adbottom'), dict(id='adbottom'),
dict(id='sitemap'), dict(id='sitemap'),
dict(name='a', href=re.compile(r'^/([a-zA-Z]+/)?')), dict(name='div', attrs={'id':'sitemap'}),
] dict(name='ul', attrs={'class':'erste_zeile'}),
dict(name='ul', attrs={'class':'zweite_zeile'}),
dict(name='div', attrs={'class':'navi_top_container'})]
feeds = [ feeds = [
('Newsticker', 'http://www.heise.de/newsticker/heise.rdf'), ('Newsticker', 'http://www.heise.de/newsticker/heise.rdf'),
('iX', 'http://www.heise.de/ix/news/news.rdf'), ('Auto', 'http://www.heise.de/autos/rss/news.rdf'),
('Technology Review', 'http://www.heise.de/tr/news-atom.xml'),
('mobil', 'http://www.heise.de/mobil/newsticker/heise-atom.xml'),
('Security', 'http://www.heise.de/security/news/news-atom.xml'),
('Netze', 'http://www.heise.de/netze/rss/netze-atom.xml'),
('Open Source', 'http://www.heise.de/open/news/news-atom.xml'),
('Resale ', 'http://www.heise.de/resale/rss/resale.rdf'),
('Foto ', 'http://www.heise.de/foto/rss/news-atom.xml'), ('Foto ', 'http://www.heise.de/foto/rss/news-atom.xml'),
('Autos', 'http://www.heise.de/autos/rss/news.rdf'), ('Mac&i', 'http://www.heise.de/mac-and-i/news.rdf'),
('Mac & i', 'http://www.heise.de/mac-and-i/news.rdf'), ('Mobile ', 'http://www.heise.de/mobil/newsticker/heise-atom.xml'),
('Netz ', 'http://www.heise.de/netze/rss/netze-atom.xml'),
('Open ', 'http://www.heise.de/open/news/news-atom.xml'),
('Resale ', 'http://www.heise.de/resale/rss/resale.rdf'),
('Security ', 'http://www.heise.de/security/news/news-atom.xml'),
('C`t', 'http://www.heise.de/ct/rss/artikel-atom.xml'),
('iX', 'http://www.heise.de/ix/news/news.rdf'),
('Mach-flott', 'http://www.heise.de/mach-flott/rss/mach-flott-atom.xml'),
('Blog: Babel-Bulletin', 'http://www.heise.de/developer/rss/babel-bulletin/blog.rdf'), ('Blog: Babel-Bulletin', 'http://www.heise.de/developer/rss/babel-bulletin/blog.rdf'),
('Blog: Der Dotnet-Doktor', 'http://www.heise.de/developer/rss/dotnet-doktor/blog.rdf'), ('Blog: Der Dotnet-Doktor', 'http://www.heise.de/developer/rss/dotnet-doktor/blog.rdf'),
('Blog: Bernds Management-Welt', 'http://www.heise.de/developer/rss/bernds-management-welt/blog.rdf'), ('Blog: Bernds Management-Welt', 'http://www.heise.de/developer/rss/bernds-management-welt/blog.rdf'),
('Blog: The World of IT', 'http://www.heise.de/developer/rss/world-of-it/blog.rdf'), ('Blog: IT conversation', 'http://www.heise.de/developer/rss/world-of-it/blog.rdf'),
('Blog: Kais bewegtes Web', 'http://www.heise.de/developer/rss/kais-bewegtes-web/blog.rdf') ('Blog: Kais bewegtes Web', 'http://www.heise.de/developer/rss/kais-bewegtes-web/blog.rdf')]
]
def print_version(self, url): def print_version(self, url):
return url + '?view=print' return url + '?view=print'

View File

@ -4,7 +4,6 @@ __license__ = 'GPL v3'
__copyright__ = '2010, matek09, matek09@gmail.com' __copyright__ = '2010, matek09, matek09@gmail.com'
from calibre.web.feeds.news import BasicNewsRecipe from calibre.web.feeds.news import BasicNewsRecipe
import re
class Histmag(BasicNewsRecipe): class Histmag(BasicNewsRecipe):
title = u'Histmag' title = u'Histmag'

View File

@ -1,5 +1,4 @@
from calibre.web.feeds.news import BasicNewsRecipe from calibre.web.feeds.news import BasicNewsRecipe
from calibre.ebooks.BeautifulSoup import BeautifulSoup
class NewsOnJapan(BasicNewsRecipe): class NewsOnJapan(BasicNewsRecipe):
title = u'News On Japan' title = u'News On Japan'
@ -14,6 +13,6 @@ class NewsOnJapan(BasicNewsRecipe):
feeds = [ feeds = [
('News', ('News',
'http://newsonjapan.com/rss/top.xml'), 'http://newsonjapan.com/rss/top.xml'),
] ]

View File

@ -37,11 +37,13 @@ class TagesspiegelRSS(BasicNewsRecipe):
keep_only_tags = dict(name='div', attrs={'class':["hcf-article"]}) keep_only_tags = dict(name='div', attrs={'class':["hcf-article"]})
remove_tags = [ remove_tags = [
dict(name='link'), dict(name='iframe'),dict(name='style'),dict(name='meta'),dict(name='button'), dict(name='link'), dict(name='iframe'),dict(name='style'),dict(name='meta'),dict(name='button'),
dict(name='div', attrs={'class':["hcf-jump-to-comments","hcf-clear","hcf-magnify hcf-media-control"] }), dict(name='div', attrs={'class':["hcf-jump-to-comments","hcf-clear","hcf-magnify hcf-media-control",
"hcf-socials-widgets hcf-socials-top","hcf-socials-widgets hcf-socials-bottom"] }),
dict(name='span', attrs={'class':["hcf-mainsearch",] }), dict(name='span', attrs={'class':["hcf-mainsearch",] }),
dict(name='ul', attrs={'class':["hcf-tools"]}), dict(name='ul', attrs={'class':["hcf-tools"]}),
dict(name='ul', attrs={'class': re.compile('hcf-services')}) dict(name='ul', attrs={'class': re.compile('hcf-services')})
] ]
def parse_index(self): def parse_index(self):
soup = self.index_to_soup('http://www.tagesspiegel.de/zeitung/') soup = self.index_to_soup('http://www.tagesspiegel.de/zeitung/')

View File

@ -5,7 +5,6 @@ www.theweek.com
''' '''
from calibre.web.feeds.news import BasicNewsRecipe from calibre.web.feeds.news import BasicNewsRecipe
import re
class TheWeek(BasicNewsRecipe): class TheWeek(BasicNewsRecipe):
title = 'The Week Magazine' title = 'The Week Magazine'
@ -21,23 +20,7 @@ class TheWeek(BasicNewsRecipe):
encoding = 'utf-8' encoding = 'utf-8'
use_embedded_content = False use_embedded_content = False
language = 'en' language = 'en'
preprocess_regexps = [(re.compile(r'<h3><a href=.*</body>', re.DOTALL), lambda match: '</body>')] auto_cleanup = True
remove_tags_before = dict(name='h1')
remove_tags_after = dict(name='div', attrs={'class':'articleSubscribe4free'})
remove_tags = [
dict(name='div', attrs={'class':['floatLeft','imageCaption','slideshowImageAttribution','postDate','utilities','cartoonInfo','left','middle','col300','articleSubscribe4free',' articleFlyout','articleFlyout floatRight','fourFreeBar']})
,dict(name='div', attrs={'id':['cartoonThumbs','rightColumn','header','partners']})
,dict(name='ul', attrs={'class':['slideshowNav','hotTopicsList topicList']})
]
remove_attributes = ['width','height', 'style', 'font', 'color']
extra_css = '''
h1{font-family:Geneva, Arial, Helvetica, sans-serif;color:#154B7A;}
h3{font-size: 14px;color:#999999; font-family:Geneva, Arial, Helvetica, sans-serif;font-weight: bold;}
h2{color:#666666; font-family:Geneva, Arial, Helvetica, sans-serif;font-size:small;}
p {font-family:Arial,Helvetica,sans-serif;}
'''
filter_regexps = [r'www\.palmcoastdata\.com']
feeds = [ feeds = [
(u'News-Opinion', u'http://theweek.com/section/index/news_opinion.rss'), (u'News-Opinion', u'http://theweek.com/section/index/news_opinion.rss'),
(u'Business', u'http://theweek.com/section/index/business.rss'), (u'Business', u'http://theweek.com/section/index/business.rss'),

View File

@ -16,6 +16,7 @@ class ZAOBAO(BasicNewsRecipe):
recursions = 1 recursions = 1
language = 'zh' language = 'zh'
encoding = 'gbk' encoding = 'gbk'
masthead_url = 'http://www.zaobao.com/ssi/images1/zblogo_original.gif'
# multithreaded_fetch = True # multithreaded_fetch = True
keep_only_tags = [ keep_only_tags = [

View File

@ -38,10 +38,12 @@
<hr class="cbj_kindle_banner_hr" /> <hr class="cbj_kindle_banner_hr" />
<!-- <!--
In addition you can add code to show the values of custom columns here. In addition you can add code to show the values of custom columns here.
The value is available as _column_name and the title as _column_name_label. The value is available as _column_name and the title as
For example, if you have a custom column with label #genre, you can add it to _column_name_label. For example, if you have a custom column with
this template with: label #genre, you can add it to this template with _genre_label and
<div>{_genre_label}: {_genre}</div> _genre. Note that the # is replaced by an underscore. For example
<div><b>{_genre_label}:</b> {_genre}</div>
--> -->
<div class="cbj_comments">{comments}</div> <div class="cbj_comments">{comments}</div>

View File

@ -12,14 +12,14 @@ msgstr ""
"Report-Msgid-Bugs-To: Debian iso-codes team <pkg-isocodes-" "Report-Msgid-Bugs-To: Debian iso-codes team <pkg-isocodes-"
"devel@lists.alioth.debian.org>\n" "devel@lists.alioth.debian.org>\n"
"POT-Creation-Date: 2011-09-27 14:31+0000\n" "POT-Creation-Date: 2011-09-27 14:31+0000\n"
"PO-Revision-Date: 2011-11-04 23:01+0000\n" "PO-Revision-Date: 2011-11-13 15:24+0000\n"
"Last-Translator: Ferran Rius <frius64@hotmail.com>\n" "Last-Translator: Ferran Rius <frius64@hotmail.com>\n"
"Language-Team: Catalan <linux@softcatala.org>\n" "Language-Team: Catalan <linux@softcatala.org>\n"
"MIME-Version: 1.0\n" "MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n" "Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n" "Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2011-11-06 05:23+0000\n" "X-Launchpad-Export-Date: 2011-11-14 05:15+0000\n"
"X-Generator: Launchpad (build 14231)\n" "X-Generator: Launchpad (build 14277)\n"
"Language: ca\n" "Language: ca\n"
#. name for aaa #. name for aaa
@ -8572,43 +8572,43 @@ msgstr "Guntai"
#. name for gnu #. name for gnu
msgid "Gnau" msgid "Gnau"
msgstr "" msgstr "Gnau"
#. name for gnw #. name for gnw
msgid "Guaraní; Western Bolivian" msgid "Guaraní; Western Bolivian"
msgstr "" msgstr "Guaraní; bolivià occidental"
#. name for gnz #. name for gnz
msgid "Ganzi" msgid "Ganzi"
msgstr "" msgstr "Ganzi"
#. name for goa #. name for goa
msgid "Guro" msgid "Guro"
msgstr "" msgstr "Guro"
#. name for gob #. name for gob
msgid "Playero" msgid "Playero"
msgstr "" msgstr "Playero"
#. name for goc #. name for goc
msgid "Gorakor" msgid "Gorakor"
msgstr "" msgstr "Gorakor"
#. name for god #. name for god
msgid "Godié" msgid "Godié"
msgstr "" msgstr "Godié"
#. name for goe #. name for goe
msgid "Gongduk" msgid "Gongduk"
msgstr "" msgstr "Gongduk"
#. name for gof #. name for gof
msgid "Gofa" msgid "Gofa"
msgstr "" msgstr "Gofa"
#. name for gog #. name for gog
msgid "Gogo" msgid "Gogo"
msgstr "" msgstr "Gogo"
#. name for goh #. name for goh
msgid "German; Old High (ca. 750-1050)" msgid "German; Old High (ca. 750-1050)"
@ -8616,23 +8616,23 @@ msgstr "Alt alemany; antic (ca. 750-1050)"
#. name for goi #. name for goi
msgid "Gobasi" msgid "Gobasi"
msgstr "" msgstr "Gobasi"
#. name for goj #. name for goj
msgid "Gowlan" msgid "Gowlan"
msgstr "" msgstr "Gowlan"
#. name for gok #. name for gok
msgid "Gowli" msgid "Gowli"
msgstr "" msgstr "Gowli"
#. name for gol #. name for gol
msgid "Gola" msgid "Gola"
msgstr "" msgstr "Gola"
#. name for gom #. name for gom
msgid "Konkani; Goan" msgid "Konkani; Goan"
msgstr "" msgstr "Konkani; goanès"
#. name for gon #. name for gon
msgid "Gondi" msgid "Gondi"
@ -8640,71 +8640,71 @@ msgstr "Gondi"
#. name for goo #. name for goo
msgid "Gone Dau" msgid "Gone Dau"
msgstr "" msgstr "Gone Dau"
#. name for gop #. name for gop
msgid "Yeretuar" msgid "Yeretuar"
msgstr "" msgstr "Yeretuar"
#. name for goq #. name for goq
msgid "Gorap" msgid "Gorap"
msgstr "" msgstr "Gorap"
#. name for gor #. name for gor
msgid "Gorontalo" msgid "Gorontalo"
msgstr "" msgstr "Gorontalo"
#. name for gos #. name for gos
msgid "Gronings" msgid "Gronings"
msgstr "" msgstr "Gronings"
#. name for got #. name for got
msgid "Gothic" msgid "Gothic"
msgstr "" msgstr "Gòtic"
#. name for gou #. name for gou
msgid "Gavar" msgid "Gavar"
msgstr "" msgstr "Gavar"
#. name for gow #. name for gow
msgid "Gorowa" msgid "Gorowa"
msgstr "" msgstr "Gorowa"
#. name for gox #. name for gox
msgid "Gobu" msgid "Gobu"
msgstr "" msgstr "Gobu"
#. name for goy #. name for goy
msgid "Goundo" msgid "Goundo"
msgstr "" msgstr "Goundo"
#. name for goz #. name for goz
msgid "Gozarkhani" msgid "Gozarkhani"
msgstr "" msgstr "Gozarkhani"
#. name for gpa #. name for gpa
msgid "Gupa-Abawa" msgid "Gupa-Abawa"
msgstr "" msgstr "Gupa-Abawa"
#. name for gpn #. name for gpn
msgid "Taiap" msgid "Taiap"
msgstr "" msgstr "Taiap"
#. name for gqa #. name for gqa
msgid "Ga'anda" msgid "Ga'anda"
msgstr "" msgstr "Gaanda"
#. name for gqi #. name for gqi
msgid "Guiqiong" msgid "Guiqiong"
msgstr "" msgstr "Guiqiong"
#. name for gqn #. name for gqn
msgid "Guana (Brazil)" msgid "Guana (Brazil)"
msgstr "" msgstr "Guana (Brasil)"
#. name for gqr #. name for gqr
msgid "Gor" msgid "Gor"
msgstr "" msgstr "Gor"
#. name for gra #. name for gra
msgid "Garasia; Rajput" msgid "Garasia; Rajput"
@ -8720,19 +8720,19 @@ msgstr "Grec antic (fins el 1453)"
#. name for grd #. name for grd
msgid "Guruntum-Mbaaru" msgid "Guruntum-Mbaaru"
msgstr "" msgstr "Guruntum"
#. name for grg #. name for grg
msgid "Madi" msgid "Madi"
msgstr "" msgstr "Madi"
#. name for grh #. name for grh
msgid "Gbiri-Niragu" msgid "Gbiri-Niragu"
msgstr "" msgstr "Gbiri-Niragu"
#. name for gri #. name for gri
msgid "Ghari" msgid "Ghari"
msgstr "" msgstr "Ghari"
#. name for grj #. name for grj
msgid "Grebo; Southern" msgid "Grebo; Southern"
@ -8740,35 +8740,35 @@ msgstr "Grebo; meridional"
#. name for grm #. name for grm
msgid "Kota Marudu Talantang" msgid "Kota Marudu Talantang"
msgstr "" msgstr "Kota Marudu; Talantang"
#. name for grn #. name for grn
msgid "Guarani" msgid "Guarani"
msgstr "guaraní" msgstr "Guaraní"
#. name for gro #. name for gro
msgid "Groma" msgid "Groma"
msgstr "" msgstr "Groma"
#. name for grq #. name for grq
msgid "Gorovu" msgid "Gorovu"
msgstr "" msgstr "Gorovu"
#. name for grr #. name for grr
msgid "Taznatit" msgid "Taznatit"
msgstr "" msgstr "Taznatit"
#. name for grs #. name for grs
msgid "Gresi" msgid "Gresi"
msgstr "" msgstr "Gresi"
#. name for grt #. name for grt
msgid "Garo" msgid "Garo"
msgstr "" msgstr "Garo"
#. name for gru #. name for gru
msgid "Kistane" msgid "Kistane"
msgstr "" msgstr "Gurage; septentrional"
#. name for grv #. name for grv
msgid "Grebo; Central" msgid "Grebo; Central"
@ -8776,11 +8776,11 @@ msgstr "Grebo; central"
#. name for grw #. name for grw
msgid "Gweda" msgid "Gweda"
msgstr "" msgstr "Gweda"
#. name for grx #. name for grx
msgid "Guriaso" msgid "Guriaso"
msgstr "" msgstr "Guriaso"
#. name for gry #. name for gry
msgid "Grebo; Barclayville" msgid "Grebo; Barclayville"
@ -8788,7 +8788,7 @@ msgstr "Grebo; Barclayville"
#. name for grz #. name for grz
msgid "Guramalum" msgid "Guramalum"
msgstr "" msgstr "Guramalum"
#. name for gse #. name for gse
msgid "Ghanaian Sign Language" msgid "Ghanaian Sign Language"
@ -8800,7 +8800,7 @@ msgstr "Llenguatge de signes alemany"
#. name for gsl #. name for gsl
msgid "Gusilay" msgid "Gusilay"
msgstr "" msgstr "Gusilay"
#. name for gsm #. name for gsm
msgid "Guatemalan Sign Language" msgid "Guatemalan Sign Language"
@ -8808,7 +8808,7 @@ msgstr "Llenguatge de signes guatemaltec"
#. name for gsn #. name for gsn
msgid "Gusan" msgid "Gusan"
msgstr "" msgstr "Gusan"
#. name for gso #. name for gso
msgid "Gbaya; Southwest" msgid "Gbaya; Southwest"
@ -8816,7 +8816,7 @@ msgstr "Gbaya; Sudoccidental"
#. name for gsp #. name for gsp
msgid "Wasembo" msgid "Wasembo"
msgstr "" msgstr "Wasembo"
#. name for gss #. name for gss
msgid "Greek Sign Language" msgid "Greek Sign Language"
@ -8828,23 +8828,23 @@ msgstr "Alemany; suís"
#. name for gta #. name for gta
msgid "Guató" msgid "Guató"
msgstr "" msgstr "Guató"
#. name for gti #. name for gti
msgid "Gbati-ri" msgid "Gbati-ri"
msgstr "" msgstr "Gbati-ri"
#. name for gua #. name for gua
msgid "Shiki" msgid "Shiki"
msgstr "" msgstr "Shiki"
#. name for gub #. name for gub
msgid "Guajajára" msgid "Guajajára"
msgstr "" msgstr "Guajajara"
#. name for guc #. name for guc
msgid "Wayuu" msgid "Wayuu"
msgstr "" msgstr "Guajiro"
#. name for gud #. name for gud
msgid "Dida; Yocoboué" msgid "Dida; Yocoboué"
@ -8852,23 +8852,23 @@ msgstr "Dida; Yocoboué"
#. name for gue #. name for gue
msgid "Gurinji" msgid "Gurinji"
msgstr "" msgstr "Gurindji"
#. name for guf #. name for guf
msgid "Gupapuyngu" msgid "Gupapuyngu"
msgstr "" msgstr "Gupapuyngu"
#. name for gug #. name for gug
msgid "Guaraní; Paraguayan" msgid "Guaraní; Paraguayan"
msgstr "" msgstr "Guaraní; paraguaià"
#. name for guh #. name for guh
msgid "Guahibo" msgid "Guahibo"
msgstr "" msgstr "Guahibo"
#. name for gui #. name for gui
msgid "Guaraní; Eastern Bolivian" msgid "Guaraní; Eastern Bolivian"
msgstr "" msgstr "Guaraní; bolivià oriental"
#. name for guj #. name for guj
msgid "Gujarati" msgid "Gujarati"
@ -8876,7 +8876,7 @@ msgstr "gujarati"
#. name for guk #. name for guk
msgid "Gumuz" msgid "Gumuz"
msgstr "" msgstr "Gumús"
#. name for gul #. name for gul
msgid "Creole English; Sea Island" msgid "Creole English; Sea Island"
@ -8884,27 +8884,27 @@ msgstr "Anglès crioll; Sea Island"
#. name for gum #. name for gum
msgid "Guambiano" msgid "Guambiano"
msgstr "" msgstr "Guambià"
#. name for gun #. name for gun
msgid "Guaraní; Mbyá" msgid "Guaraní; Mbyá"
msgstr "" msgstr "Guaraní; Mbyà"
#. name for guo #. name for guo
msgid "Guayabero" msgid "Guayabero"
msgstr "" msgstr "Guayabero"
#. name for gup #. name for gup
msgid "Gunwinggu" msgid "Gunwinggu"
msgstr "" msgstr "Gunwinggu"
#. name for guq #. name for guq
msgid "Aché" msgid "Aché"
msgstr "" msgstr "Aché"
#. name for gur #. name for gur
msgid "Farefare" msgid "Farefare"
msgstr "" msgstr "Gurenne"
#. name for gus #. name for gus
msgid "Guinean Sign Language" msgid "Guinean Sign Language"
@ -8912,67 +8912,67 @@ msgstr "Llenguatge de signes guineà"
#. name for gut #. name for gut
msgid "Maléku Jaíka" msgid "Maléku Jaíka"
msgstr "" msgstr "Guatuso"
#. name for guu #. name for guu
msgid "Yanomamö" msgid "Yanomamö"
msgstr "" msgstr "Guaharibo"
#. name for guv #. name for guv
msgid "Gey" msgid "Gey"
msgstr "" msgstr "Gey"
#. name for guw #. name for guw
msgid "Gun" msgid "Gun"
msgstr "" msgstr "Gun-Gbe"
#. name for gux #. name for gux
msgid "Gourmanchéma" msgid "Gourmanchéma"
msgstr "" msgstr "Gourmanchéma"
#. name for guz #. name for guz
msgid "Gusii" msgid "Gusii"
msgstr "" msgstr "Gusí"
#. name for gva #. name for gva
msgid "Guana (Paraguay)" msgid "Guana (Paraguay)"
msgstr "" msgstr "Guana (Paraguai)"
#. name for gvc #. name for gvc
msgid "Guanano" msgid "Guanano"
msgstr "" msgstr "Guanano"
#. name for gve #. name for gve
msgid "Duwet" msgid "Duwet"
msgstr "" msgstr "Duwet"
#. name for gvf #. name for gvf
msgid "Golin" msgid "Golin"
msgstr "" msgstr "Golin"
#. name for gvj #. name for gvj
msgid "Guajá" msgid "Guajá"
msgstr "" msgstr "Guajà"
#. name for gvl #. name for gvl
msgid "Gulay" msgid "Gulay"
msgstr "" msgstr "Gulay"
#. name for gvm #. name for gvm
msgid "Gurmana" msgid "Gurmana"
msgstr "" msgstr "Gurmana"
#. name for gvn #. name for gvn
msgid "Kuku-Yalanji" msgid "Kuku-Yalanji"
msgstr "" msgstr "Kuku; Yalanji"
#. name for gvo #. name for gvo
msgid "Gavião Do Jiparaná" msgid "Gavião Do Jiparaná"
msgstr "" msgstr "Gaviao Jiparanà"
#. name for gvp #. name for gvp
msgid "Gavião; Pará" msgid "Gavião; Pará"
msgstr "" msgstr "Gaviao Parà"
#. name for gvr #. name for gvr
msgid "Gurung; Western" msgid "Gurung; Western"
@ -8980,75 +8980,75 @@ msgstr "Gurung; occidental"
#. name for gvs #. name for gvs
msgid "Gumawana" msgid "Gumawana"
msgstr "" msgstr "Gumawana"
#. name for gvy #. name for gvy
msgid "Guyani" msgid "Guyani"
msgstr "" msgstr "Guyani"
#. name for gwa #. name for gwa
msgid "Mbato" msgid "Mbato"
msgstr "" msgstr "Mbato"
#. name for gwb #. name for gwb
msgid "Gwa" msgid "Gwa"
msgstr "" msgstr "Gwa"
#. name for gwc #. name for gwc
msgid "Kalami" msgid "Kalami"
msgstr "" msgstr "Kalami"
#. name for gwd #. name for gwd
msgid "Gawwada" msgid "Gawwada"
msgstr "" msgstr "Gawwada"
#. name for gwe #. name for gwe
msgid "Gweno" msgid "Gweno"
msgstr "" msgstr "Gweno"
#. name for gwf #. name for gwf
msgid "Gowro" msgid "Gowro"
msgstr "" msgstr "Gowro"
#. name for gwg #. name for gwg
msgid "Moo" msgid "Moo"
msgstr "" msgstr "Moo"
#. name for gwi #. name for gwi
msgid "Gwichʼin" msgid "Gwichʼin"
msgstr "" msgstr "Gwichin"
#. name for gwj #. name for gwj
msgid "/Gwi" msgid "/Gwi"
msgstr "" msgstr "Gwi"
#. name for gwn #. name for gwn
msgid "Gwandara" msgid "Gwandara"
msgstr "" msgstr "Gwandara"
#. name for gwr #. name for gwr
msgid "Gwere" msgid "Gwere"
msgstr "" msgstr "Gwere"
#. name for gwt #. name for gwt
msgid "Gawar-Bati" msgid "Gawar-Bati"
msgstr "" msgstr "Gawar-Bati"
#. name for gwu #. name for gwu
msgid "Guwamu" msgid "Guwamu"
msgstr "" msgstr "Guwamu"
#. name for gww #. name for gww
msgid "Kwini" msgid "Kwini"
msgstr "" msgstr "Goonan"
#. name for gwx #. name for gwx
msgid "Gua" msgid "Gua"
msgstr "" msgstr "Gua"
#. name for gxx #. name for gxx
msgid "Wè Southern" msgid "Wè Southern"
msgstr "" msgstr "We; meridional"
#. name for gya #. name for gya
msgid "Gbaya; Northwest" msgid "Gbaya; Northwest"
@ -9056,35 +9056,35 @@ msgstr "Gbaya; Nordoccidental"
#. name for gyb #. name for gyb
msgid "Garus" msgid "Garus"
msgstr "" msgstr "Garus"
#. name for gyd #. name for gyd
msgid "Kayardild" msgid "Kayardild"
msgstr "" msgstr "Gayardilt"
#. name for gye #. name for gye
msgid "Gyem" msgid "Gyem"
msgstr "" msgstr "Gyem"
#. name for gyf #. name for gyf
msgid "Gungabula" msgid "Gungabula"
msgstr "" msgstr "Gungabula"
#. name for gyg #. name for gyg
msgid "Gbayi" msgid "Gbayi"
msgstr "" msgstr "Gbayi"
#. name for gyi #. name for gyi
msgid "Gyele" msgid "Gyele"
msgstr "" msgstr "Gyele"
#. name for gyl #. name for gyl
msgid "Gayil" msgid "Gayil"
msgstr "" msgstr "Galila"
#. name for gym #. name for gym
msgid "Ngäbere" msgid "Ngäbere"
msgstr "" msgstr "Ngabere"
#. name for gyn #. name for gyn
msgid "Creole English; Guyanese" msgid "Creole English; Guyanese"
@ -9092,27 +9092,27 @@ msgstr "Creole English; Guyana"
#. name for gyr #. name for gyr
msgid "Guarayu" msgid "Guarayu"
msgstr "" msgstr "Guaraiú"
#. name for gyy #. name for gyy
msgid "Gunya" msgid "Gunya"
msgstr "" msgstr "Gunya"
#. name for gza #. name for gza
msgid "Ganza" msgid "Ganza"
msgstr "" msgstr "Ganza"
#. name for gzi #. name for gzi
msgid "Gazi" msgid "Gazi"
msgstr "" msgstr "Gazi"
#. name for gzn #. name for gzn
msgid "Gane" msgid "Gane"
msgstr "" msgstr "Gane"
#. name for haa #. name for haa
msgid "Han" msgid "Han"
msgstr "" msgstr "Han"
#. name for hab #. name for hab
msgid "Hanoi Sign Language" msgid "Hanoi Sign Language"
@ -9120,11 +9120,11 @@ msgstr "Llenguatge de signes de Hanoi"
#. name for hac #. name for hac
msgid "Gurani" msgid "Gurani"
msgstr "" msgstr "Hawrami"
#. name for had #. name for had
msgid "Hatam" msgid "Hatam"
msgstr "" msgstr "Hatam"
#. name for hae #. name for hae
msgid "Oromo; Eastern" msgid "Oromo; Eastern"
@ -9136,19 +9136,19 @@ msgstr "Llenguatge de signes Haipong"
#. name for hag #. name for hag
msgid "Hanga" msgid "Hanga"
msgstr "" msgstr "Hanga"
#. name for hah #. name for hah
msgid "Hahon" msgid "Hahon"
msgstr "" msgstr "Hahon"
#. name for hai #. name for hai
msgid "Haida" msgid "Haida"
msgstr "" msgstr "Haida"
#. name for haj #. name for haj
msgid "Hajong" msgid "Hajong"
msgstr "" msgstr "Hajong"
#. name for hak #. name for hak
msgid "Chinese; Hakka" msgid "Chinese; Hakka"
@ -9156,11 +9156,11 @@ msgstr "Xinès; Hakka"
#. name for hal #. name for hal
msgid "Halang" msgid "Halang"
msgstr "" msgstr "Halang"
#. name for ham #. name for ham
msgid "Hewa" msgid "Hewa"
msgstr "" msgstr "Hewa"
#. name for han #. name for han
msgid "Hangaza" msgid "Hangaza"
@ -18216,7 +18216,7 @@ msgstr ""
#. name for nhd #. name for nhd
msgid "Guaraní; Ava" msgid "Guaraní; Ava"
msgstr "" msgstr "Guaraní; Ava"
#. name for nhe #. name for nhe
msgid "Nahuatl; Eastern Huasteca" msgid "Nahuatl; Eastern Huasteca"
@ -22916,7 +22916,7 @@ msgstr ""
#. name for sgw #. name for sgw
msgid "Sebat Bet Gurage" msgid "Sebat Bet Gurage"
msgstr "" msgstr "Gurage; occidental"
#. name for sgx #. name for sgx
msgid "Sierra Leone Sign Language" msgid "Sierra Leone Sign Language"
@ -26588,7 +26588,7 @@ msgstr ""
#. name for ugb #. name for ugb
msgid "Kuku-Ugbanh" msgid "Kuku-Ugbanh"
msgstr "" msgstr "Kuku; Ugbanh"
#. name for uge #. name for uge
msgid "Ughele" msgid "Ughele"
@ -26984,7 +26984,7 @@ msgstr ""
#. name for uwa #. name for uwa
msgid "Kuku-Uwanh" msgid "Kuku-Uwanh"
msgstr "" msgstr "Kuku; Uwanh"
#. name for uya #. name for uya
msgid "Doko-Uyanga" msgid "Doko-Uyanga"
@ -27564,7 +27564,7 @@ msgstr ""
#. name for wec #. name for wec
msgid "Wè Western" msgid "Wè Western"
msgstr "" msgstr "We; occidental"
#. name for wed #. name for wed
msgid "Wedau" msgid "Wedau"
@ -27932,7 +27932,7 @@ msgstr ""
#. name for wob #. name for wob
msgid "Wè Northern" msgid "Wè Northern"
msgstr "" msgstr "We; septentrional"
#. name for woc #. name for woc
msgid "Wogeo" msgid "Wogeo"
@ -28716,7 +28716,7 @@ msgstr ""
#. name for xmh #. name for xmh
msgid "Kuku-Muminh" msgid "Kuku-Muminh"
msgstr "" msgstr "Kuku: Muminh"
#. name for xmj #. name for xmj
msgid "Majera" msgid "Majera"
@ -28744,11 +28744,11 @@ msgstr ""
#. name for xmp #. name for xmp
msgid "Kuku-Mu'inh" msgid "Kuku-Mu'inh"
msgstr "" msgstr "Kuku; Mu'inh"
#. name for xmq #. name for xmq
msgid "Kuku-Mangk" msgid "Kuku-Mangk"
msgstr "" msgstr "Kuku; Mangk"
#. name for xmr #. name for xmr
msgid "Meroitic" msgid "Meroitic"

View File

@ -9,13 +9,13 @@ msgstr ""
"Report-Msgid-Bugs-To: Debian iso-codes team <pkg-isocodes-" "Report-Msgid-Bugs-To: Debian iso-codes team <pkg-isocodes-"
"devel@lists.alioth.debian.org>\n" "devel@lists.alioth.debian.org>\n"
"POT-Creation-Date: 2011-09-27 14:31+0000\n" "POT-Creation-Date: 2011-09-27 14:31+0000\n"
"PO-Revision-Date: 2011-11-10 07:13+0000\n" "PO-Revision-Date: 2011-11-12 07:52+0000\n"
"Last-Translator: Devilinside <Unknown>\n" "Last-Translator: Devilinside <Unknown>\n"
"Language-Team: Hungarian <debian-l10n-hungarian@lists.d.o>\n" "Language-Team: Hungarian <debian-l10n-hungarian@lists.d.o>\n"
"MIME-Version: 1.0\n" "MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n" "Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n" "Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2011-11-11 04:52+0000\n" "X-Launchpad-Export-Date: 2011-11-13 05:48+0000\n"
"X-Generator: Launchpad (build 14277)\n" "X-Generator: Launchpad (build 14277)\n"
"X-Poedit-Country: HUNGARY\n" "X-Poedit-Country: HUNGARY\n"
"Language: hu\n" "Language: hu\n"
@ -4969,7 +4969,7 @@ msgstr ""
#. name for cha #. name for cha
msgid "Chamorro" msgid "Chamorro"
msgstr "chamorro" msgstr "csamorro"
#. name for chb #. name for chb
msgid "Chibcha" msgid "Chibcha"
@ -19625,7 +19625,7 @@ msgstr ""
#. name for oco #. name for oco
msgid "Cornish; Old" msgid "Cornish; Old"
msgstr "" msgstr "cornwalli; ócornwalli"
#. name for ocu #. name for ocu
msgid "Matlatzinca; Atzingo" msgid "Matlatzinca; Atzingo"

View File

@ -16,7 +16,7 @@ msgstr ""
"MIME-Version: 1.0\n" "MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n" "Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n" "Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2011-11-11 04:53+0000\n" "X-Launchpad-Export-Date: 2011-11-12 04:48+0000\n"
"X-Generator: Launchpad (build 14277)\n" "X-Generator: Launchpad (build 14277)\n"
"Language: tr\n" "Language: tr\n"

View File

@ -6,7 +6,7 @@ __copyright__ = '2009, Kovid Goyal <kovid@kovidgoyal.net>'
__docformat__ = 'restructuredtext en' __docformat__ = 'restructuredtext en'
import os, re, cStringIO, base64, httplib, subprocess, hashlib, shutil, time, \ import os, re, cStringIO, base64, httplib, subprocess, hashlib, shutil, time, \
glob, stat glob, stat, sys
from subprocess import check_call from subprocess import check_call
from tempfile import NamedTemporaryFile, mkdtemp from tempfile import NamedTemporaryFile, mkdtemp
from zipfile import ZipFile from zipfile import ZipFile
@ -58,6 +58,47 @@ class ReUpload(Command): # {{{
os.remove(x) os.remove(x)
# }}} # }}}
class ReadFileWithProgressReporting(file): # {{{
def __init__(self, path, mode='rb'):
file.__init__(self, path, mode)
self.seek(0, os.SEEK_END)
self._total = self.tell()
self.seek(0)
self.start_time = time.time()
def __len__(self):
return self._total
def read(self, size):
data = file.read(self, size)
if data:
self.report_progress(len(data))
return data
def report_progress(self, size):
sys.stdout.write(b'\x1b[s')
sys.stdout.write(b'\x1b[K')
frac = float(self.tell())/self._total
mb_pos = self.tell()/float(1024**2)
mb_tot = self._total/float(1024**2)
kb_pos = self.tell()/1024.0
kb_rate = kb_pos/(time.time()-self.start_time)
bit_rate = kb_rate * 1024
eta = int((self._total - self.tell())/bit_rate) + 1
eta_m, eta_s = eta / 60, eta % 60
sys.stdout.write(
' %.1f%% %.1f/%.1fMB %.1f KB/sec %d minutes, %d seconds left'%(
frac*100, mb_pos, mb_tot, kb_rate, eta_m, eta_s))
sys.stdout.write(b'\x1b[u')
if self.tell() >= self._total:
sys.stdout.write('\n')
t = int(time.time() - self.start_time) + 1
print ('Upload took %d minutes and %d seconds at %.1f KB/sec' % (
t/60, t%60, kb_rate))
sys.stdout.flush()
# }}}
class UploadToGoogleCode(Command): # {{{ class UploadToGoogleCode(Command): # {{{
USERNAME = 'kovidgoyal' USERNAME = 'kovidgoyal'
@ -92,7 +133,7 @@ class UploadToGoogleCode(Command): # {{{
self.upload_one(src) self.upload_one(src)
def upload_one(self, fname): def upload_one(self, fname):
self.info('Uploading', fname) self.info('\nUploading', fname)
typ = 'Type-' + ('Source' if fname.endswith('.gz') else 'Archive' if typ = 'Type-' + ('Source' if fname.endswith('.gz') else 'Archive' if
fname.endswith('.zip') else 'Installer') fname.endswith('.zip') else 'Installer')
ext = os.path.splitext(fname)[1][1:] ext = os.path.splitext(fname)[1][1:]
@ -102,7 +143,7 @@ class UploadToGoogleCode(Command): # {{{
start = time.time() start = time.time()
path = self.upload(os.path.abspath(fname), desc, path = self.upload(os.path.abspath(fname), desc,
labels=[typ, op, 'Featured']) labels=[typ, op, 'Featured'])
self.info('\tUploaded to:', path, 'in', int(time.time() - start), self.info('Uploaded to:', path, 'in', int(time.time() - start),
'seconds') 'seconds')
return path return path
@ -198,9 +239,8 @@ class UploadToGoogleCode(Command): # {{{
# Now add the file itself # Now add the file itself
file_name = os.path.basename(file_path) file_name = os.path.basename(file_path)
f = open(file_path, 'rb') with open(file_path, 'rb') as f:
file_content = f.read() file_content = f.read()
f.close()
body.extend( body.extend(
['--' + BOUNDARY, ['--' + BOUNDARY,
@ -230,10 +270,17 @@ class UploadToGoogleCode(Command): # {{{
'Content-Type': content_type, 'Content-Type': content_type,
} }
server = httplib.HTTPSConnection(self.UPLOAD_HOST) with NamedTemporaryFile(delete=False) as f:
server.request('POST', upload_uri, body, headers) f.write(body)
resp = server.getresponse()
server.close() try:
body = ReadFileWithProgressReporting(f.name)
server = httplib.HTTPSConnection(self.UPLOAD_HOST)
server.request('POST', upload_uri, body, headers)
resp = server.getresponse()
server.close()
finally:
os.remove(f.name)
if resp.status == 201: if resp.status == 201:
return resp.getheader('Location') return resp.getheader('Location')
@ -265,7 +312,7 @@ class UploadToSourceForge(Command): # {{{
if not os.path.exists(x): continue if not os.path.exists(x): continue
start = time.time() start = time.time()
self.info('Uploading', x) self.info('Uploading', x)
check_call(['rsync', '-v', '-e', 'ssh -x', x, check_call(['rsync', '-z', '--progress', '-e', 'ssh -x', x,
'%s,%s@frs.sourceforge.net:%s'%(self.USERNAME, self.PROJECT, '%s,%s@frs.sourceforge.net:%s'%(self.USERNAME, self.PROJECT,
self.rdir+'/')]) self.rdir+'/')])
print 'Uploaded in', int(time.time() - start), 'seconds' print 'Uploaded in', int(time.time() - start), 'seconds'
@ -376,7 +423,8 @@ class UploadUserManual(Command): # {{{
for x in glob.glob(self.j(path, '*')): for x in glob.glob(self.j(path, '*')):
self.build_plugin_example(x) self.build_plugin_example(x)
check_call(' '.join(['scp', '-r', 'src/calibre/manual/.build/html/*', check_call(' '.join(['rsync', '-z', '-r', '--progress',
'src/calibre/manual/.build/html/',
'bugs:%s'%USER_MANUAL]), shell=True) 'bugs:%s'%USER_MANUAL]), shell=True)
# }}} # }}}

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, 26) numeric_version = (0, 8, 27)
__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

@ -33,7 +33,7 @@ class IREXDR1000(USBMS):
MAIN_MEMORY_VOLUME_LABEL = 'IRex Digital Reader 1000 Main Memory' MAIN_MEMORY_VOLUME_LABEL = 'IRex Digital Reader 1000 Main Memory'
EBOOK_DIR_MAIN = 'ebooks' EBOOK_DIR_MAIN = ''
DELETE_EXTS = ['.mbp'] DELETE_EXTS = ['.mbp']
SUPPORTS_SUB_DIRS = True SUPPORTS_SUB_DIRS = True
@ -44,7 +44,7 @@ class IREXDR800(IREXDR1000):
WINDOWS_MAIN_MEM = 'DR800' WINDOWS_MAIN_MEM = 'DR800'
FORMATS = ['epub', 'pdb', 'html', 'pdf', 'txt'] FORMATS = ['epub', 'pdb', 'html', 'pdf', 'txt']
EBOOK_DIR_MAIN = 'Books' EBOOK_DIR_MAIN = ''
DELETE_EXTS = [] DELETE_EXTS = []
SUPPORTS_SUB_DIRS = True SUPPORTS_SUB_DIRS = True

View File

@ -388,11 +388,9 @@ class KINDLE_FIRE(KINDLE2):
EBOOK_DIR_MAIN = 'Documents' EBOOK_DIR_MAIN = 'Documents'
SUPPORTS_SUB_DIRS = False SUPPORTS_SUB_DIRS = False
SCAN_FROM_ROOT = True
def get_main_ebook_dir(self, for_upload=False): SUPPORTS_SUB_DIRS_FOR_SCAN = True
if for_upload: VENDOR_NAME = 'AMAZON'
return self.EBOOK_DIR_MAIN WINDOWS_MAIN_MEM = 'KINDLE'
return ''

View File

@ -81,12 +81,12 @@ class NOOK(USBMS):
return [x.replace('#', '_') for x in components] return [x.replace('#', '_') for x in components]
class NOOK_COLOR(NOOK): class NOOK_COLOR(NOOK):
description = _('Communicate with the Nook Color and TSR eBook readers.') description = _('Communicate with the Nook Color, TSR and Tablet eBook readers.')
PRODUCT_ID = [0x002, 0x003, 0x004] PRODUCT_ID = [0x002, 0x003, 0x004]
BCD = [0x216] BCD = [0x216]
WINDOWS_MAIN_MEM = WINDOWS_CARD_A_MEM = 'EBOOK_DISK' WINDOWS_MAIN_MEM = WINDOWS_CARD_A_MEM = ['EBOOK_DISK', 'NOOK_TABLET']
EBOOK_DIR_MAIN = 'My Files' EBOOK_DIR_MAIN = 'My Files'
NEWS_IN_FOLDER = False NEWS_IN_FOLDER = False

View File

@ -28,6 +28,8 @@ class DeviceConfig(object):
EXTRA_CUSTOMIZATION_DEFAULT = None EXTRA_CUSTOMIZATION_DEFAULT = None
SUPPORTS_SUB_DIRS = False SUPPORTS_SUB_DIRS = False
SUPPORTS_SUB_DIRS_FOR_SCAN = False # This setting is used when scanning for
# books when SUPPORTS_SUB_DIRS is False
MUST_READ_METADATA = False MUST_READ_METADATA = False
SUPPORTS_USE_AUTHOR_SORT = False SUPPORTS_USE_AUTHOR_SORT = False

View File

@ -202,7 +202,7 @@ class USBMS(CLI, Device):
debug_print('USBMS: scan from root', self.SCAN_FROM_ROOT, ebook_dir) debug_print('USBMS: scan from root', self.SCAN_FROM_ROOT, ebook_dir)
if not os.path.exists(ebook_dir): continue if not os.path.exists(ebook_dir): continue
# Get all books in the ebook_dir directory # Get all books in the ebook_dir directory
if self.SUPPORTS_SUB_DIRS: if self.SUPPORTS_SUB_DIRS or self.SUPPORTS_SUB_DIRS_FOR_SCAN:
# build a list of files to check, so we can accurately report progress # build a list of files to check, so we can accurately report progress
flist = [] flist = []
for path, dirs, files in os.walk(ebook_dir): for path, dirs, files in os.walk(ebook_dir):

View File

@ -6,11 +6,12 @@ Created on 4 Jun 2010
from base64 import b64encode, b64decode from base64 import b64encode, b64decode
import json, traceback import json, traceback
from datetime import datetime, time
from calibre.ebooks.metadata.book import SERIALIZABLE_FIELDS from calibre.ebooks.metadata.book import SERIALIZABLE_FIELDS
from calibre.constants import filesystem_encoding, preferred_encoding from calibre.constants import filesystem_encoding, preferred_encoding
from calibre.library.field_metadata import FieldMetadata from calibre.library.field_metadata import FieldMetadata
from calibre.utils.date import parse_date, isoformat, UNDEFINED_DATE from calibre.utils.date import parse_date, isoformat, UNDEFINED_DATE, local_tz
from calibre.utils.magick import Image from calibre.utils.magick import Image
from calibre import isbytestring from calibre import isbytestring
@ -22,7 +23,13 @@ def string_to_datetime(src):
return parse_date(src) return parse_date(src)
def datetime_to_string(dateval): def datetime_to_string(dateval):
if dateval is None or dateval == UNDEFINED_DATE: if dateval is None:
return "None"
if not isinstance(dateval, datetime):
dateval = datetime.combine(dateval, time())
if hasattr(dateval, 'tzinfo') and dateval.tzinfo is None:
dateval = dateval.replace(tzinfo=local_tz)
if dateval <= UNDEFINED_DATE:
return "None" return "None"
return isoformat(dateval) return isoformat(dateval)

View File

@ -16,6 +16,7 @@ from calibre.ebooks.BeautifulSoup import BeautifulSoup
from calibre.ebooks.oeb.base import XPath, XHTML_NS, XHTML from calibre.ebooks.oeb.base import XPath, XHTML_NS, XHTML
from calibre.library.comments import comments_to_html from calibre.library.comments import comments_to_html
from calibre.utils.date import is_date_undefined from calibre.utils.date import is_date_undefined
from calibre.ebooks.chardet import strip_encoding_declarations
JACKET_XPATH = '//h:meta[@name="calibre-content" and @content="jacket"]' JACKET_XPATH = '//h:meta[@name="calibre-content" and @content="jacket"]'
@ -175,15 +176,20 @@ def render_jacket(mi, output_profile,
try: try:
display_name, val = mi.format_field_extended(key)[:2] display_name, val = mi.format_field_extended(key)[:2]
key = key.replace('#', '_') key = key.replace('#', '_')
args[key] = val args[key] = escape(val)
args[key+'_label'] = display_name args[key+'_label'] = escape(display_name)
except: except:
pass pass
# Used in the comment describing use of custom columns in templates
args['_genre_label'] = args.get('_genre_label', '{_genre_label}')
args['_genre'] = args.get('_genre', '{_genre}')
generated_html = P('jacket/template.xhtml', generated_html = P('jacket/template.xhtml',
data=True).decode('utf-8').format(**args) data=True).decode('utf-8').format(**args)
# Post-process the generated html to strip out empty header items # Post-process the generated html to strip out empty header items
soup = BeautifulSoup(generated_html) soup = BeautifulSoup(generated_html)
if not series: if not series:
series_tag = soup.find(attrs={'class':'cbj_series'}) series_tag = soup.find(attrs={'class':'cbj_series'})
@ -206,7 +212,8 @@ def render_jacket(mi, output_profile,
if hr_tag is not None: if hr_tag is not None:
hr_tag.extract() hr_tag.extract()
return soup.renderContents(None) return strip_encoding_declarations(
soup.renderContents('utf-8').decode('utf-8'))
from calibre.ebooks.oeb.base import RECOVER_PARSER from calibre.ebooks.oeb.base import RECOVER_PARSER

View File

@ -23,6 +23,8 @@ from calibre.utils.icu import sort_key, capitalize
from calibre.utils.config import prefs, tweaks from calibre.utils.config import prefs, tweaks
from calibre.utils.magick.draw import identify_data from calibre.utils.magick.draw import identify_data
from calibre.utils.date import qt_to_dt from calibre.utils.date import qt_to_dt
from calibre.ptempfile import SpooledTemporaryFile
from calibre.db import SPOOL_SIZE
def get_cover_data(stream, ext): # {{{ def get_cover_data(stream, ext): # {{{
from calibre.ebooks.metadata.meta import get_metadata from calibre.ebooks.metadata.meta import get_metadata
@ -134,11 +136,12 @@ class MyBlockingBusy(QDialog): # {{{
do_autonumber, do_remove_format, remove_format, do_swap_ta, \ do_autonumber, do_remove_format, remove_format, do_swap_ta, \
do_remove_conv, do_auto_author, series, do_series_restart, \ do_remove_conv, do_auto_author, series, do_series_restart, \
series_start_value, do_title_case, cover_action, clear_series, \ series_start_value, do_title_case, cover_action, clear_series, \
pubdate, adddate, do_title_sort, languages, clear_languages = self.args pubdate, adddate, do_title_sort, languages, clear_languages, \
restore_original = self.args
# first loop: do author and title. These will commit at the end of each # first loop: All changes that modify the filesystem and commit
# operation, because each operation modifies the file system. We want to # immediately. We want to
# try hard to keep the DB and the file system in sync, even in the face # try hard to keep the DB and the file system in sync, even in the face
# of exceptions or forced exits. # of exceptions or forced exits.
if self.current_phase == 1: if self.current_phase == 1:
@ -196,6 +199,27 @@ class MyBlockingBusy(QDialog): # {{{
if covers: if covers:
self.db.set_cover(id, covers[-1][0]) self.db.set_cover(id, covers[-1][0])
covers = [] covers = []
if do_remove_format:
self.db.remove_format(id, remove_format, index_is_id=True,
notify=False, commit=True)
if restore_original:
formats = self.db.formats(id, index_is_id=True)
formats = formats.split(',') if formats else []
originals = [x.upper() for x in formats if
x.upper().startswith('ORIGINAL_')]
for ofmt in originals:
fmt = ofmt.replace('ORIGINAL_', '')
with SpooledTemporaryFile(SPOOL_SIZE) as stream:
self.db.copy_format_to(id, ofmt, stream,
index_is_id=True)
stream.seek(0)
self.db.add_format(id, fmt, stream, index_is_id=True,
notify=False)
self.db.remove_format(id, ofmt, index_is_id=True,
notify=False, commit=True)
elif self.current_phase == 2: elif self.current_phase == 2:
# All of these just affect the DB, so we can tolerate a total rollback # All of these just affect the DB, so we can tolerate a total rollback
if do_auto_author: if do_auto_author:
@ -233,9 +257,6 @@ class MyBlockingBusy(QDialog): # {{{
num = next if do_autonumber and series else 1.0 num = next if do_autonumber and series else 1.0
self.db.set_series_index(id, num, notify=False, commit=False) self.db.set_series_index(id, num, notify=False, commit=False)
if do_remove_format:
self.db.remove_format(id, remove_format, index_is_id=True, notify=False, commit=False)
if do_remove_conv: if do_remove_conv:
self.db.delete_conversion_options(id, 'PIPE', commit=False) self.db.delete_conversion_options(id, 'PIPE', commit=False)
@ -351,13 +372,13 @@ class MetadataBulkDialog(ResizableDialog, Ui_MetadataBulkDialog):
self.apply_pubdate.setChecked(True) self.apply_pubdate.setChecked(True)
def clear_pubdate(self, *args): def clear_pubdate(self, *args):
self.pubdate.setMinimumDateTime(UNDEFINED_QDATETIME) self.pubdate.setDateTime(UNDEFINED_QDATETIME)
def do_apply_adddate(self, *args): def do_apply_adddate(self, *args):
self.apply_adddate.setChecked(True) self.apply_adddate.setChecked(True)
def clear_adddate(self, *args): def clear_adddate(self, *args):
self.adddate.setMinimumDateTime(UNDEFINED_QDATETIME) self.adddate.setDateTime(UNDEFINED_QDATETIME)
def button_clicked(self, which): def button_clicked(self, which):
if which == self.button_box.button(QDialogButtonBox.Apply): if which == self.button_box.button(QDialogButtonBox.Apply):
@ -936,6 +957,7 @@ class MetadataBulkDialog(ResizableDialog, Ui_MetadataBulkDialog):
do_title_case = self.change_title_to_title_case.isChecked() do_title_case = self.change_title_to_title_case.isChecked()
do_title_sort = self.update_title_sort.isChecked() do_title_sort = self.update_title_sort.isChecked()
clear_languages = self.clear_languages.isChecked() clear_languages = self.clear_languages.isChecked()
restore_original = self.restore_original.isChecked()
languages = self.languages.lang_codes languages = self.languages.lang_codes
pubdate = adddate = None pubdate = adddate = None
if self.apply_pubdate.isChecked(): if self.apply_pubdate.isChecked():
@ -955,7 +977,8 @@ class MetadataBulkDialog(ResizableDialog, Ui_MetadataBulkDialog):
do_autonumber, do_remove_format, remove_format, do_swap_ta, do_autonumber, do_remove_format, remove_format, do_swap_ta,
do_remove_conv, do_auto_author, series, do_series_restart, do_remove_conv, do_auto_author, series, do_series_restart,
series_start_value, do_title_case, cover_action, clear_series, series_start_value, do_title_case, cover_action, clear_series,
pubdate, adddate, do_title_sort, languages, clear_languages) pubdate, adddate, do_title_sort, languages, clear_languages,
restore_original)
bb = MyBlockingBusy(_('Applying changes to %d books.\nPhase {0} {1}%%.') bb = MyBlockingBusy(_('Applying changes to %d books.\nPhase {0} {1}%%.')
%len(self.ids), args, self.db, self.ids, %len(self.ids), args, self.db, self.ids,

View File

@ -14,7 +14,7 @@
<string>Edit Meta information</string> <string>Edit Meta information</string>
</property> </property>
<property name="windowIcon"> <property name="windowIcon">
<iconset resource="../../../work/calibre/resources/images.qrc"> <iconset resource="../../../../resources/images.qrc">
<normaloff>:/images/edit_input.png</normaloff>:/images/edit_input.png</iconset> <normaloff>:/images/edit_input.png</normaloff>:/images/edit_input.png</iconset>
</property> </property>
<layout class="QGridLayout" name="gridLayout_2"> <layout class="QGridLayout" name="gridLayout_2">
@ -210,7 +210,7 @@
<string>Open Tag Editor</string> <string>Open Tag Editor</string>
</property> </property>
<property name="icon"> <property name="icon">
<iconset resource="../../../work/calibre/resources/images.qrc"> <iconset resource="../../../../resources/images.qrc">
<normaloff>:/images/chapters.png</normaloff>:/images/chapters.png</iconset> <normaloff>:/images/chapters.png</normaloff>:/images/chapters.png</iconset>
</property> </property>
</widget> </widget>
@ -381,7 +381,7 @@ from the value in the box</string>
<string>...</string> <string>...</string>
</property> </property>
<property name="icon"> <property name="icon">
<iconset resource="../../../work/calibre/resources/images.qrc"> <iconset resource="../../../../resources/images.qrc">
<normaloff>:/images/trash.png</normaloff>:/images/trash.png</iconset> <normaloff>:/images/trash.png</normaloff>:/images/trash.png</iconset>
</property> </property>
</widget> </widget>
@ -429,7 +429,7 @@ from the value in the box</string>
<string>...</string> <string>...</string>
</property> </property>
<property name="icon"> <property name="icon">
<iconset resource="../../../work/calibre/resources/images.qrc"> <iconset resource="../../../../resources/images.qrc">
<normaloff>:/images/trash.png</normaloff>:/images/trash.png</iconset> <normaloff>:/images/trash.png</normaloff>:/images/trash.png</iconset>
</property> </property>
</widget> </widget>
@ -443,7 +443,30 @@ from the value in the box</string>
</property> </property>
</widget> </widget>
</item> </item>
<item row="13" column="0"> <item row="11" column="0">
<widget class="QLabel" name="label_11">
<property name="text">
<string>&amp;Languages:</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
<property name="buddy">
<cstring>languages</cstring>
</property>
</widget>
</item>
<item row="11" column="1">
<widget class="LanguagesEdit" name="languages"/>
</item>
<item row="11" column="2">
<widget class="QCheckBox" name="clear_languages">
<property name="text">
<string>Remove &amp;all</string>
</property>
</widget>
</item>
<item row="12" column="0">
<widget class="QLabel" name="label_5"> <widget class="QLabel" name="label_5">
<property name="text"> <property name="text">
<string>Remove &amp;format:</string> <string>Remove &amp;format:</string>
@ -453,17 +476,44 @@ from the value in the box</string>
</property> </property>
</widget> </widget>
</item> </item>
<item row="13" column="1"> <item row="12" column="1">
<widget class="QComboBox" name="remove_format"> <layout class="QHBoxLayout" name="horizontalLayout_7">
<property name="maximumSize"> <item>
<size> <widget class="QComboBox" name="remove_format">
<width>120</width> <property name="maximumSize">
<height>16777215</height> <size>
</size> <width>120</width>
</property> <height>16777215</height>
</widget> </size>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_4">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QCheckBox" name="restore_original">
<property name="toolTip">
<string>When doing a same format to same format conversion, for e.g., EPUB to EPUB, calibre saves the original EPUB as ORIGINAL_EPUB. This option tells calibre to restore the EPUB from ORIGINAL_EPUB. Useful if you did a bulk conversion of a large number of books and something went wrong.</string>
</property>
<property name="text">
<string>Restore pre conversion &amp;originals, if available</string>
</property>
</widget>
</item>
</layout>
</item> </item>
<item row="14" column="0"> <item row="13" column="0">
<spacer name="verticalSpacer"> <spacer name="verticalSpacer">
<property name="orientation"> <property name="orientation">
<enum>Qt::Vertical</enum> <enum>Qt::Vertical</enum>
@ -479,7 +529,7 @@ from the value in the box</string>
</property> </property>
</spacer> </spacer>
</item> </item>
<item row="15" column="0" colspan="3"> <item row="14" column="0" colspan="2">
<layout class="QHBoxLayout" name="horizontalLayout_3"> <layout class="QHBoxLayout" name="horizontalLayout_3">
<item> <item>
<widget class="QCheckBox" name="change_title_to_title_case"> <widget class="QCheckBox" name="change_title_to_title_case">
@ -529,7 +579,7 @@ Future conversion of these books will use the default settings.</string>
</item> </item>
</layout> </layout>
</item> </item>
<item row="16" column="0" colspan="3"> <item row="15" column="0" colspan="2">
<widget class="QGroupBox" name="groupBox"> <widget class="QGroupBox" name="groupBox">
<property name="title"> <property name="title">
<string>Change &amp;cover</string> <string>Change &amp;cover</string>
@ -559,7 +609,7 @@ Future conversion of these books will use the default settings.</string>
</layout> </layout>
</widget> </widget>
</item> </item>
<item row="17" column="0"> <item row="16" column="0">
<spacer name="verticalSpacer_2"> <spacer name="verticalSpacer_2">
<property name="orientation"> <property name="orientation">
<enum>Qt::Vertical</enum> <enum>Qt::Vertical</enum>
@ -572,29 +622,6 @@ Future conversion of these books will use the default settings.</string>
</property> </property>
</spacer> </spacer>
</item> </item>
<item row="11" column="0">
<widget class="QLabel" name="label_11">
<property name="text">
<string>&amp;Languages:</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
<property name="buddy">
<cstring>languages</cstring>
</property>
</widget>
</item>
<item row="11" column="1">
<widget class="LanguagesEdit" name="languages"/>
</item>
<item row="11" column="2">
<widget class="QCheckBox" name="clear_languages">
<property name="text">
<string>Remove &amp;all</string>
</property>
</widget>
</item>
</layout> </layout>
</widget> </widget>
<widget class="QWidget" name="tab"> <widget class="QWidget" name="tab">
@ -1199,13 +1226,13 @@ not multiple and the destination field is multiple</string>
<tabstop>languages</tabstop> <tabstop>languages</tabstop>
<tabstop>clear_languages</tabstop> <tabstop>clear_languages</tabstop>
<tabstop>remove_format</tabstop> <tabstop>remove_format</tabstop>
<tabstop>restore_original</tabstop>
<tabstop>change_title_to_title_case</tabstop> <tabstop>change_title_to_title_case</tabstop>
<tabstop>update_title_sort</tabstop> <tabstop>update_title_sort</tabstop>
<tabstop>remove_conversion_settings</tabstop> <tabstop>remove_conversion_settings</tabstop>
<tabstop>cover_generate</tabstop> <tabstop>cover_generate</tabstop>
<tabstop>cover_remove</tabstop> <tabstop>cover_remove</tabstop>
<tabstop>cover_from_fmt</tabstop> <tabstop>cover_from_fmt</tabstop>
<tabstop>starting_from</tabstop>
<tabstop>multiple_separator</tabstop> <tabstop>multiple_separator</tabstop>
<tabstop>test_text</tabstop> <tabstop>test_text</tabstop>
<tabstop>test_result</tabstop> <tabstop>test_result</tabstop>
@ -1229,9 +1256,10 @@ not multiple and the destination field is multiple</string>
<tabstop>destination_field</tabstop> <tabstop>destination_field</tabstop>
<tabstop>search_for</tabstop> <tabstop>search_for</tabstop>
<tabstop>case_sensitive</tabstop> <tabstop>case_sensitive</tabstop>
<tabstop>starting_from</tabstop>
</tabstops> </tabstops>
<resources> <resources>
<include location="../../../work/calibre/resources/images.qrc"/> <include location="../../../../resources/images.qrc"/>
</resources> </resources>
<connections> <connections>
<connection> <connection>

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -291,6 +291,11 @@ def clean_date_for_sort(dt, format):
if not isinstance(dt, datetime): if not isinstance(dt, datetime):
dt = datetime.combine(dt, time()) dt = datetime.combine(dt, time())
if hasattr(dt, 'tzinfo'):
if dt.tzinfo is None:
dt = dt.replace(tzinfo=_local_tz)
dt = as_local_time(dt)
if format == 'iso': if format == 'iso':
format = 'yyMdhms' format = 'yyMdhms'