-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
13 changed files
with
361 additions
and
15 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +0,0 @@ | ||
from .imbot import nbmod | ||
from . import api | ||
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
from __future__ import annotations | ||
|
||
import os | ||
import sys | ||
import json | ||
|
||
|
||
class CacheManager: | ||
|
||
data: dict | ||
|
||
file: str | ||
|
||
def __init__(self, file: str="cache.json"): | ||
self.data = {} | ||
self.file = file | ||
|
||
if not os.path.exists(file): | ||
with open(file, "w", encoding="utf-8") as f: | ||
json.dump({}, f) | ||
|
||
def load(self): | ||
with open(self.file, "r", encoding="utf-8") as f: | ||
self.data = json.load(f) | ||
|
||
def save(self): | ||
with open(self.file, "w", encoding="utf-8") as f: | ||
json.dump(self.data, f) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,27 +1,64 @@ | ||
from __future__ import annotations | ||
|
||
import asyncio | ||
import threading | ||
|
||
import nonebot, nonebot.config | ||
from nonebot.adapters.onebot.v11 import Adapter as OnebotAdapter # 避免重复命名 | ||
|
||
from ..api import api | ||
from ..mq import redis | ||
from ..social import mgr as social_mgr | ||
from ..imbot import mgr as imbot_mgr | ||
from ..common import cache as cache_mgr | ||
|
||
|
||
class Application: | ||
|
||
cache: cache_mgr.CacheManager | ||
|
||
@property | ||
def cpx_api(self) -> api.CampuxAPI: | ||
return api.campux_api | ||
|
||
@property | ||
def config(self) -> nonebot.config.Config: | ||
return nonebot.get_driver().config | ||
|
||
mq: redis.RedisStreamMQ | ||
|
||
social: social_mgr.SocialPlatformManager | ||
|
||
imbot: imbot_mgr.IMBotManager | ||
|
||
async def run(self): | ||
|
||
def nonebot_thread(): | ||
nonebot.run() | ||
|
||
threading.Thread(target=nonebot_thread).start() | ||
|
||
# while True: | ||
# await asyncio.sleep(5) | ||
|
||
async def create_app() -> Application: | ||
|
||
# 注册适配器 | ||
driver = nonebot.get_driver() | ||
driver.register_adapter(OnebotAdapter) | ||
|
||
# 在这里加载插件 | ||
nonebot.load_plugin("campux.imbot.nbmod") # 本地插件 | ||
|
||
# 缓存管理器 | ||
cache = cache_mgr.CacheManager() | ||
cache.load() | ||
|
||
def create_app() -> Application: | ||
ap = Application() | ||
ap.cache = cache | ||
|
||
ap.mq = redis.RedisStreamMQ(ap) | ||
ap.social = social_mgr.SocialPlatformManager(ap) | ||
await ap.social.initialize() | ||
ap.imbot = imbot_mgr.IMBotManager(ap) | ||
return ap | ||
return ap |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,14 +1,44 @@ | ||
from __future__ import annotations | ||
|
||
import asyncio | ||
|
||
import nonebot | ||
|
||
from ..core import app | ||
from .qzone import api as qzone_api | ||
|
||
|
||
class SocialPlatformManager: | ||
|
||
ap: app.Application | ||
|
||
platform_api: qzone_api.QzoneAPI | ||
|
||
current_invalid_cookies: dict = None | ||
|
||
def __init__(self, ap: app.Application): | ||
self.ap = ap | ||
self.platform_api = qzone_api.QzoneAPI(ap) | ||
|
||
async def initialize(self): | ||
async def schedule_loop(): | ||
await asyncio.sleep(15) | ||
while True: | ||
asyncio.create_task(self.schedule_task()) | ||
await asyncio.sleep(30) | ||
|
||
asyncio.create_task(schedule_loop()) | ||
|
||
async def schedule_task(self): | ||
# 检查cookies是否失效 | ||
if not await self.platform_api.token_valid() and self.platform_api.cookies != self.current_invalid_cookies: | ||
|
||
await self.ap.imbot.send_private_message( | ||
self.ap.config.campux_qq_admin_uin, | ||
"QQ空间cookies已失效,请发送 #更新cookies 命令进行重新登录。" | ||
) | ||
|
||
self.current_invalid_cookies = self.platform_api.cookies | ||
|
||
async def publish_post(self, post_id: int): | ||
pass |
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,104 @@ | ||
from __future__ import annotations | ||
|
||
import asyncio | ||
import json | ||
import traceback | ||
|
||
from nonebot import logger | ||
import nonebot.adapters.onebot.v11.message as message | ||
import requests | ||
|
||
from ...core import app | ||
from . import login | ||
|
||
|
||
def generate_gtk(skey) -> str: | ||
"""生成gtk""" | ||
hash_val = 5381 | ||
for i in range(len(skey)): | ||
hash_val += (hash_val << 5) + ord(skey[i]) | ||
return str(hash_val & 2147483647) | ||
|
||
GET_VISITOR_AMOUNT_URL="https://h5.qzone.qq.com/proxy/domain/g.qzone.qq.com/cgi-bin/friendshow/cgi_get_visitor_more?uin={}&mask=7&g_tk={}&page=1&fupdate=1&clear=1" | ||
|
||
class QzoneAPI: | ||
|
||
ap: app.Application | ||
|
||
cookies: dict | ||
|
||
gtk2: str | ||
|
||
uin: int | ||
|
||
def __init__(self, ap: app.Application, cookies_dict: dict={}): | ||
self.ap = ap | ||
self.cookies = cookies_dict | ||
self.gtk2 = '' | ||
self.uin = 0 | ||
|
||
if 'qzone_cookies' in self.ap.cache.data and not cookies_dict and self.ap.cache.data['qzone_cookies']: | ||
self.cookies = self.ap.cache.data['qzone_cookies'] | ||
|
||
if 'p_skey' in self.cookies: | ||
self.gtk2 = generate_gtk(self.cookies['p_skey']) | ||
|
||
if 'uin' in self.cookies: | ||
self.uin = int(self.cookies['uin'][1:]) | ||
|
||
async def token_valid(self) -> bool: | ||
try: | ||
today, total = await self.get_visitor_amount() | ||
logger.info("检查cookies有效性结果:{}, {}".format(today, total)) | ||
return True | ||
except Exception as e: | ||
traceback.print_exc() | ||
return False | ||
|
||
async def relogin(self): | ||
loginmgr = login.QzoneLogin() | ||
|
||
async def qrcode_callback(content: bytes): | ||
asyncio.create_task(self.ap.imbot.send_private_message( | ||
self.ap.config.campux_qq_admin_uin, | ||
message=[ | ||
message.MessageSegment.text("请使用QQ扫描以下二维码以登录QQ空间:"), | ||
message.MessageSegment.image(content) | ||
] | ||
)) | ||
|
||
self.cookies = await loginmgr.login_via_qrcode(qrcode_callback) | ||
|
||
if 'p_skey' in self.cookies: | ||
self.gtk2 = generate_gtk(self.cookies['p_skey']) | ||
|
||
if 'uin' in self.cookies: | ||
self.uin = int(self.cookies['uin'][1:]) | ||
|
||
asyncio.create_task(self.ap.imbot.send_private_message( | ||
self.ap.config.campux_qq_admin_uin, | ||
"登录流程完成。" | ||
)) | ||
|
||
self.ap.cache.data['qzone_cookies'] = self.cookies | ||
self.ap.cache.save() | ||
|
||
async def get_visitor_amount(self) -> tuple[int, int]: | ||
"""获取空间访客信息 | ||
Returns: | ||
tuple[int, int]: 今日访客数, 总访客数 | ||
""" | ||
res = requests.get( | ||
url=GET_VISITOR_AMOUNT_URL.format(self.uin, self.gtk2), | ||
cookies=self.cookies, | ||
timeout=10 | ||
) | ||
json_text = res.text.replace("_Callback(", '')[:-3] | ||
|
||
try: | ||
json_obj = json.loads(json_text) | ||
visit_count = json_obj['data'] | ||
return visit_count['todaycount'], visit_count['totalcount'] | ||
except Exception as e: | ||
raise e |
Oops, something went wrong.