Remove obsolete/unused code

This commit is contained in:
Kovid Goyal 2016-09-30 10:38:55 +05:30
parent 2470ee0ff2
commit 226a920b6b
9 changed files with 0 additions and 1133 deletions

View File

@ -53,8 +53,6 @@ Everything after the -- is passed to the script.
parser.add_option('--reinitialize-db', default=None, parser.add_option('--reinitialize-db', default=None,
help=_('Re-initialize the sqlite calibre database at the ' help=_('Re-initialize the sqlite calibre database at the '
'specified path. Useful to recover from db corruption.')) 'specified path. Useful to recover from db corruption.'))
parser.add_option('-p', '--py-console', help=_('Run python console'),
default=False, action='store_true')
parser.add_option('-m', '--inspect-mobi', action='store_true', parser.add_option('-m', '--inspect-mobi', action='store_true',
default=False, default=False,
help=_('Inspect the MOBI file(s) at the specified path(s)')) help=_('Inspect the MOBI file(s) at the specified path(s)'))
@ -230,9 +228,6 @@ def main(args=sys.argv):
elif opts.viewer: elif opts.viewer:
from calibre.gui_launch import ebook_viewer from calibre.gui_launch import ebook_viewer
ebook_viewer(['ebook-viewer', '--debug-javascript'] + args[1:]) ebook_viewer(['ebook-viewer', '--debug-javascript'] + args[1:])
elif opts.py_console:
from calibre.utils.pyconsole.main import main
main()
elif opts.command: elif opts.command:
sys.argv = args sys.argv = args
exec(opts.command) exec(opts.command)

View File

@ -1,47 +0,0 @@
#!/usr/bin/env python2
# vim:fileencoding=UTF-8:ts=4:sw=4:sta:et:sts=4:ai
__license__ = 'GPL v3'
__copyright__ = '2010, Kovid Goyal <kovid@kovidgoyal.net>'
__docformat__ = 'restructuredtext en'
import sys, os
from calibre import prints as prints_, preferred_encoding, isbytestring
from calibre.utils.config import Config, ConfigProxy, JSONConfig
from calibre.utils.ipc.launch import Worker
from calibre.constants import __appname__, __version__, iswindows
from calibre.gui2 import error_dialog
# Time to wait for communication to/from the interpreter process
POLL_TIMEOUT = 0.01 # seconds
preferred_encoding, isbytestring, __appname__, __version__, error_dialog, \
iswindows
def console_config():
desc='Settings to control the calibre console'
c = Config('console', desc)
c.add_opt('theme', default='native', help='The color theme')
c.add_opt('scrollback', default=10000,
help='Max number of lines to keep in the scrollback buffer')
return c
prefs = ConfigProxy(console_config())
dynamic = JSONConfig('console')
def prints(*args, **kwargs):
kwargs['file'] = sys.__stdout__
prints_(*args, **kwargs)
class Process(Worker):
@property
def env(self):
env = dict(os.environ)
env.update(self._env)
return env

View File

