0.7.28 update

This commit is contained in:
GRiker 2010-11-12 15:18:45 -07:00
commit 62e398a3e8
43 changed files with 21945 additions and 13701 deletions

View File

@ -4,6 +4,100 @@
# for important features/bug fixes.
# Also, each release can have new and improved recipes.
- version: 0.7.28
date: 2010-11-12
new features:
- title: "Update the version of the grahical toolkit (Qt 4.7.1) used in the calibre binary builds on windows and linux. This should result in a significant speed up for the calibre ebook viewer"
- title: "Driver for Nook Color, Eken M001"
- title: "Add a tweak to turn off double clicking to open viewer"
- title: "Catalog generation: Add indication when a book has no formats"
tickets: [7376]
- title: "Advanced search dialog: Add a tab to allow searching particular metadata fields easily"
- title: "Conversion pipeline: When using the Level x Table of Contents expressions, if a tag is empty but has a non-empty title attribute, use that instead of ignoring the tag"
bug fixes:
- title: "Comic metadata reader: Sort filenames aplhabetically when choosing an image for the cover"
tickets: [7488]
- title: "Bulk convert dialog: Hide useless restore defaults button."
tickets: [7471]
- title: "Conversion pipeline: Handle input documents that encode null bytes as HTML entities correctly"
tickets: [7355]
- title: "Fix some SONY readers not being detected on windows"
tickets: [7413]
- title: "MOBI Input: Fix images missing when converting MOBI news downloads created with Mobipocket reader"
tickets: [7455]
- title: "ODT Input: Handle hyperlinks to headings that have truncated destination specifiers correctly"
tickets: [7506]
- title: "Sony driver: Ignore invalid strings when updating XML database"
- title: "Content Server: Add day to displayed date in /mobile book listing"
- title: "MOBI Input: Do not generate filenames with only extensions if the MOBI file has no internal name"
tickets: [7481]
- title: "MOBI Input: Handle files that has the record sizes set incorrectly to a long integer"
tickets: [7472]
- title: "Fix not enough vertical space for text in the preferences dialog category listing"
- title: "Remove 'sort' from Search and replace destination fields and add it to source fields. S&R is no longer marked experimental"
- title: "Edit metadata dialog: Save dialog geometry on reject as well as on accept"
- title: "E-book viewer: Fix clicking entries in TOC that point to the currently loaded flow not scrolling view to the top of the document"
- title: "Fix bug in regex used to extract charset from <meta> tags"
- title: "MOBI Output: Add support for the <q> tag"
improved recipes:
- Zeit Online
- Gamespot Review
- Ploitika
- Pagina12
- Irish Times
- elektrolese
new recipes:
- title: "Handelsblatt and European Voice"
author: "malfi"
- title: "Polityka and Newsweek"
author: "Mateusz Kielar"
- title: "MarcTV"
author: "Marc Toensings"
- title: "Rolling Stone"
author: "Darko Miletic"
- title: "Vedomosti"
author: "Nikolai Kotchetkov"
- title: "Hola.com"
author: "bmsleight"
- title: "Dnevnik, Siol.net, MMC-RTV and Avto-magazon"
author: "BlonG"
- title: "SC Print Magazine"
author: "Tony Maro"
- title: "Diario Sport"
author: "Jefferson Frantz"
- version: 0.7.27
date: 2010-11-05

View File

@ -0,0 +1,61 @@
import re
from calibre.web.feeds.news import BasicNewsRecipe
class deredactie(BasicNewsRecipe):
title = u'Deredactie.be'
oldest_article = 7
max_articles_per_feed = 100
no_stylesheets = True
cover_url = 'http://www.deredactie.be/polopoly_fs/1.510827!image/2710428628.gif'
language = 'de'
keep_only_tags = []
__author__ = 'malfi'
keep_only_tags.append(dict(name = 'div', attrs = {'id': 'articlehead'}))
keep_only_tags.append(dict(name = 'div', attrs = {'id': 'articlebody'}))
remove_tags = []
remove_tags.append(dict(name = 'div', attrs = {'id': 'story'}))
remove_tags.append(dict(name = 'div', attrs = {'id': 'useractions'}))
remove_tags.append(dict(name = 'hr'))
extra_css = '''
h1{font-family:Arial,Helvetica,sans-serif; font-weight:bold;font-size:large;}
h2{font-family:Arial,Helvetica,sans-serif; font-weight:normal;font-size:small;}
p{font-family:Arial,Helvetica,sans-serif;font-size:small;}
body{font-family:Helvetica,Arial,sans-serif;font-size:small;}
'''
def parse_index(self):
categories = []
catnames = {}
soup = self.index_to_soup('http://www.deredactie.be/cm/vrtnieuws.deutsch')
for elem in soup.findAll('li', attrs={'id' : re.compile("^navItem[2-9]") }):
a = elem.find('a', href=True)
m = re.search('(?<=/)[^/]*$', a['href'])
cat = str(m.group(0))
categories.append(cat)
catnames[cat] = a['title']
self.log("found cat %s\n" % catnames[cat])
feeds = []
for cat in categories:
articles = []
soup = self.index_to_soup('http://www.deredactie.be/cm/vrtnieuws.deutsch/'+cat)
for a in soup.findAll('a',attrs={'href' : re.compile("deutsch.*/[0-9][0-9][0-9][0-9][0-9][0-9]_")}):
skip_this_article = False
url = a['href'].strip()
if url.startswith('/'):
url = 'http://www.deredactie.be' + url
myarticle=({'title':self.tag_to_string(a), 'url':url, 'description':'', 'date':''})
for article in articles :
if article['url'] == url :
skip_this_article = True
self.log("SKIPPING DUP %s" % url)
break
if skip_this_article :
continue;
articles.append(myarticle)
self.log("Adding URL %s\n" %url)
if articles:
feeds.append((catnames[cat], articles))
return feeds

View File

