8
8
9
9
from app .chain import ChainBase
10
10
from app .core .config import settings
11
- from app .core .event import eventmanager , Event
11
+ from app .core .event import eventmanager , Event , EventManager
12
12
from app .db .models .site import Site
13
13
from app .db .site_oper import SiteOper
14
14
from app .db .siteicon_oper import SiteIconOper
15
15
from app .helper .browser import PlaywrightHelper
16
16
from app .helper .cloudflare import under_challenge
17
17
from app .helper .cookie import CookieHelper
18
+ from app .helper .cookiecloud import CookieCloudHelper
18
19
from app .helper .message import MessageHelper
20
+ from app .helper .rss import RssHelper
19
21
from app .helper .sites import SitesHelper
20
22
from app .log import logger
21
23
from app .schemas import MessageChannel , Notification
@@ -35,8 +37,14 @@ def __init__(self):
35
37
self .siteoper = SiteOper ()
36
38
self .siteiconoper = SiteIconOper ()
37
39
self .siteshelper = SitesHelper ()
40
+ self .rsshelper = RssHelper ()
38
41
self .cookiehelper = CookieHelper ()
39
42
self .message = MessageHelper ()
43
+ self .cookiecloud = CookieCloudHelper (
44
+ server = settings .COOKIECLOUD_HOST ,
45
+ key = settings .COOKIECLOUD_KEY ,
46
+ password = settings .COOKIECLOUD_PASSWORD
47
+ )
40
48
41
49
# 特殊站点登录验证
42
50
self .special_site_test = {
@@ -127,6 +135,105 @@ def __parse_favicon(url: str, cookie: str, ua: str) -> Tuple[str, Optional[str]]
127
135
logger .error (f"获取站点图标失败:{ favicon_url } " )
128
136
return favicon_url , None
129
137
138
+ def sync_cookies (self , manual = False ) -> Tuple [bool , str ]:
139
+ """
140
+ 通过CookieCloud同步站点Cookie
141
+ """
142
+ logger .info ("开始同步CookieCloud站点 ..." )
143
+ cookies , msg = self .cookiecloud .download ()
144
+ if not cookies :
145
+ logger .error (f"CookieCloud同步失败:{ msg } " )
146
+ if manual :
147
+ self .message .put (f"CookieCloud同步失败: { msg } " )
148
+ return False , msg
149
+ # 保存Cookie或新增站点
150
+ _update_count = 0
151
+ _add_count = 0
152
+ _fail_count = 0
153
+ for domain , cookie in cookies .items ():
154
+ # 获取站点信息
155
+ indexer = self .siteshelper .get_indexer (domain )
156
+ site_info = self .siteoper .get_by_domain (domain )
157
+ if site_info :
158
+ # 检查站点连通性
159
+ status , msg = self .test (domain )
160
+ # 更新站点Cookie
161
+ if status :
162
+ logger .info (f"站点【{ site_info .name } 】连通性正常,不同步CookieCloud数据" )
163
+ # 更新站点rss地址
164
+ if not site_info .public and not site_info .rss :
165
+ # 自动生成rss地址
166
+ rss_url , errmsg = self .rsshelper .get_rss_link (
167
+ url = site_info .url ,
168
+ cookie = cookie ,
169
+ ua = settings .USER_AGENT ,
170
+ proxy = True if site_info .proxy else False
171
+ )
172
+ if rss_url :
173
+ logger .info (f"更新站点 { domain } RSS地址 ..." )
174
+ self .siteoper .update_rss (domain = domain , rss = rss_url )
175
+ else :
176
+ logger .warn (errmsg )
177
+ continue
178
+ # 更新站点Cookie
179
+ logger .info (f"更新站点 { domain } Cookie ..." )
180
+ self .siteoper .update_cookie (domain = domain , cookies = cookie )
181
+ _update_count += 1
182
+ elif indexer :
183
+ # 新增站点
184
+ res = RequestUtils (cookies = cookie ,
185
+ ua = settings .USER_AGENT
186
+ ).get_res (url = indexer .get ("domain" ))
187
+ if res and res .status_code in [200 , 500 , 403 ]:
188
+ if not indexer .get ("public" ) and not SiteUtils .is_logged_in (res .text ):
189
+ _fail_count += 1
190
+ if under_challenge (res .text ):
191
+ logger .warn (f"站点 { indexer .get ('name' )} 被Cloudflare防护,无法登录,无法添加站点" )
192
+ continue
193
+ logger .warn (
194
+ f"站点 { indexer .get ('name' )} 登录失败,没有该站点账号或Cookie已失效,无法添加站点" )
195
+ continue
196
+ elif res is not None :
197
+ _fail_count += 1
198
+ logger .warn (f"站点 { indexer .get ('name' )} 连接状态码:{ res .status_code } ,无法添加站点" )
199
+ continue
200
+ else :
201
+ _fail_count += 1
202
+ logger .warn (f"站点 { indexer .get ('name' )} 连接失败,无法添加站点" )
203
+ continue
204
+ # 获取rss地址
205
+ rss_url = None
206
+ if not indexer .get ("public" ) and indexer .get ("domain" ):
207
+ # 自动生成rss地址
208
+ rss_url , errmsg = self .rsshelper .get_rss_link (url = indexer .get ("domain" ),
209
+ cookie = cookie ,
210
+ ua = settings .USER_AGENT )
211
+ if errmsg :
212
+ logger .warn (errmsg )
213
+ # 插入数据库
214
+ logger .info (f"新增站点 { indexer .get ('name' )} ..." )
215
+ self .siteoper .add (name = indexer .get ("name" ),
216
+ url = indexer .get ("domain" ),
217
+ domain = domain ,
218
+ cookie = cookie ,
219
+ rss = rss_url ,
220
+ public = 1 if indexer .get ("public" ) else 0 )
221
+ _add_count += 1
222
+
223
+ # 通知缓存站点图标
224
+ if indexer :
225
+ EventManager ().send_event (EventType .CacheSiteIcon , {
226
+ "domain" : domain ,
227
+ })
228
+ # 处理完成
229
+ ret_msg = f"更新了{ _update_count } 个站点,新增了{ _add_count } 个站点"
230
+ if _fail_count > 0 :
231
+ ret_msg += f",{ _fail_count } 个站点添加失败,下次同步时将重试,也可以手动添加"
232
+ if manual :
233
+ self .message .put (f"CookieCloud同步成功, { ret_msg } " )
234
+ logger .info (f"CookieCloud同步成功:{ ret_msg } " )
235
+ return True , ret_msg
236
+
130
237
@eventmanager .register (EventType .CacheSiteIcon )
131
238
def cache_site_icon (self , event : Event ):
132
239
"""
0 commit comments