@ -1,521 +0,0 @@
#!/usr/bin/env python2
# vim:fileencoding=UTF-8:ts=4:sw=4:sta:et:sts=4:ai
__license__ = 'GPL v3'
__copyright__ = '2010, Kovid Goyal <kovid@kovidgoyal.net>'
__docformat__ = 'restructuredtext en'
import sys, textwrap, traceback, StringIO
from functools import partial
from codeop import CommandCompiler
from PyQt5.Qt import QTextEdit, Qt, QTextFrameFormat, pyqtSignal, \
QApplication, QColor, QPalette, QMenu, QActionGroup, QTimer
from pygments.lexers import PythonLexer, PythonTracebackLexer
from pygments.styles import get_all_styles
from calibre.utils.pyconsole.formatter import Formatter
from calibre.utils.pyconsole.controller import Controller
from calibre.utils.pyconsole.history import History
from calibre.utils.pyconsole import prints, prefs, __appname__, \
__version__, error_dialog, dynamic
class EditBlock(object): # {{{
def __init__(self, cursor):
self.cursor = cursor
def __enter__(self):
self.cursor.beginEditBlock()
return self.cursor
def __exit__(self, *args):
self.cursor.endEditBlock()
# }}}
class Prepender(object): # {{{
'Helper class to insert output before the current prompt'
def __init__(self, console):
self.console = console
def __enter__(self):
c = self.console
self.opos = c.cursor_pos
cur = c.prompt_frame.firstCursorPosition()
cur.movePosition(cur.PreviousCharacter)
c.setTextCursor(cur)
def __exit__(self, *args):
self.console.cursor_pos = self.opos
# }}}
class ThemeMenu(QMenu): # {{{
def __init__(self, parent):
QMenu.__init__(self, _('Choose theme (needs restart)'))
parent.addMenu(self)
self.group = QActionGroup(self)
current = prefs['theme']
alls = list(sorted(get_all_styles()))
if current not in alls:
current = prefs['theme'] = 'default'
self.actions = []
for style in alls:
ac = self.group.addAction(style)
ac.setCheckable(True)
if current == style:
ac.setChecked(True)
self.actions.append(ac)
ac.triggered.connect(partial(self.set_theme, style))
self.addAction(ac)
def set_theme(self, style, *args):
prefs['theme'] = style
# }}}
class Console(QTextEdit):
running = pyqtSignal()
running_done = pyqtSignal()
@property
def doc(self):
return self.document()
@property
def cursor(self):
return self.textCursor()
@property
def root_frame(self):
return self.doc.rootFrame()
def unhandled_exception(self, type, value, tb):
if type == KeyboardInterrupt:
return
try:
sio = StringIO.StringIO()
traceback.print_exception(type, value, tb, file=sio)
fe = sio.getvalue()
prints(fe)
try:
val = unicode(value)
except:
val = repr(value)
msg = '<b>%s</b>:'%type.__name__ + val
error_dialog(self, _('ERROR: Unhandled exception'), msg,
det_msg=fe, show=True)
except BaseException:
pass
def __init__(self,
prompt='>>> ',
continuation='... ',
parent=None):
QTextEdit.__init__(self, parent)
self.shutting_down = False
self.compiler = CommandCompiler()
self.buf = self.old_buf = []
self.history = History([''], dynamic.get('console_history', []))
self.prompt_frame = None
self.allow_output = False
self.prompt_frame_format = QTextFrameFormat()
self.prompt_frame_format.setBorder(1)
self.prompt_frame_format.setBorderStyle(QTextFrameFormat.BorderStyle_Solid)
self.prompt_len = len(prompt)
self.doc.setMaximumBlockCount(int(prefs['scrollback']))
self.lexer = PythonLexer(ensurenl=False)
self.tb_lexer = PythonTracebackLexer()
self.context_menu = cm = QMenu(self) # {{{
cm.theme = ThemeMenu(cm)
# }}}
self.formatter = Formatter(prompt, continuation, style=prefs['theme'])
p = QPalette()
p.setColor(p.Base, QColor(self.formatter.background_color))
p.setColor(p.Text, QColor(self.formatter.color))
self.setPalette(p)
self.key_dispatcher = { # {{{
Qt.Key_Enter : self.enter_pressed,
Qt.Key_Return : self.enter_pressed,
Qt.Key_Up : self.up_pressed,
Qt.Key_Down : self.down_pressed,
Qt.Key_Home : self.home_pressed,
Qt.Key_End : self.end_pressed,
Qt.Key_Left : self.left_pressed,
Qt.Key_Right : self.right_pressed,
Qt.Key_Backspace : self.backspace_pressed,
Qt.Key_Delete : self.delete_pressed,
} # }}}
motd = textwrap.dedent('''\
# Python {0}
# {1} {2}
'''.format(sys.version.splitlines()[0], __appname__,
__version__))
sys.excepthook = self.unhandled_exception
self.controllers = []
QTimer.singleShot(0, self.launch_controller)
with EditBlock(self.cursor):
self.render_block(motd)
def shutdown(self):
dynamic.set('console_history', self.history.serialize())
self.shutting_down = True
for c in self.controllers:
c.kill()
def contextMenuEvent(self, event):
self.context_menu.popup(event.globalPos())
event.accept()
# Controller management {{{
@property
def controller(self):
return self.controllers[-1]
def no_controller_error(self):
error_dialog(self, _('No interpreter'),
_('No active interpreter found. Try restarting the'
' console'), show=True)
def launch_controller(self, *args):
c = Controller(self)
c.write_output.connect(self.show_output, type=Qt.QueuedConnection)
c.show_error.connect(self.show_error, type=Qt.QueuedConnection)
c.interpreter_died.connect(self.interpreter_died,
type=Qt.QueuedConnection)
c.interpreter_done.connect(self.execution_done)
self.controllers.append(c)
def interpreter_died(self, controller, returncode):
if not self.shutting_down and controller.current_command is not None:
error_dialog(self, _('Interpreter died'),
_('Interpreter dies while executing a command. To see '
'the command, click Show details'),
det_msg=controller.current_command, show=True)
def execute(self, prompt_lines):
c = self.root_frame.lastCursorPosition()
self.setTextCursor(c)
self.old_prompt_frame = self.prompt_frame
self.prompt_frame = None
self.old_buf = self.buf
self.buf = []
self.running.emit()
self.controller.runsource('\n'.join(prompt_lines))
def execution_done(self, controller, ret):
if controller is self.controller:
self.running_done.emit()
if ret: # Incomplete command
self.buf = self.old_buf
self.prompt_frame = self.old_prompt_frame
c = self.prompt_frame.lastCursorPosition()
c.insertBlock()
self.setTextCursor(c)
else: # Command completed
try:
self.old_prompt_frame.setFrameFormat(QTextFrameFormat())
except RuntimeError:
# Happens if enough lines of output that the old
# frame was deleted
pass
self.render_current_prompt()
# }}}
# Prompt management {{{
@dynamic_property
def cursor_pos(self):
doc = '''
The cursor position in the prompt has the form (row, col).
row starts at 0 for the first line
col is 0 if the cursor is at the start of the line, 1 if it is after
the first character, n if it is after the nth char.
'''
def fget(self):
if self.prompt_frame is not None:
pos = self.cursor.position()
it = self.prompt_frame.begin()
lineno = 0
while not it.atEnd():
bl = it.currentBlock()
if bl.contains(pos):
return (lineno, pos - bl.position())
it += 1
lineno += 1
return (-1, -1)
def fset(self, val):
row, col = val
if self.prompt_frame is not None:
it = self.prompt_frame.begin()
lineno = 0
while not it.atEnd():
if lineno == row:
c = self.cursor
c.setPosition(it.currentBlock().position())
c.movePosition(c.NextCharacter, n=col)
self.setTextCursor(c)
break
it += 1
lineno += 1
return property(fget=fget, fset=fset, doc=doc)
def move_cursor_to_prompt(self):
if self.prompt_frame is not None and self.cursor_pos[0] < 0:
c = self.prompt_frame.lastCursorPosition()
self.setTextCursor(c)
def prompt(self, strip_prompt_strings=True):
if not self.prompt_frame:
yield u'' if strip_prompt_strings else self.formatter.prompt
else:
it = self.prompt_frame.begin()
while not it.atEnd():
bl = it.currentBlock()
t = unicode(bl.text())
if strip_prompt_strings:
t = t[self.prompt_len:]
yield t
it += 1
def set_prompt(self, lines):
self.render_current_prompt(lines)
def clear_current_prompt(self):
if self.prompt_frame is None:
c = self.root_frame.lastCursorPosition()
self.prompt_frame = c.insertFrame(self.prompt_frame_format)
self.setTextCursor(c)
else:
c = self.prompt_frame.firstCursorPosition()
self.setTextCursor(c)
c.setPosition(self.prompt_frame.lastPosition(), c.KeepAnchor)
c.removeSelectedText()
c.setPosition(self.prompt_frame.firstPosition())
def render_current_prompt(self, lines=None, restore_cursor=False):
row, col = self.cursor_pos
cp = list(self.prompt()) if lines is None else lines
self.clear_current_prompt()
for i, line in enumerate(cp):
start = i == 0
end = i == len(cp) - 1
self.formatter.render_prompt(not start, self.cursor)
self.formatter.render(self.lexer.get_tokens(line), self.cursor)
if not end:
self.cursor.insertBlock()
if row > -1 and restore_cursor:
self.cursor_pos = (row, col)
self.ensureCursorVisible()
# }}}
# Non-prompt Rendering {{{
def render_block(self, text, restore_prompt=True):
self.formatter.render(self.lexer.get_tokens(text), self.cursor)
self.cursor.insertBlock()
self.cursor.movePosition(self.cursor.End)
if restore_prompt:
self.render_current_prompt()
def show_error(self, is_syntax_err, tb, controller=None):
if self.prompt_frame is not None:
# At a prompt, so redirect output
return prints(tb, end='')
try:
self.buf.append(tb)
if is_syntax_err:
self.formatter.render_syntax_error(tb, self.cursor)
else:
self.formatter.render(self.tb_lexer.get_tokens(tb), self.cursor)
except:
prints(tb, end='')
self.ensureCursorVisible()
QApplication.processEvents()
def show_output(self, raw, which='stdout', controller=None):
def do_show():
try:
self.buf.append(raw)
self.formatter.render_raw(raw, self.cursor)
except:
import traceback
prints(traceback.format_exc())
prints(raw, end='')
if self.prompt_frame is not None:
with Prepender(self):
do_show()
else:
do_show()
self.ensureCursorVisible()
QApplication.processEvents()
# }}}
# Keyboard management {{{
def keyPressEvent(self, ev):
text = unicode(ev.text())
key = ev.key()
action = self.key_dispatcher.get(key, None)
if callable(action):
action()
elif key in (Qt.Key_Escape,):
QTextEdit.keyPressEvent(self, ev)
elif text:
self.text_typed(text)
else:
QTextEdit.keyPressEvent(self, ev)
def left_pressed(self):
lineno, pos = self.cursor_pos
if lineno < 0:
return
if pos > self.prompt_len:
c = self.cursor
c.movePosition(c.PreviousCharacter)
self.setTextCursor(c)
elif lineno > 0:
c = self.cursor
c.movePosition(c.Up)
c.movePosition(c.EndOfLine)
self.setTextCursor(c)
self.ensureCursorVisible()
def up_pressed(self):
lineno, pos = self.cursor_pos
if lineno < 0:
return
if lineno == 0:
b = self.history.back()
if b is not None:
self.set_prompt(b)
else:
c = self.cursor
c.movePosition(c.Up)
self.setTextCursor(c)
self.ensureCursorVisible()
def backspace_pressed(self):
lineno, pos = self.cursor_pos
if lineno < 0:
return
if pos > self.prompt_len:
self.cursor.deletePreviousChar()
elif lineno > 0:
c = self.cursor
c.movePosition(c.Up)
c.movePosition(c.EndOfLine)
self.setTextCursor(c)
self.ensureCursorVisible()
def delete_pressed(self):
self.cursor.deleteChar()
self.ensureCursorVisible()
def right_pressed(self):
lineno, pos = self.cursor_pos
if lineno < 0:
return
c = self.cursor
cp = list(self.prompt(False))
if pos < len(cp[lineno]):
c.movePosition(c.NextCharacter)
elif lineno < len(cp)-1:
c.movePosition(c.NextCharacter, n=1+self.prompt_len)
self.setTextCursor(c)
self.ensureCursorVisible()
def down_pressed(self):
lineno, pos = self.cursor_pos
if lineno < 0:
return
c = self.cursor
cp = list(self.prompt(False))
if lineno >= len(cp) - 1:
b = self.history.forward()
if b is not None:
self.set_prompt(b)
else:
c = self.cursor
c.movePosition(c.Down)
self.setTextCursor(c)
self.ensureCursorVisible()
def home_pressed(self):
if self.prompt_frame is not None:
mods = QApplication.keyboardModifiers()
ctrl = bool(int(mods & Qt.CTRL))
if ctrl:
self.cursor_pos = (0, self.prompt_len)
else:
c = self.cursor
c.movePosition(c.StartOfLine)
c.movePosition(c.NextCharacter, n=self.prompt_len)
self.setTextCursor(c)
self.ensureCursorVisible()
def end_pressed(self):
if self.prompt_frame is not None:
mods = QApplication.keyboardModifiers()
ctrl = bool(int(mods & Qt.CTRL))
if ctrl:
self.cursor_pos = (len(list(self.prompt()))-1, self.prompt_len)
c = self.cursor
c.movePosition(c.EndOfLine)
self.setTextCursor(c)
self.ensureCursorVisible()
def enter_pressed(self):
if self.prompt_frame is None:
return
if not self.controller.is_alive:
return self.no_controller_error()
cp = list(self.prompt())
if cp[0]:
try:
ret = self.compiler('\n'.join(cp))
except:
pass
else:
if ret is None:
c = self.prompt_frame.lastCursorPosition()
c.insertBlock()
self.setTextCursor(c)
self.render_current_prompt()
return
else:
self.history.enter(cp)
self.execute(cp)
def text_typed(self, text):
if self.prompt_frame is not None:
self.move_cursor_to_prompt()
self.cursor.insertText(text)
self.render_current_prompt(restore_cursor=True)
self.history.current = list(self.prompt())
# }}}

