ftp文件 ftp_config.json

本文介绍了一个具体的FTP连接配置案例,包括主机地址、端口、用户名、密码等关键参数,并指定了本地目录及远程目录的位置。此外,还包含了版本信息及特定的应用场景说明。
{
"Host": "192.168.31.89",
    "Port": 21,   
    "User": "user", 
    "Passwd":    "pass",   
    "LocalDir":    "F:/123/", 
    "LocalFile": "",   
    "FtpDir":    "/123/",   
    "Vresion":"2018061301",  
    "Pf":    "qq",   
"Debug": false
}
import json import os import threading import PySimpleGUI as sg import telnetlib import time import queue import logging from datetime import datetime # ============== 全局配置 ============== DATA_FILE = 'pyremote_config.json' PROJECTS_FILE = 'projects_config.json' END_STR = "ROUTER_MPU /home\x1b[m # " LOG_FORMAT = '%(asctime)s - %(levelname)s - %(message)s' ENCODING = 'utf-8' BUFFER_SIZE = 4096 CHUNK_SIZE = 10 # 每10个字符发送一次 CHUNK_DELAY = 0.15 # 每个分块之间的延迟(秒) COMMAND_DELAY = 0.5 # 命令之间的延迟(秒) # ============== 日志配置 ============== def setup_logger(): """配置日志系统""" logger = logging.getLogger('RemoteControl') logger.setLevel(logging.DEBUG) # 文件处理器 file_handler = logging.FileHandler('remote_control.log') file_handler.setFormatter(logging.Formatter(LOG_FORMAT)) # 控制台处理器 console_handler = logging.StreamHandler() console_handler.setFormatter(logging.Formatter(LOG_FORMAT)) logger.addHandler(file_handler) logger.addHandler(console_handler) return logger logger = setup_logger() # ============== 项目管理类 ============== class ProjectManager: def __init__(self): self.projects = self.load_projects() def load_projects(self): """加载项目配置""" if os.path.exists(PROJECTS_FILE): try: with open(PROJECTS_FILE, 'r') as f: return json.load(f) except Exception as e: logger.error(f"加载项目配置失败: {e}") return {"projects": []} return {"projects": []} def save_projects(self): """保存项目配置""" try: with open(PROJECTS_FILE, 'w') as f: json.dump(self.projects, f, indent=4) return True except Exception as e: logger.error(f"保存项目配置失败: {e}") return False def add_project(self, name, commands): """添加新项目""" project = { "name": name, "commands": commands, "created_at": datetime.now().strftime("%Y-%m-%d %H:%M:%S") } self.projects["projects"].append(project) if self.save_projects(): return project return None def update_project(self, index, name, commands): """更新项目""" if 0 <= index < len(self.projects["projects"]): self.projects["projects"][index]["name"] = name self.projects["projects"][index]["commands"] = commands if self.save_projects(): return True return False def delete_project(self, index): """删除项目""" if 0 <= index < len(self.projects["projects"]): del self.projects["projects"][index] return self.save_projects() return False def import_projects(self, file_path): """导入项目配置""" try: with open(file_path, 'r') as f: imported = json.load(f) # 验证导入格式 if "projects" in imported and isinstance(imported["projects"], list): self.projects = imported return self.save_projects() except Exception as e: logger.error(f"导入项目失败: {e}") return False def export_projects(self, file_path): """导出项目配置""" try: with open(file_path, 'w') as f: json.dump(self.projects, f, indent=4) return True except Exception as e: logger.error(f"导出项目失败: {e}") return False def get_project_commands(self, index): """获取项目的命令列表""" if 0 <= index < len(self.projects["projects"]): return self.projects["projects"][index]["commands"] return [] # ============== 指令执行类(增强版) ============== class CommandExecutor: def __init__(self): self.tn = None self.is_connected = False self.response = "" self.prev_cmd = "" self.log_queue = queue.Queue() self.lock = threading.Lock() self.stop_event = threading.Event() self.pause_event = threading.Event() # 暂停事件 self.last_response = "" self.expected_prompt = END_STR self.current_command_index = -1 # 当前执行命令索引 self.current_command = "" # 当前执行的命令 self.total_commands = 0 # 总命令数 def connect(self, host, port): """连接设备""" try: with self.lock: self.tn = telnetlib.Telnet(host, port, timeout=10) self.is_connected = True self.log_queue.put(f"已连接到 {host}:{port}") # 初始读取以清除欢迎信息 self.read_until_prompt(timeout=3) return True except Exception as e: self.log_queue.put(f"连接失败: {str(e)}") return False def disconnect(self): """断开连接""" with self.lock: if self.tn: try: self.tn.close() except: pass self.is_connected = False self.log_queue.put("连接已断开") def send(self, content): """发送命令(分块发送)""" if not self.is_connected: self.log_queue.put("错误:未连接到设备") return False try: with self.lock: # 保存当前命令 self.current_command = content # 使用正确的编码发送 encoded_content = content.encode(ENCODING) # 分块发送(每10个字符) chunks = [encoded_content[i:i+CHUNK_SIZE] for i in range(0, len(encoded_content), CHUNK_SIZE)] for chunk in chunks: # 检查停止信号 if self.stop_event.is_set(): self.log_queue.put("发送已中止") return False # 检查暂停信号 while self.pause_event.is_set(): time.sleep(0.1) if self.stop_event.is_set(): return False # 发送分块 self.tn.write(chunk) self.log_queue.put(f"发送分块: {chunk.decode(ENCODING, errors='replace')}") # 添加分块之间的延迟 time.sleep(CHUNK_DELAY) # 发送回车符(模拟敲回车) self.tn.write(b"\r\n") self.log_queue.put("发送回车符") self.log_queue.put(f"完整发送: {content.strip()}") self.prev_cmd = content return True except Exception as e: self.log_queue.put(f"发送命令失败: {str(e)}") return False def read_until_prompt(self, timeout=5): """读取直到遇到提示符""" if not self.is_connected: return "" try: # 使用正确的编码读取 response = self.tn.read_until(self.expected_prompt.encode(ENCODING), timeout=timeout) decoded_response = response.decode(ENCODING, errors='replace') # 移除命令回显 if self.prev_cmd and decoded_response.startswith(self.prev_cmd.strip()): decoded_response = decoded_response[len(self.prev_cmd.strip()):].lstrip() # 移除尾部的提示符 if decoded_response.endswith(self.expected_prompt): decoded_response = decoded_response[:-len(self.expected_prompt)].rstrip() self.last_response = decoded_response self.log_queue.put(decoded_response) return decoded_response except Exception as e: self.log_queue.put(f"接收响应失败: {str(e)}") return "" def execute_commands(self, commands): """执行命令序列(增强版)""" if not self.is_connected: self.log_queue.put("错误:未连接到设备") return False self.stop_event.clear() self.pause_event.clear() self.total_commands = len(commands) self.log_queue.put(f"开始执行 {self.total_commands} 条命令") try: for idx, cmd in enumerate(commands): if self.stop_event.is_set(): self.log_queue.put("命令执行已中止") return False # 设置当前命令索引 self.current_command_index = idx # 检查暂停状态 while self.pause_event.is_set(): time.sleep(0.1) if self.stop_event.is_set(): return False if cmd.strip(): # 跳过空行 # 发送命令 if not self.send(cmd): return False # 等待命令完成 self.read_until_prompt(timeout=10) # 命令间延迟 delay_remaining = COMMAND_DELAY while delay_remaining > 0: if self.stop_event.is_set(): return False if self.pause_event.is_set(): time.sleep(0.1) continue time.sleep(0.1) delay_remaining -= 0.1 self.log_queue.put("命令执行完成") self.current_command_index = -1 return True except Exception as e: self.log_queue.put(f"命令执行失败: {str(e)}") return False def stop_execution(self): """停止当前执行""" self.stop_event.set() self.log_queue.put("正在停止执行...") def pause_execution(self): """暂停当前执行""" if not self.pause_event.is_set(): self.pause_event.set() self.log_queue.put("执行已暂停") return True return False def resume_execution(self): """继续执行""" if self.pause_event.is_set(): self.pause_event.clear() self.log_queue.put("执行已继续") return True return False def get_execution_status(self): """获取执行状态""" return { "is_running": not self.stop_event.is_set() and not self.pause_event.is_set(), "is_paused": self.pause_event.is_set(), "is_stopped": self.stop_event.is_set(), "current_command": self.current_command.strip(), "current_index": self.current_command_index, "total_commands": self.total_commands } # ============== GUI 界面类(增强版) ============== class RemoteControlApp: def __init__(self): self.project_manager = ProjectManager() self.executor = CommandExecutor() self.default_data = self.load_default_data() self.window = None self.setup_gui() self.log_thread = None self.status_update_thread = None self.running = True def load_default_data(self): """加载默认配置""" default_data = { "IP": "71.19.0.120", "port": "1001", "FTP_IP": "71.19.0.120", "芯片名称": "Hi1260SV100", '发送信息': "", "board_local_ip": "71.19.0.53", 'interval': "1", "start_addr": "", "end_addr": "", "文件FTP路径": "", } if os.path.exists(DATA_FILE): try: with open(DATA_FILE, 'r') as f: data = json.load(f) default_data.update({k: data[k] for k in default_data if k in data}) except Exception as e: logger.error(f"加载默认配置失败: {e}") with open(DATA_FILE, 'w') as f: json.dump(default_data, f) else: with open(DATA_FILE, 'w') as f: json.dump(default_data, f) return default_data def save_config(self): """保存配置""" try: values = self.window.read()[1] if self.window else {} with open(DATA_FILE, 'w') as f: json.dump({ "IP": values.get("IP", self.default_data["IP"]), "port": values.get("port", self.default_data["port"]), "FTP_IP": values.get("FTP_IP", self.default_data["FTP_IP"]), "芯片名称": values.get("芯片名称", self.default_data["芯片名称"]), '发送信息': values.get("发送信息", self.default_data["发送信息"]), "board_local_ip": values.get("board_local_ip", self.default_data["board_local_ip"]), 'interval': values.get("interval", self.default_data["interval"]), "start_addr": values.get("start_addr", self.default_data["start_addr"]), "end_addr": values.get("end_addr", self.default_data["end_addr"]), "文件FTP路径": values.get("文件FTP路径", self.default_data["文件FTP路径"]), }, f) return True except Exception as e: logger.error(f"保存配置失败: {e}") return False def create_project_buttons(self): """创建项目按钮区域""" layout = [] projects = self.project_manager.projects["projects"] if not projects: layout.append([sg.Text("没有项目,请添加新项目", text_color='red')]) for i, project in enumerate(projects): row = [ sg.Button(project["name"], key=f'-PROJECT-{i}-', size=(15,1), tooltip=f"创建于: {project['created_at']}\n命令数: {len(project['commands'])}"), sg.Button("一键升级", key=f'-UPGRADE-{i}-', button_color=('white', 'green')), sg.Button("编辑", key=f'-EDIT-{i}-', button_color=('white', 'blue')), sg.Button("删除", key=f'-DELETE-{i}-', button_color=('white', 'red')) ] layout.append(row) # 添加项目管理按钮 layout.append([ sg.Button("添加新项目", key='-ADD-PROJECT-', button_color=('white', 'purple')), sg.Button("导入项目", key='-IMPORT-PROJECTS-'), sg.Button("导出项目", key='-EXPORT-PROJECTS-'), sg.Button("生成模板", key='-CREATE-TEMPLATE-') ]) return layout def edit_project_window(self, index=None): """项目编辑窗口""" project = None if index is not None and 0 <= index < len(self.project_manager.projects["projects"]): project = self.project_manager.projects["projects"][index] layout = [ [sg.Text("项目名称:"), sg.Input(key='-PROJECT-NAME-', default_text=project["name"] if project else "")], [sg.Text("升级指令:")], [sg.Multiline(key='-PROJECT-COMMANDS-', size=(60, 10), default_text='\n'.join(project["commands"]) if project else "", tooltip="每行一个命令,命令将按顺序执行")], [sg.Button("保存", key='-SAVE-PROJECT-'), sg.Button("取消", key='-CANCEL-PROJECT-')] ] window = sg.Window("项目编辑", layout, modal=True) while True: event, values = window.read() if event in (sg.WINDOW_CLOSED, '-CANCEL-PROJECT-'): break elif event == '-SAVE-PROJECT-': name = values['-PROJECT-NAME-'].strip() commands = [cmd.strip() for cmd in values['-PROJECT-COMMANDS-'].split('\n') if cmd.strip()] if not name: sg.popup("项目名称不能为空") continue if index is None: new_project = self.project_manager.add_project(name, commands) if new_project: sg.popup(f"项目 '{name}' 添加成功") break else: if self.project_manager.update_project(index, name, commands): sg.popup(f"项目 '{name}' 更新成功") break sg.popup("操作失败,请查看日志") window.close() return True def setup_gui(self): """设置GUI界面(增强版)""" # 创建主布局 sg.theme('LightBlue1') # 输出区域 output = sg.Multiline( size=(80, 20), key='-OUTPUT-', autoscroll=True, background_color='#f0f0f0', text_color='black' ) # 状态信息区域 status_info = [ sg.Text("当前命令: ", size=(10,1)), sg.Text("无", key='-CURRENT-COMMAND-', size=(40,1), text_color='blue'), sg.Text("进度: ", size=(5,1)), sg.Text("0/0", key='-COMMAND-PROGRESS-', size=(10,1)) ] # 项目列表区域 projects_frame = sg.Frame("项目列表", [ [sg.Column( self.create_project_buttons(), scrollable=True, vertical_scroll_only=True, size=(700, 300), key='-PROJECTS-COLUMN-' )] ], key='-PROJECTS-FRAME-') # 执行控制区域 control_buttons = [ sg.Button('暂停执行', key='-PAUSE-EXECUTION-', button_color=('white', 'orange'), size=(10,1)), sg.Button('继续执行', key='-RESUME-EXECUTION-', button_color=('white', 'green'), size=(10,1)), sg.Button('停止执行', key='-STOP-EXECUTION-', button_color=('white', 'red'), size=(10,1)) ] # 连接状态区域 status_bar = [ sg.Text('●', key='-STATUS-LIGHT-', text_color='red', font=('Arial', 12)), sg.Text("未连接", key='-CONNECTION-STATUS-'), sg.StatusBar("就绪", key='-STATUS-', size=(50, 1)) ] # 主布局 layout = [ [sg.Text('IP:', size=(6,1)), sg.Input(key="IP", default_text=self.default_data["IP"], size=(15,1)), sg.Text('Port:', size=(5,1)), sg.Input(key="port", default_text=self.default_data["port"], size=(8,1)), sg.Button('连接', button_color=('white', 'green')), sg.Button('断开连接', button_color=('white', 'red'))], [projects_frame], status_info, # 执行控制按钮 [sg.Frame("执行控制", [control_buttons], key='-CONTROL-FRAME-')], [sg.Text("发送信息:", size=(8,1)), sg.Input(key='发送信息', size=(50, 1), default_text=self.default_data["发送信息"])], [sg.Button('ROUTER_MPU下发送'), sg.Button('Shell下发送'), sg.Text('每隔', size=(3,1)), sg.Input(key='interval', default_text=self.default_data["interval"], size=(5,1)), sg.Text("秒", size=(2,1)), sg.Button('定时发送'), sg.Button("停止定时发送")], [sg.Button('接收1s')], [sg.Text('芯片名称:', size=(8,1)), sg.Input(key="芯片名称", default_text=self.default_data["芯片名称"], size=(15,1)), sg.Text('文件FTP路径:', size=(10,1)), sg.Input(key="文件FTP路径", default_text=self.default_data["文件FTP路径"], size=(30,1))], [sg.Text('FTP_IP:', size=(6,1)), sg.Input(key="FTP_IP", default_text=self.default_data["FTP_IP"], size=(15,1)), sg.Text('单板IP:', size=(6,1)), sg.Input(key="board_local_ip", default_text=self.default_data["board_local_ip"], size=(15,1))], [sg.Text("SLT测试用"), sg.Button('重新获取sdk.out'), sg.Button("一键升级MT1"), sg.Button("一键升级MT2")], [sg.Button("使用说明", button_color=('white', 'blue'))], [sg.Text('起始地址:', size=(8,1)), sg.Input(key='start_addr', default_text=self.default_data["start_addr"], size=(12,1)), sg.Text('结束地址:', size=(8,1)), sg.Input(key='end_addr', default_text=self.default_data["end_addr"], size=(12,1)), sg.Button('dump寄存器')], [output], status_bar ] self.window = sg.Window('远程单板连接工具', layout, finalize=True, resizable=True) self.update_status_light() self.start_log_thread() self.start_status_update_thread() def update_status_light(self): """更新状态指示灯""" color = 'green' if self.executor.is_connected else 'red' status = "已连接" if self.executor.is_connected else "未连接" self.window['-STATUS-LIGHT-'].update(text_color=color) self.window['-CONNECTION-STATUS-'].update(status) def update_output(self): """更新输出区域""" while not self.executor.log_queue.empty(): try: message = self.executor.log_queue.get_nowait() current_text = self.window['-OUTPUT-'].get() self.window['-OUTPUT-'].update(current_text + message + '\n') except queue.Empty: break def start_log_thread(self): """启动日志更新线程""" self.log_thread = threading.Thread(target=self.log_update_loop, daemon=True) self.log_thread.start() def log_update_loop(self): """日志更新循环""" while self.running: self.update_output() time.sleep(0.1) def start_status_update_thread(self): """启动状态更新线程""" self.status_update_thread = threading.Thread(target=self.status_update_loop, daemon=True) self.status_update_thread.start() def status_update_loop(self): """状态更新循环""" while self.running: # 更新执行状态 status = self.executor.get_execution_status() # 更新当前命令显示 if status["current_command"]: self.window['-CURRENT-COMMAND-'].update(status["current_command"]) # 更新进度显示 if status["current_index"] >= 0 and status["total_commands"] > 0: progress_text = f"{status['current_index'] + 1}/{status['total_commands']}" self.window['-COMMAND-PROGRESS-'].update(progress_text) # 更新按钮状态 if status["is_running"]: self.window['-PAUSE-EXECUTION-'].update(disabled=False) self.window['-RESUME-EXECUTION-'].update(disabled=True) self.window['-STOP-EXECUTION-'].update(disabled=False) elif status["is_paused"]: self.window['-PAUSE-EXECUTION-'].update(disabled=True) self.window['-RESUME-EXECUTION-'].update(disabled=False) self.window['-STOP-EXECUTION-'].update(disabled=False) else: self.window['-PAUSE-EXECUTION-'].update(disabled=True) self.window['-RESUME-EXECUTION-'].update(disabled=True) self.window['-STOP-EXECUTION-'].update(disabled=True) time.sleep(0.2) def refresh_project_list(self): """刷新项目列表""" self.window['-PROJECTS-COLUMN-'].update(visible=False) self.window['-PROJECTS-COLUMN-'].update(self.create_project_buttons()) self.window['-PROJECTS-COLUMN-'].update(visible=True) def run(self): """运行主循环(增强版)""" stop_loop = 0 interval = 10000 loop_msg = "" while True: event, values = self.window.read(timeout=100) if event == sg.WINDOW_CLOSED: break # 更新输出区域 self.update_output() # 连接管理 if event == '连接': if values["IP"] and values["port"]: if self.executor.connect(values["IP"], int(values["port"])): self.window['-STATUS-'].update("已连接") self.update_status_light() else: sg.popup("请输入IP和端口") elif event == '断开连接': self.executor.disconnect() self.window['-STATUS-'].update("已断开") self.update_status_light() # 项目管理 elif event == '-ADD-PROJECT-': self.edit_project_window() self.refresh_project_list() elif event.startswith('-EDIT-'): index = int(event.split('-')[2]) self.edit_project_window(index) self.refresh_project_list() elif event.startswith('-DELETE-'): index = int(event.split('-')[2]) if self.project_manager.delete_project(index): sg.popup("项目删除成功") self.refresh_project_list() else: sg.popup("项目删除失败") elif event == '-IMPORT-PROJECTS-': file_path = sg.popup_get_file("选择项目配置文件", file_types=(("JSON Files", "*.json"),)) if file_path and self.project_manager.import_projects(file_path): sg.popup("项目导入成功") self.refresh_project_list() else: sg.popup("项目导入失败") elif event == '-EXPORT-PROJECTS-': file_path = sg.popup_get_file("保存项目配置文件", save_as=True, file_types=(("JSON Files", "*.json"),)) if file_path and self.project_manager.export_projects(file_path): sg.popup("项目导出成功") else: sg.popup("项目导出失败") elif event == '-CREATE-TEMPLATE-': self.create_template_file() sg.popup("模板文件已生成: projects_template.json") # 一键升级 elif event.startswith('-UPGRADE-'): index = int(event.split('-')[2]) if index < len(self.project_manager.projects["projects"]): project = self.project_manager.projects["projects"][index] self.window['-STATUS-'].update(f"执行 {project['name']} 升级...") # 在新线程中执行升级 threading.Thread( target=self.execute_project_upgrade, args=(index,), daemon=True ).start() # 执行控制 elif event == '-PAUSE-EXECUTION-': if self.executor.pause_execution(): self.window['-STATUS-'].update("执行已暂停") elif event == '-RESUME-EXECUTION-': if self.executor.resume_execution(): self.window['-STATUS-'].update("执行已继续") elif event == '-STOP-EXECUTION-': self.executor.stop_execution() self.window['-STATUS-'].update("执行已停止") # 其他原有功能... elif event == 'ROUTER_MPU下发送': if self.save_config() and values["发送信息"]: self.executor.send(values["发送信息"]) # 等待响应 self.executor.read_until_prompt() elif event == 'Shell下发送': if self.save_config() and values["发送信息"]: self.executor.send(values["发送信息"]) # 等待响应 self.executor.read_until_prompt() elif event == '定时发送': if self.save_config() and values["发送信息"] and values["interval"]: try: interval = float(values["interval"]) if interval <= 0: raise ValueError("间隔必须大于0") loop_msg = values["发送信息"] threading.Thread( target=self.periodic_send, args=(loop_msg, interval), daemon=True ).start() except Exception as e: sg.popup(f"无效的间隔: {str(e)}") else: sg.popup("请输入发送信息和有效间隔") elif event == "停止定时发送": self.executor.stop_execution() # 其他事件处理 elif event == '接收1s': self.executor.read_until_prompt(timeout=1) elif event == 'dump寄存器': if values["start_addr"] and values["end_addr"]: self.executor.send(f"dump {values['start_addr']} {values['end_addr']}") self.executor.read_until_prompt() elif event == '重新获取sdk.out': self.executor.send("get_sdk.out") self.executor.read_until_prompt() elif event == '一键升级MT1': self.executor.send("upgrade_mt1") self.executor.read_until_prompt() elif event == '一键升级MT2': self.executor.send("upgrade_mt2") self.executor.read_until_prompt() elif event == '使用说明': self.show_help() self.running = False self.executor.disconnect() if self.log_thread: self.log_thread.join(timeout=1.0) if self.status_update_thread: self.status_update_thread.join(timeout=1.0) self.window.close() def execute_project_upgrade(self, index): """执行项目升级(增强版)""" commands = self.project_manager.get_project_commands(index) if commands: # 重置进度显示 self.window['-CURRENT-COMMAND-'].update("") self.window['-COMMAND-PROGRESS-'].update("0/0") success = self.executor.execute_commands(commands) self.window['-STATUS-'].update("升级完成" if success else "升级失败") else: self.executor.log_queue.put("错误:项目没有配置命令") def periodic_send(self, message, interval): """周期性发送消息(优化版)""" while not self.executor.stop_event.is_set(): self.executor.send(message) # 等待响应 self.executor.read_until_prompt() # 等待指定间隔 time.sleep(interval) def show_help(self): """显示使用说明(增强版)""" help_text = """ === 远程单板连接工具使用说明 === 1. 连接管理: - 输入IP和端口后点击"连接"按钮 - 状态指示灯显示连接状态(红:未连接, 绿:已连接) 2. 项目管理: - 添加项目:点击"添加新项目"按钮 - 编辑项目:点击项目右侧的"编辑"按钮 - 删除项目:点击项目右侧的"删除"按钮 - 一键升级:点击项目右侧的"一键升级"按钮 - 导入/导出:支持JSON格式配置导入导出 3. 命令执行控制: - 暂停执行:点击"暂停执行"按钮 - 继续执行:点击"继续执行"按钮 - 停止执行:点击"停止执行"按钮 - 进度显示:显示当前执行的命令和进度 4. 发送机制: - 分块发送:每条命令按10字符分块发送 - 回车发送:每条命令发送后自动发送回车符 - 命令间延迟:每条命令之间有0.5秒延迟 - 命令同步:每条命令发送后等待响应完成 5. 特殊功能: - dump寄存器:输入起始和结束地址 - SLT测试:提供快速测试按钮 6. 优化说明: - 使用UTF-8编码避免乱码 - 命令发送后自动等待响应完成 - 自动过滤命令回显和提示符 - 实时显示执行状态和进度 """ sg.popup(help_text, title="使用说明", font=("Arial", 11)) def create_template_file(self): """创建项目配置模板""" try: template = { "projects": [ { "name": "项目A", "commands": [ "ifconfig eth0 192.168.0.100", "ftpget -u user -p pass 192.168.0.1 /home/firmware.bin firmware.bin", "flash -w 0 0x0000000 0xa000000 0x2000000" ], "created_at": datetime.now().strftime("%Y-%m-%d %H:%M:%S") }, { "name": "项目B", "commands": [ "ifconfig eth0 192.168.0.101", "ping 192.168.0.1", "reboot" ], "created_at": datetime.now().strftime("%Y-%m-%d %H:%M:%S") } ] } with open("projects_template.json", 'w') as f: json.dump(template, f, indent=4) return True except Exception as e: logger.error(f"创建模板文件失败: {e}") return False # ============== 主程序入口 ============== if __name__ == "__main__": # 启动应用 try: app = RemoteControlApp() app.run() except Exception as e: logger.exception("应用程序崩溃") sg.popup_error(f"应用程序发生致命错误: {str(e)}")
07-03
luyanxi@ubuntu:~/Desktop/nvr/nvr_2025$ git add . luyanxi@ubuntu:~/Desktop/nvr/nvr_2025$ git status On branch master Initial commit Changes to be committed: (use "git rm --cached <file>..." to unstage) new file: .gitnore new file: .repo/.repo_fetchtimes.json new file: .repo/manifest.xml new file: .repo/manifests new file: .repo/manifests.git/.repo_config.json new file: .repo/manifests.git/FETCH_HEAD new file: .repo/manifests.git/HEAD new file: .repo/manifests.git/config new file: .repo/manifests.git/description new file: .repo/manifests.git/hooks/applypatch-msg.sample new file: .repo/manifests.git/hooks/check-commit-msg.py new file: .repo/manifests.git/hooks/commit-msg new file: .repo/manifests.git/hooks/commit-msg.sample new file: .repo/manifests.git/hooks/fsmonitor-watchman.sample new file: .repo/manifests.git/hooks/post-commit new file: .repo/manifests.git/hooks/post-update.sample new file: .repo/manifests.git/hooks/pre-applypatch.sample new file: .repo/manifests.git/hooks/pre-auto-gc new file: .repo/manifests.git/hooks/pre-commit new file: .repo/manifests.git/hooks/pre-commit.sample new file: .repo/manifests.git/hooks/pre-merge-commit.sample new file: .repo/manifests.git/hooks/pre-push.sample new file: .repo/manifests.git/hooks/pre-rebase.sample new file: .repo/manifests.git/hooks/pre-receive.sample new file: .repo/manifests.git/hooks/prepare-commit-msg new file: .repo/manifests.git/hooks/prepare-commit-msg.sample new file: .repo/manifests.git/hooks/update.sample new file: .repo/manifests.git/info/exclude new file: .repo/manifests.git/logs/refs/remotes/m/master new file: .repo/manifests.git/logs/refs/remotes/origin/master new file: .repo/manifests.git/objects/pack/pack-b151f09c237eea27632610a0c81ecd28d1d93135.idx new file: .repo/manifests.git/objects/pack/pack-b151f09c237eea27632610a0c81ecd28d1d93135.pack new file: .repo/manifests.git/packed-refs new file: .repo/manifests.git/refs/heads/default new file: .repo/manifests.git/refs/remotes/m/master new file: .repo/project-objects/vigi/nvr/platform.git/HEAD new file: .repo/project-objects/vigi/nvr/platform.git/config new file: .repo/project-objects/vigi/nvr/platform.git/description new file: .repo/project-objects/vigi/nvr/platform.git/hooks/applypatch-msg.sample new file: .repo/project-objects/vigi/nvr/platform.git/hooks/check-commit-msg.py new file: .repo/project-objects/vigi/nvr/platform.git/hooks/commit-msg new file: .repo/project-objects/vigi/nvr/platform.git/hooks/commit-msg.sample new file: .repo/project-objects/vigi/nvr/platform.git/hooks/fsmonitor-watchman.sample new file: .repo/project-objects/vigi/nvr/platform.git/hooks/post-commit new file: .repo/project-objects/vigi/nvr/platform.git/hooks/post-update.sample new file: .repo/project-objects/vigi/nvr/platform.git/hooks/pre-applypatch.sample new file: .repo/project-objects/vigi/nvr/platform.git/hooks/pre-auto-gc new file: .repo/project-objects/vigi/nvr/platform.git/hooks/pre-commit new file: .repo/project-objects/vigi/nvr/platform.git/hooks/pre-commit.sample new file: .repo/project-objects/vigi/nvr/platform.git/hooks/pre-merge-commit.sample new file: .repo/project-objects/vigi/nvr/platform.git/hooks/pre-push.sample new file: .repo/project-objects/vigi/nvr/platform.git/hooks/pre-rebase.sample new file: .repo/project-objects/vigi/nvr/platform.git/hooks/pre-receive.sample new file: .repo/project-objects/vigi/nvr/platform.git/hooks/prepare-commit-msg new file: .repo/project-objects/vigi/nvr/platform.git/hooks/prepare-commit-msg.sample new file: .repo/project-objects/vigi/nvr/platform.git/hooks/update.sample new file: .repo/project-objects/vigi/nvr/platform.git/info/exclude new file: .repo/project-objects/vigi/nvr/platform.git/objects/06/456fa599723035e645bdea142da2c577cb2dc1 new file: .repo/project-objects/vigi/nvr/platform.git/objects/1b/c55859f0e3fdf8a698558bb1f197ed750e81b3 new file: .repo/project-objects/vigi/nvr/platform.git/objects/2b/59f16463f1b23a26f238b715f8477e129b720c new file: .repo/project-objects/vigi/nvr/platform.git/objects/5f/0ed92fdb9d0ed436cd77452f1ac280262990a1 new file: .repo/project-objects/vigi/nvr/platform.git/objects/73/60e9827e1e9209c411c9d78183feb754c648b3 new file: .repo/project-objects/vigi/nvr/platform.git/objects/8c/7db4f1fb2a779cb4a9afb6ebf9a8a8b1699a19 new file: .repo/project-objects/vigi/nvr/platform.git/objects/9d/7237c3feb3c56931b09d93bb40fafca425b7c5 new file: .repo/project-objects/vigi/nvr/platform.git/objects/c2/8496cf98b45893ead91482e4ef4d9b219eb240 new file: .repo/project-objects/vigi/nvr/platform.git/objects/ca/2019ef4008fc913bcfbbf6477a668abd218603 new file: .repo/project-objects/vigi/nvr/platform.git/objects/d3/8273274d84061970c96c738f6fc0ebe088bc17 new file: .repo/project-objects/vigi/nvr/platform.git/objects/e7/94a14a00690a75d98ea426e07d4e68e821b9b1 new file: .repo/project-objects/vigi/nvr/platform.git/objects/ee/71adf615a4c2b87bbfd208e53d35fd78af3e30 new file: .repo/project-objects/vigi/nvr/platform.git/objects/pack/pack-42da9e2116af04090ba29f1d5eed7bd4885b09e1.idx new file: .repo/project-objects/vigi/nvr/platform.git/objects/pack/pack-42da9e2116af04090ba29f1d5eed7bd4885b09e1.pack new file: .repo/project-objects/vigi/nvr/sstar931.git/HEAD new file: .repo/project-objects/vigi/nvr/sstar931.git/config new file: .repo/project-objects/vigi/nvr/sstar931.git/description new file: .repo/project-objects/vigi/nvr/sstar931.git/hooks/applypatch-msg.sample new file: .repo/project-objects/vigi/nvr/sstar931.git/hooks/check-commit-msg.py new file: .repo/project-objects/vigi/nvr/sstar931.git/hooks/commit-msg new file: .repo/project-objects/vigi/nvr/sstar931.git/hooks/commit-msg.sample new file: .repo/project-objects/vigi/nvr/sstar931.git/hooks/fsmonitor-watchman.sample new file: .repo/project-objects/vigi/nvr/sstar931.git/hooks/post-commit new file: .repo/project-objects/vigi/nvr/sstar931.git/hooks/post-update.sample new file: .repo/project-objects/vigi/nvr/sstar931.git/hooks/pre-applypatch.sample new file: .repo/project-objects/vigi/nvr/sstar931.git/hooks/pre-auto-gc new file: .repo/project-objects/vigi/nvr/sstar931.git/hooks/pre-commit new file: .repo/project-objects/vigi/nvr/sstar931.git/hooks/pre-commit.sample new file: .repo/project-objects/vigi/nvr/sstar931.git/hooks/pre-merge-commit.sample new file: .repo/project-objects/vigi/nvr/sstar931.git/hooks/pre-push.sample new file: .repo/project-objects/vigi/nvr/sstar931.git/hooks/pre-rebase.sample new file: .repo/project-objects/vigi/nvr/sstar931.git/hooks/pre-receive.sample new file: .repo/project-objects/vigi/nvr/sstar931.git/hooks/prepare-commit-msg new file: .repo/project-objects/vigi/nvr/sstar931.git/hooks/prepare-commit-msg.sample new file: .repo/project-objects/vigi/nvr/sstar931.git/hooks/update.sample new file: .repo/project-objects/vigi/nvr/sstar931.git/info/exclude new file: .repo/project-objects/vigi/nvr/sstar931.git/objects/pack/pack-5c02ab768abd4103fcbf6a72c07c912d909d7487.idx new file: .repo/project-objects/vigi/nvr/sstar931.git/objects/pack/pack-5c02ab768abd4103fcbf6a72c07c912d909d7487.pack new file: .repo/project-objects/vigi/nvr/tp_package.git/HEAD new file: .repo/project-objects/vigi/nvr/tp_package.git/config new file: .repo/project-objects/vigi/nvr/tp_package.git/description new file: .repo/project-objects/vigi/nvr/tp_package.git/hooks/applypatch-msg.sample new file: .repo/project-objects/vigi/nvr/tp_package.git/hooks/check-commit-msg.py new file: .repo/project-objects/vigi/nvr/tp_package.git/hooks/commit-msg new file: .repo/project-objects/vigi/nvr/tp_package.git/hooks/commit-msg.sample new file: .repo/project-objects/vigi/nvr/tp_package.git/hooks/fsmonitor-watchman.sample new file: .repo/project-objects/vigi/nvr/tp_package.git/hooks/post-commit new file: .repo/project-objects/vigi/nvr/tp_package.git/hooks/post-update.sample new file: .repo/project-objects/vigi/nvr/tp_package.git/hooks/pre-applypatch.sample new file: .repo/project-objects/vigi/nvr/tp_package.git/hooks/pre-auto-gc new file: .repo/project-objects/vigi/nvr/tp_package.git/hooks/pre-commit new file: .repo/project-objects/vigi/nvr/tp_package.git/hooks/pre-commit.sample new file: .repo/project-objects/vigi/nvr/tp_package.git/hooks/pre-merge-commit.sample new file: .repo/project-objects/vigi/nvr/tp_package.git/hooks/pre-push.sample new file: .repo/project-objects/vigi/nvr/tp_package.git/hooks/pre-rebase.sample new file: .repo/project-objects/vigi/nvr/tp_package.git/hooks/pre-receive.sample new file: .repo/project-objects/vigi/nvr/tp_package.git/hooks/prepare-commit-msg new file: .repo/project-objects/vigi/nvr/tp_package.git/hooks/prepare-commit-msg.sample new file: .repo/project-objects/vigi/nvr/tp_package.git/hooks/update.sample new file: .repo/project-objects/vigi/nvr/tp_package.git/info/exclude new file: .repo/project-objects/vigi/nvr/tp_package.git/objects/pack/pack-d7cd896a09c7c3f67ebbb3fadff60d45b8375117.idx new file: .repo/project-objects/vigi/nvr/tp_package.git/objects/pack/pack-d7cd896a09c7c3f67ebbb3fadff60d45b8375117.pack new file: .repo/project.list new file: .repo/projects/sstar931.git/.repo_config.json new file: .repo/projects/sstar931.git/FETCH_HEAD new file: .repo/projects/sstar931.git/HEAD new file: .repo/projects/sstar931.git/config new file: .repo/projects/sstar931.git/description new file: .repo/projects/sstar931.git/hooks new file: .repo/projects/sstar931.git/info new file: .repo/projects/sstar931.git/logs/refs/remotes/m/master new file: .repo/projects/sstar931.git/logs/refs/remotes/origin/master new file: .repo/projects/sstar931.git/logs/refs/remotes/origin/master_931 new file: .repo/projects/sstar931.git/logs/refs/remotes/origin/master_931_aisearch new file: .repo/projects/sstar931.git/logs/refs/remotes/origin/master_sira_931 new file: .repo/projects/sstar931.git/logs/refs/remotes/origin/nvd_v1 new file: .repo/projects/sstar931.git/logs/refs/remotes/origin/nvr4032hv1_dvt new file: .repo/projects/sstar931.git/logs/refs/remotes/origin/nvr4032hv1_singapore new file: .repo/projects/sstar931.git/logs/refs/remotes/origin/nvr_ai new file: .repo/projects/sstar931.git/logs/refs/remotes/origin/nvr_ai_v18 new file: .repo/projects/sstar931.git/logs/refs/remotes/origin/nvr_cv_20230807 new file: .repo/projects/sstar931.git/logs/refs/remotes/origin/nvr_iteration_v18_20250723 new file: .repo/projects/sstar931.git/logs/refs/remotes/origin/nvr_iterator_20230509 new file: .repo/projects/sstar931.git/logs/refs/remotes/origin/nvr_iterator_aisearch new file: .repo/projects/sstar931.git/logs/refs/remotes/origin/nvr_iterator_v15_2016v2 new file: .repo/projects/sstar931.git/logs/refs/remotes/origin/nvr_iterator_v15_2016v2_dev new file: .repo/projects/sstar931.git/logs/refs/remotes/origin/nvr_iterator_v15_2016v2_rel new file: .repo/projects/sstar931.git/logs/refs/remotes/origin/nvr_iterator_v15_4032v1_20250102 new file: .repo/projects/sstar931.git/logs/refs/remotes/origin/nvr_iterator_v15v2_2008v2_20250114 new file: .repo/projects/sstar931.git/logs/refs/remotes/origin/nvr_iterator_v18 new file: .repo/projects/sstar931.git/logs/refs/remotes/origin/nvr_iterator_v18_security new file: .repo/projects/sstar931.git/logs/refs/remotes/origin/nvr_iterator_v18_security_ddr_bcb new file: .repo/projects/sstar931.git/logs/refs/remotes/origin/nvr_iterator_v20 new file: .repo/projects/sstar931.git/logs/refs/remotes/origin/nvr_iterator_v20_omada new file: .repo/projects/sstar931.git/logs/refs/remotes/origin/nvr_wlm_20240802 new file: .repo/projects/sstar931.git/logs/refs/remotes/origin/nvr_wlm_20240919 new file: .repo/projects/sstar931.git/objects new file: .repo/projects/sstar931.git/packed-refs new file: .repo/projects/sstar931.git/refs/remotes/m/master new file: .repo/projects/sstar931.git/rr-cache new file: .repo/projects/sstar931.git/svn new file: .repo/projects/torchlight.git/.repo_config.json new file: .repo/projects/torchlight.git/FETCH_HEAD new file: .repo/projects/torchlight.git/HEAD new file: .repo/projects/torchlight.git/config new file: .repo/projects/torchlight.git/description new file: .repo/projects/torchlight.git/hooks new file: .repo/projects/torchlight.git/info new file: .repo/projects/torchlight.git/logs/refs/remotes/m/master new file: .repo/projects/torchlight.git/logs/refs/remotes/origin/1008H_iterator new file: .repo/projects/torchlight.git/logs/refs/remotes/origin/1008H_iterator_20210517 new file: .repo/projects/torchlight.git/logs/refs/remotes/origin/1008H_v2_develop_20210603 new file: .repo/projects/torchlight.git/logs/refs/remotes/origin/1008hv2_release new file: .repo/projects/torchlight.git/logs/refs/remotes/origin/2016H_16P_develop new file: .repo/projects/torchlight.git/logs/refs/remotes/origin/master new file: .repo/projects/torchlight.git/logs/refs/remotes/origin/master_931 new file: .repo/projects/torchlight.git/logs/refs/remotes/origin/master_931_aisearch new file: .repo/projects/torchlight.git/logs/refs/remotes/origin/master_poe new file: .repo/projects/torchlight.git/logs/refs/remotes/origin/master_poe_dev new file: .repo/projects/torchlight.git/logs/refs/remotes/origin/master_sira_931 new file: .repo/projects/torchlight.git/logs/refs/remotes/origin/master_wifi_dev new file: .repo/projects/torchlight.git/logs/refs/remotes/origin/master_wifi_v14 new file: .repo/projects/torchlight.git/logs/refs/remotes/origin/nvd_v1 new file: .repo/projects/torchlight.git/logs/refs/remotes/origin/nvr1008h8mpv1_singapore new file: .repo/projects/torchlight.git/logs/refs/remotes/origin/nvr4032hv1_dvt new file: .repo/projects/torchlight.git/logs/refs/remotes/origin/nvr4032hv1_singapore new file: .repo/projects/torchlight.git/logs/refs/remotes/origin/nvr_ai new file: .repo/projects/torchlight.git/logs/refs/remotes/origin/nvr_ai_v18 new file: .repo/projects/torchlight.git/logs/refs/remotes/origin/nvr_cv_20230807 new file: .repo/projects/torchlight.git/logs/refs/remotes/origin/nvr_iteration_v18_20250723 new file: .repo/projects/torchlight.git/logs/refs/remotes/origin/nvr_iterator_20230213 new file: .repo/projects/torchlight.git/logs/refs/remotes/origin/nvr_iterator_20230509 new file: .repo/projects/torchlight.git/logs/refs/remotes/origin/nvr_iterator_aisearch new file: .repo/projects/torchlight.git/logs/refs/remotes/origin/nvr_iterator_aisearch_wlm new file: .repo/projects/torchlight.git/logs/refs/remotes/origin/nvr_iterator_v13_wlm new file: .repo/projects/torchlight.git/logs/refs/remotes/origin/nvr_iterator_v14_openapi new file: .repo/projects/torchlight.git/logs/refs/remotes/origin/nvr_iterator_v15 new file: .repo/projects/torchlight.git/logs/refs/remotes/origin/nvr_iterator_v15_4032v1 new file: .repo/projects/torchlight.git/logs/refs/remotes/origin/nvr_iterator_v15_4032v1_20250102 new file: .repo/projects/torchlight.git/logs/refs/remotes/origin/nvr_iterator_v15_4032v1_dev new file: .repo/projects/torchlight.git/logs/refs/remotes/origin/nvr_iterator_v15_wlm new file: .repo/projects/torchlight.git/logs/refs/remotes/origin/nvr_iterator_v15v2 new file: .repo/projects/torchlight.git/logs/refs/remotes/origin/nvr_iterator_v15v2_security new file: .repo/projects/torchlight.git/logs/refs/remotes/origin/nvr_iterator_v16 new file: .repo/projects/torchlight.git/logs/refs/remotes/origin/nvr_iterator_v17 new file: .repo/projects/torchlight.git/logs/refs/remotes/origin/nvr_iterator_v17_cloudstorage new file: .repo/projects/torchlight.git/logs/refs/remotes/origin/nvr_iterator_v18 new file: .repo/projects/torchlight.git/logs/refs/remotes/origin/nvr_iterator_v18_security new file: .repo/projects/torchlight.git/logs/refs/remotes/origin/nvr_iterator_v18_security_allinone new file: .repo/projects/torchlight.git/logs/refs/remotes/origin/nvr_iterator_v18_security_ddr_bcb new file: .repo/projects/torchlight.git/logs/refs/remotes/origin/nvr_iterator_v18_security_onekey_disarming new file: .repo/projects/torchlight.git/logs/refs/remotes/origin/nvr_iterator_v18_security_sira new file: .repo/projects/torchlight.git/logs/refs/remotes/origin/nvr_iterator_v18_wifi new file: .repo/projects/torchlight.git/logs/refs/remotes/origin/nvr_iterator_v20_16128 new file: .repo/projects/torchlight.git/logs/refs/remotes/origin/nvr_iterator_v20_omada new file: .repo/projects/torchlight.git/logs/refs/remotes/origin/nvr_wlm_20240802 new file: .repo/projects/torchlight.git/logs/refs/remotes/origin/nvr_wlm_20240919 new file: .repo/projects/torchlight.git/logs/refs/remotes/origin/release_1004h4pv1 new file: .repo/projects/torchlight.git/logs/refs/remotes/origin/release_1008hv1 new file: .repo/projects/torchlight.git/objects new file: .repo/projects/torchlight.git/packed-refs new file: .repo/projects/torchlight.git/refs/remotes/m/master new file: .repo/projects/torchlight.git/rr-cache new file: .repo/projects/torchlight.git/svn new file: .repo/projects/tp_package.git/.repo_config.json new file: .repo/projects/tp_package.git/FETCH_HEAD new file: .repo/projects/tp_package.git/HEAD new file: .repo/projects/tp_package.git/config new file: .repo/projects/tp_package.git/description new file: .repo/projects/tp_package.git/hooks new file: .repo/projects/tp_package.git/info new file: .repo/projects/tp_package.git/logs/refs/remotes/m/master new file: .repo/projects/tp_package.git/logs/refs/remotes/origin/1008H_iterator new file: .repo/projects/tp_package.git/logs/refs/remotes/origin/1008H_iterator_20210517 new file: .repo/projects/tp_package.git/logs/refs/remotes/origin/1008H_v2_develop_20210603 new file: .repo/projects/tp_package.git/logs/refs/remotes/origin/1008hv2_release new file: .repo/projects/tp_package.git/logs/refs/remotes/origin/2016H_16P_develop new file: .repo/projects/tp_package.git/logs/refs/remotes/origin/master new file: .repo/projects/tp_package.git/logs/refs/remotes/origin/master_931 new file: .repo/projects/tp_package.git/logs/refs/remotes/origin/master_931_aisearch new file: .repo/projects/tp_package.git/logs/refs/remotes/origin/master_poe new file: .repo/projects/tp_package.git/logs/refs/remotes/origin/master_poe_dev new file: .repo/projects/tp_package.git/logs/refs/remotes/origin/master_sira_931 new file: .repo/projects/tp_package.git/logs/refs/remotes/origin/master_wifi_dev new file: .repo/projects/tp_package.git/logs/refs/remotes/origin/master_wifi_v14 new file: .repo/projects/tp_package.git/logs/refs/remotes/origin/nvd_v1 new file: .repo/projects/tp_package.git/logs/refs/remotes/origin/nvr1008h8mpv1_singapore new file: .repo/projects/tp_package.git/logs/refs/remotes/origin/nvr4032hv1_dvt new file: .repo/projects/tp_package.git/logs/refs/remotes/origin/nvr4032hv1_singapore new file: .repo/projects/tp_package.git/logs/refs/remotes/origin/nvr_ai new file: .repo/projects/tp_package.git/logs/refs/remotes/origin/nvr_ai_v18 new file: .repo/projects/tp_package.git/logs/refs/remotes/origin/nvr_cv_20230807 new file: .repo/projects/tp_package.git/logs/refs/remotes/origin/nvr_cv_20231103 new file: .repo/projects/tp_package.git/logs/refs/remotes/origin/nvr_iteration_v18_20250723 new file: .repo/projects/tp_package.git/logs/refs/remotes/origin/nvr_iterator_20230213 new file: .repo/projects/tp_package.git/logs/refs/remotes/origin/nvr_iterator_20230509 new file: .repo/projects/tp_package.git/logs/refs/remotes/origin/nvr_iterator_aisearch new file: .repo/projects/tp_package.git/logs/refs/remotes/origin/nvr_iterator_aisearch_wlm new file: .repo/projects/tp_package.git/logs/refs/remotes/origin/nvr_iterator_v13_mcmc new file: .repo/projects/tp_package.git/logs/refs/remotes/origin/nvr_iterator_v13_wlm new file: .repo/projects/tp_package.git/logs/refs/remotes/origin/nvr_iterator_v14_openapi new file: .repo/projects/tp_package.git/logs/refs/remotes/origin/nvr_iterator_v15 new file: .repo/projects/tp_package.git/logs/refs/remotes/origin/nvr_iterator_v15_2016v2 new file: .repo/projects/tp_package.git/logs/refs/remotes/origin/nvr_iterator_v15_2016v2_wlm new file: .repo/projects/tp_package.git/logs/refs/remotes/origin/nvr_iterator_v15_4032v1 new file: .repo/projects/tp_package.git/logs/refs/remotes/origin/nvr_iterator_v15_4032v1_20250102 new file: .repo/projects/tp_package.git/logs/refs/remotes/origin/nvr_iterator_v15_931 new file: .repo/projects/tp_package.git/logs/refs/remotes/origin/nvr_iterator_v15_931v2 new file: .repo/projects/tp_package.git/logs/refs/remotes/origin/nvr_iterator_v15_smartinit new file: .repo/projects/tp_package.git/logs/refs/remotes/origin/nvr_iterator_v15v2 new file: .repo/projects/tp_package.git/logs/refs/remotes/origin/nvr_iterator_v15v2_1108v1 new file: .repo/projects/tp_package.git/logs/refs/remotes/origin/nvr_iterator_v15v2_2008v2_20250114 new file: .repo/projects/tp_package.git/logs/refs/remotes/origin/nvr_iterator_v15v2_2016h16mpv2_rel new file: .repo/projects/tp_package.git/logs/refs/remotes/origin/nvr_iterator_v15v2_4064v1 new file: .repo/projects/tp_package.git/logs/refs/remotes/origin/nvr_iterator_v15v2_4064v1_dev new file: .repo/projects/tp_package.git/logs/refs/remotes/origin/nvr_iterator_v15v2_4064v1_rel new file: .repo/projects/tp_package.git/logs/refs/remotes/origin/nvr_iterator_v15v2_cloudstorage new file: .repo/projects/tp_package.git/logs/refs/remotes/origin/nvr_iterator_v15v2_ftp new file: .repo/projects/tp_package.git/logs/refs/remotes/origin/nvr_iterator_v15v2_security new file: .repo/projects/tp_package.git/logs/refs/remotes/origin/nvr_iterator_v15v2_smb new file: .repo/projects/tp_package.git/logs/refs/remotes/origin/nvr_iterator_v16 new file: .repo/projects/tp_package.git/logs/refs/remotes/origin/nvr_iterator_v17 new file: .repo/projects/tp_package.git/logs/refs/remotes/origin/nvr_iterator_v17_cloudstorage new file: .repo/projects/tp_package.git/logs/refs/remotes/origin/nvr_iterator_v18 new file: .repo/projects/tp_package.git/logs/refs/remotes/origin/nvr_iterator_v18_omada new file: .repo/projects/tp_package.git/logs/refs/remotes/origin/nvr_iterator_v18_security new file: .repo/projects/tp_package.git/logs/refs/remotes/origin/nvr_iterator_v18_security_allinone new file: .repo/projects/tp_package.git/logs/refs/remotes/origin/nvr_iterator_v18_security_ddr_bcb new file: .repo/projects/tp_package.git/logs/refs/remotes/origin/nvr_iterator_v18_security_onekey_disarming new file: .repo/projects/tp_package.git/logs/refs/remotes/origin/nvr_iterator_v18_security_sira new file: .repo/projects/tp_package.git/logs/refs/remotes/origin/nvr_iterator_v18_wifi new file: .repo/projects/tp_package.git/logs/refs/remotes/origin/nvr_iterator_v18_wifi_security new file: .repo/projects/tp_package.git/logs/refs/remotes/origin/nvr_iterator_v20 new file: .repo/projects/tp_package.git/logs/refs/remotes/origin/nvr_iterator_v20_16128 new file: .repo/projects/tp_package.git/logs/refs/remotes/origin/nvr_iterator_v20_omada new file: .repo/projects/tp_package.git/logs/refs/remotes/origin/nvr_wlm_20240802 new file: .repo/projects/tp_package.git/logs/refs/remotes/origin/nvr_wlm_20240919 new file: .repo/projects/tp_package.git/logs/refs/remotes/origin/release_1004h4pv1 new file: .repo/projects/tp_package.git/logs/refs/remotes/origin/release_1008hv1 new file: .repo/projects/tp_package.git/objects new file: .repo/projects/tp_package.git/packed-refs new file: .repo/projects/tp_package.git/refs/remotes/m/master new file: .repo/projects/tp_package.git/rr-cache new file: .repo/projects/tp_package.git/svn new file: .repo/repo new file: sstar931 new file: torchlight new file: tp_package Changes not staged for commit: (use "git add <file>..." to update what will be committed) (use "git checkout -- <file>..." to discard changes in working directory) (commit or discard the untracked or modified content in submodules) modified: sstar931 (untracked content) modified: torchlight (modified content) modified: tp_package (modified content, untracked content)
最新发布
09-05
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值