This commit is contained in:
Karthik 2014-07-19 00:06:36 +05:30
commit 8b6d7b5c40
6 changed files with 141 additions and 20 deletions

View File

@ -20,6 +20,64 @@
# new recipes:
# - title:
- version: 1.45.0
date: 2014-07-18
new features:
- title: "Edit Book: Add in-context help for HTML and CSS"
description: "Now, you can right click on any HTML/OPF/NCX tag name or CSS property and the editor will open some help for that item in your browser."
- title: "Book details panel: Make series and tags clickable. Clicking on them will search the calibre library for all books in the same series/ having the same tag"
tickets: [1341297]
- title: "Edit metadata dialog: Improve performance by only writing changed fields to the database when clicking OK or Next"
- title: "AZW3 Input: When converting from AZW3 files, use the high quality version of the image if the source AZW3 file contains both low and high quality images. These dual azw3 files are produced by kindlegen 2.9"
- title: "Edit Book: When right clicking on a link in the editor add a menu entry to open the link"
- title: "Edit Book: Search and replace panel: Add arrows to open the list of recently used search and replace expressions"
- title: "Driver for Motorola Milestone X2."
tickets: [1343704]
bug fixes:
- title: "AZW3: Preserve the page-progression-direction property when converting/editing/polishing AZW3 files"
- title: "AZW3 Input: Workaround broken AZW3 files produced by kindlegen that use uppercase attribute names."
tickets: [1341306]
- title: "PDF metadata: When updating the XMP metadata in PDF files, compress the XMP block written to the PDF. This is particularly useful when the PDF file has an existing XMP metadata block with very large amounts of data in it."
tickets: [1341549]
- title: "Fix searches on Yes/No columns using the terms ('blank', 'checked', 'unchecked') not working on non-English calibre installs"
- title: "Edit metadata dialog: Do not auto change the title sort field when clicking OK if the title was changed. Instead the title sort field must be changed explicitly."
- title: "Linux binary installer: Fix regression that caused ZSH completion to not be installed"
tickets: [1341240]
- title: "Edit Book: Spell check: When suggesting alternative for a hyphenated word, ensure the first suggestion is the word formed by removing the hyphen, if that is a valid word"
- title: "Get Books: Update the Woblink plugin to handle changes to the woblink website"
- title: "Edit Book: Fix replacement of hyphenated words in the spell checker not working"
- title: "Edit Book: Fix live syntax highlighting of links not being updated correctly after renaming an open file"
- title: "Edit Book: Fix regression that caused crash while syntax highlighting CSS stylesheets that contain url() tokens without enclosing quotes"
- title: "Linux binary: Do not fail on system with invalid locale info. Instead default to using the UTF-8 encoding on these systems."
tickets: [1343444]
improved recipes:
- The Economic Times India
- EPW
- Carta
- The Hindu
- F-Secure
- NOAA Online
- version: 1.44.0
date: 2014-07-11

View File

@ -337,7 +337,10 @@ class LinuxFreeze(Command):
enc = locale.nl_langinfo(locale.CODESET)
if not enc or enc.lower() == 'ascii':
enc = 'UTF-8'
enc = codecs.lookup(enc).name
try:
enc = codecs.lookup(enc).name
except LookupError:
enc = 'UTF-8'
sys.setdefaultencoding(enc)
del sys.setdefaultencoding

View File