@ -1,5 +1,5 @@
__license__ = 'GPL v3'
__author__ = u'Marc T\xf6nsing'
__author__ = u'Marc Toensing'
from calibre.web.feeds.news import BasicNewsRecipe
@ -17,6 +17,7 @@ class GamespotCom(BasicNewsRecipe):
no_javascript = True
feeds = [
('All Reviews', 'http://www.gamespot.com/rss/game_updates.php?type=5'),
('PC Reviews', 'http://www.gamespot.com/rss/game_updates.php?type=5&platform=5'),
('XBOX 360 Reviews', 'http://www.gamespot.com/rss/game_updates.php?type=5&platform=1029'),
('Wii Reviews', 'http://www.gamespot.com/rss/game_updates.php?type=5&platform=1031'),
@ -37,5 +38,3 @@ class GamespotCom(BasicNewsRecipe):
def get_article_url(self, article):
return article.get('link') + '?print=1'

View File

@ -0,0 +1,41 @@
import re
from calibre.web.feeds.news import BasicNewsRecipe
class Handelsblatt(BasicNewsRecipe):
title = u'Handelsblatt'
__author__ = 'malfi'
oldest_article = 7
max_articles_per_feed = 100
no_stylesheets = True
cover_url = 'http://www.handelsblatt.com/images/logo/logo_handelsblatt.com.png'
language = 'de'
keep_only_tags = []
keep_only_tags.append(dict(name = 'div', attrs = {'class': 'structOneCol'}))
keep_only_tags.append(dict(name = 'div', attrs = {'id': 'fullText'}))
remove_tags = [dict(name='img', attrs = {'src': 'http://www.handelsblatt.com/images/icon/loading.gif'})]
feeds = [
(u'Handelsblatt Exklusiv',u'http://www.handelsblatt.com/rss/exklusiv'),
(u'Handelsblatt Top-Themen',u'http://www.handelsblatt.com/rss/top-themen'),
(u'Handelsblatt Schlagzeilen',u'http://www.handelsblatt.com/rss/ticker/'),
(u'Handelsblatt Finanzen',u'http://www.handelsblatt.com/rss/finanzen/'),
(u'Handelsblatt Unternehmen',u'http://www.handelsblatt.com/rss/unternehmen/'),
(u'Handelsblatt Politik',u'http://www.handelsblatt.com/rss/politik/'),
(u'Handelsblatt Technologie',u'http://www.handelsblatt.com/rss/technologie/'),
(u'Handelsblatt Meinung',u'http://www.handelsblatt.com/rss/meinung'),
(u'Handelsblatt Magazin',u'http://www.handelsblatt.com/rss/magazin/'),
(u'Handelsblatt Weblogs',u'http://www.handelsblatt.com/rss/blogs')
]
extra_css = '''
h1{font-family:Arial,Helvetica,sans-serif; font-weight:bold;font-size:large;}
h2{font-family:Arial,Helvetica,sans-serif; font-weight:normal;font-size:small;}
p{font-family:Arial,Helvetica,sans-serif;font-size:small;}
body{font-family:Helvetica,Arial,sans-serif;font-size:small;}
'''
def print_version(self, url):
m = re.search('(?<=;)[0-9]*', url)
return u'http://www.handelsblatt.com/_b=' + str(m.group(0)) + ',_p=21,_t=ftprint,doc_page=0;printpage'

View File

@ -0,0 +1,35 @@
__license__ = 'GPL v3'
__copyright__ = '2008, Kovid Goyal <kovid at kovidgoyal.net>'
'''
Fetch MarcTV.
'''
from calibre.web.feeds.news import BasicNewsRecipe
class MarcTVde(BasicNewsRecipe):
title = 'Marc Toensings Visionen'
description = 'Marc Toensings Visionen'
language = 'de'
__author__ = 'Marc Toensing'
max_articles_per_feed = 40
oldest_article = 665
use_embedded_content = False
remove_tags = []
keep_only_tags = dict(name='div', attrs={'class':["content"]})
feeds = [(u'Spiele', u'http://feeds.feedburner.com/marctv/spiele'), (u'Leben', u'http://feeds.feedburner.com/marctv/leben'), (u'Medien', u'http://feeds.feedburner.com/marctv/medien')]
extra_css = '.#wrapper .entry p img{width:620px; height: 270px;}'
def get_cover_url(self):
return 'http://marctv.de/marctv.png'

View File

@ -0,0 +1,68 @@
#!/usr/bin/env python
__license__ = 'GPL v3'
__copyright__ = '2010, Mateusz Kielar, matek09@gmail.com'
from calibre.web.feeds.news import BasicNewsRecipe
class Newsweek(BasicNewsRecipe):
EDITION = 0
title = u'Newsweek Polska'
__author__ = 'Mateusz Kielar'
description = 'Weekly magazine'
encoding = 'utf-8'
no_stylesheets = True
language = 'en'
remove_javascript = True
keep_only_tags =[]
keep_only_tags.append(dict(name = 'div', attrs = {'class' : 'article'}))
remove_tags =[]
remove_tags.append(dict(name = 'div', attrs = {'class' : 'copy'}))
remove_tags.append(dict(name = 'div', attrs = {'class' : 'url'}))
extra_css = '''
.body {font-size: small}
.author {font-size: x-small}
.lead {font-size: x-small}
.title{font-size: x-large; font-weight: bold}
'''
def print_version(self, url):
return url.replace("http://www.newsweek.pl/artykuly/wydanie/" + str(self.EDITION), "http://www.newsweek.pl/artykuly") + '/print'
def find_last_full_issue(self):
page = self.index_to_soup('http://www.newsweek.pl/Frames/IssueCover.aspx')
issue = 'http://www.newsweek.pl/Frames/' + page.find(lambda tag: tag.name == 'span' and not tag.attrs).a['href']
page = self.index_to_soup(issue)
issue = 'http://www.newsweek.pl/Frames/' + page.find(lambda tag: tag.name == 'span' and not tag.attrs).a['href']
page = self.index_to_soup(issue)
self.EDITION = page.find('a', attrs={'target' : '_parent'})['href'].replace('/wydania/','')
def parse_index(self):
self.find_last_full_issue()
soup = self.index_to_soup('http://www.newsweek.pl/wydania/' + str(self.EDITION))
img = soup.find('img', id="ctl00_C1_PaperIsssueView_IssueImage", src=True)
self.cover_url = img['src']
feeds = []
parent = soup.find(id='content-left-big')
for txt in parent.findAll(attrs={'class':'txt_normal_red strong'}):
section = self.tag_to_string(txt).capitalize()
articles = list(self.find_articles(txt))
feeds.append((section, articles))
return feeds
def find_articles(self, txt):
for a in txt.findAllNext( attrs={'class':['strong','hr']}):
if a.name in "div":
break
yield {
'title' : self.tag_to_string(a),
'url' : 'http://www.newsweek.pl'+a['href'],
'date' : '',
'description' : ''
}

View File

@ -1,13 +1,10 @@
#!/usr/bin/env python
__license__ = 'GPL v3'
__copyright__ = '2008-2009, Darko Miletic <darko.miletic at gmail.com>'
__copyright__ = '2008-2010, Darko Miletic <darko.miletic at gmail.com>'
'''
politika.rs
'''
import re
from calibre.web.feeds.news import BasicNewsRecipe
from calibre.ebooks.BeautifulSoup import Tag
class Politika(BasicNewsRecipe):
title = 'Politika Online'
@ -19,53 +16,51 @@ class Politika(BasicNewsRecipe):
max_articles_per_feed = 100
no_stylesheets = True
use_embedded_content = False
remove_javascript = True
encoding = 'utf8'
delay = 1
language = 'sr'
lang = 'sr-Latn-RS'
direction = 'ltr'
extra_css = '@font-face {font-family: "serif1";src:url(res:///opt/sony/ebook/FONT/tt0011m_.ttf)} @font-face {font-family: "sans1";src:url(res:///opt/sony/ebook/FONT/tt0003m_.ttf)} body{font-family: serif1, serif} .article_description{font-family: sans1, sans-serif}'
publication_type = 'newspaper'
masthead_url = 'http://static.politika.co.rs/images_new/politika.gif'
extra_css = """
@font-face {font-family: "serif1";src:url(res:///opt/sony/ebook/FONT/tt0011m_.ttf)}
@font-face {font-family: "sans1";src:url(res:///opt/sony/ebook/FONT/tt0003m_.ttf)}
body{font-family: Arial,Helvetica,sans1,sans-serif}
h1{font-family: "Times New Roman",Times,serif1,serif}
.articledescription{font-family: sans1, sans-serif}
"""
conversion_options = {
'comment' : description
, 'tags' : category
, 'publisher' : publisher
, 'language' : lang
, 'pretty_print' : True
, 'language' : language
}
preprocess_regexps = [(re.compile(u'\u0110'), lambda match: u'\u00D0')]
keep_only_tags = [dict(name='div', attrs={'class':'content_center_border'})]
remove_tags = [
dict(name='div', attrs={'class':['send_print','txt-komentar']})
,dict(name=['object','link','a'])
,dict(name='h1', attrs={'class':'box_header-tags'})
]
keep_only_tags = [dict(name='div', attrs={'class':'big_article_home item_details'})]
remove_tags_after = dict(attrs={'class':'online_date'})
remove_tags = [dict(name=['link','meta','iframe','embed','object'])]
feeds = [
(u'Politika' , u'http://www.politika.rs/rubrike/Politika/index.1.lt.xml' )
,(u'Svet' , u'http://www.politika.rs/rubrike/Svet/index.1.lt.xml' )
,(u'Redakcijski komentari', u'http://www.politika.rs/rubrike/redakcijski-komentari/index.1.lt.xml')
,(u'Ostali komentari' , u'http://www.politika.rs/rubrike/ostali-komentari/index.1.lt.xml' )
,(u'Pogledi' , u'http://www.politika.rs/pogledi/index.lt.xml' )
,(u'Pogledi sa strane', u'http://www.politika.rs/rubrike/Pogledi-sa-strane/index.1.lt.xml')
,(u'Tema dana' , u'http://www.politika.rs/rubrike/tema-dana/index.1.lt.xml' )
,(u'Kultura' , u'http://www.politika.rs/rubrike/Kultura/index.1.lt.xml' )
,(u'Zivot i stil' , u'http://www.politika.rs/rubrike/zivot-i-stil/index.1.lt.xml' )
,(u'Spektar' , u'http://www.politika.rs/rubrike/zivot-i-stil/index.1.lt.xml' )
]
def preprocess_html(self, soup):
soup.html['lang'] = self.lang
soup.html['dir' ] = self.direction
mlang = Tag(soup,'meta',[("http-equiv","Content-Language"),("content",self.lang)])
soup.head.insert(0,mlang)
for item in soup.findAll(style=True):
del item['style']
ftag = soup.find('div',attrs={'class':'content_center_border'})
if ftag.has_key('align'):
del ftag['align']
return self.adeify_images(soup)
for item in soup.findAll('a', attrs={'class':'category'}):
item.name='span'
if item.has_key('href'):
del item['href']
if item.has_key('title'):
del item['title']
return soup

View File

@ -0,0 +1,68 @@
#!/usr/bin/env python
__license__ = 'GPL v3'
__copyright__ = '2010, Mateusz Kielar, matek09@gmail.com'
from calibre.web.feeds.news import BasicNewsRecipe
class Polityka(BasicNewsRecipe):
title = u'Polityka'
__author__ = 'Mateusz Kielar'
description = 'Weekly magazine. Last archive issue'
encoding = 'utf-8'
no_stylesheets = True
language = 'en'
remove_javascript = True
remove_tags_before = dict(dict(name = 'h2', attrs = {'class' : 'box_nag'}))
remove_tags_after = dict(dict(name = 'div', attrs = {'class' : 'box_footer'}))
remove_tags =[]
remove_tags.append(dict(name = 'h2', attrs = {'class' : 'box_nag'}))
remove_tags.append(dict(name = 'div', attrs = {'class' : 'box_footer'}))
extra_css = '''
h1 {font-size: x-large; font-weight: bold}
'''
def parse_index(self):
soup = self.index_to_soup('http://archiwum.polityka.pl/')
box_img3 = soup.findAll(attrs={'class' : 'box_img3'})
feeds = []
last = 0
self.cover_url = 'http://archiwum.polityka.pl' + box_img3[-1].find('img')['src']
last_edition = 'http://archiwum.polityka.pl' + box_img3[-1].find('a')['href']
while True:
index = self.index_to_soup(last_edition)
box_list = index.findAll('div', attrs={'class' : 'box_list'})
if len(box_list) == 0:
break
articles = {}
for box in box_list:
for div in box.findAll('div', attrs={'class': 'list_tresc'}):
article_page = self.index_to_soup('http://archiwum.polityka.pl' + div.a['href'],)
section = self.tag_to_string(article_page.find('h2', attrs = {'class' : 'box_nag'})).split('/')[0].lstrip().rstrip()
print section
if not articles.has_key(section):
articles[section] = []
articles[section].append( {
'title' : self.tag_to_string(div.a),
'url' : 'http://archiwum.polityka.pl' + div.a['href'],
'date' : '',
'description' : ''
})
for section in articles:
feeds.append((section, articles[section]))
last_edition = last_edition.replace('http://archiwum.polityka.pl/wydanie/' + str(last), 'http://archiwum.polityka.pl/wydanie/' + str(last + 1))
last = last + 1
return feeds

View File

@ -43,7 +43,7 @@ class ZeitDe(BasicNewsRecipe):
('Sport', 'http://newsfeed.zeit.de/sport/index'),
]
extra_css = '.reaktion,.taglist,.comments,.reponse,.responsetitle,.responsebody,.reponse,.inline,.date{display:none;}li.date{display:block}'
extra_css = '.excerpt{font-size:1em}.reaktion,.taglist,.comments,.reponse,.responsetitle,.responsebody,.reponse,.inline,.date{display:none;}li.date{display:block}'
#filter_regexps = [r'ad.de.doubleclick.net/']
@ -55,6 +55,16 @@ class ZeitDe(BasicNewsRecipe):
ans = None
return ans
def preprocess_html(self, soup):
for tag in soup.findAll(name=['ul','li']):
tag.name = 'div'
soup.html['xml:lang'] = self.lang
soup.html['lang'] = self.lang
mtag = '<meta http-equiv="Content-Type" content="text/html; charset=' + self.encoding + '">'
soup.head.insert(0,mtag)
return soup
def get_cover_url(self):
try:
inhalt = self.index_to_soup('http://www.zeit.de/inhalt')