View File

@ -1,125 +0,0 @@
#!/usr/bin/env python2
# vim:fileencoding=UTF-8:ts=4:sw=4:sta:et:sts=4:ai
__license__ = 'GPL v3'
__copyright__ = '2010, Kovid Goyal <kovid@kovidgoyal.net>'
__docformat__ = 'restructuredtext en'
import os, cPickle, signal, time
from Queue import Queue, Empty
from multiprocessing.connection import Listener, arbitrary_address
from binascii import hexlify
from PyQt5.Qt import QThread, pyqtSignal
from calibre.utils.pyconsole import Process, iswindows, POLL_TIMEOUT
class Controller(QThread):
# show_error(is_syntax_error, traceback, self)
show_error = pyqtSignal(object, object, object)
# write_output(unicode_object, stdout or stderr, self)
write_output = pyqtSignal(object, object, object)
# Indicates interpreter has finished evaluating current command
interpreter_done = pyqtSignal(object, object)
# interpreter_died(self, returncode or None if no return code available)
interpreter_died = pyqtSignal(object, object)
def __init__(self, parent):
QThread.__init__(self, parent)
self.keep_going = True
self.current_command = None
self.out_queue = Queue()
self.address = arbitrary_address('AF_PIPE' if iswindows else 'AF_UNIX')
self.auth_key = os.urandom(32)
if iswindows and self.address[1] == ':':
self.address = self.address[2:]
self.listener = Listener(address=self.address,
authkey=self.auth_key, backlog=4)
self.env = {
'CALIBRE_SIMPLE_WORKER':
'calibre.utils.pyconsole.interpreter:main',
'CALIBRE_WORKER_ADDRESS':
hexlify(cPickle.dumps(self.listener.address, -1)),
'CALIBRE_WORKER_KEY': hexlify(self.auth_key)
}
self.process = Process(self.env)
self.output_file_buf = self.process(redirect_output=False)
self.conn = self.listener.accept()
self.start()
def run(self):
while self.keep_going and self.is_alive:
try:
self.communicate()
except KeyboardInterrupt:
pass
except EOFError:
break
self.interpreter_died.emit(self, self.returncode)
try:
self.listener.close()
except:
pass
def communicate(self):
if self.conn.poll(POLL_TIMEOUT):
self.dispatch_incoming_message(self.conn.recv())
try:
obj = self.out_queue.get_nowait()
except Empty:
pass
else:
try:
self.conn.send(obj)
except:
raise EOFError('controller failed to send')
def dispatch_incoming_message(self, obj):
try:
cmd, data = obj
except:
print 'Controller received invalid message'
print repr(obj)
return
if cmd in ('stdout', 'stderr'):
self.write_output.emit(data, cmd, self)
elif cmd == 'syntaxerror':
self.show_error.emit(True, data, self)
elif cmd == 'traceback':
self.show_error.emit(False, data, self)
elif cmd == 'done':
self.current_command = None
self.interpreter_done.emit(self, data)
def runsource(self, cmd):
self.current_command = cmd
self.out_queue.put(('run', cmd))
def __nonzero__(self):
return self.process.is_alive
@property
def returncode(self):
return self.process.returncode
def interrupt(self):
if hasattr(signal, 'SIGINT'):
os.kill(self.process.pid, signal.SIGINT)
elif hasattr(signal, 'CTRL_C_EVENT'):
os.kill(self.process.pid, signal.CTRL_C_EVENT)
@property
def is_alive(self):
return self.process.is_alive
def kill(self):
self.out_queue.put(('quit', 0))
t = 0
while self.is_alive and t < 10:
time.sleep(0.1)
self.process.kill()
self.keep_going = False

