design, sorting and cleanup

master
km0 2 years ago
parent b53b4f03aa
commit b7e60025a0

@ -41,16 +41,15 @@ export default {
<div class='app-form'> <div class='app-form'>
<h2>Add a new pad</h2> <h2>Add a new pad</h2>
<input type="text" v-model="link" placeholder="URL" /> <input class='title' type="text" v-model="title" placeholder="Title" />
<input type="text" v-model="title" placeholder="Title" /> <input class='link' type="text" v-model="link" placeholder="URL" />
<input type="text" v-model="overview" placeholder="Description" /> <input class='overview' type="text" v-model="overview" placeholder="Overview" />
<input type="text" v-model="categories[index]" placeholder="Category" v-for="(category, index) in categories" :key="index"/> <input class='categories' type="text" v-model="categories[index]" placeholder="Category" v-for="(category, index) in categories" :key="index"/>
<button class="add" @click="categories.push('')">+</button> <button class="add" @click="categories.push('')">+</button>
<label for="date">date</label> <input class='date' type="date" v-model="date" placeholder="Date" />
<input type="date" v-model="date" />
<button @click="submit">Insert</button> <button @click="submit" class="submit">Insert</button>
</div> </div>

@ -2,21 +2,36 @@ export default {
setup() { setup() {
const { ref, computed } = Vue; const { ref, computed } = Vue;
const currentPage = ref("");
const pads = ref([]); const pads = ref([]);
const loaded = ref(false);
const currentSort = ref("date"); const currentSort = ref("date");
const currentSortDir = ref("asc"); const currentSortDir = ref("desc");
const sortedPads = computed(() => { const sortedPads = computed(() => {
return pads.value.sort((a, b) => { return pads.value.sort((a, b) => {
let modifier = 1; let modifier = 1;
if (currentSortDir.value === "desc") modifier = -1; if (currentSortDir.value === "desc") modifier = -1;
if (currentSort.value === "date") {
a[currentSort.value] = new Date(a[currentSort.value]);
b[currentSort.value] = new Date(b[currentSort.value]);
}
if (a[currentSort.value] < b[currentSort.value]) return -1 * modifier; if (a[currentSort.value] < b[currentSort.value]) return -1 * modifier;
if (a[currentSort.value] > b[currentSort.value]) return 1 * modifier; if (a[currentSort.value] > b[currentSort.value]) return 1 * modifier;
return 0; return 0;
}); });
}); });
const formatDate = function (date) {
return `${String(date.getDate()).padStart(2, "0")}-${String(
date.getMonth() + 1
).padStart(2, "0")}-${date.getFullYear()}`;
};
const sort = function (s) { const sort = function (s) {
if (s == currentSort.value) { if (s == currentSort.value) {
currentSortDir.value = currentSortDir.value === "asc" ? "desc" : "asc"; currentSortDir.value = currentSortDir.value === "asc" ? "desc" : "asc";
@ -26,28 +41,59 @@ export default {
const columns = ["title", "overview", "categories", "date"]; const columns = ["title", "overview", "categories", "date"];
fetch("https://hub.xpub.nl/soupboat/padliography/") // fetch("https://hub.xpub.nl/soupboat/padliography/")
fetch("http://127.0.0.1:3147/")
.then((res) => res.json()) .then((res) => res.json())
.then((data) => (pads.value = data)); .then((data) => {
pads.value = data.pads;
currentPage.value = data.page;
loaded.value = true;
});
return { pads, columns, sortedPads, sort }; return {
pads,
columns,
sortedPads,
currentPage,
currentSort,
currentSortDir,
loaded,
sort,
formatDate,
};
}, },
template: ` template: `
<table>
<tr class="header"> <div v-if="!loaded" class='loading grow'>
<th v-for="column in columns" @click='sort(column)'>{{column }}</th> Loading loading loading loading loading loading loading loading loading loading loading loading loading loading loading loading loading loading etc
</tr> </div>
<tr v-for="(pad, index) in sortedPads" key="pad.title, index" :class="pad.category">
<div v-else>
<td class="title"> <p class="from">Fetching pads from <a :href="'https://pzwiki.wdka.nl/mediadesign/' + currentPage">
<a :href="pad.link" target="_blank"> {{pad.title}} </a> {{currentPage}}
</td> </a>
<td class="overview">{{pad.overview}}</td> </p>
<td class="categories">{{pad.category}}</td>
<td class="date">{{pad.date}}</td>
<table>
</tr> <tr class="header">
</table> <th v-for="column in columns" @click='sort(column)'>
`, {{column }}
<span v-if='column == currentSort'> {{ currentSortDir == 'asc' ? '▼' : '▲'}}</span>
</th>
</tr>
<tr v-for="(pad, index) in sortedPads" key="pad.title, index" :class="pad.category">
<td class="title">
<a :href="pad.link" class='stretched' target="_blank"> {{pad.title}} </a>
</td>
<td class="overview">{{pad.overview}}</td>
<td class="categories">{{pad.categories}}</td>
<td class="date">{{formatDate(pad.date)}}</td>
</tr>
</table>
</div>
`,
}; };

@ -4,11 +4,13 @@
<meta charset="UTF-8" /> <meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" /> <meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" />
<link rel="stylesheet" href="style.css" />
<script src="https://unpkg.com/vue@3"></script> <script src="https://unpkg.com/vue@3"></script>
<title>Padliography Bis</title> <title>Padliography Bis</title>
</head> </head>
<body> <body>
<div id="app"> <div id="app">
<h1 class="title">Padliography <span class="version">2.0</span></h1>
<pad-form></pad-form> <pad-form></pad-form>
<pad-table></pad-table> <pad-table></pad-table>
</div> </div>

@ -0,0 +1,141 @@
* {
box-sizing: border-box;
}
html,
body {
font-family: Arial, Helvetica, sans-serif;
line-height: 1.6;
color: dodgerblue;
}
a {
color: currentColor;
}
.version {
font-size: 18px;
font-weight: normal;
}
input {
color: currentColor;
border: 1px solid currentColor;
outline: none;
padding: 0.4em;
margin: 0;
}
input.overview {
width: 60ch;
}
button {
display: inline-block;
background: none;
border: 1px solid currentColor;
border-radius: 50%;
color: currentColor;
line-height: 1rem;
text-align: center;
padding: 0.4em;
cursor: pointer;
}
button.add {
display: inline-block;
width: 2em;
height: 2em;
font-size: 1em;
}
button.submit {
margin-left: 12px;
padding: 0.6em;
font-size: 1em;
}
button:hover {
background-color: dodgerblue;
color: white;
}
*:not(h2) + input {
margin-left: 12px;
}
.app-form {
display: inline-block;
padding-left: 12px;
border-left: 1px solid currentColor;
margin-top: 32px;
margin-bottom: 48px;
}
.app-form h2 {
margin: 0;
font-weight: normal;
}
table {
width: 100%;
}
table a {
text-decoration: none;
}
th {
text-align: left;
padding: 24px 0;
border-bottom: 1px solid currentColor;
text-transform: capitalize;
font-size: 28px;
user-select: none;
cursor: pointer;
}
td {
padding: 12px 0;
border-bottom: 1px solid currentColor;
}
td.title {
font-weight: bold;
}
tr {
position: relative;
transition: transform 0.1s ease-in;
}
tr:hover:not(:first-of-type) {
transition: transform 0.2s ease-out;
transform: translateX(10px);
}
.stretched:after {
content: "";
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
}
.loading {
font-size: 28px;
}
.grow {
animation: grow 5s;
}
@keyframes grow {
from {
transform: scale(100%);
}
to {
transform: scale(0, 1000%);
}
}

@ -0,0 +1,238 @@
{
"cells": [
{
"cell_type": "code",
"execution_count": 25,
"metadata": {},
"outputs": [],
"source": [
"from dateutil.parser import parse\n",
"from datetime import datetime\n",
"import mwclient \n",
"from bs4 import BeautifulSoup\n",
"\n",
"import os\n",
"from dotenv import load_dotenv\n",
"from pathlib import Path\n",
"\n"
]
},
{
"cell_type": "code",
"execution_count": 26,
"metadata": {},
"outputs": [],
"source": [
"\n",
"load_dotenv()\n",
"\n",
"# Page of the wiki with the pads\n",
"padliography = 'Padliography2'\n"
]
},
{
"cell_type": "code",
"execution_count": 32,
"metadata": {},
"outputs": [],
"source": [
"\n",
"def add_pad(link, title, overview, categories, date):\n",
"\n",
" parsed_date = parse(date)\n",
" date = datetime.strftime(parsed_date, '%Y-%m-%d')\n",
"\n",
" return f'| {link} || {title} || {overview} || {categories} || {date} \\n|-\\n'"
]
},
{
"cell_type": "code",
"execution_count": 28,
"metadata": {},
"outputs": [],
"source": [
"\n",
"def get_pads():\n",
" \n",
" site = mwclient.Site('pzwiki.wdka.nl', path='/mw-mediadesign/')\n",
" site.login(\n",
" username=os.environ.get('MW_BOT'),\n",
" password=os.environ.get('MW_KEY'),\n",
"\n",
" )\n",
"\n",
" html = site.api('parse', prop='text', page=padliography)\n",
" table = BeautifulSoup(html['parse']['text']['*'], features=\"html.parser\").find(\"table\", attrs={\"class\":\"padliography\"})\n",
"\n",
" headers = [header.text.lower().strip() for header in table.find_all('th')]\n",
" pads = [\n",
" {headers[i]: cell.text.rstrip('\\n') for i, cell in enumerate(row.find_all('td'))} \n",
" for row in table.find_all('tr')]\n",
" pads = [ pad for pad in pads if pad != {}]\n",
" return pads"
]
},
{
"cell_type": "code",
"execution_count": 33,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"{| class = \"wikitable sortable padliography\"\n",
"|-\n",
"!link !! title !! overview !! categories !! date\n",
"|-\n",
"| https://pad.xpub.nl/p/o2jT2mUjNgH0Vk1uPZLR || Week_1 with Steve || Introduction to Reading, Writing and Research Methodologies + first reading, writing workshop || RWRM, Week_1 || 2021-09-22 \n",
"|-\n",
"| https://pad.xpub.nl/p/SP16_2107 || Introduction to prototyping || Knowledge and information organisation are deeply intimate acts || Prototyping, Week_1 || 2021-09-21 \n",
"|-\n",
"| https://pad.xpub.nl/p/SP16_2809 || Orientation/Navigation || Object relations are not just a story of how we use objects but rather how, through relating, we begin to inaugurate and structure our very capacity to position ourselves in reality and phantasy, and so, to the very work of thinking. || SP16, Week_2 || 2021-09-28 \n",
"|-\n",
"| https://pad.xpub.nl/p/si16-protoyping-week-2 || Prototyping || Soupboat is born || SP16, Week_2 || 2021-09-27 \n",
"|-\n",
"| https://pad.xpub.nl/p/SP16_0510 || Language patterns experiments || Cats cradle is about patterns and knots || SP16, Week_3 || 2021-10-05 \n",
"|-\n",
"| https://pad.xpub.nl/p/SP_16_0610 || Reader 'prototypes' || since we are exposed to several topics relates to orientation / disorientation / editing / so we could help(?) the readers to navigate different texts || SP16, RWRM, Week_3 || 2021-10-06 \n",
"|-\n",
"| https://pad.xpub.nl/p/SP16_1210 || Transcription processes || interpretive decisions (What is transcribed?) epresentational decisions (How is it transcribed?) || SP16, Week_4 || 2021-10-12 \n",
"|-\n",
"| https://pad.xpub.nl/p/SP16_0510_texts || Magic Words Glossary || Little spells that can be used anywhere on the pad to indicate how we want to interact with the text || SP16, Week_3 || 2021-10-05 \n",
"|-\n",
"| https://pad.xpub.nl/p/2021-10-11-protoyping || Prototyping XP8 + NLTK2 || Custom text corpus in NLTK || Prototyping, Week_4, NLTK || 2021-10-11 \n",
"|-\n",
"| https://pad.xpub.nl/p/si16-protoyping-week-3 || Prototyping XP7 + NLTK1 || Introduction to NLTK + Explorative programming ch 7 || Prototyping, Week_3, NLTK || 2021-10-04 \n",
"|-\n",
"| https://pad.xpub.nl/p/GroupMeeting_18102021 || Meeting SP16: Rejection? 🧠⚡ || First group meeting for the SP16 || SP16, Meeting, Rejection || 2021-10-18 \n",
"|-\n",
"| https://pad.xpub.nl/p/Rejection_Glossary || Rejection Glossary || Approaching rejection from a lot of points of view || SP16, Rejection || 2021-10-18 \n",
"|-\n",
"| https://pad.xpub.nl/p/GroupMeeting_27102021 || Group Meeting Structure || How do we want to work together? How can we structure future meetings? || SP16, Meeting, Rejection || 2021-10-27 \n",
"|-\n",
"| https://pad.xpub.nl/p/si16-protoyping-week-7 || Prototyping || Collecting texts and creating our own corpora || Week_7, Prototyping, NLTK || 2021-11-01 \n",
"|-\n",
"| https://pad.xpub.nl/p/week7_withClara || SP16 with Clara Balaguer || || Week_7, SP16 || 2021-11-02 \n",
"|-\n",
"| https://pad.xpub.nl/p/TBD_VLTK || TBD VLTK, by Clara Balaguer || A high-low mix tape on the vernacular || Week_7, SP16 || 2021-11-02 \n",
"|-\n",
"| https://pad.xpub.nl/p/Meeting_SP16_Nov_04 || Group Meeting || Remarks on the Rejection Glossary, Vernacular, SI16 Brainstorming, Organising our work || Week_7, SP16, Meeting, Rejection || 2021-11-04 \n",
"|-\n",
"| https://pad.xpub.nl/p/Meeting_Template || TEMPLATE for Group Meetings || Please copy from this template and paste to the actual meeting pad! || SP16, Meeting, Templates || 2021-11-04 \n",
"|-\n",
"| https://pad.xpub.nl/p/si16-protoyping-week-8 || Prototyping XP15, Publishing Pipeline || XP15 check in + Etherpad API with Python || Week_8, Prototyping || 2021-11-08 \n",
"|-\n",
"| https://pad.xpub.nl/p/SP16_0911 || SP16 with Cristina (Danny is sick) || RUMINATION, DIGESTION, REFLECTION a.k.a. \"The long day with Cristina\" || SP16, Week_8 || 2021-11-09 \n",
"|-\n",
"| https://pad.xpub.nl/p/si16-protoyping-week-9 || Prototyping || Sharing out prototypes, Creating a webpage w/ Python + html & css, What is \"documentation\" || Prototyping, Week_9 || 2021-11-15 \n",
"|-\n",
"| https://pad.xpub.nl/p/Meeting_16112021 || Group meeting || morning: SP16 structure proposals; afternoon: editorial w/ Cristina || Week_9, SP16 || 2021-11-16 \n",
"|-\n",
"| https://pad.xpub.nl/p/si16-protoyping-week-10 || Prototyping || Exploring ways to create the API [examples] || Week_10, Prototyping || 2021-11-22 \n",
"|-\n",
"| https://pad.xpub.nl/p/si16-26112021 || Guest Danny Tirthdas van der Kleij || Vernacular in the Software || Week_10, SP16 || 2021-11-26 \n",
"|-\n",
"| https://pad.xpub.nl/p/si16-protoyping-week-11 || Prototyping || Check-in + Tutorial + ... || Week_11, SP16, Prototyping || 2021-11-29 \n",
"|-\n",
"| https://pad.xpub.nl/p/si16-protoyping-week-12 || Prototyping || ... || Week_12, SP16, Prototyping || 2021-12-06 \n",
"|-\n",
"| https://pad.xpub.nl/p/si16-week-12 || SP16 with Cristina || Radical efficiency day || Week_12, SP16 || 2021-12-07 \n",
"|-\n",
"| https://pad.xpub.nl/p/18012022 || SP17 with Lidia & Co. || Ideology, gamification || Week_02, SP17 || 2022-01-18 \n",
"|-\n",
"| https://pad.xpub.nl/p/19012022 || RW&RM with Steve || Marx and Engels; Gramsci; Hebdidge; Chad McCail || Week_02, SP17, RWRM || 2022-01-19 \n",
"|-\n",
"| https://pad.xpub.nl/p/19012022 || SP17 with Lidia & Co. || Games as reproductive technologies, Predatory monetization || Week_03, SP17 || 2022-01-25 \n",
"|-\n",
"| https://pad.xpub.nl/p/si16_debrief || SP16 Debrief || Reflections, debrief with XPUB1, Aymeric, Michael, Cristina, Manetta and Steve || Debrief, SP16, Week_03 || 2022-01-26 \n",
"|-\n",
"| https://pad.xpub.nl/p/01022022 || SP17 with Lidia & Co. || Digesting, reflecting, more reads + Tutorials || SP17, Week_04 || 2022-02-01 \n",
"|-\n",
"| https://pad.xpub.nl/p/02022022 || RW&RM with Steve || NO NEW STUFF & Creating our Productive Play Glossary || SP17, RWRM, Week_04 || 2022-02-02 \n",
"|-\n",
"| https://pad.xpub.nl/p/SI17-prototyping-07022022 || Prototyping || Building little games, playful things, make mazes with python || Prototyping, Week_05 || 2022-02-07 \n",
"|-\n",
"| https://pad.xpub.nl/p/08022022 || SP17 with Lidia & Co. || What is modding and how it is connected to culture and labour || SP17, Week_05 || 2022-02-07 \n",
"|-\n",
"| https://pad.xpub.nl/p/role-playing-structure || Experimental Kitchen || Kim and Chae designed an experimental role-play session for the whole group || SP17, Week_05 || 2022-02-08 \n",
"|-\n",
"| https://pad.xpub.nl/p/paolopedercini || Paolo Pedercini session || tba || SP17, Week_05, Talks || 2022-02-09 \n",
"|-\n",
"| https://pad.xpub.nl/p/SI17-prototyping-14022022 || Prototyping || Play time for puzzles, mini-games collaboration tools || Prototyping, Week_06 || 2022-02-14 \n",
"|-\n",
"| https://pad.xpub.nl/p/16022022-ste%3C3 || RW&RM with Steve || Loot box ideas and prototypes || RWRM, Week_06 || 2022-02-16 \n",
"|-\n",
"| https://hub.xpub.nl/soupboat/pad/p/group_meeting_18022022 || Group meeting || set pre-launch date and group awareness, the loot box, our public and intentions towards our public || SP17, Meeting || 2022-02-18 \n",
"|-\n",
"| https://hub.xpub.nl/soupboat/pad/p/group_meeting_21022022 || Group meeting || Loot box proposals, PNF & confirm format - the Box || SP17, Meeting, Week_06 || 2022-02-21 \n",
"|-\n",
"| https://pad.xpub.nl/p/talks-chess-23022022 || dr. Shira Chess session || Public lecture & private Q&A with \"Play Like A Feminist\" author || SP17, Talks || 2022-02-23 \n",
"|-\n",
"| https://hub.xpub.nl/soupboat/pad/p/group_meeting_28022022 || Group meeting || Prototypes presentations, getting stuck and dividing into small groups to move on || SP17, Meeting || 2022-02-28 \n",
"|-\n",
"| https://pad.xpub.nl/p/SI17-prototyping-07-03-2022 || Prototyping || Bots, IRC [hello, again, mIRC-a :D] & chat bots with python || Prototyping, Week_09 || 2022-03-07 \n",
"|-\n",
"| https://pad.xpub.nl/p/08032022 || SP17 with Lidia & Co. || Progress updates from Teams #1, #2 and #3 || SP17, Week_09 || 2022-03-08 \n",
"|-\n",
"| https://pad.xpub.nl/p/xpub1-si17-editorial-groups-outlines || Editorial meeting || Team representatives meeting with the editors to align the overall concept || SP17, Week_09, Meeting || 2022-03-09 \n",
"|-\n",
"| https://pad.xpub.nl/p/SI17-prototyping-14-03-2022 || Prototyping || Catching up, git tutorial, deadlines for the week || Prototyping, Week_10 || 2022-03-14 \n",
"|-\n",
"| https://pad.xpub.nl/p/15032022 || SP17 with Lidia & Steve || Updates from editors and teams 1,2 3; to-dos for the week || SP17, Week_10 || 2022-03-14 \n",
"|-\n",
"| https://pad.xpub.nl/p/SI17-prototyping-21-03-2022 || Prototyping || Assessments, documentation & updates from teams 1 & 3; Hello, Spring! || SP17, Week_10 || 2022-03-21 \n",
"|-\n",
"| https://pad.xpub.nl/p/SIX-diffractive-cookbook || Diffractive Cookbook || Plan for the release of SI18.6 || SI18, Week_6 || 2022-06-02 \n",
"|-\n",
"|-\n",
"|}\n"
]
}
],
"source": [
"pads = get_pads()\n",
"\n",
"table = '{| class = \"wikitable sortable padliography\"\\n|-\\n!link !! title !! overview !! categories !! date\\n|-\\n'\n",
"for pad in pads:\n",
" table += add_pad(pad['link'], pad['title'], pad['overview'], pad['categories'], pad['date'])\n",
"table += '|-\\n|}'\n",
"print(table)\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": []
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3.10.2 ('venv': venv)",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.10.2"
},
"orig_nbformat": 4,
"vscode": {
"interpreter": {
"hash": "cc811c39cebdedb5a11cacaf3b223f5b956494f89d9226d14870082e2ebdafc1"
}
}
},
"nbformat": 4,
"nbformat_minor": 2
}

@ -1,14 +1,6 @@
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 # Flask application to serve the web pages
from flask import Flask, request, redirect, url_for, jsonify from flask import Flask, request, redirect, url_for, jsonify
from flask_cors import CORS, cross_origin from flask_cors import CORS
# from flask_mako import MakoTemplates, render_template
# Mediawiki client to interact with the Wiki # Mediawiki client to interact with the Wiki
import mwclient import mwclient
@ -22,13 +14,16 @@ import os
from dotenv import load_dotenv from dotenv import load_dotenv
from pathlib import Path from pathlib import Path
# datetime to work with dates
from datetime import datetime
import dateutil.parser
# load the mediawiki credentials from the shared folder # load the mediawiki credentials from the shared folder
dotenv_path = Path("/var/www/.mw-credentials") dotenv_path = Path("/var/www/.mw-credentials")
load_dotenv(dotenv_path=dotenv_path) load_dotenv(dotenv_path=dotenv_path)
# prefix to add /soupboat/padliography to all the routes # prefix to add /soupboat/padliography to all the routes
# and to leave the @app.route() decorator more clean # and to leave the @app.route() decorator more clean
@ -40,7 +35,7 @@ class PrefixMiddleware(object):
def __call__(self, environ, start_response): def __call__(self, environ, start_response):
if environ["PATH_INFO"].startswith(self.prefix): if environ["PATH_INFO"].startswith(self.prefix):
environ["PATH_INFO"] = environ["PATH_INFO"][len(self.prefix) :] environ["PATH_INFO"] = environ["PATH_INFO"][len(self.prefix):]
environ["SCRIPT_NAME"] = self.prefix environ["SCRIPT_NAME"] = self.prefix
return self.app(environ, start_response) return self.app(environ, start_response)
else: else:
@ -68,13 +63,15 @@ def add_pad(link, title, overview, categories, date):
site = mwclient.Site('pzwiki.wdka.nl', path='/mw-mediadesign/') site = mwclient.Site('pzwiki.wdka.nl', path='/mw-mediadesign/')
site.login( site.login(
username=os.environ.get('MW_BOT'), username=os.environ.get('MW_BOT'),
password=os.environ.get('MW_KEY') password=os.environ.get('MW_KEY')
) )
page = site.pages[padliography] page = site.pages[padliography]
text = page.text() text = page.text()
# parsed_date = dateutil.parser.parse(date)
# date = datetime.strftime(parsed_date, 'yyyy-mm-yyyy')
new_row = f'|-\n| {link} || {title} || {overview} || {categories} || {date} \n|-\n' + '|}' new_row = f'|-\n| {link} || {title} || {overview} || {categories} || {date} \n|-\n' + '|}'
@ -87,71 +84,45 @@ def get_pads():
site = mwclient.Site('pzwiki.wdka.nl', path='/mw-mediadesign/') site = mwclient.Site('pzwiki.wdka.nl', path='/mw-mediadesign/')
site.login( site.login(
username=os.environ.get('MW_BOT'), username=os.environ.get('MW_BOT'),
password=os.environ.get('MW_KEY'), password=os.environ.get('MW_KEY'),
) )
html = site.api('parse', prop='text', page=padliography) html = site.api('parse', prop='text', page=padliography)
table = BeautifulSoup(html['parse']['text']['*'], features="html.parser").find("table", attrs={"class":"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')] headers = [header.text.lower().strip() for header in table.find_all('th')]
pads = [ pads = [
{headers[i]: cell.text.rstrip('\n') for i, cell in enumerate(row.find_all('td'))} {headers[i]: cell.text.rstrip('\n')
for i, cell in enumerate(row.find_all('td'))}
for row in table.find_all('tr')] for row in table.find_all('tr')]
pads = [ pad for pad in pads if pad != {}] pads = [pad for pad in pads if pad != {}]
return pads return pads
@app.route('/', methods=['GET', 'POST']) @app.route('/', methods=['GET', 'POST'])
def home(): def home():
if request.method == 'POST': if request.method == 'POST':
link = request.json.get('link', None) link = request.json.get('link', None)
title = request.json.get('title', None) title = request.json.get('title', None)
overview = request.json.get('overview', '') overview = request.json.get('overview', '')
categories = request.json.get('categories', '') categories = request.json.get('categories', '')
date = request.json.get('date', None) date = request.json.get('date', None)
date = datetime.strftime(datetime.strptime(date, 'yyyy-mm-dd'), 'dd-mm-yyyy') date = datetime.strftime(datetime.strptime(
date, 'yyyy-mm-dd'), 'dd-mm-yyyy')
add_pad(link, title, overview, categories, date) add_pad(link, title, overview, categories, date)
redirect(url_for('home')) redirect(url_for('home'))
response = {
'page': padliography,
'pads': get_pads()
}
return jsonify(response)
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) app.run(port=3147, debug=True)

@ -1,26 +0,0 @@
beautifulsoup4==4.11.1
certifi==2022.5.18.1
charset-normalizer==2.0.12
click==8.1.3
colorama==0.4.4
Flask==2.1.2
Flask-Cors==3.0.10
Flask-Mako==0.4
idna==3.3
importlib-metadata==4.11.4
itsdangerous==2.1.2
Jinja2==3.1.2
MarkupSafe==2.1.1
mwclient==0.10.1
numpy==1.22.4
oauthlib==3.2.0
python-dateutil==2.8.2
python-dotenv==0.20.0
pytz==2022.1
requests==2.27.1
requests-oauthlib==1.3.1
six==1.16.0
soupsieve==2.3.2.post1
urllib3==1.26.9
Werkzeug==2.0.3
zipp==3.8.0

@ -1,69 +0,0 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<link rel="stylesheet" href="${url_for('static', filename='css/style.css')}" />
<title>Padliography II</title>
</head>
<body>
<form action="add">
<h2>Add a new pad</h2>
<label for="link">link</label>
<input type="text" name="link" />
<label for="title">title</label>
<input type="text" name="title" />
<label for="overview">overview</label>
<input type="text" name="overview" />
<label for="categories">categories</label>
<input type="text" name="categories" />
<label for="date">date</label>
<input type="date" name="date" />
<input type="submit" value="Add" />
</form>
% if categories:
<div class="filters">
<h3>Filters</h3>
<ul class="filters-container">
<button id="active-all" class="tag active">Show All</button>
% for category in categories:
<li
class="tag active all"
data-tag="${category}"
aria-expanded="true"
role="button"
tabindex="0"
>
${category}
</li>
% endfor
</ul>
</div>
% endif %if pads:
<table>
<tr class="header">
<th>Date</th>
<th>Title</th>
<th>Categories</th>
<th>Overview</th>
</tr>
% for pad in pads:
<tr class="${ pad['category']}">
<td class="date">${pad['date']}</td>
<td class="title">
<a href="${pad['link']}" target="_blank"> ${pad['title']} </a>
</td>
<td class="categories">${pad['category']}</td>
<td class="overview">${pad['overview']}</td>
</tr>
% endfor
</table>
% endif
</body>
</html>
Loading…
Cancel
Save