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.

158 lines
4.2 KiB
Python

import logging
logging.basicConfig(format='%(asctime)s : %(levelname)s : %(message)s', level=logging.INFO)
logging.getLogger('flask_cors').level = logging.DEBUG
from datetime import datetime
# Flask application to serve the web pages
from flask import Flask, request, redirect, url_for, jsonify
from flask_cors import CORS, cross_origin
# from flask_mako import MakoTemplates, render_template
# Mediawiki client to interact with the Wiki
import mwclient
# BS to read the html table from the wiki
from bs4 import BeautifulSoup
# os and dotenv to store the mediawiki credentials in a safe place
import os
from dotenv import load_dotenv
from pathlib import Path
# load the mediawiki credentials from the shared folder
dotenv_path = Path("/var/www/.mw-credentials")
load_dotenv(dotenv_path=dotenv_path)
# prefix to add /soupboat/padliography to all the routes
# and to leave the @app.route() decorator more clean
class PrefixMiddleware(object):
def __init__(self, app, prefix=""):
self.app = app
self.prefix = prefix
def __call__(self, environ, start_response):
if environ["PATH_INFO"].startswith(self.prefix):
environ["PATH_INFO"] = environ["PATH_INFO"][len(self.prefix) :]
environ["SCRIPT_NAME"] = self.prefix
return self.app(environ, start_response)
else:
start_response("404", [("Content-Type", "text/plain")])
return ["This url does not belong to the app.".encode()]
# create flask application
app = Flask(__name__)
CORS(app)
# Url prefix for the soupboat
base_url = os.environ.get('BASE_URL', '')
# Page of the wiki with the pads
padliography = 'Padliography2'
# register the middleware to prefix all the requests with our base_url
app.wsgi_app = PrefixMiddleware(app.wsgi_app, prefix=base_url)
def add_pad(link, title, overview, categories, date):
site = mwclient.Site('pzwiki.wdka.nl', path='/mw-mediadesign/')
site.login(
username=os.environ.get('MW_BOT'),
password=os.environ.get('MW_KEY')
)
page = site.pages[padliography]
text = page.text()
new_row = f'|-\n| {link} || {title} || {overview} || {categories} || {date} \n|-\n' + '|}'
text = text.replace('|}', new_row)
page.edit(text, f'New pad in the {padliography}: {title}')
def get_pads():
site = mwclient.Site('pzwiki.wdka.nl', path='/mw-mediadesign/')
site.login(
username=os.environ.get('MW_BOT'),
password=os.environ.get('MW_KEY'),
)
html = site.api('parse', prop='text', page=padliography)
table = BeautifulSoup(html['parse']['text']['*'], features="html.parser").find("table", attrs={"class":"padliography"})
headers = [header.text.lower().strip() for header in table.find_all('th')]
pads = [
{headers[i]: cell.text.rstrip('\n') for i, cell in enumerate(row.find_all('td'))}
for row in table.find_all('tr')]
pads = [ pad for pad in pads if pad != {}]
return pads
@app.route('/', methods=['GET', 'POST'])
def home():
if request.method == 'POST':
link = request.json.get('link', None)
title = request.json.get('title', None)
overview = request.json.get('overview', '')
categories = request.json.get('categories', '')
date = request.json.get('date', None)
date = datetime.strftime(datetime.strptime(date, 'yyyy-mm-dd'), 'dd-mm-yyyy')
add_pad(link, title, overview, categories, date)
redirect(url_for('home'))
return jsonify(get_pads())
# pads = get_pads()
# categories = list(set([
# c.strip() for pad in pads for c in pad['category'].split(',')
# ]))
# return render_template('index.html', pads=pads, categories=categories)
# @app.route('/add')
# def add():
# link = request.args.get('link', None)
# title = request.args.get('title', None)
# overview = request.args.get('overview', '')
# categories = request.args.get('categories', '')
# date = request.args.get('date', None)
# if None not in (link, title, date):
# add_pad(link, title, overview, categories, date)
# redirect(url_for('home'))
# return render_template('index.html')
app.run(port=3147, debug=True)