add plugins

This commit is contained in:
jxxghp
2023-06-08 13:18:26 +08:00
parent 7c3f233a10
commit c7d745a752
49 changed files with 4383 additions and 73 deletions

View File

@@ -0,0 +1,145 @@
import random
import re
from typing import Tuple
from lxml import etree
from app.core import settings
from app.log import logger
from app.plugins.autosignin.sites import _ISiteSigninHandler
from app.utils.http import RequestUtils
from app.utils.string import StringUtils
class FWpt(_ISiteSigninHandler):
"""
52pt
如果填写openai key则调用chatgpt获取答案
否则随机
"""
# 匹配的站点Url每一个实现类都需要设置为自己的站点Url
site_url = "52pt.site"
# 已签到
_sign_regex = ['今天已经签过到了']
# 签到成功,待补充
_success_regex = ['\\d+点魔力值']
@classmethod
def match(cls, url: str) -> bool:
"""
根据站点Url判断是否匹配当前站点签到类大部分情况使用默认实现即可
:param url: 站点Url
:return: 是否匹配如匹配则会调用该类的signin方法
"""
return True if StringUtils.url_equal(url, cls.site_url) else False
def signin(self, site_info: dict) -> Tuple[bool, str]:
"""
执行签到操作
:param site_info: 站点信息含有站点Url、站点Cookie、UA等信息
:return: 签到结果信息
"""
site = site_info.get("name")
site_cookie = site_info.get("cookie")
ua = site_info.get("ua")
proxy = settings.PROXY if site_info.get("proxy") else None
# 判断今日是否已签到
index_res = RequestUtils(cookies=site_cookie,
headers=ua,
proxies=proxy
).get_res(url='https://52pt.site/bakatest.php')
if not index_res or index_res.status_code != 200:
logger.error(f"签到失败,请检查站点连通性")
return False, f'{site}】签到失败,请检查站点连通性'
if "login.php" in index_res.text:
logger.error(f"签到失败Cookie失效")
return False, f'{site}】签到失败Cookie失效'
sign_status = self.sign_in_result(html_res=index_res.text,
regexs=self._sign_regex)
if sign_status:
logger.info(f"今日已签到")
return True, f'{site}】今日已签到'
# 没有签到则解析html
html = etree.HTML(index_res.text)
if not html:
return False, f'{site}】签到失败'
# 获取页面问题、答案
questionid = html.xpath("//input[@name='questionid']/@value")[0]
option_ids = html.xpath("//input[@name='choice[]']/@value")
question_str = html.xpath("//td[@class='text' and contains(text(),'请问:')]/text()")[0]
# 正则获取问题
match = re.search(r'请问:(.+)', question_str)
if match:
question_str = match.group(1)
logger.debug(f"获取到签到问题 {question_str}")
else:
logger.error(f"未获取到签到问题")
return False, f"{site}】签到失败,未获取到签到问题"
# 正确答案默认随机如果gpt返回则用gpt返回的答案提交
choice = [option_ids[random.randint(0, len(option_ids) - 1)]]
# 签到
return self.__signin(questionid=questionid,
choice=choice,
site_cookie=site_cookie,
ua=ua,
proxy=proxy,
site=site)
def __signin(self, questionid: str,
choice: list,
site: str,
site_cookie: str,
ua: str,
proxy: dict) -> Tuple[bool, str]:
"""
签到请求
questionid: 450
choice[]: 8
choice[]: 4
usercomment: 此刻心情:无
submit: 提交
多选会有多个choice[]....
"""
data = {
'questionid': questionid,
'choice[]': choice[0] if len(choice) == 1 else choice,
'usercomment': '太难了!',
'wantskip': '不会'
}
logger.debug(f"签到请求参数 {data}")
sign_res = RequestUtils(cookies=site_cookie,
ua=ua,
proxies=proxy
).post_res(url='https://52pt.site/bakatest.php', data=data)
if not sign_res or sign_res.status_code != 200:
logger.error(f"签到失败,签到接口请求失败")
return False, f'{site}】签到失败,签到接口请求失败'
# 判断是否签到成功
sign_status = self.sign_in_result(html_res=sign_res.text,
regexs=self._success_regex)
if sign_status:
logger.info(f"{site}签到成功")
return True, f'{site}】签到成功'
else:
sign_status = self.sign_in_result(html_res=sign_res.text,
regexs=self._sign_regex)
if sign_status:
logger.info(f"今日已签到")
return True, f'{site}】今日已签到'
logger.error(f"签到失败,请到页面查看")
return False, f'{site}】签到失败,请到页面查看'

View File

@@ -0,0 +1,46 @@
# -*- coding: utf-8 -*-
import re
from abc import ABCMeta, abstractmethod
from typing import Tuple
from ruamel.yaml import CommentedMap
from app.utils.string import StringUtils
class _ISiteSigninHandler(metaclass=ABCMeta):
"""
实现站点签到的基类所有站点签到类都需要继承此类并实现match和signin方法
实现类放置到sitesignin目录下将会自动加载
"""
# 匹配的站点Url每一个实现类都需要设置为自己的站点Url
site_url = ""
@abstractmethod
def match(self, url: str) -> bool:
"""
根据站点Url判断是否匹配当前站点签到类大部分情况使用默认实现即可
:param url: 站点Url
:return: 是否匹配如匹配则会调用该类的signin方法
"""
return True if StringUtils.url_equal(url, self.site_url) else False
@abstractmethod
def signin(self, site_info: CommentedMap) -> Tuple[bool, str]:
"""
执行签到操作
:param site_info: 站点信息含有站点Url、站点Cookie、UA等信息
:return: True|False,签到结果信息
"""
pass
@staticmethod
def sign_in_result(html_res: str, regexs: list) -> bool:
"""
判断是否签到成功
"""
html_text = re.sub(r"#\d+", "", re.sub(r"\d+px", "", html_res))
for regex in regexs:
if re.search(str(regex), html_text):
return True
return False

View File

@@ -0,0 +1,73 @@
from typing import Tuple
from ruamel.yaml import CommentedMap
from app.core import settings
from app.log import logger
from app.plugins.autosignin.sites import _ISiteSigninHandler
from app.utils.http import RequestUtils
from app.utils.string import StringUtils
class BTSchool(_ISiteSigninHandler):
"""
学校签到
"""
# 匹配的站点Url每一个实现类都需要设置为自己的站点Url
site_url = "pt.btschool.club"
# 已签到
_sign_text = '每日签到'
@classmethod
def match(cls, url) -> bool:
"""
根据站点Url判断是否匹配当前站点签到类大部分情况使用默认实现即可
:param url: 站点Url
:return: 是否匹配如匹配则会调用该类的signin方法
"""
return True if StringUtils.url_equal(url, cls.site_url) else False
def signin(self, site_info: CommentedMap) -> Tuple[bool, str]:
"""
执行签到操作
:param site_info: 站点信息含有站点Url、站点Cookie、UA等信息
:return: 签到结果信息
"""
site = site_info.get("name")
site_cookie = site_info.get("cookie")
ua = site_info.get("ua")
proxy = settings.PROXY if site_info.get("proxy") else None
logger.info(f"{site} 开始签到")
html_res = RequestUtils(cookies=site_cookie,
headers=ua,
proxies=proxy
).get_res(url="https://pt.btschool.club")
if not html_res or html_res.status_code != 200:
logger.error(f"签到失败,请检查站点连通性")
return False, f'{site}】签到失败,请检查站点连通性'
if "login.php" in html_res.text:
logger.error(f"签到失败cookie失效")
return False, f'{site}】签到失败cookie失效'
# 已签到
if self._sign_text not in html_res.text:
logger.info(f"今日已签到")
return True, f'{site}】今日已签到'
sign_res = RequestUtils(cookies=site_cookie,
headers=ua,
proxies=proxy
).get_res(url="https://pt.btschool.club/index.php?action=addbonus")
if not sign_res or sign_res.status_code != 200:
logger.error(f"签到失败,签到接口请求失败")
return False, f'{site}】签到失败,签到接口请求失败'
# 签到成功
if self._sign_text not in sign_res.text:
logger.info(f"签到成功")
return True, f'{site}】签到成功'

