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
2053ffb22c
@ -2,6 +2,11 @@ a {
|
|||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
color: blue
|
color: blue
|
||||||
}
|
}
|
||||||
|
|
||||||
|
a:hover {
|
||||||
|
color: red
|
||||||
|
}
|
||||||
|
|
||||||
.comments {
|
.comments {
|
||||||
margin-top: 0;
|
margin-top: 0;
|
||||||
padding-top: 0;
|
padding-top: 0;
|
||||||
|
@ -156,17 +156,17 @@ class HeuristicProcessor(object):
|
|||||||
]
|
]
|
||||||
|
|
||||||
ITALICIZE_STYLE_PATS = [
|
ITALICIZE_STYLE_PATS = [
|
||||||
r'(?msu)(?<=[\s>])_(?P<words>[^_]+)_',
|
ur'(?msu)(?<=[\s>"“\'‘])_(?P<words>[^_]+)_',
|
||||||
r'(?msu)(?<=[\s>])/(?P<words>[^/\*>]+)/',
|
ur'(?msu)(?<=[\s>"“\'‘])/(?P<words>[^/\*>]+)/',
|
||||||
r'(?msu)(?<=[\s>])~~(?P<words>[^~]+)~~',
|
ur'(?msu)(?<=[\s>"“\'‘])~~(?P<words>[^~]+)~~',
|
||||||
r'(?msu)(?<=[\s>])\*(?P<words>[^\*]+)\*',
|
ur'(?msu)(?<=[\s>"“\'‘])\*(?P<words>[^\*]+)\*',
|
||||||
r'(?msu)(?<=[\s>])~(?P<words>[^~]+)~',
|
ur'(?msu)(?<=[\s>"“\'‘])~(?P<words>[^~]+)~',
|
||||||
r'(?msu)(?<=[\s>])_/(?P<words>[^/_]+)/_',
|
ur'(?msu)(?<=[\s>"“\'‘])_/(?P<words>[^/_]+)/_',
|
||||||
r'(?msu)(?<=[\s>])_\*(?P<words>[^\*_]+)\*_',
|
ur'(?msu)(?<=[\s>"“\'‘])_\*(?P<words>[^\*_]+)\*_',
|
||||||
r'(?msu)(?<=[\s>])\*/(?P<words>[^/\*]+)/\*',
|
ur'(?msu)(?<=[\s>"“\'‘])\*/(?P<words>[^/\*]+)/\*',
|
||||||
r'(?msu)(?<=[\s>])_\*/(?P<words>[^\*_]+)/\*_',
|
ur'(?msu)(?<=[\s>"“\'‘])_\*/(?P<words>[^\*_]+)/\*_',
|
||||||
r'(?msu)(?<=[\s>])/:(?P<words>[^:/]+):/',
|
ur'(?msu)(?<=[\s>"“\'‘])/:(?P<words>[^:/]+):/',
|
||||||
r'(?msu)(?<=[\s>])\|:(?P<words>[^:\|]+):\|',
|
ur'(?msu)(?<=[\s>"“\'‘])\|:(?P<words>[^:\|]+):\|',
|
||||||
]
|
]
|
||||||
|
|
||||||
for word in ITALICIZE_WORDS:
|
for word in ITALICIZE_WORDS:
|
||||||
|
@ -563,10 +563,12 @@ class Metadata(object):
|
|||||||
def format_tags(self):
|
def format_tags(self):
|
||||||
return u', '.join([unicode(t) for t in sorted(self.tags, key=sort_key)])
|
return u', '.join([unicode(t) for t in sorted(self.tags, key=sort_key)])
|
||||||
|
|
||||||
def format_rating(self, v = None):
|
def format_rating(self, v=None, divide_by=1.0):
|
||||||
if v is None:
|
if v is None:
|
||||||
return unicode(self.rating/2)
|
if self.rating is not None:
|
||||||
return unicode(v/2)
|
return unicode(self.rating/divide_by)
|
||||||
|
return u'None'
|
||||||
|
return unicode(v/divide_by)
|
||||||
|
|
||||||
def format_field(self, key, series_with_index=True):
|
def format_field(self, key, series_with_index=True):
|
||||||
'''
|
'''
|
||||||
|
@ -40,6 +40,11 @@ path_to_ebook to the database.
|
|||||||
parser.add_option('--ignore-plugins', default=False, action='store_true',
|
parser.add_option('--ignore-plugins', default=False, action='store_true',
|
||||||
help=_('Ignore custom plugins, useful if you installed a plugin'
|
help=_('Ignore custom plugins, useful if you installed a plugin'
|
||||||
' that is preventing calibre from starting'))
|
' that is preventing calibre from starting'))
|
||||||
|
parser.add_option('-s', '--shutdown-running-calibre', default=False,
|
||||||
|
action='store_true',
|
||||||
|
help=_('Cause a running calibre instance, if any, to be'
|
||||||
|
' shutdown. Note that if there are running jobs, they '
|
||||||
|
'will be silently aborted, so use with care.'))
|
||||||
return parser
|
return parser
|
||||||
|
|
||||||
def init_qt(args):
|
def init_qt(args):
|
||||||
@ -339,7 +344,7 @@ def cant_start(msg=_('If you are sure it is not running')+', ',
|
|||||||
|
|
||||||
raise SystemExit(1)
|
raise SystemExit(1)
|
||||||
|
|
||||||
def communicate(args):
|
def communicate(opts, args):
|
||||||
t = RC()
|
t = RC()
|
||||||
t.start()
|
t.start()
|
||||||
time.sleep(3)
|
time.sleep(3)
|
||||||
@ -348,6 +353,9 @@ def communicate(args):
|
|||||||
cant_start(what=_('try deleting the file')+': '+f)
|
cant_start(what=_('try deleting the file')+': '+f)
|
||||||
raise SystemExit(1)
|
raise SystemExit(1)
|
||||||
|
|
||||||
|
if opts.shutdown_running_calibre:
|
||||||
|
t.conn.send('shutdown:')
|
||||||
|
else:
|
||||||
if len(args) > 1:
|
if len(args) > 1:
|
||||||
args[1] = os.path.abspath(args[1])
|
args[1] = os.path.abspath(args[1])
|
||||||
t.conn.send('launched:'+repr(args))
|
t.conn.send('launched:'+repr(args))
|
||||||
@ -365,6 +373,8 @@ def main(args=sys.argv):
|
|||||||
from calibre.utils.lock import singleinstance
|
from calibre.utils.lock import singleinstance
|
||||||
from multiprocessing.connection import Listener
|
from multiprocessing.connection import Listener
|
||||||
si = singleinstance('calibre GUI')
|
si = singleinstance('calibre GUI')
|
||||||
|
if si and opts.shutdown_running_calibre:
|
||||||
|
return 0
|
||||||
if si:
|
if si:
|
||||||
try:
|
try:
|
||||||
listener = Listener(address=ADDRESS)
|
listener = Listener(address=ADDRESS)
|
||||||
@ -390,10 +400,10 @@ def main(args=sys.argv):
|
|||||||
else:
|
else:
|
||||||
# On windows only singleinstance can be trusted
|
# On windows only singleinstance can be trusted
|
||||||
otherinstance = True if iswindows else False
|
otherinstance = True if iswindows else False
|
||||||
if not otherinstance:
|
if not otherinstance and not opts.shutdown_running_calibre:
|
||||||
return run_gui(opts, args, actions, listener, app, gui_debug=gui_debug)
|
return run_gui(opts, args, actions, listener, app, gui_debug=gui_debug)
|
||||||
|
|
||||||
communicate(args)
|
communicate(opts, args)
|
||||||
|
|
||||||
return 0
|
return 0
|
||||||
|
|
||||||
|
@ -100,6 +100,7 @@ class ThreadedJob(BaseJob):
|
|||||||
try:
|
try:
|
||||||
self.consolidate_log()
|
self.consolidate_log()
|
||||||
except:
|
except:
|
||||||
|
if self.log is not None:
|
||||||
self.log.exception('Log consolidation failed')
|
self.log.exception('Log consolidation failed')
|
||||||
|
|
||||||
# No need to keep references to these around anymore
|
# No need to keep references to these around anymore
|
||||||
@ -112,7 +113,7 @@ class ThreadedJob(BaseJob):
|
|||||||
self.start_time = time.time()
|
self.start_time = time.time()
|
||||||
self.duration = 0.0001
|
self.duration = 0.0001
|
||||||
else:
|
else:
|
||||||
self.duration = time.time() - self.start_time()
|
self.duration = time.time() - self.start_time
|
||||||
self.abort.set()
|
self.abort.set()
|
||||||
|
|
||||||
self.log('Aborted job:', self.description)
|
self.log('Aborted job:', self.description)
|
||||||
|
@ -446,6 +446,8 @@ class Main(MainWindow, MainWindowMixin, DeviceMixin, EmailMixin, # {{{
|
|||||||
self.library_view.model().refresh()
|
self.library_view.model().refresh()
|
||||||
self.library_view.model().research()
|
self.library_view.model().research()
|
||||||
self.tags_view.recount()
|
self.tags_view.recount()
|
||||||
|
elif msg.startswith('shutdown:'):
|
||||||
|
self.quit(confirm_quit=False)
|
||||||
else:
|
else:
|
||||||
print msg
|
print msg
|
||||||
|
|
||||||
@ -599,8 +601,9 @@ class Main(MainWindow, MainWindowMixin, DeviceMixin, EmailMixin, # {{{
|
|||||||
dynamic.set('sort_history', self.library_view.model().sort_history)
|
dynamic.set('sort_history', self.library_view.model().sort_history)
|
||||||
self.save_layout_state()
|
self.save_layout_state()
|
||||||
|
|
||||||
def quit(self, checked=True, restart=False, debug_on_restart=False):
|
def quit(self, checked=True, restart=False, debug_on_restart=False,
|
||||||
if not self.confirm_quit():
|
confirm_quit=True):
|
||||||
|
if confirm_quit and not self.confirm_quit():
|
||||||
return
|
return
|
||||||
try:
|
try:
|
||||||
self.shutdown()
|
self.shutdown()
|
||||||
|
@ -189,7 +189,7 @@ def get_components(template, mi, id, timefmt='%b %Y', length=250,
|
|||||||
else:
|
else:
|
||||||
template = re.sub(r'\{series_index[^}]*?\}', '', template)
|
template = re.sub(r'\{series_index[^}]*?\}', '', template)
|
||||||
if mi.rating is not None:
|
if mi.rating is not None:
|
||||||
format_args['rating'] = mi.format_rating()
|
format_args['rating'] = mi.format_rating(divide_by=2.0)
|
||||||
if hasattr(mi.timestamp, 'timetuple'):
|
if hasattr(mi.timestamp, 'timetuple'):
|
||||||
format_args['timestamp'] = strftime(timefmt, mi.timestamp.timetuple())
|
format_args['timestamp'] = strftime(timefmt, mi.timestamp.timetuple())
|
||||||
if hasattr(mi.pubdate, 'timetuple'):
|
if hasattr(mi.pubdate, 'timetuple'):
|
||||||
@ -212,7 +212,8 @@ def get_components(template, mi, id, timefmt='%b %Y', length=250,
|
|||||||
elif cm['datatype'] == 'bool':
|
elif cm['datatype'] == 'bool':
|
||||||
format_args[key] = _('yes') if format_args[key] else _('no')
|
format_args[key] = _('yes') if format_args[key] else _('no')
|
||||||
elif cm['datatype'] == 'rating':
|
elif cm['datatype'] == 'rating':
|
||||||
format_args[key] = mi.format_rating(format_args[key])
|
format_args[key] = mi.format_rating(format_args[key],
|
||||||
|
divide_by=2.0)
|
||||||
elif cm['datatype'] in ['int', 'float']:
|
elif cm['datatype'] in ['int', 'float']:
|
||||||
if format_args[key] != 0:
|
if format_args[key] != 0:
|
||||||
format_args[key] = unicode(format_args[key])
|
format_args[key] = unicode(format_args[key])
|
||||||
|
@ -195,9 +195,10 @@ It can get tiresome to keep re-adding a plugin to calibre to test small changes.
|
|||||||
|
|
||||||
Once you've located the zip file of your plugin you can then directly update it with your changes instead of re-adding it each time. To do so from the command line, in the directory that contains your plugin source code, use::
|
Once you've located the zip file of your plugin you can then directly update it with your changes instead of re-adding it each time. To do so from the command line, in the directory that contains your plugin source code, use::
|
||||||
|
|
||||||
zip -R /path/to/plugin/zip/file.zip *
|
calibre -s; sleep 4s; zip -R /path/to/plugin/zip/file.zip *; calibre
|
||||||
|
|
||||||
This will update all changed files. It relies on the freely available zip command line tool. Note that you should quit calibre before running this command.
|
This will shutdown a running calibre. Wait for the shutdown to complete, then update your plugin files and relaunch calibre.
|
||||||
|
It relies on the freely available zip command line tool.
|
||||||
|
|
||||||
More plugin examples
|
More plugin examples
|
||||||
----------------------
|
----------------------
|
||||||
|
Loading…
x
Reference in New Issue
Block a user