skeleton of interacting with mediawiki. abandoning pywikibot
moving discord stuff back into a class
This commit is contained in:
parent
e4ba87171b
commit
079669a6d3
5 changed files with 202 additions and 65 deletions
40
poetry.lock
generated
40
poetry.lock
generated
|
@ -292,6 +292,14 @@ scripts = ["isbnlib", "unidecode", "mwparserfromhell (>=0.5.0)", "memento-client
|
||||||
"weblinkchecker.py" = ["memento-client (==0.6.1)"]
|
"weblinkchecker.py" = ["memento-client (==0.6.1)"]
|
||||||
wikitextparser = ["wikitextparser (>=0.47.5)", "wikitextparser (>=0.47.0)"]
|
wikitextparser = ["wikitextparser (>=0.47.5)", "wikitextparser (>=0.47.0)"]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "regex"
|
||||||
|
version = "2022.9.13"
|
||||||
|
description = "Alternative regular expression module, to replace re."
|
||||||
|
category = "main"
|
||||||
|
optional = false
|
||||||
|
python-versions = ">=3.6"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "requests"
|
name = "requests"
|
||||||
version = "2.28.0"
|
version = "2.28.0"
|
||||||
|
@ -388,6 +396,30 @@ brotli = ["brotlicffi (>=0.8.0)", "brotli (>=1.0.9)", "brotlipy (>=0.6.0)"]
|
||||||
secure = ["pyOpenSSL (>=0.14)", "cryptography (>=1.3.4)", "idna (>=2.0.0)", "certifi", "ipaddress"]
|
secure = ["pyOpenSSL (>=0.14)", "cryptography (>=1.3.4)", "idna (>=2.0.0)", "certifi", "ipaddress"]
|
||||||
socks = ["PySocks (>=1.5.6,!=1.5.7,<2.0)"]
|
socks = ["PySocks (>=1.5.6,!=1.5.7,<2.0)"]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "wcwidth"
|
||||||
|
version = "0.2.5"
|
||||||
|
description = "Measures the displayed width of unicode strings in a terminal"
|
||||||
|
category = "main"
|
||||||
|
optional = false
|
||||||
|
python-versions = "*"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "wikitextparser"
|
||||||
|
version = "0.51.1"
|
||||||
|
description = "A simple parsing tool for MediaWiki's wikitext markup."
|
||||||
|
category = "main"
|
||||||
|
optional = false
|
||||||
|
python-versions = ">=3.6"
|
||||||
|
|
||||||
|
[package.dependencies]
|
||||||
|
regex = ">=2022.9.11"
|
||||||
|
wcwidth = "*"
|
||||||
|
|
||||||
|
[package.extras]
|
||||||
|
dev = ["path.py", "coverage", "twine"]
|
||||||
|
tests = ["pytest"]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "yarl"
|
name = "yarl"
|
||||||
version = "1.8.1"
|
version = "1.8.1"
|
||||||
|
@ -403,7 +435,7 @@ multidict = ">=4.0"
|
||||||
[metadata]
|
[metadata]
|
||||||
lock-version = "1.1"
|
lock-version = "1.1"
|
||||||
python-versions = "^3.9"
|
python-versions = "^3.9"
|
||||||
content-hash = "a12006faa296b74e34d600ab7300f2926d58c153fa76c15a5b73f7c91077b6ab"
|
content-hash = "061b7fa1deb95223cf42da4bf28189c4e64a837bc00ff1617c1e66569184ac01"
|
||||||
|
|
||||||
[metadata.files]
|
[metadata.files]
|
||||||
aiohttp = []
|
aiohttp = []
|
||||||
|
@ -481,6 +513,7 @@ python-dateutil = [
|
||||||
{file = "python_dateutil-2.8.2-py2.py3-none-any.whl", hash = "sha256:961d03dc3453ebbc59dbdea9e4e11c5651520a876d0f4db161e8674aae935da9"},
|
{file = "python_dateutil-2.8.2-py2.py3-none-any.whl", hash = "sha256:961d03dc3453ebbc59dbdea9e4e11c5651520a876d0f4db161e8674aae935da9"},
|
||||||
]
|
]
|
||||||
pywikibot = []
|
pywikibot = []
|
||||||
|
regex = []
|
||||||
requests = [
|
requests = [
|
||||||
{file = "requests-2.28.0-py3-none-any.whl", hash = "sha256:bc7861137fbce630f17b03d3ad02ad0bf978c844f3536d0edda6499dafce2b6f"},
|
{file = "requests-2.28.0-py3-none-any.whl", hash = "sha256:bc7861137fbce630f17b03d3ad02ad0bf978c844f3536d0edda6499dafce2b6f"},
|
||||||
{file = "requests-2.28.0.tar.gz", hash = "sha256:d568723a7ebd25875d8d1eaf5dfa068cd2fc8194b2e483d7b1f7c81918dbec6b"},
|
{file = "requests-2.28.0.tar.gz", hash = "sha256:d568723a7ebd25875d8d1eaf5dfa068cd2fc8194b2e483d7b1f7c81918dbec6b"},
|
||||||
|
@ -509,4 +542,9 @@ urllib3 = [
|
||||||
{file = "urllib3-1.26.9-py2.py3-none-any.whl", hash = "sha256:44ece4d53fb1706f667c9bd1c648f5469a2ec925fcf3a776667042d645472c14"},
|
{file = "urllib3-1.26.9-py2.py3-none-any.whl", hash = "sha256:44ece4d53fb1706f667c9bd1c648f5469a2ec925fcf3a776667042d645472c14"},
|
||||||
{file = "urllib3-1.26.9.tar.gz", hash = "sha256:aabaf16477806a5e1dd19aa41f8c2b7950dd3c746362d7e3223dbe6de6ac448e"},
|
{file = "urllib3-1.26.9.tar.gz", hash = "sha256:aabaf16477806a5e1dd19aa41f8c2b7950dd3c746362d7e3223dbe6de6ac448e"},
|
||||||
]
|
]
|
||||||
|
wcwidth = [
|
||||||
|
{file = "wcwidth-0.2.5-py2.py3-none-any.whl", hash = "sha256:beb4802a9cebb9144e99086eff703a642a13d6a0052920003a230f3294bbe784"},
|
||||||
|
{file = "wcwidth-0.2.5.tar.gz", hash = "sha256:c4d647b99872929fdb7bdcaa4fbe7f01413ed3d98077df798530e5b04f116c83"},
|
||||||
|
]
|
||||||
|
wikitextparser = []
|
||||||
yarl = []
|
yarl = []
|
||||||
|
|
|
@ -19,6 +19,7 @@ parse = "^1.19.0"
|
||||||
pywikibot = "^7.7.0"
|
pywikibot = "^7.7.0"
|
||||||
pyparsing = "^3.0.9"
|
pyparsing = "^3.0.9"
|
||||||
"discord.py" = "^2.0.1"
|
"discord.py" = "^2.0.1"
|
||||||
|
wikitextparser = "^0.51.1"
|
||||||
|
|
||||||
[tool.poetry.dev-dependencies]
|
[tool.poetry.dev-dependencies]
|
||||||
pytest = "^7.1.2"
|
pytest = "^7.1.2"
|
||||||
|
|
|
@ -5,75 +5,75 @@ from wiki_postbot.patterns.wikilink import Wikilink
|
||||||
|
|
||||||
from discord.ext import commands
|
from discord.ext import commands
|
||||||
from discord import Emoji
|
from discord import Emoji
|
||||||
|
#
|
||||||
|
# intents = Intents.default()
|
||||||
|
# intents.message_content = True
|
||||||
|
#
|
||||||
|
# bot = commands.Bot(command_prefix='/', intents=intents)
|
||||||
|
#
|
||||||
|
# DEBUG = False
|
||||||
|
#
|
||||||
|
# @bot.event
|
||||||
|
# async def on_message(message:discord.Message):
|
||||||
|
# print(message)
|
||||||
|
#
|
||||||
|
# if message.content == 'ping':
|
||||||
|
# await message.channel.send('pong')
|
||||||
|
#
|
||||||
|
# if 'good bot' in message.content:
|
||||||
|
# await message.add_reaction("❤️🔥")
|
||||||
|
#
|
||||||
|
# wl = Wikilink.parse(message.content)
|
||||||
|
# if len(wl) > 0:
|
||||||
|
# if DEBUG:
|
||||||
|
# await message.channel.send(f"Wikilinks detected: \n" + '\n'.join([str(l) for l in wl]))
|
||||||
|
# else:
|
||||||
|
# await message.add_reaction("⏳")
|
||||||
|
#
|
||||||
|
# await bot.process_commands(message)
|
||||||
|
#
|
||||||
|
# @bot.command()
|
||||||
|
|
||||||
intents = Intents.default()
|
|
||||||
intents.message_content = True
|
|
||||||
|
|
||||||
bot = commands.Bot(command_prefix='/', intents=intents)
|
|
||||||
|
|
||||||
DEBUG = False
|
|
||||||
|
|
||||||
@bot.event
|
|
||||||
async def on_message(message:discord.Message):
|
|
||||||
print(message)
|
|
||||||
|
|
||||||
if message.content == 'ping':
|
|
||||||
await message.channel.send('pong')
|
|
||||||
|
|
||||||
if 'good bot' in message.content:
|
|
||||||
await message.add_reaction("❤️🔥")
|
|
||||||
|
|
||||||
wl = Wikilink.parse(message.content)
|
|
||||||
if len(wl) > 0:
|
|
||||||
if DEBUG:
|
|
||||||
await message.channel.send(f"Wikilinks detected: \n" + '\n'.join([str(l) for l in wl]))
|
|
||||||
else:
|
|
||||||
await message.add_reaction("⏳")
|
|
||||||
|
|
||||||
await bot.process_commands(message)
|
|
||||||
|
|
||||||
@bot.command()
|
|
||||||
async def debug(ctx:discord.ext.commands.Context, arg):
|
|
||||||
print('debug command')
|
|
||||||
global DEBUG
|
|
||||||
if arg == "on":
|
|
||||||
DEBUG = True
|
|
||||||
await ctx.message.add_reaction("🧪")
|
|
||||||
elif arg == "off":
|
|
||||||
DEBUG = False
|
|
||||||
await ctx.message.add_reaction("🤐")
|
|
||||||
else:
|
|
||||||
await ctx.message.reply("usage: /debug off or /debug on")
|
|
||||||
# @bot.command
|
# @bot.command
|
||||||
|
|
||||||
|
|
||||||
#
|
|
||||||
# class MyClient(Client):
|
|
||||||
#
|
|
||||||
# def __init__(self, intents=None, **kwargs):
|
|
||||||
# if intents is None:
|
|
||||||
# intents = Intents.default()
|
|
||||||
# intents.message_content = True
|
|
||||||
#
|
|
||||||
# super(MyClient, self).__init__(intents=intents, **kwargs)
|
|
||||||
#
|
|
||||||
#
|
|
||||||
# async def on_ready(self):
|
|
||||||
# print('Logged on as', self.user)
|
|
||||||
#
|
|
||||||
# async def on_message(self, message):
|
|
||||||
# print(message)
|
|
||||||
# # don't respond to ourselves
|
|
||||||
# if message.author == self.user:
|
|
||||||
# return
|
|
||||||
#
|
|
||||||
# if message.content == 'ping':
|
|
||||||
# await message.channel.send('pong')
|
|
||||||
#
|
|
||||||
# wl = Wikilink.parse(message.content)
|
|
||||||
# if len(wl)>0:
|
|
||||||
# await message.channel.send(f"Wikilinks detected: \n" + '\n'.join([str(l) for l in wl]))
|
|
||||||
|
|
||||||
|
class MyClient(Client):
|
||||||
|
|
||||||
|
def __init__(self, intents=None, debug:bool=False, **kwargs):
|
||||||
|
if intents is None:
|
||||||
|
intents = Intents.default()
|
||||||
|
intents.message_content = True
|
||||||
|
|
||||||
|
self.debug = debug
|
||||||
|
|
||||||
|
super(MyClient, self).__init__(intents=intents, **kwargs)
|
||||||
|
|
||||||
|
|
||||||
|
async def on_ready(self):
|
||||||
|
print('Logged on as', self.user)
|
||||||
|
|
||||||
|
async def on_message(self, message):
|
||||||
|
print(message)
|
||||||
|
# don't respond to ourselves
|
||||||
|
if message.author == self.user:
|
||||||
|
return
|
||||||
|
|
||||||
|
wl = Wikilink.parse(message.content)
|
||||||
|
if len(wl)>0:
|
||||||
|
await message.channel.send(f"Wikilinks detected: \n" + '\n'.join([str(l) for l in wl]))
|
||||||
|
|
||||||
|
async def debug(ctx: discord.ext.commands.Context, arg):
|
||||||
|
print('debug command')
|
||||||
|
global DEBUG
|
||||||
|
if arg == "on":
|
||||||
|
DEBUG = True
|
||||||
|
await ctx.message.add_reaction("🧪")
|
||||||
|
elif arg == "off":
|
||||||
|
DEBUG = False
|
||||||
|
await ctx.message.add_reaction("🤐")
|
||||||
|
else:
|
||||||
|
await ctx.message.reply("usage: /debug off or /debug on")
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
|
|
|
@ -41,3 +41,15 @@ class Discord_Creds:
|
||||||
with open(path, 'r') as jfile:
|
with open(path, 'r') as jfile:
|
||||||
creds = json.load(jfile)
|
creds = json.load(jfile)
|
||||||
return Discord_Creds(**creds)
|
return Discord_Creds(**creds)
|
||||||
|
|
||||||
|
|
||||||
|
@dataclass
|
||||||
|
class Mediawiki_Creds:
|
||||||
|
user:str
|
||||||
|
password:str
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def from_json(cls, path:Path) -> 'Mediawiki_Creds':
|
||||||
|
with open(path, 'r') as jfile:
|
||||||
|
creds = json.load(jfile)
|
||||||
|
return Mediawiki_Creds(**creds)
|
|
@ -1,4 +1,90 @@
|
||||||
"""
|
"""
|
||||||
Class for interfacing with mediawiki
|
Class for interfacing with mediawiki
|
||||||
"""
|
"""
|
||||||
|
from typing import List
|
||||||
|
from urllib.parse import urljoin
|
||||||
|
from dataclasses import dataclass
|
||||||
|
from wiki_postbot.creds import Mediawiki_Creds
|
||||||
|
import requests
|
||||||
|
|
||||||
|
# creds = Mediawiki_Creds.from_json('mediawiki_creds.json')
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
class Wiki:
|
||||||
|
def __init__(self, url:str, api_suffix:str="/api.php"):
|
||||||
|
self.url = url
|
||||||
|
self.api_url = urljoin(self.url, api_suffix)
|
||||||
|
self.sess = None
|
||||||
|
|
||||||
|
|
||||||
|
def login(self, creds:Mediawiki_Creds) -> requests.Session:
|
||||||
|
# get token to log in
|
||||||
|
sess = requests.Session()
|
||||||
|
|
||||||
|
login_token = sess.get(
|
||||||
|
self.api_url,
|
||||||
|
params={
|
||||||
|
"action":"query",
|
||||||
|
"meta":"tokens",
|
||||||
|
"type":"login",
|
||||||
|
"format":"json"
|
||||||
|
},
|
||||||
|
verify=False
|
||||||
|
).json()['query']['tokens']['logintoken']
|
||||||
|
|
||||||
|
|
||||||
|
login_result = sess.post(
|
||||||
|
self.api_url,
|
||||||
|
data = {
|
||||||
|
"action":"login",
|
||||||
|
"lgname":creds.user,
|
||||||
|
"lgpassword":creds.password,
|
||||||
|
"lgtoken": login_token,
|
||||||
|
"format": "json"
|
||||||
|
},
|
||||||
|
verify=False
|
||||||
|
)
|
||||||
|
assert login_result.json()['login']['result'] == "Success"
|
||||||
|
self.sess = sess
|
||||||
|
return sess
|
||||||
|
|
||||||
|
def get_page_content(self, page:str) -> str:
|
||||||
|
|
||||||
|
content = self.sess.get(
|
||||||
|
self.api_url,
|
||||||
|
params={
|
||||||
|
'action':'parse',
|
||||||
|
'page': page,
|
||||||
|
'prop': 'wikitext',
|
||||||
|
'formatversion':'2',
|
||||||
|
'format':'json'
|
||||||
|
}
|
||||||
|
).json()
|
||||||
|
return content['parse']['wikitext']
|
||||||
|
|
||||||
|
def insert_text(self, page, section, text):
|
||||||
|
|
||||||
|
token = self.sess.get(
|
||||||
|
self.api_url,
|
||||||
|
params={
|
||||||
|
"action": "query",
|
||||||
|
"meta": "tokens",
|
||||||
|
"format": "json"
|
||||||
|
},
|
||||||
|
verify=False
|
||||||
|
).json()['query']['tokens']['csrftoken']
|
||||||
|
|
||||||
|
result = self.sess.post(
|
||||||
|
self.api_url,
|
||||||
|
data={
|
||||||
|
"action":"edit",
|
||||||
|
"title":page,
|
||||||
|
"section":"new",
|
||||||
|
"sectiontitle":section,
|
||||||
|
"appendtext":text,
|
||||||
|
"format":"json",
|
||||||
|
"token":token
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
Loading…
Reference in a new issue