View File

@@ -0,0 +1,146 @@
import random
import re
from typing import Tuple
from lxml import etree
from ruamel.yaml import CommentedMap
from app.core import settings
from app.log import logger
from app.plugins.autosignin.sites import _ISiteSigninHandler
from app.utils.http import RequestUtils
from app.utils.string import StringUtils
class CHDBits(_ISiteSigninHandler):
"""
彩虹岛签到
如果填写openai key则调用chatgpt获取答案
否则随机
"""
# 匹配的站点Url每一个实现类都需要设置为自己的站点Url
site_url = "chdbits.co"
# 已签到
_sign_regex = ['今天已经签过到了']
# 签到成功,待补充
_success_regex = ['\\d+点魔力值']
@classmethod
def match(cls, url: str) -> bool:
"""
根据站点Url判断是否匹配当前站点签到类大部分情况使用默认实现即可
:param url: 站点Url
:return: 是否匹配如匹配则会调用该类的signin方法
"""
return True if StringUtils.url_equal(url, cls.site_url) else False
def signin(self, site_info: CommentedMap) -> Tuple[bool, str]:
"""
执行签到操作
:param site_info: 站点信息含有站点Url、站点Cookie、UA等信息
:return: 签到结果信息
"""
site = site_info.get("name")
site_cookie = site_info.get("cookie")
ua = site_info.get("ua")
proxy = settings.PROXY if site_info.get("proxy") else None
# 判断今日是否已签到
index_res = RequestUtils(cookies=site_cookie,
headers=ua,
proxies=proxy
).get_res(url='https://chdbits.co/bakatest.php')
if not index_res or index_res.status_code != 200:
logger.error(f"签到失败,请检查站点连通性")
return False, f'{site}】签到失败,请检查站点连通性'
if "login.php" in index_res.text:
logger.error(f"签到失败cookie失效")
return False, f'{site}】签到失败cookie失效'
sign_status = self.sign_in_result(html_res=index_res.text,
regexs=self._sign_regex)
if sign_status:
logger.info(f"今日已签到")
return True, f'{site}】今日已签到'
# 没有签到则解析html
html = etree.HTML(index_res.text)
if not html:
return False, f'{site}】签到失败'
# 获取页面问题、答案
questionid = html.xpath("//input[@name='questionid']/@value")[0]
option_ids = html.xpath("//input[@name='choice[]']/@value")
question_str = html.xpath("//td[@class='text' and contains(text(),'请问:')]/text()")[0]
# 正则获取问题
match = re.search(r'请问:(.+)', question_str)
if match:
question_str = match.group(1)
logger.debug(f"获取到签到问题 {question_str}")
else:
logger.error(f"未获取到签到问题")
return False, f"{site}】签到失败,未获取到签到问题"
# 正确答案默认随机如果gpt返回则用gpt返回的答案提交
choice = [option_ids[random.randint(0, len(option_ids) - 1)]]
# 签到
return self.__signin(questionid=questionid,
choice=choice,
site_cookie=site_cookie,
ua=ua,
proxy=proxy,
site=site)
def __signin(self, questionid: str,
choice: list,
site: str,
site_cookie: str,
ua: str,
proxy: dict) -> Tuple[bool, str]:
"""
签到请求
questionid: 450
choice[]: 8
choice[]: 4
usercomment: 此刻心情:无
submit: 提交
多选会有多个choice[]....
"""
data = {
'questionid': questionid,
'choice[]': choice[0] if len(choice) == 1 else choice,
'usercomment': '太难了!',
'wantskip': '不会'
}
logger.debug(f"签到请求参数 {data}")
sign_res = RequestUtils(cookies=site_cookie,
ua=ua,
proxies=proxy
).post_res(url='https://chdbits.co/bakatest.php', data=data)
if not sign_res or sign_res.status_code != 200:
logger.error(f"签到失败,签到接口请求失败")
return False, f'{site}】签到失败,签到接口请求失败'
# 判断是否签到成功
sign_status = self.sign_in_result(html_res=sign_res.text,
regexs=self._success_regex)
if sign_status:
logger.info(f"{site} 签到成功")
return True, f'{site}】签到成功'
else:
sign_status = self.sign_in_result(html_res=sign_res.text,
regexs=self._sign_regex)
if sign_status:
logger.info(f"今日已签到")
return True, f'{site}】今日已签到'
logger.error(f"签到失败,请到页面查看")
return False, f'{site}】签到失败,请到页面查看'

View File

@@ -0,0 +1,65 @@
import random
import re
from typing import Tuple
from lxml import etree
from ruamel.yaml import CommentedMap
from app.core import settings
from app.log import logger
from app.plugins.autosignin.sites import _ISiteSigninHandler
from app.utils.http import RequestUtils
from app.utils.string import StringUtils
class HaiDan(_ISiteSigninHandler):
"""
海胆签到
"""
# 匹配的站点Url每一个实现类都需要设置为自己的站点Url
site_url = "haidan.video"
# 签到成功
_succeed_regex = ['(?<=value=")已经打卡(?=")']
@classmethod
def match(cls, url: str) -> bool:
"""
根据站点Url判断是否匹配当前站点签到类大部分情况使用默认实现即可
:param url: 站点Url
:return: 是否匹配如匹配则会调用该类的signin方法
"""
return True if StringUtils.url_equal(url, cls.site_url) else False
def signin(self, site_info: CommentedMap) -> Tuple[bool, str]:
"""
执行签到操作
:param site_info: 站点信息含有站点Url、站点Cookie、UA等信息
:return: 签到结果信息
"""
site = site_info.get("name")
site_cookie = site_info.get("cookie")
ua = site_info.get("ua")
proxy = settings.PROXY if site_info.get("proxy") else None
# 签到
sign_res = RequestUtils(cookies=site_cookie,
headers=ua,
proxies=proxy
).get_res(url="https://www.haidan.video/signin.php")
if not sign_res or sign_res.status_code != 200:
logger.error(f"签到失败,请检查站点连通性")
return False, f'{site}】签到失败,请检查站点连通性'
if "login.php" in sign_res.text:
logger.error(f"签到失败cookie失效")
return False, f'{site}】签到失败cookie失效'
sign_status = self.sign_in_result(html_res=sign_res.text,
regexs=self._succeed_regex)
if sign_status:
logger.info(f"签到成功")
return True, f'{site}】签到成功'
logger.error(f"签到失败,签到接口返回 {sign_res.text}")
return False, f'{site}】签到失败'

