This commit is contained in:
2026-09-12 23:34:46 +08:00
commit 416e864ffe
4 changed files with 323 additions and 0 deletions
+175
View File
@@ -0,0 +1,175 @@
# ---> Python
# Byte-compiled / optimized / DLL files
__pycache__/
*.py[cod]
*$py.class
# C extensions
*.so
# Distribution / packaging
.Python
build/
develop-eggs/
dist/
downloads/
eggs/
.eggs/
lib/
lib64/
parts/
sdist/
var/
wheels/
share/python-wheels/
*.egg-info/
.installed.cfg
*.egg
MANIFEST
# PyInstaller
# Usually these files are written by a python script from a template
# before PyInstaller builds the exe, so as to inject date/other infos into it.
*.manifest
*.spec
# Installer logs
pip-log.txt
pip-delete-this-directory.txt
# Unit test / coverage reports
htmlcov/
.tox/
.nox/
.coverage
.coverage.*
.cache
nosetests.xml
coverage.xml
*.cover
*.py,cover
.hypothesis/
.pytest_cache/
cover/
# Translations
*.mo
*.pot
# Django stuff:
*.log
local_settings.py
db.sqlite3
db.sqlite3-journal
# Flask stuff:
instance/
.webassets-cache
# Scrapy stuff:
.scrapy
# Sphinx documentation
docs/_build/
# PyBuilder
.pybuilder/
target/
# Jupyter Notebook
.ipynb_checkpoints
# IPython
profile_default/
ipython_config.py
# pyenv
# For a library or package, you might want to ignore these files since the code is
# intended to run in multiple environments; otherwise, check them in:
# .python-version
# pipenv
# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
# However, in case of collaboration, if having platform-specific dependencies or dependencies
# having no cross-platform support, pipenv may install dependencies that don't work, or not
# install all needed dependencies.
#Pipfile.lock
# UV
# Similar to Pipfile.lock, it is generally recommended to include uv.lock in version control.
# This is especially recommended for binary packages to ensure reproducibility, and is more
# commonly ignored for libraries.
#uv.lock
# poetry
# Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control.
# This is especially recommended for binary packages to ensure reproducibility, and is more
# commonly ignored for libraries.
# https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control
#poetry.lock
# pdm
# Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control.
#pdm.lock
# pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it
# in version control.
# https://pdm.fming.dev/latest/usage/project/#working-with-version-control
.pdm.toml
.pdm-python
.pdm-build/
# PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm
__pypackages__/
# Celery stuff
celerybeat-schedule
celerybeat.pid
# SageMath parsed files
*.sage.py
# Environments
.env
.venv
env/
venv/
ENV/
env.bak/
venv.bak/
# Spyder project settings
.spyderproject
.spyproject
# Rope project settings
.ropeproject
# mkdocs documentation
/site
# mypy
.mypy_cache/
.dmypy.json
dmypy.json
# Pyre type checker
.pyre/
# pytype static type analyzer
.pytype/
# Cython debug symbols
cython_debug/
# PyCharm
# JetBrains specific template is maintained in a separate JetBrains.gitignore that can
# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
# and can be added to the global gitignore or merged into this file. For a more nuclear
# option (not recommended) you can uncomment the following to ignore the entire idea folder.
#.idea/
# Ruff stuff:
.ruff_cache/
# PyPI configuration file
.pypirc
+87
View File
@@ -0,0 +1,87 @@
import requests
import re
import json
import time
import random
class bobbySession(requests.Session):
def __init__(self,account:str,password:str) -> None:
super().__init__()
self.account = account
self.password = password
try:
self.Refresh()
except:
raise SystemError("无法连接到bobby皮肤站")
def Refresh(self):
self.__XSRF_COOKIE_Init()
self.__Login(self.account,self.password)
def __XSRF_COOKIE_Init(self) :
url = r"https://www.bobbyskin.com/auth/login"
html = self.get(url)
# 正则查找
pattern = r'<meta name="csrf-token"([^<^>^]*)>'
txt = html.text
pattern2 = r'(?<=content=)"[^"]*"'
res1 = re.search(pattern,txt)
if res1 is None:
raise ValueError("cant find xsrf token")
res2 = re.search(pattern2,res1[0])
if res2 is None :
raise ValueError("cant find xsrf token")
self.headers['X-Csrf-Token'] = res2[0].replace('"',"")
return
# 登录初始化
def __Login(self,account:str,password:str):
body = {
"identification" : account,
"keep" : "true",
"password" : password
}
resp = self.post(r"https://www.bobbyskin.com/auth/login",json=body)
# 生成邀请码
def __GenerateInvite (self) :
xsrf = self.headers.get("X-Csrf-Token")
if xsrf is None :
raise requests.RequestException("XSRF expired or unavailable")
body = {
"_token" : xsrf,
"description" : time.strftime("%Y%m%d%H%M%S")
}
res = self.post(r"https://www.bobbyskin.com/admin/invitation-codes/generate",data=body)
# print(res.text,res.status_code)
# 查找可用邀请码
def __getInvite(self)->list[str]:
url = "https://www.bobbyskin.com/admin/invitation-codes"
tablePattern = r'<tbody>((?!</tbody>)[\S\s])*</tbody>'
codePattern = r'(?<=<td>)([a-zA-Z0-9])+(?=</td>)'
html = self.get(url).text
table = re.search(tablePattern,html)
if table is None :
raise ValueError("cant parse html table")
codes =re.finditer(codePattern,table[0])
# print (table[0])
res:list[str] = []
for i in codes :
res.append(i.group())
return res
def getInviteCode(self,step=0)->str:
if step == 5:
raise SystemError("验证码查找失败")
try :
codes = self.__getInvite()
if codes.__len__() == 0:
self.__GenerateInvite()
return self.getInviteCode(step+1)
rand =random.randrange(0,codes.__len__())
return codes[rand]
except:
self.Refresh()
return self.getInviteCode(step+1)
+58
View File
@@ -0,0 +1,58 @@
import botpy
from botpy.message import Message
from dotenv import load_dotenv
import os
import types
from bobby import bobbySession
#环境配置
class djtuWebsocket (botpy.Client) :
async def on_group_at_message_create(self, message: Message):
await self.parseCommand(message)
async def on_group_message_create(self,message:Message):
await self.parseGlobalMessage(message)
async def parseCommand(self,msg :Message):
commands:dict[str,types.MethodType|types.FunctionType] = {
r'/邀请码' : bobby.getInviteCode,
r'吃什么' : lambda :"是啊吃什么"
}
required = msg.content
reply = ""
for cmd,func in commands.items():
if required.find(cmd) != -1:
try:
reply = func()
except:
reply = "服务异常"
break
if reply.__len__() == 0:
reply = "你在发什么东西我怎么看不懂?"
await msg.reply(content=reply)
async def parseGlobalMessage(self,msg:Message):
await msg.reply(content="awda")
# source
load_dotenv(".env")
print(os.getenv("APP_ID"))
bbyAccount = os.getenv("BOBBY_ACCOUNT")
bbyPasswd = os.getenv("BOBBY_PASSWORD")
appid = os.getenv("APP_ID")
secret_bot = os.getenv("SECRET")
# bobby Session
if bbyAccount is None or bbyPasswd is None :
raise SystemError("未找到账密配置")
if appid is None or secret_bot is None :
raise SystemError("未找到bot配置")
bobby = bobbySession(bbyAccount,bbyPasswd)
#bot 启动
ws = djtuWebsocket(botpy.Intents(public_messages=True))
ws.run(appid=appid,secret=secret_bot)
+3
View File
@@ -0,0 +1,3 @@
requests
qq-botpy
dotenv