Merge from trunk

This commit is contained in:
Charles Haley 2010-07-10 05:26:15 +01:00
commit 2ac4403254
40 changed files with 15721 additions and 13556 deletions

View File

@ -4,6 +4,74 @@
# for important features/bug fixes.
# Also, each release can have new and improved recipes.
- version: 0.7.8
date: 2010-07-09
new features:
- title: "New tool to help prepare EPUBs for publication"
type: major
description: >
"calibre now contains a new command line tool called epub-fix that can automatically fix
common problems in EPUB files that cause them to be rejected by poorly designed publishing services.
The tool is plugin based for extensible functionality in the future. Currently, it can fix unmanifested files
and workaround the date and svg preserveaspectratio bugs of epubcheck."
- title: "New icons for the toolbar buttons by Kamil Tatara"
- title: "Display rating (when available) in cover browser"
- title: "Clicking on the central cover int the cover browser now opens that book in the viewer"
- title: "Use the status bar instead of the area to the right of the location view to display status information"
- title: "Driver for the Pandigital Novel e-book reader"
bug fixes:
- title: "News download: Don not specify a font family for article descriptions"
- title: "News download: Fix regression introduced in 0.7.0 that broke download of some embedded content feeds"
- title: "MOBI Output: Partial support for nested superscript and subscripts."
tickets: [6132]
- title: "CHM Input: Fix handling of buggy CHM files with no .hhc"
tickets: [6087]
- title: "EPUB Input: Fix bug in unzipping EPUB files that have been zipped in depth first order."
tickets: [6127]
- title: "TXT Input: Convert HTML entities to characters."
tickets: [6114]
- title: "LRF Input: Handle LRF files with random null bytes in the text"
tickets: [6097]
- title: "Kobo driver: Fix detection of txt/html files on the device"
- title: "Fix opening of books when calibre library is on an unmapped network share in windows"
- title: "SONY driver: Only update the timestamp in the XML db for newly added books"
- title: "Cover browser: Fix rendering of center cover when width of cover browser is less than the width of a single cover"
- title: "Cover browser: Correct fix for setPixel out of bounds warning causing UI slowdown in calibre"
new recipes:
- title: "evz.ro"
author: Darko Miletic
- title: "Anchorage Daily News, China Economic Net, BBC Chinese and Singtao Daily"
author: rty
- title: Big Oven
author: Starson17
improved recipes:
- Haaretz
- Editor and Publisher
- Estadao
- version: 0.7.7
date: 2010-07-02

View File

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

View File

