Commit 02107a1f authored by Robin Sonnabend's avatar Robin Sonnabend

Implement everything

parents
venv/
*.sw[po]
__pycache__/
.flaskenv
config.py
This source diff could not be displayed because it is too large. You can view the blob instead.
body {
padding-top: 65px;
padding-bottom: 10px;
}
.alert {
font-weight: bold;
text-align: center;
}
.alert-error {
color: #800000;
}
.alert-success {
color: #008000;
}
.alert-warning {
color: #808000;
}
h2 > a, h3 > a {
font-size: 18px;
}
h4 > a {
font-size: 14px;
}
form:not(.form-inline) {
max-width: 350px;
margin: 0 auto;
}
.form-inline {
padding-bottom: 5px;
}
input[type="file"] {
padding: 0;
}
.centered {
text-align: center;
}
.centered > a, .centered > span {
margin: 8px;
}
pre.error-description {
white-space: pre-wrap;
}
.expansion-text {
display: none;
font-style: normal;
}
textarea {
border: 0 none white;
padding: 0;
outline: none;
background-color: #d0d0d0;
}
li.defaulttop {
font-style: italic;
}
div.expandable {
max-height: 4rem;
overflow: hidden;
cursor: zoom-in;
box-shadow: 0px 0px 30px #d0d0d0;
margin: 10px 0 10px 0;
padding: 0 10px 0 10px;
}
div.expandable:focus-within {
max-height: none;
overflow: auto;
cursor: default;
}
This diff is collapsed.
This diff is collapsed.
from flask import Flask, request, session, redirect, url_for, abort, render_template, Response, Markup
from flask_wtf import FlaskForm
from wtforms import StringField, TextAreaField, SelectField
import requests
import bs4
import os
import urllib
app = Flask(__name__, static_folder="argumenthelperstatic")
app.config["SECRET_KEY"] = os.urandom(64)
wikis = {
"Wikipedia Deutsch": "https://de.wikipedia.org/wiki/",
"Wikipedia English": "https://en.wikipedia.org/wiki/",
"Wikipedia Deutsch (mobil)": "https://de.m.wikipedia.org/wiki/",
"Wikipedia English (mobile)": "https://en.m.wikipedia.org/wiki/",
"FSMPI PubWiki": "https://pubwiki.fsmpi.rwth-aachen.de",
}
wiki_choices = list(zip(wikis.keys(), wikis.keys()))
class RequestForm(FlaskForm):
page = StringField("Page")
wiki = SelectField("Wiki", choices=wiki_choices)
text = TextAreaField("Inhalt")
def fix_link(href, wiki_url):
parts = urllib.parse.urlparse(href)
if not parts.netloc:
parts = list(parts)
parts[1] = urllib.parse.urlparse(wiki_url).netloc
return urllib.parse.urlunparse(parts)
def fix_links(soup, wiki_url):
for tag in soup.find_all(["a", "link"], href=True):
tag["href"] = fix_link(tag["href"], wiki_url)
for tag in soup.find_all(["script", "img"], src=True):
tag["src"] = fix_link(tag["src"], wiki_url)
def insert_content(soup, new_content):
content_element = soup.find("div", class_="mw-parser-output")
first_paragraph = content_element.find("p", class_=None)
first_paragraph.append(new_content)
@app.route("/", methods=["GET", "POST"])
def index():
form = RequestForm()
if form.validate_on_submit():
page_title = form.page.data
wiki = form.wiki.data
session["wiki"] = wiki
print(session["wiki"])
new_content = form.text.data
original_url = wikis[wiki] + page_title
response = requests.get(original_url)
if response.status_code == 404:
form.page.errors.append("Page not found")
return render_template("index.html", form=form)
content = response.text
soup = bs4.BeautifulSoup(content, "html.parser")
fix_links(soup, wikis[wiki])
insert_content(soup, new_content)
return str(soup)
return render_template("index.html", form=form)
@app.route("/<path:path>")
def catch_all(path):
parts = list(urllib.parse.urlparse(request.url))
base_url = wikis.get(session.get("wiki", "Wikipedia English"))
parts[1] = urllib.parse.urlparse(base_url).netloc
return redirect(urllib.parse.urlunparse(parts))
{% extends "layout.html" %}
{% from "macros.html" import render_form %}
{% block title %}Startseite{% endblock %}
{% block content %}
{{render_form(form)}}
{% endblock %}
<!doctype html>
<html>
<head>
{% block head %}
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="description" content="E-Schrank" />
<link rel="stylesheet" href="{{url_for("static", filename="css/bootstrap.min.css")}}">
<link rel="stylesheet" href="{{url_for("static", filename="css/style.css")}}" />
{% block additional_js %}
{% endblock %}
<script src="{{url_for("static", filename="js/script.js")}}" async></script>
<title>{% block title %}Seite{% endblock %} - Wiki-Argument-Helper</title>
{% endblock %}
</head>
<body>
<nav class="navbar navbar-default navbar-fixed-top">
<div class="container">
<div class="navbar-header">
<button class="navbar-toggle collapsed" type="button" data-toggle="collapse" data-target="#navbar" aria-expanded="false" aria-controls="navbar">
<span class="sr-only">Toggle navigation</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a class="navbar-brand" href="{{url_for("index")}}">Wiki-Argument-Helper</a>
</div>
</div>
</nav>
<div class="container">
{% with messages = get_flashed_messages(with_categories=true) %}
{% if messages %}
{% for category, message in messages %}
<div class="alert {{ category }}">
{{ message }}
</div>
{% endfor %}
{% endif %}
{% endwith %}
{% block content %}
Diese Seite ist leer.
{% endblock %}
</div>
<script src="{{url_for("static", filename="js/jquery.min.js")}}"></script>
<script src="{{url_for("static", filename="js/bootstrap.min.js")}}"></script>
</body>
<!-- Taken from https://gist.github.com/bearz/7394681 and modified
to not render a label for the CRSFTokenField -->
{# Renders field for bootstrap 3 standards.
Params:
field - WTForm field
kwargs - pass any arguments you want in order to put them into the html attributes.
There are few exceptions: for - for_, class - class_, class__ - class_
Example usage:
{{ macros.render_field(form.email, placeholder='Input email', type='email') }}
#}
{% macro render_field(field, label_visible=true) -%}
<div class="form-group {% if field.errors %}has-error{% endif %} {{ kwargs.pop('class_', '') }}">
{% if field.type != 'HiddenField' and field.type !='CSRFTokenField' and label_visible %}
<label for="{{ field.id }}" class="control-label">{{ field.label }}</label>
{#<span onclick="el=document.getElementById('{{field.id}}-description');el.style.display=(el.style.display=='none'?'flex':'none')" class="field-description-questionmark">?</span>#}
{% endif %}
{{ field(title=field.description, placeholder=field.label.text, class_='form-control', **kwargs) }}
{% if field.errors %}
{% for e in field.errors %}
<p class="help-block">{{ e }}</p>
{% endfor %}
{% endif %}
</div>
{#<div id="{{field.id}}-description" style="display:none" class="field-description">{{field.description}}</div>#}
{%- endmacro %}
{# Renders checkbox fields since they are represented differently in bootstrap
Params:
field - WTForm field (there are no check, but you should put here only BooleanField.
kwargs - pass any arguments you want in order to put them into the html attributes.
There are few exceptions: for - for_, class - class_, class__ - class_
Example usage:
{{ macros.render_checkbox_field(form.remember_me) }}
#}
{% macro render_checkbox_field(field) -%}
<div class="checkbox {% if field.errors %}has-error{% endif %}">
<label>
{{ field(type='checkbox', **kwargs) }} {{ field.label }}
</label>
<!--<span onclick="el=document.getElementById('{{field.id}}-description');el.style.display=(el.style.display=='none'?'flex':'none')" class="field-description-questionmark">?</span>-->
{% if field.errors %}
{% for e in field.errors %}
<p class="help-block">{{ e }}</p>
{% endfor %}
{% endif %}
</div>
<div id="{{field.id}}-description" style="display:none" class="field-description">{{field.description}}</div>
{%- endmacro %}
{# Renders radio field
Params:
field - WTForm field (there are no check, but you should put here only BooleanField.
kwargs - pass any arguments you want in order to put them into the html attributes.
There are few exceptions: for - for_, class - class_, class__ - class_
Example usage:
{{ macros.render_radio_field(form.answers) }}
#}
{% macro render_radio_field(field) -%}
{% for value, label, _ in field.iter_choices() %}
<div class="radio">
<label>
<input type="radio" name="{{ field.id }}" id="{{ field.id }}" value="{{ value }}">{{ label }}
</label>
</div>
{% endfor %}
{%- endmacro %}
{% macro render_form_inner(field, labels_visible, method) -%}
{% if field.type == 'BooleanField' %}
{{ render_checkbox_field(field) }}
{% elif field.type == 'RadioField' %}
{{ render_radio_field(field) }}
{% elif field.type == 'TextAreaField' %}
{{ render_field(field, label_visible=labels_visible, **kwargs) }}
{% elif field.type == 'FormField' %}
{% for f in field %}
{{render_form_inner(f, labels_visible=labels_visible)}}
{% endfor %}
{% elif field.type == 'CSRFTokenField' %}
{% if method != "GET" %}
{{ render_field(field, label_visible=labels_visible) }}
{% endif %}
{% else %}
{{ render_field(field, label_visible=labels_visible) }}
{% endif %}
{%- endmacro %}
{# Renders WTForm in bootstrap way. There are two ways to call function:
- as macros: it will render all field forms using cycle to iterate over them
- as call: it will insert form fields as you specify:
e.g. {% call macros.render_form(form, action_url=url_for('login_view'), action_text='Login',
class_='login-form') %}
{{ macros.render_field(form.email, placeholder='Input email', type='email') }}
{{ macros.render_field(form.password, placeholder='Input password', type='password') }}
{{ macros.render_checkbox_field(form.remember_me, type='checkbox') }}
{% endcall %}
Params:
form - WTForm class
action_url - url where to submit this form
action_text - text of submit button
class_ - sets a class for form
#}
{% macro render_form(form, action_url='', action_text='Submit', class_='', btn_class='btn btn-default', enctype=None, labels_visible=True, method="POST", textarea_rows=5) -%}
<form method="{{method}}" action="{{ action_url }}" role="form" class="{{ class_ }}"{% if enctype is not none %}enctype="{{enctype}}"{% endif %}>
{#{{ form.hidden_tag() if form.hidden_tag }}#}
{% if caller %}
{{ caller() }}
{% else %}
{% for f in form %}
{{render_form_inner(f, labels_visible=labels_visible, textarea_rows=textarea_rows, method=method, **kwargs)}}
{% endfor %}
{% endif %}
<button type="submit" class="{{btn_class}}">{{action_text}}</button>
</form>
{%- endmacro %}
{% macro render_table(table) -%}
{% set classes = table.classes() %}
<h3>
{{table.title}}
{% if table.newlink is not none %}
<a href="{{table.newlink}}">{{table.newtext}}</a>
{% endif %}
</h3>
<table class="table table-striped table-hover">
<thead>
<tr>
{% for (header, class) in zip(table.headers(), classes) %}
<th{% if class is not none %} class="{{class}}"{% endif %}>{{header}}</th>
{% endfor %}
</tr>
</thead>
<tbody>
{% for row in table.rows() %}
<tr>
{% for (entry, class) in zip(row, classes) %}
<td{% if class is not none %} class="{{class}}"{% endif %}>{{entry}}</td>
{% endfor %}
</tr>
{% endfor %}
</tbody>
</table>
{%- endmacro %}
{% macro render_single_table(table) -%}
<h3>
{{table.title}}
{% if table.newlink is not none %}
<a href="{{table.newlink}}">{{table.newtext}}</a>
{% endif %}
</h3>
<table class="table table-striped">
<tbody>
{% for key, value in zip(table.headers(), table.row()) %}
<tr>
<td>{{key}}</td>
<td>{{value}}</td>
</tr>
{% endfor %}
</tbody>
</table>
{%- endmacro %}
{% macro page_link(text, _page=None, _page_length=None) -%}
{% set args = request.view_args.copy() %}
{% set _ = args.update(request.args) %}
{% if _page is not none %}
{% set _ = args.update({"page": _page}) %}
{% endif %}
{% if _page_length is not none %}
{% set _ = args.update({"page_length": _page_length}) %}
{% endif %}
<a href="{{url_for(request.endpoint, **args)}}">{{text}}</a>
{%- endmacro %}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment