mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-09 03:04:10 -04:00
IGN:Updated translations and various minor bug fixes
This commit is contained in:
parent
252dd342e0
commit
58a09d73f0
@ -2,8 +2,30 @@ from __future__ import with_statement
|
||||
__license__ = 'GPL v3'
|
||||
__copyright__ = '2008, Kovid Goyal <kovid at kovidgoyal.net>'
|
||||
|
||||
import sys
|
||||
|
||||
from calibre.ptempfile import PersistentTemporaryFile
|
||||
|
||||
class Plugin(object):
|
||||
'''
|
||||
A calibre plugin. Useful members include:
|
||||
|
||||
* ``self.plugin_path``: Stores path to the zip file that contains
|
||||
this plugin or None if it is a builtin
|
||||
plugin
|
||||
* ``self.site_customization``: Stores a customization string entered
|
||||
by the user.
|
||||
|
||||
Methods that should be overridden in sub classes:
|
||||
|
||||
* :method:`initialize`
|
||||
* :method:`customization_help`
|
||||
|
||||
Useful methods:
|
||||
|
||||
* :method:`temporary_file`
|
||||
|
||||
'''
|
||||
#: List of platforms this plugin works on
|
||||
#: For example: ``['windows', 'osx', 'linux']
|
||||
supported_platforms = []
|
||||
@ -29,25 +51,95 @@ class Plugin(object):
|
||||
|
||||
#: The earliest version of calibre this plugin requires
|
||||
minimum_calibre_version = (0, 4, 118)
|
||||
|
||||
type = _('Base')
|
||||
|
||||
def __init__(self, plugin_path):
|
||||
self.plugin_path = plugin_path
|
||||
self.site_customization = None
|
||||
|
||||
def initialize(self):
|
||||
'''
|
||||
Called once when calibre plugins are initialized. Plugins are re-initialized
|
||||
every time a new plugin is added.
|
||||
|
||||
:param plugin_path: Path to the zip file this plugin is distributed in.
|
||||
'''
|
||||
self.plugin_path = plugin_path
|
||||
Perform any plugin specific initialization here, such as extracting
|
||||
resources from the plugin zip file. The path to the zip file is
|
||||
available as ``self.plugin_path``.
|
||||
|
||||
def customization_help(self):
|
||||
Note that ``self.site_customization`` is **not** available at this point.
|
||||
'''
|
||||
pass
|
||||
|
||||
@classmethod
|
||||
def customization_help(cls):
|
||||
'''
|
||||
Return a string giving help on how to customize this plugin.
|
||||
By default raise a :class:`NotImplementedError`, which indicates that
|
||||
the plugin does not require customization.
|
||||
the plugin does not require customization.
|
||||
|
||||
If you re-implement this method in your subclass, the user will
|
||||
be asked to enter a string as customization for this plugin.
|
||||
The customization string will be available as
|
||||
``self.site_customization``.
|
||||
|
||||
Site customization could be anything, for example, the path to
|
||||
a needed binary on the user's computer.
|
||||
'''
|
||||
raise NotImplementedError
|
||||
|
||||
def run(self, path_to_ebook, site_customization=''):
|
||||
def temporary_file(self, suffix):
|
||||
'''
|
||||
Return a file-like object that is a temporary file on the file system.
|
||||
This file will remain available even after being closed and will only
|
||||
be removed on interpreter shutdown. Use the ``name`` member of the
|
||||
returned object to access the full path to the created temporary file.
|
||||
|
||||
:param suffix: The suffix that the temporary file will have.
|
||||
'''
|
||||
return PersistentTemporaryFile(suffix)
|
||||
|
||||
@classmethod
|
||||
def is_customizable(cls):
|
||||
try:
|
||||
cls.customization_help()
|
||||
return True
|
||||
except NotImplementedError:
|
||||
return False
|
||||
|
||||
def __enter__(self, *args):
|
||||
if self.plugin_path is not None:
|
||||
sys.path.insert(0, self.plugin_path)
|
||||
|
||||
def __exit__(self, *args):
|
||||
if self.plugin_path in sys.path:
|
||||
sys.path.remove(self.plugin_path)
|
||||
|
||||
|
||||
class FileTypePlugin(Plugin):
|
||||
'''
|
||||
A plugin that is associated with a particular set of file types.
|
||||
'''
|
||||
|
||||
#: List of file types for which this plugin should be run
|
||||
#: For example: ``set(['lit', 'mobi', 'prc'])``
|
||||
file_types = set([])
|
||||
|
||||
#: If True, this plugin is run when books are added
|
||||
#: to the database
|
||||
on_import = False
|
||||
|
||||
#: If True, this plugin is run whenever an any2* tool
|
||||
#: is used, on the file passed to the any2* tool.
|
||||
on_preprocess = False
|
||||
|
||||
#: If True, this plugin is run after an any2* tool is
|
||||
#: used, on the final file produced by the tool.
|
||||
on_postprocess = False
|
||||
|
||||
type = _('File type')
|
||||
|
||||
def run(self, path_to_ebook):
|
||||
'''
|
||||
Run the plugin. Must be implemented in subclasses.
|
||||
It should perform whatever modifications are required
|
||||
@ -57,12 +149,10 @@ class Plugin(object):
|
||||
it should raise an Exception. The default implementation
|
||||
simply return the path to the original ebook.
|
||||
|
||||
:param path_to_ebook: Absolute path to the ebook
|
||||
:param site_customization: A (possibly empty) string that the user
|
||||
has specified to customize this plugin.
|
||||
For example, it could be the path to a needed
|
||||
executable on her system.
|
||||
|
||||
The modified ebook file should be created with the
|
||||
:method:`temporary_file` method.
|
||||
|
||||
:param path_to_ebook: Absolute path to the ebook.
|
||||
:return: Absolute path to the modified ebook.
|
||||
'''
|
||||
# Default implementation does nothing
|
||||
|
29
src/calibre/customize/builtins.py
Normal file
29
src/calibre/customize/builtins.py
Normal file
@ -0,0 +1,29 @@
|
||||
from __future__ import with_statement
|
||||
__license__ = 'GPL v3'
|
||||
__copyright__ = '2008, Kovid Goyal <kovid at kovidgoyal.net>'
|
||||
|
||||
import textwrap
|
||||
from calibre.customize import FileTypePlugin
|
||||
from calibre.constants import __version__
|
||||
|
||||
class HTML2ZIP(FileTypePlugin):
|
||||
name = 'HTML to ZIP'
|
||||
author = 'Kovid Goyal'
|
||||
description = textwrap.dedent(_('''\
|
||||
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.\
|
||||
'''))
|
||||
version = tuple(map(int, (__version__.split('.'))[:3]))
|
||||
file_types = ['html', 'htm', 'xhtml', 'xhtm']
|
||||
supported_platforms = ['windows', 'osx', 'linux']
|
||||
on_import = True
|
||||
|
||||
def run(self, htmlfile):
|
||||
of = self.temporary_file('_plugin_html2zip.zip')
|
||||
from calibre.ebooks.html import gui_main as html2oeb
|
||||
html2oeb(htmlfile, of)
|
||||
return of.name
|
||||
|
||||
|
||||
plugins = [HTML2ZIP]
|
@ -1,28 +0,0 @@
|
||||
from __future__ import with_statement
|
||||
__license__ = 'GPL v3'
|
||||
__copyright__ = '2008, Kovid Goyal <kovid at kovidgoyal.net>'
|
||||
|
||||
from calibre.customize import Plugin as PluginBase
|
||||
|
||||
class Plugin(PluginBase):
|
||||
'''
|
||||
A plugin that is associated with a particular set of file types.
|
||||
'''
|
||||
|
||||
#: List of file types for which this plugin should be run
|
||||
#: For example: ``['lit', 'mobi', 'prc']``
|
||||
file_types = []
|
||||
|
||||
#: If True, this plugin is run when books are added
|
||||
#: to the database
|
||||
on_import = False
|
||||
|
||||
#: If True, this plugin is run whenever an any2* tool
|
||||
#: is used, on the file passed to the any2* tool.
|
||||
on_preprocess = False
|
||||
|
||||
#: If True, this plugin is run after an any2* tool is
|
||||
#: used, on the final file produced by the tool.
|
||||
on_postprocess = False
|
||||
|
||||
|
@ -4,8 +4,8 @@ __copyright__ = '2008, Kovid Goyal <kovid at kovidgoyal.net>'
|
||||
|
||||
import os, shutil, traceback, functools, sys
|
||||
|
||||
from calibre.customize import Plugin
|
||||
from calibre.customize.filetype import Plugin as FileTypePlugin
|
||||
from calibre.customize import Plugin, FileTypePlugin
|
||||
from calibre.customize.builtins import plugins as builtin_plugins
|
||||
from calibre.constants import __version__, iswindows, isosx
|
||||
from calibre.utils.config import make_config_dir, Config, ConfigProxy, \
|
||||
plugin_dir, OptionParser
|
||||
@ -24,7 +24,7 @@ from zipfile import ZipFile
|
||||
def _config():
|
||||
c = Config('customize')
|
||||
c.add_opt('plugins', default={}, help=_('Installed plugins'))
|
||||
c.add_opt('filetype_mapping', default={}, help=_('Maping for filetype plugins'))
|
||||
c.add_opt('filetype_mapping', default={}, help=_('Mapping for filetype plugins'))
|
||||
c.add_opt('plugin_customization', default={}, help=_('Local plugin customization'))
|
||||
c.add_opt('disabled_plugins', default=set([]), help=_('Disabled plugins'))
|
||||
|
||||
@ -100,12 +100,13 @@ def _run_filetype_plugins(path_to_file, ft, occasion='preprocess'):
|
||||
for plugin in occasion.get(ft, []):
|
||||
if is_disabled(plugin):
|
||||
continue
|
||||
sc = customization.get(plugin.name, '')
|
||||
try:
|
||||
nfp = plugin.run(path_to_file, sc)
|
||||
except:
|
||||
print 'Running file type plugin %s failed with traceback:'%plugin.name
|
||||
traceback.print_exc()
|
||||
plugin.site_customization = customization.get(plugin.name, '')
|
||||
with plugin:
|
||||
try:
|
||||
nfp = plugin.run(path_to_file)
|
||||
except:
|
||||
print 'Running file type plugin %s failed with traceback:'%plugin.name
|
||||
traceback.print_exc()
|
||||
return nfp
|
||||
|
||||
run_plugins_on_import = functools.partial(_run_filetype_plugins,
|
||||
@ -117,10 +118,10 @@ run_plugins_on_postprocess = functools.partial(_run_filetype_plugins,
|
||||
|
||||
|
||||
def initialize_plugin(plugin, path_to_zip_file):
|
||||
print 'Initializing plugin', plugin.name
|
||||
try:
|
||||
plugin(path_to_zip_file)
|
||||
except Exception:
|
||||
print 'Failed to initialize plugin:', plugin.name, plugin.version
|
||||
tb = traceback.format_exc()
|
||||
raise InvalidPlugin((_('Initialization of plugin %s failed with traceback:')
|
||||
%tb) + '\n'+tb)
|
||||
@ -164,10 +165,10 @@ def enable_plugin(plugin_or_name):
|
||||
def initialize_plugins():
|
||||
global _initialized_plugins
|
||||
_initialized_plugins = []
|
||||
for zfp in config['plugins'].values():
|
||||
for zfp in list(config['plugins'].values()) + builtin_plugins:
|
||||
try:
|
||||
plugin = load_plugin(zfp)
|
||||
initialize_plugin(plugin, zfp)
|
||||
plugin = load_plugin(zfp) if not isinstance(zfp, type) else zfp
|
||||
initialize_plugin(plugin, zfp if not isinstance(zfp, type) else zfp)
|
||||
_initialized_plugins.append(plugin)
|
||||
except:
|
||||
print 'Failed to initialize plugin...'
|
||||
@ -195,6 +196,9 @@ def option_parser():
|
||||
help=_('Disable the named plugin'))
|
||||
return parser
|
||||
|
||||
def initialized_plugins():
|
||||
return _initialized_plugins
|
||||
|
||||
def main(args=sys.argv):
|
||||
parser = option_parser()
|
||||
if len(args) < 2:
|
||||
@ -216,11 +220,19 @@ def main(args=sys.argv):
|
||||
if opts.disable_plugin is not None:
|
||||
disable_plugin(opts.disable_plugin.strip())
|
||||
if opts.list_plugins:
|
||||
print 'Name\tVersion\tDisabled\tLocal Customization'
|
||||
for plugin in _initialized_plugins:
|
||||
print '%s\t%s\t%s\t%s'%(plugin.name, plugin.version, is_disabled(plugin),
|
||||
config['plugin_customization'].get(plugin.name))
|
||||
print '\t', plugin.customization_help()
|
||||
fmt = '%-15s%-20s%-15s%-15s%s'
|
||||
print fmt%tuple(('Type|Name|Version|Disabled|Site Customization'.split('|')))
|
||||
print
|
||||
for plugin in initialized_plugins():
|
||||
print fmt%(
|
||||
plugin.type, plugin.name,
|
||||
plugin.version, is_disabled(plugin),
|
||||
config['plugin_customization'].get(plugin.name, '')
|
||||
)
|
||||
print '\t', plugin.description
|
||||
if plugin.is_customizable():
|
||||
print '\t', plugin.customization_help()
|
||||
print
|
||||
|
||||
return 0
|
||||
|
||||
|
@ -21,8 +21,8 @@ Run an embedded python interpreter.
|
||||
'Module specifications are of the form full.name.of.module,path_to_module.py', default=None
|
||||
)
|
||||
parser.add_option('-c', '--command', help='Run python code.', default=None)
|
||||
parser.add_option('-g', '--run-gui', help='Run the GUI', default=False,
|
||||
action='store_true')
|
||||
parser.add_option('-g', '--gui', default=False, action='store_true',
|
||||
help='Run the GUI',)
|
||||
parser.add_option('--migrate', action='store_true', default=False,
|
||||
help='Migrate old database. Needs two arguments. Path to library1.db and path to new library folder.')
|
||||
return parser
|
||||
@ -74,9 +74,9 @@ def migrate(old, new):
|
||||
|
||||
def main(args=sys.argv):
|
||||
opts, args = option_parser().parse_args(args)
|
||||
if opts.run_gui:
|
||||
if opts.gui:
|
||||
from calibre.gui2.main import main
|
||||
main()
|
||||
main(['calibre'])
|
||||
elif opts.update_module:
|
||||
mod, path = opts.update_module.partition(',')[0], opts.update_module.partition(',')[-1]
|
||||
update_module(mod, os.path.expanduser(path))
|
||||
|
@ -1044,11 +1044,12 @@ def main(args=sys.argv):
|
||||
|
||||
return 0
|
||||
|
||||
def gui_main(htmlfile):
|
||||
def gui_main(htmlfile, pt=None):
|
||||
'''
|
||||
Convenience wrapper for use in recursively importing HTML files.
|
||||
'''
|
||||
pt = PersistentTemporaryFile('_html2oeb_gui.oeb.zip')
|
||||
if pt is None:
|
||||
pt = PersistentTemporaryFile('_html2oeb_gui.oeb.zip')
|
||||
pt.close()
|
||||
opts = '''
|
||||
pretty_print = True
|
||||
|
@ -14,7 +14,6 @@ from calibre import __author__, islinux, iswindows, isosx
|
||||
from calibre.startup import get_lang
|
||||
from calibre.utils.config import Config, ConfigProxy, dynamic
|
||||
import calibre.resources as resources
|
||||
from calibre.ebooks.html import gui_main as html2oeb
|
||||
|
||||
NONE = QVariant() #: Null value to return from the data function of item models
|
||||
|
||||
@ -389,14 +388,6 @@ def pixmap_to_data(pixmap, format='JPEG'):
|
||||
pixmap.save(buf, format)
|
||||
return str(ba.data())
|
||||
|
||||
html_pat = re.compile(r'\.x{0,1}htm(l{0,1})\s*$', re.IGNORECASE)
|
||||
def import_format(path):
|
||||
if html_pat.search(path) is not None:
|
||||
try:
|
||||
return html2oeb(path), 'zip'
|
||||
except:
|
||||
traceback.print_exc()
|
||||
return None, None
|
||||
|
||||
try:
|
||||
from calibre.utils.single_qt_application import SingleApplication
|
||||
|
@ -1,32 +1,111 @@
|
||||
__license__ = 'GPL v3'
|
||||
__copyright__ = '2008, Kovid Goyal <kovid at kovidgoyal.net>'
|
||||
import os, re, time
|
||||
import os, re, time, textwrap
|
||||
|
||||
from PyQt4.QtGui import QDialog, QMessageBox, QListWidgetItem, QIcon, \
|
||||
from PyQt4.Qt import QDialog, QMessageBox, QListWidgetItem, QIcon, \
|
||||
QDesktopServices, QVBoxLayout, QLabel, QPlainTextEdit, \
|
||||
QStringListModel
|
||||
from PyQt4.QtCore import SIGNAL, QTimer, Qt, QSize, QVariant, QUrl
|
||||
QStringListModel, QAbstractItemModel, \
|
||||
SIGNAL, QTimer, Qt, QSize, QVariant, QUrl, \
|
||||
QModelIndex
|
||||
|
||||
from calibre.constants import islinux, iswindows
|
||||
from calibre.gui2.dialogs.config_ui import Ui_Dialog
|
||||
from calibre.gui2 import qstring_to_unicode, choose_dir, error_dialog, config, \
|
||||
warning_dialog, ALL_COLUMNS
|
||||
ALL_COLUMNS, NONE
|
||||
from calibre.utils.config import prefs
|
||||
from calibre.gui2.widgets import FilenamePattern
|
||||
from calibre.gui2.library import BooksModel
|
||||
from calibre.ebooks import BOOK_EXTENSIONS
|
||||
from calibre.ebooks.epub.iterator import is_supported
|
||||
from calibre.library import server_config
|
||||
from calibre.customize.ui import initialized_plugins, is_disabled
|
||||
|
||||
class PluginModel(QAbstractItemModel):
|
||||
|
||||
def __init__(self, *args):
|
||||
QAbstractItemModel.__init__(self, *args)
|
||||
self.icon = QVariant(QIcon(':/images/plugins.svg'))
|
||||
self.populate()
|
||||
|
||||
def populate(self):
|
||||
self._data = {}
|
||||
for plugin in initialized_plugins():
|
||||
if plugin.type not in self._data:
|
||||
self._data[plugin.type] = [plugin]
|
||||
else:
|
||||
self._data[plugin.type].append(plugin)
|
||||
self.categories = sorted(self._data.keys())
|
||||
|
||||
def index(self, row, column, parent):
|
||||
if not self.hasIndex(row, column, parent):
|
||||
return QModelIndex()
|
||||
|
||||
if parent.isValid():
|
||||
return self.createIndex(row, column, parent.row())
|
||||
else:
|
||||
return self.createIndex(row, column, -1)
|
||||
|
||||
def parent(self, index):
|
||||
if not index.isValid() or index.internalId() == -1:
|
||||
return QModelIndex()
|
||||
return self.createIndex(index.internalId(), 0, -1)
|
||||
|
||||
def rowCount(self, parent):
|
||||
if not parent.isValid():
|
||||
return len(self.categories)
|
||||
if parent.internalId() == -1:
|
||||
category = self.categories[parent.row()]
|
||||
return len(self._data[category])
|
||||
return 0
|
||||
|
||||
def columnCount(self, parent):
|
||||
return 1
|
||||
|
||||
def index_to_plugin(self, index):
|
||||
category = self.categories[index.parent().row()]
|
||||
return self._data[category][index.row()]
|
||||
|
||||
def flags(self, index):
|
||||
if not index.isValid():
|
||||
return 0
|
||||
if index.internalId() == -1:
|
||||
return Qt.ItemIsEnabled
|
||||
flags = Qt.ItemIsSelectable
|
||||
if not is_disabled(self.data(index, Qt.UserRole)):
|
||||
flags |= Qt.ItemIsEnabled
|
||||
return flags
|
||||
|
||||
def data(self, index, role):
|
||||
if not index.isValid():
|
||||
return NONE
|
||||
if index.internalId() == -1:
|
||||
if role == Qt.DisplayRole:
|
||||
category = self.categories[index.row()]
|
||||
return QVariant(category + _(' plugins'))
|
||||
else:
|
||||
plugin = self.index_to_plugin(index)
|
||||
if role == Qt.DisplayRole:
|
||||
ver = '.'.join(map(str, plugin.version))
|
||||
desc = '\n'.join(textwrap.wrap(plugin.description, 70))
|
||||
return QVariant('%s (%s) by %s\n%s'%(plugin.name, ver, plugin.author, desc))
|
||||
if role == Qt.DecorationRole:
|
||||
return self.icon
|
||||
if role == Qt.UserRole:
|
||||
return plugin
|
||||
return NONE
|
||||
|
||||
|
||||
|
||||
class CategoryModel(QStringListModel):
|
||||
|
||||
def __init__(self, *args):
|
||||
QStringListModel.__init__(self, *args)
|
||||
self.setStringList([_('General'), _('Interface'), _('Advanced'),
|
||||
_('Content\nServer')])
|
||||
_('Content\nServer'), _('Plugins')])
|
||||
self.icons = list(map(QVariant, map(QIcon,
|
||||
[':/images/dialog_information.svg', ':/images/lookfeel.svg',
|
||||
':/images/view.svg', ':/images/network-server.svg'])))
|
||||
':/images/view.svg', ':/images/network-server.svg',
|
||||
':/images/plugins.svg'])))
|
||||
|
||||
def data(self, index, role):
|
||||
if role == Qt.DecorationRole:
|
||||
@ -139,6 +218,8 @@ class ConfigDialog(QDialog, Ui_Dialog):
|
||||
self.priority.setVisible(iswindows)
|
||||
self.priority_label.setVisible(iswindows)
|
||||
self.category_view.setCurrentIndex(self._category_model.index(0))
|
||||
self._plugin_model = PluginModel()
|
||||
self.plugin_view.setModel(self._plugin_model)
|
||||
|
||||
def up_column(self):
|
||||
idx = self.columns.currentRow()
|
||||
|
@ -72,7 +72,7 @@
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="currentIndex" >
|
||||
<number>0</number>
|
||||
<number>4</number>
|
||||
</property>
|
||||
<widget class="QWidget" name="page_3" >
|
||||
<layout class="QVBoxLayout" name="verticalLayout" >
|
||||
@ -767,6 +767,111 @@
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<widget class="QWidget" name="page_5" >
|
||||
<layout class="QVBoxLayout" name="verticalLayout_6" >
|
||||
<item>
|
||||
<widget class="QLabel" name="label_8" >
|
||||
<property name="text" >
|
||||
<string>Here you can customize the behavior of Calibre by controlling what plugins it uses.</string>
|
||||
</property>
|
||||
<property name="wordWrap" >
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QTreeView" name="plugin_view" >
|
||||
<property name="iconSize" >
|
||||
<size>
|
||||
<width>32</width>
|
||||
<height>32</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="animated" >
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="headerHidden" >
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_6" >
|
||||
<item>
|
||||
<widget class="QPushButton" name="toggle_plugin" >
|
||||
<property name="text" >
|
||||
<string>Enable/&Disable plugin</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="customize_plugin" >
|
||||
<property name="text" >
|
||||
<string>&Customize plugin</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QGroupBox" name="groupBox_4" >
|
||||
<property name="title" >
|
||||
<string>Add new plugin</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_5" >
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_5" >
|
||||
<item>
|
||||
<widget class="QLabel" name="label_14" >
|
||||
<property name="text" >
|
||||
<string>Plugin &file:</string>
|
||||
</property>
|
||||
<property name="buddy" >
|
||||
<cstring>plugin_path</cstring>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLineEdit" name="plugin_path" />
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QToolButton" name="button_plugin_browse" >
|
||||
<property name="text" >
|
||||
<string>...</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_4" >
|
||||
<item>
|
||||
<spacer name="horizontalSpacer_2" >
|
||||
<property name="orientation" >
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0" >
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="button_plugin_add" >
|
||||
<property name="text" >
|
||||
<string>&Add</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
|
@ -49,11 +49,8 @@ class JobsDialog(QDialog, Ui_JobsDialog):
|
||||
self.connect(self.running_time_timer, SIGNAL('timeout()'), self.update_running_time)
|
||||
self.running_time_timer.start(1000)
|
||||
|
||||
def update_running_time(self):
|
||||
model = self.model
|
||||
for row, job in enumerate(model.jobs):
|
||||
if job.is_running:
|
||||
self.jobs_view.dataChanged(model.index(row, 3), model.index(row, 3))
|
||||
def update_running_time(self, *args):
|
||||
self.model.running_time_updated()
|
||||
|
||||
def kill_job(self):
|
||||
for index in self.jobs_view.selectedIndexes():
|
||||
|
@ -11,7 +11,7 @@ from PyQt4.QtGui import QPixmap, QListWidgetItem, QErrorMessage, QDialog
|
||||
|
||||
|
||||
from calibre.gui2 import qstring_to_unicode, error_dialog, file_icon_provider, \
|
||||
choose_files, pixmap_to_data, choose_images, import_format
|
||||
choose_files, pixmap_to_data, choose_images
|
||||
from calibre.gui2.dialogs.metadata_single_ui import Ui_MetadataSingleDialog
|
||||
from calibre.gui2.dialogs.fetch_metadata import FetchMetadata
|
||||
from calibre.gui2.dialogs.tag_editor import TagEditor
|
||||
@ -21,6 +21,7 @@ from calibre.ebooks.metadata import authors_to_sort_string, string_to_authors, a
|
||||
from calibre.ebooks.metadata.library_thing import login, cover_from_isbn, LibraryThingError
|
||||
from calibre import islinux
|
||||
from calibre.utils.config import prefs
|
||||
from calibre.customize.ui import run_plugins_on_import
|
||||
|
||||
class Format(QListWidgetItem):
|
||||
def __init__(self, parent, ext, size, path=None):
|
||||
@ -84,9 +85,7 @@ class MetadataSingleDialog(QDialog, Ui_MetadataSingleDialog):
|
||||
QErrorMessage(self.window).showMessage("You do not have "+\
|
||||
"permission to read the file: " + _file)
|
||||
continue
|
||||
nf = import_format(_file)[0]
|
||||
if nf is not None:
|
||||
_file = nf
|
||||
_file = run_plugins_on_import(_file, os.path.splitext(_file)[1].lower())
|
||||
size = os.stat(_file).st_size
|
||||
ext = os.path.splitext(_file)[1].lower()
|
||||
if '.' in ext:
|
||||
|
@ -2254,7 +2254,7 @@
|
||||
id="mask7160"
|
||||
maskUnits="userSpaceOnUse">
|
||||
<path
|
||||
style="opacity:1;fill:url(#radialGradient7164);fill-opacity:1;stroke:none;stroke-width:0.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:1.08779998;stroke-opacity:1"
|
||||
style="opacity:1;fill-opacity:1;stroke:none;stroke-width:0.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:1.08779998;stroke-opacity:1"
|
||||
d="M 137.37423,-51.650649 C 136.90963,-51.650649 136.53048,-51.183286 136.53048,-50.619399 L 136.53048,-0.18189907 C 141.47984,0.40821793 146.5415,0.72435094 151.68673,0.72435094 C 164.60291,0.72435094 176.96094,-1.191205 188.40548,-4.713149 L 188.40548,-50.619399 C 188.40548,-51.183286 188.02634,-51.650649 187.56173,-51.650649 L 137.37423,-51.650649 z "
|
||||
id="path7162" />
|
||||
</mask>
|
||||
|
Before Width: | Height: | Size: 168 KiB After Width: | Height: | Size: 168 KiB |
694
src/calibre/gui2/images/plugins.svg
Normal file
694
src/calibre/gui2/images/plugins.svg
Normal file
@ -0,0 +1,694 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Generator: Adobe Illustrator 13.0.2, SVG Export Plug-In . SVG Version: 6.00 Build 14948) -->
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://web.resource.org/cc/"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
version="1.0"
|
||||
id="Layer_1"
|
||||
x="0px"
|
||||
y="0px"
|
||||
width="128"
|
||||
height="128"
|
||||
viewBox="0 0 112 112"
|
||||
enable-background="new 0 0 112 112"
|
||||
xml:space="preserve"
|
||||
sodipodi:version="0.32"
|
||||
inkscape:version="0.45.1"
|
||||
sodipodi:docname="preferences-plugin.svg.svgz"
|
||||
sodipodi:docbase="/home/david/Desktop"
|
||||
inkscape:output_extension="org.inkscape.output.svgz.inkscape"><metadata
|
||||
id="metadata95"><rdf:RDF><cc:Work
|
||||
rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" /></cc:Work></rdf:RDF></metadata><defs
|
||||
id="defs93"><linearGradient
|
||||
inkscape:collect="always"
|
||||
id="linearGradient13107"><stop
|
||||
style="stop-color:#000000;stop-opacity:1;"
|
||||
offset="0"
|
||||
id="stop13109" /><stop
|
||||
style="stop-color:#000000;stop-opacity:0;"
|
||||
offset="1"
|
||||
id="stop13111" /></linearGradient><linearGradient
|
||||
id="linearGradient7263"><stop
|
||||
style="stop-color:#ffffff;stop-opacity:0;"
|
||||
offset="0"
|
||||
id="stop7265" /><stop
|
||||
style="stop-color:#ffffff;stop-opacity:0.48453608;"
|
||||
offset="1"
|
||||
id="stop7267" /></linearGradient><linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#SVGID_9_"
|
||||
id="linearGradient3216"
|
||||
x1="1.999"
|
||||
y1="55.862"
|
||||
x2="109.998"
|
||||
y2="55.862"
|
||||
gradientUnits="userSpaceOnUse" /><linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#SVGID_9_"
|
||||
id="linearGradient3218"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
x1="1.999"
|
||||
y1="55.862"
|
||||
x2="109.998"
|
||||
y2="55.862" /><linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#SVGID_9_"
|
||||
id="linearGradient3222"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
x1="1.999"
|
||||
y1="55.862"
|
||||
x2="109.998"
|
||||
y2="55.862" /><linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#SVGID_9_"
|
||||
id="linearGradient3226"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
x1="1.999"
|
||||
y1="55.862"
|
||||
x2="109.998"
|
||||
y2="55.862" /><linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#SVGID_9_"
|
||||
id="linearGradient3230"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
x1="1.999"
|
||||
y1="55.862"
|
||||
x2="109.998"
|
||||
y2="55.862" /><linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#SVGID_9_"
|
||||
id="linearGradient3234"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
x1="1.999"
|
||||
y1="55.862"
|
||||
x2="109.998"
|
||||
y2="55.862" /><filter
|
||||
inkscape:collect="always"
|
||||
id="filter3248"><feGaussianBlur
|
||||
inkscape:collect="always"
|
||||
stdDeviation="0.5392541"
|
||||
id="feGaussianBlur3250" /></filter><linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#SVGID_9_"
|
||||
id="linearGradient3304"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
x1="1.999"
|
||||
y1="55.862"
|
||||
x2="109.998"
|
||||
y2="55.862" /><linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#SVGID_9_"
|
||||
id="linearGradient3306"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
x1="1.999"
|
||||
y1="55.862"
|
||||
x2="109.998"
|
||||
y2="55.862" /><linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#SVGID_9_"
|
||||
id="linearGradient3310"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
x1="1.999"
|
||||
y1="55.862"
|
||||
x2="109.998"
|
||||
y2="55.862" /><linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#SVGID_9_"
|
||||
id="linearGradient3314"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
x1="1.999"
|
||||
y1="55.862"
|
||||
x2="109.998"
|
||||
y2="55.862" /><linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#SVGID_9_"
|
||||
id="linearGradient3318"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
x1="1.999"
|
||||
y1="55.862"
|
||||
x2="109.998"
|
||||
y2="55.862" /><linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#SVGID_9_"
|
||||
id="linearGradient3322"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
x1="1.999"
|
||||
y1="55.862"
|
||||
x2="109.998"
|
||||
y2="55.862" /><filter
|
||||
inkscape:collect="always"
|
||||
id="filter4299"><feGaussianBlur
|
||||
inkscape:collect="always"
|
||||
stdDeviation="0.26962705"
|
||||
id="feGaussianBlur4301" /></filter><linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#SVGID_9_"
|
||||
id="linearGradient4328"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
x1="88.745003"
|
||||
y1="55.154892"
|
||||
x2="94.44165"
|
||||
y2="95.81353" /><linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#SVGID_9_"
|
||||
id="linearGradient4334"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
x1="91.39418"
|
||||
y1="55.862"
|
||||
x2="89.845459"
|
||||
y2="26.322001" /><linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#SVGID_9_"
|
||||
id="linearGradient4338"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
x1="56.799774"
|
||||
y1="11.643"
|
||||
x2="80.800003"
|
||||
y2="26.163515" /><filter
|
||||
inkscape:collect="always"
|
||||
id="filter6290"><feGaussianBlur
|
||||
inkscape:collect="always"
|
||||
stdDeviation="2.24"
|
||||
id="feGaussianBlur6292" /></filter><linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient4344"
|
||||
id="linearGradient9215"
|
||||
x1="75.195961"
|
||||
y1="-4"
|
||||
x2="94.433243"
|
||||
y2="113.6292"
|
||||
gradientUnits="userSpaceOnUse" /><filter
|
||||
inkscape:collect="always"
|
||||
id="filter12134"><feGaussianBlur
|
||||
inkscape:collect="always"
|
||||
stdDeviation="2.4"
|
||||
id="feGaussianBlur12136" /></filter><linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient13107"
|
||||
id="linearGradient13113"
|
||||
x1="46.91169"
|
||||
y1="116"
|
||||
x2="48.325901"
|
||||
y2="-2.5101759"
|
||||
gradientUnits="userSpaceOnUse" /><linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient13107"
|
||||
id="linearGradient13161"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
x1="46.91169"
|
||||
y1="116"
|
||||
x2="48.325901"
|
||||
y2="-2.5101759" /><linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient13107"
|
||||
id="linearGradient13163"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
x1="46.91169"
|
||||
y1="116"
|
||||
x2="48.325901"
|
||||
y2="-2.5101759" /><linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient4344"
|
||||
id="linearGradient13165"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
x1="75.195961"
|
||||
y1="-4"
|
||||
x2="94.433243"
|
||||
y2="113.6292" /><linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient4344"
|
||||
id="linearGradient13167"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
x1="75.195961"
|
||||
y1="-4"
|
||||
x2="94.433243"
|
||||
y2="113.6292" /><linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#SVGID_9_"
|
||||
id="linearGradient13175"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
x1="91.39418"
|
||||
y1="55.862"
|
||||
x2="89.845459"
|
||||
y2="26.322001" /><linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#SVGID_9_"
|
||||
id="linearGradient13179"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
x1="88.745003"
|
||||
y1="55.154892"
|
||||
x2="94.44165"
|
||||
y2="95.81353" /><linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#SVGID_9_"
|
||||
id="linearGradient13183"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
x1="1.999"
|
||||
y1="55.862"
|
||||
x2="109.998"
|
||||
y2="55.862" /><linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#SVGID_9_"
|
||||
id="linearGradient13187"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
x1="1.999"
|
||||
y1="55.862"
|
||||
x2="109.998"
|
||||
y2="55.862" /><linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#SVGID_9_"
|
||||
id="linearGradient13191"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
x1="56.799774"
|
||||
y1="11.643"
|
||||
x2="80.800003"
|
||||
y2="26.163515" /><linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#SVGID_9_"
|
||||
id="linearGradient13221"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="matrix(1.009217,0,0,0.9999274,-0.5151412,-5.9972184)"
|
||||
x1="35.38496"
|
||||
y1="13.143368"
|
||||
x2="70.239304"
|
||||
y2="69.509804" /><linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient7263"
|
||||
id="linearGradient13223"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
x1="1.999"
|
||||
y1="35.897853"
|
||||
x2="109.99844"
|
||||
y2="35.897853"
|
||||
gradientTransform="matrix(1.0092222,0,0,0.9999326,-0.5151516,-5.9975816)" /><linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#SVGID_2_"
|
||||
id="linearGradient13243"
|
||||
x1="62.578949"
|
||||
y1="127.77134"
|
||||
x2="58.966991"
|
||||
y2="-31.68124"
|
||||
gradientUnits="userSpaceOnUse" /><linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#SVGID_9_"
|
||||
id="linearGradient13245"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
x1="1.999"
|
||||
y1="55.862"
|
||||
x2="109.998"
|
||||
y2="55.862" /><linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#SVGID_9_"
|
||||
id="linearGradient13247"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
x1="23.533312"
|
||||
y1="107.83435"
|
||||
x2="28.680723"
|
||||
y2="78.514572" /><linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#SVGID_9_"
|
||||
id="linearGradient13249"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
x1="1.999"
|
||||
y1="55.862"
|
||||
x2="109.998"
|
||||
y2="55.862" /><linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#SVGID_9_"
|
||||
id="linearGradient13251"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
x1="1.999"
|
||||
y1="55.862"
|
||||
x2="109.998"
|
||||
y2="55.862" /><linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#SVGID_9_"
|
||||
id="linearGradient13257"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
x1="88.745003"
|
||||
y1="55.154892"
|
||||
x2="94.44165"
|
||||
y2="95.81353" /><linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#SVGID_9_"
|
||||
id="linearGradient13259"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
x1="63.870842"
|
||||
y1="86.705002"
|
||||
x2="109.998"
|
||||
y2="55.862" /><linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#SVGID_9_"
|
||||
id="linearGradient13265"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
x1="56.799774"
|
||||
y1="11.643"
|
||||
x2="80.800003"
|
||||
y2="26.163515" /><linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#SVGID_9_"
|
||||
id="linearGradient13267"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
x1="45.839619"
|
||||
y1="18.38534"
|
||||
x2="109.998"
|
||||
y2="55.862" /><linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#SVGID_9_"
|
||||
id="linearGradient13269"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
x1="91.39418"
|
||||
y1="55.862"
|
||||
x2="89.845459"
|
||||
y2="26.322001" /><linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#SVGID_9_"
|
||||
id="linearGradient13271"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
x1="63.870842"
|
||||
y1="21.023001"
|
||||
x2="109.998"
|
||||
y2="55.862" /><filter
|
||||
inkscape:collect="always"
|
||||
id="filter18426"><feGaussianBlur
|
||||
inkscape:collect="always"
|
||||
stdDeviation="1.12"
|
||||
id="feGaussianBlur18428" /></filter></defs><sodipodi:namedview
|
||||
inkscape:window-height="713"
|
||||
inkscape:window-width="1024"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:pageopacity="0.0"
|
||||
guidetolerance="10.0"
|
||||
gridtolerance="10.0"
|
||||
objecttolerance="10.0"
|
||||
borderopacity="1.0"
|
||||
bordercolor="#666666"
|
||||
pagecolor="#ffffff"
|
||||
id="base"
|
||||
width="128px"
|
||||
height="128px"
|
||||
inkscape:zoom="2.8284271"
|
||||
inkscape:cx="56"
|
||||
inkscape:cy="62.542861"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="0"
|
||||
inkscape:current-layer="g3266" />
|
||||
|
||||
<linearGradient
|
||||
id="SVGID_2_"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
x1="55.998501"
|
||||
y1="122.1953"
|
||||
x2="55.998501"
|
||||
y2="-27.688801">
|
||||
<stop
|
||||
offset="0"
|
||||
style="stop-color:#00892C"
|
||||
id="stop13" />
|
||||
<stop
|
||||
offset="0.0791"
|
||||
style="stop-color:#259E34"
|
||||
id="stop15" />
|
||||
<stop
|
||||
offset="0.1681"
|
||||
style="stop-color:#48B23B"
|
||||
id="stop17" />
|
||||
<stop
|
||||
offset="0.2522"
|
||||
style="stop-color:#61C041"
|
||||
id="stop19" />
|
||||
<stop
|
||||
offset="0.3286"
|
||||
style="stop-color:#71C944"
|
||||
id="stop21" />
|
||||
<stop
|
||||
offset="0.3901"
|
||||
style="stop-color:#71d73a;stop-opacity:1;"
|
||||
id="stop23" />
|
||||
<stop
|
||||
offset="1"
|
||||
style="stop-color:#00892C"
|
||||
id="stop25" />
|
||||
</linearGradient>
|
||||
|
||||
|
||||
<linearGradient
|
||||
id="SVGID_8_"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
x1="65.537102"
|
||||
y1="106.5479"
|
||||
x2="65.537102"
|
||||
y2="2.0360999">
|
||||
<stop
|
||||
offset="0"
|
||||
style="stop-color:#F8FFBF"
|
||||
id="stop77" />
|
||||
<stop
|
||||
offset="0.4"
|
||||
style="stop-color:#FFFFFF"
|
||||
id="stop79" />
|
||||
<stop
|
||||
offset="1"
|
||||
style="stop-color:#F8FFBF"
|
||||
id="stop81" />
|
||||
</linearGradient>
|
||||
|
||||
<linearGradient
|
||||
id="SVGID_9_"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
x1="29.021"
|
||||
y1="6.0723"
|
||||
x2="70.239304"
|
||||
y2="69.509804">
|
||||
<stop
|
||||
offset="0"
|
||||
style="stop-color:#FFFFFF"
|
||||
id="stop86" />
|
||||
<stop
|
||||
offset="1"
|
||||
style="stop-color:#ffffff;stop-opacity:0;"
|
||||
id="stop88" />
|
||||
</linearGradient>
|
||||
<g
|
||||
id="g3266"
|
||||
transform="matrix(0.875,0,0,0.875,6.9999998,7)"><g
|
||||
style="opacity:0.5;fill:#000000;fill-opacity:1;stroke:url(#linearGradient13161);stroke-width:8;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;filter:url(#filter12134)"
|
||||
id="g11155"
|
||||
transform="translate(0,-2)">
|
||||
<linearGradient
|
||||
style="stroke:url(#linearGradient13113)"
|
||||
y2="144.4818"
|
||||
x2="126.7421"
|
||||
y1="5.7275"
|
||||
x1="19.7563"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
id="linearGradient11157">
|
||||
<stop
|
||||
id="stop11159"
|
||||
style="stop-color:#64ba32;stop-opacity:1;stroke:url(#linearGradient13113)"
|
||||
offset="0" />
|
||||
<stop
|
||||
id="stop11161"
|
||||
style="stop-color:#00892C;stroke:url(#linearGradient13113)"
|
||||
offset="1" />
|
||||
</linearGradient>
|
||||
<path
|
||||
id="path11163"
|
||||
d="M 63.718,0 C 71.232,0 78.445,0.652 82,6 C 85.555,11.348 75.978,14.839 78.645,19.459 C 85.19,22.815 101.277,22.06 112,22 C 112,22 112,53.03 112,53.376 C 106.208,56.712 100.089,51.931 95,51 C 85.395,55.274 85.348,78.515 95,82.68 C 100.722,83.13 100.419,77.649 107,78.96 C 112.013,85.694 112,112 112,112 L 22,112 C 22,112 22.422,83.565 19.538,80.682 C 16.654,77.799 14.483,85.954 7.26,84.41 C 2.943,82.345 0,78.605 0,68 C 0,57.395 2.812,52.71 7.068,50.316 C 13.635,48.93 14.699,57.379 18.178,53.9 C 21.657,50.421 22.07,34.826 22,22 C 32.448,22 45.674,24 52,19 C 52.428,13.665 48.199,13.695 48,9 C 49.149,2.904 56.22,0.222 63.718,0 z "
|
||||
clip-rule="evenodd"
|
||||
style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:url(#linearGradient13163);stroke-width:8;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
|
||||
</g><g
|
||||
id="g4342"
|
||||
style="fill:none;stroke:url(#linearGradient13165);stroke-width:8;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
transform="translate(0,-4)">
|
||||
<linearGradient
|
||||
id="linearGradient4344"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
x1="19.7563"
|
||||
y1="5.7275"
|
||||
x2="126.7421"
|
||||
y2="144.4818"
|
||||
style="stroke:url(#linearGradient9215)">
|
||||
<stop
|
||||
offset="0"
|
||||
style="stop-color:#64ba32;stop-opacity:1;"
|
||||
id="stop4346" />
|
||||
<stop
|
||||
offset="1"
|
||||
style="stop-color:#00892C;stroke:url(#linearGradient9215)"
|
||||
id="stop4348" />
|
||||
</linearGradient>
|
||||
<path
|
||||
style="fill:none;fill-rule:evenodd;stroke:url(#linearGradient13167);stroke-width:8;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
clip-rule="evenodd"
|
||||
d="M 63.718,0 C 71.232,0 78.445,0.652 82,6 C 85.555,11.348 75.978,14.839 78.645,19.459 C 85.19,22.815 101.277,22.06 112,22 C 112,22 112,53.03 112,53.376 C 106.208,56.712 100.089,51.931 95,51 C 85.395,55.274 85.348,78.515 95,82.68 C 100.722,83.13 100.419,77.649 107,78.96 C 112.013,85.694 112,112 112,112 L 22,112 C 22,112 22.422,83.565 19.538,80.682 C 16.654,77.799 14.483,85.954 7.26,84.41 C 2.943,82.345 0,78.605 0,68 C 0,57.395 2.812,52.71 7.068,50.316 C 13.635,48.93 14.699,57.379 18.178,53.9 C 21.657,50.421 22.07,34.826 22,22 C 32.448,22 45.674,24 52,19 C 52.428,13.665 48.199,13.695 48,9 C 49.149,2.904 56.22,0.222 63.718,0 z "
|
||||
id="path4350" />
|
||||
</g><g
|
||||
id="g3"
|
||||
style="filter:url(#filter18426);fill:url(#linearGradient13243)"
|
||||
transform="translate(0,-4)">
|
||||
<linearGradient
|
||||
y2="144.4818"
|
||||
x2="126.7421"
|
||||
y1="5.7275"
|
||||
x1="19.7563"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
id="SVGID_1_"
|
||||
style="fill:url(#linearGradient13243)">
|
||||
<stop
|
||||
id="stop6"
|
||||
style="stop-color:#76CC45;fill:url(#linearGradient13243)"
|
||||
offset="0" />
|
||||
<stop
|
||||
id="stop8"
|
||||
style="stop-color:#00892C;fill:url(#linearGradient13243)"
|
||||
offset="1" />
|
||||
</linearGradient>
|
||||
<path
|
||||
id="path10"
|
||||
d="M 63.718,0 C 71.232,0 78.445,0.652 82,6 C 85.555,11.348 75.978,14.839 78.645,19.459 C 85.19,22.815 101.277,22.06 112,22 C 112,22 112,53.03 112,53.376 C 106.208,56.712 100.089,51.931 95,51 C 85.395,55.274 85.348,78.515 95,82.68 C 100.722,83.13 100.419,77.649 107,78.96 C 112.013,85.694 112,112 112,112 L 22,112 C 22,112 22.422,83.565 19.538,80.682 C 16.654,77.799 14.483,85.954 7.26,84.41 C 2.943,82.345 0,78.605 0,68 C 0,57.395 2.812,52.71 7.068,50.316 C 13.635,48.93 14.699,57.379 18.178,53.9 C 21.657,50.421 22.07,34.826 22,22 C 32.448,22 45.674,24 52,19 C 52.428,13.665 48.199,13.695 48,9 C 49.149,2.904 56.22,0.222 63.718,0 z "
|
||||
clip-rule="evenodd"
|
||||
style="fill:url(#linearGradient13243);fill-rule:evenodd" />
|
||||
</g><path
|
||||
id="path90"
|
||||
d="M 108.47928,18.045036 C 108.47121,18.045036 108.46414,18.045036 108.45708,18.045036 L 107.81521,18.053036 C 105.52429,18.084034 103.11328,18.115032 100.68005,18.115032 C 88.864141,18.115032 81.849073,17.229095 77.934321,15.239241 L 77.4065,14.96926 L 77.107772,14.460297 C 75.306319,11.364522 76.910974,8.8507039 79.038404,6.1039029 C 80.439197,4.2960347 80.948851,3.5030919 81.02858,2.6521537 C 81.049773,2.4281699 81.030598,2.2031862 80.9761,1.9852021 C 80.907474,1.7072222 80.767192,1.4132435 80.562321,1.1072657 C 77.722385,-3.1224273 71.824521,-3.994364 63.779044,-3.9963639 C 61.025899,-3.9093702 51.906615,-3.1664241 50.081951,2.6851512 C 49.984057,3.0041281 49.964882,3.3441034 50.03149,3.6710797 C 50.244435,4.7130036 50.809597,5.3829555 51.522103,6.2298944 C 52.749312,7.6837885 54.27222,9.4956574 53.977528,13.160391 L 53.908902,14.028328 L 53.217588,14.569289 C 48.912269,17.942044 42.37557,18.396011 36.548351,18.396011 C 34.030355,18.396011 31.426576,18.294019 28.850044,18.195025 C 27.809541,18.154029 26.791242,18.114032 25.799182,18.081034 C 25.77597,18.081034 25.753767,18.079034 25.730555,18.079034 C 25.209799,18.079034 24.708218,18.28002 24.330771,18.637994 C 23.937176,19.012966 23.716157,19.528929 23.71212,20.06889 C 23.599089,42.061294 21.398995,47.195921 19.260464,49.316767 C 18.284552,50.279697 17.279372,50.747663 16.18639,50.747663 C 14.451546,50.747663 13.214247,49.531751 12.11319,48.44883 L 11.91942,48.260844 L 11.54702,47.90087 C 10.410641,46.825948 9.4296827,46.161996 8.0591661,46.161996 C 7.658507,46.161996 7.2174791,46.281987 6.8824192,46.503971 C 3.2118971,48.951793 1.5022835,53.875437 1.5022835,61.997847 C 1.5022835,62.619802 1.5133849,63.212759 1.5345785,63.780717 C 31.217668,64.093694 70.03518,58.029135 110.49772,33.866889 L 110.49772,20.045892 C 110.49772,19.51193 110.28275,18.999967 109.89824,18.622995 C 109.5218,18.254021 109.01013,18.045036 108.47928,18.045036 z "
|
||||
clip-rule="evenodd"
|
||||
style="fill:url(#linearGradient13221);fill-rule:evenodd;stroke:url(#linearGradient13223);stroke-width:1.00456667" /><g
|
||||
id="g31"
|
||||
style="fill:url(#linearGradient13269);filter:url(#filter4299)"
|
||||
transform="translate(0,-6)">
|
||||
<linearGradient
|
||||
id="SVGID_3_"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
x1="73.623001"
|
||||
y1="23.672899"
|
||||
x2="118.9906"
|
||||
y2="23.672899"
|
||||
style="fill:url(#linearGradient3216)">
|
||||
<stop
|
||||
offset="0"
|
||||
style="stop-color:#FFFFFF;fill:url(#linearGradient3216)"
|
||||
id="stop34" />
|
||||
<stop
|
||||
offset="1"
|
||||
style="stop-color:#000000;fill:url(#linearGradient3216)"
|
||||
id="stop36" />
|
||||
</linearGradient>
|
||||
<path
|
||||
clip-rule="evenodd"
|
||||
d="M 77.314,21.023 C 77.438,21.49 77.628,21.966 77.913,22.46 L 78.209,22.969 L 78.732,23.239 C 82.611,25.229 89.562,26.115 101.27,26.115 C 103.681,26.115 106.071,26.084 108.34,26.053 L 108.976,26.045 C 108.984,26.045 108.991,26.045 108.998,26.045 C 109.353,26.045 109.696,26.147 109.998,26.322 L 109.998,26.045 C 109.998,25.511 109.785,24.999 109.404,24.622 C 109.031,24.253 108.524,24.044 107.998,24.044 C 107.99,24.044 107.983,24.044 107.976,24.044 L 107.34,24.052 C 105.07,24.083 102.681,24.114 100.27,24.114 C 88.562,24.114 81.611,23.228 77.732,21.238 L 77.314,21.023 z "
|
||||
id="path38"
|
||||
style="fill:url(#linearGradient13271);fill-rule:evenodd" />
|
||||
</g><g
|
||||
id="g40"
|
||||
style="fill:url(#linearGradient13257);filter:url(#filter4299)"
|
||||
transform="translate(2,-6)">
|
||||
<linearGradient
|
||||
id="SVGID_4_"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
x1="86.693398"
|
||||
y1="83.060501"
|
||||
x2="111.9058"
|
||||
y2="83.060501"
|
||||
style="fill:url(#linearGradient3216)">
|
||||
<stop
|
||||
offset="0"
|
||||
style="stop-color:#FFFFFF;fill:url(#linearGradient3216)"
|
||||
id="stop43" />
|
||||
<stop
|
||||
offset="1"
|
||||
style="stop-color:#000000;fill:url(#linearGradient3216)"
|
||||
id="stop45" />
|
||||
</linearGradient>
|
||||
<path
|
||||
clip-rule="evenodd"
|
||||
d="M 95.208,86.515 L 95.513,86.648 L 95.842,86.672 C 96.125,86.694 96.395,86.705 96.652,86.705 C 99.594,86.705 101.274,85.371 102.622,84.301 C 103.601,83.521 104.245,83.038 105.18,82.843 C 105.317,82.815 105.451,82.802 105.585,82.802 C 106.084,82.802 106.547,83.005 106.91,83.332 C 106.755,82.863 106.595,82.417 106.426,82.02 C 106.108,81.27 105.374,80.802 104.585,80.802 C 104.451,80.802 104.316,80.815 104.18,80.843 C 103.245,81.038 102.602,81.521 101.622,82.301 C 100.274,83.371 98.595,84.705 95.652,84.705 C 95.395,84.705 95.126,84.694 94.842,84.672 L 94.513,84.648 L 94.208,84.515 C 91.836,83.493 90.052,81.66 88.745,79.415 C 90.08,82.559 92.163,85.202 95.208,86.515 z "
|
||||
id="path47"
|
||||
style="fill:url(#linearGradient13259);fill-rule:evenodd" />
|
||||
</g><g
|
||||
id="g49"
|
||||
style="fill:url(#linearGradient13249);filter:url(#filter4299)"
|
||||
transform="translate(0,-6)">
|
||||
<linearGradient
|
||||
id="SVGID_5_"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
x1="-3.9907"
|
||||
y1="47.521"
|
||||
x2="69.618896"
|
||||
y2="47.521"
|
||||
style="fill:url(#linearGradient3216)">
|
||||
<stop
|
||||
offset="0"
|
||||
style="stop-color:#FFFFFF;fill:url(#linearGradient3216)"
|
||||
id="stop52" />
|
||||
<stop
|
||||
offset="1"
|
||||
style="stop-color:#000000;fill:url(#linearGradient3216)"
|
||||
id="stop54" />
|
||||
</linearGradient>
|
||||
<path
|
||||
clip-rule="evenodd"
|
||||
d="M 2.999,70 C 2.999,61.877 4.693,56.953 8.327,54.503 C 8.659,54.281 9.096,54.161 9.493,54.161 C 10.851,54.161 11.823,54.826 12.949,55.9 L 13.318,56.26 L 13.51,56.448 C 14.601,57.531 15.827,58.747 17.546,58.747 C 18.629,58.747 19.625,58.278 20.592,57.315 C 22.711,55.195 24.891,50.06 25.003,28.066 C 25.007,27.526 25.227,27.01 25.616,26.635 C 25.991,26.277 26.488,26.076 27.003,26.076 C 27.026,26.076 27.048,26.078 27.071,26.078 C 28.054,26.111 29.063,26.151 30.094,26.192 C 32.647,26.292 35.227,26.393 37.722,26.393 C 43.495,26.393 49.972,25.939 54.239,22.566 L 54.924,22.025 L 54.992,21.157 C 55.2,18.538 54.487,16.873 53.62,15.601 C 53.936,16.562 54.107,17.711 53.992,19.157 L 53.924,20.025 L 53.239,20.566 C 48.973,23.939 42.496,24.393 36.722,24.393 C 34.227,24.393 31.647,24.291 29.094,24.192 C 28.063,24.151 27.054,24.111 26.071,24.078 C 26.048,24.078 26.026,24.076 26.003,24.076 C 25.487,24.076 24.99,24.277 24.616,24.635 C 24.226,25.01 24.007,25.526 24.003,26.066 C 23.891,48.06 21.711,53.195 19.592,55.316 C 18.625,56.279 17.629,56.747 16.546,56.747 C 14.827,56.747 13.601,55.531 12.51,54.448 L 12.318,54.26 L 11.949,53.9 C 10.823,52.825 9.851,52.161 8.493,52.161 C 8.096,52.161 7.659,52.281 7.327,52.503 C 3.693,54.953 1.999,59.877 1.999,68 C 1.999,73.927 2.971,77.338 4.329,79.438 C 3.52,77.321 2.999,74.334 2.999,70 z "
|
||||
id="path56"
|
||||
style="fill:url(#linearGradient13251);fill-rule:evenodd" />
|
||||
</g><g
|
||||
id="g58"
|
||||
style="fill:url(#linearGradient13245);filter:url(#filter4299)"
|
||||
transform="translate(-2,-4)">
|
||||
<linearGradient
|
||||
id="SVGID_6_"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
x1="21.6807"
|
||||
y1="95.531197"
|
||||
x2="25.875299"
|
||||
y2="95.531197"
|
||||
style="fill:url(#linearGradient3216)">
|
||||
<stop
|
||||
offset="0"
|
||||
style="stop-color:#FFFFFF;fill:url(#linearGradient3216)"
|
||||
id="stop61" />
|
||||
<stop
|
||||
offset="1"
|
||||
style="stop-color:#000000;fill:url(#linearGradient3216)"
|
||||
id="stop63" />
|
||||
</linearGradient>
|
||||
<path
|
||||
clip-rule="evenodd"
|
||||
d="M 22.022,81.343 C 23.062,84.495 24.117,91.695 24.041,107.991 C 24.039,108.52 24.248,109.032 24.623,109.409 C 24.748,109.534 24.892,109.634 25.042,109.721 C 25.125,88.172 23.22,82.671 22.022,81.343 z "
|
||||
id="path65"
|
||||
style="fill:url(#linearGradient13247);fill-rule:evenodd" />
|
||||
</g><g
|
||||
id="g67"
|
||||
style="fill:url(#linearGradient13265);filter:url(#filter4299)"
|
||||
transform="translate(0,-6)">
|
||||
<linearGradient
|
||||
id="SVGID_7_"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
x1="46.571301"
|
||||
y1="6.8223"
|
||||
x2="89.260399"
|
||||
y2="6.8223"
|
||||
style="fill:url(#linearGradient3216)">
|
||||
<stop
|
||||
offset="0"
|
||||
style="stop-color:#FFFFFF;fill:url(#linearGradient3216)"
|
||||
id="stop70" />
|
||||
<stop
|
||||
offset="1"
|
||||
style="stop-color:#000000;fill:url(#linearGradient3216)"
|
||||
id="stop72" />
|
||||
</linearGradient>
|
||||
<path
|
||||
clip-rule="evenodd"
|
||||
d="M 51.082,11.643 C 51.022,11.324 51.039,10.995 51.134,10.684 C 52.942,4.832 61.979,4.089 64.706,4.002 C 72.203,4.004 77.816,4.776 80.8,8.387 C 80.794,8.252 80.779,8.116 80.746,7.985 C 80.678,7.707 80.539,7.413 80.336,7.107 C 77.522,2.877 71.678,2.005 63.706,2.003 C 60.978,2.09 51.942,2.833 50.134,8.685 C 50.037,9.004 50.018,9.344 50.084,9.671 C 50.245,10.461 50.607,11.04 51.082,11.643 z "
|
||||
id="path74"
|
||||
style="fill:url(#linearGradient13267);fill-rule:evenodd" />
|
||||
</g></g>
|
||||
</svg>
|
After Width: | Height: | Size: 25 KiB |
@ -132,6 +132,13 @@ class JobManager(QAbstractTableModel):
|
||||
self.emit(SIGNAL('dataChanged(QModelIndex, QModelIndex)'),
|
||||
self.index(row, 0), self.index(row, 3))
|
||||
|
||||
def running_time_updated(self):
|
||||
for job in self.jobs:
|
||||
if not job.is_running:
|
||||
continue
|
||||
row = self.jobs.index(job)
|
||||
self.emit(SIGNAL('dataChanged(QModelIndex, QModelIndex)'),
|
||||
self.index(row, 3), self.index(row, 3))
|
||||
|
||||
def has_device_jobs(self):
|
||||
for job in self.jobs:
|
||||
|
@ -21,7 +21,7 @@ from calibre.gui2 import APP_UID, warning_dialog, choose_files, error_dialog, \
|
||||
pixmap_to_data, choose_dir, ORG_NAME, \
|
||||
set_sidebar_directories, Dispatcher, \
|
||||
SingleApplication, Application, available_height, \
|
||||
max_available_height, config, info_dialog, import_format
|
||||
max_available_height, config, info_dialog
|
||||
from calibre.gui2.cover_flow import CoverFlow, DatabaseImages, pictureflowerror
|
||||
from calibre.library.database import LibraryDatabase
|
||||
from calibre.gui2.dialogs.scheduler import Scheduler
|
||||
@ -658,11 +658,11 @@ class Main(MainWindow, Ui_MainWindow):
|
||||
model = self.library_view.model()
|
||||
|
||||
paths = list(paths)
|
||||
for i, path in enumerate(paths):
|
||||
npath, fmt = import_format(path)
|
||||
if npath is not None:
|
||||
paths[i] = npath
|
||||
formats[i] = fmt
|
||||
#for i, path in enumerate(paths):
|
||||
# npath, fmt = import_format(path)
|
||||
# if npath is not None:
|
||||
# paths[i] = npath
|
||||
# formats[i] = fmt
|
||||
duplicates, number_added = model.add_books(paths, formats, metadata)
|
||||
if duplicates:
|
||||
files = _('<p>Books with the same title as the following already exist in the database. Add them anyway?<ul>')
|
||||
|
@ -358,8 +358,8 @@ list of id numbers (you can get id numbers by using the list command). For examp
|
||||
|
||||
return 0
|
||||
|
||||
def do_add_format(db, id, fmt, buffer):
|
||||
db.add_format(id, fmt.upper(), buffer, index_is_id=True)
|
||||
def do_add_format(db, id, fmt, path):
|
||||
db.add_format_with_hooks(id, fmt.upper(), path, index_is_id=True)
|
||||
|
||||
|
||||
def command_add_format(args, dbpath):
|
||||
@ -377,10 +377,10 @@ by id. You can get id by using the list command. If the format already exists, i
|
||||
print >>sys.stderr, _('You must specify an id and an ebook file')
|
||||
return 1
|
||||
|
||||
id, file, fmt = int(args[1]), open(args[2], 'rb'), os.path.splitext(args[2])[-1]
|
||||
id, path, fmt = int(args[1]), args[2], os.path.splitext(args[2])[-1]
|
||||
if not fmt:
|
||||
print _('ebook file must have an extension')
|
||||
do_add_format(get_db(dbpath, opts), id, fmt[1:], file)
|
||||
do_add_format(get_db(dbpath, opts), id, fmt[1:], path)
|
||||
return 0
|
||||
|
||||
def do_remove_format(db, id, fmt):
|
||||
|
@ -22,7 +22,8 @@ from calibre.utils.search_query_parser import SearchQueryParser
|
||||
from calibre.ebooks.metadata import string_to_authors, authors_to_string
|
||||
from calibre.ebooks.metadata.meta import get_metadata
|
||||
from calibre.constants import preferred_encoding, iswindows, isosx
|
||||
|
||||
from calibre.ptempfile import PersistentTemporaryFile
|
||||
from calibre.customize.ui import run_plugins_on_import
|
||||
|
||||
copyfile = os.link if hasattr(os, 'link') else shutil.copyfile
|
||||
filesystem_encoding = sys.getfilesystemencoding()
|
||||
@ -37,6 +38,7 @@ def normpath(x):
|
||||
return x
|
||||
|
||||
_filename_sanitize = re.compile(r'[\xae\0\\|\?\*<":>\+\[\]/]')
|
||||
|
||||
def sanitize_file_name(name, substitute='_'):
|
||||
'''
|
||||
Sanitize the filename `name`. All invalid characters are replaced by `substitute`.
|
||||
@ -656,6 +658,12 @@ class LibraryDatabase2(LibraryDatabase):
|
||||
if self.has_format(index, format, index_is_id):
|
||||
self.remove_format(id, format, index_is_id=True)
|
||||
|
||||
def add_format_with_hooks(self, index, format, fpath, index_is_id=False,
|
||||
path=None, notify=True):
|
||||
npath = self.run_import_plugins(fpath, format)
|
||||
return self.add_format(index, format, open(npath, 'rb'),
|
||||
index_is_id=index_is_id, path=path, notify=notify)
|
||||
|
||||
def add_format(self, index, format, stream, index_is_id=False, path=None, notify=True):
|
||||
id = index if index_is_id else self.id(index)
|
||||
if path is None:
|
||||
@ -1077,6 +1085,18 @@ class LibraryDatabase2(LibraryDatabase):
|
||||
self.data.refresh_ids(self.conn, [id]) # Needed to update format list and size
|
||||
return id
|
||||
|
||||
def run_import_plugins(self, path_or_stream, format):
|
||||
format = format.lower()
|
||||
if hasattr(path_or_stream, 'seek'):
|
||||
path_or_stream.seek(0)
|
||||
pt = PersistentTemporaryFile('_import_plugin.'+format)
|
||||
shutil.copyfileobj(path_or_stream, pt, 1024**2)
|
||||
pt.close()
|
||||
path = pt.name
|
||||
else:
|
||||
path = path_or_stream
|
||||
return run_plugins_on_import(path, format)
|
||||
|
||||
def add_books(self, paths, formats, metadata, uris=[], add_duplicates=True):
|
||||
'''
|
||||
Add a book to the database. The result cache is not updated.
|
||||
@ -1105,12 +1125,10 @@ class LibraryDatabase2(LibraryDatabase):
|
||||
self.set_path(id, True)
|
||||
self.conn.commit()
|
||||
self.set_metadata(id, mi)
|
||||
stream = path if hasattr(path, 'read') else open(path, 'rb')
|
||||
stream.seek(0)
|
||||
|
||||
npath = self.run_import_plugins(path, format)
|
||||
stream = open(npath, 'rb')
|
||||
self.add_format(id, format, stream, index_is_id=True)
|
||||
if not hasattr(path, 'read'):
|
||||
stream.close()
|
||||
stream.close()
|
||||
self.conn.commit()
|
||||
self.data.refresh_ids(self.conn, ids) # Needed to update format list and size
|
||||
if duplicates:
|
||||
|
@ -203,7 +203,7 @@ There can be several causes for this:
|
||||
|
||||
If it still wont launch, start a command prompt (press the windows key and R; then type :command:`cmd.exe` in the Run dialog that appears). At the command prompt type the following command and press Enter::
|
||||
|
||||
calibre-debug -c "from calibre.gui2.main import main; main()"
|
||||
calibre-debug -g
|
||||
|
||||
Post any output you see in a help message on the `Forum <http://www.mobileread.com/forums/forumdisplay.php?f=166>`_.
|
||||
|
||||
|
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
Loading…
x
Reference in New Issue
Block a user