Skip to content

Commit 9edcd17

Browse files
author
zaxtyson
committed
fix bugs
1 parent 2bbff1b commit 9edcd17

File tree

3 files changed

+47
-34
lines changed

3 files changed

+47
-34
lines changed

README.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,12 @@
2424
# API 文档
2525
API 文档请查看 [wiki](https://github.com/zaxtyson/LanZouCloud-API/wiki) 页面
2626

27+
# `2.3.1` 更新说明
28+
- 开放了对 `is_file_url()``is_folder_url()` 两个函数的调用
29+
- 修复了文件夹深度达到 4 层时 `get_full_path()` 报错的问题
30+
- `mkdir()` 创建文件夹时会检查是否有同名文件夹,有的话加上 `_` 后缀
31+
- `get_folder_id_list()` 返回的文件夹中加入了根目录信息 `{LanZouCloud: -1}`
32+
2733
# `2.3.0` 更新说明
2834
- 重新封装了 `_get()``_post()`方法,防止弱网环境炸出一堆网络异常导致程序崩溃
2935

lanzou/api.py

Lines changed: 40 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -69,18 +69,6 @@ def _post(self, url, data, **kwargs):
6969
except (ConnectionError, requests.RequestException):
7070
return None
7171

72-
@staticmethod
73-
def _is_file_url(share_url) -> bool:
74-
"""判断是否为文件的分享链接"""
75-
pat = 'https?://www.lanzous.com/i[a-z0-9]{6,}/?'
76-
return True if re.fullmatch(pat, share_url) else False
77-
78-
@staticmethod
79-
def _is_folder_url(share_url) -> bool:
80-
"""判断是否为文件夹的分享链接"""
81-
pat = 'https?://www.lanzous.com/b[a-z0-9]{7,}/?'
82-
return True if re.fullmatch(pat, share_url) else False
83-
8472
@staticmethod
8573
def _remove_notes(html) -> str:
8674
"""删除网页的注释"""
@@ -117,6 +105,18 @@ def _get_right_name(self, filename):
117105
ftype = filename.split('.')[-1] # 正确的文件后缀
118106
return filename, ftype.lower()
119107

108+
@staticmethod
109+
def is_file_url(share_url) -> bool:
110+
"""判断是否为文件的分享链接"""
111+
pat = 'https?://www.lanzous.com/i[a-z0-9]{6,}/?'
112+
return True if re.fullmatch(pat, share_url) else False
113+
114+
@staticmethod
115+
def is_folder_url(share_url) -> bool:
116+
"""判断是否为文件夹的分享链接"""
117+
pat = 'https?://www.lanzous.com/b[a-z0-9]{7,}/?'
118+
return True if re.fullmatch(pat, share_url) else False
119+
120120
def set_rar_tool(self, bin_path) -> int:
121121
"""设置解压工具路径"""
122122
if os.path.isfile(bin_path):
@@ -356,19 +356,20 @@ def get_full_path(self, folder_id=-1) -> dict:
356356
html = self._get(self._mydisk_url, params={'item': 'files', 'action': 'index', 'folder_id': folder_id})
357357
if not html:
358358
return path_list
359-
path = re.findall(r'&raquo;&nbsp;.+folder_id=([0-9]+)">.+&nbsp;(.+?)</a>', html.text)
360-
for i in path:
361-
path_list[i[1]] = int(i[0])
359+
html = LanZouCloud._remove_notes(html.text)
360+
path = re.findall(r'&raquo;&nbsp;.+?folder_id=(\d+)">.+?&nbsp;(.+?)</a>', html)
361+
for fid, name in path:
362+
path_list[name] = int(fid)
362363
# 获取当前文件夹名称
363364
if folder_id != -1:
364-
current_folder = re.findall(r'&raquo;&nbsp;.+&nbsp;(.+) <font', html.text)[0].replace('&amp;', '&')
365+
current_folder = re.search(r'align="(top|absmiddle)" />&nbsp;(.+?)\s<(span|font)', html).group(2).replace('&amp;', '&')
365366
path_list[current_folder] = folder_id
366367
return path_list
367368

368369
def get_file_info_by_url(self, share_url, pwd=''):
369370
"""获取直链"""
370-
no_result = {'name': '', 'size': '', 'type': '', 'time': '', 'desc': '', 'durl': ''}
371-
if not self._is_file_url(share_url): # 非文件链接返回错误
371+
no_result = {'name': '', 'size': '', 'type': '', 'time': '', 'desc': '', 'pwd': '', 'url': '', 'durl': ''}
372+
if not self.is_file_url(share_url): # 非文件链接返回错误
372373
return {'code': LanZouCloud.URL_INVALID, **no_result}
373374

374375
first_page = self._get(share_url) # 文件分享页面(第一页)
@@ -422,15 +423,15 @@ def get_file_info_by_url(self, share_url, pwd=''):
422423
return {'code': LanZouCloud.NETWORK_ERROR, **no_result}
423424
else:
424425
link_info = link_info.json()
425-
# link_info['inf'] = f_name # 无提取码时 inf 字段为 0,有提取码时该字段为文件名
426426

427427
# 这里开始获取文件直链
428428
if link_info['zt'] == 1:
429429
fake_url = link_info['dom'] + '/file/' + link_info['url'] # 假直连,存在流量异常检测
430430
direct_url = self._get(fake_url, allow_redirects=False).headers['Location'] # 重定向后的真直链
431431
f_name, ftype = self._get_right_name(f_name)
432432
return {'code': LanZouCloud.SUCCESS, 'name': f_name, 'size': f_size, 'type': ftype,
433-
'time': LanZouCloud._time_format(f_time), 'desc': f_desc, 'durl': direct_url}
433+
'time': LanZouCloud._time_format(f_time), 'desc': f_desc, 'pwd': pwd,
434+
'url': share_url, 'durl': direct_url}
434435
else:
435436
return {'code': LanZouCloud.PASSWORD_ERROR, **no_result}
436437