View File

@@ -0,0 +1,80 @@
import json
from typing import Tuple
from ruamel.yaml import CommentedMap
from app.core import settings
from app.log import logger
from app.plugins.autosignin.sites import _ISiteSigninHandler
from app.utils.http import RequestUtils
from app.utils.string import StringUtils
class Hares(_ISiteSigninHandler):
"""
白兔签到
"""
# 匹配的站点Url每一个实现类都需要设置为自己的站点Url
site_url = "club.hares.top"
# 已签到
_sign_text = '已签到'
@classmethod
def match(cls, url: str) -> bool:
"""
根据站点Url判断是否匹配当前站点签到类大部分情况使用默认实现即可
:param url: 站点Url
:return: 是否匹配如匹配则会调用该类的signin方法
"""
return True if StringUtils.url_equal(url, cls.site_url) else False
def signin(self, site_info: CommentedMap) -> Tuple[bool, str]:
"""
执行签到操作
:param site_info: 站点信息含有站点Url、站点Cookie、UA等信息
:return: 签到结果信息
"""
site = site_info.get("name")
site_cookie = site_info.get("cookie")
ua = site_info.get("ua")
proxy = settings.PROXY if site_info.get("proxy") else None
# 获取页面html
html_res = RequestUtils(cookies=site_cookie,
headers=ua,
proxies=proxy
).get_res(url="https://club.hares.top")
if not html_res or html_res.status_code != 200:
logger.error(f"模拟访问失败,请检查站点连通性")
return False, f'{site}】模拟访问失败,请检查站点连通性'
if "login.php" in html_res.text:
logger.error(f"模拟访问失败cookie失效")
return False, f'{site}】模拟访问失败cookie失效'
# if self._sign_text in html_res.text:
# logger.info(f"今日已签到")
# return True, f'【{site}】今日已签到'
headers = {
'Accept': 'application/json',
"User-Agent": ua
}
sign_res = RequestUtils(cookies=site_cookie,
headers=headers,
proxies=proxy
).get_res(url="https://club.hares.top/attendance.php?action=sign")
if not sign_res or sign_res.status_code != 200:
logger.error(f"签到失败,签到接口请求失败")
return False, f'{site}】签到失败,签到接口请求失败'
# {"code":1,"msg":"您今天已经签到过了"}
# {"code":0,"msg":"签到成功"}
sign_dict = json.loads(sign_res.text)
if sign_dict['code'] == 0:
logger.info(f"签到成功")
return True, f'{site}】签到成功'
else:
logger.info(f"今日已签到")
return True, f'{site}】今日已签到'

View File

@@ -0,0 +1,69 @@
from typing import Tuple
from ruamel.yaml import CommentedMap
from app.core import settings
from app.log import logger
from app.plugins.autosignin.sites import _ISiteSigninHandler
from app.utils.http import RequestUtils
from app.utils.string import StringUtils
class HDArea(_ISiteSigninHandler):
"""
好大签到
"""
# 匹配的站点Url每一个实现类都需要设置为自己的站点Url
site_url = "hdarea.co"
# 签到成功
_success_text = "此次签到您获得"
_repeat_text = "请不要重复签到哦"
@classmethod
def match(cls, url: str) -> bool:
"""
根据站点Url判断是否匹配当前站点签到类大部分情况使用默认实现即可
:param url: 站点Url
:return: 是否匹配如匹配则会调用该类的signin方法
"""
return True if StringUtils.url_equal(url, cls.site_url) else False
def signin(self, site_info: CommentedMap) -> Tuple[bool, str]:
"""
执行签到操作
:param site_info: 站点信息含有站点Url、站点Cookie、UA等信息
:return: 签到结果信息
"""
site = site_info.get("name")
site_cookie = site_info.get("cookie")
ua = site_info.get("ua")
proxy = settings.PROXY if site_info.get("proxy") else None
# 获取页面html
data = {
'action': 'sign_in'
}
html_res = RequestUtils(cookies=site_cookie,
headers=ua,
proxies=proxy
).post_res(url="https://www.hdarea.co/sign_in.php", data=data)
if not html_res or html_res.status_code != 200:
logger.error(f"签到失败,请检查站点连通性")
return False, f'{site}】签到失败,请检查站点连通性'
if "login.php" in html_res.text:
logger.error(f"签到失败cookie失效")
return False, f'{site}】签到失败cookie失效'
# 判断是否已签到
# '已连续签到278天此次签到您获得了100魔力值奖励!'
if self._success_text in html_res.text:
logger.info(f"签到成功")
return True, f'{site}】签到成功'
if self._repeat_text in html_res.text:
logger.info(f"今日已签到")
return True, f'{site}】今日已签到'
logger.error(f"签到失败,签到接口返回 {html_res.text}")
return False, f'{site}】签到失败'

View File

@@ -0,0 +1,117 @@
import json
from typing import Tuple
from lxml import etree
from ruamel.yaml import CommentedMap
from app.core import settings
from app.log import logger
from app.plugins.autosignin.sites import _ISiteSigninHandler
from app.utils.http import RequestUtils
from app.utils.string import StringUtils
class HDChina(_ISiteSigninHandler):
"""
瓷器签到
"""
# 匹配的站点Url每一个实现类都需要设置为自己的站点Url
site_url = "hdchina.org"
# 已签到
_sign_regex = ['<a class="label label-default" href="#">已签到</a>']
@classmethod
def match(cls, url: str) -> bool:
"""
根据站点Url判断是否匹配当前站点签到类大部分情况使用默认实现即可
:param url: 站点Url
:return: 是否匹配如匹配则会调用该类的signin方法
"""
return True if StringUtils.url_equal(url, cls.site_url) else False
def signin(self, site_info: CommentedMap) -> Tuple[bool, str]:
"""
执行签到操作
:param site_info: 站点信息含有站点Url、站点Cookie、UA等信息
:return: 签到结果信息
"""
site = site_info.get("name")
site_cookie = site_info.get("cookie")
ua = site_info.get("ua")
proxy = settings.PROXY if site_info.get("proxy") else None
# 尝试解决瓷器cookie每天签到后过期,只保留hdchina=部分
cookie = ""
# 按照分号进行字符串拆分
sub_strs = site_cookie.split(";")
# 遍历每个子字符串
for sub_str in sub_strs:
if "hdchina=" in sub_str:
# 如果子字符串包含"hdchina=",则保留该子字符串
cookie += sub_str + ";"
if "hdchina=" not in cookie:
logger.error(f"签到失败cookie失效")
return False, f'{site}】签到失败cookie失效'
site_cookie = cookie
# 获取页面html
html_res = RequestUtils(cookies=site_cookie,
headers=ua,
proxies=proxy
).get_res(url="https://hdchina.org/index.php")
if not html_res or html_res.status_code != 200:
logger.error(f"签到失败,请检查站点连通性")
return False, f'{site}】签到失败,请检查站点连通性'
if "login.php" in html_res.text or "阻断页面" in html_res.text:
logger.error(f"签到失败cookie失效")
return False, f'{site}】签到失败cookie失效'
# 获取新返回的cookie进行签到
site_cookie = ';'.join(['{}={}'.format(k, v) for k, v in html_res.cookies.get_dict().items()])
# 判断是否已签到
html_res.encoding = "utf-8"
sign_status = self.sign_in_result(html_res=html_res.text,
regexs=self._sign_regex)
if sign_status:
logger.info(f"今日已签到")
return True, f'{site}】今日已签到'
# 没有签到则解析html
html = etree.HTML(html_res.text)
if not html:
return False, f'{site}】签到失败'
# x_csrf
x_csrf = html.xpath("//meta[@name='x-csrf']/@content")[0]
if not x_csrf:
logger.error("签到失败获取x-csrf失败")
return False, f'{site}】签到失败'
logger.debug(f"获取到x-csrf {x_csrf}")
# 签到
data = {
'csrf': x_csrf
}
sign_res = RequestUtils(cookies=site_cookie,
headers=ua,
proxies=proxy
).post_res(url="https://hdchina.org/plugin_sign-in.php?cmd=signin", data=data)
if not sign_res or sign_res.status_code != 200:
logger.error(f"签到失败,签到接口请求失败")
return False, f'{site}】签到失败,签到接口请求失败'
sign_dict = json.loads(sign_res.text)
logger.debug(f"签到返回结果 {sign_dict}")
if sign_dict['state']:
# {'state': 'success', 'signindays': 10, 'integral': 20}
logger.info(f"签到成功")
return True, f'{site}】签到成功'
else:
# {'state': False, 'msg': '不正确的CSRF / Incorrect CSRF token'}
logger.error(f"签到失败不正确的CSRF / Incorrect CSRF token")
return False, f'{site}】签到失败'