View File

@ -2,7 +2,7 @@ __license__ = 'GPL v3'
__copyright__ = '2008, Kovid Goyal kovid@kovidgoyal.net'
__docformat__ = 'restructuredtext en'
__appname__ = 'calibre'
__version__ = '0.7.27'
__version__ = '0.7.28'
__author__ = "Kovid Goyal <kovid@kovidgoyal.net>"
import re

View File

@ -2,9 +2,7 @@ import os.path
__license__ = 'GPL v3'
__copyright__ = '2008, Kovid Goyal <kovid at kovidgoyal.net>'
import textwrap
import os
import glob
import textwrap, os, glob, functools
from calibre.customize import FileTypePlugin, MetadataReaderPlugin, \
MetadataWriterPlugin, PreferencesPlugin, InterfaceActionBase
from calibre.constants import numeric_version
@ -95,10 +93,12 @@ class ComicMetadataReader(MetadataReaderPlugin):
def get_metadata(self, stream, ftype):
if ftype == 'cbr':
from calibre.libunrar import extract_member as extract_first
from calibre.libunrar import extract_first_alphabetically as extract_first
extract_first
else:
from calibre.libunzip import extract_member as extract_first
from calibre.libunzip import extract_member
extract_first = functools.partial(extract_member,
sort_alphabetically=True)
from calibre.ebooks.metadata import MetaInformation
ret = extract_first(stream)
mi = MetaInformation(None, None)
@ -462,7 +462,7 @@ from calibre.devices.iliad.driver import ILIAD
from calibre.devices.irexdr.driver import IREXDR1000, IREXDR800
from calibre.devices.jetbook.driver import JETBOOK, MIBUK, JETBOOK_MINI
from calibre.devices.kindle.driver import KINDLE, KINDLE2, KINDLE_DX
from calibre.devices.nook.driver import NOOK
from calibre.devices.nook.driver import NOOK, NOOK_COLOR
from calibre.devices.prs505.driver import PRS505
from calibre.devices.android.driver import ANDROID, S60
from calibre.devices.nokia.driver import N770, N810, E71X, E52
@ -548,6 +548,7 @@ plugins += [
KINDLE2,
KINDLE_DX,
NOOK,
NOOK_COLOR,
PRS505,
ANDROID,
S60,

View File

@ -616,7 +616,7 @@ class KindleDXOutput(OutputProfile):
supports_mobi_indexing = True
periodical_date_in_title = False
ratings_char = u'\u2605'
read_char = u'\2713'
read_char = u'\u2713'
mobi_ems_per_blockquote = 2.0
@classmethod

View File

@ -23,6 +23,9 @@ class ANDROID(USBMS):
: [0x0100, 0x0227, 0x0226], 0x0c87: [0x0100, 0x0227, 0x0226],
0xc92 : [0x100]},
# Eken
0x040d : { 0x8510 : [0x0001] },
# Motorola
0x22b8 : { 0x41d9 : [0x216], 0x2d67 : [0x100], 0x41db : [0x216],
0x4285 : [0x216]},