@@ -502,6 +503,8 @@ def mkdir(self, parent_id, folder_name, desc='') -> int:
502503
folder_list = self.get_dir_id_list(parent_id)
503504
if folder_name in folder_list.keys(): # 如果文件夹已经存在,直接返回 id
504505
return folder_list.get(folder_name)
506+
if folder_name in self.get_folder_id_list().keys(): # 防止文件夹名重复导致其它功能混乱
507+
return self.mkdir(parent_id, folder_name + '_', desc)
505508
post_data = {"task": 2, "parent_id": parent_id or -1, "folder_name": folder_name,
506509
"folder_description": desc}
507510
result = self._post(self._doupload_url, post_data) # 创建文件夹
@@ -548,10 +551,12 @@ def set_desc(self, fid, desc, is_file=True) -> int:
548551
def get_folder_id_list(self) -> dict:
549552
"""获取全部文件夹 name-id 列表,用于移动文件至新的文件夹"""
550553
# 这里 file_id 可以为任意值,不会对结果产生影响
551-
result = self._post(self._doupload_url, data={"task": 19, "file_id": -1})
552-
if not result or result.json()['zt'] != 1: # 获取失败或者网络异常
553-
return {}
554-
return {i['folder_name']: int(i['folder_id']) for i in result.json()['info']}
554+
result = {'LanZouCloud': -1}
555+
resp = self._post(self._doupload_url, data={"task": 19, "file_id": -1})
556+
if not resp or resp.json()['zt'] != 1: # 获取失败或者网络异常
557+
return result
558+
folder_id_list = {i['folder_name']: int(i['folder_id']) for i in resp.json()['info']}
559+
return {**result, **folder_id_list}
555560

556561
def move_file(self, file_id, folder_id=-1) -> int:
557562
"""移动文件到指定文件夹"""
@@ -685,7 +690,7 @@ def upload_file(self, file_path, folder_id=-1, call_back=None) -> dict:
685690
# 现在上传真正的文件并保存上传结果
686691
code = self._upload_a_file('./tmp/' + f, dir_id, call_back)
687692
if code != LanZouCloud.SUCCESS: # 记录上传失败的文件
688-
result['status'] = LanZouCloud.FAILED
693+
result['code'] = LanZouCloud.FAILED
689694
result['failed'].append(f)
690695
rmtree('./tmp')
691696
return result
@@ -704,13 +709,13 @@ def upload_dir(self, dir_path, folder_id=-1, call_back=None) -> dict:
704709
continue # 跳过子文件夹
705710
up_failed = self.upload_file(dir_path + os.sep + file, dir_id, call_back)['failed']
706711
if up_failed: # 上传失败的文件列表
707-
result['status'] = LanZouCloud.FAILED
712+
result['code'] = LanZouCloud.FAILED
708713
result['failed'] += up_failed
709714
return result
710715

