Browse Source

代码上传

dukuisong 3 days ago
parent
commit
e065ed2d53

+ 1 - 0
config.json

@@ -0,0 +1 @@
+{"username": "admin", "password": "jxkj123456", "worker_path": "E:\\\\PycharmProjects\\\\office_plugin\\\\tools\\\\storage", "server": "http://120.195.49.22:7215"}

+ 9 - 2
tools/config.py → config.py

@@ -2,7 +2,8 @@ import os
 import sys
 
 CONFIG = {'oss': {
-    'endpoint': '172.10.3.36:9000',
+    # 'endpoint': '172.10.3.36:9000',
+    'endpoint': '10.18.5.29:9000',
     'access_key': 'miniominio',
     'secret_key': 'miniominio'
 }}
@@ -28,4 +29,10 @@ file_type_map = {
     'xlsx': ['ket.Application', 'Workbooks'],
     'xls': ['ket.Application', 'Workbooks'],
 }
-base_path = os.path.dirname(sys.executable if getattr(sys, 'frozen', False) else __file__)
+
+headers = {
+    'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/133.0.0.0 Safari/537.36',
+    'content-type': 'text/plain;charset=UTF-8'
+}
+dl_code = os.path.realpath(sys.argv[0])[:1]
+base_path = os.path.dirname(os.path.dirname(sys.executable if getattr(sys, 'frozen', False) else __file__))

+ 5 - 6
core/api_app.py

@@ -1,9 +1,7 @@
-import ctypes
 import logging
 import os
 import shutil
-import site
-import sys
+import socket
 
 import pythoncom
 import pywintypes
@@ -13,13 +11,13 @@ from flask_cors import CORS
 from win10toast import ToastNotifier
 
 from core.wps_handle import is_file_open_in_wps, bring_wps_window_to_front
-from tools.check import detect_oss_file_changes, detect_local_file_changes
-from tools.config import get_config, file_type_map
+from config import file_type_map
 from tools.file_manager import get_file_md5
 from tools.logger_handle import logger
 from tools.oss_client import oss_handle
-from tools.serve_client import ServerClient
 
+# ✅ 修复主机名非 UTF-8 解码错误
+socket.getfqdn = lambda name=None: 'localhost'
 toaster = ToastNotifier()
 
 app = Flask(__name__)
@@ -263,4 +261,5 @@ def start_flask(serve_client, work_path):
     app.config['work_path'] = work_path
     # app.logger.handlers.clear()
     # app.logger.addHandler(InterceptHandler())
+
     app.run(host='0.0.0.0', port=5855)

+ 35 - 7
core/monitor_file.py

@@ -1,29 +1,57 @@
 import os
 import time
+from threading import Timer
 
 from watchdog.observers import Observer
 from watchdog.events import FileSystemEventHandler
 from tools.logger_handle import logger
-from tools.oss_client import MinioClient, oss_handle
 
 
 class FileSaveHandler(FileSystemEventHandler):
     def __init__(self, serve_client):
         self.serve_client = serve_client
+        self.debounce_timers = {}
+        self.upload_cache = {}  # 文件路径 → 上次上传时间戳
+        self.debounce_delay = 5  # 延迟秒数
         super().__init__()
 
     def on_modified(self, event):
+        if event.is_directory:
+            return
+        filepath = event.src_path
         ext = os.path.splitext(event.src_path)[-1]
         if '~$' in event.src_path:
             return
 
-        if ext in ['.docx', '.doc', '.ppt', '.pptx', '.xls', '.xlsx']:
-            logger.info(f"[文件修改] 文件已保存: {event.src_path}, 执行上传操作。")
-            res = self.serve_client.upload_file(event.src_path)
+        if ext not in ['.docx', '.doc', '.ppt', '.pptx', '.xls', '.xlsx']:
+            return
+
+        def do_upload():
+            if not os.path.exists(filepath):
+                return
+
+            mtime = os.path.getmtime(filepath)
+            if self.upload_cache.get(filepath) == mtime:
+                logger.debug(f"[重复上传跳过] {filepath}")
+                return
+
+            logger.info(f"[文件修改] 文件已保存: {filepath}, 执行上传操作。")
+            res = self.serve_client.upload_file(filepath)
             if res:
-                logger.info(f'文件{event.src_path}上传成功')
+                logger.info(f'文件{filepath}上传成功')
             else:
-                logger.info(f'文件{event.src_path}上传失败')
+                logger.info(f'文件{filepath}上传失败')
+
+            self.upload_cache[filepath] = mtime
+            self.debounce_timers.pop(filepath, None)
+
+        if filepath in self.debounce_timers:
+            self.debounce_timers[filepath].cancel()
+
+        # 创建新的延迟上传任务
+        timer = Timer(self.debounce_delay, do_upload)
+        self.debounce_timers[filepath] = timer
+        timer.start()
 
 
 def start_watchdog(serve_client, work_path):
@@ -31,7 +59,7 @@ def start_watchdog(serve_client, work_path):
     observer = Observer()
     observer.schedule(event_handler, work_path, recursive=True)
     observer.start()
-    logger.info('watch dog start')
+    logger.info(f'watch dog start {serve_client}')
     try:
         while True:
             time.sleep(1)

+ 1 - 24
core/wps_handle.py

@@ -1,45 +1,22 @@
-import os
 import time
 
 import pythoncom
 import win32com
 import win32com.client
-import win32con
-import win32gui
 from win10toast import ToastNotifier
 
 from tools.check import is_file_open_in_wps
-from tools.config import file_type_map
 
 toaster = ToastNotifier()
 
 
-
 def bring_wps_window_to_front(file_path: str) -> bool:
     '''
     找到文件被打开的窗口置顶,目前实现方式会被windows安全程序拦截只会在控制栏闪烁窗口图标
     :param file_path:
     :return:
     '''
-    # abs_path = os.path.abspath(file_path).lower()
-    # suffix = file_path.split('.')[-1]
-    #
-    # try:
-    #     pythoncom.CoInitialize()
-    #     app = win32com.client.GetActiveObject(file_type_map[suffix][0])
-    #     for wb in getattr(app, file_type_map[suffix][1]):
-    #         if wb.FullName.lower() == abs_path:
-    #             hwnd = app.Hwnd  # WPS 主窗口句柄
-    #             if hwnd:
-    #                 win32gui.ShowWindow(hwnd, win32con.SW_RESTORE)  # 恢复最小化窗口
-    #                 win32gui.SetForegroundWindow(hwnd)  # 置顶窗口
-    #                 return True
-    # except Exception as e:
-    #     print("置顶失败:", e)
-    #     return False
-    # finally:
-    #     pythoncom.CoUninitialize()
-    # return False
+
     return True
 
 

BIN
icon.ico


+ 73 - 0
office_helper.py