@ -460,7 +460,7 @@ from calibre.devices.hanvon.driver import N516, EB511, ALEX, AZBOOKA, THEBOOK
from calibre.devices.edge.driver import EDGE
from calibre.devices.teclast.driver import TECLAST_K3, NEWSMY, IPAPYRUS
from calibre.devices.sne.driver import SNE
from calibre.devices.misc import PALMPRE, AVANT, SWEEX
from calibre.devices.misc import PALMPRE, AVANT, SWEEX, PDNOVEL
from calibre.devices.folder_device.driver import FOLDER_DEVICE_FOR_CONFIG
from calibre.devices.kobo.driver import KOBO
@ -562,6 +562,7 @@ plugins += [
AVANT,
MENTOR,
SWEEX,
PDNOVEL,
ITUNES,
]
plugins += [x for x in list(locals().values()) if isinstance(x, type) and \

View File

@ -213,7 +213,7 @@ class KINDLE_DX(KINDLE2):
PRODUCT_ID = [0x0003]
BCD = [0x0100]
class Bookmark():
class Bookmark(): # {{{
'''
A simple class fetching bookmark data
Kindle-specific
@ -517,3 +517,6 @@ class Bookmark():
else:
print "unsupported bookmark_extension: %s" % self.bookmark_extension
# }}}

View File

@ -176,23 +176,22 @@ class KOBO(USBMS):
ImageID = row[0]
cursor.close()
cursor = connection.cursor()
if ContentType == 6:
# Delete the shortcover_pages first
cursor.execute('delete from shortcover_page where shortcoverid in (select ContentID from content where BookID = ?)', t)
#Delete the volume_shortcovers second
cursor.execute('delete from volume_shortcovers where volumeid = ?', t)
# Delete the chapters associated with the book next
t = (ContentID,ContentID,)
cursor.execute('delete from content where BookID = ? or ContentID = ?', t)
connection.commit()
cursor.close()
if ImageID != None:
cursor = connection.cursor()
if ContentType == 6:
# Delete the shortcover_pages first
cursor.execute('delete from shortcover_page where shortcoverid in (select ContentID from content where BookID = ?)', t)
#Delete the volume_shortcovers second
cursor.execute('delete from volume_shortcovers where volumeid = ?', t)
# Delete the chapters associated with the book next
t = (ContentID,ContentID,)
cursor.execute('delete from content where BookID = ? or ContentID = ?', t)
connection.commit()
cursor.close()
else:
print "Error condition ImageID was not found"
print "You likely tried to delete a book that the kobo has not yet added to the database"
@ -227,12 +226,16 @@ class KOBO(USBMS):
#print "kobo book"
ContentType = 6
ContentID = self.contentid_from_path(path, ContentType)
if extension == '.pdf' or extension == '.epub':
elif extension == '.pdf' or extension == '.epub':
# print "ePub or pdf"
ContentType = 16
#print "Path: " + path
ContentID = self.contentid_from_path(path, ContentType)
# print "ContentID: " + ContentID
else: # if extension == '.html' or extension == '.txt':
ContentType = 999 # Yet another hack: to get around Kobo changing how ContentID is stored
ContentID = self.contentid_from_path(path, ContentType)
ImageID = self.delete_via_sql(ContentID, ContentType)
#print " We would now delete the Images for" + ImageID
self.delete_images(ImageID)
@ -316,6 +319,11 @@ class KOBO(USBMS):
ContentID = ContentID.replace(self._main_prefix, '')
if self._card_a_prefix is not None:
ContentID = ContentID.replace(self._card_a_prefix, '')
elif ContentType == 999: # HTML Files
ContentID = path
ContentID = ContentID.replace(self._main_prefix, "/mnt/onboard/")
if self._card_a_prefix is not None:
ContentID = ContentID.replace(self._card_a_prefix, "/mnt/sd/")
else: # ContentType = 16
ContentID = path
ContentID = ContentID.replace(self._main_prefix, "file:///mnt/onboard/")

View File

@ -69,3 +69,21 @@ class SWEEX(USBMS):
EBOOK_DIR_MAIN = ''
SUPPORTS_SUB_DIRS = True
class PDNOVEL(USBMS):
name = 'Pandigital Novel device interface'
gui_name = 'PD Novel'
description = _('Communicate with the Pandigital Novel')
author = 'Kovid Goyal'
supported_platforms = ['windows', 'linux', 'osx']
FORMATS = ['epub', 'pdf']
VENDOR_ID = [0x18d1]
PRODUCT_ID = [0xb004]
BCD = [0x224]
VENDOR_NAME = 'ANDROID'
WINDOWS_MAIN_MEM = WINDOWS_CARD_A_MEM = '__UMS_COMPOSITE'
EBOOK_DIR_MAIN = 'eBooks'
SUPPORTS_SUB_DIRS = False

View File

@ -49,7 +49,6 @@ class CHMInput(InputFormatPlugin):
log.debug('stream.name=%s' % stream.name)
mainname = self._chmtohtml(tdir, chm_name, no_images, log)
mainpath = os.path.join(tdir, mainname)
#raw_input()
metadata = get_metadata_from_reader(self._chm_reader)
@ -141,10 +140,9 @@ class CHMInput(InputFormatPlugin):
log.debug('Found %d section nodes' % len(chapters))
htmlpath = os.path.splitext(hhcpath)[0] + ".html"
f = open(htmlpath, 'wb')
f.write('<html><head><meta http-equiv="Content-type"'
' content="text/html;charset=UTF-8" /></head><body>\n')
if chapters:
f.write('<html><head><meta http-equiv="Content-type"'
' content="text/html;charset=UTF-8" /></head><body>\n')
path0 = chapters[0][1]
subpath = os.path.dirname(path0)
@ -158,7 +156,9 @@ class CHMInput(InputFormatPlugin):
url = url.encode('utf-8')
f.write(url)
f.write("</body></html>")
f.write("</body></html>")
else:
f.write(hhcdata)
f.close()
return htmlpath

View File

@ -8,7 +8,7 @@ import os, re
from mimetypes import guess_type as guess_mimetype
from calibre.ebooks.BeautifulSoup import BeautifulSoup, NavigableString
from calibre.constants import iswindows
from calibre.constants import iswindows, filesystem_encoding
from calibre.utils.chm.chm import CHMFile
from calibre.utils.chm.chmlib import (
CHM_RESOLVE_SUCCESS, CHM_ENUMERATE_NORMAL,
@ -78,6 +78,8 @@ class CHMError(Exception):
class CHMReader(CHMFile):
def __init__(self, input, log):
CHMFile.__init__(self)
if isinstance(input, unicode):
input = input.encode(filesystem_encoding)
if not self.LoadCHM(input):
raise CHMError("Unable to open CHM file '%s'"%(input,))
self.log = log
@ -91,7 +93,6 @@ class CHMReader(CHMFile):
self.root, ext = os.path.splitext(self.topics.lstrip('/'))
self.hhc_path = self.root + ".hhc"
def _parse_toc(self, ul, basedir=os.getcwdu()):
toc = TOC(play_order=self._playorder, base_path=basedir, text='')
self._playorder += 1
@ -152,6 +153,8 @@ class CHMReader(CHMFile):
if f.lower() == self.hhc_path.lower():
self.hhc_path = f
break
if self.hhc_path not in files and files:
self.hhc_path = files[0]
def _reformat(self, data):
try:
@ -159,7 +162,7 @@ class CHMReader(CHMFile):
soup = BeautifulSoup(data)
except ValueError:
# hit some strange encoding problems...
print "Unable to parse html for cleaning, leaving it :("
self.log.exception("Unable to parse html for cleaning, leaving it")
return data
# nuke javascript...
[s.extract() for s in soup('script')]

View File

@ -58,6 +58,7 @@ class FormatState(object):
self.fsize = 3
self.ids = set()
self.valign = 'baseline'
self.nest = False
self.italic = False
self.bold = False
self.strikethrough = False
@ -233,9 +234,17 @@ class MobiMLizer(object):
inline = etree.SubElement(inline, XHTML('a'), href=href)
bstate.anchor = inline
if valign == 'super':
inline = etree.SubElement(inline, XHTML('sup'))
parent = inline
if istate.nest and bstate.inline is not None:
parent = bstate.inline
istate.nest = False
inline = etree.SubElement(parent, XHTML('sup'))
elif valign == 'sub':
inline = etree.SubElement(inline, XHTML('sub'))
parent = inline
if istate.nest and bstate.inline is not None:
parent = bstate.inline
istate.nest = False
inline = etree.SubElement(parent, XHTML('sub'))
elif fsize != 3:
inline = etree.SubElement(inline, XHTML('font'),
size=str(fsize))
@ -343,8 +352,10 @@ class MobiMLizer(object):
istate.family = 'serif'
valign = style['vertical-align']
if valign in ('super', 'text-top') or asfloat(valign) > 0:
istate.nest = istate.valign in ('sub', 'super')
istate.valign = 'super'
elif valign == 'sub' or asfloat(valign) < 0:
istate.nest = istate.valign in ('sub', 'super')
istate.valign = 'sub'
else:
istate.valign = 'baseline'

View File

@ -66,7 +66,7 @@ class DeleteMatchingFromDeviceDialog(QDialog, Ui_DeleteMatchingFromDeviceDialog)
self.explanation.setText('<p>'+_('All checked books will be '
'<b>permanently deleted</b> from your '
'device. Please verify the list.'+'</p>'))
'device. Please verify the list.')+'</p>')
self.buttonBox.accepted.connect(self.accepted)
self.table.cellClicked.connect(self.cell_clicked)
self.table.setSelectionMode(QAbstractItemView.NoSelection)

View File

@ -17,7 +17,7 @@ class ListWidgetItem(QListWidgetItem):
def data(self, role):
if role == Qt.DisplayRole:
if self.old_value != self.cur_value:
return _('%s (was %s)'%(self.cur_value, self.old_value))
return _('%s (was %s)')%(self.cur_value, self.old_value)
else:
return self.cur_value
elif role == Qt.EditRole:

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

@ -1071,8 +1071,13 @@ class ZipFile:
# Create all upper directories if necessary.
upperdirs = os.path.dirname(targetpath)
if upperdirs and os.path.exists(upperdirs) and not os.path.isdir(upperdirs):
os.unlink(upperdirs)
while upperdirs:
if os.path.exists(upperdirs):
if os.path.isdir(upperdirs):
break
os.remove(upperdirs)
upperdirs = os.path.dirname(upperdirs)
upperdirs = os.path.dirname(targetpath)
if upperdirs and not os.path.exists(upperdirs):
os.makedirs(upperdirs)

View File

@ -264,7 +264,7 @@ class BasicNewsRecipe(Recipe):
}
.article_description {
font-family: sans; text-indent: 0pt;
text-indent: 0pt;
}
a.article {

View File

@ -70,7 +70,10 @@ class EmbeddedContent(Template):
div.text = elements[0]
elements = list(elements)[1:]
for elem in elements:
elem.getparent().remove(elem)
if hasattr(elem, 'getparent'):
elem.getparent().remove(elem)
else:
elem = SPAN(elem)
div.append(elem)
class IndexTemplate(Template):