From f6aa939fe5b963544e575f6c4e44a60813062912 Mon Sep 17 00:00:00 2001 From: Artem Lavrenov Date: Tue, 16 Jun 2020 13:11:11 +0300 Subject: [PATCH] webserver add tray icon --- plugin/httpserver.ico | Bin 0 -> 78396 bytes plugin/httpserver_mobile.py | 148 ++++++++++++++++++++++++++++++------ plugin/run_webserver.bat | 2 + plugin/settings.py | 2 + plugin/store.py | 3 +- python/get_python.bat | 2 +- 6 files changed, 130 insertions(+), 27 deletions(-) create mode 100644 plugin/httpserver.ico create mode 100644 plugin/run_webserver.bat diff --git a/plugin/httpserver.ico b/plugin/httpserver.ico new file mode 100644 index 0000000000000000000000000000000000000000..74dde81b649eedaee58db05851f4f8c4af246501 GIT binary patch literal 78396 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 a2|up36ZGeS|LJd-L*rL{4|UXWasLa3XY@J% literal 0 HcmV?d00001 diff --git a/plugin/httpserver_mobile.py b/plugin/httpserver_mobile.py index b78507d..49bed5f 100644 --- a/plugin/httpserver_mobile.py +++ b/plugin/httpserver_mobile.py @@ -1,10 +1,15 @@ # -*- coding: utf8 -*- ''' Автор ArtyLa ''' import os, sys, re, time, json, traceback, threading, logging, importlib,configparser +import wsgiref.simple_server from wsgiref.simple_server import make_server, WSGIServer, WSGIRequestHandler from socketserver import ThreadingMixIn sys.path.append('..\\plugin') import settings, store, dbengine # pylint: disable=import-error +try: + import win32api, win32gui, win32con, winerror +except ModuleNotFoundError: + print('No win32 installed, no tray icon') lang='p' # Для плагинов на python преффикс lang всегда 'p' @@ -132,24 +137,86 @@ def getreport(param=[]): res = template.format(style=style, html_header=html_header, html_table='\n'.join(html_table)) return 'text/html', [res] +class TrayIcon: + def __init__(self): + msg_TaskbarRestart = win32gui.RegisterWindowMessage("TaskbarCreated"); + message_map = { + msg_TaskbarRestart: self.OnRestart, + win32con.WM_DESTROY: self.OnDestroy, + win32con.WM_COMMAND: self.OnCommand, + win32con.WM_USER+20 : self.OnTaskbarNotify, + } + wc = win32gui.WNDCLASS() + hinst = wc.hInstance = win32api.GetModuleHandle(None) + wc.lpszClassName = "PythonTaskbarDemo" + wc.style = win32con.CS_VREDRAW | win32con.CS_HREDRAW; + wc.hCursor = win32api.LoadCursor( 0, win32con.IDC_ARROW ) + wc.hbrBackground = win32con.COLOR_WINDOW + wc.lpfnWndProc = message_map # could also specify a wndproc. + try: + classAtom = win32gui.RegisterClass(wc) + except win32gui.error as err_info: + if err_info.winerror!=winerror.ERROR_CLASS_ALREADY_EXISTS: + raise + style = win32con.WS_OVERLAPPED | win32con.WS_SYSMENU + self.hwnd = win32gui.CreateWindow( wc.lpszClassName, "Taskbar Demo", style, \ + 0, 0, win32con.CW_USEDEFAULT, win32con.CW_USEDEFAULT, \ + 0, 0, hinst, None) + win32gui.UpdateWindow(self.hwnd) + self._DoCreateIcons() -def simple_app(environ, start_response): - status = '200 OK' - ct, text = 'text/html',[] - fn=environ.get('PATH_INFO', None) - _, cmd, *param = fn.split('/') - #print(f'{cmd}, {param}') - if cmd.lower() == 'getbalance': - ct, text = getbalance(param) # TODO !!! Но правильно все-таки через POST - if cmd == '' or cmd == 'report': # report - ct, text = getreport(param) - #ct, text = 'text/html', [f'REPORT'] - #th = f'{threading.currentThread().name}:{chr(44).join([t.name for t in threading.enumerate()[1:]])}' - headers = [('Content-type', ct)] - start_response(status, headers) - #print('text',text) - return [line.encode('cp1251') for line in text] - + def run_forever(self): + win32gui.PumpMessages() + + def _DoCreateIcons(self, iconame = 'httpserver.ico'): + # Try and find a custom icon + hinst = win32api.GetModuleHandle(None) + iconPathName = os.path.join(os.path.split(os.path.abspath(sys.argv[0]))[0], iconame) + if os.path.isfile(iconPathName): + icon_flags = win32con.LR_LOADFROMFILE | win32con.LR_DEFAULTSIZE + hicon = win32gui.LoadImage(hinst, iconPathName, win32con.IMAGE_ICON, 0, 0, icon_flags) + else: + hicon = win32gui.LoadIcon(0, win32con.IDI_APPLICATION) + + flags = win32gui.NIF_ICON | win32gui.NIF_MESSAGE | win32gui.NIF_TIP + nid = (self.hwnd, 0, flags, win32con.WM_USER+20, hicon, "Python Demo") + try: + win32gui.Shell_NotifyIcon(win32gui.NIM_ADD, nid) + except win32gui.error: + print(f"Failed to add the taskbar icon - is explorer running? {''.join(traceback.format_exception(*sys.exc_info()))}") + + def OnRestart(self, hwnd, msg, wparam, lparam): + self._DoCreateIcons() + + def OnDestroy(self, hwnd, msg, wparam, lparam): + nid = (self.hwnd, 0) + win32gui.Shell_NotifyIcon(win32gui.NIM_DELETE, nid) + win32gui.PostQuitMessage(0) # Terminate the app. + + def OnTaskbarNotify(self, hwnd, msg, wparam, lparam): + if lparam==win32con.WM_LBUTTONDBLCLK: + print("You double-clicked me - goodbye") + win32gui.DestroyWindow(self.hwnd) + elif lparam==win32con.WM_RBUTTONUP: + print("You right clicked me.") + menu = win32gui.CreatePopupMenu() + #win32gui.AppendMenu( menu, win32con.MF_STRING, 1024, "Say Hello") + win32gui.AppendMenu( menu, win32con.MF_STRING, 1025, "Exit program" ) + pos = win32gui.GetCursorPos() + # See http://msdn.microsoft.com/library/default.asp?url=/library/en-us/winui/menus_0hdi.asp + win32gui.SetForegroundWindow(self.hwnd) + win32gui.TrackPopupMenu(menu, win32con.TPM_LEFTALIGN, pos[0], pos[1], 0, self.hwnd, None) + win32gui.PostMessage(self.hwnd, win32con.WM_NULL, 0, 0) + return 1 + + def OnCommand(self, hwnd, msg, wparam, lparam): + id = win32api.LOWORD(wparam) + #if id == 1024: print("Hello") + if id == 1025: + print("Goodbye") + win32gui.DestroyWindow(self.hwnd) + else: + print("Unknown command -", id) class Handler(WSGIRequestHandler): # Disable logging DNS lookups @@ -164,15 +231,46 @@ class ThreadingWSGIServer(ThreadingMixIn, WSGIServer): pass +class WebServer(): + def __init__(self): + logging.basicConfig(filename="..\\log\\http.log", level=logging.INFO,format = u'[%(asctime)s] %(levelname)s %(funcName)s %(message)s') + port = int(store.read_ini()['HttpServer'].get('port', settings.port)) + with wsgiref.simple_server.make_server('127.0.0.1', port, self.simple_app, server_class=ThreadingWSGIServer, handler_class=Handler) as self.httpd: + logging.info(f'Listening on port {port}....') + if 'win32api' in sys.modules: + self.webserver_thread = threading.Thread(target=self.httpd.serve_forever) + self.webserver_thread.daemon = True + self.webserver_thread.name = 'ThrWeb' + self.webserver_thread.start() + TrayIcon().run_forever() + else: + # не установлен pywin32, иконки в трее не будет запускаем web сервер в основном потоке + self.httpd.serve_forever() + + + def simple_app(self,environ, start_response): + status = '200 OK' + ct, text = 'text/html',[] + fn=environ.get('PATH_INFO', None) + _, cmd, *param = fn.split('/') + #print(f'{cmd}, {param}') + if cmd.lower() == 'getbalance': + ct, text = getbalance(param) # TODO !!! Но правильно все-таки через POST + if cmd == '' or cmd == 'report': # report + ct, text = getreport(param) + #ct, text = 'text/html', [f'REPORT'] + if cmd == 'exit': # exit cmd + self.httpd.shutdown() + + #th = f'{threading.currentThread().name}:{chr(44).join([t.name for t in threading.enumerate()[1:]])}' + headers = [('Content-type', ct)] + start_response(status, headers) + #print('text',text) + return [line.encode('cp1251') for line in text] + + def main(): - logging.basicConfig(filename="..\\log\\http.log", level=logging.INFO, - format = u'[%(asctime)s] %(levelname)s %(funcName)s %(message)s') - - # with make_server('', self.port, self.web_app, handler_class=Handler) as server: - port = int(store.read_ini()['HttpServer'].get('port', settings.port)) - with make_server('127.0.0.1', port, simple_app, server_class=ThreadingWSGIServer, handler_class=Handler) as httpd: - print(f'Listening on port {port}....') - httpd.serve_forever() + WebServer() if __name__ == '__main__': main() diff --git a/plugin/run_webserver.bat b/plugin/run_webserver.bat new file mode 100644 index 0000000..25a5245 --- /dev/null +++ b/plugin/run_webserver.bat @@ -0,0 +1,2 @@ +@echo off +start "" ..\python\pythonw.exe httpserver_mobile.py \ No newline at end of file diff --git a/plugin/settings.py b/plugin/settings.py index 8d539d2..abf1d6f 100644 --- a/plugin/settings.py +++ b/plugin/settings.py @@ -25,5 +25,7 @@ # порт http сервера с отчетами port = '8000' +# host '127.0.0.1' - доступ только локально, '0.0.0.0' - разрешить доступ к по сети +host = '127.0.0.1' # формат вывода по умолчанию table_format = 'PhoneNumber,Operator,UslugiOn,Balance,RealAverage,BalDelta,BalDeltaQuery,NoChangeDays,CalcTurnOff,SpendMin,SMS,Internet,Minutes,TarifPlan,BlockStatus' # ? UserName diff --git a/plugin/store.py b/plugin/store.py index f28535f..87d31cd 100644 --- a/plugin/store.py +++ b/plugin/store.py @@ -75,8 +75,9 @@ def read_ini(fn=settings.mbplugin_ini): 'balance_html':settings.balance_html } ini['HttpServer'] = {'port': settings.port, + 'host': settings.host, 'table_format': settings.table_format} - + ini.write(open(inipath, 'w')) else: raise RuntimeError(f'Not found {fn}') diff --git a/python/get_python.bat b/python/get_python.bat index 17b0901..c5c85f9 100644 --- a/python/get_python.bat +++ b/python/get_python.bat @@ -19,7 +19,7 @@ if not exist Scripts\pip.exe python get-pip.py python -c "d=open('python38._pth').read();open('python38._pth','w').write(d.replace('#import site','import site'))" @REM mbplugin\python -python -m pip install --upgrade requests pillow beautifulsoup4 pyodbc pyreadline +python -m pip install --upgrade requests pillow beautifulsoup4 pyodbc pyreadline pywin32 @REM tkinter python @rem https://stackoverflow.com/questions/37710205/python-embeddable-zip-install-tkinter