diff options
author | m32 <grzegorz.makarewicz@gmail.com> | 2021-04-08 01:49:36 +0300 |
---|---|---|
committer | m32 <grzegorz.makarewicz@gmail.com> | 2021-04-08 01:49:36 +0300 |
commit | 2d805b20d52694cb639dd1f33a04da2b7b39976e (patch) | |
tree | d1f805bbfa0b45208920fb0ecda0551493882d90 /python/configs | |
parent | 491ab599043660d88177621d16fbe4a8f4fbfe7e (diff) |
use standard python logging module
use vscode to debug python plugins - py:debug in shell window
dynamic loading python plugins from user directory ~.config/far2l/plugins/python in shell winow command - py:load, py:unload
included plugins should be loaded in a new way after copying to the configured directory
Diffstat (limited to 'python/configs')
-rw-r--r-- | python/configs/plug/far2l/.vscode/launch.json | 14 | ||||
-rw-r--r-- | python/configs/plug/far2l/.vscode/settings.json | 18 | ||||
-rw-r--r-- | python/configs/plug/far2l/__init__.py | 12 | ||||
-rw-r--r-- | python/configs/plug/far2l/logger.ini | 33 | ||||
-rw-r--r-- | python/configs/plug/far2l/logger.py | 43 | ||||
-rw-r--r-- | python/configs/plug/far2l/plugin.py | 61 | ||||
-rw-r--r-- | python/configs/plug/far2l/pluginmanager.py | 270 | ||||
-rw-r--r-- | python/configs/plug/far2l/rpdb.py | 125 | ||||
-rw-r--r-- | python/configs/plug/far2l/ucharmap.py | 15 | ||||
-rw-r--r-- | python/configs/plug/far2l/udialog.py | 20 | ||||
-rw-r--r-- | python/configs/plug/far2l/upanel.py | 6 |
11 files changed, 317 insertions, 300 deletions
diff --git a/python/configs/plug/far2l/.vscode/launch.json b/python/configs/plug/far2l/.vscode/launch.json new file mode 100644 index 00000000..04eb947b --- /dev/null +++ b/python/configs/plug/far2l/.vscode/launch.json @@ -0,0 +1,14 @@ +{ + "version": "0.2.0", + "configurations": [ + { + "name": "Python Attach", + "type": "python", + "request": "attach", + "localRoot": "${workspaceRoot}", + "remoteRoot": "${workspaceRoot}", + "port": 5678, + "host": "localhost" + } + ] +}
\ No newline at end of file diff --git a/python/configs/plug/far2l/.vscode/settings.json b/python/configs/plug/far2l/.vscode/settings.json new file mode 100644 index 00000000..9eb6c7cd --- /dev/null +++ b/python/configs/plug/far2l/.vscode/settings.json @@ -0,0 +1,18 @@ +{ + "actionButtons": { + "reloadButton": null, + "loadNpmCommands": false, + "commands": [ + { + "name": "Run Cargo", + "singleInstance": true, + "color": "#af565c", + "command": "cargo run ${file}", + }, + ] + }, + "python.pythonPath": "/devel/bin/farg/Plugins/python/plug/python/bin/python", + "python.analysis.extraPaths": [ + "/devel/bin/farg/Plugins/python/plug", + ] +}
\ No newline at end of file diff --git a/python/configs/plug/far2l/__init__.py b/python/configs/plug/far2l/__init__.py index a77bbacd..1b1f654b 100644 --- a/python/configs/plug/far2l/__init__.py +++ b/python/configs/plug/far2l/__init__.py @@ -1,13 +1,5 @@ -import sys -import io from . import logger +from .pluginmanager import PluginManager -try: - from .pluginmanager import PluginManager - pluginmanager = PluginManager() -except: - fp = io.StringIO() - import traceback - traceback.print_exc(file=fp) - sys.stderr.write(fp.getvalue()) +pluginmanager = PluginManager() diff --git a/python/configs/plug/far2l/logger.ini b/python/configs/plug/far2l/logger.ini new file mode 100644 index 00000000..8eb82a0f --- /dev/null +++ b/python/configs/plug/far2l/logger.ini @@ -0,0 +1,33 @@ +[loggers] +keys = root, sqlalchemy + +[handlers] +keys = file + +[formatters] +keys = simple + +[formatter_simple] +format = %(asctime)s %(module)s:%(lineno)d:%(levelname)s: %(message)s + +[handler_file] +class = logging.handlers.TimedRotatingFileHandler +args = ['/tmp/far2l-py', 'D', 1, 7] +formatter = simple + +[logger_root] +;level=NOTSET +level=DEBUG +;level=INFO +;level=WARNING +;level=ERROR +;level=CRITICAL +handlers=file + +[logger_sqlalchemy] +level = INFO +handlers = +qualname = sqlalchemy.engine +# "level = INFO" logs SQL queries. +# "level = DEBUG" logs SQL queries and results. +# "level = WARN" logs neither. (Recommended for production systems.) diff --git a/python/configs/plug/far2l/logger.py b/python/configs/plug/far2l/logger.py index 6e18dec0..7e21b8d9 100644 --- a/python/configs/plug/far2l/logger.py +++ b/python/configs/plug/far2l/logger.py @@ -1,23 +1,30 @@ import os import sys +import configparser +import logging +import logging.config -class Logger: - def __init__(self): - self.stdout = sys.stdout - self.stderr = sys.stderr - self.fp = open('/tmp/far2.py.log-py','at') - def write(self, msg): - self.fp.write(msg) - self.fp.flush() - def flush(self): - self.fp.flush() - def close(self): - self.fp.close() - sys.stdout = self.stdout - sys.stderr = self.stderr +logging.basicConfig(level=logging.INFO) -sys.stderr = sys.stdout = Logger() +def setup(): + fname = __file__.replace('.py','.ini') + with open(fname, "rt") as fp: + ini = configparser.ConfigParser() + ini.read_file(fp) + logging.config.fileConfig(ini) -print('%s start' % ('*'*20)) -print('sys.path=', sys.path) -print('cwd=', os.getcwd()) +setup() + +log = logging.getLogger(__name__) +log.debug('%s start' % ('*'*20)) +log.debug('sys.path={0}'.format(sys.path)) +log.debug('cwd={0}'.format(os.getcwd())) + +def handle_exception(exc_type, exc_value, exc_traceback): + if issubclass(exc_type, KeyboardInterrupt): + sys.__excepthook__(exc_type, exc_value, exc_traceback) + return + + log.error("Uncaught exception", exc_info=(exc_type, exc_value, exc_traceback)) + +sys.excepthook = handle_exception diff --git a/python/configs/plug/far2l/plugin.py b/python/configs/plug/far2l/plugin.py index 79d91ebd..64eca949 100644 --- a/python/configs/plug/far2l/plugin.py +++ b/python/configs/plug/far2l/plugin.py @@ -1,5 +1,8 @@ -class PluginBase: +import logging + +log = logging.getLogger(__name__) +class PluginBase: conf = False area = None @@ -16,95 +19,87 @@ class PluginBase: def f2s(self, s): return self.ffi.string(self.ffi.cast("wchar_t *", s)) - def HandleCommandLine(self, line): - print("Plugin.HandleCommandLine(", line, ")") + @staticmethod + def HandleCommandLine(line): + log.debug("Plugin.HandleCommandLine({0})".format(line)) + return False def OpenPlugin(self, OpenFrom): - print("Plugin.OpenPlugin(", OpenFrom, ")") + log.debug("Plugin.OpenPlugin({0})".format(OpenFrom)) def Close(self): - print("Plugin.Close()") + log.debug("Plugin.Close()") class PluginVFS(PluginBase): def GetOpenPluginInfo(self, OpenInfo): - print("VFS.GetOpenPluginInfo(", OpenInfo, ")") + log.debug("VFS.GetOpenPluginInfo({0})".format(OpenInfo)) def FreeFindData(self, PanelItem, ItemsNumber): - print("VFS.FreeFindData(", PanelItem, ",", ItemsNumber, ")") + log.debug("VFS.FreeFindData({0}, {1})".format(PanelItem, ItemsNumber)) def FreeVirtualFindData(self, PanelItem, ItemsNumber): - print("VFS.FreeVirtualFindData(", PanelItem, ",", ItemsNumber, ")") + log.debug("VFS.FreeVirtualFindData({0}, {1})".format(PanelItem, ItemsNumber)) def Compare(self, PanelItem1, PanelItem2, Mode): - print("VFS.Compare(", PanelItem1, ",", PanelItem2, ",", Mode, ")") + log.debug("VFS.Compare({0}, {1}, {2})".format(PanelItem1, PanelItem2, Mode)) return -2 def DeleteFiles(self, PanelItem, ItemsNumber, OpMode): - print("VFS.DeleteFiles(", PanelItem, ",", ItemsNumber, ",", OpMode, ")") + log.debug("VFS.DeleteFiles({0}, {1}, {2})".format(PanelItem, ItemsNumber, OpMode)) return 0 def GetFiles(self, PanelItem, ItemsNumber, Move, DestPath, OpMode): - print( - "VFS.GetFiles(", + log.debug("VFS.GetFiles({0}, {1}, {2}, {3}, {4}".format( PanelItem, - ",", ItemsNumber, - ",", Move, - ",", DestPath, - ",", OpMode, - ")", + ) ) return 0 def GetFindData(self, PanelItem, ItemsNumber, OpMode): - print("VFS.GetFindData(", PanelItem, ",", ItemsNumber, ",", OpMode, ")") + log.debug("VFS.GetFindData({0}, {1}, {2})".format(PanelItem, ItemsNumber, OpMode)) return 0 def GetVirtualFindData(self, PanelItem, ItemsNumber, Path): - print("VFS.GetVirtualFindData(", PanelItem, ",", ItemsNumber, ",", Path, ")") + log.debug("VFS.GetVirtualFindData({0}, {1}, {2})".format(PanelItem, ItemsNumber, Path)) return 0 - def MakeDirectory(self, PanelItem, Name, OpMode): - print("VFS.GetMakeDirectoryFindData(", PanelItem, ",", Name, ",", OpMode, ")") + def MakeDirectory(self, Name, OpMode): + log.debug("VFS.GetMakeDirectoryFindData({0}, {1})".format(Name, OpMode)) return 0 def ProcessEvent(self, Event, Param): - print("VFS.ProcessEvent(", Event, ",", Param, ")") + log.debug("VFS.ProcessEvent({0}, {1})".format(Event, Param)) return 0 def ProcessHostFile(self, PanelItem, ItemsNumber, OpMode): - print("VFS.ProcessHostFile(", PanelItem, ",", ItemsNumber, ",", OpMode, ")") + log.debug("VFS.ProcessHostFile({0}, {1}, {2})".format(PanelItem, ItemsNumber, OpMode)) return 0 def ProcessKey(self, Key, ControlState): - print("VFS.ProcessKey(", Key, ",", ControlState, ")") + log.debug("VFS.ProcessKey({0}, {1})".format(Key, ControlState)) return 0 def PutFiles(self, PanelItem, ItemsNumber, Move, SrcPath, OpMode): - print( - "VFS.PutFiles(", + log.debug("VFS.PutFiles({0}, {1}, {2}, {3}, {4}".format( PanelItem, - ",", ItemsNumber, - ",", Move, - ",", SrcPath, - ",", OpMode, - ")", + ) ) return 0 def SetDirectory(self, Dir, OpMode): - print("VFS.SetDirectory(", Dir, ",", OpMode, ")") + log.debug("VFS.SetDirectory({0}, {1})".format(Dir, OpMode)) return 0 def SetFindList(self, PanelItem, ItemsNumber): - print("VFS.SetFindList(", PanelItem, ",", ItemsNumber, ")") + log.debug("VFS.SetFindList({0}, {1})".format(PanelItem, ItemsNumber)) return 0 diff --git a/python/configs/plug/far2l/pluginmanager.py b/python/configs/plug/far2l/pluginmanager.py index 0a6c0ca0..fb63a56d 100644 --- a/python/configs/plug/far2l/pluginmanager.py +++ b/python/configs/plug/far2l/pluginmanager.py @@ -1,30 +1,36 @@ import os +import os.path +import sys +import types +import logging import cffi -from sys import platform -from . import rpdb +import debugpy +from .plugin import PluginBase + +sys.path.insert(1, os.path.expanduser('~/.config/far2l/plugins/python')) +log = logging.getLogger(__name__) +debugpy.log_to("/tmp") +# in vs code debuger select attach, port = 5678 +# commands in shell: +# py:debug +# py:load <python modulename> +# py:unload <registered python module name> +debugpy.listen(("localhost", 5678)) + def installffi(ffi): - print('installffi(', __file__, ')') - dname = '/'.join(__file__.split('/')[:-1]) - for fname in ( - 'farwin.h', - 'farcolor.hpp', - 'farkeys.hpp', - 'plugin.hpp' - ): - data = open(os.path.join(dname, fname), 'rt', encoding='utf-8').read() + dname = "/".join(__file__.split("/")[:-1]) + for fname in ("farwin.h", "farcolor.hpp", "farkeys.hpp", "plugin.hpp"): + fqname = os.path.join(dname, fname) + log.debug("installffi({0})".format(fqname)) + data = open(fqname, "rt", encoding="utf-8").read() ffi.cdef(data, packed=True) + ffi = cffi.FFI() installffi(ffi) -#ffi.cdef(open(__file__+'.h', 'rt').read(), packed=True) -ffic = ffi.dlopen('c' if platform != 'darwin' else 'libSystem.dylib') - -from . import ( - udialog, - ucharmap, - upanel, -) +# ffi.cdef(open(__file__+'.h', 'rt').read(), packed=True) +ffic = ffi.dlopen("c" if sys.platform != "darwin" else "libSystem.dylib") class PluginManager: Info = None @@ -33,85 +39,107 @@ class PluginManager: self.openplugins = {} self.plugins = [] - self.AddPlugin(udialog) - self.AddPlugin(ucharmap) - self.AddPlugin(upanel) - - def AddPlugin(self, plugin): - self.plugins.append(plugin) - def debugger(self): - # in another window type: nc 127.0.0.1 7654 - rpdb.RemotePdb(host='127.0.0.1', port=7654).set_trace() + debugpy.wait_for_client() def SetStartupInfo(self, Info): - #print('SetStartupInfo %08X' % Info) + log.debug("SetStartupInfo({0:08X})".format(Info)) self.Info = ffi.cast("struct PluginStartupInfo *", Info) def area2where(self, area): cvt = { - 'disk': ffic.OPEN_DISKMENU, - 'plugins': ffic.OPEN_PLUGINSMENU, - 'find': ffic.OPEN_FINDLIST, - 'shortcut': ffic.OPEN_SHORTCUT, - 'shell': ffic.OPEN_COMMANDLINE, - 'editor': ffic.OPEN_EDITOR, - 'viewer': ffic.OPEN_VIEWER, - 'panel': ffic.OPEN_FILEPANEL, - 'dialog': ffic.OPEN_DIALOG, - 'analyse': ffic.OPEN_ANALYSE, + "disk": ffic.OPEN_DISKMENU, + "plugins": ffic.OPEN_PLUGINSMENU, + "find": ffic.OPEN_FINDLIST, + "shortcut": ffic.OPEN_SHORTCUT, + "shell": ffic.OPEN_COMMANDLINE, + "editor": ffic.OPEN_EDITOR, + "viewer": ffic.OPEN_VIEWER, + "panel": ffic.OPEN_FILEPANEL, + "dialog": ffic.OPEN_DIALOG, + "analyse": ffic.OPEN_ANALYSE, } where = 0 for area in area.split(): - where |= 1<<cvt[area.lower()] + where |= 1 << cvt[area.lower()] return where - def getplugin(self, hPlugin): + def pluginRemove(self, name): + log.debug("remove plugin: {0}".format(name)) + for i in range(len(self.plugins)): + if self.plugins[i].Plugin.name == name: + del self.plugins[i] + del sys.modules[name] + return + log.error("install plugin: {0} - not installed".format(name)) + + def pluginInstall(self, name): + log.debug("install plugin: {0}".format(name)) + for i in range(len(self.plugins)): + if self.plugins[i].Plugin.name == name: + log.error("install plugin: {0} - allready installed".format(name)) + return + #plugin = __import__(name, globals(), locals(), [], 0) + plugin = __import__(name) + cls = getattr(plugin, 'Plugin', None) + if type(cls) == type(PluginBase) and issubclass(cls, PluginBase): + # inject plugin name + cls.name = name + self.plugins.append(plugin) + else: + log.error("install plugin: {0} - not a far2l python plugin".format(name)) + del sys.modules[name] + + def pluginGet(self, hPlugin): v = self.openplugins.get(hPlugin, None) if v is None: + class Nop: def __getattr__(self, name): - print('Nop.', name) + log.debug("Nop."+name) return self + def __call__(self, *args): - print('Nop(', name,')') + log.debug("Nop({0})".format(args)) return None + v = Nop + log.error("unhandled pluginGet{0}".format(hPlugin)) return v def GetPluginInfo(self, Info): - #print('GetPluginInfo %08X' % Info) + # log.debug("GetPluginInfo({0:08X})".format(Info)) Info = ffi.cast("struct PluginInfo *", Info) self._DiskItems = [] self._MenuItems = [] self._ConfigItems = [] - print('GetPluginInfo') + log.debug("GetPluginInfo") for plugin in sorted(self.plugins, key=lambda plugin: plugin.Plugin.label): where = self.area2where(plugin.Plugin.area) - print(plugin.Plugin.label, '%08X'%where) - if where & 1<<ffic.OPEN_DISKMENU: + log.debug("{0} - {1:08X}".format(plugin.Plugin.label, where)) + if where & 1 << ffic.OPEN_DISKMENU: self._DiskItems.append(ffi.new("wchar_t []", plugin.Plugin.label)) if plugin.Plugin.conf: self._ConfigItems.append(ffi.new("wchar_t []", plugin.Plugin.label)) # find # shortcut - if where & 1<<ffic.OPEN_PLUGINSMENU: + if where & 1 << ffic.OPEN_PLUGINSMENU: self._MenuItems.append(ffi.new("wchar_t []", plugin.Plugin.label)) - elif where & 1<<ffic.OPEN_COMMANDLINE: + elif where & 1 << ffic.OPEN_COMMANDLINE: self._MenuItems.append(ffi.new("wchar_t []", plugin.Plugin.label)) - elif where & 1<<ffic.OPEN_EDITOR: + elif where & 1 << ffic.OPEN_EDITOR: self._MenuItems.append(ffi.new("wchar_t []", plugin.Plugin.label)) - elif where & 1<<ffic.OPEN_VIEWER: + elif where & 1 << ffic.OPEN_VIEWER: self._MenuItems.append(ffi.new("wchar_t []", plugin.Plugin.label)) - elif where & 1<<ffic.OPEN_FILEPANEL: + elif where & 1 << ffic.OPEN_FILEPANEL: self._MenuItems.append(ffi.new("wchar_t []", plugin.Plugin.label)) - elif where & 1<<ffic.OPEN_DIALOG: + elif where & 1 << ffic.OPEN_DIALOG: self._MenuItems.append(ffi.new("wchar_t []", plugin.Plugin.label)) # analyse self.DiskItems = ffi.new("wchar_t *[]", self._DiskItems) self.MenuItems = ffi.new("wchar_t *[]", self._MenuItems) self.ConfigItems = ffi.new("wchar_t *[]", self._ConfigItems) - Info.Flags = ffic.PF_EDITOR |ffic.PF_VIEWER |ffic.PF_DIALOG + Info.Flags = ffic.PF_EDITOR | ffic.PF_VIEWER | ffic.PF_DIALOG Info.DiskMenuStrings = self.DiskItems Info.DiskMenuStringsNumber = len(self._DiskItems) Info.PluginMenuStrings = self.MenuItems @@ -121,81 +149,110 @@ class PluginManager: Info.CommandPrefix = ffi.new("wchar_t []", "py") def ClosePlugin(self, hPlugin): - print('ClosePlugin %08X' % hPlugin) + log.debug("ClosePlugin %08X" % hPlugin) plugin = self.openplugins.get(hPlugin, None) if plugin is not None: plugin.Close() del self.openplugins[hPlugin] def Compare(self, hPlugin, PanelItem1, PanelItem2, Mode): - print('Compare', hPlugin, PanelItem1, PanelItem2, Mode) - plugin = self.getplugin(hPlugin) + log.debug("Compare({0}, {1}, {2}, {3})".format(hPlugin, PanelItem1, PanelItem2, Mode)) + plugin = self.pluginGet(hPlugin) return plugin.Compare(PanelItem1, PanelItem2, Mode) def Configure(self, ItemNumber): - print('Configure', ItemNumber) + log.debug("Configure({0})".format(ItemNumber)) def DeleteFiles(self, hPlugin, PanelItem, ItemsNumber, OpMode): - print('DeleteFiles', hPlugin, PanelItem, ItemsNumber, OpMode) - plugin = self.getplugin(hPlugin) + log.debug("DeleteFiles({0}, {1}, {2})".format(hPlugin, PanelItem, ItemsNumber, OpMode)) + plugin = self.pluginGet(hPlugin) return plugin.DeleteFiles(PanelItem, ItemsNumber, OpMode) def ExitFAR(self): - print('ExitFAR') + log.debug("ExitFAR()") def FreeFindData(self, hPlugin, PanelItem, ItemsNumber): - print('FreeFindData', hPlugin, PanelItem, ItemsNumber) - plugin = self.getplugin(hPlugin) + log.debug("FreeFindData({0}, {1}, {2})".format(hPlugin, PanelItem, ItemsNumber)) + plugin = self.pluginGet(hPlugin) return plugin.FreeFindData(PanelItem, ItemsNumber) def FreeVirtualFindData(self, hPlugin, PanelItem, ItemsNumber): - print('FreeVirtualData', hPlugin, PanelItem, ItemsNumber) - plugin = self.getplugin(hPlugin) + log.debug("FreeVirtualData({0}, {1}, {2})".format(hPlugin, PanelItem, ItemsNumber)) + plugin = self.pluginGet(hPlugin) return plugin.FreeVirtualFindData(PanelItem, ItemsNumber) def GetFiles(self, hPlugin, PanelItem, ItemsNumber, Move, DestPath, OpMode): - print('GetFiles', hPlugin, PanelItem, ItemsNumber, Move, DestPath, OpMode) - plugin = self.getplugin(hPlugin) + log.debug("GetFiles({0}, {1}, {2}, {3}, {4}, {5})".format(hPlugin, PanelItem, ItemsNumber, Move, DestPath, OpMode)) + plugin = self.pluginGet(hPlugin) return plugin.GetFiles(PanelItem, ItemsNumber, Move, DestPath, OpMode) def GetFindData(self, hPlugin, PanelItem, ItemsNumber, OpMode): - print('GetFindData', hPlugin, PanelItem, ItemsNumber, OpMode) - plugin = self.getplugin(hPlugin) + log.debug("GetFindData({0}, {1}, {2}, {3})".format(hPlugin, PanelItem, ItemsNumber, OpMode)) + plugin = self.pluginGet(hPlugin) return plugin.GetFindData(PanelItem, ItemsNumber, OpMode) def GetMinFarVersion(self): - print('GetMinFarVersion') + log.debug("GetMinFarVersion()") def GetOpenPluginInfo(self, hPlugin, OpenInfo): - print('GetOpenPluginInfo', hPlugin, OpenInfo) - plugin = self.getplugin(hPlugin) + log.debug("GetOpenPluginInfo({0}, {1},)".format(hPlugin, OpenInfo)) + plugin = self.pluginGet(hPlugin) return plugin.GetOpenPluginInfo(OpenInfo) def GetVirtualFindData(self, hPlugin, PanelItem, ItemsNumber, Path): - print('GetVirtualFindData', hPlugin, PanelItem, ItemsNumber, Path) - plugin = self.getplugin(hPlugin) + log.debug("GetVirtualFindData({0}, {1}, {2}, {3})".format(hPlugin, PanelItem, ItemsNumber, Path)) + plugin = self.pluginGet(hPlugin) return plugin.GetVirtualFindData(PanelItem, ItemsNumber, Path) def MakeDirectory(self, hPlugin, Name, OpMode): - print('MakeDirectory', hPlugin, Name, OpMode) - plugin = self.getplugin(hPlugin) - return plugin.MakeDirectory(PanelItem, Name, OpMode) + log.debug("MakeDirectory({0}, {1}, {2})".format(hPlugin, Name, OpMode)) + plugin = self.pluginGet(hPlugin) + return plugin.MakeDirectory(Name, OpMode) def OpenFilePlugin(self, Name, Data, DataSize, OpMode): - print('OpenFilePlugin', Name, Data, DataSize, OpMode) + log.debug("OpenFilePlugin({0}, {1}, {2}, {3})".format(Name, Data, DataSize, OpMode)) def OpenPlugin(self, OpenFrom, Item): - print('OpenPlugin:', OpenFrom, Item) + log.debug("OpenPlugin({0}, {1})".format(OpenFrom, Item)) if OpenFrom == ffic.OPEN_COMMANDLINE: line = ffi.string(ffi.cast("wchar_t *", Item)) - print('cmd:', line) + log.debug("cmd:{0}".format(line)) + linesplit = line.split(' ') + if linesplit[0] == "debug": + self.debugger() + elif linesplit[0] == "unload": + if len(linesplit) > 1: + self.pluginRemove(linesplit[1]) + else: + log.debug("missing plugin name in py:unload <plugin name>") + elif linesplit[0] == "load": + if len(linesplit) > 1: + self.pluginInstall(linesplit[1]) + else: + log.debug("missing plugin name in py:load <plugin name>") + else: + for plugin in self.plugins: + log.debug("{0} | {1}".format(plugin.Plugin.label, plugin.Plugin.area)) + if plugin.Plugin.HandleCommandLine(line) is True: + plugin = plugin.Plugin(self, self.Info, ffi, ffic) + plugin.CommandLine(line) + break return this = None no = 0 for plugin in sorted(self.plugins, key=lambda plugin: plugin.Plugin.label): where = self.area2where(plugin.Plugin.area) - print(1, plugin.Plugin.label, '|', plugin.Plugin.area, '|', '%04X'%(1<<OpenFrom), 'where:', '%04X'%where, 'mask:', (1<<OpenFrom)&where, 'no:', no, 'Item', Item) - if (1<<OpenFrom) & where: + log.debug( + "where(1, {0} | {1} | {2:04X} where={3:04X} mask={4:04X} no={5} Item={6}".format( + plugin.Plugin.label, + plugin.Plugin.area, + (1 << OpenFrom), + where, + (1 << OpenFrom) & where, + no, + Item, + )) + if (1 << OpenFrom) & where: if no == Item: this = plugin break @@ -203,14 +260,23 @@ class PluginManager: if this is None: for plugin in sorted(self.plugins, key=lambda plugin: plugin.Plugin.label): where = self.area2where(plugin.Plugin.area) - print(2, plugin.Plugin.label, '|', plugin.Plugin.area, '|', '%04X'%(1<<OpenFrom), 'where:', '%04X'%where, 'mask:', (1<<OpenFrom)&where, 'no:', no, 'Item', Item) - if where & 1<<ffic.OPEN_PLUGINSMENU: + log.debug( + "where(2, {0} | {1} | {2:04X} where={3:04X} mask={4:04X} no={5} Item={6}".format( + plugin.Plugin.label, + plugin.Plugin.area, + (1 << OpenFrom), + where, + (1 << OpenFrom) & where, + no, + Item, + )) + if where & 1 << ffic.OPEN_PLUGINSMENU: if no == Item: this = plugin break no += 1 if not this: - print('unknown') + log.debug("unknown") return plugin = this.Plugin(self, self.Info, ffi, ffic) rc = plugin.OpenPlugin(OpenFrom) @@ -220,50 +286,50 @@ class PluginManager: return rc def ProcessDialogEvent(self, Event, Param): - #print('ProcessDialogEvent', Event, Param) + # log.debug("ProcessDialogEvent({0}, {1}))".format(Event, Param)) pass def ProcessEditorEvent(self, Event, Param): - #print('ProcessEditorEvent', Event, Param) + # log.debug("ProcessEditorEvent({0}, {1})".format(Event, Param)) pass def ProcessEditorInput(self, Rec): - print('ProcessEditorInput', Rec) + log.debug("ProcessEditorInput({0})".format(Rec)) def ProcessEvent(self, hPlugin, Event, Param): - #print('ProcessEvent', hPlugin, Event, Param) - plugin = self.getplugin(hPlugin) + # log.debug("ProcessEvent({0}, {1}, {2})".format(hPlugin, Event, Param)) + plugin = self.pluginGet(hPlugin) return plugin.ProcessEvent(Event, Param) def ProcessHostFile(self, hPlugin, PanelItem, ItemsNumber, OpMode): - print('ProcessHostFile', hPlugin, PanelItem, ItemsNumber, OpMode) - plugin = self.getplugin(hPlugin) + log.debug("ProcessHostFile({0}, {1}, {2}, {3})".format(hPlugin, PanelItem, ItemsNumber, OpMode)) + plugin = self.pluginGet(hPlugin) return plugin.ProcessHostFile(PanelItem, ItemsNumber, OpMode) def ProcessKey(self, hPlugin, Key, ControlState): - print('ProcessKey', hPlugin, Key, ControlState) - plugin = self.getplugin(hPlugin) + log.debug("ProcessKey({0}, {1}, {2})".format(hPlugin, Key, ControlState)) + plugin = self.pluginGet(hPlugin) return plugin.ProcessKey(Key, ControlState) def ProcessSynchroEvent(self, Event, Param): - #print('ProcessSynchroEvent', Event, Param) + # log.debug("ProcessSynchroEvent({0}, {1})".format(Event, Param)) pass def ProcessViewerEvent(self, Event, Param): - #print('ProcessViewerEvent', Event, Param) + # log.debug("ProcessViewerEvent({0}, {1})".format(Event, Param)) pass def PutFiles(self, hPlugin, PanelItem, ItemsNumber, Move, SrcPath, OpMode): - print('PutFiles', hPlugin, PanelItem, ItemsNumber, Move, SrcPath, OpMode) - plugin = self.getplugin(hPlugin) + log.debug("PutFiles({0}, {1}, {2}, {3}, {4}, {5})".format(hPlugin, PanelItem, ItemsNumber, Move, SrcPath, OpMode)) + plugin = self.pluginGet(hPlugin) return plugin.PutFiles(PanelItem, ItemsNumber, Move, SrcPath, OpMode) def SetDirectory(self, hPlugin, Dir, OpMode): - print('SetDirectory', hPlugin, Dir, OpMode) - plugin = self.getplugin(hPlugin) + log.debug("SetDirectory({0}, {1}, {2})".format(hPlugin, Dir, OpMode)) + plugin = self.pluginGet(hPlugin) return plugin.SetDirectory(Dir, OpMode) def SetFindList(self, hPlugin, PanelItem, ItemsNumber): - print('SetFindList', hPlugin, PanelItem, ItemsNumber) - plugin = self.getplugin(hPlugin) + log.debug("SetFindList({0}, {1}, {2})".format(hPlugin, PanelItem, ItemsNumber)) + plugin = self.pluginGet(hPlugin) return plugin.SetFindList(PanelItem, ItemsNumber) diff --git a/python/configs/plug/far2l/rpdb.py b/python/configs/plug/far2l/rpdb.py deleted file mode 100644 index cfbeb5dc..00000000 --- a/python/configs/plug/far2l/rpdb.py +++ /dev/null @@ -1,125 +0,0 @@ -import errno -import logging -import re -import socket -import sys - -from pdb import Pdb - -__version__ = "1.2.0" - -PY3 = sys.version_info[0] == 3 - - -def cry(message, stderr=sys.__stderr__): - logging.critical(message) - print(message, file=stderr) - stderr.flush() - - -class LF2CRLF_FileWrapper(object): - def __init__(self, fh): - self.stream = fh - self.read = fh.read - self.readline = fh.readline - self.readlines = fh.readlines - self.close = fh.close - self.flush = fh.flush - self.fileno = fh.fileno - - @property - def encoding(self): - return self.stream.encoding - - def __iter__(self): - return self.stream.__iter__() - - def write(self, data, nl_rex=re.compile("\r?\n")): - self.stream.write(nl_rex.sub("\r\n", data)) - # we have to explicitly flush, and unfortunately we cannot just disable buffering because on Python 3 text - # streams line buffering seems the minimum and on Windows line buffering doesn't work properly because we - # write unix-style line endings - self.stream.flush() - - def writelines(self, lines, nl_rex=re.compile("\r?\n")): - self.stream.writelines(nl_rex.sub("\r\n", line) for line in lines) - self.stream.flush() - - -class RemotePdb(Pdb): - """ - This will run pdb as a ephemeral telnet service. Once you connect no one - else can connect. On construction this object will block execution till a - client has connected. - - Based on https://github.com/tamentis/rpdb I think ... - - To use this:: - - RemotePdb(host='0.0.0.0', port=4444).set_trace() - - Then run: telnet 127.0.0.1 4444 - """ - active_instance = None - - def __init__(self, host, port, patch_stdstreams=False): - listen_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) - listen_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, True) - listen_socket.bind((host, port)) - cry("RemotePdb session open at %s:%s, waiting for connection ..." % listen_socket.getsockname()) - listen_socket.listen(1) - connection, address = listen_socket.accept() - cry("RemotePdb accepted connection from %s." % repr(address)) - if PY3: - self.handle = LF2CRLF_FileWrapper(connection.makefile('rw')) - else: - self.handle = LF2CRLF_FileWrapper(connection.makefile()) - Pdb.__init__(self, completekey='tab', stdin=self.handle, stdout=self.handle) - self.backup = [] - if patch_stdstreams: - for name in ( - 'stderr', - 'stdout', - '__stderr__', - '__stdout__', - 'stdin', - '__stdin__', - ): - self.backup.append((name, getattr(sys, name))) - setattr(sys, name, self.handle) - RemotePdb.active_instance = self - - def __restore(self): - if self.backup: - cry('Restoring streams: %s ...' % self.backup) - for name, fh in self.backup: - setattr(sys, name, fh) - self.handle.close() - RemotePdb.active_instance = None - - def do_quit(self, arg): - self.__restore() - self.set_quit() - return 1 - - do_q = do_exit = do_quit - - def set_trace(self, frame=None): - if frame is None: - frame = sys._getframe().f_back - try: - Pdb.set_trace(self, frame) - except IOError as exc: - if exc.errno != errno.ECONNRESET: - raise - - def set_quit(self): - sys.settrace(None) - - -def set_trace(host='127.0.0.1', port=0, patch_stdstreams=False): - """ - Opens a remote PDB on first available port. - """ - rdb = RemotePdb(host=host, port=port, patch_stdstreams=patch_stdstreams) - rdb.set_trace(frame=sys._getframe().f_back) diff --git a/python/configs/plug/far2l/ucharmap.py b/python/configs/plug/far2l/ucharmap.py index 8b537701..a73ac056 100644 --- a/python/configs/plug/far2l/ucharmap.py +++ b/python/configs/plug/far2l/ucharmap.py @@ -1,4 +1,9 @@ -from .plugin import PluginBase +import logging +from far2l.plugin import PluginBase + + +log = logging.getLogger(__name__) + class Plugin(PluginBase): label = "Python Character Map" @@ -56,7 +61,7 @@ class Plugin(PluginBase): elif Msg == self.ffic.DN_BTNCLICK: return self.info.DefDlgProc(hDlg, Msg, Param1, Param2) elif Msg == self.ffic.DN_KEY and Param1 == self.first_text_item-1: - #print('key DialogProc(', hDlg, ', DN_KEY,', Param1, ',', Param2, ')') + log.debug('key DialogProc({0}, {1}, {2}, {3})'.format(hDlg, 'DN_KEY', Param1, Param2)) if Param2 == self.ffic.KEY_LEFT: self.cur_col -= 1 elif Param2 == self.ffic.KEY_UP: @@ -68,7 +73,7 @@ class Plugin(PluginBase): elif Param2 == self.ffic.KEY_ENTER: offset = self.cur_row*self.max_col+self.cur_col self.text = self.symbols[offset] - #print('enter:', offset, 'row:', self.cur_row, 'col:', self.cur_col, 'ch:', self.text) + log.debug('enter:{0} row:{1} col:{2}, ch:{3}'.format(offset, self.cur_row, self.cur_col, self.text)) return 0 elif Param2 == self.ffic.KEY_ESC: return 0 @@ -85,11 +90,11 @@ class Plugin(PluginBase): self.Rebuild(hDlg) return 1 elif Msg == self.ffic.DN_MOUSECLICK: - #print('mou DialogProc(', hDlg, ', DN_MOUSECLICK,', Param1, ',', Param2, ')') + log.debug('mou DialogProc({0}, {1}, {2}, {3})'.format(hDlg, 'DN_MOUSECLICK', Param1, Param2)) ch = Param1 - self.first_text_item if ch >= 0: focus = self.info.SendDlgMessage(hDlg, self.ffic.DM_GETFOCUS, 0, 0) - #print('ch=', ch, 'focus:', focus) + log.debug('ch:{0} focus:{1}'.format(ch, focus)) if focus != self.first_text_item-1: self.info.SendDlgMessage(hDlg, self.ffic.DM_SETFOCUS, self.first_text_item-1, 0) self.cur_row = ch // self.max_col diff --git a/python/configs/plug/far2l/udialog.py b/python/configs/plug/far2l/udialog.py index 1f457876..fc50733d 100644 --- a/python/configs/plug/far2l/udialog.py +++ b/python/configs/plug/far2l/udialog.py @@ -1,12 +1,21 @@ -from .plugin import PluginBase +import logging +from far2l.plugin import PluginBase + + +log = logging.getLogger(__name__) + class Plugin(PluginBase): label = "Python Command" area = "Plugins" - def HandleCommandLine(self, line): + @staticmethod + def HandleCommandLine(line): + return True + + def CommandLine(self, line): if line == 'dialog': - print('dialog') + log.debug('dialog') @self.ffi.callback("FARWINDOWPROC") def KeyDialogProc(hDlg, Msg, Param1, Param2): #if Msg == self.ffic.DN_KEY: @@ -25,12 +34,11 @@ class Plugin(PluginBase): if res != -1: sptr = self.info.SendDlgMessage(hDlg, self.ffic.DM_GETCONSTTEXTPTR, 2, 0) path = self.f2s(sptr) - print('path:', path) + log.debug('path: {0}'.format(path)) self.info.DialogFree(hDlg) - print('end dialog') + log.debug('end dialog') else: exec(line, globals(), locals()) - return -1 def OpenPlugin(self, OpenFrom): _MsgItems = [ diff --git a/python/configs/plug/far2l/upanel.py b/python/configs/plug/far2l/upanel.py index f789da13..b5d4d2a1 100644 --- a/python/configs/plug/far2l/upanel.py +++ b/python/configs/plug/far2l/upanel.py @@ -1,5 +1,9 @@ import os -from .plugin import PluginVFS +import logging +from far2l.plugin import PluginVFS + + +log = logging.getLogger(__name__) class Screen: |