View File

@ -1,99 +0,0 @@
#!/usr/bin/env python2
# vim:fileencoding=UTF-8:ts=4:sw=4:sta:et:sts=4:ai
__license__ = 'GPL v3'
__copyright__ = '2010, Kovid Goyal <kovid@kovidgoyal.net>'
__docformat__ = 'restructuredtext en'
from PyQt5.Qt import QTextCharFormat, QFont, QBrush, QColor
from pygments.formatter import Formatter as PF
from pygments.token import Token, Generic, string_to_tokentype
class Formatter(object):
def __init__(self, prompt, continuation, style='default'):
if len(prompt) != len(continuation):
raise ValueError('%r does not have the same length as %r' %
(prompt, continuation))
self.prompt, self.continuation = prompt, continuation
self.set_style(style)
def set_style(self, style):
pf = PF(style=style)
self.styles = {}
self.normal = self.base_fmt()
self.background_color = pf.style.background_color
self.color = 'black'
for ttype, ndef in pf.style:
fmt = self.base_fmt()
fmt.setProperty(fmt.UserProperty, str(ttype))
if ndef['color']:
fmt.setForeground(QBrush(QColor('#%s'%ndef['color'])))
fmt.setUnderlineColor(QColor('#%s'%ndef['color']))
if ttype == Generic.Output:
self.color = '#%s'%ndef['color']
if ndef['bold']:
fmt.setFontWeight(QFont.Bold)
if ndef['italic']:
fmt.setFontItalic(True)
if ndef['underline']:
fmt.setFontUnderline(True)
if ndef['bgcolor']:
fmt.setBackground(QBrush(QColor('#%s'%ndef['bgcolor'])))
if ndef['border']:
pass # No support for borders
self.styles[ttype] = fmt
def get_fmt(self, token):
if type(token) != type(Token.Generic): # noqa
token = string_to_tokentype(token)
fmt = self.styles.get(token, None)
if fmt is None:
fmt = self.base_fmt()
fmt.setProperty(fmt.UserProperty, str(token))
return fmt
def base_fmt(self):
fmt = QTextCharFormat()
fmt.setFontFamily('monospace')
return fmt
def render_raw(self, raw, cursor):
cursor.insertText(raw, self.normal)
def render_syntax_error(self, tb, cursor):
fmt = self.get_fmt(Token.Error)
cursor.insertText(tb, fmt)
def render(self, tokens, cursor):
lastval = ''
lasttype = None
for ttype, value in tokens:
while ttype not in self.styles:
ttype = ttype.parent
if ttype == lasttype:
lastval += value
else:
if lastval:
fmt = self.styles[lasttype]
cursor.insertText(lastval, fmt)
lastval = value
lasttype = ttype
if lastval:
fmt = self.styles[lasttype]
cursor.insertText(lastval, fmt)
def render_prompt(self, is_continuation, cursor):
pr = self.continuation if is_continuation else self.prompt
fmt = self.get_fmt(Generic.Prompt)
if fmt is None:
fmt = self.base_fmt()
cursor.insertText(pr, fmt)