View File

@@ -0,0 +1,66 @@
from typing import Tuple
from ruamel.yaml import CommentedMap
from app.core import settings
from app.log import logger
from app.plugins.autosignin.sites import _ISiteSigninHandler
from app.utils.http import RequestUtils
from app.utils.string import StringUtils
class HDCity(_ISiteSigninHandler):
"""
城市签到
"""
# 匹配的站点Url每一个实现类都需要设置为自己的站点Url
site_url = "hdcity.city"
# 签到成功
_success_text = '本次签到获得魅力'
# 重复签到
_repeat_text = '已签到'
@classmethod
def match(cls, url: str) -> bool:
"""
根据站点Url判断是否匹配当前站点签到类大部分情况使用默认实现即可
:param url: 站点Url
:return: 是否匹配如匹配则会调用该类的signin方法
"""
return True if StringUtils.url_equal(url, cls.site_url) else False
def signin(self, site_info: CommentedMap) -> Tuple[bool, str]:
"""
执行签到操作
:param site_info: 站点信息含有站点Url、站点Cookie、UA等信息
:return: 签到结果信息
"""
site = site_info.get("name")
site_cookie = site_info.get("cookie")
ua = site_info.get("ua")
proxy = settings.PROXY if site_info.get("proxy") else None
# 获取页面html
html_res = RequestUtils(cookies=site_cookie,
headers=ua,
proxies=proxy
).get_res(url="https://hdcity.city/sign")
if not html_res or html_res.status_code != 200:
logger.error(f"签到失败,请检查站点连通性")
return False, f'{site}】签到失败,请检查站点连通性'
if "login" in html_res.text:
logger.error(f"签到失败cookie失效")
return False, f'{site}】签到失败cookie失效'
# 判断是否已签到
# '已连续签到278天此次签到您获得了100魔力值奖励!'
if self._success_text in html_res.text:
logger.info(f"签到成功")
return True, f'{site}】签到成功'
if self._repeat_text in html_res.text:
logger.info(f"今日已签到")
return True, f'{site}】今日已签到'
logger.error(f"签到失败,签到接口返回 {html_res.text}")
return False, f'{site}】签到失败'

View File

@@ -0,0 +1,131 @@
import json
import time
from typing import Tuple
from ruamel.yaml import CommentedMap
from app.core import settings
from app.helper.ocr import OcrHelper
from app.log import logger
from app.plugins.autosignin.sites import _ISiteSigninHandler
from app.utils.http import RequestUtils
from app.utils.string import StringUtils
class HDSky(_ISiteSigninHandler):
"""
天空ocr签到
"""
# 匹配的站点Url每一个实现类都需要设置为自己的站点Url
site_url = "hdsky.me"
# 已签到
_sign_regex = ['已签到']
@classmethod
def match(cls, url: str) -> bool:
"""
根据站点Url判断是否匹配当前站点签到类大部分情况使用默认实现即可
:param url: 站点Url
:return: 是否匹配如匹配则会调用该类的signin方法
"""
return True if StringUtils.url_equal(url, cls.site_url) else False
def signin(self, site_info: CommentedMap) -> Tuple[bool, str]:
"""
执行签到操作
:param site_info: 站点信息含有站点Url、站点Cookie、UA等信息
:return: 签到结果信息
"""
site = site_info.get("name")
site_cookie = site_info.get("cookie")
ua = site_info.get("ua")
proxy = settings.PROXY if site_info.get("proxy") else None
# 判断今日是否已签到
index_res = RequestUtils(cookies=site_cookie,
headers=ua,
proxies=proxy
).get_res(url='https://hdsky.me')
if not index_res or index_res.status_code != 200:
logger.error(f"签到失败,请检查站点连通性")
return False, f'{site}】签到失败,请检查站点连通性'
if "login.php" in index_res.text:
logger.error(f"签到失败cookie失效")
return False, f'{site}】签到失败cookie失效'
sign_status = self.sign_in_result(html_res=index_res.text,
regexs=self._sign_regex)
if sign_status:
logger.info(f"今日已签到")
return True, f'{site}】今日已签到'
# 获取验证码请求,考虑到网络问题获取失败,多获取几次试试
res_times = 0
img_hash = None
while not img_hash and res_times <= 3:
image_res = RequestUtils(cookies=site_cookie,
headers=ua,
proxies=proxy
).post_res(url='https://hdsky.me/image_code_ajax.php',
data={'action': 'new'})
if image_res and image_res.status_code == 200:
image_json = json.loads(image_res.text)
if image_json["success"]:
img_hash = image_json["code"]
break
res_times += 1
logger.debug(f"获取{site}验证码失败,正在进行重试,目前重试次数 {res_times}")
time.sleep(1)
# 获取到二维码hash
if img_hash:
# 完整验证码url
img_get_url = 'https://hdsky.me/image.php?action=regimage&imagehash=%s' % img_hash
logger.debug(f"获取到{site}验证码链接 {img_get_url}")
# ocr识别多次获取6位验证码
times = 0
ocr_result = None
# 识别几次
while times <= 3:
# ocr二维码识别
ocr_result = OcrHelper().get_captcha_text(image_url=img_get_url,
cookie=site_cookie,
ua=ua)
logger.debug(f"ocr识别{site}验证码 {ocr_result}")
if ocr_result:
if len(ocr_result) == 6:
logger.info(f"ocr识别{site}验证码成功 {ocr_result}")
break
times += 1
logger.debug(f"ocr识别{site}验证码失败,正在进行重试,目前重试次数 {times}")
time.sleep(1)
if ocr_result:
# 组装请求参数
data = {
'action': 'showup',
'imagehash': img_hash,
'imagestring': ocr_result
}
# 访问签到链接
res = RequestUtils(cookies=site_cookie,
headers=ua,
proxies=proxy
).post_res(url='https://hdsky.me/showup.php', data=data)
if res and res.status_code == 200:
if json.loads(res.text)["success"]:
logger.info(f"签到成功")
return True, f'{site}】签到成功'
elif str(json.loads(res.text)["message"]) == "date_unmatch":
# 重复签到
logger.warn(f"重复成功")
return True, f'{site}】今日已签到'
elif str(json.loads(res.text)["message"]) == "invalid_imagehash":
# 验证码错误
logger.warn(f"签到失败:验证码错误")
return False, f'{site}】签到失败:验证码错误'
logger.error(f'签到失败:未获取到验证码')
return False, f'{site}】签到失败:未获取到验证码'

