mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-08 10:44:09 -04:00
Add item to Preferences menu to restart calibre in debug mode. Fixes #7359 (Make debug mode accessible from within the GUI)
This commit is contained in:
parent
29dd71b130
commit
3960f3d6f3
@ -23,6 +23,12 @@ Run an embedded python interpreter.
|
||||
help='Debug the specified device driver.')
|
||||
parser.add_option('-g', '--gui', default=False, action='store_true',
|
||||
help='Run the GUI',)
|
||||
parser.add_option('--gui-debug', default=None,
|
||||
help='Run the GUI with a debug console, logging to the'
|
||||
' specified path',)
|
||||
parser.add_option('--show-gui-debug', default=None,
|
||||
help='Display the specified log file.',)
|
||||
|
||||
parser.add_option('-w', '--viewer', default=False, action='store_true',
|
||||
help='Run the ebook viewer',)
|
||||
parser.add_option('--paths', default=False, action='store_true',
|
||||
@ -135,7 +141,28 @@ def add_simple_plugin(path_to_plugin):
|
||||
os.chdir(odir)
|
||||
shutil.rmtree(tdir)
|
||||
|
||||
|
||||
def run_debug_gui(logpath):
|
||||
import time, platform
|
||||
time.sleep(3) # Give previous GUI time to shutdown fully and release locks
|
||||
from calibre.constants import __appname__, __version__, isosx
|
||||
print __appname__, _('Debug log')
|
||||
print __appname__, __version__
|
||||
print platform.platform()
|
||||
print platform.system()
|
||||
print platform.system_alias(platform.system(), platform.release(),
|
||||
platform.version())
|
||||
print 'Python', platform.python_version()
|
||||
try:
|
||||
if iswindows:
|
||||
print 'Windows:', platform.win32_ver()
|
||||
elif isosx:
|
||||
print 'OSX:', platform.mac_ver()
|
||||
else:
|
||||
print 'Linux:', platform.linux_distribution()
|
||||
except:
|
||||
pass
|
||||
from calibre.gui2.main import main
|
||||
main(['__CALIBRE_GUI_DEBUG__', logpath])
|
||||
|
||||
def main(args=sys.argv):
|
||||
from calibre.constants import debug
|
||||
@ -154,6 +181,20 @@ def main(args=sys.argv):
|
||||
if opts.gui:
|
||||
from calibre.gui2.main import main
|
||||
main(['calibre'])
|
||||
elif opts.gui_debug is not None:
|
||||
run_debug_gui(opts.gui_debug)
|
||||
elif opts.show_gui_debug:
|
||||
import time, re
|
||||
time.sleep(1)
|
||||
from calibre.gui2 import open_local_file
|
||||
if iswindows:
|
||||
with open(opts.show_gui_debug, 'r+b') as f:
|
||||
raw = f.read()
|
||||
raw = re.sub('(?<!\r)\n', '\r\n', raw)
|
||||
f.seek(0)
|
||||
f.truncate()
|
||||
f.write(raw)
|
||||
open_local_file(opts.show_gui_debug)
|
||||
elif opts.viewer:
|
||||
from calibre.gui2.viewer.main import main
|
||||
vargs = ['ebook-viewer', '--debug-javascript']
|
||||
|
@ -10,6 +10,7 @@ from PyQt4.Qt import QIcon, QMenu, Qt
|
||||
from calibre.gui2.actions import InterfaceAction
|
||||
from calibre.gui2.preferences.main import Preferences
|
||||
from calibre.gui2 import error_dialog
|
||||
from calibre.constants import DEBUG
|
||||
|
||||
class PreferencesAction(InterfaceAction):
|
||||
|
||||
@ -22,6 +23,10 @@ class PreferencesAction(InterfaceAction):
|
||||
pm.addAction(QIcon(I('config.png')), _('Preferences'), self.do_config)
|
||||
pm.addAction(QIcon(I('wizard.png')), _('Run welcome wizard'),
|
||||
self.gui.run_wizard)
|
||||
if not DEBUG:
|
||||
pm.addSeparator()
|
||||
pm.addAction(QIcon(I('debug.png')), _('Restart in debug mode'),
|
||||
self.debug_restart)
|
||||
self.qaction.setMenu(pm)
|
||||
self.preferences_menu = pm
|
||||
for x in (self.gui.preferences_action, self.qaction):
|
||||
@ -44,4 +49,6 @@ class PreferencesAction(InterfaceAction):
|
||||
d.run_wizard_requested.connect(self.gui.run_wizard,
|
||||
type=Qt.QueuedConnection)
|
||||
|
||||
def debug_restart(self, *args):
|
||||
self.gui.quit(restart=True, debug_on_restart=True)
|
||||
|
||||
|
@ -135,9 +135,10 @@ class GuiRunner(QObject):
|
||||
'''Make sure an event loop is running before starting the main work of
|
||||
initialization'''
|
||||
|
||||
def __init__(self, opts, args, actions, listener, app):
|
||||
def __init__(self, opts, args, actions, listener, app, gui_debug=None):
|
||||
self.startup_time = time.time()
|
||||
self.opts, self.args, self.listener, self.app = opts, args, listener, app
|
||||
self.gui_debug = gui_debug
|
||||
self.actions = actions
|
||||
self.main = None
|
||||
QObject.__init__(self)
|
||||
@ -148,7 +149,7 @@ class GuiRunner(QObject):
|
||||
|
||||
def start_gui(self):
|
||||
from calibre.gui2.ui import Main
|
||||
main = Main(self.opts)
|
||||
main = Main(self.opts, gui_debug=self.gui_debug)
|
||||
if self.splash_screen is not None:
|
||||
self.splash_screen.showMessage(_('Initializing user interface...'))
|
||||
self.splash_screen.finish(main)
|
||||
@ -249,34 +250,56 @@ class GuiRunner(QObject):
|
||||
|
||||
self.initialize_db()
|
||||
|
||||
def run_in_debug_mode(logpath=None):
|
||||
e = sys.executable if getattr(sys, 'frozen', False) else sys.argv[0]
|
||||
import tempfile, subprocess
|
||||
fd, logpath = tempfile.mkstemp('.txt')
|
||||
|
||||
if hasattr(sys, 'frameworks_dir'):
|
||||
base = os.path.dirname(sys.frameworks_dir)
|
||||
if 'console.app' not in base:
|
||||
base = os.path.join(base, 'console.app', 'Contents')
|
||||
exe = os.path.basename(e)
|
||||
exe = os.path.join(base, 'MacOS', exe+'-debug')
|
||||
else:
|
||||
base, ext = os.path.splitext(e)
|
||||
exe = base + '-debug' + ext
|
||||
print 'Starting debug executable:', exe
|
||||
subprocess.Popen([exe, '--gui-debug', logpath], stdout=fd, stderr=fd)
|
||||
|
||||
def run_gui(opts, args, actions, listener, app):
|
||||
def run_gui(opts, args, actions, listener, app, gui_debug=None):
|
||||
initialize_file_icon_provider()
|
||||
if not dynamic.get('welcome_wizard_was_run', False):
|
||||
from calibre.gui2.wizard import wizard
|
||||
wizard().exec_()
|
||||
dynamic.set('welcome_wizard_was_run', True)
|
||||
runner = GuiRunner(opts, args, actions, listener, app)
|
||||
runner = GuiRunner(opts, args, actions, listener, app, gui_debug=gui_debug)
|
||||
ret = app.exec_()
|
||||
if getattr(runner.main, 'run_wizard_b4_shutdown', False):
|
||||
from calibre.gui2.wizard import wizard
|
||||
wizard().exec_()
|
||||
if getattr(runner.main, 'restart_after_quit', False):
|
||||
e = sys.executable if getattr(sys, 'frozen', False) else sys.argv[0]
|
||||
print 'Restarting with:', e, sys.argv
|
||||
if hasattr(sys, 'frameworks_dir'):
|
||||
app = os.path.dirname(os.path.dirname(sys.frameworks_dir))
|
||||
import subprocess
|
||||
subprocess.Popen('sleep 3s; open '+app, shell=True)
|
||||
if getattr(runner.main, 'debug_on_restart', False):
|
||||
run_in_debug_mode()
|
||||
else:
|
||||
os.execvp(e, sys.argv)
|
||||
print 'Restarting with:', e, sys.argv
|
||||
if hasattr(sys, 'frameworks_dir'):
|
||||
app = os.path.dirname(os.path.dirname(sys.frameworks_dir))
|
||||
import subprocess
|
||||
subprocess.Popen('sleep 3s; open '+app, shell=True)
|
||||
else:
|
||||
os.execvp(e, sys.argv)
|
||||
else:
|
||||
if iswindows:
|
||||
try:
|
||||
runner.main.system_tray_icon.hide()
|
||||
except:
|
||||
pass
|
||||
if runner.main.gui_debug is not None:
|
||||
e = sys.executable if getattr(sys, 'frozen', False) else sys.argv[0]
|
||||
import subprocess
|
||||
subprocess.Popen([e, '--show-gui-debug', runner.main.gui_debug])
|
||||
return ret
|
||||
|
||||
def cant_start(msg=_('If you are sure it is not running')+', ',
|
||||
@ -317,6 +340,11 @@ def communicate(args):
|
||||
|
||||
|
||||
def main(args=sys.argv):
|
||||
gui_debug = None
|
||||
if args[0] == '__CALIBRE_GUI_DEBUG__':
|
||||
gui_debug = args[1]
|
||||
args = ['calibre']
|
||||
|
||||
app, opts, args, actions = init_qt(args)
|
||||
from calibre.utils.lock import singleinstance
|
||||
from multiprocessing.connection import Listener
|
||||
@ -333,9 +361,11 @@ def main(args=sys.argv):
|
||||
except socket.error:
|
||||
cant_start()
|
||||
else:
|
||||
return run_gui(opts, args, actions, listener, app)
|
||||
return run_gui(opts, args, actions, listener, app,
|
||||
gui_debug=gui_debug)
|
||||
else:
|
||||
return run_gui(opts, args, actions, listener, app)
|
||||
return run_gui(opts, args, actions, listener, app,
|
||||
gui_debug=gui_debug)
|
||||
otherinstance = False
|
||||
try:
|
||||
listener = Listener(address=ADDRESS)
|
||||
@ -345,8 +375,7 @@ def main(args=sys.argv):
|
||||
# On windows only singleinstance can be trusted
|
||||
otherinstance = True if iswindows else False
|
||||
if not otherinstance:
|
||||
sys.setcheckinterval(50) # Make GUI more responsive
|
||||
return run_gui(opts, args, actions, listener, app)
|
||||
return run_gui(opts, args, actions, listener, app, gui_debug=gui_debug)
|
||||
|
||||
communicate(args)
|
||||
|
||||
|
@ -96,10 +96,11 @@ class Main(MainWindow, MainWindowMixin, DeviceMixin, EmailMixin, # {{{
|
||||
'The main GUI'
|
||||
|
||||
|
||||
def __init__(self, opts, parent=None):
|
||||
def __init__(self, opts, parent=None, gui_debug=None):
|
||||
MainWindow.__init__(self, opts, parent)
|
||||
self.opts = opts
|
||||
self.device_connected = None
|
||||
self.gui_debug = gui_debug
|
||||
acmap = OrderedDict()
|
||||
for action in interface_actions():
|
||||
ac = action.load_actual_plugin(self)
|
||||
@ -261,6 +262,14 @@ class Main(MainWindow, MainWindowMixin, DeviceMixin, EmailMixin, # {{{
|
||||
for ac in self.iactions.values():
|
||||
ac.initialization_complete()
|
||||
|
||||
if show_gui and self.gui_debug is not None:
|
||||
info_dialog(self, _('Debug mode'), '<p>' +
|
||||
_('You have started calibre in debug mode. After you '
|
||||
'quit calibre, the debug log will be available in '
|
||||
'the file: %s<p>The '
|
||||
'log will be displayed automatically.')%self.gui_debug, show=True)
|
||||
|
||||
|
||||
def start_content_server(self):
|
||||
from calibre.library.server.main import start_threaded_server
|
||||
from calibre.library.server import server_config
|
||||
@ -495,7 +504,7 @@ class Main(MainWindow, MainWindowMixin, DeviceMixin, EmailMixin, # {{{
|
||||
dynamic.set('sort_history', self.library_view.model().sort_history)
|
||||
self.save_layout_state()
|
||||
|
||||
def quit(self, checked=True, restart=False):
|
||||
def quit(self, checked=True, restart=False, debug_on_restart=False):
|
||||
if not self.confirm_quit():
|
||||
return
|
||||
try:
|
||||
@ -503,6 +512,7 @@ class Main(MainWindow, MainWindowMixin, DeviceMixin, EmailMixin, # {{{
|
||||
except:
|
||||
pass
|
||||
self.restart_after_quit = restart
|
||||
self.debug_on_restart = debug_on_restart
|
||||
QApplication.instance().quit()
|
||||
|
||||
def donate(self, *args):
|
||||
|
Loading…
x
Reference in New Issue
Block a user