View File

@ -1,56 +0,0 @@
#!/usr/bin/env python2
# vim:fileencoding=UTF-8:ts=4:sw=4:sta:et:sts=4:ai
__license__ = 'GPL v3'
__copyright__ = '2010, Kovid Goyal <kovid@kovidgoyal.net>'
__docformat__ = 'restructuredtext en'
from collections import deque
class History(object): # {{{
def __init__(self, current, entries):
self.entries = deque(entries, maxlen=max(2000, len(entries)))
self.index = len(self.entries) - 1
self.current = self.default = current
self.last_was_back = False
def back(self, amt=1):
if self.entries:
oidx = self.index
ans = self.entries[self.index]
self.index = max(0, self.index - amt)
self.last_was_back = self.index != oidx
return ans
def forward(self, amt=1):
if self.entries:
d = self.index
if self.last_was_back:
d += 1
if d >= len(self.entries) - 1:
self.index = len(self.entries) - 1
self.last_was_back = False
return self.current
if self.last_was_back:
amt += 1
self.index = min(len(self.entries)-1, self.index + amt)
self.last_was_back = False
return self.entries[self.index]
def enter(self, x):
try:
self.entries.remove(x)
except ValueError:
pass
self.entries.append(x)
self.index = len(self.entries) - 1
self.current = self.default
self.last_was_back = False
def serialize(self):
return list(self.entries)
# }}}