View File

@ -19,7 +19,7 @@ class BLACKBERRY(USBMS):
VENDOR_ID = [0x0fca]
PRODUCT_ID = [0x8004, 0x0004]
BCD = [0x0200, 0x0107, 0x0210, 0x0201]
BCD = [0x0200, 0x0107, 0x0210, 0x0201, 0x0211]
VENDOR_NAME = 'RIM'
WINDOWS_MAIN_MEM = 'BLACKBERRY_SD'

View File

@ -74,9 +74,9 @@ class DevicePlugin(Plugin):
if bcd is None or len(bcd) == 0:
return True
for c in bcd:
# Bug in winutil.get_usb_devices converts a to :
rev = ('rev_%4.4x'%c).replace('a', ':')
if rev in device_id:
rev = 'rev_%4.4x'%c
# Bug in winutil.get_usb_devices sometimes converts a to :
if rev in device_id or rev.replace('a', ':') in device_id:
return True
return False

View File

@ -80,3 +80,14 @@ class NOOK(USBMS):
def sanitize_path_components(self, components):
return [x.replace('#', '_') for x in components]
class NOOK_COLOR(NOOK):
gui_name = _('Nook Color')
description = _('Communicate with the Nook Color eBook reader.')
PRODUCT_ID = [0x002]
BCD = [0x216]
WINDOWS_MAIN_MEM = WINDOWS_CARD_A_MEM = 'EBOOK_DISK'
EBOOK_DIR_MAIN = 'My Files/Books'

View File

@ -619,6 +619,13 @@ class XMLCache(object):
x.replace(u'\0', '')
return x
def record_set(k, v):
try:
record.set(k, clean(v))
except:
# v is not suitable for XML, ignore
pass
if not getattr(book, '_new_book', False): # book is not new
if record.get('tz', None) is not None:
use_tz_var = True
@ -641,20 +648,20 @@ class XMLCache(object):
record.set('date', clean(date))
record.set('size', clean(str(os.stat(path).st_size)))
title = book.title if book.title else _('Unknown')
record.set('title', clean(title))
record_set('title', title)
ts = book.title_sort
if not ts:
ts = title_sort(title)
record.set('titleSorter', clean(ts))
record_set('titleSorter', ts)
if self.use_author_sort:
if book.author_sort:
aus = book.author_sort
else:
debug_print('Author_sort is None for book', book.lpath)
aus = authors_to_sort_string(book.authors)
record.set('author', clean(aus))
record_set('author', aus)
else:
record.set('author', clean(authors_to_string(book.authors)))
record_set('author', authors_to_string(book.authors))
ext = os.path.splitext(path)[1]
if ext:
ext = ext[1:].lower()

View File

@ -569,6 +569,10 @@ class MobiReader(object):
for attr in self.IMAGE_ATTRS:
recindex = attrib.pop(attr, None) or recindex
if recindex is not None:
try:
recindex = '%05d'%int(recindex)
except:
pass
attrib['src'] = 'images/%s.jpg' % recindex
for attr in ('width', 'height'):
if attr in attrib:

View File

@ -787,6 +787,8 @@ class Manifest(object):
# Convert to Unicode and normalize line endings
data = self.oeb.decode(data)
data = self.oeb.html_preprocessor(data)
# There could be null bytes in data if it had &#0; entities in it
data = data.replace('\0', '')
# Remove DOCTYPE declaration as it messes up parsing
# In particular, it causes tostring to insert xmlns

View File

@ -47,6 +47,8 @@ class BulkConfig(Config):
self.show_pane)
self.connect(self.groups, SIGNAL('entered(QModelIndex)'),
self.show_group_help)
rb = self.buttonBox.button(self.buttonBox.RestoreDefaults)
rb.setVisible(False)
self.groups.setMouseTracking(True)

View File

@ -7,7 +7,7 @@
<x>0</x>
<y>0</y>
<width>731</width>
<height>384</height>
<height>411</height>
</rect>
</property>
<property name="windowTitle">
@ -19,6 +19,35 @@
</property>
<layout class="QGridLayout" name="gridLayout_2">
<item row="0" column="0">
<widget class="QLabel" name="label_5">
<property name="text">
<string>What kind of match to use:</string>
</property>
<property name="buddy">
<cstring>matchkind</cstring>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QComboBox" name="matchkind">
<item>
<property name="text">
<string>Contains: the word or phrase matches anywhere in the metadata field</string>
</property>
</item>
<item>
<property name="text">
<string>Equals: the word or phrase must match the entire metadata field</string>
</property>
</item>
<item>
<property name="text">
<string>Regular expression: the expression must match anywhere in the metadata field</string>
</property>
</item>
</widget>
</item>
<item row="2" column="0" colspan="2">
<widget class="QTabWidget" name="tabWidget">
<property name="currentIndex">
<number>0</number>
@ -27,8 +56,8 @@
<attribute name="title">
<string>A&amp;dvanced Search</string>
</attribute>
<layout class="QVBoxLayout" name="verticalLayout_5">
<item>
<layout class="QGridLayout" name="gridLayout_3">
<item row="0" column="0">
<widget class="QGroupBox" name="groupBox">
<property name="title">
<string>Find entries that have...</string>
@ -88,7 +117,7 @@
</layout>
</widget>
</item>
<item>
<item row="1" column="0">
<widget class="QGroupBox" name="groupBox_2">
<property name="title">
<string>But dont show entries that have...</string>
@ -120,35 +149,6 @@
</size>
</property>
<layout class="QHBoxLayout" name="horizontalLayout_5">
<item>
<widget class="QLabel" name="label_5">
<property name="text">
<string>What kind of match to use:</string>
</property>
<property name="buddy">
<cstring>matchkind</cstring>
</property>
</widget>
</item>
<item>
<widget class="QComboBox" name="matchkind">
<item>
<property name="text">
<string>Contains: the word or phrase matches anywhere in the metadata</string>
</property>
</item>
<item>
<property name="text">
<string>Equals: the word or phrase must match an entire metadata field</string>
</property>
</item>
<item>
<property name="text">
<string>Regular expression: the expression must match anywhere in the metadata</string>
</property>
</item>
</widget>
</item>
<item>
<widget class="QLabel" name="label_51">
<property name="sizePolicy">
@ -187,7 +187,7 @@
</layout>
</widget>
</item>
<item>
<item row="2" column="0">
<spacer name="verticalSpacer_2">
<property name="orientation">
<enum>Qt::Vertical</enum>
@ -200,7 +200,7 @@
</property>
</spacer>
</item>
<item>
<item row="3" column="0">
<widget class="QDialogButtonBox" name="buttonBox">
<property name="orientation">
<enum>Qt::Horizontal</enum>
@ -333,6 +333,19 @@
</widget>
</widget>
</item>
<item row="1" column="1">
<spacer name="verticalSpacer_3">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
<tabstops>
@ -340,7 +353,6 @@
<tabstop>phrase</tabstop>
<tabstop>any</tabstop>
<tabstop>none</tabstop>
<tabstop>matchkind</tabstop>
<tabstop>buttonBox</tabstop>
<tabstop>title_box</tabstop>
<tabstop>authors_box</tabstop>
@ -350,7 +362,6 @@
<tabstop>general_box</tabstop>
<tabstop>clear_button</tabstop>
<tabstop>tab_2_button_box</tabstop>
<tabstop>tabWidget</tabstop>
</tabstops>
<resources>
<include location="../../../../resources/images.qrc"/>