@ -229,7 +229,18 @@ def parse_metadata(raw, namelist, zf):
raise ValueError('Could not find plugin class')
def get_plugin_info(raw):
def check_qt5_compatibility(zf, names):
uses_qt = False
for name in names:
if name.endswith('.py'):
raw = zf.read(name)
has_qt4 = b'PyQt4' in raw
uses_qt = uses_qt or has_qt4
if uses_qt and has_qt4 and b'PyQt5' not in raw:
return False
return True
def get_plugin_info(raw, check_for_qt5=False):
metadata = None
with zipfile.ZipFile(io.BytesIO(raw)) as zf:
names = {x.decode('utf-8') if isinstance(x, bytes) else x : x for x in zf.namelist()}
@ -248,6 +259,8 @@ def get_plugin_info(raw):
raw = zf.open(metadata).read()
ans = parse_metadata(raw, names, zf)
if isinstance(ans, dict):
if check_for_qt5:
ans['qt5'] = check_qt5_compatibility(zf, names)
return ans
# The plugin is importing its base class from somewhere else, le sigh
for mod, _ in ans:
@ -259,6 +272,8 @@ def get_plugin_info(raw):
raw = zf.open(names[mod]).read()
ans = parse_metadata(raw, names, zf)
if isinstance(ans, dict):
if check_for_qt5:
ans['qt5'] = check_qt5_compatibility(zf, names)
return ans
raise ValueError('Failed to find plugin class')
@ -498,6 +513,49 @@ def update_stats():
json.dump(stats, f, indent=2)
return stats
def check_for_qt5_incompatibility():
ok_plugins, bad_plugins = [], []
for name in os.listdir('.'):
if name.endswith('.zip') and not name.endswith('-deprecated.zip'):
with open(name, 'rb') as f:
info = get_plugin_info(f.read(), check_for_qt5=True)
if info['qt5']:
ok_plugins.append(info)
else:
bad_plugins.append(info)
plugs = ['<li>%s</li>' % x['name'] for x in bad_plugins]
gplugs = ('<li>%s</li>' % x['name'] for x in ok_plugins)
stats = '''
<!DOCTYPE html>
<html>
<head><meta charset="utf-8"><title>Stats for porting of calibre plugins to Qt 5</title>
<link rel="icon" type="image/x-icon" href="http://calibre-ebook.com/favicon.ico" />
<style type="text/css">
body { background-color: #eee; }
h1 img, h3 img { vertical-align: middle; margin-right: 0.5em; }
h1 { text-align: center }
</style>
</head>
<body>
<h1><img src="http://manual.calibre-ebook.com/_static/logo.png">Stats for porting of calibre plugins to Qt 5</h1>
<p>Number of Qt 5 compatible plugins: %s<br>Number of Qt 5 incompatible plugins: %s<br>Percentage of plugins ported: %.0f%%</p>
<h2>Plugins that have been ported</h2>
<ul>
%s
</ul>
<h2>Plugins still to be ported</h2>
<ul>
%s
</ul>
</body>
</html>
''' % (len(ok_plugins), len(bad_plugins), len(ok_plugins)/(len(ok_plugins) + len(bad_plugins)) * 100,
'\n'.join(sorted(gplugs, key=lambda x:x.lower())),
'\n'.join(sorted(plugs, key=lambda x:x.lower())))
with open('porting.html', 'wb') as f:
f.write(stats.encode('utf-8'))
def main():
try:
os.chdir(WORKDIR)
@ -519,6 +577,7 @@ def main():
plugins_index = load_plugins_index()
plugins_index = fetch_plugins(plugins_index)
create_index(plugins_index, stats)
check_for_qt5_incompatibility()
except:
import traceback
log('Failed to run at:', datetime.utcnow().isoformat())

View File

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

View File

@ -62,21 +62,22 @@ class ANDROID(USBMS):
},
# Motorola
0x22b8 : {0x41d9 : [0x216], 0x2d61 : [0x100], 0x2d67 : [0x100],
0x2de8 : [0x229],
0x41db : [0x216], 0x4285 : [0x216], 0x42a3 : [0x216],
0x4286 : [0x216], 0x42b3 : [0x216], 0x42b4 : [0x216],
0x7086 : [0x0226], 0x70a8: [0x9999], 0x42c4 : [0x216],
0x70c6 : [0x226],
0x4316 : [0x216],
0x4317 : [0x216],
0x42d6 : [0x216],
0x42d7 : [0x216],
0x42f7 : [0x216],
0x4365 : [0x216],
0x4366 : [0x216],
0x4371 : [0x216],
},
0x22b8 : {
0x41d9 : [0x216], 0x2d61 : [0x100], 0x2d67 : [0x100],
0x2de8 : [0x229],
0x41db : [0x216], 0x4285 : [0x216], 0x42a3 : [0x216],
0x4286 : [0x216], 0x42b3 : [0x216], 0x42b4 : [0x216],
0x7086 : [0x0226], 0x70a8: [0x9999], 0x42c4 : [0x216],
0x70c6 : [0x226], 0x70c7: [0x226],
0x4316 : [0x216],
0x4317 : [0x216],
0x42d6 : [0x216],
0x42d7 : [0x216],
0x42f7 : [0x216],
0x4365 : [0x216],
0x4366 : [0x216],
0x4371 : [0x216],
},
# Freescale
0x15a2 : {
0x0c01 : [0x226]

View File

@ -45,7 +45,7 @@ def find_pages(dir, sort_on_mtime=False, verbose=False):
:param sort_on_mtime: If True sort pages based on their last modified time.
Otherwise, sort alphabetically.
'''
extensions = ['jpeg', 'jpg', 'gif', 'png']
extensions = {'jpeg', 'jpg', 'gif', 'png', 'webp'}
pages = []
for datum in os.walk(dir):
for name in datum[-1]:
@ -229,7 +229,7 @@ class Progress(object):
def __call__(self, percent, msg=''):
self.done += 1
#msg = msg%os.path.basename(job.args[0])
# msg = msg%os.path.basename(job.args[0])
self.update(float(self.done)/self.total, msg)
def process_pages(pages, opts, update, tdir):