View File

@ -1,178 +0,0 @@
#!/usr/bin/env python2
# vim:fileencoding=UTF-8:ts=4:sw=4:sta:et:sts=4:ai
__license__ = 'GPL v3'
__copyright__ = '2010, Kovid Goyal <kovid@kovidgoyal.net>'
__docformat__ = 'restructuredtext en'
import sys, cPickle, os, binascii
from code import InteractiveInterpreter
from Queue import Queue, Empty
from threading import Thread
from binascii import unhexlify
from multiprocessing.connection import Client
from repr import repr as safe_repr
from calibre.utils.pyconsole import preferred_encoding, isbytestring, \
POLL_TIMEOUT
'''
Messages sent by client:
(stdout, unicode)
(stderr, unicode)
(syntaxerror, unicode)
(traceback, unicode)
(done, True iff incomplete command)
Messages that can be received by client:
(quit, return code)
(run, unicode)
'''
def tounicode(raw): # {{{
if isbytestring(raw):
try:
raw = raw.decode(preferred_encoding, 'replace')
except:
raw = safe_repr(raw)
if isbytestring(raw):
try:
raw.decode('utf-8', 'replace')
except:
raw = u'Undecodable bytestring'
return raw
# }}}
class DummyFile(object): # {{{
def __init__(self, what, out_queue):
self.closed = False
self.name = 'console'
self.softspace = 0
self.what = what
self.out_queue = out_queue
def flush(self):
pass
def close(self):
pass
def write(self, raw):
self.out_queue.put((self.what, tounicode(raw)))
# }}}
class Comm(Thread): # {{{
def __init__(self, conn, out_queue, in_queue):
Thread.__init__(self)
self.daemon = True
self.conn = conn
self.out_queue = out_queue
self.in_queue = in_queue
self.keep_going = True
def run(self):
while self.keep_going:
try:
self.communicate()
except KeyboardInterrupt:
pass
except EOFError:
pass
def communicate(self):
if self.conn.poll(POLL_TIMEOUT):
try:
obj = self.conn.recv()
except:
pass
else:
self.in_queue.put(obj)
try:
obj = self.out_queue.get_nowait()
except Empty:
pass
else:
try:
self.conn.send(obj)
except:
raise EOFError('interpreter failed to send')
# }}}
class Interpreter(InteractiveInterpreter): # {{{
def __init__(self, queue, local={}):
if '__name__' not in local:
local['__name__'] = '__console__'
if '__doc__' not in local:
local['__doc__'] = None
self.out_queue = queue
sys.stdout = DummyFile('stdout', queue)
sys.stderr = DummyFile('sdterr', queue)
InteractiveInterpreter.__init__(self, locals=local)
def showtraceback(self, *args, **kwargs):
self.is_syntax_error = False
InteractiveInterpreter.showtraceback(self, *args, **kwargs)
def showsyntaxerror(self, *args, **kwargs):
self.is_syntax_error = True
InteractiveInterpreter.showsyntaxerror(self, *args, **kwargs)
def write(self, raw):
what = 'syntaxerror' if self.is_syntax_error else 'traceback'
self.out_queue.put((what, tounicode(raw)))
# }}}
def connect():
os.chdir(cPickle.loads(binascii.unhexlify(os.environ['ORIGWD'])))
address = cPickle.loads(unhexlify(os.environ['CALIBRE_WORKER_ADDRESS']))
key = unhexlify(os.environ['CALIBRE_WORKER_KEY'])
return Client(address, authkey=key)
def main():
out_queue = Queue()
in_queue = Queue()
conn = connect()
comm = Comm(conn, out_queue, in_queue)
comm.start()
interpreter = Interpreter(out_queue)
ret = 0
while True:
try:
try:
cmd, data = in_queue.get(1)
except Empty:
pass
else:
if cmd == 'quit':
ret = data
comm.keep_going = False
comm.join()
break
elif cmd == 'run':
if not comm.is_alive():
ret = 1
break
ret = False
try:
ret = interpreter.runsource(data)
except KeyboardInterrupt:
pass
except SystemExit:
out_queue.put(('stderr', 'SystemExit ignored\n'))
out_queue.put(('done', ret))
except KeyboardInterrupt:
pass
return ret
if __name__ == '__main__':
main()

