def check_put_pause(self, put_file_dict, puted_file, pause_init, sock): #检查文件的MD5码 #1、如果文件MD5码一致,则会调用put_file_existed方法告知客户端 #2、如果MD5码不一致,且断点续传配置文件中也存在上传文件的断点记录的话,会让用户选择是否继续断点续传 puted_file_md5 = set_md5.set_file_md5(puted_file) if puted_file_md5 == put_file_dict['file_md5']: f, recv_size = self.put_file_existed(sock) return f, recv_size else: if os.path.exists(pause_init): recv_size = conf_obj.set_conf({'file_name': puted_file}, 'read_recv_size', pause_init) put_status_dict = { 'put_status': False, 'put_message': self.put_response_code['202'], 'put_again': 'yes', 'is_choice': 'yes' } set_struct.send_message(sock, put_status_dict) diff_dict = set_struct.recv_message(sock) if diff_dict['is_pause_go'] == 'y': f = set_file.write_file(puted_file, 'ab') if diff_dict['is_pause_go'] == 'n': f = set_file.write_file(puted_file, 'wb') recv_size = 0 return f, int(recv_size)
def put_diff(self, put_file, file_size, put_file_dict): '''接收服务端针对下载文件的状态反馈 1、如果反馈信息为True则可以开始执行puting方法,开始上传文件 2、如果反馈信息为False,是因为由服务端检查了,准备上传文件在断点续传配置文件中的记录 3、由用户选择是否进行断点续传,提供了y和n选项 ''' while True: put_status_dict = set_struct.recv_message(self.client) while True: print(put_status_dict['put_message']) if put_status_dict['is_choice'] == 'yes': is_pause_go = input('>>>').lower() if put_status_dict['put_status'] == False: if put_status_dict['put_again'] == 'yes': if is_pause_go in ['n' 'y']: diff_dict = {'is_pause_go': is_pause_go} set_struct.send_message(self.client, diff_dict) break else: print(self.put_request_code['205']) continue else: return else: self.puting(put_file, put_status_dict, file_size, put_file_dict) return
def ll(self, sock, wdata, rlist): #浏览当前文件夹下文件的方法 files_list = os.listdir(self.current_directory) for file in files_list: print(os.stat(os.path.join(self.current_directory, file))) set_struct.send_message(sock, files_list) rlist.append(sock)
def get(self, filename, sock, wdata, rlist): #服务端接收get请求的方法,判断下载的文件是否存在 #1、如果文件存在,会将文件信息以字典的形式发送给客户端 #2、如果文件不存在,则会get_status设置为False geted_file = os.path.join(self.base_dir, 'share', wdata[sock][0], filename) pause_init = os.path.join(self.base_dir, 'db', 'pause.init') get_file = os.path.join(self.base_dir, 'download', wdata[sock][0], filename) if os.path.exists(geted_file): file_size = os.path.getsize(geted_file) file_md5 = set_md5.set_file_md5(geted_file) get_dict = { 'file_name': filename, 'file_size': file_size, 'file_md5': file_md5, 'get_status': True } set_struct.send_message(sock, get_dict) pool = ThreadPoolExecutor() confirm_dict = pool.submit(set_struct.recv_message, sock).result() print(confirm_dict) if confirm_dict['confirm_get'] == False: return t = Thread(target=self.downloading, args=(geted_file, pause_init, get_file, confirm_dict, sock, wdata, rlist)) t.start() else: get_dict = {'get_status': False} set_struct.send_message(sock, get_dict)
def login(self, sock, wdata): while True: try: login_info = set_struct.recv_message(sock) if login_info == None: break except BlockingIOError: continue #z在客户端登录时如果失去连接,那么会导致服务端也会被终止,在此捕获异常 except ConnectionResetError: queue.get() break #验证帐号是否正确,将返回的结果True和False返回给客户端,客户端以此凭据来展示登录成功或失败 is_success, username = login_obj.verify_account(login_info) wdata[sock] = [ username, ] is_success_dict = {'is_success': is_success, 'username': username} set_struct.send_message(sock, is_success_dict) if is_success_dict['is_success'] == True: print(self.put_response_code['204']) return else: print(self.put_response_code['205']) continue
def put(self, cmd, filename): '''初始上传文件的函数方法,验证准备上传的文件, 1、如果文件不存在,则会告知用户,准备上传的文件不存在 2、如果文件存在,则会调用put_diff方法检查断点续传配置文件中,是否有该文件的断点记录 ''' put_file = os.path.join(self.base_dir, 'download', self.username, filename) if os.path.exists(put_file): # self.client.send(cmd.encode(self.encoding)) set_struct.send_message(self.client, {'cmd': cmd}) file_size = os.path.getsize(put_file) file_md5 = set_md5.set_file_md5(put_file) put_file_dict = { 'file_name': filename, 'file_size': file_size, 'file_md5': file_md5, 'put_time': str(set_time.set_time()) } set_struct.send_message(self.client, put_file_dict) self.put_diff(put_file, file_size, put_file_dict) else: print(self.put_request_code['206']) return
def put_file_existed(self, sock): #如果上传的文件已经存在,且MD5码一直,告知客户端文件已存在 put_status_dict = { 'put_status': False, 'put_message': self.put_response_code['201'], 'put_again': 'no', 'is_choice': 'no' } set_struct.send_message(sock, put_status_dict) return None, None
def ll(self, cmd): #通过ll函数方法,可以查看用户通过cd命令到达指定目录后的文件 set_struct.send_message(self.client, {'cmd': cmd}) file_list = set_struct.recv_message(self.client) #如果返回的文件列表为空,则告知用户,否则打印文件 if len(file_list) == 0: print(self.put_request_code['210']) return else: print('文件列表如下:') for file in file_list: print(file)
def cd(self, request_content, sock, wdata, rlist): #通过cd命令切换目录 if request_content not in ['/', '..']: self.user_directory = os.path.join(self.base_dir, 'share', wdata[sock][0]) if request_content == '/': self.current_directory = self.root_directory set_struct.send_message(sock, self.current_directory) rlist.append(sock) elif request_content == '..': if self.current_directory == self.root_directory: self.current_directory = self.root_directory set_struct.send_message(sock, self.current_directory) rlist.append(sock) if self.current_directory == self.user_directory: self.current_directory = self.root_directory set_struct.send_message(sock, self.current_directory) rlist.append(sock) elif request_content in os.listdir(self.current_directory): self.current_directory = self.user_directory set_struct.send_message(sock, self.current_directory) rlist.append(sock)
def cd(self, cmd, directory): print(directory) '''通过cd命令,用户可以切换目录''' root_directory = os.path.join(self.base_dir, 'share') root_directory_list = os.listdir(root_directory) #如果用户指定切换的目录,在云盘列表,或使用cd / | cd ..命令时会将请求发送至客户端 if directory in root_directory_list or directory in ['/', '..']: set_struct.send_message(self.client, {'cmd': cmd}) self.current_directory = os.path.split( set_struct.recv_message(self.client))[1] if self.current_directory == 'share': self.current_directory = '/' else: print('没有找到%s' % directory)
def view(self, cmd, username): #用户可通过view命令浏览个人云盘空间文件的方法 if username != self.username: print(self.put_request_code['208']) return set_struct.send_message(self.client, {'cmd': cmd}) view_info = set_struct.recv_message(self.client) #如果返回的结果是列表,则告知用户云盘是空的 #如果返回的结果是字典,则会调用show_view_file犯法打印文件 if isinstance(view_info, list): print(self.put_request_code['209']) if isinstance(view_info, dict): self.show_view_file(view_info)
def size_not_enough(self, put_file_dict, sock, wdata): free_size = self.free_size(sock, wdata) #云盘空间不足,告知客户端的方法 put_status_dict = { 'put_status': False, 'put_message': '很抱歉,您的云盘空间不足,剩余空间为%sMB,您上传附件的大小是%sMB' % (set_bytes.set_bytes(free_size), set_bytes.set_bytes(put_file_dict['file_size'])), 'put_again': 'no', 'is_choice': 'no' } set_struct.send_message(sock, put_status_dict) return
def put(self, filename, sock, wdata, rlist): print('jin') #服务端接收到put命令,处理上传文件的函数犯法 #1、如果文件存在,则会调用check_put_pause方法,检查断点续传配置文件爱你 #2、如果文件不存在,且磁盘空间满足上传文件的大小,则会调用puting方法执行上传 put_file_dict = set_struct.recv_message(sock) print('put_file_dict', put_file_dict) puted_file = os.path.join(self.base_dir, 'share', wdata[sock][0], filename) pause_init = os.path.join(self.base_dir, 'db', 'pause.init') free_size = self.free_size(sock, wdata) if os.path.exists(puted_file): f, recv_size = self.check_put_pause(put_file_dict, puted_file, pause_init, sock) if f == None: return else: f = None recv_size = 0 if put_file_dict['file_size'] < free_size: put_status_dict = { 'put_status': True, 'put_message': self.put_response_code['200'], 'put_again': 'no', 'is_choice': 'no', 'recv_size': recv_size } set_struct.send_message(sock, put_status_dict) t = Thread(target=self.puting, args=(f, recv_size, put_file_dict, puted_file, sock, rlist)) t.start() t.join() else: self.size_not_enough(put_file_dict, sock, wdata)
def login(self, client): while True: login_choice = input('还没有账号?按r注册账号,已有账号请按g>>>:') if login_choice in ['r', 'R', 'g', 'G']: if login_choice in ['r', 'R']: self.register() continue if login_choice in ['g', 'G']: if not os.path.exists( '%s/%s/%s' % (self.base_dir, 'db', 'account.init')): print('当前系统内还没有任何账号,请先注册') continue while True: username = input('请输入用户名:') password = input('请输入密码:') login_info = { 'username': username, 'password': password } set_struct.send_message(client, login_info) is_success_dict = set_struct.recv_message(client) if is_success_dict['is_success'] == True: self.username = is_success_dict['username'] print('连接成功') return username else: print('用户名或密码错误,请重新输入') continue else: print('您的输入有误,请重新输入') continue
def get(self, cmd, filename): '''初始下载文件函数方法,在函数中验证准备下载的文件是否存在 1、如果文件存在,且MD5码一致,则告知用户无需重复下载 2、如果文件存在,但MD5码不一致,则调用check_get_pause方法,检查断点续传配置文件 3、如果文件不存在,则会调用downloading方法执行下载方法 ''' pause_init = os.path.join(self.base_dir, 'db', 'pause.init') get_file = os.path.join(self.base_dir, 'download', self.username, filename) if not os.path.exists(get_file): set_struct.send_message(self.client, {'cmd': cmd}) # self.client.send(cmd.encode(self.encoding)) get_dict = set_struct.recv_message(self.client) if get_dict['get_status'] == False: print(self.put_request_code['201']) return confirm_dict = {'confirm_get': True} set_struct.send_message(self.client, confirm_dict) print(self.put_request_code['200']) set_bar.set_bar() f = set_file.write_file(get_file, 'wb') recv_size = 0 self.downloading(f, recv_size, get_file, get_dict) else: set_struct.send_message(self.client, {'cmd': cmd}) # self.client.send(cmd.encode(self.encoding)) get_dict = set_struct.recv_message(self.client) if get_dict['get_status'] == False: print(self.put_request_code['201']) return get_file_md5 = set_md5.set_file_md5(get_file) if get_file_md5 == get_dict['file_md5']: self.get_file_existed() return else: f, file_name, recv_size = self.check_get_pause( get_file, pause_init) confirm_dict = { 'confirm_get': True, 'is_pause_go': self.is_pause_go } set_struct.send_message(self.client, confirm_dict) self.downloading(f, int(recv_size), file_name, get_dict)
def view(self, sock, wdata, rlist): view_dict = {} share_file_list = os.listdir( os.path.join(self.base_dir, 'share', wdata[sock][0]))[:] #通过view命令浏览云盘文件,返回文件的名称、大小、上传日期等属性 if len(share_file_list) == 0: set_struct.send_message(sock, share_file_list) else: for file in share_file_list: view_dict[file] = { 'file_name': file, 'file_size': os.path.getsize( os.path.join(self.base_dir, 'share', wdata[sock][0], file)), 'put_date': set_time.set_time( os.path.getctime( os.path.join(self.base_dir, 'share', wdata[sock][0], file))) } set_struct.send_message(sock, view_dict) rlist.append(sock)
def pwd(self, cmd): #查看当前所在目录的命令 set_struct.send_message(self.client, {'cmd': cmd}) current_directory = set_struct.recv_message(self.client) print(current_directory)
def get_file_existed(self): #验证准备下载的文件已存在,告知用户“文件已存在,无需重复下载” print(self.put_request_code['203']) confirm_dict = {'confirm_get': False} set_struct.send_message(self.client, confirm_dict)
def pwd(self, sock, wdata, rlist): #查看当前所在路径的方法 set_struct.send_message(sock, self.current_directory) rlist.append(sock)