def get_file_list(self, folder_id=-1) -> FileList: """获取文件列表""" page = 1 file_list = FileList() while True: post_data = {'task': 5, 'folder_id': folder_id, 'pg': page} resp = self._post(self._doupload_url, post_data) if not resp: # 网络异常,重试 continue else: resp = resp.json() if resp["info"] == 0: break # 已经拿到了全部的文件信息 else: page += 1 # 下一页 # 文件信息处理 for file in resp["text"]: file_list.append(File( id=int(file['id']), name=file['name_all'], time=file['time'], # 上传时间 size=file['size'], # 文件大小 type=file['name_all'].split('.')[-1], # 文件类型 downs=int(file['downs']), # 下载次数 has_pwd=True if int(file['onof']) == 1 else False, # 是否存在提取码 has_des=True if int(file['is_des']) == 1 else False # 是否存在描述 )) return file_list
def get_rec_file_list(self, folder_id=-1) -> FileList: """获取回收站文件列表""" if folder_id == -1: # 列出回收站根目录文件 # 回收站文件夹中的文件也会显示在根目录 html = self._get(self._mydisk_url, params={ 'item': 'recycle', 'action': 'files' }) if not html: return FileList() html = remove_notes(html.text) files = re.findall( r'fl_sel_ids[^\n]+value="(\d+)".+?filetype/(\w+)\.gif.+?/>\s?(.+?)(?:\.{3})?</a>.+?<td.+?>([\d\-]+?)</td>', html, re.DOTALL) file_list = FileList() file_name_list = [] counter = 1 for fid, ftype, name, time in sorted(files, key=lambda x: x[2]): if not name.endswith(ftype): # 防止文件名太长导致丢失了文件后缀 name = name + '.' + ftype if name in file_name_list: # 防止长文件名前 17:34 个字符相同重名 counter += 1 name = f'{name}({counter})' else: counter = 1 file_name_list.append(name) file_list.append( RecFile(name, int(fid), ftype, size='', time=time)) return file_list else: # 列出回收站中文件夹内的文件,信息只有部分文件名和文件大小 para = { 'item': 'recycle', 'action': 'folder_restore', 'folder_id': folder_id } html = self._get(self._mydisk_url, params=para) if not html or '此文件夹没有包含文件' in html.text: return FileList() html = remove_notes(html.text) files = re.findall( r'com/(\d+?)".+?filetype/(\w+)\.gif.+?/> (.+?)(?:\.{3})?</a> <font color="#CCCCCC">\((.+?)\)</font>', html) file_list = FileList() file_name_list = [] counter = 1 for fid, ftype, name, size in sorted(files, key=lambda x: x[2]): if not name.endswith(ftype): # 防止文件名太长丢失后缀 name = name + '.' + ftype if name in file_name_list: counter += 1 name = f'{name}({counter})' # 防止文件名太长且前17个字符重复 else: counter = 1 file_name_list.append(name) file_list.append( RecFile(name, int(fid), ftype, size=size, time='')) return file_list
def get_folder_info_by_url(self, share_url, dir_pwd=''): """获取文件夹里所有文件的信息""" if is_file_url(share_url): return FolderDetail(LanZouCloud.URL_INVALID) try: html = requests.get(share_url, headers=self._headers).text except requests.RequestException: return FolderDetail(LanZouCloud.NETWORK_ERROR) if '文件不存在' in html: return FolderDetail(LanZouCloud.FILE_CANCELLED) if '请输入密码' in html and len(dir_pwd) == 0: return FolderDetail(LanZouCloud.LACK_PASSWORD) try: # 获取文件需要的参数 html = remove_notes(html) lx = re.findall(r"'lx':'?(\d)'?,", html)[0] t = re.findall(r"var [0-9a-z]{6} = '(\d{10})';", html)[0] k = re.findall(r"var [0-9a-z]{6} = '([0-9a-z]{15,})';", html)[0] # 文件夹的信息 folder_id = re.findall(r"'fid':'?(\d+)'?,", html)[0] folder_name = re.findall(r"var.+?='(.+?)';\n.+document.title", html)[0] folder_time = re.findall(r'class="rets">([\d\-]+?)<a', html)[0] # 日期不全 %m-%d folder_desc = re.findall(r'id="filename">(.+?)</span>', html) # 无描述时无法完成匹配 folder_desc = folder_desc[0] if len(folder_desc) == 1 else '' except IndexError: return FolderDetail(LanZouCloud.FAILED) page = 1 files = FileList() while True: try: # 这里不用封装好的 post 函数是为了支持未登录的用户通过 URL 下载, 无密码时设置 pwd 字段也不影响 post_data = {'lx': lx, 'pg': page, 'k': k, 't': t, 'fid': folder_id, 'pwd': dir_pwd} resp = requests.post(self._host_url + '/filemoreajax.php', data=post_data, headers=self._headers).json() except requests.RequestException: return FolderDetail(LanZouCloud.NETWORK_ERROR) if resp['zt'] == 1: # 成功获取一页文件信息 for f in resp["text"]: files.append(FileInFolder( name=f["name_all"], # 文件名 time=f["time"], # 上传时间 size=f["size"], # 文件大小 type=f["name_all"].split('.')[-1], # 文件格式 url=self._host_url + "/" + f["id"] # 文件分享链接 )) page += 1 # 下一页 continue elif resp['zt'] == 2: # 已经拿到全部的文件信息 break elif resp['zt'] == 3: # 提取码错误 return FolderDetail(LanZouCloud.PASSWORD_ERROR) elif resp["zt"] == 4: continue else: return FolderDetail(LanZouCloud.FAILED) # 其它未知错误 # 通过文件的时间信息补全文件夹的年份(如果有文件的话) if files: # 最后一个文件上传时间最早,文件夹的创建年份与其相同 folder_time = files[-1].time.split('-')[0] + '-' + folder_time else: # 可恶,没有文件,日期就设置为今年吧 folder_time = datetime.today().strftime('%Y-%m-%d') return FolderDetail(LanZouCloud.SUCCESS, FolderInfo(folder_name, folder_id, dir_pwd, folder_time, folder_desc, share_url), files)