@@ -0,0 +1,73 @@
+import functools
+import json
+import os.path
+import sys
+
+import threading
+
+from core.api_app import start_flask
+from core.monitor_file import start_watchdog
+from config import base_path, dl_code
+from tools.serve_client import ServerClient
+from tools.logger_handle import logger
+
+# 初始化 Flask 应用
+
+
+# 初始化桌面通知工具
+
+
+# 存储文档内容和推荐内容
+current_text = ""
+recommendation = "这是默认推荐内容"
+
+
+def ApplicationInstance(func):
+    @functools.wraps(func)
+    def fun(*args, **kwargs):
+        import socket
+        try:
+            global s
+            s = socket.socket()
+            host = socket.gethostname()
+            s.bind((host, 60123))
+        except:
+            logger.error('不能重复打开已存在的程序')
+            return None
+        return func(*args, **kwargs)
+
+    return fun
+
+
+# 启动所有后台服务
+@ApplicationInstance
+def start_all_services(serve_client, work_path):
+    # 启动 Flask 服务
+    threading.Thread(target=start_flask, args=[serve_client, work_path], daemon=True).start()
+    # 启动文件监控
+    threading.Thread(target=start_watchdog, args=[serve_client, work_path], daemon=True).start()
+    # 启动文档内容检查
+    # threading.Thread(target=check_for_changes, daemon=True).start()
+    logger.info('server running')
+    while True:
+        a = 0
+
+
+if __name__ == "__main__":
+    def set_working_directory():
+        if getattr(sys, 'frozen', False):
+            # 打包后的 exe
+            os.chdir(os.path.dirname(sys.executable))
+        else:
+            # 普通 Python 脚本
+            os.chdir(os.path.dirname(os.path.abspath(__file__)))
+
+
+    with open(f'{dl_code}:\\ProgramData\\OfficeAssistant\\config.json', 'r', encoding='utf-8') as f:
+        args = json.load(f)
+
+    client = ServerClient(args['server'], args['username'], args['password'])
+    if not os.path.exists(os.path.join(args['worker_path'], args['username'])):
+        os.makedirs(os.path.join(args['worker_path'], args['username']))
+
+    start_all_services(client, os.path.join(args['worker_path'], args['username']))

+ 0 - 50
office_helper_main.py

@@ -1,50 +0,0 @@
-import argparse
-import os.path
-
-
-import threading
-
-from core.api_app import app, start_flask
-from core.monitor_file import start_watchdog
-from tools.serve_client import ServerClient
-from tools.logger_handle import logger
-
-# 初始化 Flask 应用
-
-
-# 初始化桌面通知工具
-
-
-# 存储文档内容和推荐内容
-current_text = ""
-recommendation = "这是默认推荐内容"
-
-
-# 启动所有后台服务
-def start_all_services(serve_client, work_path):
-    # 启动 Flask 服务
-    threading.Thread(target=start_flask, args=[serve_client, work_path], daemon=True).start()
-    # 启动文件监控
-    # threading.Thread(target=start_watchdog, args=[serve_client, work_path], daemon=True).start()
-    # 启动文档内容检查
-    # threading.Thread(target=check_for_changes, daemon=True).start()
-    logger.info('server running')
-    while True:
-        a = 0
-
-
-if __name__ == "__main__":
-    parser = argparse.ArgumentParser(description='办公助手')
-
-    parser.add_argument('--worker_path', type=str, required=True, help='文件下载目录。')
-    parser.add_argument('--username', type=str, required=True, help='用户名')
-    parser.add_argument('--password', type=str, required=True, help='密码')
-    parser.add_argument('--server', type=str, required=True, help='密码')
-    args = parser.parse_args()
-
-    client = ServerClient(args.server, args.username, args.password)
-    if not os.path.exists(os.path.join(args.worker_path, args.username)):
-        os.makedirs(os.path.join(args.worker_path, args.username))
-
-    start_all_services(client, os.path.join(args.worker_path, args.username))
-

+ 2 - 2
readme

@@ -27,6 +27,6 @@ check_file_change_bu_oss
 upload_file
 上传本地文件覆盖oss端文件\
 
+pyinstaller --onefile --noconsole --windowed --icon=../icon.ico init_wps_plug.py
 
-
-pyinstaller --onefile --noconsole --windowed main.py
+pyinstaller --onefile --noconsole --windowed --icon=icon.ico office_helper.py

+ 22 - 0
setup_wps/init_wps_plug.py

@@ -0,0 +1,22 @@
+import json
+
+import requests
+
+import base64
+
+payload = {'data': {"cmd": "enable", "name": "wpsPlugin", "url": "http://172.10.3.110:3000/", "addonType": "wps",
+                    "online": "true"},
+           'serverId': '524ef80e-7ccd-43af-9fcb-69f3b0269730'}
+
+payload['data'] = base64.b64encode(json.dumps(payload['data']).encode('utf-8')).decode('utf-8')
+
+headers = {
+    'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/133.0.0.0 Safari/537.36',
+    'content-type': 'text/plain;charset=UTF-8'
+}
+resp = requests.post('http://localhost:58890/deployaddons/runParams', data=json.dumps(payload), headers=headers)
+
+
+# print(resp.text)
+
+