View File

@@ -0,0 +1,81 @@
import re
from typing import Tuple
from ruamel.yaml import CommentedMap
from app.core import settings
from app.log import logger
from app.plugins.autosignin.sites import _ISiteSigninHandler
from app.utils.http import RequestUtils
from app.utils.string import StringUtils
class HDUpt(_ISiteSigninHandler):
"""
hdu签到
"""
# 匹配的站点Url每一个实现类都需要设置为自己的站点Url
site_url = "pt.hdupt.com"
# 已签到
_sign_regex = ['<span id="yiqiandao">']
# 签到成功
_success_text = '本次签到获得魅力'
@classmethod
def match(cls, url: str) -> bool:
"""
根据站点Url判断是否匹配当前站点签到类大部分情况使用默认实现即可
:param url: 站点Url
:return: 是否匹配如匹配则会调用该类的signin方法
"""
return True if StringUtils.url_equal(url, cls.site_url) else False
def signin(self, site_info: CommentedMap) -> Tuple[bool, str]:
"""
执行签到操作
:param site_info: 站点信息含有站点Url、站点Cookie、UA等信息
:return: 签到结果信息
"""
site = site_info.get("name")
site_cookie = site_info.get("cookie")
ua = site_info.get("ua")
proxy = settings.PROXY if site_info.get("proxy") else None
# 获取页面html
index_res = RequestUtils(cookies=site_cookie,
headers=ua,
proxies=proxy
).get_res(url="https://pt.hdupt.com")
if not index_res or index_res.status_code != 200:
logger.error(f"签到失败,请检查站点连通性")
return False, f'{site}】签到失败,请检查站点连通性'
if "login.php" in index_res.text:
logger.error(f"签到失败cookie失效")
return False, f'{site}】签到失败cookie失效'
sign_status = self.sign_in_result(html_res=index_res.text,
regexs=self._sign_regex)
if sign_status:
logger.info(f"今日已签到")
return True, f'{site}】今日已签到'
# 签到
sign_res = RequestUtils(cookies=site_cookie,
headers=ua,
proxies=proxy
).post_res(url="https://pt.hdupt.com/added.php?action=qiandao")
if not sign_res or sign_res.status_code != 200:
logger.error(f"签到失败,请检查站点连通性")
return False, f'{site}】签到失败,请检查站点连通性'
logger.debug(f"签到接口返回 {sign_res.text}")
# 判断是否已签到 sign_res.text = ".23"
if len(list(map(int, re.findall(r"\d+", sign_res.text)))) > 0:
logger.info(f"签到成功")
return True, f'{site}】签到成功'
logger.error(f"签到失败,签到接口返回 {sign_res.text}")
return False, f'{site}】签到失败'

View File

@@ -0,0 +1,129 @@
import json
import time
from typing import Tuple
from lxml import etree
from ruamel.yaml import CommentedMap
from app.core import settings
from app.helper.ocr import OcrHelper
from app.log import logger
from app.plugins.autosignin.sites import _ISiteSigninHandler
from app.utils.http import RequestUtils
from app.utils.string import StringUtils
class Opencd(_ISiteSigninHandler):
"""
皇后ocr签到
"""
# 匹配的站点Url每一个实现类都需要设置为自己的站点Url
site_url = "open.cd"
# 已签到
_repeat_text = "/plugin_sign-in.php?cmd=show-log"
@classmethod
def match(cls, url: str) -> bool:
"""
根据站点Url判断是否匹配当前站点签到类大部分情况使用默认实现即可
:param url: 站点Url
:return: 是否匹配如匹配则会调用该类的signin方法
"""
return True if StringUtils.url_equal(url, cls.site_url) else False
def signin(self, site_info: CommentedMap) -> Tuple[bool, str]:
"""
执行签到操作
:param site_info: 站点信息含有站点Url、站点Cookie、UA等信息
:return: 签到结果信息
"""
site = site_info.get("name")
site_cookie = site_info.get("cookie")
ua = site_info.get("ua")
proxy = settings.PROXY if site_info.get("proxy") else None
# 判断今日是否已签到
index_res = RequestUtils(cookies=site_cookie,
headers=ua,
proxies=proxy
).get_res(url='https://www.open.cd')
if not index_res or index_res.status_code != 200:
logger.error(f"签到失败,请检查站点连通性")
return False, f'{site}】签到失败,请检查站点连通性'
if "login.php" in index_res.text:
logger.error(f"签到失败cookie失效")
return False, f'{site}】签到失败cookie失效'
if self._repeat_text in index_res.text:
logger.info(f"今日已签到")
return True, f'{site}】今日已签到'
# 获取签到参数
sign_param_res = RequestUtils(cookies=site_cookie,
headers=ua,
proxies=proxy
).get_res(url='https://www.open.cd/plugin_sign-in.php')
if not sign_param_res or sign_param_res.status_code != 200:
logger.error(f"签到失败,请检查站点连通性")
return False, f'{site}】签到失败,请检查站点连通性'
# 没有签到则解析html
html = etree.HTML(sign_param_res.text)
if not html:
return False, f'{site}】签到失败'
# 签到参数
img_url = html.xpath('//form[@id="frmSignin"]//img/@src')[0]
img_hash = html.xpath('//form[@id="frmSignin"]//input[@name="imagehash"]/@value')[0]
if not img_url or not img_hash:
logger.error(f"签到失败,获取签到参数失败")
return False, f'{site}】签到失败,获取签到参数失败'
# 完整验证码url
img_get_url = 'https://www.open.cd/%s' % img_url
logger.debug(f"获取到{site}验证码链接 {img_get_url}")
# ocr识别多次获取6位验证码
times = 0
ocr_result = None
# 识别几次
while times <= 3:
# ocr二维码识别
ocr_result = OcrHelper().get_captcha_text(image_url=img_get_url,
cookie=site_cookie,
ua=ua)
logger.debug(f"ocr识别{site}验证码 {ocr_result}")
if ocr_result:
if len(ocr_result) == 6:
logger.info(f"ocr识别{site}验证码成功 {ocr_result}")
break
times += 1
logger.debug(f"ocr识别{site}验证码失败,正在进行重试,目前重试次数 {times}")
time.sleep(1)
if ocr_result:
# 组装请求参数
data = {
'imagehash': img_hash,
'imagestring': ocr_result
}
# 访问签到链接
sign_res = RequestUtils(cookies=site_cookie,
headers=ua,
proxies=proxy
).post_res(url='https://www.open.cd/plugin_sign-in.php?cmd=signin', data=data)
if sign_res and sign_res.status_code == 200:
logger.debug(f"sign_res返回 {sign_res.text}")
# sign_res.text = '{"state":"success","signindays":"0","integral":"10"}'
sign_dict = json.loads(sign_res.text)
if sign_dict['state']:
logger.info(f"签到成功")
return True, f'{site}】签到成功'
else:
logger.error(f"签到失败,签到接口返回 {sign_dict}")
return False, f'{site}】签到失败'
logger.error(f'签到失败:未获取到验证码')
return False, f'{site}】签到失败:未获取到验证码'

