def user_info(self): bduss = self._bduss timestamp = str(int(time.time())) model = get_phone_model(bduss) phoneIMEIStr = sum_IMEI(bduss) data = { "bdusstoken": bduss + "|null", "channel_id": "", "channel_uid": "", "stErrorNums": "0", "subapp_type": "mini", "timestamp": timestamp + "922", } data["_client_type"] = "2" data["_client_version"] = "7.0.0.0" data["_phone_imei"] = phoneIMEIStr data["from"] = "mini_ad_wandoujia" data["model"] = model data["cuid"] = ( calu_md5( bduss + "_" + data["_client_version"] + "_" + data["_phone_imei"] + "_" + data["from"] ).upper() + "|" + phoneIMEIStr[::-1] ) data["sign"] = calu_md5( "".join([k + "=" + data[k] for k in sorted(data.keys())]) + "tiebaclient!!!" ).upper() headers = { "Content-Type": "application/x-www-form-urlencoded", "Cookie": "ka=open", "net": "1", "User-Agent": "bdtb for Android 6.9.2.1", "client_logid": timestamp + "416", "Connection": "Keep-Alive", } resp = requests.post( "http://tieba.baidu.com/c/s/login", headers=headers, data=data ) return resp.json()
def download_link(self, remotepath: str, pcs: bool = False): if pcs: return { "errno": 0, "urls": [{ "url": ("http://c.pcs.baidu.com/rest/2.0/pcs/file" f"?method=download&app_id={PCS_APP_ID}&path={quote_plus(remotepath)}" "&ver=2.0&clienttype=1") }], } bduss = self._bduss uid = str(self._user_id) or "" timestamp = str(int(time.time() * 1000)) devuid = "0|" + calu_md5(bduss).upper() enc = calu_sha1(bduss) rand = calu_sha1(enc + uid + "ebrcUYiuxaZv2XGu7KIYKxUrqfnOfpDF" + timestamp + devuid) url = self._form_url(PcsNode.File, domain=PCS_BAIDU_COM) params = { "method": "locatedownload", "ver": "2", "path": remotepath, "time": timestamp, "rand": rand, "devuid": devuid, } resp = self._request(Method.Get, url, params=params) return resp.json()
def shared_password(self, share_id: int): """ Only return password """ url = PanNode.SharedPassword.url() params = { "shareid": str(share_id), "sign": calu_md5(f"{share_id}_sharesurlinfo!@#"), } resp = self._request(Method.Get, url, params=params) return resp.json()
def shared_password(self, share_id: int): """ Only return password """ url = self._form_url(PcsNode.SharedPassword, domain=PAN_BAIDU_COM) params = { "shareid": str(share_id), "sign": calu_md5(f"{share_id}_sharesurlinfo!@#"), } resp = self._request(Method.Get, url, params=params) return resp.json()
def tieba_user_info(self, user_id: int): params = f"has_plist=0&need_post_count=1&rn=1&uid={user_id}" params += "&sign=" + calu_md5(params.replace("&", "") + "tiebaclient!!!") url = "http://c.tieba.baidu.com/c/u/user/profile?" + params headers = { "Content-Type": "application/x-www-form-urlencoded", "Cookie": "ka=open", "net": "1", "User-Agent": "bdtb for Android 6.9.2.1", "client_logid": str(int(time.time() * 1000)), "Connection": "Keep-Alive", } resp = requests.get(url, headers=headers, params=None) return resp.json()
def download_link(self, remotepath: str, pcs: bool = False) -> Optional[str]: if pcs: return ( "http://c.pcs.baidu.com/rest/2.0/pcs/file" f"?method=download&app_id={PCS_APP_ID}&path={quote_plus(remotepath)}" "&ver=2.0&clienttype=1") bduss = self._bduss uid = str(self._user_id) or "" devuid = "0|" + calu_md5(bduss).upper() enc = calu_sha1(bduss) while True: timestamp = str(now_timestamp() * 1000) rand = calu_sha1(enc + uid + "ebrcUYiuxaZv2XGu7KIYKxUrqfnOfpDF" + timestamp + devuid) url = PcsNode.File.url() params = { "method": "locatedownload", "ver": "2", "path": remotepath, "time": timestamp, "rand": rand, "devuid": devuid, } resp = self._request(Method.Get, url, params=params) # Error: "user is not authorized" # This error occurs when the method is called by too many times if not resp.ok: time.sleep(2) continue info = resp.json() # This error is gotten when remote path is blocked if info.get("host") == "issuecdn.baidupcs.com": return None if not info.get("urls"): return None else: return info["urls"][0]["url"]
def __init__( self, bduss: Optional[str] = None, stoken: Optional[str] = None, ptoken: Optional[str] = None, cookies: Dict[str, Optional[str]] = {}, user_id: Optional[int] = None, ): if not bduss and cookies and cookies.get("BDUSS", ""): bduss = cookies["BDUSS"] if not stoken and cookies and cookies.get("STOKEN", ""): stoken = cookies["STOKEN"] if not ptoken and cookies and cookies.get("PTOKEN", ""): ptoken = cookies["PTOKEN"] assert bduss, "`bduss` must be set. Or `BDUSS` is in `cookies`." if not cookies: cookies = {"BDUSS": bduss, "STOKEN": stoken, "PTOKEN": ptoken} self._bduss = bduss self._stoken = stoken self._ptoken = ptoken self._bdstoken = calu_md5(bduss) self._logid = None self._baiduid = cookies.get("BAIDUID") if self._baiduid: self._logid = standard_b64encode( self._baiduid.encode("ascii")).decode("utf-8") self._cookies = cookies self._session = requests.Session() self._session.cookies.update(cookies) user_info = None if not user_id: user_info = self.user_info() user_id = user_info.get("user", {}).get("id") if not user_id: user_info = None self._user_id = user_id self._user_info = user_info
def rapid_upload_params(io: IO) -> Tuple[str, str, int, int]: io_len = 0 chunk_size = constant.OneM crc32_v = 0 md5_v = hashlib.md5() buf = io.read(256 * constant.OneK) io_len += len(buf) slice_md5 = calu_md5(buf) md5_v.update(buf) t = io.read(chunk_size - 256 * constant.OneK) io_len += len(t) md5_v.update(t) buf += t crc32_v = crc32(buf, crc32_v).conjugate() # content_crc32, content_md5 = calu_crc32_and_md5(io, constant.OneM) while True: buf = io.read(chunk_size) if buf: md5_v.update(buf) crc32_v = crc32(buf, crc32_v).conjugate() io_len += len(buf) else: break content_crc32, content_md5 = crc32_v.conjugate( ) & 0xFFFFFFFF, md5_v.hexdigest() # if isinstance(io, EncryptIO): # io_len = len(io) # else: # io_len = io.seek(0, 2) # io.seek(0, 0) return slice_md5, content_md5, content_crc32, io_len
def rapid_upload_info(self, remotepath: str, check: bool = True) -> Optional[PcsRapidUploadInfo]: pcs_file = self.meta(remotepath)[0] content_length = pcs_file.size if content_length < 256 * constant.OneK: return None fs = self.file_stream(remotepath, pcs=False) if not fs: return None data = fs.read(256 * constant.OneK) assert data and len(data) == 256 * constant.OneK slice_md5 = calu_md5(data) assert (content_length and content_length == fs._auto_decrypt_request.content_length) content_md5 = fs._auto_decrypt_request.content_md5 content_crc32 = fs._auto_decrypt_request.content_crc32 or 0 if not content_md5: return None block_list = pcs_file.block_list if block_list and len( block_list) == 1 and block_list[0] == pcs_file.md5: return PcsRapidUploadInfo( slice_md5=slice_md5, content_md5=content_md5, content_crc32=content_crc32, content_length=content_length, remotepath=pcs_file.path, ) if check: try: # Try rapid_upload_file self.rapid_upload_file( slice_md5, content_md5, content_crc32, content_length, pcs_file.path, local_ctime=pcs_file.local_ctime, local_mtime=pcs_file.local_mtime, ondup="overwrite", ) except BaiduPCSError as err: # 31079: "未找到文件MD5" if err.error_code != 31079: raise err return None return PcsRapidUploadInfo( slice_md5=slice_md5, content_md5=content_md5, content_crc32=content_crc32, content_length=content_length, remotepath=pcs_file.path, )
def rapid_upload_params2(localPath: Path) -> Tuple[str, str, int, int]: buf = localPath.open("rb").read(constant.OneM) slice_md5 = calu_md5(buf[:256 * constant.OneK]) content_crc32, content_md5 = calu_crc32_and_md5(localPath.open("rb"), constant.OneM) return slice_md5, content_md5, content_crc32, localPath.stat().st_size
def bdstoken(self) -> Optional[str]: bdstoken = calu_md5(self._bduss) return bdstoken
def test_localstorage(): db_path = "./test_rapid_upload.db" db = RapidUploadInfo(db_path) rows = [ ( "abc", "/localpath/abc", "/remotepath/abc", calu_md5(b"sdfdf"), calu_md5("ggg"), 0, 9599, b"pwd", "Simple", None, "peter", ), ( "ryhg", "/localpath/ryhg", "/remotepath/ryhg", calu_md5(b"sdfdf"), calu_md5("ggg"), 0, 959, b"pwd", "Simple", None, "tim", ), ( "9553", "/localpath/9553", "/remotepath/9553", calu_md5(b"sdfdf"), calu_md5("ggg"), 0, 59, b"pwd", "Simple", None, "moo", ), ] for r in rows: db.insert(*r) r = db.list(desc=False, limit=1, offset=1) for i in r: print(i) r = db.search("a") for i in r: print(i) db.delete(1) r = db.list() for i in r: print(i)