mastodon-ld/masto_ld/interfaces/mediawiki.py

150 lines
4.5 KiB
Python

from pathlib import Path
from typing import Optional
from urllib.parse import urljoin
import requests
from masto_ld.creds import Mediawiki_Creds
from masto_ld.formats.wiki import WikiPage
from masto_ld.logger import init_logger
from masto_ld.config import Config
class Wiki:
def __init__(self, config:Config,
api_suffix:str="/api.php", index_page="Discord Messages",
log_dir:Path=Path('/var/www/wikibot')):
self.url = config.WIKI_URL
self.api_url = urljoin(self.url, api_suffix)
self.creds = Mediawiki_Creds(config.WIKI_USER, config.WIKI_PASSWORD)
self.sess = None
self.index_page = index_page
self.logger = init_logger('wiki_interface', basedir=log_dir)
self.login(self.creds)
def login(self, creds:Mediawiki_Creds):
# 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
def get_page(self, page:str) -> Optional[WikiPage]:
content = self.sess.get(
self.api_url,
params={
'action':'parse',
'page': page,
'prop': 'wikitext',
'formatversion':'2',
'format':'json'
}
).json()
if content.get('error', {}).get('code', '') == 'missingtitle':
# Page does not exist!
self.logger.debug("Page does not exist")
return None
self.logger.debug(f"Got Page content:")
self.logger.debug(content)
return WikiPage.from_source(title=content['parse']['title'], source=content['parse']['wikitext'])
def new_page(self, page, 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,
"appendtext": text,
"format": "json",
"token": token
}
)
def insert_text(self, page, section, text):
# TODO: Move finding section IDs into the page class!
page_text = self.get_page(page)
matching_section = -1
if page_text is not None:
# find section number
sections = page_text.content.get_sections()
for i, page_section in enumerate(sections):
if page_section.title is not None and page_section.title.strip().lower() == section.lower():
matching_section = i
break
token = self.sess.get(
self.api_url,
params={
"action": "query",
"meta": "tokens",
"format": "json"
},
verify=False
).json()['query']['tokens']['csrftoken']
if matching_section >= 0:
print(f'found matching section {matching_section}')
result = self.sess.post(
self.api_url,
data={
"action":"edit",
"title":page,
"section":str(matching_section),
"appendtext":text,
"format":"json",
"token":token
}
)
else:
self.logger.debug('making new section')
result = self.sess.post(
self.api_url,
data={
"action":"edit",
"title":page,
"section":"new",
"sectiontitle":section,
"appendtext":text,
"format":"json",
"token":token
}
)
return result