新增日志
This commit is contained in:
parent
a986d57492
commit
1947f5dcda
@ -2,6 +2,9 @@ import psycopg2
|
||||
from psycopg2.extras import RealDictCursor
|
||||
import datetime
|
||||
import uuid
|
||||
from utils.logger import get_logger, log_timing
|
||||
|
||||
logger = get_logger("db_manager")
|
||||
|
||||
class DatabaseManager:
|
||||
def __init__(self):
|
||||
@ -14,14 +17,16 @@ class DatabaseManager:
|
||||
}
|
||||
self.schema = '"tzwork"'
|
||||
|
||||
@log_timing
|
||||
def get_connection(self):
|
||||
try:
|
||||
conn = psycopg2.connect(**self.config)
|
||||
return conn
|
||||
except Exception as e:
|
||||
print(f"Database connection error: {e}")
|
||||
logger.error(f"Database connection error: {e}", exc_info=True)
|
||||
return None
|
||||
|
||||
@log_timing
|
||||
def insert_analysis_data(self, data_list):
|
||||
conn = self.get_connection()
|
||||
if not conn:
|
||||
@ -60,6 +65,7 @@ class DatabaseManager:
|
||||
conn.close()
|
||||
return False, str(e)
|
||||
|
||||
@log_timing
|
||||
def authenticate_user(self, user_id, password_md5):
|
||||
conn = self.get_connection()
|
||||
if not conn:
|
||||
@ -93,11 +99,12 @@ class DatabaseManager:
|
||||
}
|
||||
|
||||
except Exception as e:
|
||||
print(f"Authentication error: {e}")
|
||||
logger.error(f"Authentication error: {e}", exc_info=True)
|
||||
if conn:
|
||||
conn.close()
|
||||
return False, f"认证失败: {str(e)}"
|
||||
|
||||
@log_timing
|
||||
def get_latest_sample_data(self):
|
||||
"""
|
||||
Retrieves the most recently measured sample data, flattened.
|
||||
@ -145,7 +152,7 @@ class DatabaseManager:
|
||||
return result
|
||||
|
||||
except Exception as e:
|
||||
print(f"Query error: {e}")
|
||||
logger.error(f"Query error: {e}", exc_info=True)
|
||||
if conn:
|
||||
conn.close()
|
||||
return None
|
||||
@ -159,6 +166,7 @@ class DatabaseManager:
|
||||
return "合格"
|
||||
return "不合格"
|
||||
|
||||
@log_timing
|
||||
def insert_inspection_data(self, inspection_data):
|
||||
"""
|
||||
插入检验数据到 e_pz_hjqy_import 表
|
||||
@ -281,6 +289,7 @@ class DatabaseManager:
|
||||
conn.close()
|
||||
return False, f"插入失败: {str(e)}"
|
||||
|
||||
@log_timing
|
||||
def query_by_gch(self, gch):
|
||||
"""
|
||||
根据工程号查询产地、规格、炉号、材质等信息
|
||||
@ -322,6 +331,7 @@ class DatabaseManager:
|
||||
conn.close()
|
||||
return None, f"查询失败: {str(e)}"
|
||||
|
||||
@log_timing
|
||||
def get_inspection_list(self, limit=10, offset=0, user_id=''):
|
||||
"""
|
||||
分页获取检验数据列表
|
||||
@ -383,6 +393,7 @@ class DatabaseManager:
|
||||
conn.close()
|
||||
return None, f"查询失败: {str(e)}"
|
||||
|
||||
@log_timing
|
||||
def query_standard_range(self, heat_number, heat_number2):
|
||||
"""
|
||||
根据炉号1(tph)和炉号2(company_ph)查询标准值范围
|
||||
|
||||
@ -4,6 +4,7 @@ from ui.inspection_window import InspectionWindow
|
||||
from ui.login_window import LoginWindow
|
||||
from src.session_manager import SessionManager
|
||||
from datetime import datetime
|
||||
from utils.logger import setup_logging, get_logger
|
||||
|
||||
def get_mock_data():
|
||||
return [
|
||||
@ -73,6 +74,9 @@ def get_mock_data():
|
||||
]
|
||||
|
||||
def main():
|
||||
setup_logging()
|
||||
logger = get_logger("inspection_app")
|
||||
logger.info("Application starting...")
|
||||
app = QApplication(sys.argv)
|
||||
|
||||
font = app.font()
|
||||
|
||||
@ -1,7 +1,10 @@
|
||||
import xml.etree.ElementTree as ET
|
||||
import os
|
||||
from utils.logger import get_logger, log_timing
|
||||
logger = get_logger("xml_parser")
|
||||
|
||||
class XmlParser:
|
||||
@log_timing
|
||||
def parse_file(self, file_path):
|
||||
if not os.path.exists(file_path):
|
||||
return None, f"文件未找到: {file_path}"
|
||||
@ -123,6 +126,5 @@ class XmlParser:
|
||||
return extracted_data, "Success"
|
||||
|
||||
except Exception as e:
|
||||
import traceback
|
||||
traceback.print_exc()
|
||||
logger.error(f"Parse error: {str(e)}", exc_info=True)
|
||||
return None, f"Parse error: {str(e)}"
|
||||
|
||||
@ -8,6 +8,8 @@ from src.db_manager import DatabaseManager
|
||||
from src.xml_parser import XmlParser
|
||||
from utils.readMTP import MTPHandler
|
||||
from src.session_manager import SessionManager
|
||||
from utils.logger import get_logger, log_timing_context
|
||||
logger = get_logger("base_page")
|
||||
|
||||
class BaseInspectionPage(QDialog):
|
||||
def __init__(self, title, parent=None):
|
||||
@ -172,6 +174,7 @@ class BaseInspectionPage(QDialog):
|
||||
self.main_layout.addWidget(button_bar)
|
||||
|
||||
def on_sync(self):
|
||||
logger.info(f"[{self.page_type}] 开始同步操作")
|
||||
sync_mode = self.settings.value("sync_mode", "local")
|
||||
|
||||
xml_path = None
|
||||
@ -189,13 +192,15 @@ class BaseInspectionPage(QDialog):
|
||||
latest_xml = max(xml_files, key=os.path.getmtime)
|
||||
xml_path = latest_xml
|
||||
target_xml_name = os.path.basename(latest_xml)
|
||||
logger.info(f"本地模式,选定文件: {target_xml_name}")
|
||||
else:
|
||||
device_name = self.settings.value("mtp_device", "Trizeps VII")
|
||||
remote_path = self.settings.value("mtp_path", "")
|
||||
|
||||
self.show_info("正在同步", f"正在从设备 [{device_name}] 读取最新数据...")
|
||||
|
||||
local_cache, filename = self.mtp_handler.get_latest_xml_windows(device_name, remote_path)
|
||||
with log_timing_context(f"MTP同步 设备={device_name}", "base_page"):
|
||||
local_cache, filename = self.mtp_handler.get_latest_xml_windows(device_name, remote_path)
|
||||
if not local_cache:
|
||||
self.show_info("同步失败", f"MTP同步错误: {filename}")
|
||||
return
|
||||
@ -205,7 +210,8 @@ class BaseInspectionPage(QDialog):
|
||||
|
||||
# 1.解析xml
|
||||
parser = XmlParser()
|
||||
parsed_data, msg = parser.parse_file(xml_path)
|
||||
with log_timing_context("XML解析", "base_page"):
|
||||
parsed_data, msg = parser.parse_file(xml_path)
|
||||
|
||||
if not parsed_data:
|
||||
self.show_info("同步失败", f"XML解析错误: {msg}")
|
||||
@ -213,19 +219,21 @@ class BaseInspectionPage(QDialog):
|
||||
|
||||
# 2. 写入数据
|
||||
db = DatabaseManager()
|
||||
success, db_msg = db.insert_analysis_data(parsed_data)
|
||||
with log_timing_context("DB写入分析数据", "base_page"):
|
||||
success, db_msg = db.insert_analysis_data(parsed_data)
|
||||
|
||||
if not success:
|
||||
self.show_info("数据库错误", f"插入失败: {db_msg}\n(请检查数据库连接)")
|
||||
return
|
||||
|
||||
latest_data = db.get_latest_sample_data()
|
||||
with log_timing_context("DB读取最新样本数据", "base_page"):
|
||||
latest_data = db.get_latest_sample_data()
|
||||
if latest_data:
|
||||
self.update_ui_with_data(latest_data)
|
||||
self.show_info("同步成功", f"已同步 {len(parsed_data)} 条元素数据。\n源文件: {target_xml_name}")
|
||||
else:
|
||||
self.show_info("同步异常", "数据插入成功但无法读取回显。")
|
||||
|
||||
logger.info(f"[{self.page_type}] 同步操作完成")
|
||||
def update_ui_with_data(self, data):
|
||||
### 更新UI界面,如果不符合,对不符合的元素字体标红,并且
|
||||
pass
|
||||
@ -236,6 +244,7 @@ class BaseInspectionPage(QDialog):
|
||||
|
||||
def on_submit(self):
|
||||
"""提交检验数据到 e_pz_hjqy_import 表"""
|
||||
logger.info(f"[{self.page_type}] 开始提交检验数据")
|
||||
try:
|
||||
# 1. 收集表单数据
|
||||
gch = self.inputs.get("batch_no").text().strip() if self.inputs.get("batch_no") else ""
|
||||
@ -296,15 +305,19 @@ class BaseInspectionPage(QDialog):
|
||||
|
||||
# 6. 插入数据库
|
||||
db = DatabaseManager()
|
||||
success, message = db.insert_inspection_data(inspection_data)
|
||||
with log_timing_context(f"DB提交检验数据 gch={gch}", "base_page"):
|
||||
success, message = db.insert_inspection_data(inspection_data)
|
||||
|
||||
if success:
|
||||
logger.info(f"[{self.page_type}] 提交成功: {message}")
|
||||
self.show_info("提交成功", message)
|
||||
self.clear_data()
|
||||
else:
|
||||
logger.warning(f"[{self.page_type}] 提交失败: {message}")
|
||||
self.show_info("提交失败", message)
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"[{self.page_type}] 提交异常: {e}", exc_info=True)
|
||||
self.show_info("提交异常", f"发生错误: {str(e)}")
|
||||
|
||||
def show_info(self, title, message):
|
||||
|
||||
@ -6,6 +6,8 @@ from openpyxl.styles.builtins import headline_1
|
||||
|
||||
from ui.base_page import BaseInspectionPage
|
||||
from src.db_manager import DatabaseManager
|
||||
from utils.logger import get_logger, log_timing_context
|
||||
logger = get_logger("incoming_inspection")
|
||||
|
||||
class IncomingInspectionPage(BaseInspectionPage):
|
||||
def __init__(self, parent=None):
|
||||
@ -241,8 +243,11 @@ class IncomingInspectionPage(BaseInspectionPage):
|
||||
return
|
||||
|
||||
self.last_gch = gch
|
||||
data, err = self.db_manager.query_by_gch(gch)
|
||||
logger.info(f"查询工程号: {gch}")
|
||||
with log_timing_context(f"query_by_gch({gch})", "incoming_inspection"):
|
||||
data, err = self.db_manager.query_by_gch(gch)
|
||||
if err:
|
||||
logger.warning(f"查询失败: {err}")
|
||||
self.show_info("查询失败", err)
|
||||
return
|
||||
|
||||
@ -252,7 +257,6 @@ class IncomingInspectionPage(BaseInspectionPage):
|
||||
self.inputs["spec1"].setText(data.get("qy_czt") or "")
|
||||
self.inputs["info1"].setText(data.get("heat_number2") or "")
|
||||
self.inputs["spec2"].setText(data.get("qy_czw") or "")
|
||||
|
||||
def update_ui_with_data(self, data):
|
||||
"""
|
||||
根据数据库数据更新UI。
|
||||
@ -294,7 +298,8 @@ class IncomingInspectionPage(BaseInspectionPage):
|
||||
if not hn1 and not hn2:
|
||||
return
|
||||
|
||||
heat1_range, heat2_range, err = self.db_manager.query_standard_range(hn1, hn2)
|
||||
with log_timing_context("query_standard_range", "incoming_inspection"):
|
||||
heat1_range, heat2_range, err = self.db_manager.query_standard_range(hn1, hn2)
|
||||
if err:
|
||||
self.show_info("标准值查询失败", err)
|
||||
return
|
||||
@ -334,7 +339,7 @@ class IncomingInspectionPage(BaseInspectionPage):
|
||||
min_val = float(min_val) if min_val is not None and min_val != '' else None
|
||||
max_val = float(max_val) if max_val is not None and max_val != '' else None
|
||||
except (ValueError, TypeError) as e:
|
||||
print(e)
|
||||
logger.debug(f"标准值解析异常: {e}")
|
||||
is_out = False
|
||||
if min_val is not None and value < min_val:
|
||||
is_out = True
|
||||
|
||||
@ -8,6 +8,8 @@ from ui.incoming_inspection_page import IncomingInspectionPage
|
||||
from ui.manual_inspection_page import ManualInspectionPage
|
||||
from src.db_manager import DatabaseManager
|
||||
from src.session_manager import SessionManager
|
||||
from utils.logger import get_logger, log_timing_context
|
||||
logger = get_logger("inspection_window")
|
||||
|
||||
class InspectionWindow(QMainWindow):
|
||||
def __init__(self):
|
||||
@ -116,6 +118,7 @@ class InspectionWindow(QMainWindow):
|
||||
|
||||
self.is_loading = True
|
||||
self.loading_label.show()
|
||||
logger.debug(f"触发加载更多数据, page={self.current_page}")
|
||||
|
||||
# 使用 QTimer 异步加载,避免阻塞 UI
|
||||
QTimer.singleShot(100, self._fetch_data)
|
||||
@ -124,9 +127,11 @@ class InspectionWindow(QMainWindow):
|
||||
"""从数据库获取数据"""
|
||||
offset = self.current_page * self.page_size
|
||||
user_id = self.session_manager.get_user_id() or ''
|
||||
rows, error = self.db_manager.get_inspection_list(self.page_size, offset, user_id=user_id)
|
||||
with log_timing_context(f"get_inspection_list(page={self.current_page})", "inspection_window"):
|
||||
rows, error = self.db_manager.get_inspection_list(self.page_size, offset, user_id=user_id)
|
||||
|
||||
if error:
|
||||
logger.error(f"加载失败: {error}")
|
||||
self.loading_label.setText(f"加载失败: {error}")
|
||||
self.is_loading = False
|
||||
QTimer.singleShot(2000, lambda: self.loading_label.hide())
|
||||
@ -141,6 +146,7 @@ class InspectionWindow(QMainWindow):
|
||||
self.add_card(dict(row))
|
||||
|
||||
self.current_page += 1
|
||||
logger.debug(f"加载了 {len(rows)} 条记录, 当前页={self.current_page}")
|
||||
|
||||
if len(rows) < self.page_size:
|
||||
self.has_more_data = False
|
||||
|
||||
@ -6,6 +6,8 @@ from PySide6.QtCore import Qt, Signal
|
||||
from PySide6.QtGui import QFont
|
||||
import hashlib
|
||||
from src.db_manager import DatabaseManager
|
||||
from utils.logger import get_logger, log_timing_context
|
||||
logger = get_logger("login")
|
||||
|
||||
|
||||
class LoginWindow(QMainWindow):
|
||||
@ -117,12 +119,16 @@ class LoginWindow(QMainWindow):
|
||||
QMessageBox.warning(self, "登录失败", "请输入账号和密码")
|
||||
return
|
||||
|
||||
logger.info(f"用户登录尝试: {user_id}")
|
||||
password_md5 = hashlib.md5(password.encode()).hexdigest()
|
||||
success, user_info = self.db.authenticate_user(user_id, password_md5)
|
||||
with log_timing_context(f"authenticate_user({user_id})", "login"):
|
||||
success, user_info = self.db.authenticate_user(user_id, password_md5)
|
||||
if success:
|
||||
logger.info(f"登录成功: {user_id}")
|
||||
self.login_success.emit(user_info)
|
||||
self.close()
|
||||
else:
|
||||
logger.warning(f"登录失败: {user_id} - {user_info}")
|
||||
QMessageBox.warning(self, "登录失败", user_info)
|
||||
self.password_input.clear()
|
||||
self.password_input.setFocus()
|
||||
|
||||
102
utils/logger.py
Normal file
102
utils/logger.py
Normal file
@ -0,0 +1,102 @@
|
||||
import os
|
||||
import time
|
||||
import logging
|
||||
import functools
|
||||
from logging.handlers import RotatingFileHandler
|
||||
from contextlib import contextmanager
|
||||
|
||||
_logger_initialized = False
|
||||
|
||||
LOG_DIR = os.path.join(os.path.dirname(os.path.dirname(os.path.abspath(__file__))), "logs")
|
||||
LOG_FILE = os.path.join(LOG_DIR, "app.log")
|
||||
|
||||
SLOW_THRESHOLD = 1.0
|
||||
CRITICAL_THRESHOLD = 5.0
|
||||
|
||||
LOG_FORMAT = "[%(asctime)s] [%(levelname)-8s] [%(name)s:%(funcName)s:%(lineno)d] %(message)s"
|
||||
DATE_FORMAT = "%Y-%m-%d %H:%M:%S"
|
||||
|
||||
|
||||
def setup_logging(level=logging.DEBUG):
|
||||
global _logger_initialized
|
||||
if _logger_initialized:
|
||||
return
|
||||
_logger_initialized = True
|
||||
|
||||
os.makedirs(LOG_DIR, exist_ok=True)
|
||||
|
||||
root_logger = logging.getLogger("app")
|
||||
root_logger.setLevel(level)
|
||||
|
||||
if root_logger.handlers:
|
||||
return
|
||||
|
||||
formatter = logging.Formatter(LOG_FORMAT, datefmt=DATE_FORMAT)
|
||||
|
||||
file_handler = RotatingFileHandler(
|
||||
LOG_FILE, maxBytes=5 * 1024 * 1024, backupCount=3, encoding="utf-8"
|
||||
)
|
||||
file_handler.setLevel(logging.DEBUG)
|
||||
file_handler.setFormatter(formatter)
|
||||
|
||||
console_handler = logging.StreamHandler()
|
||||
console_handler.setLevel(logging.INFO)
|
||||
console_handler.setFormatter(formatter)
|
||||
|
||||
root_logger.addHandler(file_handler)
|
||||
root_logger.addHandler(console_handler)
|
||||
|
||||
|
||||
def get_logger(name):
|
||||
return logging.getLogger(f"app.{name}")
|
||||
|
||||
|
||||
def log_timing(func=None, *, logger_name=None):
|
||||
def decorator(fn):
|
||||
_logger = get_logger(logger_name or fn.__module__)
|
||||
|
||||
@functools.wraps(fn)
|
||||
def wrapper(*args, **kwargs):
|
||||
fn_name = fn.__qualname__
|
||||
_logger.debug(f"[ENTER] {fn_name}")
|
||||
start = time.perf_counter()
|
||||
try:
|
||||
result = fn(*args, **kwargs)
|
||||
return result
|
||||
except Exception as e:
|
||||
_logger.error(f"[ERROR] {fn_name}: {e}", exc_info=True)
|
||||
raise
|
||||
finally:
|
||||
elapsed = time.perf_counter() - start
|
||||
if elapsed >= CRITICAL_THRESHOLD:
|
||||
_logger.critical(f"[SLOW!] {fn_name} took {elapsed:.3f}s (>={CRITICAL_THRESHOLD}s)")
|
||||
elif elapsed >= SLOW_THRESHOLD:
|
||||
_logger.warning(f"[SLOW] {fn_name} took {elapsed:.3f}s (>={SLOW_THRESHOLD}s)")
|
||||
else:
|
||||
_logger.debug(f"[EXIT] {fn_name} took {elapsed:.3f}s")
|
||||
|
||||
return wrapper
|
||||
|
||||
if func is not None:
|
||||
return decorator(func)
|
||||
return decorator
|
||||
|
||||
|
||||
@contextmanager
|
||||
def log_timing_context(operation, logger_name=None):
|
||||
_logger = get_logger(logger_name or "timing")
|
||||
_logger.debug(f"[START] {operation}")
|
||||
start = time.perf_counter()
|
||||
try:
|
||||
yield
|
||||
except Exception as e:
|
||||
_logger.error(f"[ERROR] {operation}: {e}", exc_info=True)
|
||||
raise
|
||||
finally:
|
||||
elapsed = time.perf_counter() - start
|
||||
if elapsed >= CRITICAL_THRESHOLD:
|
||||
_logger.critical(f"[SLOW!] {operation} took {elapsed:.3f}s (>={CRITICAL_THRESHOLD}s)")
|
||||
elif elapsed >= SLOW_THRESHOLD:
|
||||
_logger.warning(f"[SLOW] {operation} took {elapsed:.3f}s (>={SLOW_THRESHOLD}s)")
|
||||
else:
|
||||
_logger.debug(f"[DONE] {operation} took {elapsed:.3f}s")
|
||||
@ -1,5 +1,7 @@
|
||||
import os
|
||||
import time
|
||||
from utils.logger import get_logger, log_timing
|
||||
logger = get_logger("mtp")
|
||||
|
||||
try:
|
||||
import win32com.client
|
||||
@ -14,11 +16,12 @@ class MTPHandler:
|
||||
if not os.path.exists(self.cache_dir):
|
||||
os.makedirs(self.cache_dir)
|
||||
|
||||
@log_timing
|
||||
def get_latest_xml_windows(self, device_name, path_str):
|
||||
"""
|
||||
在 Windows MTP 设备上寻找并复制最新的 XML 文件。
|
||||
"""
|
||||
print(f"\n[MTP] >>> 开始同步工作: 设备={device_name}")
|
||||
logger.info(f"开始同步工作: 设备={device_name}")
|
||||
if win32com is None:
|
||||
return None, "系统未安装 pywin32。"
|
||||
|
||||
@ -31,7 +34,7 @@ class MTPHandler:
|
||||
device_item = None
|
||||
target_name = device_name.strip().lower()
|
||||
|
||||
print(f"[MTP] 正在检索设备,目标名称: '{target_name}'")
|
||||
logger.debug(f"正在检索设备,目标名称: '{target_name}'")
|
||||
items = computer.Items()
|
||||
available_devices = []
|
||||
|
||||
@ -39,12 +42,12 @@ class MTPHandler:
|
||||
available_devices.append(item.Name)
|
||||
if item.Name.strip().lower() == target_name:
|
||||
device_item = item
|
||||
print(f"[MTP] 匹配成功: '{item.Name}'")
|
||||
logger.info(f"匹配成功: '{item.Name}'")
|
||||
break
|
||||
|
||||
if not device_item:
|
||||
print(f"[MTP] 未找到设备: '{device_name}'")
|
||||
print(f"[MTP] 当前电脑识别到的设备列表: {available_devices}")
|
||||
logger.warning(f"未找到设备: '{device_name}'")
|
||||
logger.warning(f"当前电脑识别到的设备列表: {available_devices}")
|
||||
return None, f"未找到 MTP 设备: {device_name} (请检查名称)"
|
||||
|
||||
current_folder = device_item.GetFolder
|
||||
@ -59,20 +62,20 @@ class MTPHandler:
|
||||
found = True
|
||||
break
|
||||
if not found:
|
||||
print(f"[MTP] 路径中断,找不到文件夹: '{folder_name}'")
|
||||
logger.warning(f"路径中断,找不到文件夹: '{folder_name}'")
|
||||
# 打印一下当前目录下有的东西,帮用户排查
|
||||
content = [i.Name for i in current_folder.Items()]
|
||||
print(f"[MTP] 当前所在位置 [ {current_folder.Title} ] 下的可选内容: {content}")
|
||||
logger.debug(f"当前所在位置 [ {current_folder.Title} ] 下的可选内容: {content}")
|
||||
return None, f"路径点不存在: {folder_name}"
|
||||
|
||||
# 3. 扫描文件并识别“最新”
|
||||
print(f"[MTP] 已到达目标目录: [ {current_folder.Title} ]")
|
||||
print(f"[MTP] 正在列出该目录下所有项目...")
|
||||
print("-" * 40)
|
||||
logger.info(f"已到达目标目录: [ {current_folder.Title} ]")
|
||||
logger.debug(f"正在列出该目录下所有项目...")
|
||||
logger.debug("-" * 40)
|
||||
|
||||
xml_items = []
|
||||
all_items = current_folder.Items()
|
||||
print(f"[MTP] 目录内总项数: {all_items.Count}")
|
||||
logger.debug(f"目录内总项数: {all_items.Count}")
|
||||
|
||||
for i in range(all_items.Count):
|
||||
try:
|
||||
@ -83,7 +86,7 @@ class MTPHandler:
|
||||
# 打印每一个文件的详细信息用于排查
|
||||
# 尝试打印前 6 个详情列,看看哪一列是类型,哪一列是时间
|
||||
details = [str(current_folder.GetDetailsOf(item, j)) for j in range(6)]
|
||||
if i == 0: print(f"[MTP] 属性列参考(0-5): {details}")
|
||||
if i == 0: logger.debug(f"属性列参考(0-5): {details}")
|
||||
|
||||
item_type = details[2]
|
||||
# 识别逻辑:
|
||||
@ -106,16 +109,16 @@ class MTPHandler:
|
||||
'time': mtime,
|
||||
'name_ts': name_ts
|
||||
})
|
||||
print(f"[MTP] 识别 XML: '{name}' | 创建/修改时间: {mtime} | 文件名时间: {name_ts}")
|
||||
logger.debug(f"识别 XML: '{name}' | 创建/修改时间: {mtime} | 文件名时间: {name_ts}")
|
||||
else:
|
||||
pass
|
||||
except Exception as e:
|
||||
print(f"[MTP] 读取第 {i} 个项目时出错: {e}")
|
||||
logger.error(f"读取第 {i} 个项目时出错: {e}")
|
||||
|
||||
print("-" * 40)
|
||||
logger.debug("-" * 40)
|
||||
|
||||
if not xml_items:
|
||||
print(f"[MTP] 报错: 在目录 [ {current_folder.Title} ] 中没有找到任何以 .xml 结尾的文件")
|
||||
logger.warning(f"在目录 [ {current_folder.Title} ] 中没有找到任何以 .xml 结尾的文件")
|
||||
return None, "该目录中没有 XML 文件"
|
||||
|
||||
# 排序逻辑优化:
|
||||
@ -128,9 +131,9 @@ class MTPHandler:
|
||||
latest_item = latest['item']
|
||||
filename = latest['name']
|
||||
|
||||
print(f"[MTP] 选定最新文件: {filename}")
|
||||
print(f"[MTP] - 属性时间: {latest['time']}")
|
||||
print(f"[MTP] - 名称日期: {latest['name_ts']}")
|
||||
logger.info(f"选定最新文件: {filename}")
|
||||
logger.debug(f" - 属性时间: {latest['time']}")
|
||||
logger.debug(f" - 名称日期: {latest['name_ts']}")
|
||||
|
||||
# 4. 复制到本地
|
||||
local_path = os.path.abspath(os.path.join(self.cache_dir, filename))
|
||||
@ -140,7 +143,7 @@ class MTPHandler:
|
||||
try: os.remove(os.path.join(self.cache_dir, f))
|
||||
except: pass
|
||||
|
||||
print(f"[MTP] 正在拉取文件到本地缓存...")
|
||||
logger.info(f"正在拉取文件到本地缓存...")
|
||||
dest_shell_folder = shell.NameSpace(os.path.abspath(self.cache_dir))
|
||||
dest_shell_folder.CopyHere(latest_item, 4 | 16)
|
||||
|
||||
@ -153,13 +156,13 @@ class MTPHandler:
|
||||
time.sleep(0.5)
|
||||
|
||||
if success:
|
||||
print(f"[MTP] ✨ 同步成功: {filename}")
|
||||
logger.info(f"同步成功: {filename}")
|
||||
return local_path, filename
|
||||
else:
|
||||
return None, "同步超时"
|
||||
|
||||
except Exception as e:
|
||||
print(f"[MTP] 异常: {e}")
|
||||
logger.error(f"MTP异常: {e}", exc_info=True)
|
||||
return None, str(e)
|
||||
finally:
|
||||
pythoncom.CoUninitialize()
|
||||
|
||||
Loading…
Reference in New Issue
Block a user