View File

@@ -0,0 +1,58 @@
import json
from typing import Tuple
from ruamel.yaml import CommentedMap
from app.core import settings
from app.log import logger
from app.plugins.autosignin.sites import _ISiteSigninHandler
from app.utils.http import RequestUtils
from app.utils.string import StringUtils
class PTerClub(_ISiteSigninHandler):
"""
猫签到
"""
# 匹配的站点Url每一个实现类都需要设置为自己的站点Url
site_url = "pterclub.com"
@classmethod
def match(cls, url: str) -> bool:
"""
根据站点Url判断是否匹配当前站点签到类大部分情况使用默认实现即可
:param url: 站点Url
:return: 是否匹配如匹配则会调用该类的signin方法
"""
return True if StringUtils.url_equal(url, cls.site_url) else False
def signin(self, site_info: CommentedMap) -> Tuple[bool, str]:
"""
执行签到操作
:param site_info: 站点信息含有站点Url、站点Cookie、UA等信息
:return: 签到结果信息
"""
site = site_info.get("name")
site_cookie = site_info.get("cookie")
ua = site_info.get("ua")
proxy = settings.PROXY if site_info.get("proxy") else None
# 签到
sign_res = RequestUtils(cookies=site_cookie,
headers=ua,
proxies=proxy
).get_res(url="https://pterclub.com/attendance-ajax.php")
if not sign_res or sign_res.status_code != 200:
logger.error(f"签到失败,签到接口请求失败")
return False, f'{site}】签到失败请检查cookie是否失效'
sign_dict = json.loads(sign_res.text)
if sign_dict['status'] == '1':
# {"status":"1","data":" (签到已成功300)","message":"<p>这是您的第<b>237</b>次签到,
# 已连续签到<b>237</b>天。</p><p>本次签到获得<b>300</b>克猫粮。</p>"}
logger.info(f"签到成功")
return True, f'{site}】签到成功'
else:
# {"status":"0","data":"抱歉","message":"您今天已经签到过了,请勿重复刷新。"}
logger.info(f"今日已签到")
return True, f'{site}】今日已签到'

View File

@@ -0,0 +1,272 @@
import json
import os
import time
from io import BytesIO
from typing import Tuple
from PIL import Image
from lxml import etree
from ruamel.yaml import CommentedMap
from app.core import settings
from app.log import logger
from app.plugins.autosignin.sites import _ISiteSigninHandler
from app.utils.http import RequestUtils
from app.utils.string import StringUtils
class Tjupt(_ISiteSigninHandler):
"""
北洋签到
"""
# 匹配的站点Url每一个实现类都需要设置为自己的站点Url
site_url = "tjupt.org"
# 签到地址
_sign_in_url = 'https://www.tjupt.org/attendance.php'
# 已签到
_sign_regex = ['<a href="attendance.php">今日已签到</a>']
# 签到成功
_succeed_regex = ['这是您的首次签到,本次签到获得\\d+个魔力值。',
'签到成功,这是您的第\\d+次签到,已连续签到\\d+天,本次签到获得\\d+个魔力值。',
'重新签到成功,本次签到获得\\d+个魔力值']
# 存储正确的答案,后续可直接查
_answer_path = settings.TEMP_PATH / "signin/"
_answer_file = _answer_path / "tjupt.json"
@classmethod
def match(cls, url: str) -> bool:
"""
根据站点Url判断是否匹配当前站点签到类大部分情况使用默认实现即可
:param url: 站点Url
:return: 是否匹配如匹配则会调用该类的signin方法
"""
return True if StringUtils.url_equal(url, cls.site_url) else False
def signin(self, site_info: CommentedMap) -> Tuple[bool, str]:
"""
执行签到操作
:param site_info: 站点信息含有站点Url、站点Cookie、UA等信息
:return: 签到结果信息
"""
site = site_info.get("name")
site_cookie = site_info.get("cookie")
ua = site_info.get("ua")
proxy = settings.PROXY if site_info.get("proxy") else None
# 创建正确答案存储目录
if not os.path.exists(os.path.dirname(self._answer_file)):
os.makedirs(os.path.dirname(self._answer_file))
# 获取北洋签到页面html
html_res = RequestUtils(cookies=site_cookie,
headers=ua,
proxies=proxy
).get_res(url=self._sign_in_url)
# 获取签到后返回html判断是否签到成功
if not html_res or html_res.status_code != 200:
logger.error(f"签到失败,请检查站点连通性")
return False, f'{site}】签到失败,请检查站点连通性'
if "login.php" in html_res.text:
logger.error(f"签到失败cookie失效")
return False, f'{site}】签到失败cookie失效'
sign_status = self.sign_in_result(html_res=html_res.text,
regexs=self._sign_regex)
if sign_status:
logger.info(f"今日已签到")
return True, f'{site}】今日已签到'
# 没有签到则解析html
html = etree.HTML(html_res.text)
if not html:
return False, f'{site}】签到失败'
img_url = html.xpath('//table[@class="captcha"]//img/@src')[0]
if not img_url:
logger.error(f"签到失败,未获取到签到图片")
return False, f'{site}】签到失败,未获取到签到图片'
# 签到图片
img_url = "https://www.tjupt.org" + img_url
logger.info(f"获取到签到图片 {img_url}")
# 获取签到图片hash
captcha_img_res = RequestUtils(cookies=site_cookie,
headers=ua,
proxies=proxy
).get_res(url=img_url)
if not captcha_img_res or captcha_img_res.status_code != 200:
logger.error(f"签到图片 {img_url} 请求失败")
return False, f'{site}】签到失败,未获取到签到图片'
captcha_img = Image.open(BytesIO(captcha_img_res.content))
captcha_img_hash = self._tohash(captcha_img)
logger.debug(f"签到图片hash {captcha_img_hash}")
# 签到答案选项
values = html.xpath("//input[@name='answer']/@value")
options = html.xpath("//input[@name='answer']/following-sibling::text()")
if not values or not options:
logger.error(f"签到失败,未获取到答案选项")
return False, f'{site}】签到失败,未获取到答案选项'
# value+选项
answers = list(zip(values, options))
logger.debug(f"获取到所有签到选项 {answers}")
# 查询已有答案
exits_answers = {}
try:
with open(self._answer_file, 'r') as f:
json_str = f.read()
exits_answers = json.loads(json_str)
# 查询本地本次验证码hash答案
captcha_answer = exits_answers[captcha_img_hash]
# 本地存在本次hash对应的正确答案再遍历查询
if captcha_answer:
for value, answer in answers:
if str(captcha_answer) == str(answer):
# 确实是答案
return self.__signin(answer=value,
site_cookie=site_cookie,
ua=ua,
proxy=proxy,
site=site)
except (FileNotFoundError, IOError, OSError) as e:
logger.debug(f"查询本地已知答案失败:{e},继续请求豆瓣查询")
# 本地不存在正确答案则请求豆瓣查询匹配
for value, answer in answers:
if answer:
# 豆瓣检索
db_res = RequestUtils().get_res(url=f'https://movie.douban.com/j/subject_suggest?q={answer}')
if not db_res or db_res.status_code != 200:
logger.debug(f"签到选项 {answer} 未查询到豆瓣数据")
continue
# 豆瓣返回结果
db_answers = json.loads(db_res.text)
if not isinstance(db_answers, list):
db_answers = [db_answers]
if len(db_answers) == 0:
logger.debug(f"签到选项 {answer} 查询到豆瓣数据为空")
for db_answer in db_answers:
answer_img_url = db_answer['img']
# 获取答案hash
answer_img_res = RequestUtils().get_res(url=answer_img_url)
if not answer_img_res or answer_img_res.status_code != 200:
logger.debug(f"签到答案 {answer} {answer_img_url} 请求失败")
continue
answer_img = Image.open(BytesIO(answer_img_res.content))
answer_img_hash = self._tohash(answer_img)
logger.debug(f"签到答案图片hash {answer} {answer_img_hash}")
# 获取选项图片与签到图片相似度大于0.9默认是正确答案
score = self._comparehash(captcha_img_hash, answer_img_hash)
logger.info(f"签到图片与选项 {answer} 豆瓣图片相似度 {score}")
if score > 0.9:
# 确实是答案
return self.__signin(answer=value,
site_cookie=site_cookie,
ua=ua,
proxy=proxy,
site=site,
exits_answers=exits_answers,
captcha_img_hash=captcha_img_hash)
# 间隔5s防止请求太频繁被豆瓣屏蔽ip
time.sleep(5)
logger.error(f"豆瓣图片匹配,未获取到匹配答案")
# 没有匹配签到成功,则签到失败
return False, f'{site}】签到失败,未获取到匹配答案'
def __signin(self, answer, site_cookie, ua, proxy, site, exits_answers=None, captcha_img_hash=None):
"""
签到请求
"""
data = {
'answer': answer,
'submit': '提交'
}
logger.debug(f"提交data {data}")
sign_in_res = RequestUtils(cookies=site_cookie,
headers=ua,
proxies=proxy
).post_res(url=self._sign_in_url, data=data)
if not sign_in_res or sign_in_res.status_code != 200:
logger.error(f"签到失败,签到接口请求失败")
return False, f'{site}】签到失败,签到接口请求失败'
# 获取签到后返回html判断是否签到成功
sign_status = self.sign_in_result(html_res=sign_in_res.text,
regexs=self._succeed_regex)
if sign_status:
logger.info(f"签到成功")
if exits_answers and captcha_img_hash:
# 签到成功写入本地文件
self.__write_local_answer(exits_answers=exits_answers or {},
captcha_img_hash=captcha_img_hash,
answer=answer)
return True, f'{site}】签到成功'
else:
logger.error(f"签到失败,请到页面查看")
return False, f'{site}】签到失败,请到页面查看'
def __write_local_answer(self, exits_answers, captcha_img_hash, answer):
"""
签到成功写入本地文件
"""
try:
exits_answers[captcha_img_hash] = answer
# 序列化数据
formatted_data = json.dumps(exits_answers, indent=4)
with open(self._answer_file, 'w') as f:
f.write(formatted_data)
except (FileNotFoundError, IOError, OSError) as e:
logger.debug(f"签到成功写入本地文件失败:{e}")
@staticmethod
def _tohash(img, shape=(10, 10)):
"""
获取图片hash
"""
img = img.resize(shape)
gray = img.convert('L')
s = 0
hash_str = ''
for i in range(shape[1]):
for j in range(shape[0]):
s = s + gray.getpixel((j, i))
avg = s / (shape[0] * shape[1])
for i in range(shape[1]):
for j in range(shape[0]):
if gray.getpixel((j, i)) > avg:
hash_str = hash_str + '1'
else:
hash_str = hash_str + '0'
return hash_str
@staticmethod
def _comparehash(hash1, hash2, shape=(10, 10)):
"""
比较图片hash
返回相似度
"""
n = 0
if len(hash1) != len(hash2):
return -1
for i in range(len(hash1)):
if hash1[i] == hash2[i]:
n = n + 1
return n / (shape[0] * shape[1])

