From 180b187dbf7e2a7b7bde8e4bc7c0d120b70beea5 Mon Sep 17 00:00:00 2001 From: liuxin Date: Wed, 21 Dec 2016 14:13:53 +0800 Subject: [PATCH 1/9] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E4=B8=80=E5=A4=84python3?= =?UTF-8?q?=E4=B8=8B=E7=BC=96=E8=AF=91=E5=BC=82=E5=B8=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- baidupcsapi/api.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/baidupcsapi/api.py b/baidupcsapi/api.py index c7456d7..088a9e4 100644 --- a/baidupcsapi/api.py +++ b/baidupcsapi/api.py @@ -1065,7 +1065,7 @@ def rename(self, rename_pair_list, **kwargs): } url = 'http://{0}/api/filemanager'.format(BAIDUPAN_SERVER) - print '请求url', url + print('请求url', url) logging.debug('rename ' + str(data) + 'URL:' + url) return self._request('filemanager', 'rename', url=url, data=data, extra_params=params, **kwargs) From 2be9fd4c82e8165270f2e0a7e7be7bca04669a5d Mon Sep 17 00:00:00 2001 From: liuxin Date: Wed, 21 Dec 2016 16:36:45 +0800 Subject: [PATCH 2/9] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E4=B8=80=E5=A4=84python3?= =?UTF-8?q?=20urllib=E5=BC=95=E7=94=A8=E9=94=99=E8=AF=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- baidupcsapi.egg-info/PKG-INFO | 20 + baidupcsapi.egg-info/SOURCES.txt | 14 + baidupcsapi.egg-info/dependency_links.txt | 1 + baidupcsapi.egg-info/not-zip-safe | 1 + baidupcsapi.egg-info/requires.txt | 3 + baidupcsapi.egg-info/top_level.txt | 1 + baidupcsapi/api.py | 2 +- build/lib/baidupcsapi/__init__.py | 9 + build/lib/baidupcsapi/api.py | 1798 +++++++++++++++++++++ dist/baidupcsapi-0.3.8-py3.5.egg | Bin 0 -> 39709 bytes 10 files changed, 1848 insertions(+), 1 deletion(-) create mode 100644 baidupcsapi.egg-info/PKG-INFO create mode 100644 baidupcsapi.egg-info/SOURCES.txt create mode 100644 baidupcsapi.egg-info/dependency_links.txt create mode 100644 baidupcsapi.egg-info/not-zip-safe create mode 100644 baidupcsapi.egg-info/requires.txt create mode 100644 baidupcsapi.egg-info/top_level.txt create mode 100644 build/lib/baidupcsapi/__init__.py create mode 100644 build/lib/baidupcsapi/api.py create mode 100644 dist/baidupcsapi-0.3.8-py3.5.egg diff --git a/baidupcsapi.egg-info/PKG-INFO b/baidupcsapi.egg-info/PKG-INFO new file mode 100644 index 0000000..b05ebf4 --- /dev/null +++ b/baidupcsapi.egg-info/PKG-INFO @@ -0,0 +1,20 @@ +Metadata-Version: 1.1 +Name: baidupcsapi +Version: 0.3.8 +Summary: 百度网盘API +Home-page: https://github.com/ly0/baidupcsapi +Author: liyangjie,mozillazg,capric8416,a1exwang +Author-email: latyas@gmail.com,mozillazg101@gmail.com +License: MIT +Download-URL: https://github.com/ly0/baidupcsapi +Description: UNKNOWN +Keywords: 百度网盘,百度云,API +Platform: UNKNOWN +Classifier: Development Status :: 5 - Production/Stable +Classifier: Intended Audience :: Developers +Classifier: License :: OSI Approved :: MIT License +Classifier: Operating System :: OS Independent +Classifier: Programming Language :: Python +Classifier: Programming Language :: Python :: 2 +Classifier: Programming Language :: Python :: 2.7 +Classifier: Topic :: Utilities diff --git a/baidupcsapi.egg-info/SOURCES.txt b/baidupcsapi.egg-info/SOURCES.txt new file mode 100644 index 0000000..0b61ee5 --- /dev/null +++ b/baidupcsapi.egg-info/SOURCES.txt @@ -0,0 +1,14 @@ +CHANGELOG.md +LICENSE.md +MANIFEST.in +README.md +requirements.txt +setup.py +baidupcsapi/__init__.py +baidupcsapi/api.py +baidupcsapi.egg-info/PKG-INFO +baidupcsapi.egg-info/SOURCES.txt +baidupcsapi.egg-info/dependency_links.txt +baidupcsapi.egg-info/not-zip-safe +baidupcsapi.egg-info/requires.txt +baidupcsapi.egg-info/top_level.txt \ No newline at end of file diff --git a/baidupcsapi.egg-info/dependency_links.txt b/baidupcsapi.egg-info/dependency_links.txt new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/baidupcsapi.egg-info/dependency_links.txt @@ -0,0 +1 @@ + diff --git a/baidupcsapi.egg-info/not-zip-safe b/baidupcsapi.egg-info/not-zip-safe new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/baidupcsapi.egg-info/not-zip-safe @@ -0,0 +1 @@ + diff --git a/baidupcsapi.egg-info/requires.txt b/baidupcsapi.egg-info/requires.txt new file mode 100644 index 0000000..283b886 --- /dev/null +++ b/baidupcsapi.egg-info/requires.txt @@ -0,0 +1,3 @@ +requests>=1.1.0 +requests_toolbelt>=0.1.2 +rsa>=3.1.4 diff --git a/baidupcsapi.egg-info/top_level.txt b/baidupcsapi.egg-info/top_level.txt new file mode 100644 index 0000000..7678cb7 --- /dev/null +++ b/baidupcsapi.egg-info/top_level.txt @@ -0,0 +1 @@ +baidupcsapi diff --git a/baidupcsapi/api.py b/baidupcsapi/api.py index 088a9e4..cb014f2 100644 --- a/baidupcsapi/api.py +++ b/baidupcsapi/api.py @@ -12,7 +12,7 @@ import random import base64 from hashlib import sha1, md5 -from urllib import urlencode, quote +from urllib.parse import urlencode, quote from zlib import crc32 from requests_toolbelt import MultipartEncoder import requests diff --git a/build/lib/baidupcsapi/__init__.py b/build/lib/baidupcsapi/__init__.py new file mode 100644 index 0000000..ad93e2d --- /dev/null +++ b/build/lib/baidupcsapi/__init__.py @@ -0,0 +1,9 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +__title__ = 'baidupcsapi' +__version__ = '0.2.12' +__author__ = 'mozillazg,latyas' +__license__ = 'MIT' + +from .api import PCS \ No newline at end of file diff --git a/build/lib/baidupcsapi/api.py b/build/lib/baidupcsapi/api.py new file mode 100644 index 0000000..cb014f2 --- /dev/null +++ b/build/lib/baidupcsapi/api.py @@ -0,0 +1,1798 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +from functools import wraps +import re +import time +import json +import os +import logging +import pickle +import string +import random +import base64 +from hashlib import sha1, md5 +from urllib.parse import urlencode, quote +from zlib import crc32 +from requests_toolbelt import MultipartEncoder +import requests +requests.packages.urllib3.disable_warnings() +import rsa +import urllib + + +""" +logging.basicConfig(level=logging.DEBUG, + format='%(asctime)s %(filename)s[line:%(lineno)d] %(levelname)s %(message)s', + datefmt='%a, %d %b %Y %H:%M:%S') +""" + +BAIDUPAN_SERVER = 'pan.baidu.com' +BAIDUPCS_SERVER = 'pcs.baidu.com' +BAIDUPAN_HEADERS = {"Referer": "http://pan.baidu.com/disk/home", + "User-Agent": "netdisk;4.6.2.0;PC;PC-Windows;10.0.10240;WindowsBaiduYunGuanJia"} + +# https://pcs.baidu.com/rest/2.0/pcs/manage?method=listhost -> baidu cdn +# uses CDN_DOMAIN/monitor.jpg to test speed for each CDN +api_template = 'http://%s/api/{0}' % BAIDUPAN_SERVER + + +class LoginFailed(Exception): + + """因为帐号原因引起的登录失败异常 + 如果是超时则是返回Timeout的异常 + """ + pass + +# experimental + + +class CancelledError(Exception): + + """ + 用户取消文件上传 + """ + + def __init__(self, msg): + self.msg = msg + Exception.__init__(self, msg) + + def __str__(self): + return self.msg + + __repr__ = __str__ + + +class BufferReader(MultipartEncoder): + + """将multipart-formdata转化为stream形式的Proxy类 + """ + + def __init__(self, fields, boundary=None, callback=None, cb_args=(), cb_kwargs={}): + self._callback = callback + self._progress = 0 + self._cb_args = cb_args + self._cb_kwargs = cb_kwargs + super(BufferReader, self).__init__(fields, boundary) + + def read(self, size=None): + chunk = super(BufferReader, self).read(size) + self._progress += int(len(chunk)) + self._cb_kwargs.update({ + 'size': self._len, + 'progress': self._progress + }) + if self._callback: + try: + self._callback(*self._cb_args, **self._cb_kwargs) + except: # catches exception from the callback + raise CancelledError('The upload was cancelled.') + return chunk + + +def check_login(func): + """检查用户登录状态 + 这是pcs的检查方法 + """ + @wraps(func) + def wrapper(*args, **kwargs): + ret = func(*args, **kwargs) + if type(ret) == requests.Response: + try: + foo = json.loads(ret.content) + if foo.has_key('errno') and foo['errno'] == -6: + logging.debug( + 'Offline, deleting cookies file then relogin.') + path = '.{0}.cookies'.format(args[0].username) + if os.path.exists(path): + os.remove(path) + args[0]._initiate() + except: + pass + return ret + return wrapper + + +class BaseClass(object): + + """提供PCS类的基本方法 + """ + + def __init__(self, username, password, api_template=api_template, captcha_func=None): + self.session = requests.session() + self.api_template = api_template + self.username = username + self.password = password + self.user = {} + self.progress_func = None + if captcha_func: + self.captcha_func = captcha_func + else: + self.captcha_func = self.show_captcha + # 设置pcs服务器 + logging.debug('setting pcs server') + self.set_pcs_server(self.get_fastest_pcs_server()) + self._initiate() + + def get_fastest_pcs_server_test(self): + """通过测试返回最快的pcs服务器 + :returns: str -- 服务器地址 + """ + ret = requests.get( + 'https://pcs.baidu.com/rest/2.0/pcs/manage?method=listhost').content + serverlist = [server['host'] for server in json.loads(ret)['list']] + url_pattern = 'http://{0}/monitor.jpg' + time_record = [] + for server in serverlist: + start = time.time() * 1000 + requests.get(url_pattern.format(server)) + end = time.time() * 1000 + time_record.append((end - start, server)) + logging.info('TEST %s %s ms' % (server, int(end - start))) + return min(time_record)[1] + + def get_fastest_pcs_server(self): + """通过百度返回设置最快的pcs服务器 + """ + url = 'http://pcs.baidu.com/rest/2.0/pcs/file?app_id=250528&method=locateupload' + ret = requests.get(url).content + foo = json.loads(ret) + return foo['host'] + + def set_pcs_server(self, server): + """手动设置百度pcs服务器 + :params server: 服务器地址或域名 + + .. warning:: + 不要加 http:// 和末尾的 / + """ + global BAIDUPCS_SERVER + BAIDUPCS_SERVER = server + + def _remove_empty_items(self, data): + for k, v in data.copy().items(): + if v is None: + data.pop(k) + + def user_info(self, **kwargs): + params = { + 'method': "query", + 'reminder': "1", + } + + url = 'https://pan.baidu.com/rest/2.0/membership/user' + return self._request('membership/user', 'user', url=url, extra_params=params, **kwargs) + + def _initiate(self): + if not self._load_cookies(): + self.session.get('http://www.baidu.com') + self.user['token'] = self._get_token() + self._login() + else: + self.user['token'] = self._get_token() + + def _save_cookies(self): + cookies_file = '.{0}.cookies'.format(self.username) + with open(cookies_file, 'w') as f: + pickle.dump( + requests.utils.dict_from_cookiejar(self.session.cookies), f) + + def _load_cookies(self): + cookies_file = '.{0}.cookies'.format(self.username) + logging.debug('cookies file:' + cookies_file) + if os.path.exists(cookies_file): + logging.debug('%s cookies file has already existed.' % + self.username) + with open(cookies_file) as cookies_file: + cookies = requests.utils.cookiejar_from_dict( + pickle.load(cookies_file)) + logging.debug(str(cookies)) + self.session.cookies = cookies + self.user['BDUSS'] = self.session.cookies['BDUSS'] + return True + else: + return False + + def _get_token(self): + # Token + ret = self.session.get( + 'https://passport.baidu.com/v2/api/?getapi&tpl=mn&apiver=v3&class=login&tt=%s&logintype=dialogLogin&callback=0' % int(time.time())).text.replace('\'', '\"') + foo = json.loads(ret) + logging.info('token %s' % foo['data']['token']) + return foo['data']['token'] + + def _get_captcha(self, code_string): + # Captcha + if code_string: + verify_code = self.captcha_func("https://passport.baidu.com/cgi-bin/genimage?" + code_string) + else: + verify_code = "" + + return verify_code + + def show_captcha(self, url_verify_code): + print(url_verify_code) + verify_code = raw_input('open url aboved with your web browser, then input verify code > ') + + return verify_code + + def _get_publickey(self): + url = 'https://passport.baidu.com/v2/getpublickey?token=' + \ + self.user['token'] + content = self.session.get(url).content + jdata = json.loads(content.replace('\'','"')) + return (jdata['pubkey'], jdata['key']) + + def _login(self): + # Login + #code_string, captcha = self._get_captcha() + captcha = '' + code_string = '' + pubkey, rsakey = self._get_publickey() + key = rsa.PublicKey.load_pkcs1_openssl_pem(pubkey) + password_rsaed = base64.b64encode(rsa.encrypt(self.password, key)) + while True: + login_data = {'staticpage': 'http://www.baidu.com/cache/user/html/v3Jump.html', + 'charset': 'UTF-8', + 'token': self.user['token'], + 'tpl': 'pp', + 'subpro': '', + 'apiver': 'v3', + 'tt': str(int(time.time())), + 'codestring': code_string, + 'isPhone': 'false', + 'safeflg': '0', + 'u': 'https://passport.baidu.com/', + 'quick_user': '0', + 'logLoginType': 'pc_loginBasic', + 'loginmerge': 'true', + 'logintype': 'basicLogin', + 'username': self.username, + 'password': password_rsaed, + 'verifycode': captcha, + 'mem_pass': 'on', + 'rsakey': str(rsakey), + 'crypttype': 12, + 'ppui_logintime': '50918', + 'callback': 'parent.bd__pcbs__oa36qm'} + result = self.session.post( + 'https://passport.baidu.com/v2/api/?login', data=login_data) + + # 是否需要验证码 + if 'err_no=257' in result.content or 'err_no=6' in result.content: + code_string = re.findall('codeString=(.*?)&', result.content)[0] + logging.debug('need captcha, codeString=' + code_string) + captcha = self._get_captcha(code_string) + continue + + break + + # check exception + self._check_account_exception(result.content) + + if not result.ok: + raise LoginFailed('Logging failed.') + logging.info('COOKIES' + str(self.session.cookies)) + try: + self.user['BDUSS'] = self.session.cookies['BDUSS'] + except: + raise LoginFailed('Logging failed.') + logging.info('user %s Logged in BDUSS: %s' % + (self.username, self.user['BDUSS'])) + + self.user_info() + self._save_cookies() + + def _check_account_exception(self, content): + err_id = re.findall('err_no=([\d]+)', content)[0] + + if err_id == '0': + return + error_message = { + '-1':'系统错误, 请稍后重试', + '1':'您输入的帐号格式不正确', + '3':'验证码不存在或已过期,请重新输入', + '4': '您输入的帐号或密码有误', + '5': '请在弹出的窗口操作,或重新登录', + '6':'验证码输入错误', + '16': '您的帐号因安全问题已被限制登录', + '257': '需要验证码', + '100005': '系统错误, 请稍后重试', + '120016': '未知错误 120016', + '120019': '近期登录次数过多, 请先通过 passport.baidu.com 解除锁定', + '120021': '登录失败,请在弹出的窗口操作,或重新登录', + '500010': '登录过于频繁,请24小时后再试', + '400031': '账号异常,请在当前网络环境下在百度网页端正常登录一次', + '401007': '您的手机号关联了其他帐号,请选择登录'} + try: + msg = error_message[err_id] + except: + msg = 'unknown err_id=' + err_id + raise LoginFailed(msg) + + def _params_utf8(self, params): + for k, v in params.items(): + if isinstance(v, unicode): + params[k] = v.encode('utf-8') + + @check_login + def _request(self, uri, method=None, url=None, extra_params=None, + data=None, files=None, callback=None, **kwargs): + params = { + 'method': method, + 'app_id': "250528", + 'BDUSS': self.user['BDUSS'], + 't': str(int(time.time())), + 'bdstoken': self.user['token'] + } + if extra_params: + params.update(extra_params) + self._remove_empty_items(params) + + headers = dict(BAIDUPAN_HEADERS) + if 'headers' in kwargs: + headers.update(kwargs['headers']) + kwargs.pop('headers') + + self._params_utf8(params) + if not url: + url = self.api_template.format(uri) + if data or files: + + if '?' in url: + api = "%s&%s" % (url, urlencode(params)) + else: + api = '%s?%s' % (url, urlencode(params)) + + # print params + if data: + self._remove_empty_items(data) + response = self.session.post(api, data=data, verify=False, + headers=headers, **kwargs) + else: + self._remove_empty_items(files) + + body = BufferReader(files, callback=callback) + headers.update({ + "Content-Type": body.content_type + } + ) + + response = self.session.post( + api, data=body, verify=False, headers=headers, **kwargs) + else: + api = url + if uri == 'filemanager' or uri == 'rapidupload' or uri == 'filemetas' or uri == 'precreate': + response = self.session.post( + api, params=params, verify=False, headers=headers, **kwargs) + else: + response = self.session.get( + api, params=params, verify=False, headers=headers, **kwargs) + return response + + +class PCS(BaseClass): + + def __init__(self, username, password, captcha_callback=None): + """ + :param username: 百度网盘的用户名 + :type username: str + + :param password: 百度网盘的密码 + :type password: str + + :param captcha_callback: 验证码的回调函数 + + .. note:: + 该函数会获得一个jpeg文件的内容,返回值需为验证码 + """ + super(PCS, self).__init__(username, password, api_template, captcha_func=captcha_callback) + + def __err_handler(self, act, errno, callback=None, args=(), kwargs={}): + """百度网盘下载错误控制 + :param act: 出错时的行为, 有 download + :param errno: 出错时的errno,这个要配合act才有实际意义 + :param callback: 返回时的调用函数, 为空时返回None + :param args: 给callback函数的参数tuple + :param kwargs: 给callback函数的带名参数字典 + + 在本函数调用后一定可以解决提交过来的问题, 在外部不需要重复检查是否存在原问题 + """ + errno = int(errno) + + def err_handler_download(): + if errno == 112: + # 页面失效, 重新刷新页面 + url = 'http://pan.baidu.com/disk/home' + self.session.get(url) + + return + + def err_handler_upload(): + # 实际出问题了再写 + return + + def err_handler_generic(): + return + + _act = {'download': err_handler_download, + 'upload': err_handler_upload, + 'generic': err_handler_generic + } + + if act not in _act: + raise Exception('行为未定义, 无法处理该行为的错误') + + if callback: + return callback(*args, **kwargs) + return None + + def quota(self, **kwargs): + """获得配额信息 + :return requests.Response + + .. note:: + 返回正确时返回的 Reponse 对象 content 中的数据结构 + + {"errno":0,"total":配额字节数,"used":已使用字节数,"request_id":请求识别号} + """ + return self._request('quota', **kwargs) + + def upload(self, dir, file_handler, filename, ondup="newcopy", callback=None, **kwargs): + """上传单个文件(<2G). + + | 百度PCS服务目前支持最大2G的单个文件上传。 + | 如需支持超大文件(>2G)的断点续传,请参考下面的“分片文件上传”方法。 + + :param dir: 网盘中文件的保存路径(不包含文件名)。 + 必须以 / 开头。 + + .. warning:: + * 注意本接口的 dir 参数不包含文件名,只包含路径 + * 路径长度限制为1000; + * 径中不能包含以下字符:``\\\\ ? | " > < : *``; + * 文件名或路径名开头结尾不能是 ``.`` + 或空白字符,空白字符包括: + ``\\r, \\n, \\t, 空格, \\0, \\x0B`` 。 + :param file_handler: 上传文件对象 。(e.g. ``open('foobar', 'rb')`` ) + + .. warning:: + 注意不要使用 .read() 方法. + :type file_handler: file + :param callback: 上传进度回调函数 + 需要包含 size 和 progress 名字的参数 + + :param filename: + + :param ondup: (可选) + + * 'overwrite':表示覆盖同名文件; + * 'newcopy':表示生成文件副本并进行重命名,命名规则为“ + 文件名_日期.后缀”。 + :return: requests.Response 对象 + + .. note:: + 返回正确时返回的 Reponse 对象 content 中的数据结构 + + {"path":"服务器文件路径","size":文件大小,"ctime":创建时间,"mtime":修改时间,"md5":"文件md5值","fs_id":服务器文件识别号,"isdir":是否为目录,"request_id":请求识别号} + + """ + + params = { + 'dir': dir, + 'ondup': ondup, + 'filename': filename + } + + tmp_filename = ''.join(random.sample(string.ascii_letters, 10)) + files = {'file': (tmp_filename, file_handler)} + + url = 'https://{0}/rest/2.0/pcs/file'.format(BAIDUPCS_SERVER) + return self._request('file', 'upload', url=url, extra_params=params, + files=files, callback=callback, **kwargs) + + def upload_tmpfile(self, file_handler, callback=None, **kwargs): + """分片上传—文件分片及上传. + + 百度 PCS 服务支持每次直接上传最大2G的单个文件。 + + 如需支持上传超大文件(>2G),则可以通过组合调用分片文件上传的 + ``upload_tmpfile`` 方法和 ``upload_superfile`` 方法实现: + + 1. 首先,将超大文件分割为2G以内的单文件,并调用 ``upload_tmpfile`` + 将分片文件依次上传; + 2. 其次,调用 ``upload_superfile`` ,完成分片文件的重组。 + + 除此之外,如果应用中需要支持断点续传的功能, + 也可以通过分片上传文件并调用 ``upload_superfile`` 接口的方式实现。 + + :param file_handler: 上传文件对象 。(e.g. ``open('foobar', 'rb')`` ) + + .. warning:: + 注意不要使用 .read() 方法. + :type file_handler: file + + :param callback: 上传进度回调函数 + 需要包含 size 和 progress 名字的参数 + + :param ondup: (可选) + + * 'overwrite':表示覆盖同名文件; + * 'newcopy':表示生成文件副本并进行重命名,命名规则为“ + 文件名_日期.后缀”。 + :type ondup: str + + :return: requests.Response + + .. note:: + 这个对象的内容中的 md5 字段为合并文件的凭依 + + .. note:: + 返回正确时返回的 Reponse 对象 content 中的数据结构 + + {"md5":"片段的 md5 值","request_id":请求识别号} + + + + """ + + params = { + 'type': 'tmpfile' + } + files = {'file': (str(int(time.time())), file_handler)} + url = 'https://{0}/rest/2.0/pcs/file'.format(BAIDUPCS_SERVER) + return self._request('file', 'upload', url=url, extra_params=params, callback=callback, + files=files, **kwargs) + + def upload_superfile(self, remote_path, block_list, ondup="newcopy", **kwargs): + """分片上传—合并分片文件. + + 与分片文件上传的 ``upload_tmpfile`` 方法配合使用, + 可实现超大文件(>2G)上传,同时也可用于断点续传的场景。 + + :param remote_path: 网盘中文件的保存路径(包含文件名)。 + 必须以 开头。 + + .. warning:: + * 路径长度限制为1000; + * 径中不能包含以下字符:``\\\\ ? | " > < : *``; + * 文件名或路径名开头结尾不能是 ``.`` + 或空白字符,空白字符包括: + ``\\r, \\n, \\t, 空格, \\0, \\x0B`` 。 + :param block_list: 子文件内容的 MD5 值列表;子文件至少两个,最多1024个。 + :type block_list: list + :param ondup: (可选) + + * 'overwrite':表示覆盖同名文件; + * 'newcopy':表示生成文件副本并进行重命名,命名规则为“ + 文件名_日期.后缀”。 + :return: Response 对象 + + .. note:: + 返回正确时返回的 Reponse 对象 content 中的数据结构 + + {"path":"服务器文件路径","size":文件大小,"ctime":创建时间,"mtime":修改时间,"md5":"文件md5值","fs_id":服务器文件识别号,"isdir":是否为目录,"request_id":请求识别号} + + """ + + params = { + 'path': remote_path, + 'ondup': ondup + } + data = { + 'param': json.dumps({'block_list': block_list}), + } + url = 'https://{0}/rest/2.0/pcs/file'.format(BAIDUPCS_SERVER) + return self._request('file', 'createsuperfile', url=url, extra_params=params, + data=data, **kwargs) + + def get_sign(self): + # refered: + # https://github.com/PeterDing/iScript/blob/master/pan.baidu.com.py + url = 'http://pan.baidu.com/disk/home' + r = self.session.get(url) + html = r.content + sign1 = re.search(r'"sign1":"([A-Za-z0-9]+)"', html).group(1) + sign3 = re.search(r'"sign3":"([A-Za-z0-9]+)"', html).group(1) + timestamp = re.search(r'"timestamp":([0-9]+)[^0-9]', html).group(1) + + def sign2(j, r): + a = [] + p = [] + o = '' + v = len(j) + + for q in xrange(256): + a.append(ord(j[q % v])) + p.append(q) + + u = 0 + for q in xrange(256): + u = (u + p[q] + a[q]) % 256 + t = p[q] + p[q] = p[u] + p[u] = t + + i = 0 + u = 0 + for q in xrange(len(r)): + i = (i + 1) % 256 + u = (u + p[i]) % 256 + t = p[i] + p[i] = p[u] + p[u] = t + k = p[((p[i] + p[u]) % 256)] + o += chr(ord(r[q]) ^ k) + + return base64.b64encode(o) + + self.dsign = sign2(sign3, sign1) + self.timestamp = timestamp + + def _locatedownload(self, remote_path, **kwargs): + """百度云管家获得方式 + :param remote_path: 需要下载的文件路径 + :type remote_path: str + """ + params = { + 'path': remote_path + } + url = 'https://{0}/rest/2.0/pcs/file'.format(BAIDUPCS_SERVER) + return self._request('file', 'locatedownload', url=url, + extra_params=params, **kwargs) + + def _yunguanjia_format(self, remote_path, **kwargs): + ret = self._locatedownload(remote_path, **kwargs).content + data = json.loads(ret) + return 'http://' + data['host'] + data['path'] + + def download_url(self, remote_path, **kwargs): + """返回目标文件可用的下载地址 + :param remote_path: 每一项代表需要下载的文件路径 + :type remote_path: str list + """ + + def get_url(dlink): + return self.session.get(dlink, + headers=BAIDUPAN_HEADERS, + stream=True).url + + if not hasattr(self, 'dsign'): + self.get_sign() + + if isinstance(remote_path, str) or isinstance(remote_path, unicode): + remote_path = [remote_path] + + file_list = [] + jdata = json.loads(self.meta(remote_path).content) + if jdata['errno'] != 0: + jdata = self.__err_handler('generic', jdata['errno'], + self.meta, + args=(remote_path,) + ) + logging.debug('[*]' + str(jdata)) + for i, entry in enumerate(jdata['info']): + url = entry['dlink'] + foo = get_url(url) + if 'wenxintishi' in foo: + file_list.append(self._yunguanjia_format(remote_path[i])) + else: + file_list.append(get_url(entry['dlink'])) + + return file_list + + def save_album_file(self, album_id, from_uk, save_path, fsid_list): + data = { + "from_uk": from_uk, + "album_id": album_id, + "to_path": save_path, + "fsid_list": fsid_list} + url = "http://pan.baidu.com/pcloud/album/transfertask/create" + print (self._request(None, data=data, url=url).content) + + def _verify_shared_file(self, shareid, uk, password): + data = { + "pwd": password, + "vcode": "", + "vcode_str": "", + "shareid": shareid, + "uk": uk + } + url = "http://pan.baidu.com/share/verify?shareid="+shareid+"&uk="+uk + return json.loads(self._request(None, data=data, url=url).content) + + def _save_shared_file_list(self, shareid, uk, path, file_list): + url = "http://pan.baidu.com/share/transfer?shareid="+shareid+"&from="+uk + data = { + "filelist": json.dumps(file_list), + "path": path + } + return json.loads(self._request(None, url=url, data=data).content) + + def save_share_list(self, url, path, password=None, filter_callback=None): + """ 保存分享文件列表到自己的网盘, 支持密码, 支持文件过滤的回调函数 + :param url: 分享的url + :type url: str + + :param path 保存到自己网盘的位置 + :type path: str + + :param password 分享密码, 如果没有分享资源没有密码则不用填 + :type password: str + + :param filter_callback 过滤文件列表中文件的回调函数, filter(file), 返回值是假值则被过滤掉 + file = { + "filename": "xxx", + "size": 1234, + "isdir": 0 + } + :return + { + "error": 0, # 无错误为0, 否则出错. + "result": [] # 如果成功会返回添加到自己网盘的文件列表 + } + + context是从分享页面的html中提取的json, 里面保存了分享文件列表 + 暂时有用的是file_list, uk, shareid + context = { + "typicalPath": "\/\u65b0\u5efa\u6587\u4ef6\u5939(1)\/[SumiSora][Yosuga_no_Sora][BDRip][BIG5][720P]", + "self": false, + "username": "", + "photo": "http:\/\/himg.bdimg.com\/sys\/portrait\/item\/0237bb1b.jpg", + "uk": 924798052, + "ctime": 1455779404, + "flag": 2, + "linkusername": "cls1010123", + "vCnt": 118442, + "tCnt": 27916, + "dCnt": 12006, + "file_list": { + "errno": 0, + "list": [{ + "fs_id": 882212291049391, + "app_id": "250528", + "parent_path": "%2F%E6%96%B0%E5%BB%BA%E6%96%87%E4%BB%B6%E5%A4%B9%281%29", + "server_filename": "[SumiSora][Yosuga_no_Sora][BDRip][BIG5][720P]", + "size": 0, + "server_mtime": 1455779174, + "server_ctime": 1455779174, + "local_mtime": 1455779174, + "local_ctime": 1455779174, + "isdir": 1, + "isdelete": "0", + "status": "0", + "category": 6, + "share": "0", + "path_md5": "18281300157632491061", + "delete_fs_id": "0", + "extent_int3": "0", + "extent_tinyint1": "0", + "extent_tinyint2": "0", + "extent_tinyint3": "0", + "extent_tinyint4": "0", + "path": "\/\u65b0\u5efa\u6587\u4ef6\u5939(1)\/[SumiSora][Yosuga_no_Sora][BDRip][BIG5][720P]", + "root_ns": 465254146, + "md5": "", + "file_key": "" + }] + }, + "loginstate": 0, + "channel": 4, + "third_url": 0, + "bdstoken": null , + "sampling": { + "expvar": ["chengyong"] + }, + "is_vip": 0, + "description": "", + "shorturl": "1skhBegP", + "shareinfo": "", + "is_baiduspider": 0, + "isinwhitelist": 0, + "public": 0, + "shareid": 23915657, + "bj_unicom": 0, + "visitor_uk": null , + "visitor_avatar": null , + "timestamp": 1458198232, + "sign": "xxxx", + "sekey": "xxxx", + "novelid": false, + "is_master_vip": 0, + "urlparam": [], + "XDUSS": "null" + } + """ + # 这里无论是短链接还是长链接如果带密码, 则都被重定向到长链接, 可以直接取出shareid, uk + # 而如果是不带密码的分享, 则此时还不需要shareid,uk + respond = self._request(None, url=url) + + target_url = respond.url + shareid, uk = None, None + m = re.search(r"shareid=(\d+)", target_url) + if m: + shareid = m.group(1) + m = re.search(r"uk=(\d+)", target_url) + if m: + uk = m.group(1) + + # 检查验证码, 如果成功, 当前用户就被授权直接访问资源了 + if shareid and uk and password: + verify_result = self._verify_shared_file(shareid, uk, password) + if not verify_result or verify_result['errno'] != 0: + return verify_result + + # 从html中解析文件列表, 同时把shareid, uk也解析出来 + html = self._request(None, url=target_url).content + r = re.compile(r".*_context =(.*);.*") + m = r.search(html) + if m: + context = json.loads(m.group(1)) + file_list = context['file_list']['list'] + uk = str(context['uk']) + shareid = str(context['shareid']) + ret = {"filelist": []} + for f in file_list: + file_obj = { + 'filename': f['server_filename'], + 'size': f['size'], + 'isdir': f['isdir'] + } + if not filter_callback or filter_callback(file_obj): + ret['filelist'].append(f['path']) + save_share_file_ret = self._save_shared_file_list(shareid, uk, path, ret['filelist']) + if save_share_file_ret and save_share_file_ret['errno'] == 0: + return save_share_file_ret + else: + return ret + else: + # 获取文件列表失败 + return {"errno": -1, "error_msg": "PCS.save_share_list failed, mayby url is incorrect!"} + + # Deprecated + # using download_url to get real download url + def download(self, remote_path, **kwargs): + """下载单个文件。 + + download 接口支持HTTP协议标准range定义,通过指定range的取值可以实现 + 断点下载功能。 例如:如果在request消息中指定“Range: bytes=0-99”, + 那么响应消息中会返回该文件的前100个字节的内容; + 继续指定“Range: bytes=100-199”, + 那么响应消息中会返回该文件的第二个100字节内容:: + + >>> headers = {'Range': 'bytes=0-99'} + >>> pcs = PCS('username','password') + >>> pcs.download('/test_sdk/test.txt', headers=headers) + + :param remote_path: 网盘中文件的路径(包含文件名)。 + 必须以 / 开头。 + + .. warning:: + * 路径长度限制为1000; + * 径中不能包含以下字符:``\\\\ ? | " > < : *``; + * 文件名或路径名开头结尾不能是 ``.`` + 或空白字符,空白字符包括: + ``\\r, \\n, \\t, 空格, \\0, \\x0B`` 。 + :return: requests.Response 对象 + """ + + params = { + 'path': remote_path, + } + url = 'https://{0}/rest/2.0/pcs/file'.format(BAIDUPCS_SERVER) + return self._request('file', 'download', url=url, + extra_params=params, **kwargs) + + def get_streaming(self, path, stype="M3U8_AUTO_480", **kwargs): + """获得视频的m3u8列表 + + :param path: 视频文件路径 + :param type: 返回stream类型, 已知有``M3U8_AUTO_240``/``M3U8_AUTO_480``/``M3U8_AUTO_720`` + + .. warning:: + M3U8_AUTO_240会有问题, 目前480P是最稳定的, 也是百度网盘默认的 + :return: str 播放(列表)需要的信息 + """ + + params = { + 'path': path, + 'type': stype + } + url = 'https://{0}/rest/2.0/pcs/file'.format(BAIDUPCS_SERVER) + while True: + ret = self._request('file', 'streaming', url=url, extra_params=params, **kwargs) + if not ret.ok: + logging.debug('get_streaming ret_status_code %s' % ret.status_code) + jdata = json.loads(ret.content) + if jdata['error_code'] == 31345: + # 再试一次 + continue + elif jdata['error_code'] == 31066: + # 文件不存在 + return 31066 + elif jdata['error_code'] == 31304: + # 文件类型不支持 + return 31304 + elif jdata['error_code'] == 31023: + # params error + return 31023 + return ret.content + + def mkdir(self, remote_path, **kwargs): + """为当前用户创建一个目录. + + :param remote_path: 网盘中目录的路径,必须以 / 开头。 + + .. warning:: + * 路径长度限制为1000; + * 径中不能包含以下字符:``\\\\ ? | " > < : *``; + * 文件名或路径名开头结尾不能是 ``.`` + 或空白字符,空白字符包括: + ``\\r, \\n, \\t, 空格, \\0, \\x0B`` 。 + :return: Response 对象 + + .. note:: + 返回正确时返回的 Reponse 对象 content 中的数据结构 + + {"fs_id":服务器文件识别号,"path":"路径","ctime":创建时间,"mtime":修改时间,"status":0,"isdir":1,"errno":0,"name":"文件路径"} + + """ + + data = { + 'path': remote_path, + 'isdir': "1", + "size": "", + "block_list": "[]" + } + # 奇怪的是创建新目录的method是post + return self._request('create', 'post', data=data, **kwargs) + + def list_files(self, remote_path, by="name", order="desc", + limit=None, **kwargs): + """获取目录下的文件列表. + + :param remote_path: 网盘中目录的路径,必须以 / 开头。 + + .. warning:: + * 路径长度限制为1000; + * 径中不能包含以下字符:``\\\\ ? | " > < : *``; + * 文件名或路径名开头结尾不能是 ``.`` + 或空白字符,空白字符包括: + ``\\r, \\n, \\t, 空格, \\0, \\x0B`` 。 + :param by: 排序字段,缺省根据文件类型排序: + + * time(修改时间) + * name(文件名) + * size(大小,注意目录无大小) + :param order: “asc”或“desc”,缺省采用降序排序。 + + * asc(升序) + * desc(降序) + :param limit: 返回条目控制,参数格式为:n1-n2。 + + 返回结果集的[n1, n2)之间的条目,缺省返回所有条目; + n1从0开始。 + :return: requests.Response 对象 + + .. note:: + 返回正确时返回的 Reponse 对象 content 中的数据结构 + + { + "errno":0, + "list":[ + {"fs_id":服务器文件识别号"path":"路径","server_filename":"服务器文件名(不汗含路径)","size":文件大小,"server_mtime":服务器修改时间,"server_ctime":服务器创建时间,"local_mtime":本地修改时间,"local_ctime":本地创建时间,"isdir":是否是目录,"category":类型,"md5":"md5值"}……等等 + ], + "request_id":请求识别号 + } + + """ + if order == "desc": + desc = "1" + else: + desc = "0" + + params = { + 'dir': remote_path, + 'order': by, + 'desc': desc + } + return self._request('list', 'list', extra_params=params, **kwargs) + + def move(self, path_list, dest, **kwargs): + """ + 移动文件或文件夹 + + :param path_list: 在百度盘上要移动的源文件path + :type path_list: list + + :param dest: 要移动到的目录 + :type dest: str + + """ + def __path(path): + if path.endswith('/'): + return path.split('/')[-2] + else: + return os.path.basename(path) + params = { + 'opera': 'move' + } + data = { + 'filelist': json.dumps([{ + "path": path, + "dest": dest, + "newname": __path(path)} for path in path_list]), + } + url = 'http://{0}/api/filemanager'.format(BAIDUPAN_SERVER) + return self._request('filemanager', 'move', url=url, data=data, extra_params=params, **kwargs) + + def rename(self, rename_pair_list, **kwargs): + """重命名 + + :param rename_pair_list: 需要重命名的文件(夹)pair (路径,新名称)列表,如[('/aa.txt','bb.txt')] + :type rename_pair_list: list + + """ + foo = [] + for path, newname in rename_pair_list: + foo.append({'path': path, + 'newname': newname + }) + + data = {'filelist': json.dumps(foo)} + params = { + 'opera': 'rename' + } + + url = 'http://{0}/api/filemanager'.format(BAIDUPAN_SERVER) + print('请求url', url) + logging.debug('rename ' + str(data) + 'URL:' + url) + return self._request('filemanager', 'rename', url=url, data=data, extra_params=params, **kwargs) + + def copy(self, path_list, dest, **kwargs): + """ + 复制文件或文件夹 + + :param path_list: 在百度盘上要复制的源文件path + :type path_list: list + + :param dest: 要复制到的目录 + :type dest: str + + """ + def __path(path): + if path.endswith('/'): + return path.split('/')[-2] + else: + return os.path.basename(path) + params = { + 'opera': 'copy' + } + data = { + 'filelist': json.dumps([{ + "path": path, + "dest": dest, + "newname": __path(path)} for path in path_list]), + } + url = 'http://{0}/api/filemanager'.format(BAIDUPAN_SERVER) + return self._request('filemanager', 'move', url=url, data=data, extra_params=params, **kwargs) + + def delete(self, path_list, **kwargs): + """ + 删除文件或文件夹 + + :param path_list: 待删除的文件或文件夹列表,每一项为服务器路径 + :type path_list: list + + + """ + data = { + 'filelist': json.dumps([path for path in path_list]) + } + url = 'http://{0}/api/filemanager?opera=delete'.format(BAIDUPAN_SERVER) + return self._request('filemanager', 'delete', url=url, data=data, **kwargs) + + def share(self, file_ids, pwd=None, **kwargs): + """ + 创建一个文件的分享链接 + + :param file_ids: 要分享的文件fid列表 + :type path_list: list + + :param pwd: 分享密码,没有则没有密码 + :type pwd: str + + :return: requests.Response 对象 + + .. note:: + 返回正确 + { + "errno": 0, + + "request_id": 请求识别号, + + "shareid": 分享识别号, + + "link": "分享地址", + + "shorturl": "段网址", + + "ctime": 创建时间, + + "premis": false + } + + """ + if pwd: + data = { + 'fid_list': json.dumps([int(fid) for fid in file_ids]), + 'pwd': pwd, + 'schannel': 4, + 'channel_list': json.dumps([]) + } + else: + data = { + 'fid_list': json.dumps([int(fid) for fid in file_ids]), + 'schannel': 0, + 'channel_list': json.dumps([]) + } + url = 'http://pan.baidu.com/share/set' + return self._request('share/set', '', url=url, data=data, **kwargs) + + def list_streams(self, file_type, start=0, limit=1000, order='time', desc='1', + filter_path=None, **kwargs): + """以视频、音频、图片及文档四种类型的视图获取所创建应用程序下的 + 文件列表. + + :param file_type: 类型分为video audio image doc other exe torrent + :param start: 返回条目控制起始值,缺省值为0。 + :param limit: 返回条目控制长度,缺省为1000,可配置。 + :param filter_path: 需要过滤的前缀路径,如:/album + + .. warning:: + * 路径长度限制为1000; + * 径中不能包含以下字符:``\\\\ ? | " > < : *``; + * 文件名或路径名开头结尾不能是 ``.`` + 或空白字符,空白字符包括: + ``\\r, \\n, \\t, 空格, \\0, \\x0B`` 。 + :return: requests.Response 对象, 结构和 list_files 相同 + """ + if file_type == 'doc': + file_type = '4' + elif file_type == 'video': + file_type = '1' + elif file_type == 'image': + file_type = '3' + elif file_type == 'torrent': + file_type = '7' + elif file_type == 'other': + file_type = '6' + elif file_type == 'audio': + file_type = '2' + elif file_type == 'exe': + file_type = '5' + + params = { + 'category': file_type, + 'pri': '-1', + 'start': start, + 'num': limit, + 'order': order, + 'desc': desc, + 'filter_path': filter_path, + } + url = 'http://pan.baidu.com/api/categorylist' + return self._request('categorylist', 'list', url=url, extra_params=params, + **kwargs) + + def add_download_task(self, source_url, remote_path, selected_idx=(), **kwargs): + """ + 添加离线任务,支持所有百度网盘支持的类型 + """ + if source_url.startswith('magnet:?'): + print('Magnet: "%s"' % source_url) + return self.add_magnet_task(source_url, remote_path, selected_idx, **kwargs) + elif source_url.endswith('.torrent'): + print('BitTorrent: "%s"' % source_url) + return self.add_torrent_task(source_url, remote_path, selected_idx, **kwargs) + else: + print('Others: "%s"' % source_url) + data = { + 'method': 'add_task', + 'source_url': source_url, + 'save_path': remote_path, + } + url = 'http://{0}/rest/2.0/services/cloud_dl'.format(BAIDUPAN_SERVER) + return self._request('services/cloud_dl', 'add_task', url=url, + data=data, **kwargs) + + def add_torrent_task(self, torrent_path, save_path='/', selected_idx=(), **kwargs): + """ + 添加本地BT任务 + + :param torrent_path: 本地种子的路径 + + :param save_path: 远程保存路径 + + :param selected_idx: 要下载的文件序号 —— 集合为空下载所有,非空集合指定序号集合,空串下载默认 + + :return: requests.Response + + .. note:: + 返回正确时返回的 Reponse 对象 content 中的数据结构 + + {"task_id":任务编号,"rapid_download":是否已经完成(急速下载),"request_id":请求识别号} + + """ + + # 上传种子文件 + torrent_handler = open(torrent_path, 'rb') + basename = os.path.basename(torrent_path) + + # 清理同名文件 + self.delete(['/' + basename]) + + response = self.upload('/', torrent_handler, basename).json() + remote_path = response['path'] + logging.debug('REMOTE PATH:' + remote_path) + + # 获取种子信息 + response = self._get_torrent_info(remote_path).json() + if response.get('error_code'): + print(response.get('error_code')) + return + if not response['torrent_info']['file_info']: + return + + # 要下载的文件序号:集合为空下载所有,非空集合指定序号集合,空串下载默认 + if isinstance(selected_idx, (tuple, list, set)): + if len(selected_idx) > 0: + selected_idx = ','.join(map(str, selected_idx)) + else: + selected_idx = ','.join(map(str, range(1, len(response['torrent_info']['file_info']) + 1))) + else: + selected_idx = '' + + # 开始下载 + data = { + 'file_sha1': response['torrent_info']['sha1'], + 'save_path': save_path, + 'selected_idx': selected_idx, + 'task_from': '1', + 'source_path': remote_path, + 'type': '2' # 2 is torrent file + } + url = 'http://{0}/rest/2.0/services/cloud_dl'.format(BAIDUPAN_SERVER) + return self._request('create', 'add_task', url=url, data=data, **kwargs) + + def _get_torrent_info(self, torrent_path): + data = { + 'source_path': torrent_path, + 'type': '2' # 2 is torrent + } + url = 'http://{0}/rest/2.0/services/cloud_dl'.format(BAIDUPAN_SERVER) + + return self._request('cloud_dl', 'query_sinfo', url=url, data=data, timeout=30) + + def add_magnet_task(self, magnet, remote_path, selected_idx=(), **kwargs): + response = self._get_magnet_info(magnet).json() + if response.get('error_code'): + print(response.get('error_code')) + return + if not response['magnet_info']: + return + + # 要下载的文件序号:集合为空下载所有,非空集合指定序号集合,空串下载默认 + if isinstance(selected_idx, (tuple, list, set)): + if len(selected_idx) > 0: + selected_idx = ','.join(map(str, selected_idx)) + else: + selected_idx = ','.join(map(str, range(1, len(response['magnet_info']) + 1))) + else: + selected_idx = '' + + data = { + 'source_url': magnet, + 'save_path': remote_path, + 'selected_idx': selected_idx, + 'task_from': '1', + 'type': '4' # 4 is magnet + } + url = 'http://{0}/rest/2.0/services/cloud_dl'.format(BAIDUPAN_SERVER) + + return self._request('create', 'add_task', url=url, data=data, timeout=30) + + def _get_magnet_info(self, magnet): + data = { + 'source_url': magnet, + 'save_path': '/', + 'type': '4' # 4 is magnet + } + url = 'http://{0}/rest/2.0/services/cloud_dl'.format(BAIDUPAN_SERVER) + + return self._request('cloud_dl', 'query_magnetinfo', url=url, data=data, timeout=30) + + def query_download_tasks(self, task_ids, operate_type=1, **kwargs): + """根据任务ID号,查询离线下载任务信息及进度信息。 + + :param task_ids: 要查询的任务 ID字符串 列表 + :type task_ids: list or tuple + :param operate_type: + * 0:查任务信息 + * 1:查进度信息,默认为1 + + :return: requests.Response + + .. note:: + 返回正确时返回的 Reponse 对象 content 中的数据结构 + + 给出一个范例 + + { + "task_info": + {"70970481":{ + "status":"0", + + "file_size":"122328178", + + "finished_size":"122328178", + + "create_time":"1391620757", + + "start_time":"1391620757", + + "finish_time":"1391620757", + + "save_path":"\/", + + "source_url":"\/saki-nation04gbcn.torrent", + + "task_name":"[KTXP][Saki-National][04][GB_CN][720p]", + + "od_type":"2", + + "file_list":[ + { + "file_name":"[KTXP][Saki-National][04][GB_CN][720p].mp4", + + "file_size":"122328178" + } + ], + + "result":0 + + } + }, + + "request_id":861570268 + + } + + + """ + + params = { + 'task_ids': ','.join(map(str, task_ids)), + 'op_type': operate_type, + } + url = 'http://{0}/rest/2.0/services/cloud_dl'.format(BAIDUPAN_SERVER) + return self._request('services/cloud_dl', 'query_task', url=url, + extra_params=params, **kwargs) + + def download_tasks_number(self): + """获取离线任务总数 + + :return: int + """ + ret = self.list_download_tasks().content + foo = json.loads(ret) + return foo['total'] + + def list_download_tasks(self, need_task_info="1", asc="0", start=0, create_time=None, limit=1000, status="255", source_url=None, remote_path=None, **kwargs): + """查询离线下载任务ID列表及任务信息. + + :param need_task_info: 是否需要返回任务信息: + * 0:不需要 + * 1:需要,默认为1 + :param start: 查询任务起始位置,默认为0。 + :param limit: 设定返回任务数量,默认为10。 + :param asc: + * 0:降序,默认值 + * 1:升序 + :param create_time: 任务创建时间,默认为空。 + :type create_time: int + :param status: 任务状态,默认为空。 + + .. note:: + 任务状态有 + 0:下载成功 + + 1:下载进行中 + + 2:系统错误 + + 3:资源不存在 + + 4:下载超时 + + 5:资源存在但下载失败 + + 6:存储空间不足 + + 7:目标地址数据已存在, 8:任务取消. + :type status: int + :param source_url: 源地址URL,默认为空。 + :param remote_path: 文件保存路径,默认为空。 + + .. warning:: + * 路径长度限制为1000; + * 径中不能包含以下字符:``\\\\ ? | " > < : *``; + * 文件名或路径名开头结尾不能是 ``.`` + 或空白字符,空白字符包括: + ``\\r, \\n, \\t, 空格, \\0, \\x0B`` 。 + :param expires: 请求失效时间,如果有,则会校验。 + :type expires: int + :return: Response 对象 + + .. note:: + 返回正确时返回的 Reponse 对象 content 中的数据结构 + + { + "task_info": [ + + { + + "task_id": "任务识别号", + + "od_type": "2", + + "source_url": "原地址,bt任务为种子在服务器上的路径,否则为原始URL", + + "save_path": "保存路径", + + "rate_limit": "速度限制,0为不限", + + "timeout": "0", + + "callback": "", + + "status": "任务状态", + + "create_time": "创建时间", + + "task_name": "任务名" + + },……等等 + + ], + + "total": 总数, + + "request_id": 请求识别号 + + } + """ + + params = { + 'start': start, + 'limit': limit, + 'status': status, + 'need_task_info': need_task_info, + 'asc': asc, + 'source_url': source_url, + 'remote_path': remote_path, + 'create_time': create_time + + } + url = 'http://{0}/rest/2.0/services/cloud_dl'.format(BAIDUPAN_SERVER) + return self._request('services/cloud_dl', 'list_task', url=url, extra_params=params, **kwargs) + + def cancel_download_task(self, task_id, expires=None, **kwargs): + """取消离线下载任务. + + :param task_id: 要取消的任务ID号。 + :type task_id: str + :param expires: 请求失效时间,如果有,则会校验。 + :type expires: int + :return: requests.Response + """ + + data = { + 'expires': expires, + 'task_id': task_id, + } + url = 'http://{0}/rest/2.0/services/cloud_dl'.format(BAIDUPAN_SERVER) + return self._request('services/cloud_dl', 'cancel_task', url=url, + data=data, **kwargs) + + def list_recycle_bin(self, order="time", desc="1", start=0, limit=1000, page=1, **kwargs): + # Done + """获取回收站中的文件及目录列表. + + :param start: 返回条目的起始值,缺省值为0 + :param limit: 返回条目的长度,缺省值为1000 + :return: requests.Response + + 格式同 list_files + """ + + params = { + 'start': start, + 'num': limit, + 'dir': '/', + 'order': order, + 'desc': desc + } + url = 'http://{0}/api/recycle/list'.format(BAIDUPAN_SERVER) + return self._request('recycle', 'list', url=url, extra_params=params, **kwargs) + + def restore_recycle_bin(self, fs_ids, **kwargs): + """批量还原文件或目录(非强一致接口,调用后请sleep1秒 ). + + :param fs_ids: 所还原的文件或目录在 PCS 的临时唯一标识 ID 的列表。 + :type fs_ids: list or tuple + :return: requests.Response 对象 + """ + + data = { + 'fidlist': json.dumps(fs_ids) + } + url = 'http://{0}/api/recycle/restore'.format(BAIDUPAN_SERVER) + return self._request('recycle', 'restore', data=data, **kwargs) + + def clean_recycle_bin(self, **kwargs): + """清空回收站. + + :return: requests.Response + """ + + url = 'http://{0}/api/recycle/clear'.format(BAIDUPAN_SERVER) + return self._request('recycle', 'clear', url=url, **kwargs) + + def rapidupload(self, file_handler, path, **kwargs): + """秒传一个文件 + + :param file_handler: 文件handler, e.g. open('file','rb') + :type file_handler: file + + :param path: 上传到服务器的路径,包含文件名 + :type path: str + + :return: requests.Response + + .. note:: + * 文件已在服务器上存在,不上传,返回示例 + { + + "path" : "/apps/album/1.jpg", + + "size" : 372121, + + "ctime" : 1234567890, + + "mtime" : 1234567890, + + "md5" : "cb123afcc12453543ef", + + "fs_id" : 12345, + + "isdir" : 0, + + "request_id" : 12314124 + + } + + * 文件不存在,需要上传 + + {"errno":404,"info":[],"request_id":XXX} + + * 文件大小不足 256kb (slice-md5 == content-md5) 时 + + {"errno":2,"info":[],"request_id":XXX} + + * 远程文件已存在 + + {"errno":-8,"info":[],"request_id":XXX} + + + """ + file_handler.seek(0, 2) + _BLOCK_SIZE = 2 ** 20 + content_length = file_handler.tell() + file_handler.seek(0) + + # 校验段为前 256kb + first_256bytes = file_handler.read(256 * 1024) + slice_md5 = md5(first_256bytes).hexdigest() + + content_crc32 = crc32(first_256bytes).conjugate() + content_md5 = md5(first_256bytes) + + while True: + block = file_handler.read(_BLOCK_SIZE) + if not block: + break + # 更新crc32和md5校验值 + content_crc32 = crc32(block, content_crc32).conjugate() + content_md5.update(block) + + data = {'path': path, + 'content-length': content_length, + 'content-md5': content_md5.hexdigest(), + 'slice-md5': slice_md5, + 'content-crc32': '%d' % (content_crc32.conjugate() & 0xFFFFFFFF)} + logging.debug('RAPIDUPLOAD DATA ' + str(data)) + #url = 'http://pan.baidu.com/api/rapidupload' + return self._request('rapidupload', 'rapidupload', data=data, **kwargs) + + def search(self, path, keyword, page=1, recursion=1, limit=1000, **kwargs): + """搜索文件 + + :param path: 搜索目录 + :param keyword: 关键词 + :param page: 返回第几页的数据 + :param recursion: 是否递归搜索,默认为1 (似乎0和1都没影响,都是递归搜索的) + :param limit: 每页条目 + + :return: requests.Repsonse + 返回结果和list_files一样结构 + """ + params = {'dir': path, + 'recursion': recursion, + 'key': keyword, + 'page': page, + 'num': limit} + + #url = 'http://pan.baidu.com/api/search' + + return self._request('search', 'search', extra_params=params, **kwargs) + + def thumbnail(self, path, height, width, quality=100, **kwargs): + """获取文件缩略图 + + :param path: 远程文件路径 + :param height: 缩略图高 + :param width: 缩略图宽 + :param quality: 缩略图质量,默认100 + + :return: requests.Response + + .. note:: + 如果返回 HTTP 404 说明该文件不存在缩略图形式 + """ + params = {'ec': 1, + 'path': path, + 'quality': quality, + 'width': width, + 'height': height} + + url = 'http://{0}/rest/2.0/pcs/thumbnail'.format(BAIDUPCS_SERVER) + return self._request('thumbnail', 'generate', url=url, extra_params=params, **kwargs) + + def meta(self, file_list, **kwargs): + """获得文件(s)的metainfo + + :param file_list: 文件路径列表,如 ['/aaa.txt'] + :type file_list: list + + :return: requests.Response + .. note :: + 示例 + + * 文件不存在 + + {"errno":12,"info":[{"errno":-9}],"request_id":3294861771} + + * 文件存在 + { + "errno": 0, + + "info": [ + + { + + "fs_id": 文件id, + + "path": "\/\u5c0f\u7c73\/mi2s\u5237recovery.rar", + + "server_filename": "mi2s\u5237recovery.rar", + + "size": 8292134, + + "server_mtime": 1391274570, + + "server_ctime": 1391274570, + + "local_mtime": 1391274570, + + "local_ctime": 1391274570, + + "isdir": 0, + + "category": 6, + + "path_md5": 279827390796736883, + + "delete_fs_id": 0, + + "object_key": "84221121-2193956150-1391274570512754", + + "block_list": [ + "76b469302a02b42fd0a548f1a50dd8ac" + ], + + "md5": "76b469302a02b42fd0a548f1a50dd8ac", + + "errno": 0 + + } + + ], + + "request_id": 2964868977 + + } + + """ + if not isinstance(file_list, list): + file_list = [file_list] + data = {'target': json.dumps(file_list)} + + return self._request('filemetas?blocks=0&dlink=1', 'filemetas', data=data, **kwargs) + + def check_file_blocks(self, path, size, block_list, **kwargs): + """文件块检查 + + :param path: 文件路径 + :param size: 文件大小 + :param block_list: 文件块的列表,注意按文件块顺序 + :type block_list: list + + .. note:: + 如果服务器不存在path的文件,则返回中的block_list会等于提交的block_list + + :return: requests.Response + .. note:: + 返回示例 + { + "errno": 0, + "path": "/18.rar", + "request_id": 2462633013, + "block_list": [ + "8da0ac878f3702c0768dc6ea6820d3ff", + "3c1eb99b0e64993f38cd8317788a8855" + ] + } + + 其中block_list是需要上传的块的MD5 + + + + """ + + data = {'path': path, + 'size': size, + 'isdir': 0, + 'block_list': json.dumps(block_list)} + + return self._request('precreate', 'post', data=data, **kwargs) diff --git a/dist/baidupcsapi-0.3.8-py3.5.egg b/dist/baidupcsapi-0.3.8-py3.5.egg new file mode 100644 index 0000000000000000000000000000000000000000..e0b1926ea70d79fecddc58aaa1b61c646b1aa892 GIT binary patch literal 39709 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
)eXM-h-LLF9QK$ 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%0Ab;7+Y3?ug9 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 literal 0 HcmV?d00001 From 4cf2abcfd4402a7d0a8c4777fdeb8a7563975208 Mon Sep 17 00:00:00 2001 From: liuxin Date: Thu, 22 Dec 2016 00:01:50 +0800 Subject: [PATCH 3/9] =?UTF-8?q?=E5=85=BC=E5=AE=B9python3=E6=94=B9=E5=8A=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .talkliu.cookies | 0 baidupcsapi/api.py | 26 ++++++++++++++++---------- build/lib/baidupcsapi/api.py | 26 ++++++++++++++++---------- dist/baidupcsapi-0.3.8-py3.5.egg | Bin 39709 -> 39875 bytes 4 files changed, 32 insertions(+), 20 deletions(-) create mode 100644 .talkliu.cookies diff --git a/.talkliu.cookies b/.talkliu.cookies new file mode 100644 index 0000000..e69de29 diff --git a/baidupcsapi/api.py b/baidupcsapi/api.py index cb014f2..8dd82ae 100644 --- a/baidupcsapi/api.py +++ b/baidupcsapi/api.py @@ -156,7 +156,7 @@ def get_fastest_pcs_server(self): """ url = 'http://pcs.baidu.com/rest/2.0/pcs/file?app_id=250528&method=locateupload' ret = requests.get(url).content - foo = json.loads(ret) + foo = json.loads(ret.decode()) return foo['host'] def set_pcs_server(self, server): @@ -192,20 +192,26 @@ def _initiate(self): self.user['token'] = self._get_token() def _save_cookies(self): + #liuxin 将baidukey写入cookies + cookies_file = '.{0}.cookies'.format(self.username) with open(cookies_file, 'w') as f: + print(self.session.cookies) pickle.dump( requests.utils.dict_from_cookiejar(self.session.cookies), f) def _load_cookies(self): + #读取cookies中的baidukey cookies_file = '.{0}.cookies'.format(self.username) logging.debug('cookies file:' + cookies_file) if os.path.exists(cookies_file): logging.debug('%s cookies file has already existed.' % self.username) + print(cookies_file) with open(cookies_file) as cookies_file: + print(type(cookies_file)) cookies = requests.utils.cookiejar_from_dict( - pickle.load(cookies_file)) + pickle.loads(cookies_file.read().encode("utf-8"))) logging.debug(str(cookies)) self.session.cookies = cookies self.user['BDUSS'] = self.session.cookies['BDUSS'] @@ -232,7 +238,7 @@ def _get_captcha(self, code_string): def show_captcha(self, url_verify_code): print(url_verify_code) - verify_code = raw_input('open url aboved with your web browser, then input verify code > ') + verify_code = input('open url aboved with your web browser, then input verify code > ') return verify_code @@ -240,7 +246,7 @@ def _get_publickey(self): url = 'https://passport.baidu.com/v2/getpublickey?token=' + \ self.user['token'] content = self.session.get(url).content - jdata = json.loads(content.replace('\'','"')) + jdata = json.loads(content.decode().replace('\'','"')) return (jdata['pubkey'], jdata['key']) def _login(self): @@ -250,7 +256,7 @@ def _login(self): code_string = '' pubkey, rsakey = self._get_publickey() key = rsa.PublicKey.load_pkcs1_openssl_pem(pubkey) - password_rsaed = base64.b64encode(rsa.encrypt(self.password, key)) + password_rsaed = base64.b64encode(rsa.encrypt(self.password.encode('utf-8'), key)) while True: login_data = {'staticpage': 'http://www.baidu.com/cache/user/html/v3Jump.html', 'charset': 'UTF-8', @@ -279,8 +285,8 @@ def _login(self): 'https://passport.baidu.com/v2/api/?login', data=login_data) # 是否需要验证码 - if 'err_no=257' in result.content or 'err_no=6' in result.content: - code_string = re.findall('codeString=(.*?)&', result.content)[0] + if 'err_no=257' in result.content.decode() or 'err_no=6' in result.content.decode(): + code_string = re.findall('codeString=(.*?)&', result.content.decode())[0] logging.debug('need captcha, codeString=' + code_string) captcha = self._get_captcha(code_string) continue @@ -304,7 +310,7 @@ def _login(self): self._save_cookies() def _check_account_exception(self, content): - err_id = re.findall('err_no=([\d]+)', content)[0] + err_id = re.findall('err_no=([\d]+)', content.decode())[0] if err_id == '0': return @@ -332,7 +338,7 @@ def _check_account_exception(self, content): def _params_utf8(self, params): for k, v in params.items(): - if isinstance(v, unicode): + if isinstance(v, str): params[k] = v.encode('utf-8') @check_login @@ -680,7 +686,7 @@ def get_url(dlink): if not hasattr(self, 'dsign'): self.get_sign() - if isinstance(remote_path, str) or isinstance(remote_path, unicode): + if isinstance(remote_path, bytes) or isinstance(remote_path, str): remote_path = [remote_path] file_list = [] diff --git a/build/lib/baidupcsapi/api.py b/build/lib/baidupcsapi/api.py index cb014f2..8dd82ae 100644 --- a/build/lib/baidupcsapi/api.py +++ b/build/lib/baidupcsapi/api.py @@ -156,7 +156,7 @@ def get_fastest_pcs_server(self): """ url = 'http://pcs.baidu.com/rest/2.0/pcs/file?app_id=250528&method=locateupload' ret = requests.get(url).content - foo = json.loads(ret) + foo = json.loads(ret.decode()) return foo['host'] def set_pcs_server(self, server): @@ -192,20 +192,26 @@ def _initiate(self): self.user['token'] = self._get_token() def _save_cookies(self): + #liuxin 将baidukey写入cookies + cookies_file = '.{0}.cookies'.format(self.username) with open(cookies_file, 'w') as f: + print(self.session.cookies) pickle.dump( requests.utils.dict_from_cookiejar(self.session.cookies), f) def _load_cookies(self): + #读取cookies中的baidukey cookies_file = '.{0}.cookies'.format(self.username) logging.debug('cookies file:' + cookies_file) if os.path.exists(cookies_file): logging.debug('%s cookies file has already existed.' % self.username) + print(cookies_file) with open(cookies_file) as cookies_file: + print(type(cookies_file)) cookies = requests.utils.cookiejar_from_dict( - pickle.load(cookies_file)) + pickle.loads(cookies_file.read().encode("utf-8"))) logging.debug(str(cookies)) self.session.cookies = cookies self.user['BDUSS'] = self.session.cookies['BDUSS'] @@ -232,7 +238,7 @@ def _get_captcha(self, code_string): def show_captcha(self, url_verify_code): print(url_verify_code) - verify_code = raw_input('open url aboved with your web browser, then input verify code > ') + verify_code = input('open url aboved with your web browser, then input verify code > ') return verify_code @@ -240,7 +246,7 @@ def _get_publickey(self): url = 'https://passport.baidu.com/v2/getpublickey?token=' + \ self.user['token'] content = self.session.get(url).content - jdata = json.loads(content.replace('\'','"')) + jdata = json.loads(content.decode().replace('\'','"')) return (jdata['pubkey'], jdata['key']) def _login(self): @@ -250,7 +256,7 @@ def _login(self): code_string = '' pubkey, rsakey = self._get_publickey() key = rsa.PublicKey.load_pkcs1_openssl_pem(pubkey) - password_rsaed = base64.b64encode(rsa.encrypt(self.password, key)) + password_rsaed = base64.b64encode(rsa.encrypt(self.password.encode('utf-8'), key)) while True: login_data = {'staticpage': 'http://www.baidu.com/cache/user/html/v3Jump.html', 'charset': 'UTF-8', @@ -279,8 +285,8 @@ def _login(self): 'https://passport.baidu.com/v2/api/?login', data=login_data) # 是否需要验证码 - if 'err_no=257' in result.content or 'err_no=6' in result.content: - code_string = re.findall('codeString=(.*?)&', result.content)[0] + if 'err_no=257' in result.content.decode() or 'err_no=6' in result.content.decode(): + code_string = re.findall('codeString=(.*?)&', result.content.decode())[0] logging.debug('need captcha, codeString=' + code_string) captcha = self._get_captcha(code_string) continue @@ -304,7 +310,7 @@ def _login(self): self._save_cookies() def _check_account_exception(self, content): - err_id = re.findall('err_no=([\d]+)', content)[0] + err_id = re.findall('err_no=([\d]+)', content.decode())[0] if err_id == '0': return @@ -332,7 +338,7 @@ def _check_account_exception(self, content): def _params_utf8(self, params): for k, v in params.items(): - if isinstance(v, unicode): + if isinstance(v, str): params[k] = v.encode('utf-8') @check_login @@ -680,7 +686,7 @@ def get_url(dlink): if not hasattr(self, 'dsign'): self.get_sign() - if isinstance(remote_path, str) or isinstance(remote_path, unicode): + if isinstance(remote_path, bytes) or isinstance(remote_path, str): remote_path = [remote_path] file_list = [] diff --git a/dist/baidupcsapi-0.3.8-py3.5.egg b/dist/baidupcsapi-0.3.8-py3.5.egg index e0b1926ea70d79fecddc58aaa1b61c646b1aa892..6cc81fc55861bd78a56ec3d0192f5122d9fc1fbc 100644 GIT binary patch delta 38080 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 delta 38006 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 From 68725a014d003a07b58e13e39f61bfde763041ec Mon Sep 17 00:00:00 2001 From: liuxin Date: Thu, 22 Dec 2016 00:04:01 +0800 Subject: [PATCH 4/9] =?UTF-8?q?=E5=88=A0=E9=99=A4=E6=B2=A1=E7=94=A8?= =?UTF-8?q?=E7=9A=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .talkliu.cookies | 0 dist/baidupcsapi-0.3.8-py3.5.egg | Bin 39875 -> 39875 bytes 2 files changed, 0 insertions(+), 0 deletions(-) delete mode 100644 .talkliu.cookies diff --git a/.talkliu.cookies b/.talkliu.cookies deleted file mode 100644 index e69de29..0000000 diff --git a/dist/baidupcsapi-0.3.8-py3.5.egg b/dist/baidupcsapi-0.3.8-py3.5.egg index 6cc81fc55861bd78a56ec3d0192f5122d9fc1fbc..7b0ca3eb619c764c78b29fbcc276c5802ad1ab63 100644 GIT binary patch delta 124 zcmX@So$2s)rVYpJnTr^vZ9Zx5$_Qo%I+}%m7?ZuG7J>!#P2B{RnOr3Z~U&b%W_Gvuwch=UEP5+H5x1s>v0zy#e_fF$@3z delta 124 zcmX@So$2s)rVYpJnalP~-F(vCl@ZJkbTkVAF(!LWEd&efo4N@sGr4$r99ZJY^owA6 q#f)QMx^QL`m_9c%6ilnl>ITzWX4!!0&$ArBwApO1Rg)`bdjkMt0Xv!i From f6f8726bced1e04fad825bae1d74ed2435cfe39f Mon Sep 17 00:00:00 2001 From: liuxin Date: Thu, 22 Dec 2016 09:02:40 +0800 Subject: [PATCH 5/9] =?UTF-8?q?=E5=85=BC=E5=AE=B9python3=E7=9A=84=E6=94=B9?= =?UTF-8?q?=E5=8A=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- baidupcsapi/api.py | 9 +++------ build/lib/baidupcsapi/api.py | 9 +++------ dist/baidupcsapi-0.3.8-py3.5.egg | Bin 39875 -> 39808 bytes 3 files changed, 6 insertions(+), 12 deletions(-) diff --git a/baidupcsapi/api.py b/baidupcsapi/api.py index 8dd82ae..a648626 100644 --- a/baidupcsapi/api.py +++ b/baidupcsapi/api.py @@ -195,8 +195,7 @@ def _save_cookies(self): #liuxin 将baidukey写入cookies cookies_file = '.{0}.cookies'.format(self.username) - with open(cookies_file, 'w') as f: - print(self.session.cookies) + with open(cookies_file, 'wb') as f: pickle.dump( requests.utils.dict_from_cookiejar(self.session.cookies), f) @@ -207,11 +206,9 @@ def _load_cookies(self): if os.path.exists(cookies_file): logging.debug('%s cookies file has already existed.' % self.username) - print(cookies_file) - with open(cookies_file) as cookies_file: - print(type(cookies_file)) + with open(cookies_file,'rb') as cookies_file: cookies = requests.utils.cookiejar_from_dict( - pickle.loads(cookies_file.read().encode("utf-8"))) + pickle.load(cookies_file)) logging.debug(str(cookies)) self.session.cookies = cookies self.user['BDUSS'] = self.session.cookies['BDUSS'] diff --git a/build/lib/baidupcsapi/api.py b/build/lib/baidupcsapi/api.py index 8dd82ae..a648626 100644 --- a/build/lib/baidupcsapi/api.py +++ b/build/lib/baidupcsapi/api.py @@ -195,8 +195,7 @@ def _save_cookies(self): #liuxin 将baidukey写入cookies cookies_file = '.{0}.cookies'.format(self.username) - with open(cookies_file, 'w') as f: - print(self.session.cookies) + with open(cookies_file, 'wb') as f: pickle.dump( requests.utils.dict_from_cookiejar(self.session.cookies), f) @@ -207,11 +206,9 @@ def _load_cookies(self): if os.path.exists(cookies_file): logging.debug('%s cookies file has already existed.' % self.username) - print(cookies_file) - with open(cookies_file) as cookies_file: - print(type(cookies_file)) + with open(cookies_file,'rb') as cookies_file: cookies = requests.utils.cookiejar_from_dict( - pickle.loads(cookies_file.read().encode("utf-8"))) + pickle.load(cookies_file)) logging.debug(str(cookies)) self.session.cookies = cookies self.user['BDUSS'] = self.session.cookies['BDUSS'] diff --git a/dist/baidupcsapi-0.3.8-py3.5.egg b/dist/baidupcsapi-0.3.8-py3.5.egg index 7b0ca3eb619c764c78b29fbcc276c5802ad1ab63..4a94851769791027e5db24445f67e230a75d3b65 100644 GIT binary patch delta 37936 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�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 B!`J`- delta 38010 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

  • 7kyXzW#Jy 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 z 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 Date: Thu, 22 Dec 2016 09:06:39 +0800 Subject: [PATCH 6/9] =?UTF-8?q?=E5=88=A0=E9=99=A4=E6=B2=A1=E7=94=A8?= =?UTF-8?q?=E7=9A=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- baidupcsapi.egg-info/PKG-INFO | 20 - baidupcsapi.egg-info/SOURCES.txt | 14 - baidupcsapi.egg-info/dependency_links.txt | 1 - baidupcsapi.egg-info/not-zip-safe | 1 - baidupcsapi.egg-info/requires.txt | 3 - baidupcsapi.egg-info/top_level.txt | 1 - build/lib/baidupcsapi/__init__.py | 9 - build/lib/baidupcsapi/api.py | 1801 --------------------- dist/baidupcsapi-0.3.8-py3.5.egg | Bin 39808 -> 0 bytes 9 files changed, 1850 deletions(-) delete mode 100644 baidupcsapi.egg-info/PKG-INFO delete mode 100644 baidupcsapi.egg-info/SOURCES.txt delete mode 100644 baidupcsapi.egg-info/dependency_links.txt delete mode 100644 baidupcsapi.egg-info/not-zip-safe delete mode 100644 baidupcsapi.egg-info/requires.txt delete mode 100644 baidupcsapi.egg-info/top_level.txt delete mode 100644 build/lib/baidupcsapi/__init__.py delete mode 100644 build/lib/baidupcsapi/api.py delete mode 100644 dist/baidupcsapi-0.3.8-py3.5.egg diff --git a/baidupcsapi.egg-info/PKG-INFO b/baidupcsapi.egg-info/PKG-INFO deleted file mode 100644 index b05ebf4..0000000 --- a/baidupcsapi.egg-info/PKG-INFO +++ /dev/null @@ -1,20 +0,0 @@ -Metadata-Version: 1.1 -Name: baidupcsapi -Version: 0.3.8 -Summary: 百度网盘API -Home-page: https://github.com/ly0/baidupcsapi -Author: liyangjie,mozillazg,capric8416,a1exwang -Author-email: latyas@gmail.com,mozillazg101@gmail.com -License: MIT -Download-URL: https://github.com/ly0/baidupcsapi -Description: UNKNOWN -Keywords: 百度网盘,百度云,API -Platform: UNKNOWN -Classifier: Development Status :: 5 - Production/Stable -Classifier: Intended Audience :: Developers -Classifier: License :: OSI Approved :: MIT License -Classifier: Operating System :: OS Independent -Classifier: Programming Language :: Python -Classifier: Programming Language :: Python :: 2 -Classifier: Programming Language :: Python :: 2.7 -Classifier: Topic :: Utilities diff --git a/baidupcsapi.egg-info/SOURCES.txt b/baidupcsapi.egg-info/SOURCES.txt deleted file mode 100644 index 0b61ee5..0000000 --- a/baidupcsapi.egg-info/SOURCES.txt +++ /dev/null @@ -1,14 +0,0 @@ -CHANGELOG.md -LICENSE.md -MANIFEST.in -README.md -requirements.txt -setup.py -baidupcsapi/__init__.py -baidupcsapi/api.py -baidupcsapi.egg-info/PKG-INFO -baidupcsapi.egg-info/SOURCES.txt -baidupcsapi.egg-info/dependency_links.txt -baidupcsapi.egg-info/not-zip-safe -baidupcsapi.egg-info/requires.txt -baidupcsapi.egg-info/top_level.txt \ No newline at end of file diff --git a/baidupcsapi.egg-info/dependency_links.txt b/baidupcsapi.egg-info/dependency_links.txt deleted file mode 100644 index 8b13789..0000000 --- a/baidupcsapi.egg-info/dependency_links.txt +++ /dev/null @@ -1 +0,0 @@ - diff --git a/baidupcsapi.egg-info/not-zip-safe b/baidupcsapi.egg-info/not-zip-safe deleted file mode 100644 index 8b13789..0000000 --- a/baidupcsapi.egg-info/not-zip-safe +++ /dev/null @@ -1 +0,0 @@ - diff --git a/baidupcsapi.egg-info/requires.txt b/baidupcsapi.egg-info/requires.txt deleted file mode 100644 index 283b886..0000000 --- a/baidupcsapi.egg-info/requires.txt +++ /dev/null @@ -1,3 +0,0 @@ -requests>=1.1.0 -requests_toolbelt>=0.1.2 -rsa>=3.1.4 diff --git a/baidupcsapi.egg-info/top_level.txt b/baidupcsapi.egg-info/top_level.txt deleted file mode 100644 index 7678cb7..0000000 --- a/baidupcsapi.egg-info/top_level.txt +++ /dev/null @@ -1 +0,0 @@ -baidupcsapi diff --git a/build/lib/baidupcsapi/__init__.py b/build/lib/baidupcsapi/__init__.py deleted file mode 100644 index ad93e2d..0000000 --- a/build/lib/baidupcsapi/__init__.py +++ /dev/null @@ -1,9 +0,0 @@ -#!/usr/bin/env python -# -*- coding: utf-8 -*- - -__title__ = 'baidupcsapi' -__version__ = '0.2.12' -__author__ = 'mozillazg,latyas' -__license__ = 'MIT' - -from .api import PCS \ No newline at end of file diff --git a/build/lib/baidupcsapi/api.py b/build/lib/baidupcsapi/api.py deleted file mode 100644 index a648626..0000000 --- a/build/lib/baidupcsapi/api.py +++ /dev/null @@ -1,1801 +0,0 @@ -#!/usr/bin/env python -# -*- coding: utf-8 -*- - -from functools import wraps -import re -import time -import json -import os -import logging -import pickle -import string -import random -import base64 -from hashlib import sha1, md5 -from urllib.parse import urlencode, quote -from zlib import crc32 -from requests_toolbelt import MultipartEncoder -import requests -requests.packages.urllib3.disable_warnings() -import rsa -import urllib - - -""" -logging.basicConfig(level=logging.DEBUG, - format='%(asctime)s %(filename)s[line:%(lineno)d] %(levelname)s %(message)s', - datefmt='%a, %d %b %Y %H:%M:%S') -""" - -BAIDUPAN_SERVER = 'pan.baidu.com' -BAIDUPCS_SERVER = 'pcs.baidu.com' -BAIDUPAN_HEADERS = {"Referer": "http://pan.baidu.com/disk/home", - "User-Agent": "netdisk;4.6.2.0;PC;PC-Windows;10.0.10240;WindowsBaiduYunGuanJia"} - -# https://pcs.baidu.com/rest/2.0/pcs/manage?method=listhost -> baidu cdn -# uses CDN_DOMAIN/monitor.jpg to test speed for each CDN -api_template = 'http://%s/api/{0}' % BAIDUPAN_SERVER - - -class LoginFailed(Exception): - - """因为帐号原因引起的登录失败异常 - 如果是超时则是返回Timeout的异常 - """ - pass - -# experimental - - -class CancelledError(Exception): - - """ - 用户取消文件上传 - """ - - def __init__(self, msg): - self.msg = msg - Exception.__init__(self, msg) - - def __str__(self): - return self.msg - - __repr__ = __str__ - - -class BufferReader(MultipartEncoder): - - """将multipart-formdata转化为stream形式的Proxy类 - """ - - def __init__(self, fields, boundary=None, callback=None, cb_args=(), cb_kwargs={}): - self._callback = callback - self._progress = 0 - self._cb_args = cb_args - self._cb_kwargs = cb_kwargs - super(BufferReader, self).__init__(fields, boundary) - - def read(self, size=None): - chunk = super(BufferReader, self).read(size) - self._progress += int(len(chunk)) - self._cb_kwargs.update({ - 'size': self._len, - 'progress': self._progress - }) - if self._callback: - try: - self._callback(*self._cb_args, **self._cb_kwargs) - except: # catches exception from the callback - raise CancelledError('The upload was cancelled.') - return chunk - - -def check_login(func): - """检查用户登录状态 - 这是pcs的检查方法 - """ - @wraps(func) - def wrapper(*args, **kwargs): - ret = func(*args, **kwargs) - if type(ret) == requests.Response: - try: - foo = json.loads(ret.content) - if foo.has_key('errno') and foo['errno'] == -6: - logging.debug( - 'Offline, deleting cookies file then relogin.') - path = '.{0}.cookies'.format(args[0].username) - if os.path.exists(path): - os.remove(path) - args[0]._initiate() - except: - pass - return ret - return wrapper - - -class BaseClass(object): - - """提供PCS类的基本方法 - """ - - def __init__(self, username, password, api_template=api_template, captcha_func=None): - self.session = requests.session() - self.api_template = api_template - self.username = username - self.password = password - self.user = {} - self.progress_func = None - if captcha_func: - self.captcha_func = captcha_func - else: - self.captcha_func = self.show_captcha - # 设置pcs服务器 - logging.debug('setting pcs server') - self.set_pcs_server(self.get_fastest_pcs_server()) - self._initiate() - - def get_fastest_pcs_server_test(self): - """通过测试返回最快的pcs服务器 - :returns: str -- 服务器地址 - """ - ret = requests.get( - 'https://pcs.baidu.com/rest/2.0/pcs/manage?method=listhost').content - serverlist = [server['host'] for server in json.loads(ret)['list']] - url_pattern = 'http://{0}/monitor.jpg' - time_record = [] - for server in serverlist: - start = time.time() * 1000 - requests.get(url_pattern.format(server)) - end = time.time() * 1000 - time_record.append((end - start, server)) - logging.info('TEST %s %s ms' % (server, int(end - start))) - return min(time_record)[1] - - def get_fastest_pcs_server(self): - """通过百度返回设置最快的pcs服务器 - """ - url = 'http://pcs.baidu.com/rest/2.0/pcs/file?app_id=250528&method=locateupload' - ret = requests.get(url).content - foo = json.loads(ret.decode()) - return foo['host'] - - def set_pcs_server(self, server): - """手动设置百度pcs服务器 - :params server: 服务器地址或域名 - - .. warning:: - 不要加 http:// 和末尾的 / - """ - global BAIDUPCS_SERVER - BAIDUPCS_SERVER = server - - def _remove_empty_items(self, data): - for k, v in data.copy().items(): - if v is None: - data.pop(k) - - def user_info(self, **kwargs): - params = { - 'method': "query", - 'reminder': "1", - } - - url = 'https://pan.baidu.com/rest/2.0/membership/user' - return self._request('membership/user', 'user', url=url, extra_params=params, **kwargs) - - def _initiate(self): - if not self._load_cookies(): - self.session.get('http://www.baidu.com') - self.user['token'] = self._get_token() - self._login() - else: - self.user['token'] = self._get_token() - - def _save_cookies(self): - #liuxin 将baidukey写入cookies - - cookies_file = '.{0}.cookies'.format(self.username) - with open(cookies_file, 'wb') as f: - pickle.dump( - requests.utils.dict_from_cookiejar(self.session.cookies), f) - - def _load_cookies(self): - #读取cookies中的baidukey - cookies_file = '.{0}.cookies'.format(self.username) - logging.debug('cookies file:' + cookies_file) - if os.path.exists(cookies_file): - logging.debug('%s cookies file has already existed.' % - self.username) - with open(cookies_file,'rb') as cookies_file: - cookies = requests.utils.cookiejar_from_dict( - pickle.load(cookies_file)) - logging.debug(str(cookies)) - self.session.cookies = cookies - self.user['BDUSS'] = self.session.cookies['BDUSS'] - return True - else: - return False - - def _get_token(self): - # Token - ret = self.session.get( - 'https://passport.baidu.com/v2/api/?getapi&tpl=mn&apiver=v3&class=login&tt=%s&logintype=dialogLogin&callback=0' % int(time.time())).text.replace('\'', '\"') - foo = json.loads(ret) - logging.info('token %s' % foo['data']['token']) - return foo['data']['token'] - - def _get_captcha(self, code_string): - # Captcha - if code_string: - verify_code = self.captcha_func("https://passport.baidu.com/cgi-bin/genimage?" + code_string) - else: - verify_code = "" - - return verify_code - - def show_captcha(self, url_verify_code): - print(url_verify_code) - verify_code = input('open url aboved with your web browser, then input verify code > ') - - return verify_code - - def _get_publickey(self): - url = 'https://passport.baidu.com/v2/getpublickey?token=' + \ - self.user['token'] - content = self.session.get(url).content - jdata = json.loads(content.decode().replace('\'','"')) - return (jdata['pubkey'], jdata['key']) - - def _login(self): - # Login - #code_string, captcha = self._get_captcha() - captcha = '' - code_string = '' - pubkey, rsakey = self._get_publickey() - key = rsa.PublicKey.load_pkcs1_openssl_pem(pubkey) - password_rsaed = base64.b64encode(rsa.encrypt(self.password.encode('utf-8'), key)) - while True: - login_data = {'staticpage': 'http://www.baidu.com/cache/user/html/v3Jump.html', - 'charset': 'UTF-8', - 'token': self.user['token'], - 'tpl': 'pp', - 'subpro': '', - 'apiver': 'v3', - 'tt': str(int(time.time())), - 'codestring': code_string, - 'isPhone': 'false', - 'safeflg': '0', - 'u': 'https://passport.baidu.com/', - 'quick_user': '0', - 'logLoginType': 'pc_loginBasic', - 'loginmerge': 'true', - 'logintype': 'basicLogin', - 'username': self.username, - 'password': password_rsaed, - 'verifycode': captcha, - 'mem_pass': 'on', - 'rsakey': str(rsakey), - 'crypttype': 12, - 'ppui_logintime': '50918', - 'callback': 'parent.bd__pcbs__oa36qm'} - result = self.session.post( - 'https://passport.baidu.com/v2/api/?login', data=login_data) - - # 是否需要验证码 - if 'err_no=257' in result.content.decode() or 'err_no=6' in result.content.decode(): - code_string = re.findall('codeString=(.*?)&', result.content.decode())[0] - logging.debug('need captcha, codeString=' + code_string) - captcha = self._get_captcha(code_string) - continue - - break - - # check exception - self._check_account_exception(result.content) - - if not result.ok: - raise LoginFailed('Logging failed.') - logging.info('COOKIES' + str(self.session.cookies)) - try: - self.user['BDUSS'] = self.session.cookies['BDUSS'] - except: - raise LoginFailed('Logging failed.') - logging.info('user %s Logged in BDUSS: %s' % - (self.username, self.user['BDUSS'])) - - self.user_info() - self._save_cookies() - - def _check_account_exception(self, content): - err_id = re.findall('err_no=([\d]+)', content.decode())[0] - - if err_id == '0': - return - error_message = { - '-1':'系统错误, 请稍后重试', - '1':'您输入的帐号格式不正确', - '3':'验证码不存在或已过期,请重新输入', - '4': '您输入的帐号或密码有误', - '5': '请在弹出的窗口操作,或重新登录', - '6':'验证码输入错误', - '16': '您的帐号因安全问题已被限制登录', - '257': '需要验证码', - '100005': '系统错误, 请稍后重试', - '120016': '未知错误 120016', - '120019': '近期登录次数过多, 请先通过 passport.baidu.com 解除锁定', - '120021': '登录失败,请在弹出的窗口操作,或重新登录', - '500010': '登录过于频繁,请24小时后再试', - '400031': '账号异常,请在当前网络环境下在百度网页端正常登录一次', - '401007': '您的手机号关联了其他帐号,请选择登录'} - try: - msg = error_message[err_id] - except: - msg = 'unknown err_id=' + err_id - raise LoginFailed(msg) - - def _params_utf8(self, params): - for k, v in params.items(): - if isinstance(v, str): - params[k] = v.encode('utf-8') - - @check_login - def _request(self, uri, method=None, url=None, extra_params=None, - data=None, files=None, callback=None, **kwargs): - params = { - 'method': method, - 'app_id': "250528", - 'BDUSS': self.user['BDUSS'], - 't': str(int(time.time())), - 'bdstoken': self.user['token'] - } - if extra_params: - params.update(extra_params) - self._remove_empty_items(params) - - headers = dict(BAIDUPAN_HEADERS) - if 'headers' in kwargs: - headers.update(kwargs['headers']) - kwargs.pop('headers') - - self._params_utf8(params) - if not url: - url = self.api_template.format(uri) - if data or files: - - if '?' in url: - api = "%s&%s" % (url, urlencode(params)) - else: - api = '%s?%s' % (url, urlencode(params)) - - # print params - if data: - self._remove_empty_items(data) - response = self.session.post(api, data=data, verify=False, - headers=headers, **kwargs) - else: - self._remove_empty_items(files) - - body = BufferReader(files, callback=callback) - headers.update({ - "Content-Type": body.content_type - } - ) - - response = self.session.post( - api, data=body, verify=False, headers=headers, **kwargs) - else: - api = url - if uri == 'filemanager' or uri == 'rapidupload' or uri == 'filemetas' or uri == 'precreate': - response = self.session.post( - api, params=params, verify=False, headers=headers, **kwargs) - else: - response = self.session.get( - api, params=params, verify=False, headers=headers, **kwargs) - return response - - -class PCS(BaseClass): - - def __init__(self, username, password, captcha_callback=None): - """ - :param username: 百度网盘的用户名 - :type username: str - - :param password: 百度网盘的密码 - :type password: str - - :param captcha_callback: 验证码的回调函数 - - .. note:: - 该函数会获得一个jpeg文件的内容,返回值需为验证码 - """ - super(PCS, self).__init__(username, password, api_template, captcha_func=captcha_callback) - - def __err_handler(self, act, errno, callback=None, args=(), kwargs={}): - """百度网盘下载错误控制 - :param act: 出错时的行为, 有 download - :param errno: 出错时的errno,这个要配合act才有实际意义 - :param callback: 返回时的调用函数, 为空时返回None - :param args: 给callback函数的参数tuple - :param kwargs: 给callback函数的带名参数字典 - - 在本函数调用后一定可以解决提交过来的问题, 在外部不需要重复检查是否存在原问题 - """ - errno = int(errno) - - def err_handler_download(): - if errno == 112: - # 页面失效, 重新刷新页面 - url = 'http://pan.baidu.com/disk/home' - self.session.get(url) - - return - - def err_handler_upload(): - # 实际出问题了再写 - return - - def err_handler_generic(): - return - - _act = {'download': err_handler_download, - 'upload': err_handler_upload, - 'generic': err_handler_generic - } - - if act not in _act: - raise Exception('行为未定义, 无法处理该行为的错误') - - if callback: - return callback(*args, **kwargs) - return None - - def quota(self, **kwargs): - """获得配额信息 - :return requests.Response - - .. note:: - 返回正确时返回的 Reponse 对象 content 中的数据结构 - - {"errno":0,"total":配额字节数,"used":已使用字节数,"request_id":请求识别号} - """ - return self._request('quota', **kwargs) - - def upload(self, dir, file_handler, filename, ondup="newcopy", callback=None, **kwargs): - """上传单个文件(<2G). - - | 百度PCS服务目前支持最大2G的单个文件上传。 - | 如需支持超大文件(>2G)的断点续传,请参考下面的“分片文件上传”方法。 - - :param dir: 网盘中文件的保存路径(不包含文件名)。 - 必须以 / 开头。 - - .. warning:: - * 注意本接口的 dir 参数不包含文件名,只包含路径 - * 路径长度限制为1000; - * 径中不能包含以下字符:``\\\\ ? | " > < : *``; - * 文件名或路径名开头结尾不能是 ``.`` - 或空白字符,空白字符包括: - ``\\r, \\n, \\t, 空格, \\0, \\x0B`` 。 - :param file_handler: 上传文件对象 。(e.g. ``open('foobar', 'rb')`` ) - - .. warning:: - 注意不要使用 .read() 方法. - :type file_handler: file - :param callback: 上传进度回调函数 - 需要包含 size 和 progress 名字的参数 - - :param filename: - - :param ondup: (可选) - - * 'overwrite':表示覆盖同名文件; - * 'newcopy':表示生成文件副本并进行重命名,命名规则为“ - 文件名_日期.后缀”。 - :return: requests.Response 对象 - - .. note:: - 返回正确时返回的 Reponse 对象 content 中的数据结构 - - {"path":"服务器文件路径","size":文件大小,"ctime":创建时间,"mtime":修改时间,"md5":"文件md5值","fs_id":服务器文件识别号,"isdir":是否为目录,"request_id":请求识别号} - - """ - - params = { - 'dir': dir, - 'ondup': ondup, - 'filename': filename - } - - tmp_filename = ''.join(random.sample(string.ascii_letters, 10)) - files = {'file': (tmp_filename, file_handler)} - - url = 'https://{0}/rest/2.0/pcs/file'.format(BAIDUPCS_SERVER) - return self._request('file', 'upload', url=url, extra_params=params, - files=files, callback=callback, **kwargs) - - def upload_tmpfile(self, file_handler, callback=None, **kwargs): - """分片上传—文件分片及上传. - - 百度 PCS 服务支持每次直接上传最大2G的单个文件。 - - 如需支持上传超大文件(>2G),则可以通过组合调用分片文件上传的 - ``upload_tmpfile`` 方法和 ``upload_superfile`` 方法实现: - - 1. 首先,将超大文件分割为2G以内的单文件,并调用 ``upload_tmpfile`` - 将分片文件依次上传; - 2. 其次,调用 ``upload_superfile`` ,完成分片文件的重组。 - - 除此之外,如果应用中需要支持断点续传的功能, - 也可以通过分片上传文件并调用 ``upload_superfile`` 接口的方式实现。 - - :param file_handler: 上传文件对象 。(e.g. ``open('foobar', 'rb')`` ) - - .. warning:: - 注意不要使用 .read() 方法. - :type file_handler: file - - :param callback: 上传进度回调函数 - 需要包含 size 和 progress 名字的参数 - - :param ondup: (可选) - - * 'overwrite':表示覆盖同名文件; - * 'newcopy':表示生成文件副本并进行重命名,命名规则为“ - 文件名_日期.后缀”。 - :type ondup: str - - :return: requests.Response - - .. note:: - 这个对象的内容中的 md5 字段为合并文件的凭依 - - .. note:: - 返回正确时返回的 Reponse 对象 content 中的数据结构 - - {"md5":"片段的 md5 值","request_id":请求识别号} - - - - """ - - params = { - 'type': 'tmpfile' - } - files = {'file': (str(int(time.time())), file_handler)} - url = 'https://{0}/rest/2.0/pcs/file'.format(BAIDUPCS_SERVER) - return self._request('file', 'upload', url=url, extra_params=params, callback=callback, - files=files, **kwargs) - - def upload_superfile(self, remote_path, block_list, ondup="newcopy", **kwargs): - """分片上传—合并分片文件. - - 与分片文件上传的 ``upload_tmpfile`` 方法配合使用, - 可实现超大文件(>2G)上传,同时也可用于断点续传的场景。 - - :param remote_path: 网盘中文件的保存路径(包含文件名)。 - 必须以 开头。 - - .. warning:: - * 路径长度限制为1000; - * 径中不能包含以下字符:``\\\\ ? | " > < : *``; - * 文件名或路径名开头结尾不能是 ``.`` - 或空白字符,空白字符包括: - ``\\r, \\n, \\t, 空格, \\0, \\x0B`` 。 - :param block_list: 子文件内容的 MD5 值列表;子文件至少两个,最多1024个。 - :type block_list: list - :param ondup: (可选) - - * 'overwrite':表示覆盖同名文件; - * 'newcopy':表示生成文件副本并进行重命名,命名规则为“ - 文件名_日期.后缀”。 - :return: Response 对象 - - .. note:: - 返回正确时返回的 Reponse 对象 content 中的数据结构 - - {"path":"服务器文件路径","size":文件大小,"ctime":创建时间,"mtime":修改时间,"md5":"文件md5值","fs_id":服务器文件识别号,"isdir":是否为目录,"request_id":请求识别号} - - """ - - params = { - 'path': remote_path, - 'ondup': ondup - } - data = { - 'param': json.dumps({'block_list': block_list}), - } - url = 'https://{0}/rest/2.0/pcs/file'.format(BAIDUPCS_SERVER) - return self._request('file', 'createsuperfile', url=url, extra_params=params, - data=data, **kwargs) - - def get_sign(self): - # refered: - # https://github.com/PeterDing/iScript/blob/master/pan.baidu.com.py - url = 'http://pan.baidu.com/disk/home' - r = self.session.get(url) - html = r.content - sign1 = re.search(r'"sign1":"([A-Za-z0-9]+)"', html).group(1) - sign3 = re.search(r'"sign3":"([A-Za-z0-9]+)"', html).group(1) - timestamp = re.search(r'"timestamp":([0-9]+)[^0-9]', html).group(1) - - def sign2(j, r): - a = [] - p = [] - o = '' - v = len(j) - - for q in xrange(256): - a.append(ord(j[q % v])) - p.append(q) - - u = 0 - for q in xrange(256): - u = (u + p[q] + a[q]) % 256 - t = p[q] - p[q] = p[u] - p[u] = t - - i = 0 - u = 0 - for q in xrange(len(r)): - i = (i + 1) % 256 - u = (u + p[i]) % 256 - t = p[i] - p[i] = p[u] - p[u] = t - k = p[((p[i] + p[u]) % 256)] - o += chr(ord(r[q]) ^ k) - - return base64.b64encode(o) - - self.dsign = sign2(sign3, sign1) - self.timestamp = timestamp - - def _locatedownload(self, remote_path, **kwargs): - """百度云管家获得方式 - :param remote_path: 需要下载的文件路径 - :type remote_path: str - """ - params = { - 'path': remote_path - } - url = 'https://{0}/rest/2.0/pcs/file'.format(BAIDUPCS_SERVER) - return self._request('file', 'locatedownload', url=url, - extra_params=params, **kwargs) - - def _yunguanjia_format(self, remote_path, **kwargs): - ret = self._locatedownload(remote_path, **kwargs).content - data = json.loads(ret) - return 'http://' + data['host'] + data['path'] - - def download_url(self, remote_path, **kwargs): - """返回目标文件可用的下载地址 - :param remote_path: 每一项代表需要下载的文件路径 - :type remote_path: str list - """ - - def get_url(dlink): - return self.session.get(dlink, - headers=BAIDUPAN_HEADERS, - stream=True).url - - if not hasattr(self, 'dsign'): - self.get_sign() - - if isinstance(remote_path, bytes) or isinstance(remote_path, str): - remote_path = [remote_path] - - file_list = [] - jdata = json.loads(self.meta(remote_path).content) - if jdata['errno'] != 0: - jdata = self.__err_handler('generic', jdata['errno'], - self.meta, - args=(remote_path,) - ) - logging.debug('[*]' + str(jdata)) - for i, entry in enumerate(jdata['info']): - url = entry['dlink'] - foo = get_url(url) - if 'wenxintishi' in foo: - file_list.append(self._yunguanjia_format(remote_path[i])) - else: - file_list.append(get_url(entry['dlink'])) - - return file_list - - def save_album_file(self, album_id, from_uk, save_path, fsid_list): - data = { - "from_uk": from_uk, - "album_id": album_id, - "to_path": save_path, - "fsid_list": fsid_list} - url = "http://pan.baidu.com/pcloud/album/transfertask/create" - print (self._request(None, data=data, url=url).content) - - def _verify_shared_file(self, shareid, uk, password): - data = { - "pwd": password, - "vcode": "", - "vcode_str": "", - "shareid": shareid, - "uk": uk - } - url = "http://pan.baidu.com/share/verify?shareid="+shareid+"&uk="+uk - return json.loads(self._request(None, data=data, url=url).content) - - def _save_shared_file_list(self, shareid, uk, path, file_list): - url = "http://pan.baidu.com/share/transfer?shareid="+shareid+"&from="+uk - data = { - "filelist": json.dumps(file_list), - "path": path - } - return json.loads(self._request(None, url=url, data=data).content) - - def save_share_list(self, url, path, password=None, filter_callback=None): - """ 保存分享文件列表到自己的网盘, 支持密码, 支持文件过滤的回调函数 - :param url: 分享的url - :type url: str - - :param path 保存到自己网盘的位置 - :type path: str - - :param password 分享密码, 如果没有分享资源没有密码则不用填 - :type password: str - - :param filter_callback 过滤文件列表中文件的回调函数, filter(file), 返回值是假值则被过滤掉 - file = { - "filename": "xxx", - "size": 1234, - "isdir": 0 - } - :return - { - "error": 0, # 无错误为0, 否则出错. - "result": [] # 如果成功会返回添加到自己网盘的文件列表 - } - - context是从分享页面的html中提取的json, 里面保存了分享文件列表 - 暂时有用的是file_list, uk, shareid - context = { - "typicalPath": "\/\u65b0\u5efa\u6587\u4ef6\u5939(1)\/[SumiSora][Yosuga_no_Sora][BDRip][BIG5][720P]", - "self": false, - "username": "", - "photo": "http:\/\/himg.bdimg.com\/sys\/portrait\/item\/0237bb1b.jpg", - "uk": 924798052, - "ctime": 1455779404, - "flag": 2, - "linkusername": "cls1010123", - "vCnt": 118442, - "tCnt": 27916, - "dCnt": 12006, - "file_list": { - "errno": 0, - "list": [{ - "fs_id": 882212291049391, - "app_id": "250528", - "parent_path": "%2F%E6%96%B0%E5%BB%BA%E6%96%87%E4%BB%B6%E5%A4%B9%281%29", - "server_filename": "[SumiSora][Yosuga_no_Sora][BDRip][BIG5][720P]", - "size": 0, - "server_mtime": 1455779174, - "server_ctime": 1455779174, - "local_mtime": 1455779174, - "local_ctime": 1455779174, - "isdir": 1, - "isdelete": "0", - "status": "0", - "category": 6, - "share": "0", - "path_md5": "18281300157632491061", - "delete_fs_id": "0", - "extent_int3": "0", - "extent_tinyint1": "0", - "extent_tinyint2": "0", - "extent_tinyint3": "0", - "extent_tinyint4": "0", - "path": "\/\u65b0\u5efa\u6587\u4ef6\u5939(1)\/[SumiSora][Yosuga_no_Sora][BDRip][BIG5][720P]", - "root_ns": 465254146, - "md5": "", - "file_key": "" - }] - }, - "loginstate": 0, - "channel": 4, - "third_url": 0, - "bdstoken": null , - "sampling": { - "expvar": ["chengyong"] - }, - "is_vip": 0, - "description": "", - "shorturl": "1skhBegP", - "shareinfo": "", - "is_baiduspider": 0, - "isinwhitelist": 0, - "public": 0, - "shareid": 23915657, - "bj_unicom": 0, - "visitor_uk": null , - "visitor_avatar": null , - "timestamp": 1458198232, - "sign": "xxxx", - "sekey": "xxxx", - "novelid": false, - "is_master_vip": 0, - "urlparam": [], - "XDUSS": "null" - } - """ - # 这里无论是短链接还是长链接如果带密码, 则都被重定向到长链接, 可以直接取出shareid, uk - # 而如果是不带密码的分享, 则此时还不需要shareid,uk - respond = self._request(None, url=url) - - target_url = respond.url - shareid, uk = None, None - m = re.search(r"shareid=(\d+)", target_url) - if m: - shareid = m.group(1) - m = re.search(r"uk=(\d+)", target_url) - if m: - uk = m.group(1) - - # 检查验证码, 如果成功, 当前用户就被授权直接访问资源了 - if shareid and uk and password: - verify_result = self._verify_shared_file(shareid, uk, password) - if not verify_result or verify_result['errno'] != 0: - return verify_result - - # 从html中解析文件列表, 同时把shareid, uk也解析出来 - html = self._request(None, url=target_url).content - r = re.compile(r".*_context =(.*);.*") - m = r.search(html) - if m: - context = json.loads(m.group(1)) - file_list = context['file_list']['list'] - uk = str(context['uk']) - shareid = str(context['shareid']) - ret = {"filelist": []} - for f in file_list: - file_obj = { - 'filename': f['server_filename'], - 'size': f['size'], - 'isdir': f['isdir'] - } - if not filter_callback or filter_callback(file_obj): - ret['filelist'].append(f['path']) - save_share_file_ret = self._save_shared_file_list(shareid, uk, path, ret['filelist']) - if save_share_file_ret and save_share_file_ret['errno'] == 0: - return save_share_file_ret - else: - return ret - else: - # 获取文件列表失败 - return {"errno": -1, "error_msg": "PCS.save_share_list failed, mayby url is incorrect!"} - - # Deprecated - # using download_url to get real download url - def download(self, remote_path, **kwargs): - """下载单个文件。 - - download 接口支持HTTP协议标准range定义,通过指定range的取值可以实现 - 断点下载功能。 例如:如果在request消息中指定“Range: bytes=0-99”, - 那么响应消息中会返回该文件的前100个字节的内容; - 继续指定“Range: bytes=100-199”, - 那么响应消息中会返回该文件的第二个100字节内容:: - - >>> headers = {'Range': 'bytes=0-99'} - >>> pcs = PCS('username','password') - >>> pcs.download('/test_sdk/test.txt', headers=headers) - - :param remote_path: 网盘中文件的路径(包含文件名)。 - 必须以 / 开头。 - - .. warning:: - * 路径长度限制为1000; - * 径中不能包含以下字符:``\\\\ ? | " > < : *``; - * 文件名或路径名开头结尾不能是 ``.`` - 或空白字符,空白字符包括: - ``\\r, \\n, \\t, 空格, \\0, \\x0B`` 。 - :return: requests.Response 对象 - """ - - params = { - 'path': remote_path, - } - url = 'https://{0}/rest/2.0/pcs/file'.format(BAIDUPCS_SERVER) - return self._request('file', 'download', url=url, - extra_params=params, **kwargs) - - def get_streaming(self, path, stype="M3U8_AUTO_480", **kwargs): - """获得视频的m3u8列表 - - :param path: 视频文件路径 - :param type: 返回stream类型, 已知有``M3U8_AUTO_240``/``M3U8_AUTO_480``/``M3U8_AUTO_720`` - - .. warning:: - M3U8_AUTO_240会有问题, 目前480P是最稳定的, 也是百度网盘默认的 - :return: str 播放(列表)需要的信息 - """ - - params = { - 'path': path, - 'type': stype - } - url = 'https://{0}/rest/2.0/pcs/file'.format(BAIDUPCS_SERVER) - while True: - ret = self._request('file', 'streaming', url=url, extra_params=params, **kwargs) - if not ret.ok: - logging.debug('get_streaming ret_status_code %s' % ret.status_code) - jdata = json.loads(ret.content) - if jdata['error_code'] == 31345: - # 再试一次 - continue - elif jdata['error_code'] == 31066: - # 文件不存在 - return 31066 - elif jdata['error_code'] == 31304: - # 文件类型不支持 - return 31304 - elif jdata['error_code'] == 31023: - # params error - return 31023 - return ret.content - - def mkdir(self, remote_path, **kwargs): - """为当前用户创建一个目录. - - :param remote_path: 网盘中目录的路径,必须以 / 开头。 - - .. warning:: - * 路径长度限制为1000; - * 径中不能包含以下字符:``\\\\ ? | " > < : *``; - * 文件名或路径名开头结尾不能是 ``.`` - 或空白字符,空白字符包括: - ``\\r, \\n, \\t, 空格, \\0, \\x0B`` 。 - :return: Response 对象 - - .. note:: - 返回正确时返回的 Reponse 对象 content 中的数据结构 - - {"fs_id":服务器文件识别号,"path":"路径","ctime":创建时间,"mtime":修改时间,"status":0,"isdir":1,"errno":0,"name":"文件路径"} - - """ - - data = { - 'path': remote_path, - 'isdir': "1", - "size": "", - "block_list": "[]" - } - # 奇怪的是创建新目录的method是post - return self._request('create', 'post', data=data, **kwargs) - - def list_files(self, remote_path, by="name", order="desc", - limit=None, **kwargs): - """获取目录下的文件列表. - - :param remote_path: 网盘中目录的路径,必须以 / 开头。 - - .. warning:: - * 路径长度限制为1000; - * 径中不能包含以下字符:``\\\\ ? | " > < : *``; - * 文件名或路径名开头结尾不能是 ``.`` - 或空白字符,空白字符包括: - ``\\r, \\n, \\t, 空格, \\0, \\x0B`` 。 - :param by: 排序字段,缺省根据文件类型排序: - - * time(修改时间) - * name(文件名) - * size(大小,注意目录无大小) - :param order: “asc”或“desc”,缺省采用降序排序。 - - * asc(升序) - * desc(降序) - :param limit: 返回条目控制,参数格式为:n1-n2。 - - 返回结果集的[n1, n2)之间的条目,缺省返回所有条目; - n1从0开始。 - :return: requests.Response 对象 - - .. note:: - 返回正确时返回的 Reponse 对象 content 中的数据结构 - - { - "errno":0, - "list":[ - {"fs_id":服务器文件识别号"path":"路径","server_filename":"服务器文件名(不汗含路径)","size":文件大小,"server_mtime":服务器修改时间,"server_ctime":服务器创建时间,"local_mtime":本地修改时间,"local_ctime":本地创建时间,"isdir":是否是目录,"category":类型,"md5":"md5值"}……等等 - ], - "request_id":请求识别号 - } - - """ - if order == "desc": - desc = "1" - else: - desc = "0" - - params = { - 'dir': remote_path, - 'order': by, - 'desc': desc - } - return self._request('list', 'list', extra_params=params, **kwargs) - - def move(self, path_list, dest, **kwargs): - """ - 移动文件或文件夹 - - :param path_list: 在百度盘上要移动的源文件path - :type path_list: list - - :param dest: 要移动到的目录 - :type dest: str - - """ - def __path(path): - if path.endswith('/'): - return path.split('/')[-2] - else: - return os.path.basename(path) - params = { - 'opera': 'move' - } - data = { - 'filelist': json.dumps([{ - "path": path, - "dest": dest, - "newname": __path(path)} for path in path_list]), - } - url = 'http://{0}/api/filemanager'.format(BAIDUPAN_SERVER) - return self._request('filemanager', 'move', url=url, data=data, extra_params=params, **kwargs) - - def rename(self, rename_pair_list, **kwargs): - """重命名 - - :param rename_pair_list: 需要重命名的文件(夹)pair (路径,新名称)列表,如[('/aa.txt','bb.txt')] - :type rename_pair_list: list - - """ - foo = [] - for path, newname in rename_pair_list: - foo.append({'path': path, - 'newname': newname - }) - - data = {'filelist': json.dumps(foo)} - params = { - 'opera': 'rename' - } - - url = 'http://{0}/api/filemanager'.format(BAIDUPAN_SERVER) - print('请求url', url) - logging.debug('rename ' + str(data) + 'URL:' + url) - return self._request('filemanager', 'rename', url=url, data=data, extra_params=params, **kwargs) - - def copy(self, path_list, dest, **kwargs): - """ - 复制文件或文件夹 - - :param path_list: 在百度盘上要复制的源文件path - :type path_list: list - - :param dest: 要复制到的目录 - :type dest: str - - """ - def __path(path): - if path.endswith('/'): - return path.split('/')[-2] - else: - return os.path.basename(path) - params = { - 'opera': 'copy' - } - data = { - 'filelist': json.dumps([{ - "path": path, - "dest": dest, - "newname": __path(path)} for path in path_list]), - } - url = 'http://{0}/api/filemanager'.format(BAIDUPAN_SERVER) - return self._request('filemanager', 'move', url=url, data=data, extra_params=params, **kwargs) - - def delete(self, path_list, **kwargs): - """ - 删除文件或文件夹 - - :param path_list: 待删除的文件或文件夹列表,每一项为服务器路径 - :type path_list: list - - - """ - data = { - 'filelist': json.dumps([path for path in path_list]) - } - url = 'http://{0}/api/filemanager?opera=delete'.format(BAIDUPAN_SERVER) - return self._request('filemanager', 'delete', url=url, data=data, **kwargs) - - def share(self, file_ids, pwd=None, **kwargs): - """ - 创建一个文件的分享链接 - - :param file_ids: 要分享的文件fid列表 - :type path_list: list - - :param pwd: 分享密码,没有则没有密码 - :type pwd: str - - :return: requests.Response 对象 - - .. note:: - 返回正确 - { - "errno": 0, - - "request_id": 请求识别号, - - "shareid": 分享识别号, - - "link": "分享地址", - - "shorturl": "段网址", - - "ctime": 创建时间, - - "premis": false - } - - """ - if pwd: - data = { - 'fid_list': json.dumps([int(fid) for fid in file_ids]), - 'pwd': pwd, - 'schannel': 4, - 'channel_list': json.dumps([]) - } - else: - data = { - 'fid_list': json.dumps([int(fid) for fid in file_ids]), - 'schannel': 0, - 'channel_list': json.dumps([]) - } - url = 'http://pan.baidu.com/share/set' - return self._request('share/set', '', url=url, data=data, **kwargs) - - def list_streams(self, file_type, start=0, limit=1000, order='time', desc='1', - filter_path=None, **kwargs): - """以视频、音频、图片及文档四种类型的视图获取所创建应用程序下的 - 文件列表. - - :param file_type: 类型分为video audio image doc other exe torrent - :param start: 返回条目控制起始值,缺省值为0。 - :param limit: 返回条目控制长度,缺省为1000,可配置。 - :param filter_path: 需要过滤的前缀路径,如:/album - - .. warning:: - * 路径长度限制为1000; - * 径中不能包含以下字符:``\\\\ ? | " > < : *``; - * 文件名或路径名开头结尾不能是 ``.`` - 或空白字符,空白字符包括: - ``\\r, \\n, \\t, 空格, \\0, \\x0B`` 。 - :return: requests.Response 对象, 结构和 list_files 相同 - """ - if file_type == 'doc': - file_type = '4' - elif file_type == 'video': - file_type = '1' - elif file_type == 'image': - file_type = '3' - elif file_type == 'torrent': - file_type = '7' - elif file_type == 'other': - file_type = '6' - elif file_type == 'audio': - file_type = '2' - elif file_type == 'exe': - file_type = '5' - - params = { - 'category': file_type, - 'pri': '-1', - 'start': start, - 'num': limit, - 'order': order, - 'desc': desc, - 'filter_path': filter_path, - } - url = 'http://pan.baidu.com/api/categorylist' - return self._request('categorylist', 'list', url=url, extra_params=params, - **kwargs) - - def add_download_task(self, source_url, remote_path, selected_idx=(), **kwargs): - """ - 添加离线任务,支持所有百度网盘支持的类型 - """ - if source_url.startswith('magnet:?'): - print('Magnet: "%s"' % source_url) - return self.add_magnet_task(source_url, remote_path, selected_idx, **kwargs) - elif source_url.endswith('.torrent'): - print('BitTorrent: "%s"' % source_url) - return self.add_torrent_task(source_url, remote_path, selected_idx, **kwargs) - else: - print('Others: "%s"' % source_url) - data = { - 'method': 'add_task', - 'source_url': source_url, - 'save_path': remote_path, - } - url = 'http://{0}/rest/2.0/services/cloud_dl'.format(BAIDUPAN_SERVER) - return self._request('services/cloud_dl', 'add_task', url=url, - data=data, **kwargs) - - def add_torrent_task(self, torrent_path, save_path='/', selected_idx=(), **kwargs): - """ - 添加本地BT任务 - - :param torrent_path: 本地种子的路径 - - :param save_path: 远程保存路径 - - :param selected_idx: 要下载的文件序号 —— 集合为空下载所有,非空集合指定序号集合,空串下载默认 - - :return: requests.Response - - .. note:: - 返回正确时返回的 Reponse 对象 content 中的数据结构 - - {"task_id":任务编号,"rapid_download":是否已经完成(急速下载),"request_id":请求识别号} - - """ - - # 上传种子文件 - torrent_handler = open(torrent_path, 'rb') - basename = os.path.basename(torrent_path) - - # 清理同名文件 - self.delete(['/' + basename]) - - response = self.upload('/', torrent_handler, basename).json() - remote_path = response['path'] - logging.debug('REMOTE PATH:' + remote_path) - - # 获取种子信息 - response = self._get_torrent_info(remote_path).json() - if response.get('error_code'): - print(response.get('error_code')) - return - if not response['torrent_info']['file_info']: - return - - # 要下载的文件序号:集合为空下载所有,非空集合指定序号集合,空串下载默认 - if isinstance(selected_idx, (tuple, list, set)): - if len(selected_idx) > 0: - selected_idx = ','.join(map(str, selected_idx)) - else: - selected_idx = ','.join(map(str, range(1, len(response['torrent_info']['file_info']) + 1))) - else: - selected_idx = '' - - # 开始下载 - data = { - 'file_sha1': response['torrent_info']['sha1'], - 'save_path': save_path, - 'selected_idx': selected_idx, - 'task_from': '1', - 'source_path': remote_path, - 'type': '2' # 2 is torrent file - } - url = 'http://{0}/rest/2.0/services/cloud_dl'.format(BAIDUPAN_SERVER) - return self._request('create', 'add_task', url=url, data=data, **kwargs) - - def _get_torrent_info(self, torrent_path): - data = { - 'source_path': torrent_path, - 'type': '2' # 2 is torrent - } - url = 'http://{0}/rest/2.0/services/cloud_dl'.format(BAIDUPAN_SERVER) - - return self._request('cloud_dl', 'query_sinfo', url=url, data=data, timeout=30) - - def add_magnet_task(self, magnet, remote_path, selected_idx=(), **kwargs): - response = self._get_magnet_info(magnet).json() - if response.get('error_code'): - print(response.get('error_code')) - return - if not response['magnet_info']: - return - - # 要下载的文件序号:集合为空下载所有,非空集合指定序号集合,空串下载默认 - if isinstance(selected_idx, (tuple, list, set)): - if len(selected_idx) > 0: - selected_idx = ','.join(map(str, selected_idx)) - else: - selected_idx = ','.join(map(str, range(1, len(response['magnet_info']) + 1))) - else: - selected_idx = '' - - data = { - 'source_url': magnet, - 'save_path': remote_path, - 'selected_idx': selected_idx, - 'task_from': '1', - 'type': '4' # 4 is magnet - } - url = 'http://{0}/rest/2.0/services/cloud_dl'.format(BAIDUPAN_SERVER) - - return self._request('create', 'add_task', url=url, data=data, timeout=30) - - def _get_magnet_info(self, magnet): - data = { - 'source_url': magnet, - 'save_path': '/', - 'type': '4' # 4 is magnet - } - url = 'http://{0}/rest/2.0/services/cloud_dl'.format(BAIDUPAN_SERVER) - - return self._request('cloud_dl', 'query_magnetinfo', url=url, data=data, timeout=30) - - def query_download_tasks(self, task_ids, operate_type=1, **kwargs): - """根据任务ID号,查询离线下载任务信息及进度信息。 - - :param task_ids: 要查询的任务 ID字符串 列表 - :type task_ids: list or tuple - :param operate_type: - * 0:查任务信息 - * 1:查进度信息,默认为1 - - :return: requests.Response - - .. note:: - 返回正确时返回的 Reponse 对象 content 中的数据结构 - - 给出一个范例 - - { - "task_info": - {"70970481":{ - "status":"0", - - "file_size":"122328178", - - "finished_size":"122328178", - - "create_time":"1391620757", - - "start_time":"1391620757", - - "finish_time":"1391620757", - - "save_path":"\/", - - "source_url":"\/saki-nation04gbcn.torrent", - - "task_name":"[KTXP][Saki-National][04][GB_CN][720p]", - - "od_type":"2", - - "file_list":[ - { - "file_name":"[KTXP][Saki-National][04][GB_CN][720p].mp4", - - "file_size":"122328178" - } - ], - - "result":0 - - } - }, - - "request_id":861570268 - - } - - - """ - - params = { - 'task_ids': ','.join(map(str, task_ids)), - 'op_type': operate_type, - } - url = 'http://{0}/rest/2.0/services/cloud_dl'.format(BAIDUPAN_SERVER) - return self._request('services/cloud_dl', 'query_task', url=url, - extra_params=params, **kwargs) - - def download_tasks_number(self): - """获取离线任务总数 - - :return: int - """ - ret = self.list_download_tasks().content - foo = json.loads(ret) - return foo['total'] - - def list_download_tasks(self, need_task_info="1", asc="0", start=0, create_time=None, limit=1000, status="255", source_url=None, remote_path=None, **kwargs): - """查询离线下载任务ID列表及任务信息. - - :param need_task_info: 是否需要返回任务信息: - * 0:不需要 - * 1:需要,默认为1 - :param start: 查询任务起始位置,默认为0。 - :param limit: 设定返回任务数量,默认为10。 - :param asc: - * 0:降序,默认值 - * 1:升序 - :param create_time: 任务创建时间,默认为空。 - :type create_time: int - :param status: 任务状态,默认为空。 - - .. note:: - 任务状态有 - 0:下载成功 - - 1:下载进行中 - - 2:系统错误 - - 3:资源不存在 - - 4:下载超时 - - 5:资源存在但下载失败 - - 6:存储空间不足 - - 7:目标地址数据已存在, 8:任务取消. - :type status: int - :param source_url: 源地址URL,默认为空。 - :param remote_path: 文件保存路径,默认为空。 - - .. warning:: - * 路径长度限制为1000; - * 径中不能包含以下字符:``\\\\ ? | " > < : *``; - * 文件名或路径名开头结尾不能是 ``.`` - 或空白字符,空白字符包括: - ``\\r, \\n, \\t, 空格, \\0, \\x0B`` 。 - :param expires: 请求失效时间,如果有,则会校验。 - :type expires: int - :return: Response 对象 - - .. note:: - 返回正确时返回的 Reponse 对象 content 中的数据结构 - - { - "task_info": [ - - { - - "task_id": "任务识别号", - - "od_type": "2", - - "source_url": "原地址,bt任务为种子在服务器上的路径,否则为原始URL", - - "save_path": "保存路径", - - "rate_limit": "速度限制,0为不限", - - "timeout": "0", - - "callback": "", - - "status": "任务状态", - - "create_time": "创建时间", - - "task_name": "任务名" - - },……等等 - - ], - - "total": 总数, - - "request_id": 请求识别号 - - } - """ - - params = { - 'start': start, - 'limit': limit, - 'status': status, - 'need_task_info': need_task_info, - 'asc': asc, - 'source_url': source_url, - 'remote_path': remote_path, - 'create_time': create_time - - } - url = 'http://{0}/rest/2.0/services/cloud_dl'.format(BAIDUPAN_SERVER) - return self._request('services/cloud_dl', 'list_task', url=url, extra_params=params, **kwargs) - - def cancel_download_task(self, task_id, expires=None, **kwargs): - """取消离线下载任务. - - :param task_id: 要取消的任务ID号。 - :type task_id: str - :param expires: 请求失效时间,如果有,则会校验。 - :type expires: int - :return: requests.Response - """ - - data = { - 'expires': expires, - 'task_id': task_id, - } - url = 'http://{0}/rest/2.0/services/cloud_dl'.format(BAIDUPAN_SERVER) - return self._request('services/cloud_dl', 'cancel_task', url=url, - data=data, **kwargs) - - def list_recycle_bin(self, order="time", desc="1", start=0, limit=1000, page=1, **kwargs): - # Done - """获取回收站中的文件及目录列表. - - :param start: 返回条目的起始值,缺省值为0 - :param limit: 返回条目的长度,缺省值为1000 - :return: requests.Response - - 格式同 list_files - """ - - params = { - 'start': start, - 'num': limit, - 'dir': '/', - 'order': order, - 'desc': desc - } - url = 'http://{0}/api/recycle/list'.format(BAIDUPAN_SERVER) - return self._request('recycle', 'list', url=url, extra_params=params, **kwargs) - - def restore_recycle_bin(self, fs_ids, **kwargs): - """批量还原文件或目录(非强一致接口,调用后请sleep1秒 ). - - :param fs_ids: 所还原的文件或目录在 PCS 的临时唯一标识 ID 的列表。 - :type fs_ids: list or tuple - :return: requests.Response 对象 - """ - - data = { - 'fidlist': json.dumps(fs_ids) - } - url = 'http://{0}/api/recycle/restore'.format(BAIDUPAN_SERVER) - return self._request('recycle', 'restore', data=data, **kwargs) - - def clean_recycle_bin(self, **kwargs): - """清空回收站. - - :return: requests.Response - """ - - url = 'http://{0}/api/recycle/clear'.format(BAIDUPAN_SERVER) - return self._request('recycle', 'clear', url=url, **kwargs) - - def rapidupload(self, file_handler, path, **kwargs): - """秒传一个文件 - - :param file_handler: 文件handler, e.g. open('file','rb') - :type file_handler: file - - :param path: 上传到服务器的路径,包含文件名 - :type path: str - - :return: requests.Response - - .. note:: - * 文件已在服务器上存在,不上传,返回示例 - { - - "path" : "/apps/album/1.jpg", - - "size" : 372121, - - "ctime" : 1234567890, - - "mtime" : 1234567890, - - "md5" : "cb123afcc12453543ef", - - "fs_id" : 12345, - - "isdir" : 0, - - "request_id" : 12314124 - - } - - * 文件不存在,需要上传 - - {"errno":404,"info":[],"request_id":XXX} - - * 文件大小不足 256kb (slice-md5 == content-md5) 时 - - {"errno":2,"info":[],"request_id":XXX} - - * 远程文件已存在 - - {"errno":-8,"info":[],"request_id":XXX} - - - """ - file_handler.seek(0, 2) - _BLOCK_SIZE = 2 ** 20 - content_length = file_handler.tell() - file_handler.seek(0) - - # 校验段为前 256kb - first_256bytes = file_handler.read(256 * 1024) - slice_md5 = md5(first_256bytes).hexdigest() - - content_crc32 = crc32(first_256bytes).conjugate() - content_md5 = md5(first_256bytes) - - while True: - block = file_handler.read(_BLOCK_SIZE) - if not block: - break - # 更新crc32和md5校验值 - content_crc32 = crc32(block, content_crc32).conjugate() - content_md5.update(block) - - data = {'path': path, - 'content-length': content_length, - 'content-md5': content_md5.hexdigest(), - 'slice-md5': slice_md5, - 'content-crc32': '%d' % (content_crc32.conjugate() & 0xFFFFFFFF)} - logging.debug('RAPIDUPLOAD DATA ' + str(data)) - #url = 'http://pan.baidu.com/api/rapidupload' - return self._request('rapidupload', 'rapidupload', data=data, **kwargs) - - def search(self, path, keyword, page=1, recursion=1, limit=1000, **kwargs): - """搜索文件 - - :param path: 搜索目录 - :param keyword: 关键词 - :param page: 返回第几页的数据 - :param recursion: 是否递归搜索,默认为1 (似乎0和1都没影响,都是递归搜索的) - :param limit: 每页条目 - - :return: requests.Repsonse - 返回结果和list_files一样结构 - """ - params = {'dir': path, - 'recursion': recursion, - 'key': keyword, - 'page': page, - 'num': limit} - - #url = 'http://pan.baidu.com/api/search' - - return self._request('search', 'search', extra_params=params, **kwargs) - - def thumbnail(self, path, height, width, quality=100, **kwargs): - """获取文件缩略图 - - :param path: 远程文件路径 - :param height: 缩略图高 - :param width: 缩略图宽 - :param quality: 缩略图质量,默认100 - - :return: requests.Response - - .. note:: - 如果返回 HTTP 404 说明该文件不存在缩略图形式 - """ - params = {'ec': 1, - 'path': path, - 'quality': quality, - 'width': width, - 'height': height} - - url = 'http://{0}/rest/2.0/pcs/thumbnail'.format(BAIDUPCS_SERVER) - return self._request('thumbnail', 'generate', url=url, extra_params=params, **kwargs) - - def meta(self, file_list, **kwargs): - """获得文件(s)的metainfo - - :param file_list: 文件路径列表,如 ['/aaa.txt'] - :type file_list: list - - :return: requests.Response - .. note :: - 示例 - - * 文件不存在 - - {"errno":12,"info":[{"errno":-9}],"request_id":3294861771} - - * 文件存在 - { - "errno": 0, - - "info": [ - - { - - "fs_id": 文件id, - - "path": "\/\u5c0f\u7c73\/mi2s\u5237recovery.rar", - - "server_filename": "mi2s\u5237recovery.rar", - - "size": 8292134, - - "server_mtime": 1391274570, - - "server_ctime": 1391274570, - - "local_mtime": 1391274570, - - "local_ctime": 1391274570, - - "isdir": 0, - - "category": 6, - - "path_md5": 279827390796736883, - - "delete_fs_id": 0, - - "object_key": "84221121-2193956150-1391274570512754", - - "block_list": [ - "76b469302a02b42fd0a548f1a50dd8ac" - ], - - "md5": "76b469302a02b42fd0a548f1a50dd8ac", - - "errno": 0 - - } - - ], - - "request_id": 2964868977 - - } - - """ - if not isinstance(file_list, list): - file_list = [file_list] - data = {'target': json.dumps(file_list)} - - return self._request('filemetas?blocks=0&dlink=1', 'filemetas', data=data, **kwargs) - - def check_file_blocks(self, path, size, block_list, **kwargs): - """文件块检查 - - :param path: 文件路径 - :param size: 文件大小 - :param block_list: 文件块的列表,注意按文件块顺序 - :type block_list: list - - .. note:: - 如果服务器不存在path的文件,则返回中的block_list会等于提交的block_list - - :return: requests.Response - .. note:: - 返回示例 - { - "errno": 0, - "path": "/18.rar", - "request_id": 2462633013, - "block_list": [ - "8da0ac878f3702c0768dc6ea6820d3ff", - "3c1eb99b0e64993f38cd8317788a8855" - ] - } - - 其中block_list是需要上传的块的MD5 - - - - """ - - data = {'path': path, - 'size': size, - 'isdir': 0, - 'block_list': json.dumps(block_list)} - - return self._request('precreate', 'post', data=data, **kwargs) diff --git a/dist/baidupcsapi-0.3.8-py3.5.egg b/dist/baidupcsapi-0.3.8-py3.5.egg deleted file mode 100644 index 4a94851769791027e5db24445f67e230a75d3b65..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 39808 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 Date: Fri, 23 Dec 2016 00:56:28 +0800 Subject: [PATCH 7/9] =?UTF-8?q?=E5=85=BC=E5=AE=B9python3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- baidupcsapi/api.py | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/baidupcsapi/api.py b/baidupcsapi/api.py index a648626..28620d8 100644 --- a/baidupcsapi/api.py +++ b/baidupcsapi/api.py @@ -99,8 +99,8 @@ def wrapper(*args, **kwargs): ret = func(*args, **kwargs) if type(ret) == requests.Response: try: - foo = json.loads(ret.content) - if foo.has_key('errno') and foo['errno'] == -6: + foo = json.loads(ret.content.decode()) + if ('errno' in foo) and foo['errno'] == -6: logging.debug( 'Offline, deleting cookies file then relogin.') path = '.{0}.cookies'.format(args[0].username) @@ -193,14 +193,13 @@ def _initiate(self): def _save_cookies(self): #liuxin 将baidukey写入cookies - cookies_file = '.{0}.cookies'.format(self.username) - with open(cookies_file, 'wb') as f: + with open(cookies_file, 'wb') as cookies_file: pickle.dump( - requests.utils.dict_from_cookiejar(self.session.cookies), f) + requests.utils.dict_from_cookiejar(self.session.cookies), cookies_file) def _load_cookies(self): - #读取cookies中的baidukey + #liuxin 读取cookies中的baidukey cookies_file = '.{0}.cookies'.format(self.username) logging.debug('cookies file:' + cookies_file) if os.path.exists(cookies_file): From 8cdd1da20f7fd26b395af9a03bbf1b3e5a8927d4 Mon Sep 17 00:00:00 2001 From: liuxin Date: Wed, 11 Jan 2017 19:29:35 +0800 Subject: [PATCH 8/9] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E9=A6=96=E6=AC=A1?= =?UTF-8?q?=E7=99=BB=E9=99=86=E9=94=99=E8=AF=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- baidupcsapi/api.py | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/baidupcsapi/api.py b/baidupcsapi/api.py index 28620d8..5b9e2f1 100644 --- a/baidupcsapi/api.py +++ b/baidupcsapi/api.py @@ -208,7 +208,6 @@ def _load_cookies(self): with open(cookies_file,'rb') as cookies_file: cookies = requests.utils.cookiejar_from_dict( pickle.load(cookies_file)) - logging.debug(str(cookies)) self.session.cookies = cookies self.user['BDUSS'] = self.session.cookies['BDUSS'] return True @@ -220,7 +219,7 @@ def _get_token(self): ret = self.session.get( 'https://passport.baidu.com/v2/api/?getapi&tpl=mn&apiver=v3&class=login&tt=%s&logintype=dialogLogin&callback=0' % int(time.time())).text.replace('\'', '\"') foo = json.loads(ret) - logging.info('token %s' % foo['data']['token']) + logging.debug('token %s' % foo['data']['token']) return foo['data']['token'] def _get_captcha(self, code_string): @@ -248,11 +247,13 @@ def _get_publickey(self): def _login(self): # Login #code_string, captcha = self._get_captcha() + captcha = '' code_string = '' pubkey, rsakey = self._get_publickey() key = rsa.PublicKey.load_pkcs1_openssl_pem(pubkey) password_rsaed = base64.b64encode(rsa.encrypt(self.password.encode('utf-8'), key)) + isCheck=False while True: login_data = {'staticpage': 'http://www.baidu.com/cache/user/html/v3Jump.html', 'charset': 'UTF-8', @@ -280,17 +281,21 @@ def _login(self): result = self.session.post( 'https://passport.baidu.com/v2/api/?login', data=login_data) + if self.user['token'].find('the fisrt two args should be string')!=-1: + self._initiate() + break # 是否需要验证码 if 'err_no=257' in result.content.decode() or 'err_no=6' in result.content.decode(): code_string = re.findall('codeString=(.*?)&', result.content.decode())[0] logging.debug('need captcha, codeString=' + code_string) captcha = self._get_captcha(code_string) continue - + isCheck=True break # check exception - self._check_account_exception(result.content) + if isCheck: + self._check_account_exception(result.content) if not result.ok: raise LoginFailed('Logging failed.') @@ -390,6 +395,7 @@ def _request(self, uri, method=None, url=None, extra_params=None, else: response = self.session.get( api, params=params, verify=False, headers=headers, **kwargs) +# print(response.url) return response From db7ab0ec9142d7c4d53f7ef2bde8352d8e671bb7 Mon Sep 17 00:00:00 2001 From: liuxin Date: Fri, 13 Jan 2017 09:15:54 +0800 Subject: [PATCH 9/9] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E7=99=BB=E5=BD=95?= =?UTF-8?q?=E5=8F=AA=E4=BF=9D=E6=8C=8110=E5=88=86=E9=92=9F=E5=B0=B1?= =?UTF-8?q?=E8=A6=81=E8=BE=93=E5=85=A5=E9=AA=8C=E8=AF=81=E7=A0=81=E7=9A=84?= =?UTF-8?q?=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- baidupcsapi/api.py | 84 +++++++++++++++++++++++++++++++--------------- 1 file changed, 57 insertions(+), 27 deletions(-) diff --git a/baidupcsapi/api.py b/baidupcsapi/api.py index 5b9e2f1..de51487 100644 --- a/baidupcsapi/api.py +++ b/baidupcsapi/api.py @@ -217,9 +217,10 @@ def _load_cookies(self): def _get_token(self): # Token ret = self.session.get( - 'https://passport.baidu.com/v2/api/?getapi&tpl=mn&apiver=v3&class=login&tt=%s&logintype=dialogLogin&callback=0' % int(time.time())).text.replace('\'', '\"') - foo = json.loads(ret) - logging.debug('token %s' % foo['data']['token']) + 'https://passport.baidu.com/v2/api/?getapi&tpl=netdisk' + '&apiver=v3&tt={}&class=login&logintype=basicLogin'.format(int(time.time()))) + foo = json.loads(ret.content.decode().replace('\'', '"')) + logging.info('token %s' % foo['data']['token']) return foo['data']['token'] def _get_captcha(self, code_string): @@ -255,35 +256,65 @@ def _login(self): password_rsaed = base64.b64encode(rsa.encrypt(self.password.encode('utf-8'), key)) isCheck=False while True: - login_data = {'staticpage': 'http://www.baidu.com/cache/user/html/v3Jump.html', - 'charset': 'UTF-8', - 'token': self.user['token'], - 'tpl': 'pp', - 'subpro': '', - 'apiver': 'v3', - 'tt': str(int(time.time())), - 'codestring': code_string, - 'isPhone': 'false', - 'safeflg': '0', - 'u': 'https://passport.baidu.com/', - 'quick_user': '0', - 'logLoginType': 'pc_loginBasic', - 'loginmerge': 'true', - 'logintype': 'basicLogin', - 'username': self.username, - 'password': password_rsaed, - 'verifycode': captcha, - 'mem_pass': 'on', - 'rsakey': str(rsakey), - 'crypttype': 12, - 'ppui_logintime': '50918', - 'callback': 'parent.bd__pcbs__oa36qm'} + + login_data = { +# 'staticpage': 'http://www.baidu.com/cache/user/html/v3Jump.html', +# 'charset': 'UTF-8', +# 'token': self.user['token'], +# 'tpl': 'pp', +# 'subpro': '', +# 'apiver': 'v3', +# 'tt': str(int(time.time())), +# 'codestring': code_string, +# 'isPhone': 'false', +# 'safeflg': '0', +# 'u': 'https://passport.baidu.com/', +# 'quick_user': '0', +# 'logLoginType': 'pc_loginBasic', +# 'loginmerge': 'true', +# 'logintype': 'basicLogin', +# 'username': self.username, +# 'password': password_rsaed, +# 'verifycode': captcha, +# 'mem_pass': 'on', +# 'rsakey': str(rsakey), +# 'crypttype': 12, +# 'ppui_logintime': '50918', +# 'callback': 'parent.bd__pcbs__oa36qm' + "staticpage": "http://pan.baidu.com/res/static/thirdparty/pass_v3_jump.html", + "charset": "utf-8", + "token": self.user['token'], + "tpl": "netdisk", + "subpro": "", + "apiver": "v3", + "tt": int(time.time()), + "codestring": code_string, + "safeflg": "0", + "u": "http://pan.baidu.com/", + "isPhone": "", + "quick_user": "0", + "logintype": "basicLogin", + "logLoginType": "pc_loginBasic", + "idc": "", + "loginmerge": "true", + "username": self.username, + "password": self.password, + "verifycode": captcha, + "mem_pass": "on", + "rsakey": str(rsakey), + "crypttype": "", + "ppui_logintime": "2602", + "callback": "parent.bd__pcbs__ahhlgk", + } +# if captcha=='': +# del login_data['verifycode'] result = self.session.post( 'https://passport.baidu.com/v2/api/?login', data=login_data) if self.user['token'].find('the fisrt two args should be string')!=-1: self._initiate() break + # 是否需要验证码 if 'err_no=257' in result.content.decode() or 'err_no=6' in result.content.decode(): code_string = re.findall('codeString=(.*?)&', result.content.decode())[0] @@ -395,7 +426,6 @@ def _request(self, uri, method=None, url=None, extra_params=None, else: response = self.session.get( api, params=params, verify=False, headers=headers, **kwargs) -# print(response.url) return response