711716
def down_file_by_url(self, share_url, pwd='', save_path='.', call_back=None) -> int:
712717
"""通过分享链接下载文件(需提取码)"""
713-
if not self._is_file_url(share_url):
718+
if not self.is_file_url(share_url):
714719
return LanZouCloud.URL_INVALID
715720
if not os.path.exists(save_path):
716721
os.makedirs(save_path)
@@ -766,7 +771,7 @@ def _unzip(self, file_list, save_path) -> int:
766771
def get_folder_info_by_url(self, share_url, dir_pwd='') -> dict:
767772
"""获取文件夹里所有文件的信息"""
768773
no_result = {'folder': {}, 'files': []}
769-
if LanZouCloud._is_file_url(share_url):
774+
if LanZouCloud.is_file_url(share_url):
770775
return {'code': LanZouCloud.URL_INVALID, **no_result}
771776
try:
772777
html = requests.get(share_url, headers=self._headers).text
@@ -828,7 +833,7 @@ def get_folder_info_by_url(self, share_url, dir_pwd='') -> dict:
828833
folder_time = datetime.today().strftime('%Y-%m-%d')
829834
return {'code': LanZouCloud.SUCCESS,
830835
'folder': {'name': folder_name, 'id': folder_id, 'pwd': dir_pwd, 'time': folder_time,
831-
'desc': folder_desc},
836+
'desc': folder_desc, 'url': share_url},
832837
'files': files}
833838

834839
def get_folder_info_by_id(self, folder_id):
@@ -850,11 +855,11 @@ def down_dir_by_url(self, share_url, dir_pwd='', save_path='./down', call_back=N
850855
for name, url in info:
851856
code = self.down_file_by_url(url, '', save_path, call_back)
852857
if code != LanZouCloud.SUCCESS: # 有文件下载失败了
853-
result['status'] = LanZouCloud.FAILED
858+
result['code'] = LanZouCloud.FAILED
854859
result['failed'].append({'name': name, 'url': url, 'code': code})
855860

856861
# 部分文件下载失败,没必要尝试解压了
857-
if result['status'] != LanZouCloud.SUCCESS:
862+
if result['code'] != LanZouCloud.SUCCESS:
858863
return result
859864

860865
# 全部下载成功且文件都是分卷压缩文件 *.xxx[0-9]+.rar,则下载后需要解压
@@ -865,6 +870,7 @@ def down_dir_by_url(self, share_url, dir_pwd='', save_path='./down', call_back=N
865870

866871
if self._unzip(f_name_list, save_path) == LanZouCloud.ZIP_ERROR:
867872
return {'code': LanZouCloud.ZIP_ERROR, 'failed': []} # 解压时发生错误
873+
return result
868874

869875
def down_dir_by_id(self, fid, save_path='./down', call_back=None) -> dict:
870876
"""登录用户通过id下载文件夹"""
@@ -876,13 +882,14 @@ def down_dir_by_id(self, fid, save_path='./down', call_back=None) -> dict:
876882
code = self.down_file_by_id(fid, save_path, call_back)
877883
logger.debug(f'Download file result code: {code}')
878884
if code != LanZouCloud.SUCCESS:
879-
result['status'] = LanZouCloud.FAILED
885+
result['code'] = LanZouCloud.FAILED
880886
result['failed'].append({'name': name, 'id': fid, 'code': code})
881-
if result['status'] != LanZouCloud.SUCCESS:
887+
if result['code'] != LanZouCloud.SUCCESS:
882888
return result
883889
f_name_list = list(file_list.keys()) # 文件名列表
884890
for name in f_name_list:
885891
if not re.match(r'.*\.\w+[0-9]+\.rar', name):
886892
return result
887893
if self._unzip(f_name_list, save_path) == LanZouCloud.ZIP_ERROR:
888894
return {'code': LanZouCloud.ZIP_ERROR, 'failed': []} # 解压时发生错误
895+
return result

setup.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55

66
setuptools.setup(
77
name="lanzou-api",
8-
version="2.3.0",
8+
version="2.3.1",
99
author="zaxtyson",
1010
author_email="zaxtyson@foxmail.com",
1111
description="LanZouCloud API",

0 commit comments

Comments
 (0)