View File

@ -50,10 +50,11 @@ class BooksView(QTableView): # {{{
def __init__(self, parent, modelcls=BooksModel):
QTableView.__init__(self, parent)
self.setEditTriggers(self.SelectedClicked|self.EditKeyPressed)
self.setEditTriggers(self.EditKeyPressed)
if tweaks['doubleclick_on_library_view'] == 'edit_cell':
self.setEditTriggers(self.DoubleClicked|self.editTriggers())
elif tweaks['doubleclick_on_library_view'] == 'open_viewer':
self.setEditTriggers(self.SelectedClicked|self.editTriggers())
self.doubleClicked.connect(parent.iactions['View'].view_triggered)
self.drag_allowed = True

View File

@ -269,3 +269,16 @@ def extract_member(path, match=re.compile(r'\.(jpg|jpeg|gif|png)\s*$', re.I),
path = _extract_member(path, match, name)
return path, open(path, 'rb').read()
def extract_first_alphabetically(path):
if hasattr(path, 'read'):
data = path.read()
f = NamedTemporaryFile(suffix='.rar')
f.write(data)
f.flush()
path = f.name
names_ = [x for x in names(path) if os.path.splitext(x)[1][1:].lower() in
('png', 'jpg', 'jpeg', 'gif')]
names_.sort()
return extract_member(path, name=names_[0], match=None)

View File

@ -43,9 +43,12 @@ def extract(filename, dir):
zf = zipfile.ZipFile( filename )
zf.extractall(dir)
def extract_member(filename, match=re.compile(r'\.(jpg|jpeg|gif|png)\s*$', re.I)):
def extract_member(filename, match=re.compile(r'\.(jpg|jpeg|gif|png)\s*$',
re.I), sort_alphabetically=False):
zf = zipfile.ZipFile(filename)
names = zf.namelist()
names = list(zf.namelist())
if sort_alphabetically:
names.sort()
for name in names:
if match.search(name):
return name, zf.read(name)

File diff suppressed because it is too large Load Diff

View File

@ -4,9 +4,9 @@
#
msgid ""
msgstr ""
"Project-Id-Version: calibre 0.7.27\n"
"POT-Creation-Date: 2010-11-10 07:14+MST\n"
"PO-Revision-Date: 2010-11-10 07:14+MST\n"
"Project-Id-Version: calibre 0.7.28\n"
"POT-Creation-Date: 2010-11-12 13:07+MST\n"
"PO-Revision-Date: 2010-11-12 13:07+MST\n"
"Last-Translator: Automatically generated\n"
"Language-Team: LANGUAGE\n"
"MIME-Version: 1.0\n"
@ -29,7 +29,7 @@ msgstr ""
#: /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/prs500/books.py:267
#: /home/kovid/work/calibre/src/calibre/devices/prs505/sony_cache.py:643
#: /home/kovid/work/calibre/src/calibre/devices/prs505/sony_cache.py:650
#: /home/kovid/work/calibre/src/calibre/devices/usbms/driver.py:401
#: /home/kovid/work/calibre/src/calibre/ebooks/chm/input.py:97
#: /home/kovid/work/calibre/src/calibre/ebooks/chm/input.py:100
@ -72,14 +72,14 @@ msgstr ""
#: /home/kovid/work/calibre/src/calibre/ebooks/mobi/reader.py:78
#: /home/kovid/work/calibre/src/calibre/ebooks/mobi/reader.py:119
#: /home/kovid/work/calibre/src/calibre/ebooks/mobi/reader.py:153
#: /home/kovid/work/calibre/src/calibre/ebooks/mobi/reader.py:616
#: /home/kovid/work/calibre/src/calibre/ebooks/mobi/reader.py:822
#: /home/kovid/work/calibre/src/calibre/ebooks/mobi/reader.py:824
#: /home/kovid/work/calibre/src/calibre/ebooks/mobi/reader.py:620
#: /home/kovid/work/calibre/src/calibre/ebooks/mobi/reader.py:826
#: /home/kovid/work/calibre/src/calibre/ebooks/mobi/reader.py:828
#: /home/kovid/work/calibre/src/calibre/ebooks/odt/input.py:49
#: /home/kovid/work/calibre/src/calibre/ebooks/odt/input.py:51
#: /home/kovid/work/calibre/src/calibre/ebooks/oeb/base.py:911
#: /home/kovid/work/calibre/src/calibre/ebooks/oeb/base.py:916
#: /home/kovid/work/calibre/src/calibre/ebooks/oeb/base.py:982
#: /home/kovid/work/calibre/src/calibre/ebooks/oeb/base.py:913
#: /home/kovid/work/calibre/src/calibre/ebooks/oeb/base.py:918
#: /home/kovid/work/calibre/src/calibre/ebooks/oeb/base.py:984
#: /home/kovid/work/calibre/src/calibre/ebooks/oeb/reader.py:143
#: /home/kovid/work/calibre/src/calibre/ebooks/oeb/reader.py:150
#: /home/kovid/work/calibre/src/calibre/ebooks/oeb/transforms/jacket.py:64
@ -121,8 +121,8 @@ msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/convert/metadata.py:141
#: /home/kovid/work/calibre/src/calibre/gui2/device.py:927
#: /home/kovid/work/calibre/src/calibre/gui2/device.py:936
#: /home/kovid/work/calibre/src/calibre/gui2/device.py:1243
#: /home/kovid/work/calibre/src/calibre/gui2/device.py:1246
#: /home/kovid/work/calibre/src/calibre/gui2/device.py:1249
#: /home/kovid/work/calibre/src/calibre/gui2/device.py:1252
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/comicconf.py:47
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/fetch_metadata.py:120
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/fetch_metadata.py:155
@ -190,19 +190,19 @@ msgstr ""
msgid "Preferences"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:17
#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:15
msgid "Follow all local links in an HTML file and create a ZIP file containing all linked files. This plugin is run every time you add an HTML file to the library."
msgstr ""
#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:53
#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:51
msgid "Character encoding for the input HTML files. Common choices include: cp1252, latin1, iso-8859-1 and utf-8."
msgstr ""
#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:60
#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:58
msgid "Create a PMLZ archive containing the PML file and all images in the directory pmlname_img or images. This plugin is run every time you add a PML file to the library."
msgstr ""
#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:94
#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:92
msgid "Extract cover from comic files"
msgstr ""
@ -249,163 +249,163 @@ msgstr ""
msgid "Set metadata from %s files"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:711
#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:712
msgid "Look and Feel"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:713
#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:725
#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:736
#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:747
#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:714
#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:726
#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:737
#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:748
msgid "Interface"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:717
#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:718
msgid "Adjust the look and feel of the calibre interface to suit your tastes"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:723
#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:724
msgid "Behavior"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:729
#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:730
msgid "Change the way calibre behaves"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:734
#: /home/kovid/work/calibre/src/calibre/gui2/library/views.py:208
#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:735
#: /home/kovid/work/calibre/src/calibre/gui2/library/views.py:209
msgid "Add your own columns"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:740
#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:741
msgid "Add/remove your own columns to the calibre book list"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:745
#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:746
msgid "Customize the toolbar"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:751
#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:752
msgid "Customize the toolbars and context menus, changing which actions are available in each"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:757
#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:758
msgid "Input Options"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:759
#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:770
#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:781
#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:760
#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:771
#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:782
msgid "Conversion"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:763
#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:764
msgid "Set conversion options specific to each input format"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:768
#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:769
msgid "Common Options"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:774
#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:775
msgid "Set conversion options common to all formats"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:779
#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:780
msgid "Output Options"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:785
#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:786
msgid "Set conversion options specific to each output format"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:790
#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:791
msgid "Adding books"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:792
#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:804
#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:816
#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:828
#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:793
#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:805
#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:817
#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:829
msgid "Import/Export"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:796
#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:797
msgid "Control how calibre reads metadata from files when adding books"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:802
#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:803
msgid "Saving books to disk"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:808
#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:809
msgid "Control how calibre exports files from its database to disk when using Save to disk"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:814
#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:815
msgid "Sending books to devices"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:820
#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:821
msgid "Control how calibre transfers files to your ebook reader"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:826
#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:827
msgid "Metadata plugboards"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:832
#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:833
msgid "Change metadata fields before saving/sending"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:837
#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:838
msgid "Sharing books by email"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:839
#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:851
#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:840
#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:852
msgid "Sharing"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:843
#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:844
msgid "Setup sharing of books via email. Can be used for automatic sending of downloaded news to your devices"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:849
#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:850
msgid "Sharing over the net"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:855
#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:856
msgid "Setup the calibre Content Server which will give you access to your calibre library from anywhere, on any device, over the internet"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:862
#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:863
msgid "Plugins"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:864
#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:876
#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:887
#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:865
#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:877
#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:888
msgid "Advanced"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:868
#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:869
msgid "Add/remove/customize various bits of calibre functionality"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:874
#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:875
msgid "Tweaks"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:880
#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:881
msgid "Fine tune how calibre behaves in various contexts"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:885
#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:886
msgid "Miscellaneous"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:891
#: /home/kovid/work/calibre/src/calibre/customize/builtins.py:892
msgid "Miscellaneous advanced configuration"
msgstr ""
@ -434,7 +434,7 @@ msgid "This profile tries to provide sane defaults and is useful if you know not
msgstr ""
#: /home/kovid/work/calibre/src/calibre/customize/profiles.py:59
#: /home/kovid/work/calibre/src/calibre/customize/profiles.py:436
#: /home/kovid/work/calibre/src/calibre/customize/profiles.py:444
msgid "This profile is intended for the SONY PRS line. The 500/505/600/700 etc."
msgstr ""
@ -443,62 +443,62 @@ msgid "This profile is intended for the SONY PRS 300."
msgstr ""
#: /home/kovid/work/calibre/src/calibre/customize/profiles.py:80
#: /home/kovid/work/calibre/src/calibre/customize/profiles.py:476
#: /home/kovid/work/calibre/src/calibre/customize/profiles.py:484
msgid "This profile is intended for the SONY PRS-900."
msgstr ""
#: /home/kovid/work/calibre/src/calibre/customize/profiles.py:88
#: /home/kovid/work/calibre/src/calibre/customize/profiles.py:506
#: /home/kovid/work/calibre/src/calibre/customize/profiles.py:513
msgid "This profile is intended for the Microsoft Reader."
msgstr ""
#: /home/kovid/work/calibre/src/calibre/customize/profiles.py:99
#: /home/kovid/work/calibre/src/calibre/customize/profiles.py:517
#: /home/kovid/work/calibre/src/calibre/customize/profiles.py:524
msgid "This profile is intended for the Mobipocket books."
msgstr ""
#: /home/kovid/work/calibre/src/calibre/customize/profiles.py:112
#: /home/kovid/work/calibre/src/calibre/customize/profiles.py:530
#: /home/kovid/work/calibre/src/calibre/customize/profiles.py:537
msgid "This profile is intended for the Hanlin V3 and its clones."
msgstr ""
#: /home/kovid/work/calibre/src/calibre/customize/profiles.py:124
#: /home/kovid/work/calibre/src/calibre/customize/profiles.py:542
#: /home/kovid/work/calibre/src/calibre/customize/profiles.py:549
msgid "This profile is intended for the Hanlin V5 and its clones."
msgstr ""
#: /home/kovid/work/calibre/src/calibre/customize/profiles.py:134
#: /home/kovid/work/calibre/src/calibre/customize/profiles.py:550
#: /home/kovid/work/calibre/src/calibre/customize/profiles.py:557
msgid "This profile is intended for the Cybook G3."
msgstr ""
#: /home/kovid/work/calibre/src/calibre/customize/profiles.py:147
#: /home/kovid/work/calibre/src/calibre/customize/profiles.py:563
#: /home/kovid/work/calibre/src/calibre/customize/profiles.py:570
msgid "This profile is intended for the Cybook Opus."
msgstr ""
#: /home/kovid/work/calibre/src/calibre/customize/profiles.py:159
#: /home/kovid/work/calibre/src/calibre/customize/profiles.py:576
#: /home/kovid/work/calibre/src/calibre/customize/profiles.py:583
msgid "This profile is intended for the Amazon Kindle."
msgstr ""
#: /home/kovid/work/calibre/src/calibre/customize/profiles.py:171
#: /home/kovid/work/calibre/src/calibre/customize/profiles.py:617
#: /home/kovid/work/calibre/src/calibre/customize/profiles.py:631
msgid "This profile is intended for the Irex Illiad."
msgstr ""
#: /home/kovid/work/calibre/src/calibre/customize/profiles.py:183
#: /home/kovid/work/calibre/src/calibre/customize/profiles.py:630
#: /home/kovid/work/calibre/src/calibre/customize/profiles.py:644
msgid "This profile is intended for the IRex Digital Reader 1000."
msgstr ""
#: /home/kovid/work/calibre/src/calibre/customize/profiles.py:196
#: /home/kovid/work/calibre/src/calibre/customize/profiles.py:644
#: /home/kovid/work/calibre/src/calibre/customize/profiles.py:658
msgid "This profile is intended for the IRex Digital Reader 800."
msgstr ""
#: /home/kovid/work/calibre/src/calibre/customize/profiles.py:208
#: /home/kovid/work/calibre/src/calibre/customize/profiles.py:658
#: /home/kovid/work/calibre/src/calibre/customize/profiles.py:672
msgid "This profile is intended for the B&N Nook."
msgstr ""
@ -510,35 +510,35 @@ msgstr ""
msgid "This profile tries to provide sane defaults and is useful if you want to produce a document intended to be read at a computer or on a range of devices."
msgstr ""
#: /home/kovid/work/calibre/src/calibre/customize/profiles.py:273
#: /home/kovid/work/calibre/src/calibre/customize/profiles.py:276
msgid "Intended for the iPad and similar devices with a resolution of 768x1024"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/customize/profiles.py:427
#: /home/kovid/work/calibre/src/calibre/customize/profiles.py:435
msgid "Intended for generic tablet devices, does no resizing of images"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/customize/profiles.py:454
#: /home/kovid/work/calibre/src/calibre/customize/profiles.py:462
msgid "This profile is intended for the Kobo Reader."
msgstr ""
#: /home/kovid/work/calibre/src/calibre/customize/profiles.py:467
#: /home/kovid/work/calibre/src/calibre/customize/profiles.py:475
msgid "This profile is intended for the SONY PRS-300."
msgstr ""
#: /home/kovid/work/calibre/src/calibre/customize/profiles.py:485
#: /home/kovid/work/calibre/src/calibre/customize/profiles.py:493
msgid "This profile is intended for the 5-inch JetBook."
msgstr ""
#: /home/kovid/work/calibre/src/calibre/customize/profiles.py:494
#: /home/kovid/work/calibre/src/calibre/customize/profiles.py:502
msgid "This profile is intended for the SONY PRS line. The 500/505/700 etc, in landscape mode. Mainly useful for comics."
msgstr ""
#: /home/kovid/work/calibre/src/calibre/customize/profiles.py:597
#: /home/kovid/work/calibre/src/calibre/customize/profiles.py:609
msgid "This profile is intended for the Amazon Kindle DX."
msgstr ""
#: /home/kovid/work/calibre/src/calibre/customize/profiles.py:672
#: /home/kovid/work/calibre/src/calibre/customize/profiles.py:686
msgid "This profile is intended for the Sanda Bambook."
msgstr ""
@ -606,11 +606,11 @@ msgstr ""
msgid "Communicate with Android phones."
msgstr ""
#: /home/kovid/work/calibre/src/calibre/devices/android/driver.py:53
#: /home/kovid/work/calibre/src/calibre/devices/android/driver.py:56
msgid "Comma separated list of directories to send e-books to on the device. The first one that exists will be used"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/devices/android/driver.py:95
#: /home/kovid/work/calibre/src/calibre/devices/android/driver.py:98
msgid "Communicate with S60 phones."
msgstr ""
@ -945,6 +945,14 @@ msgstr ""
msgid "Communicate with the Nook eBook reader."
msgstr ""
#: /home/kovid/work/calibre/src/calibre/devices/nook/driver.py:85
msgid "Nook Color"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/devices/nook/driver.py:86
msgid "Communicate with the Nook Color eBook reader."
msgstr ""
#: /home/kovid/work/calibre/src/calibre/devices/nuut2/driver.py:17
msgid "Communicate with the Nuut2 eBook reader."
msgstr ""
@ -2180,7 +2188,7 @@ msgid ""
msgstr ""
#: /home/kovid/work/calibre/src/calibre/ebooks/metadata/opf2.py:1308
#: /home/kovid/work/calibre/src/calibre/ebooks/oeb/base.py:1399
#: /home/kovid/work/calibre/src/calibre/ebooks/oeb/base.py:1401
msgid "Cover"
msgstr ""
@ -2217,70 +2225,70 @@ msgstr ""
msgid "This is an Amazon Topaz book. It cannot be processed."
msgstr ""
#: /home/kovid/work/calibre/src/calibre/ebooks/oeb/base.py:1400
#: /home/kovid/work/calibre/src/calibre/ebooks/oeb/base.py:1402
msgid "Title Page"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/ebooks/oeb/base.py:1401
#: /home/kovid/work/calibre/src/calibre/ebooks/oeb/base.py:1403
#: /home/kovid/work/calibre/src/calibre/ebooks/oeb/transforms/htmltoc.py:15
#: /home/kovid/work/calibre/src/calibre/gui2/viewer/main.py:53
#: /home/kovid/work/calibre/src/calibre/gui2/viewer/main_ui.py:199
msgid "Table of Contents"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/ebooks/oeb/base.py:1402
#: /home/kovid/work/calibre/src/calibre/ebooks/oeb/base.py:1404
msgid "Index"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/ebooks/oeb/base.py:1403
#: /home/kovid/work/calibre/src/calibre/ebooks/oeb/base.py:1405
msgid "Glossary"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/ebooks/oeb/base.py:1404
#: /home/kovid/work/calibre/src/calibre/ebooks/oeb/base.py:1406
msgid "Acknowledgements"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/ebooks/oeb/base.py:1405
#: /home/kovid/work/calibre/src/calibre/ebooks/oeb/base.py:1407
msgid "Bibliography"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/ebooks/oeb/base.py:1406
#: /home/kovid/work/calibre/src/calibre/ebooks/oeb/base.py:1408
msgid "Colophon"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/ebooks/oeb/base.py:1407
#: /home/kovid/work/calibre/src/calibre/ebooks/oeb/base.py:1409
msgid "Copyright"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/ebooks/oeb/base.py:1408
#: /home/kovid/work/calibre/src/calibre/ebooks/oeb/base.py:1410
msgid "Dedication"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/ebooks/oeb/base.py:1409
#: /home/kovid/work/calibre/src/calibre/ebooks/oeb/base.py:1411
msgid "Epigraph"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/ebooks/oeb/base.py:1410
#: /home/kovid/work/calibre/src/calibre/ebooks/oeb/base.py:1412
msgid "Foreword"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/ebooks/oeb/base.py:1411
#: /home/kovid/work/calibre/src/calibre/ebooks/oeb/base.py:1413
msgid "List of Illustrations"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/ebooks/oeb/base.py:1412
#: /home/kovid/work/calibre/src/calibre/ebooks/oeb/base.py:1414
msgid "List of Tables"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/ebooks/oeb/base.py:1413
#: /home/kovid/work/calibre/src/calibre/ebooks/oeb/base.py:1415
msgid "Notes"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/ebooks/oeb/base.py:1414
#: /home/kovid/work/calibre/src/calibre/ebooks/oeb/base.py:1416
msgid "Preface"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/ebooks/oeb/base.py:1415
#: /home/kovid/work/calibre/src/calibre/ebooks/oeb/base.py:1417
msgid "Main Text"
msgstr ""
@ -3140,7 +3148,7 @@ msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/actions/choose_library.py:391
#: /home/kovid/work/calibre/src/calibre/gui2/actions/save_to_disk.py:101
#: /home/kovid/work/calibre/src/calibre/gui2/library/views.py:741
#: /home/kovid/work/calibre/src/calibre/gui2/library/views.py:742
msgid "Not allowed"
msgstr ""
@ -4163,11 +4171,11 @@ msgstr ""
msgid "For settings that cannot be specified in this dialog, use the values saved in a previous conversion (if they exist) instead of using the defaults specified in the Preferences"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/convert/bulk.py:68
#: /home/kovid/work/calibre/src/calibre/gui2/convert/bulk.py:70
msgid "Bulk Convert"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/convert/bulk.py:81
#: /home/kovid/work/calibre/src/calibre/gui2/convert/bulk.py:83
#: /home/kovid/work/calibre/src/calibre/gui2/convert/single.py:185
msgid "Options specific to the output format."
msgstr ""
@ -5299,10 +5307,10 @@ msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/device.py:982
#: /home/kovid/work/calibre/src/calibre/gui2/device.py:990
#: /home/kovid/work/calibre/src/calibre/gui2/device.py:1083
#: /home/kovid/work/calibre/src/calibre/gui2/device.py:1168
#: /home/kovid/work/calibre/src/calibre/gui2/device.py:1287
#: /home/kovid/work/calibre/src/calibre/gui2/device.py:1295
#: /home/kovid/work/calibre/src/calibre/gui2/device.py:1089
#: /home/kovid/work/calibre/src/calibre/gui2/device.py:1174
#: /home/kovid/work/calibre/src/calibre/gui2/device.py:1293
#: /home/kovid/work/calibre/src/calibre/gui2/device.py:1301
msgid "No suitable formats"
msgstr ""
@ -5326,45 +5334,45 @@ msgstr ""
msgid "Sent by email:"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/device.py:1042
#: /home/kovid/work/calibre/src/calibre/gui2/device.py:1048
msgid "News:"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/device.py:1043
#: /home/kovid/work/calibre/src/calibre/gui2/device.py:1049
msgid "Attached is the"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/device.py:1054
#: /home/kovid/work/calibre/src/calibre/gui2/device.py:1060
msgid "Sent news to"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/device.py:1084
#: /home/kovid/work/calibre/src/calibre/gui2/device.py:1169
#: /home/kovid/work/calibre/src/calibre/gui2/device.py:1288
#: /home/kovid/work/calibre/src/calibre/gui2/device.py:1090
#: /home/kovid/work/calibre/src/calibre/gui2/device.py:1175
#: /home/kovid/work/calibre/src/calibre/gui2/device.py:1294
msgid "Auto convert the following books before uploading to the device?"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/device.py:1114
#: /home/kovid/work/calibre/src/calibre/gui2/device.py:1120
msgid "Sending catalogs to device."
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/device.py:1201
#: /home/kovid/work/calibre/src/calibre/gui2/device.py:1207
msgid "Sending news to device."
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/device.py:1254
#: /home/kovid/work/calibre/src/calibre/gui2/device.py:1260
msgid "Sending books to device."
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/device.py:1296
#: /home/kovid/work/calibre/src/calibre/gui2/device.py:1302
msgid "Could not upload the following books to the device, as no suitable formats were found. Convert the book(s) to a format supported by your device first."
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/device.py:1360
#: /home/kovid/work/calibre/src/calibre/gui2/device.py:1366
msgid "No space on device"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/device.py:1361
#: /home/kovid/work/calibre/src/calibre/gui2/device.py:1367
msgid "<p>Cannot upload books to device there is no more free space available "
msgstr ""
@ -6590,43 +6598,43 @@ msgid "Advanced Search"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/search_ui.py:199
msgid "Find entries that have..."
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/search_ui.py:200
msgid "&All these words:"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/search_ui.py:201
msgid "This exact &phrase:"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/search_ui.py:202
msgid "&One or more of these words:"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/search_ui.py:203
msgid "But dont show entries that have..."
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/search_ui.py:204
msgid "Any of these &unwanted words:"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/search_ui.py:205
msgid "What kind of match to use:"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/search_ui.py:200
msgid "Contains: the word or phrase matches anywhere in the metadata field"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/search_ui.py:201
msgid "Equals: the word or phrase must match the entire metadata field"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/search_ui.py:202
msgid "Regular expression: the expression must match anywhere in the metadata field"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/search_ui.py:203
msgid "Find entries that have..."
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/search_ui.py:204
msgid "&All these words:"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/search_ui.py:205
msgid "This exact &phrase:"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/search_ui.py:206
msgid "Contains: the word or phrase matches anywhere in the metadata"
msgid "&One or more of these words:"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/search_ui.py:207
msgid "Equals: the word or phrase must match an entire metadata field"
msgid "But dont show entries that have..."
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/search_ui.py:208
msgid "Regular expression: the expression must match anywhere in the metadata"
msgid "Any of these &unwanted words:"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/dialogs/search_ui.py:209
@ -7371,47 +7379,47 @@ msgstr ""
msgid "Double click to <b>edit</b> me<br><br>"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/library/views.py:146
#: /home/kovid/work/calibre/src/calibre/gui2/library/views.py:147
msgid "Hide column %s"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/library/views.py:151
#: /home/kovid/work/calibre/src/calibre/gui2/library/views.py:152
msgid "Sort on %s"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/library/views.py:152
#: /home/kovid/work/calibre/src/calibre/gui2/library/views.py:153
msgid "Ascending"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/library/views.py:155
#: /home/kovid/work/calibre/src/calibre/gui2/library/views.py:156
msgid "Descending"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/library/views.py:167
#: /home/kovid/work/calibre/src/calibre/gui2/library/views.py:168
msgid "Change text alignment for %s"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/library/views.py:169
#: /home/kovid/work/calibre/src/calibre/gui2/library/views.py:170
msgid "Left"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/library/views.py:169
#: /home/kovid/work/calibre/src/calibre/gui2/library/views.py:170
msgid "Right"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/library/views.py:170
#: /home/kovid/work/calibre/src/calibre/gui2/library/views.py:171
msgid "Center"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/library/views.py:189
#: /home/kovid/work/calibre/src/calibre/gui2/library/views.py:190
msgid "Show column"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/library/views.py:201
#: /home/kovid/work/calibre/src/calibre/gui2/library/views.py:202
msgid "Restore default layout"
msgstr ""
#: /home/kovid/work/calibre/src/calibre/gui2/library/views.py:742
#: /home/kovid/work/calibre/src/calibre/gui2/library/views.py:743
msgid "Dropping onto a device is not supported. First add the book to the calibre library."
msgstr ""

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

@ -21,15 +21,14 @@
#import pdb
#pdb.set_trace()
import zipfile
import xml.sax
from xml.sax import handler, expatreader
from xml.sax.xmlreader import InputSource
from xml.sax.saxutils import escape, quoteattr
from cStringIO import StringIO
from namespaces import ANIMNS, CHARTNS, CONFIGNS, DCNS, DR3DNS, DRAWNS, FONS, \
FORMNS, MATHNS, METANS, NUMBERNS, OFFICENS, PRESENTATIONNS, SCRIPTNS, \
SMILNS, STYLENS, SVGNS, TABLENS, TEXTNS, XLINKNS
from namespaces import DCNS, DRAWNS, FONS, \
METANS, NUMBERNS, OFFICENS, PRESENTATIONNS, \
STYLENS, SVGNS, TABLENS, TEXTNS, XLINKNS
# Handling of styles
#
@ -526,7 +525,8 @@ class ODF2XHTML(handler.ContentHandler):
def get_anchor(self, name):
if not self.anchors.has_key(name):
self.anchors[name] = "anchor%03d" % (len(self.anchors) + 1)
# Changed by Kovid
self.anchors[name] = "anchor%d" % (len(self.anchors) + 1)
return self.anchors.get(name)
@ -1025,9 +1025,13 @@ class ODF2XHTML(handler.ContentHandler):
if level < 1: level = 1
lev = self.headinglevels[1:level+1]
outline = '.'.join(map(str,lev) )
anchor = self.get_anchor("%s.%s" % ( outline, ''.join(self.data)))
tail = ''.join(self.data)
anchor = self.get_anchor("%s.%s" % ( outline, tail))
anchor2 = self.get_anchor(tail) # Added by kovid to fix #7506
self.opentag('a', {'id': anchor} )
self.closetag('a', False)
self.opentag('a', {'id': anchor2} )
self.closetag('a', False)
self.closetag('h%s' % level)
self.purgedata()