View File

@@ -0,0 +1,96 @@
import re
from typing import Tuple
from ruamel.yaml import CommentedMap
from app.core import settings
from app.log import logger
from app.plugins.autosignin.sites import _ISiteSigninHandler
from app.utils.http import RequestUtils
from app.utils.string import StringUtils
class TTG(_ISiteSigninHandler):
"""
TTG签到
"""
# 匹配的站点Url每一个实现类都需要设置为自己的站点Url
site_url = "totheglory.im"
# 已签到
_sign_regex = ['<b style="color:green;">已签到</b>']
_sign_text = '亲,您今天已签到过,不要太贪哦'
# 签到成功
_success_text = '您已连续签到'
@classmethod
def match(cls, url: str) -> bool:
"""
根据站点Url判断是否匹配当前站点签到类大部分情况使用默认实现即可
:param url: 站点Url
:return: 是否匹配如匹配则会调用该类的signin方法
"""
return True if StringUtils.url_equal(url, cls.site_url) else False
def signin(self, site_info: CommentedMap) -> Tuple[bool, str]:
"""
执行签到操作
:param site_info: 站点信息含有站点Url、站点Cookie、UA等信息
:return: 签到结果信息
"""
site = site_info.get("name")
site_cookie = site_info.get("cookie")
ua = site_info.get("ua")
proxy = settings.PROXY if site_info.get("proxy") else None
# 获取页面html
html_res = RequestUtils(cookies=site_cookie,
headers=ua,
proxies=proxy
).get_res(url="https://totheglory.im")
if not html_res or html_res.status_code != 200:
logger.error(f"签到失败,请检查站点连通性")
return False, f'{site}】签到失败,请检查站点连通性'
if "login.php" in html_res.text:
logger.error(f"签到失败cookie失效")
return False, f'{site}】签到失败cookie失效'
# 判断是否已签到
html_res.encoding = "utf-8"
sign_status = self.sign_in_result(html_res=html_res.text,
regexs=self._sign_regex)
if sign_status:
logger.info(f"今日已签到")
return True, f'{site}】今日已签到'
# 获取签到参数
signed_timestamp = re.search('(?<=signed_timestamp: ")\\d{10}', html_res.text).group()
signed_token = re.search('(?<=signed_token: ").*(?=")', html_res.text).group()
logger.debug(f"signed_timestamp={signed_timestamp} signed_token={signed_token}")
data = {
'signed_timestamp': signed_timestamp,
'signed_token': signed_token
}
# 签到
sign_res = RequestUtils(cookies=site_cookie,
headers=ua,
proxies=proxy
).post_res(url="https://totheglory.im/signed.php",
data=data)
if not sign_res or sign_res.status_code != 200:
logger.error(f"签到失败,签到接口请求失败")
return False, f'{site}】签到失败,签到接口请求失败'
sign_res.encoding = "utf-8"
if self._success_text in sign_res.text:
logger.info(f"签到成功")
return True, f'{site}】签到成功'
if self._sign_text in sign_res.text:
logger.info(f"今日已签到")
return True, f'{site}】今日已签到'
logger.error(f"签到失败,未知原因")
return False, f'{site}】签到失败,未知原因'

