|
|
|
from flask import Flask, jsonify, request, redirect, url_for
|
|
|
|
from flask_cors import CORS, cross_origin
|
|
|
|
import datetime
|
|
|
|
import frontmatter
|
|
|
|
from glob import glob
|
|
|
|
|
|
|
|
import os
|
|
|
|
from dotenv import load_dotenv
|
|
|
|
from pathlib import Path
|
|
|
|
|
|
|
|
dotenv_path = Path("/var/www/.mw-credentials")
|
|
|
|
load_dotenv(dotenv_path=dotenv_path)
|
|
|
|
|
|
|
|
|
|
|
|
# prefix to add /SOUPBOAT/ATLAS-API 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()]
|
|
|
|
|
|
|
|
|
|
|
|
base_url = "/soupboat/cookbook"
|
|
|
|
|
|
|
|
# create flask application
|
|
|
|
app = Flask(__name__)
|
|
|
|
CORS(app)
|
|
|
|
|
|
|
|
# register the middleware to prefix all the requests with our base_url
|
|
|
|
app.wsgi_app = PrefixMiddleware(app.wsgi_app, prefix=base_url)
|
|
|
|
|
|
|
|
|
|
|
|
# save the incoming data into a markdown file
|
|
|
|
# data is a dictionary with at least a 'title' key
|
|
|
|
def create_recipe(data):
|
|
|
|
# create filename from the title
|
|
|
|
# TODO: ensure safe filename
|
|
|
|
slug = data["title"].replace(" ", "-").lower()
|
|
|
|
today = datetime.datetime.now().strftime("%d-%m-%Y_%H-%M-%S")
|
|
|
|
|
|
|
|
# create the list of properties from the incoming data, add the date
|
|
|
|
recipe = {**data, "date": datetime.datetime.now()}
|
|
|
|
post = frontmatter.Post("", **recipe)
|
|
|
|
|
|
|
|
# save the data in a markdown file
|
|
|
|
# TODO: print directly yml file instead of md?
|
|
|
|
# since we are not really using the body of the md but just the yml frontmatter
|
|
|
|
with open(f"recipes/{slug}_{today}.md", "w") as f:
|
|
|
|
documentation = frontmatter.dumps(post)
|
|
|
|
f.write(documentation)
|
|
|
|
print(f"{data['title']} - saved in the archive")
|
|
|
|
|
|
|
|
|
|
|
|
# read the files from the recipes folder and return them in a list
|
|
|
|
def get_recipes():
|
|
|
|
recipes = []
|
|
|
|
paths = glob("recipes/*.md")
|
|
|
|
for path in paths:
|
|
|
|
with open(path, "r") as f:
|
|
|
|
meta, content = frontmatter.parse(f.read())
|
|
|
|
recipes.append(meta)
|
|
|
|
return recipes
|
|
|
|
|
|
|
|
|
|
|
|
def update_wiki(recipe):
|
|
|
|
import mwclient
|
|
|
|
import textwrap
|
|
|
|
|
|
|
|
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['Test form test form test form test']
|
|
|
|
|
|
|
|
text = page.text()
|
|
|
|
|
|
|
|
steps = [f"# {log}" for log in recipe["logs"]].join('\n')
|
|
|
|
|
|
|
|
# PROV TEMPLATE
|
|
|
|
content = f"""
|
|
|
|
=== {recipe['title']} ===
|
|
|
|
''{recipe['description']}''
|
|
|
|
<br>
|
|
|
|
'''Nature of the input'''
|
|
|
|
<br>
|
|
|
|
{recipe['nature']}
|
|
|
|
<br>
|
|
|
|
''' Process Log'''
|
|
|
|
<br>
|
|
|
|
{steps}
|
|
|
|
'''Who'''
|
|
|
|
<br>
|
|
|
|
{recipe['who']}
|
|
|
|
"""
|
|
|
|
|
|
|
|
# mi disp
|
|
|
|
text += [line.strip() for line in content.splitlines()].join('\n')
|
|
|
|
|
|
|
|
|
|
|
|
print(text)
|
|
|
|
|
|
|
|
page.edit(text, f'Added a new recipe! {recipe["title"]}')
|
|
|
|
|
|
|
|
|
|
|
|
# sample object to test the md output
|
|
|
|
r = {
|
|
|
|
"title": "Test test test",
|
|
|
|
"description": "A super simple description",
|
|
|
|
"logs": ["first step", "second step", "third step"],
|
|
|
|
"who": "a friend of mine",
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
# TODO: get data from client
|
|
|
|
@app.route("/", methods=["GET", "POST"])
|
|
|
|
def home():
|
|
|
|
if request.method == "POST":
|
|
|
|
create_recipe(request.json)
|
|
|
|
update_wiki(request.json)
|
|
|
|
redirect(url_for("home"))
|
|
|
|
|
|
|
|
return redirect("https://issue.xpub.nl/18/")
|
|
|
|
|
|
|
|
|
|
|
|
# return the list of recipes in JSON format
|
|
|
|
@app.route("/get")
|
|
|
|
def get():
|
|
|
|
recipes = get_recipes()
|
|
|
|
return jsonify(recipes)
|
|
|
|
|
|
|
|
|
|
|
|
# TODO: set another port and setup nginx
|
|
|
|
app.run(port=3145)
|