mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-09 03:04:10 -04:00
Merge from trunk
This commit is contained in:
commit
b670fe2194
@ -57,7 +57,7 @@ class ANDROID(USBMS):
|
|||||||
0x413c : { 0xb007 : [0x0100, 0x0224]},
|
0x413c : { 0xb007 : [0x0100, 0x0224]},
|
||||||
|
|
||||||
# LG
|
# LG
|
||||||
0x1004 : { 0x61cc : [0x100] },
|
0x1004 : { 0x61cc : [0x100], 0x61ce : [0x100] },
|
||||||
|
|
||||||
# Archos
|
# Archos
|
||||||
0x0e79 : {
|
0x0e79 : {
|
||||||
@ -78,6 +78,9 @@ class ANDROID(USBMS):
|
|||||||
# Xperia
|
# Xperia
|
||||||
0x13d3 : { 0x3304 : [0x0001, 0x0002] },
|
0x13d3 : { 0x3304 : [0x0001, 0x0002] },
|
||||||
|
|
||||||
|
# CREEL?? Also Nextbook
|
||||||
|
0x5e3 : { 0x726 : [0x222] },
|
||||||
|
|
||||||
}
|
}
|
||||||
EBOOK_DIR_MAIN = ['eBooks/import', 'wordplayer/calibretransfer', 'Books']
|
EBOOK_DIR_MAIN = ['eBooks/import', 'wordplayer/calibretransfer', 'Books']
|
||||||
EXTRA_CUSTOMIZATION_MESSAGE = _('Comma separated list of directories to '
|
EXTRA_CUSTOMIZATION_MESSAGE = _('Comma separated list of directories to '
|
||||||
|
@ -22,7 +22,7 @@ class CHMInput(InputFormatPlugin):
|
|||||||
def _chmtohtml(self, output_dir, chm_path, no_images, log):
|
def _chmtohtml(self, output_dir, chm_path, no_images, log):
|
||||||
from calibre.ebooks.chm.reader import CHMReader
|
from calibre.ebooks.chm.reader import CHMReader
|
||||||
log.debug('Opening CHM file')
|
log.debug('Opening CHM file')
|
||||||
rdr = CHMReader(chm_path, log)
|
rdr = CHMReader(chm_path, log, self.opts)
|
||||||
log.debug('Extracting CHM to %s' % output_dir)
|
log.debug('Extracting CHM to %s' % output_dir)
|
||||||
rdr.extract_content(output_dir)
|
rdr.extract_content(output_dir)
|
||||||
self._chm_reader = rdr
|
self._chm_reader = rdr
|
||||||
@ -32,13 +32,13 @@ class CHMInput(InputFormatPlugin):
|
|||||||
def convert(self, stream, options, file_ext, log, accelerators):
|
def convert(self, stream, options, file_ext, log, accelerators):
|
||||||
from calibre.ebooks.chm.metadata import get_metadata_from_reader
|
from calibre.ebooks.chm.metadata import get_metadata_from_reader
|
||||||
from calibre.customize.ui import plugin_for_input_format
|
from calibre.customize.ui import plugin_for_input_format
|
||||||
|
self.opts = options
|
||||||
|
|
||||||
log.debug('Processing CHM...')
|
log.debug('Processing CHM...')
|
||||||
with TemporaryDirectory('_chm2oeb') as tdir:
|
with TemporaryDirectory('_chm2oeb') as tdir:
|
||||||
html_input = plugin_for_input_format('html')
|
html_input = plugin_for_input_format('html')
|
||||||
for opt in html_input.options:
|
for opt in html_input.options:
|
||||||
setattr(options, opt.option.name, opt.recommended_value)
|
setattr(options, opt.option.name, opt.recommended_value)
|
||||||
options.input_encoding = 'utf-8'
|
|
||||||
no_images = False #options.no_images
|
no_images = False #options.no_images
|
||||||
chm_name = stream.name
|
chm_name = stream.name
|
||||||
#chm_data = stream.read()
|
#chm_data = stream.read()
|
||||||
@ -54,6 +54,7 @@ class CHMInput(InputFormatPlugin):
|
|||||||
|
|
||||||
odi = options.debug_pipeline
|
odi = options.debug_pipeline
|
||||||
options.debug_pipeline = None
|
options.debug_pipeline = None
|
||||||
|
options.input_encoding = 'utf-8'
|
||||||
# try a custom conversion:
|
# try a custom conversion:
|
||||||
#oeb = self._create_oebbook(mainpath, tdir, options, log, metadata)
|
#oeb = self._create_oebbook(mainpath, tdir, options, log, metadata)
|
||||||
# try using html converter:
|
# try using html converter:
|
||||||
|
@ -40,13 +40,14 @@ class CHMError(Exception):
|
|||||||
pass
|
pass
|
||||||
|
|
||||||
class CHMReader(CHMFile):
|
class CHMReader(CHMFile):
|
||||||
def __init__(self, input, log):
|
def __init__(self, input, log, opts):
|
||||||
CHMFile.__init__(self)
|
CHMFile.__init__(self)
|
||||||
if isinstance(input, unicode):
|
if isinstance(input, unicode):
|
||||||
input = input.encode(filesystem_encoding)
|
input = input.encode(filesystem_encoding)
|
||||||
if not self.LoadCHM(input):
|
if not self.LoadCHM(input):
|
||||||
raise CHMError("Unable to open CHM file '%s'"%(input,))
|
raise CHMError("Unable to open CHM file '%s'"%(input,))
|
||||||
self.log = log
|
self.log = log
|
||||||
|
self.opts = opts
|
||||||
self._sourcechm = input
|
self._sourcechm = input
|
||||||
self._contents = None
|
self._contents = None
|
||||||
self._playorder = 0
|
self._playorder = 0
|
||||||
@ -151,6 +152,8 @@ class CHMReader(CHMFile):
|
|||||||
break
|
break
|
||||||
|
|
||||||
def _reformat(self, data, htmlpath):
|
def _reformat(self, data, htmlpath):
|
||||||
|
if self.opts.input_encoding:
|
||||||
|
data = data.decode(self.opts.input_encoding)
|
||||||
try:
|
try:
|
||||||
data = xml_to_unicode(data, strip_encoding_pats=True)[0]
|
data = xml_to_unicode(data, strip_encoding_pats=True)[0]
|
||||||
soup = BeautifulSoup(data)
|
soup = BeautifulSoup(data)
|
||||||
|
@ -8,11 +8,7 @@ from __future__ import with_statement
|
|||||||
__license__ = 'GPL v3'
|
__license__ = 'GPL v3'
|
||||||
__copyright__ = '2008, Marshall T. Vandegrift <llasram@gmail.com>'
|
__copyright__ = '2008, Marshall T. Vandegrift <llasram@gmail.com>'
|
||||||
|
|
||||||
import os
|
import os, itertools, re, logging, copy, unicodedata
|
||||||
import itertools
|
|
||||||
import re
|
|
||||||
import logging
|
|
||||||
import copy
|
|
||||||
from weakref import WeakKeyDictionary
|
from weakref import WeakKeyDictionary
|
||||||
from xml.dom import SyntaxErr as CSSSyntaxError
|
from xml.dom import SyntaxErr as CSSSyntaxError
|
||||||
import cssutils
|
import cssutils
|
||||||
@ -234,8 +230,18 @@ class Stylizer(object):
|
|||||||
for elem in matches:
|
for elem in matches:
|
||||||
for x in elem.iter():
|
for x in elem.iter():
|
||||||
if x.text:
|
if x.text:
|
||||||
span = E.span(x.text[0])
|
punctuation_chars = []
|
||||||
span.tail = x.text[1:]
|
text = unicode(x.text)
|
||||||
|
while text:
|
||||||
|
if not unicodedata.category(text[0]).startswith('P'):
|
||||||
|
break
|
||||||
|
punctuation_chars.append(text[0])
|
||||||
|
text = text[1:]
|
||||||
|
|
||||||
|
special_text = u''.join(punctuation_chars) + \
|
||||||
|
(text[0] if text else u'')
|
||||||
|
span = E.span(special_text)
|
||||||
|
span.tail = text[1:]
|
||||||
x.text = None
|
x.text = None
|
||||||
x.insert(0, span)
|
x.insert(0, span)
|
||||||
self.style(span)._update_cssdict(cssdict)
|
self.style(span)._update_cssdict(cssdict)
|
||||||
|
@ -46,7 +46,8 @@ def get_pdf_printer(opts, for_comic=False):
|
|||||||
printer = QPrinter(QPrinter.HighResolution)
|
printer = QPrinter(QPrinter.HighResolution)
|
||||||
custom_size = get_custom_size(opts)
|
custom_size = get_custom_size(opts)
|
||||||
|
|
||||||
if opts.output_profile.short_name == 'default':
|
if opts.output_profile.short_name == 'default' or \
|
||||||
|
opts.output_profile.width > 10000:
|
||||||
if custom_size is None:
|
if custom_size is None:
|
||||||
printer.setPaperSize(paper_size(opts.paper_size))
|
printer.setPaperSize(paper_size(opts.paper_size))
|
||||||
else:
|
else:
|
||||||
|
@ -4,7 +4,7 @@ __copyright__ = '2008, Kovid Goyal <kovid at kovidgoyal.net>'
|
|||||||
import time, os
|
import time, os
|
||||||
|
|
||||||
from PyQt4.Qt import SIGNAL, QUrl, QAbstractListModel, Qt, \
|
from PyQt4.Qt import SIGNAL, QUrl, QAbstractListModel, Qt, \
|
||||||
QVariant
|
QVariant, QFont
|
||||||
|
|
||||||
from calibre.web.feeds.recipes import compile_recipe, custom_recipes
|
from calibre.web.feeds.recipes import compile_recipe, custom_recipes
|
||||||
from calibre.web.feeds.news import AutomaticNewsRecipe
|
from calibre.web.feeds.news import AutomaticNewsRecipe
|
||||||
@ -83,6 +83,9 @@ class UserProfiles(ResizableDialog, Ui_Dialog):
|
|||||||
self._model = self.model = CustomRecipeModel(recipe_model)
|
self._model = self.model = CustomRecipeModel(recipe_model)
|
||||||
self.available_profiles.setModel(self._model)
|
self.available_profiles.setModel(self._model)
|
||||||
self.available_profiles.currentChanged = self.current_changed
|
self.available_profiles.currentChanged = self.current_changed
|
||||||
|
f = QFont()
|
||||||
|
f.setStyleHint(f.Monospace)
|
||||||
|
self.source_code.setFont(f)
|
||||||
|
|
||||||
self.connect(self.remove_feed_button, SIGNAL('clicked(bool)'),
|
self.connect(self.remove_feed_button, SIGNAL('clicked(bool)'),
|
||||||
self.added_feeds.remove_selected_items)
|
self.added_feeds.remove_selected_items)
|
||||||
|
@ -410,11 +410,6 @@ p, li { white-space: pre-wrap; }
|
|||||||
<verstretch>0</verstretch>
|
<verstretch>0</verstretch>
|
||||||
</sizepolicy>
|
</sizepolicy>
|
||||||
</property>
|
</property>
|
||||||
<property name="font">
|
|
||||||
<font>
|
|
||||||
<family>DejaVu Sans Mono</family>
|
|
||||||
</font>
|
|
||||||
</property>
|
|
||||||
<property name="lineWrapMode">
|
<property name="lineWrapMode">
|
||||||
<enum>QTextEdit::NoWrap</enum>
|
<enum>QTextEdit::NoWrap</enum>
|
||||||
</property>
|
</property>
|
||||||
|
@ -17,17 +17,19 @@ from calibre.gui2.viewer.bookmarkmanager import BookmarkManager
|
|||||||
from calibre.gui2.widgets import ProgressIndicator
|
from calibre.gui2.widgets import ProgressIndicator
|
||||||
from calibre.gui2.main_window import MainWindow
|
from calibre.gui2.main_window import MainWindow
|
||||||
from calibre.gui2 import Application, ORG_NAME, APP_UID, choose_files, \
|
from calibre.gui2 import Application, ORG_NAME, APP_UID, choose_files, \
|
||||||
info_dialog, error_dialog, open_url, available_height, gprefs
|
info_dialog, error_dialog, open_url, available_height
|
||||||
from calibre.ebooks.oeb.iterator import EbookIterator
|
from calibre.ebooks.oeb.iterator import EbookIterator
|
||||||
from calibre.ebooks import DRMError
|
from calibre.ebooks import DRMError
|
||||||
from calibre.constants import islinux, isfreebsd, isosx, filesystem_encoding
|
from calibre.constants import islinux, isfreebsd, isosx, filesystem_encoding
|
||||||
from calibre.utils.config import Config, StringConfig, dynamic
|
from calibre.utils.config import Config, StringConfig, JSONConfig
|
||||||
from calibre.gui2.search_box import SearchBox2
|
from calibre.gui2.search_box import SearchBox2
|
||||||
from calibre.ebooks.metadata import MetaInformation
|
from calibre.ebooks.metadata import MetaInformation
|
||||||
from calibre.customize.ui import available_input_formats
|
from calibre.customize.ui import available_input_formats
|
||||||
from calibre.gui2.viewer.dictionary import Lookup
|
from calibre.gui2.viewer.dictionary import Lookup
|
||||||
from calibre import as_unicode, force_unicode, isbytestring
|
from calibre import as_unicode, force_unicode, isbytestring
|
||||||
|
|
||||||
|
vprefs = JSONConfig('viewer')
|
||||||
|
|
||||||
class TOCItem(QStandardItem):
|
class TOCItem(QStandardItem):
|
||||||
|
|
||||||
def __init__(self, toc):
|
def __init__(self, toc):
|
||||||
@ -303,7 +305,7 @@ class EbookViewer(MainWindow, Ui_EbookViewer):
|
|||||||
m = self.open_history_menu
|
m = self.open_history_menu
|
||||||
m.clear()
|
m.clear()
|
||||||
count = 0
|
count = 0
|
||||||
for path in gprefs.get('viewer_open_history', []):
|
for path in vprefs.get('viewer_open_history', []):
|
||||||
if count > 9:
|
if count > 9:
|
||||||
break
|
break
|
||||||
if os.path.exists(path):
|
if os.path.exists(path):
|
||||||
@ -315,17 +317,17 @@ class EbookViewer(MainWindow, Ui_EbookViewer):
|
|||||||
return MainWindow.closeEvent(self, e)
|
return MainWindow.closeEvent(self, e)
|
||||||
|
|
||||||
def save_state(self):
|
def save_state(self):
|
||||||
state = str(self.saveState(self.STATE_VERSION))
|
state = bytearray(self.saveState(self.STATE_VERSION))
|
||||||
dynamic['viewer_toolbar_state'] = state
|
vprefs['viewer_toolbar_state'] = state
|
||||||
dynamic.set('viewer_window_geometry', self.saveGeometry())
|
vprefs.set('viewer_window_geometry', bytearray(self.saveGeometry()))
|
||||||
if self.current_book_has_toc:
|
if self.current_book_has_toc:
|
||||||
dynamic.set('viewer_toc_isvisible', bool(self.toc.isVisible()))
|
vprefs.set('viewer_toc_isvisible', bool(self.toc.isVisible()))
|
||||||
if self.toc.isVisible():
|
if self.toc.isVisible():
|
||||||
dynamic.set('viewer_splitter_state',
|
vprefs.set('viewer_splitter_state',
|
||||||
bytearray(self.splitter.saveState()))
|
bytearray(self.splitter.saveState()))
|
||||||
|
|
||||||
def restore_state(self):
|
def restore_state(self):
|
||||||
state = dynamic.get('viewer_toolbar_state', None)
|
state = vprefs.get('viewer_toolbar_state', None)
|
||||||
if state is not None:
|
if state is not None:
|
||||||
try:
|
try:
|
||||||
state = QByteArray(state)
|
state = QByteArray(state)
|
||||||
@ -676,13 +678,13 @@ class EbookViewer(MainWindow, Ui_EbookViewer):
|
|||||||
self.action_table_of_contents.setChecked(False)
|
self.action_table_of_contents.setChecked(False)
|
||||||
if isbytestring(pathtoebook):
|
if isbytestring(pathtoebook):
|
||||||
pathtoebook = force_unicode(pathtoebook, filesystem_encoding)
|
pathtoebook = force_unicode(pathtoebook, filesystem_encoding)
|
||||||
vh = gprefs.get('viewer_open_history', [])
|
vh = vprefs.get('viewer_open_history', [])
|
||||||
try:
|
try:
|
||||||
vh.remove(pathtoebook)
|
vh.remove(pathtoebook)
|
||||||
except:
|
except:
|
||||||
pass
|
pass
|
||||||
vh.insert(0, pathtoebook)
|
vh.insert(0, pathtoebook)
|
||||||
gprefs.set('viewer_open_history', vh[:50])
|
vprefs.set('viewer_open_history', vh[:50])
|
||||||
self.build_recent_menu()
|
self.build_recent_menu()
|
||||||
|
|
||||||
self.action_table_of_contents.setDisabled(not self.iterator.toc)
|
self.action_table_of_contents.setDisabled(not self.iterator.toc)
|
||||||
@ -739,13 +741,13 @@ class EbookViewer(MainWindow, Ui_EbookViewer):
|
|||||||
c = config().parse()
|
c = config().parse()
|
||||||
self.splitter.setSizes([1, 300])
|
self.splitter.setSizes([1, 300])
|
||||||
if c.remember_window_size:
|
if c.remember_window_size:
|
||||||
wg = dynamic.get('viewer_window_geometry', None)
|
wg = vprefs.get('viewer_window_geometry', None)
|
||||||
if wg is not None:
|
if wg is not None:
|
||||||
self.restoreGeometry(wg)
|
self.restoreGeometry(wg)
|
||||||
ss = dynamic.get('viewer_splitter_state', None)
|
ss = vprefs.get('viewer_splitter_state', None)
|
||||||
if ss is not None:
|
if ss is not None:
|
||||||
self.splitter.restoreState(ss)
|
self.splitter.restoreState(ss)
|
||||||
self.show_toc_on_open = dynamic.get('viewer_toc_isvisible', False)
|
self.show_toc_on_open = vprefs.get('viewer_toc_isvisible', False)
|
||||||
av = available_height() - 30
|
av = available_height() - 30
|
||||||
if self.height() > av:
|
if self.height() > av:
|
||||||
self.resize(self.width(), av)
|
self.resize(self.width(), av)
|
||||||
|
@ -193,8 +193,8 @@ class RecursiveFetcher(object):
|
|||||||
data = None
|
data = None
|
||||||
self.log.debug('Fetching', url)
|
self.log.debug('Fetching', url)
|
||||||
delta = time.time() - self.last_fetch_at
|
delta = time.time() - self.last_fetch_at
|
||||||
if delta < self.delay:
|
if delta < self.delay:
|
||||||
time.sleep(delta)
|
time.sleep(self.delay - delta)
|
||||||
if isinstance(url, unicode):
|
if isinstance(url, unicode):
|
||||||
url = url.encode('utf-8')
|
url = url.encode('utf-8')
|
||||||
# Not sure is this is really needed as I think mechanize
|
# Not sure is this is really needed as I think mechanize
|
||||||
|
Loading…
x
Reference in New Issue
Block a user