View File

@@ -0,0 +1,122 @@
import datetime
import random
import re
from typing import Tuple
from lxml import etree
from ruamel.yaml import CommentedMap
from app.core import settings
from app.log import logger
from app.plugins.autosignin.sites import _ISiteSigninHandler
from app.utils.http import RequestUtils
from app.utils.string import StringUtils
class U2(_ISiteSigninHandler):
"""
U2签到 随机
"""
# 匹配的站点Url每一个实现类都需要设置为自己的站点Url
site_url = "u2.dmhy.org"
# 已签到
_sign_regex = ['<a href="showup.php">已签到</a>',
'<a href="showup.php">Show Up</a>',
'<a href="showup.php">Показать</a>',
'<a href="showup.php">已簽到</a>',
'<a href="showup.php">已簽到</a>']
# 签到成功
_success_text = "window.location.href = 'showup.php';</script>"
@classmethod
def match(cls, url: str) -> bool:
"""
根据站点Url判断是否匹配当前站点签到类大部分情况使用默认实现即可
:param url: 站点Url
:return: 是否匹配如匹配则会调用该类的signin方法
"""
return True if StringUtils.url_equal(url, cls.site_url) else False
def signin(self, site_info: CommentedMap) -> Tuple[bool, str]:
"""
执行签到操作
:param site_info: 站点信息含有站点Url、站点Cookie、UA等信息
:return: 签到结果信息
"""
site = site_info.get("name")
site_cookie = site_info.get("cookie")
ua = site_info.get("ua")
proxy = settings.PROXY if site_info.get("proxy") else None
now = datetime.datetime.now()
# 判断当前时间是否小于9点
if now.hour < 9:
logger.error(f"签到失败9点前不签到")
return False, f'{site}】签到失败9点前不签到'
# 获取页面html
html_res = RequestUtils(cookies=site_cookie,
headers=ua,
proxies=proxy
).get_res(url="https://u2.dmhy.org/showup.php")
if not html_res or html_res.status_code != 200:
logger.error(f"签到失败,请检查站点连通性")
return False, f'{site}】签到失败,请检查站点连通性'
if "login.php" in html_res.text:
logger.error(f"签到失败cookie失效")
return False, f'{site}】签到失败cookie失效'
# 判断是否已签到
html_res.encoding = "utf-8"
sign_status = self.sign_in_result(html_res=html_res.text,
regexs=self._sign_regex)
if sign_status:
logger.info(f"今日已签到")
return True, f'{site}】今日已签到'
# 没有签到则解析html
html = etree.HTML(html_res.text)
if not html:
return False, f'{site}】签到失败'
# 获取签到参数
req = html.xpath("//form//td/input[@name='req']/@value")[0]
hash_str = html.xpath("//form//td/input[@name='hash']/@value")[0]
form = html.xpath("//form//td/input[@name='form']/@value")[0]
submit_name = html.xpath("//form//td/input[@type='submit']/@name")
submit_value = html.xpath("//form//td/input[@type='submit']/@value")
if not re or not hash_str or not form or not submit_name or not submit_value:
logger.error("签到失败,未获取到相关签到参数")
return False, f'{site}】签到失败'
# 随机一个答案
answer_num = random.randint(0, 3)
data = {
'req': req,
'hash': hash_str,
'form': form,
'message': '一切随缘~',
submit_name[answer_num]: submit_value[answer_num]
}
# 签到
sign_res = RequestUtils(cookies=site_cookie,
headers=ua,
proxies=proxy
).post_res(url="https://u2.dmhy.org/showup.php?action=show",
data=data)
if not sign_res or sign_res.status_code != 200:
logger.error(f"签到失败,签到接口请求失败")
return False, f'{site}】签到失败,签到接口请求失败'
# 判断是否签到成功
# sign_res.text = "<script type="text/javascript">window.location.href = 'showup.php';</script>"
if self._success_text in sign_res.text:
logger.info(f"签到成功")
return True, f'{site}】签到成功'
else:
logger.error(f"签到失败,未知原因")
return False, f'{site}】签到失败,未知原因'

View File

@@ -0,0 +1,86 @@
import json
from typing import Tuple
from lxml import etree
from ruamel.yaml import CommentedMap
from app.core import settings
from app.log import logger
from app.plugins.autosignin.sites import _ISiteSigninHandler
from app.utils.http import RequestUtils
from app.utils.string import StringUtils
class ZhuQue(_ISiteSigninHandler):
"""
ZHUQUE签到
"""
# 匹配的站点Url每一个实现类都需要设置为自己的站点Url
site_url = "zhuque.in"
@classmethod
def match(cls, url: str) -> bool:
"""
根据站点Url判断是否匹配当前站点签到类大部分情况使用默认实现即可
:param url: 站点Url
:return: 是否匹配如匹配则会调用该类的signin方法
"""
return True if StringUtils.url_equal(url, cls.site_url) else False
def signin(self, site_info: CommentedMap) -> Tuple[bool, str]:
"""
执行签到操作
:param site_info: 站点信息含有站点Url、站点Cookie、UA等信息
:return: 签到结果信息
"""
site = site_info.get("name")
site_cookie = site_info.get("cookie")
ua = site_info.get("ua")
proxy = settings.PROXY if site_info.get("proxy") else None
# 获取页面html
html_res = RequestUtils(cookies=site_cookie,
headers=ua,
proxies=proxy
).get_res(url="https://zhuque.in")
if not html_res or html_res.status_code != 200:
logger.error(f"模拟登录失败,请检查站点连通性")
return False, f'{site}】模拟登录失败,请检查站点连通性'
if "login.php" in html_res.text:
logger.error(f"模拟登录失败cookie失效")
return False, f'{site}】模拟登录失败cookie失效'
html = etree.HTML(html_res.text)
if not html:
return False, f'{site}】模拟登录失败'
# 释放技能
msg = '失败'
x_csrf_token = html.xpath("//meta[@name='x-csrf-token']/@content")[0]
if x_csrf_token:
data = {
"all": 1,
"resetModal": "true"
}
headers = {
"x-csrf-token": str(x_csrf_token),
"Content-Type": "application/json; charset=utf-8",
"User-Agent": ua
}
skill_res = RequestUtils(cookies=site_cookie,
headers=headers,
proxies=proxy
).post_res(url="https://zhuque.in/api/gaming/fireGenshinCharacterMagic", json=data)
if not skill_res or skill_res.status_code != 200:
logger.error(f"模拟登录失败,释放技能失败")
# '{"status":200,"data":{"code":"FIRE_GENSHIN_CHARACTER_MAGIC_SUCCESS","bonus":0}}'
skill_dict = json.loads(skill_res.text)
if skill_dict['status'] == 200:
bonus = int(skill_dict['data']['bonus'])
msg = f'成功,获得{bonus}魔力'
logger.info(f'{site}】模拟登录成功,技能释放{msg}')
return True, f'{site}】模拟登录成功,技能释放{msg}'