1
+ import os
1
2
import json
2
3
3
- from typing import Tuple , Optional
4
+ from typing import Any , Dict , Tuple , Optional
4
5
from hashlib import md5
5
6
6
7
from app .utils .http import RequestUtils
@@ -12,83 +13,108 @@ class CookieCloudHelper:
12
13
13
14
_ignore_cookies : list = ["CookieAutoDeleteBrowsingDataCleanup" , "CookieAutoDeleteCleaningDiscarded" ]
14
15
15
- def __init__ (self , server : str , key : str , password : str ):
16
+ def __init__ (self , server : str , key : str , password : str , enable_local : bool , local_path : str ):
16
17
self ._server = server
17
18
self ._key = key
18
19
self ._password = password
20
+ self ._enable_local = enable_local
21
+ self ._local_path = local_path
19
22
self ._req = RequestUtils (content_type = "application/json" )
20
23
21
24
def download (self ) -> Tuple [Optional [dict ], str ]:
22
25
"""
23
26
从CookieCloud下载数据
24
27
:return: Cookie数据、错误信息
25
28
"""
26
- if not self ._server or not self ._key or not self ._password :
29
+ if (not self ._server and
30
+ not self ._enable_local ) or not self ._key or not self ._password :
27
31
return None , "CookieCloud参数不正确"
28
- req_url = "%s/get/%s" % (self ._server , str (self ._key ).strip ())
29
- ret = self ._req .get_res (url = req_url )
30
- if ret and ret .status_code == 200 :
31
- result = ret .json ()
32
- if not result :
33
- return {}, "未下载到数据"
34
- encrypted = result .get ("encrypted" )
35
- if not encrypted :
36
- return {}, "未获取到cookie密文"
37
- else :
38
- crypt_key = self .get_crypt_key ()
39
- try :
40
- decrypted_data = decrypt (encrypted , crypt_key ).decode ('utf-8' )
41
- result = json .loads (decrypted_data )
42
- except Exception as e :
43
- return {}, "cookie解密失败" + str (e )
44
32
33
+ result = None
34
+ if self ._enable_local :
35
+ # 开启本地服务时,从本地直接读取数据
36
+ result = self .load_local_encrypt_data (self ._key )
45
37
if not result :
46
- return {}, "cookie解密为空"
47
-
48
- if result .get ("cookie_data" ):
49
- contents = result .get ("cookie_data" )
38
+ return {}, "未从本地CookieCloud服务加载到cookie数据"
39
+ else :
40
+ req_url = "%s/get/%s" % (self ._server , str (self ._key ).strip ())
41
+ ret = self ._req .get_res (url = req_url )
42
+ if ret and ret .status_code == 200 :
43
+ result = ret .json ()
44
+ if not result :
45
+ return {}, "未从" + self ._server + "下载到数据"
46
+ elif ret :
47
+ return None , f"远程同步CookieCloud失败,错误码:{ ret .status_code } "
50
48
else :
51
- contents = result
52
- # 整理数据,使用domain域名的最后两级作为分组依据
53
- domain_groups = {}
54
- for site , cookies in contents .items ():
55
- for cookie in cookies :
56
- domain_key = StringUtils .get_url_domain (cookie .get ("domain" ))
57
- if not domain_groups .get (domain_key ):
58
- domain_groups [domain_key ] = [cookie ]
59
- else :
60
- domain_groups [domain_key ].append (cookie )
61
- # 返回错误
62
- ret_cookies = {}
63
- # 索引器
64
- for domain , content_list in domain_groups .items ():
65
- if not content_list :
66
- continue
67
- # 只有cf的cookie过滤掉
68
- cloudflare_cookie = True
69
- for content in content_list :
70
- if content ["name" ] != "cf_clearance" :
71
- cloudflare_cookie = False
72
- break
73
- if cloudflare_cookie :
74
- continue
75
- # 站点Cookie
76
- cookie_str = ";" .join (
77
- [f"{ content .get ('name' )} ={ content .get ('value' )} "
78
- for content in content_list
79
- if content .get ("name" ) and content .get ("name" ) not in self ._ignore_cookies ]
80
- )
81
- ret_cookies [domain ] = cookie_str
82
- return ret_cookies , ""
83
- elif ret :
84
- return None , f"同步CookieCloud失败,错误码:{ ret .status_code } "
49
+ return None , "CookieCloud请求失败,请检查服务器地址、用户KEY及加密密码是否正确"
50
+
51
+ encrypted = result .get ("encrypted" )
52
+ if not encrypted :
53
+ return {}, "未获取到cookie密文"
85
54
else :
86
- return None , "CookieCloud请求失败,请检查服务器地址、用户KEY及加密密码是否正确"
87
-
55
+ crypt_key = self .get_crypt_key ()
56
+ try :
57
+ decrypted_data = decrypt (encrypted , crypt_key ).decode ('utf-8' )
58
+ result = json .loads (decrypted_data )
59
+ except Exception as e :
60
+ return {}, "cookie解密失败" + str (e )
61
+
62
+ if not result :
63
+ return {}, "cookie解密为空"
64
+
65
+ if result .get ("cookie_data" ):
66
+ contents = result .get ("cookie_data" )
67
+ else :
68
+ contents = result
69
+ # 整理数据,使用domain域名的最后两级作为分组依据
70
+ domain_groups = {}
71
+ for site , cookies in contents .items ():
72
+ for cookie in cookies :
73
+ domain_key = StringUtils .get_url_domain (cookie .get ("domain" ))
74
+ if not domain_groups .get (domain_key ):
75
+ domain_groups [domain_key ] = [cookie ]
76
+ else :
77
+ domain_groups [domain_key ].append (cookie )
78
+ # 返回错误
79
+ ret_cookies = {}
80
+ # 索引器
81
+ for domain , content_list in domain_groups .items ():
82
+ if not content_list :
83
+ continue
84
+ # 只有cf的cookie过滤掉
85
+ cloudflare_cookie = True
86
+ for content in content_list :
87
+ if content ["name" ] != "cf_clearance" :
88
+ cloudflare_cookie = False
89
+ break
90
+ if cloudflare_cookie :
91
+ continue
92
+ # 站点Cookie
93
+ cookie_str = ";" .join (
94
+ [f"{ content .get ('name' )} ={ content .get ('value' )} "
95
+ for content in content_list
96
+ if content .get ("name" ) and content .get ("name" ) not in self ._ignore_cookies ]
97
+ )
98
+ ret_cookies [domain ] = cookie_str
99
+ return ret_cookies , ""
100
+
88
101
def get_crypt_key (self ) -> bytes :
89
102
"""
90
103
使用UUID和密码生成CookieCloud的加解密密钥
91
104
"""
92
105
md5_generator = md5 ()
93
106
md5_generator .update ((str (self ._key ).strip () + '-' + str (self ._password ).strip ()).encode ('utf-8' ))
94
107
return (md5_generator .hexdigest ()[:16 ]).encode ('utf-8' )
108
+
109
+ def load_local_encrypt_data (self ,uuid : str ) -> Dict [str , Any ]:
110
+ file_path = os .path .join (self ._local_path , os .path .basename (uuid ) + ".json" )
111
+
112
+ # 检查文件是否存在
113
+ if not os .path .exists (file_path ):
114
+ return None
115
+
116
+ # 读取文件
117
+ with open (file_path , encoding = "utf-8" , mode = "r" ) as file :
118
+ read_content = file .read ()
119
+ data = json .loads (read_content )
120
+ return data
0 commit comments