def send_files(self, file_list, write_to, set_progress=None): for file_path in file_list: file_name = os.path.basename(file_path) size, unit, bytes_size = tools.file_size(file_path) with open(file_path, 'rb') as fp: protocol = dict(code=100, msg='', size=os.path.getsize(file_path), write_path=os.path.join(write_to, file_name)) self.before_send(protocol) b_data = fp.read(self.file_group_len) last_s = int(time.time()) last_s_send_group = int() send_group = int() start_time = int(time.time()) while b_data: if self.base_socket.send_all(b_data): send_group += 1 last_s_send_group += 1 b_data = fp.read(self.file_group_len) # 如果设置了回调函数,每秒钟调用并且传递回调函数 if int(time.time() ) != last_s and set_progress: # 说明过去了一秒 QApplication.processEvents() d = tools.Dict( operation="传送中", name=file_name, progress=int(send_group * self.file_group_len / bytes_size * 100), speed=tools.bytes_to_speed( last_s_send_group * self.file_group_len), detail=tools.bytes_to_speed( send_group * self.file_group_len) + "/" + str(size) + unit, elapsed_time=tools.second_to_time( int(time.time()) - start_time), remaining_time=tools.second_to_time( (bytes_size - send_group * self.file_group_len) / (last_s_send_group * self.file_group_len))) last_s_send_group = int() last_s = int(time.time()) set_progress.emit(d) else: print("scoket异常 文件发送停止。") return False print("文件发送完毕", file_name) return True
def remove_dirs(self, package): del_count = len(package.data.removes_list) package.data.title = "考虑清楚了吗?" package.data.text = f"批量删除 {del_count}个对象,删除后不可撤回!" if self.aer_you_sure(package): self.show_progress.emit() for i in package.data.removes_list: if self.set_progress: progress_data = tools.Dict(operation="批量删除", name=os.path.basename(i), progress=100, speed="---", detail="", elapsed_time="00:00:00", remaining_time="00:00:00") self.set_progress.emit(progress_data) QApplication.processEvents() self.local_table_func.remove(i) self.hide_progress.emit() self.local_reload_table()
def sendfile_or_mkdir(self, file_list, write_to): # 打开传送窗口 self.send_data(600, '') for item in file_list: cur_path = os.path.dirname(item) for flag, path in tools.list_dir_all(cur_path, os.path.basename(item)): path = path.replace("\\", "/") if flag == 0: # 创建目录 progress_data = tools.Dict(operation="创建目录", name=os.path.basename(path), progress=100, speed="---", detail="创建完毕", elapsed_time="00:00:00", remaining_time="00:00:00") # 更新状态 print("创建目录", path) abs_path = os.path.join(write_to, path) self.os_mkdir(abs_path) self.send_data(602, '', progress_data) # time.sleep(0.1) else: file_path = os.path.join(cur_path, path).replace("\\", "/") client_write_to = os.path.dirname( os.path.join(write_to, path)) + "/" # progress_data = tools.Dict( # operation="下载中...", # name=os.path.basename(file_path), # progress=100, # speed="---", # detail="下载暂不提供进度", # elapsed_time="00:00:00", # remaining_time="00:00:00" # ) # self.send_data(602, '', progress_data) self.send_files([file_path], client_write_to) # time.sleep(0.1) # 关闭传送窗口 self.send_data(601, '') self.client_reload()
once_recv_btyes) # 注册session的响应类 Session.on_msg = remote_handler.on_msg # 启动session监听 Session.recv_data_for_every() # 实例主窗口的子组件(交互输入框、进度展示界面) input_window = InputWindow() progress = ProgressWindow() # 实例化主窗口(文件窗口的主窗口) main_window = MainWindow( local_handler, remote_handler, local_handler.Dict(input_window=input_window, progress_window=progress)) # 注册控制类的回调函数 remote_handler.local_reload = main_window.local_reload_table remote_handler.show_progress = main_window.show_progress # 信号槽 remote_handler.hide_progress = main_window.hide_progress remote_handler.set_status = main_window.set_progress # 注册进度条关闭的时间 progress.on_close = main_window.on_progress_window_close # 显示主窗口 main_window.show() # 运行应用,并监听事件 sys.exit(app.exec_())
def on_msg(self, b_data): try: protocol = self.decode_protocol(b_data) except Exception as e: print("解析协议出错", e, b_data, len(b_data)) return try: code = protocol["code"] next_size = protocol.get("size") msg = protocol["msg"] except Exception as e: print("解析协议错误", e) return if code == 100: # 收到了文件流 print(f"收到文件流 {protocol['write_path']}") all_size = next_size last_d = b'' # 接收到上一组的数据 last_second_recv_bytes = int() # 上一秒接收到的字节数,用于计算下载进度条 last_second = int(time.time()) # 用来控制间隔一秒更新一次下载进度的变量 start_time = int(time.time()) # 下载数据开始的时间 once_recv = self.once_recv # 规定了一次最多接收多少数据 receive_size = 0 # 一共接收了多少数据 detail_size = tools.bytes_to_speed(all_size) # 需要下载的数据大小以人性化方式展示 # 首次接收到文件,需要实例化一个文件类 if not self.file_fp: try: self.file_fp = self.file_io( write_path=protocol["write_path"]) except Exception as e: print("初始化文件对象错误:", str(e)) return # 当需要接收的数据大于单次最大接收量时,需要进入while循环,直到接收完毕 if all_size > once_recv: while receive_size != all_size: receive_data = self.base_socket.recv_once(once_recv) last_d = receive_data last_second_recv_bytes += len(receive_data) receive_size += len(receive_data) # 为了不让IO耽误时间,这里使用工厂模式处理文件的写入 self.file_fp.stream_queue.put(receive_data) # 当剩余的数据小于一组的大小,需要更改下一次接收字节的数量,否则会打乱数据 if (all_size - receive_size) < once_recv: once_recv = all_size - receive_size # 每秒钟更新下载进度条 if int(time.time()) != last_second and self.set_status: progress = tools.Dict( operation="传送中", name=os.path.basename(protocol["write_path"]), progress=int(receive_size / all_size * 100), speed=tools.bytes_to_speed(last_second_recv_bytes), detail=tools.bytes_to_speed(receive_size) + "/" + detail_size, elapsed_time=tools.second_to_time( int(time.time()) - start_time), remaining_time=tools.second_to_time( (all_size - receive_size) / last_second_recv_bytes)) self.set_status.emit(tools.Dict(progress)) last_second = int(time.time()) last_second_recv_bytes = int() else: receive_data = self.base_socket.recv_once(all_size) last_d = receive_data self.file_fp.stream_queue.put(receive_data) # 发送一个字典对象,表示写入结束 self.file_fp.stream_queue.put(protocol) self.file_fp = None print( f"文件写入缓存成功 {os.path.basename(protocol['write_path'])} \n" f"文件一共{all_size} 接收了 {receive_size} 最后一组数据长度 {len(last_d)} \n {last_d}" ) elif code == 101: # 客户端需要下载文件 receive_data = self.base_socket.recv_agroup(next_size) data = tools.decode_dict(receive_data) file_list = data["file_list"] write_to = data["write_path"] print("客户下载文件", file_list) self.send_files(file_list, write_to) elif code == 200: # 创建新目录 # 只有服务器才会使用此方法 receive_data = self.base_socket.recv_agroup(next_size) data = tools.decode_dict(receive_data) # if data.get("dir_path") == "C:/test/Keil/C51/Examples/ST uPSD/upsd3300/DK3300-ELCD/I2C/I2C_Master": # print("11111") dir_path = data["dir_path"] succ, msg = tools.mkdir(dir_path) if not succ: # return self.send_data(201, '创建新目录成功') return self.error(msg) elif code == 202: # 更改名字 # 只有服务器才会使用此方法 receive_data = self.base_socket.recv_agroup(next_size) data = tools.decode_dict(receive_data) succ, msg = tools.rename(data["old"], data["new"]) if succ: return self.send_data(203, '重命名成功') return self.error(msg) elif code == 204: #删除服务器目录或者文件 # 只有服务器才会使用此方法 receive_data = self.base_socket.recv_agroup(next_size) data = tools.decode_dict(receive_data) succ, msg = tools.remove(data["abs_path"]) if succ: return self.send_data(205, '删除成功') return self.error(msg) elif code == 206: # 客户端获取服务器目录 receive_data = self.base_socket.recv_agroup(next_size) data = tools.decode_dict(receive_data) list_dir = tools.listdir(data["dir_path"]) self.send_data(207, data=dict(list_dir=list_dir)) elif code == 207: # 服务器返回目录 receive_data = self.base_socket.recv_agroup(next_size) data = tools.decode_dict(receive_data) self.response_data.put(data) elif code == 208: # 客户端获取服务器磁盘 disk_list = tools.get_disk() self.send_data(207, data=dict(disk_list=disk_list)) elif code == 209: receive_data = self.base_socket.recv_agroup(next_size) data = tools.decode_dict(receive_data) self.response_data.put(data["disk_list"]) disk_list = data["disk_list"] print("收到服务器磁盘列表", disk_list) elif code == 210: if self.local_reload: print("刷新本地文件") self.local_reload() elif code == 500: # 收到异常 receive_data = self.base_socket.recv_agroup(next_size) data = tools.decode_dict(receive_data) if self.on_error: self.on_error(data) print(f"收到异常: {data}") elif code == 501: # 收到通知 print(f"收到消息: {protocol['msg']}") elif code == 600: if self.show_progress: self.show_progress.emit() elif code == 601: if self.hide_progress: self.hide_progress.emit() elif code == 602: receive_data = self.base_socket.recv_agroup(next_size) data = tools.decode_dict(receive_data) if self.set_status: self.set_status.emit(tools.Dict(data))