View File

@ -1,91 +0,0 @@
#!/usr/bin/env python2
# vim:fileencoding=UTF-8:ts=4:sw=4:sta:et:sts=4:ai
__license__ = 'GPL v3'
__copyright__ = '2010, Kovid Goyal <kovid@kovidgoyal.net>'
__docformat__ = 'restructuredtext en'
__version__ = '0.1.0'
from functools import partial
from PyQt5.Qt import QDialog, QToolBar, QStatusBar, QLabel, QFont, Qt, \
QApplication, QIcon, QVBoxLayout, QAction
from calibre.utils.pyconsole import dynamic, __appname__, __version__
from calibre.utils.pyconsole.console import Console
class MainWindow(QDialog):
def __init__(self,
default_status_msg=_('Welcome to') + ' ' + __appname__+' console',
parent=None):
QDialog.__init__(self, parent)
self.restart_requested = False
self.l = QVBoxLayout()
self.setLayout(self.l)
self.resize(800, 600)
geom = dynamic.get('console_window_geometry', None)
if geom is not None:
self.restoreGeometry(geom)
# Setup tool bar {{{
self.tool_bar = QToolBar(self)
self.tool_bar.setToolButtonStyle(Qt.ToolButtonTextOnly)
self.l.addWidget(self.tool_bar)
# }}}
# Setup status bar {{{
self.status_bar = QStatusBar(self)
self.status_bar.defmsg = QLabel(__appname__ + _(' console ') +
__version__)
self.status_bar._font = QFont()
self.status_bar._font.setBold(True)
self.status_bar.defmsg.setFont(self.status_bar._font)
self.status_bar.addWidget(self.status_bar.defmsg)
# }}}
self.console = Console(parent=self)
self.console.running.connect(partial(self.status_bar.showMessage,
_('Code is running')))
self.console.running_done.connect(self.status_bar.clearMessage)
self.l.addWidget(self.console)
self.l.addWidget(self.status_bar)
self.setWindowTitle(__appname__ + ' console')
self.setWindowIcon(QIcon(I('console.png')))
self.restart_action = QAction(_('Restart console'), self)
self.restart_action.setShortcut(_('Ctrl+R'))
self.addAction(self.restart_action)
self.restart_action.triggered.connect(self.restart)
self.console.context_menu.addAction(self.restart_action)
def restart(self):
self.restart_requested = True
self.reject()
def closeEvent(self, *args):
dynamic.set('console_window_geometry',
bytearray(self.saveGeometry()))
self.console.shutdown()
return QDialog.closeEvent(self, *args)
def show():
while True:
m = MainWindow()
m.exec_()
if not m.restart_requested:
break
def main():
QApplication.setApplicationName(__appname__+' console')
QApplication.setOrganizationName('Kovid Goyal')
app = QApplication([])
app
show()
if __name__ == '__main__':
main()

View File

@ -1,11 +0,0 @@
#!/usr/bin/env python2
# vim:fileencoding=utf-8
from __future__ import (unicode_literals, division, absolute_import,
print_function)
__license__ = 'GPL v3'
__copyright__ = '2013, Kovid Goyal <kovid at kovidgoyal.net>'
# Dummy file for backwards compatibility with older plugins
from calibre.utils.search_query_parser import ParseException # noqa