You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
242 lines
9.9 KiB
Python
242 lines
9.9 KiB
Python
import json
|
|
import sys
|
|
import time
|
|
from typing import Optional
|
|
import aiohttp
|
|
import config
|
|
|
|
class MediaWikiApiException(Exception):
|
|
def __init__(self, info: str, code: Optional[str] = None) -> None:
|
|
super().__init__(info)
|
|
self.info = info
|
|
self.code = code
|
|
self.message = self.info
|
|
|
|
def __str__(self) -> str:
|
|
return self.info
|
|
|
|
class MediaWikiPageNotFoundException(MediaWikiApiException):
|
|
pass
|
|
|
|
class MediaWikiApi:
|
|
cookie_jar = aiohttp.CookieJar(unsafe=True)
|
|
|
|
@staticmethod
|
|
def create():
|
|
return MediaWikiApi(config.MW_API)
|
|
|
|
def __init__(self, api_url: str):
|
|
self.api_url = api_url
|
|
self.login_time = 0
|
|
self.login_identity = None
|
|
|
|
async def get_page_info(self, title: str):
|
|
async with aiohttp.ClientSession(cookie_jar=self.cookie_jar) as session:
|
|
params = {
|
|
"action": "query",
|
|
"format": "json",
|
|
"formatversion": "2",
|
|
"prop": "info",
|
|
"titles": title,
|
|
"inprop": "url"
|
|
}
|
|
async with session.get(self.api_url, params=params, proxy=config.REQUEST_PROXY) as resp:
|
|
data = await resp.json()
|
|
if "error" in data:
|
|
raise MediaWikiApiException(data["error"]["info"], data["error"]["code"])
|
|
|
|
if "missing" in data["query"]["pages"][0]:
|
|
raise MediaWikiPageNotFoundException()
|
|
|
|
return data["query"]["pages"][0]
|
|
|
|
async def parse_page(self, title: str):
|
|
async with aiohttp.ClientSession(cookie_jar=self.cookie_jar) as session:
|
|
params = {
|
|
"action": "parse",
|
|
"format": "json",
|
|
"formatversion": "2",
|
|
"prop": "text",
|
|
"page": title,
|
|
"disableeditsection": "true",
|
|
"disabletoc": "true",
|
|
"disablelimitreport": "true",
|
|
}
|
|
async with session.get(self.api_url, params=params, proxy=config.REQUEST_PROXY) as resp:
|
|
data = await resp.json()
|
|
if "error" in data:
|
|
raise MediaWikiApiException(data["error"]["info"], data["error"]["code"])
|
|
|
|
return data["parse"]["text"]
|
|
|
|
async def get_site_meta(self):
|
|
async with aiohttp.ClientSession(cookie_jar=self.cookie_jar) as session:
|
|
params = {
|
|
"action": "query",
|
|
"format": "json",
|
|
"formatversion": "2",
|
|
"meta": "siteinfo|userinfo",
|
|
"siprop": "general"
|
|
}
|
|
async with session.get(self.api_url, params=params, proxy=config.REQUEST_PROXY) as resp:
|
|
data = await resp.json()
|
|
if "error" in data:
|
|
raise MediaWikiApiException(data["error"]["info"], data["error"]["code"])
|
|
|
|
ret = {
|
|
"sitename": "Unknown",
|
|
"user": "Anonymous",
|
|
}
|
|
if "query" in data:
|
|
if "general" in data["query"]:
|
|
ret["sitename"] = data["query"]["general"]["sitename"]
|
|
if "userinfo" in data["query"]:
|
|
ret["user"] = data["query"]["userinfo"]["name"]
|
|
|
|
return ret
|
|
|
|
|
|
async def get_token(self, token_type: str):
|
|
async with aiohttp.ClientSession(cookie_jar=self.cookie_jar) as session:
|
|
params = {
|
|
"action": "query",
|
|
"format": "json",
|
|
"formatversion": "2",
|
|
"meta": "tokens",
|
|
"type": token_type
|
|
}
|
|
async with session.get(self.api_url, params=params, proxy=config.REQUEST_PROXY) as resp:
|
|
data = await resp.json()
|
|
if "error" in data:
|
|
raise MediaWikiApiException(data["error"]["info"], data["error"]["code"])
|
|
|
|
return data["query"]["tokens"][token_type + "token"]
|
|
|
|
async def robot_login(self, username: str, password: str):
|
|
token = await self.get_token("login")
|
|
async with aiohttp.ClientSession(cookie_jar=self.cookie_jar) as session:
|
|
post_data = {
|
|
"action": "login",
|
|
"format": "json",
|
|
"formatversion": "2",
|
|
"lgname": username,
|
|
"lgpassword": password,
|
|
"lgtoken": token,
|
|
}
|
|
async with session.post(self.api_url, data=post_data, proxy=config.REQUEST_PROXY) as resp:
|
|
data = await resp.json()
|
|
if "error" in data:
|
|
raise MediaWikiApiException(data["error"]["info"], data["error"]["code"])
|
|
|
|
if "result" not in data["login"] or data["login"]["result"] != "Success":
|
|
raise MediaWikiApiException("Login failed")
|
|
|
|
self.login_time = time.time()
|
|
self.login_identity = {
|
|
"username": username,
|
|
"password": password,
|
|
}
|
|
|
|
return True
|
|
|
|
async def refresh_login(self):
|
|
if self.login_identity is None:
|
|
return False
|
|
if time.time() - self.login_time > 10:
|
|
return await self.robot_login(self.login_identity["username"], self.login_identity["password"])
|
|
|
|
async def chat_complete_user_info(self, user_id: int):
|
|
await self.refresh_login()
|
|
|
|
async with aiohttp.ClientSession(cookie_jar=self.cookie_jar) as session:
|
|
params = {
|
|
"action": "chatcompletebot",
|
|
"method": "userinfo",
|
|
"userid": user_id,
|
|
"format": "json",
|
|
"formatversion": "2",
|
|
}
|
|
async with session.get(self.api_url, params=params, proxy=config.REQUEST_PROXY) as resp:
|
|
data = await resp.json()
|
|
if "error" in data:
|
|
if data["error"]["code"] == "user-not-found":
|
|
raise MediaWikiPageNotFoundException(data["error"]["info"], data["error"]["code"])
|
|
else:
|
|
raise MediaWikiApiException(data["error"]["info"], data["error"]["code"])
|
|
|
|
return data["chatcompletebot"]["userinfo"]
|
|
|
|
async def chat_complete_start_transaction(self, user_id: int, user_action: str, tokens: Optional[int] = None, extractlines: Optional[int] = None) -> str:
|
|
await self.refresh_login()
|
|
|
|
async with aiohttp.ClientSession(cookie_jar=self.cookie_jar) as session:
|
|
post_data = {
|
|
"action": "chatcompletebot",
|
|
"method": "reportusage",
|
|
"step": "start",
|
|
"userid": int(user_id),
|
|
"useraction": user_action,
|
|
"tokens": int(tokens),
|
|
"extractlines": int(extractlines),
|
|
"format": "json",
|
|
"formatversion": "2",
|
|
}
|
|
# Filter out None values
|
|
post_data = {k: v for k, v in post_data.items() if v is not None}
|
|
async with session.post(self.api_url, data=post_data, proxy=config.REQUEST_PROXY) as resp:
|
|
data = await resp.json()
|
|
if "error" in data:
|
|
print(data)
|
|
raise MediaWikiApiException(data["error"]["info"], data["error"]["code"])
|
|
|
|
return data["chatcompletebot"]["reportusage"]["transactionid"]
|
|
|
|
async def chat_complete_end_transaction(self, transaction_id: str, tokens: Optional[int] = None):
|
|
await self.refresh_login()
|
|
|
|
try:
|
|
async with aiohttp.ClientSession(cookie_jar=self.cookie_jar) as session:
|
|
post_data = {
|
|
"action": "chatcompletebot",
|
|
"method": "reportusage",
|
|
"step": "end",
|
|
"transactionid": transaction_id,
|
|
"tokens": tokens,
|
|
"format": "json",
|
|
"formatversion": "2",
|
|
}
|
|
# Filter out None values
|
|
post_data = {k: v for k, v in post_data.items() if v is not None}
|
|
async with session.post(self.api_url, data=post_data, proxy=config.REQUEST_PROXY) as resp:
|
|
data = await resp.json()
|
|
if "error" in data:
|
|
raise MediaWikiApiException(data["error"]["info"], data["error"]["code"])
|
|
|
|
return data["chatcompletebot"]["reportusage"]["success"]
|
|
except Exception as e:
|
|
print(e, file=sys.stderr)
|
|
|
|
async def chat_complete_cancel_transaction(self, transaction_id: str, error: Optional[str] = None):
|
|
await self.refresh_login()
|
|
|
|
try:
|
|
async with aiohttp.ClientSession(cookie_jar=self.cookie_jar) as session:
|
|
post_data = {
|
|
"action": "chatcompletebot",
|
|
"method": "reportusage",
|
|
"step": "cancel",
|
|
"transactionid": transaction_id,
|
|
"error": error,
|
|
"format": "json",
|
|
"formatversion": "2",
|
|
}
|
|
# Filter out None values
|
|
post_data = {k: v for k, v in post_data.items() if v is not None}
|
|
async with session.get(self.api_url, data=post_data, proxy=config.REQUEST_PROXY) as resp:
|
|
data = await resp.json()
|
|
if "error" in data:
|
|
raise MediaWikiApiException(data["error"]["info"], data["error"]["code"])
|
|
|
|
return data["chatcompletebot"]["reportusage"]["success"]
|
|
except Exception as e:
|
|
print(e, file=sys.stderr) |