+ 1 - 2
tools/check.py

@@ -1,13 +1,12 @@
 import json
 import os
-import re
 import ipaddress
 from urllib.parse import urlparse
 
 import pythoncom
 import win32com
 
-from tools.config import base_path, file_type_map
+from config import base_path, file_type_map
 from tools.oss_client import MinioClient
 
 REPLY = {'html': None, 'cookies': None, 'token': None}

+ 1 - 7
tools/logger_handle.py

@@ -1,15 +1,9 @@
-import io
-
-import sys
-
 from loguru import logger
 
 from datetime import datetime
 
 log_month = datetime.now().strftime("%Y-%m")
 logger.remove()
-# sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding='utf-8')
-#
-logger.add(sys.stdout, level="INFO", format="{time:YYYY-MM-DD HH:mm:ss} | {level} | {message}")
+
 logger.add(f"serve_log/log_{datetime.now().strftime('%Y-%m-%d')}.log", format="{time} {level} {message}",
            rotation="100 MB", retention="1 week", compression=None)

+ 2 - 6
tools/oss_client.py

@@ -1,11 +1,9 @@
-import datetime
 import hashlib
 import json
-import os
 
 from minio import Minio, S3Error
 
-from tools.config import get_config
+from config import get_config
 from tools.logger_handle import logger
 
 
@@ -105,6 +103,4 @@ if __name__ == '__main__':
     print(client.upload_file(r'E:\PycharmProjects\office_plugin\tools\storage\admin\document-mgr_test.docx'))
     oss_path = 'test.docx'
     print(client.get_cloud_file_md5('document-mgr', 'test.docx'))
-    # client.fget_file('document-mgr',
-    #                  'document-mgr/ten_1/2_2/document-mgr/document-mgr/2025/05/27/2025-05-271112065750681423872-新建文件.docx',
-    #                  '接口文档.docx')
+

+ 3 - 6
tools/serve_client.py

@@ -5,12 +5,10 @@ import os.path
 import re
 
 import requests
-
 from Crypto.Cipher import AES
 
-from tools.config import SERVER_POINT
-from tools.oss_client import oss_handle
 from tools.logger_handle import logger
+from tools.oss_client import oss_handle
 
 
 class ServerClient:
@@ -185,13 +183,12 @@ class ServerClient:
 
 
 if __name__ == '__main__':
-    client = ServerClient('http://172.10.3.71:10001','admin', '123456')
+    client = ServerClient('http://172.10.3.71:10001', 'admin', '123456')
     # client = ServerClient('admin', 'jxkj123456')
     # client.download_file(
     #     {'file_name': 'test.docx', 'file_id': 'c5a8f3d5811e572265501eeaf6d8b1cf', 'bucket_name': 'aaa', }, '')
     res = client.get_file_info(r'585ec718900fa82ce3d35d515c9d8a4b')
-    res = client.decryption(
-        "")
+    res = client.decryption("")
 
     for row in res['data']:
         print(row)

+ 21 - 0
tools/wps_plugin_contorl.py

@@ -0,0 +1,21 @@
+import json
+
+import base64
+
+from config import base_path
+
+print(base_path)
+
+
+def encode_payload(payload):
+    payload['data'] = base64.b64encode(json.dumps(payload['data']).encode('utf-8')).decode('utf-8')
+    return json.dumps(payload)
+
+
+payload = {'data': {"cmd": "enable", "name": "wpsPlugin", "url": "http://172.10.3.110:3000/", "addonType": "wps",
+                    "online": "true"},
+           'serverId': '524ef80e-7ccd-43af-9fcb-69f3b0269730'}
+
+payload['data'] = base64.b64encode(json.dumps(payload['data']).encode('utf-8')).decode('utf-8')
+
+print(payload)