From 60850241c6975af2eb7477dd2d047f5a0f602e07 Mon Sep 17 00:00:00 2001 From: Christian Heller <c.heller@plomlompom.de> Date: Sat, 7 Nov 2020 19:33:05 +0100 Subject: [PATCH 1/1] Initial commit. --- guiltcards.py | 101 ++++++++++++++++++++++++++++++++++++++++++ requirements.txt | 1 + run.sh | 18 ++++++++ views/card.tpl | 22 +++++++++ views/card_form.tpl | 25 +++++++++++ views/cards.tpl | 13 ++++++ views/delete_card.tpl | 9 ++++ views/intro.tpl | 5 +++ 8 files changed, 194 insertions(+) create mode 100755 guiltcards.py create mode 100644 requirements.txt create mode 100755 run.sh create mode 100644 views/card.tpl create mode 100644 views/card_form.tpl create mode 100644 views/cards.tpl create mode 100644 views/delete_card.tpl create mode 100644 views/intro.tpl diff --git a/guiltcards.py b/guiltcards.py new file mode 100755 index 0000000..8bf3cb4 --- /dev/null +++ b/guiltcards.py @@ -0,0 +1,101 @@ +#!/usr/bin/env python3 +from bottle import debug, run, default_app, get, view, request, post, redirect +import os +import json + +web_path = '' +#web_path = '/guiltcards' +cards_dir = 'cards/' + +def get_card_data(card_id): + if not os.path.exists(cards_dir): + os.makedirs(cards_dir) + path_card = cards_dir + card_id + if os.path.exists(path_card): + with open(path_card, 'r') as f: + data = json.loads(f.read())#f.read() + else: + data = {'title': '?', + 'prompt':'?', + 'answers': ['?', '?']} + return data + +@get(web_path + '/') +@view('intro') +def intro(): + return dict() + +@get(web_path + '/cards') +@view('cards') +def list_cards(): + if not os.path.exists(cards_dir): + os.makedirs(cards_dir) + card_ids = os.listdir(cards_dir) + return dict(web_path=web_path, + card_ids=card_ids) + +@get(web_path + '/cards/') +def new_card(): + card_id = request.query.get('card_id') + redirect(web_path + '/cards/' + card_id + '/form') + +@get(web_path + '/cards/<card_id>/view') +@view('card') +def show_card(card_id): + data = get_card_data(card_id) + return dict(web_path=web_path, + title=data['title'], + prompt=data['prompt'], + answers=data['answers']) + +@post(web_path + '/cards/<card_id>') +def update_card(card_id): + if not os.path.exists(cards_dir): + os.makedirs(cards_dir) + path_card = cards_dir + card_id + json_dict = { + 'title': request.forms.get('title'), + 'prompt': request.forms.get('prompt'), + 'answers': request.forms.getall('answer') + } + json_dict['answers'] = [answer for answer in json_dict['answers'] + if answer.strip() != ''] + with open(path_card, 'w') as f: + f.write(json.dumps(json_dict, indent=4)) + redirect(web_path + '/cards/' + card_id + '/view') + +@get(web_path + '/cards/<card_id>/form') +@view('card_form') +def card_form(card_id): + data = get_card_data(card_id) + card_path = cards_dir + '/' + card_id + deletable = False + if os.path.exists(card_path): + deletable = True + return dict(web_path=web_path, + card_id=card_id, + title=data['title'], + prompt=data['prompt'], + answers=data['answers'], + deletable=deletable) + +@get(web_path + '/cards/<card_id>/delete') +@view('delete_card') +def delete_card_ask(card_id): + return dict(web_path=web_path, + card_id=card_id) + +@post(web_path + '/cards/<card_id>/delete') +def delete_card_do(card_id): + card_path = cards_dir + '/' + card_id + if os.path.exists(card_path): + os.remove(card_path) + redirect(web_path + '/cards') + +# App running. + +if __name__ == "__main__": + debug(True) + run(port=8000) +else: + app = application = default_app() diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..310dc0b --- /dev/null +++ b/requirements.txt @@ -0,0 +1 @@ +bottle diff --git a/run.sh b/run.sh new file mode 100755 index 0000000..ba51215 --- /dev/null +++ b/run.sh @@ -0,0 +1,18 @@ +#!/bin/bash + +# This script runs the guilt cards web app +# in a virtual environment with temporarily +# installed required external Python libraries. +set -e + +DIR_ENV=.temp_env + +python3 -m venv $DIR_ENV +source $DIR_ENV/bin/activate +pip install -r requirements.txt +echo +set +e +uwsgi --socket 127.0.0.1:9000 --wsgi-file guiltcards.py +set -e +deactivate +rm -rf $DIR_ENV diff --git a/views/card.tpl b/views/card.tpl new file mode 100644 index 0000000..8e89f50 --- /dev/null +++ b/views/card.tpl @@ -0,0 +1,22 @@ +<!DOCTYPE HTML> +<html> +<style> + #card { + box-sizing: border-box; + border: 30px solid #aaaaaa; + width: 200px; + height: 400px; } +</style> +<body> + <div id="card"> + <h1 id="title">{{ title }}</h1> + <p id="prompt">{{ prompt }}</p> + <ul id="answers"> + % for answer in answers: + <li>{{ answer }}</li> + % end + <ul/> + </div> +<a href="{{ web_path }}/cards">back to overview</a> +</body> +</html> diff --git a/views/card_form.tpl b/views/card_form.tpl new file mode 100644 index 0000000..a2aa551 --- /dev/null +++ b/views/card_form.tpl @@ -0,0 +1,25 @@ +<!DOCTYPE HTML> +<html> +<body> +<form action="{{ web_path }}/cards/{{ card_id }}" method="POST"> +title: <input type="text" name="title" value="{{ title }}" /><br /> +prompt: <input type="text" name="prompt" value="{{ prompt }}" /><br /> +% for answer in answers: +answer: <input type="text" name="answer" value="{{ answer }}" /><br /> +% end +answer: <input type="text" name="answer" /><br /> +answer: <input type="text" name="answer" /><br /> +answer: <input type="text" name="answer" /><br /> +<input type="submit" value="OK" /> +</form> +<p> +(leave specific answer fields empty to remove them as answer options) +</p> +% if deletable: +<p> +Or would you rather <a href="{{ web_path }}/cards/{{ card_id }}/delete">DELETE</a> this card? +</p> +% end +</form> +</body> +</html> diff --git a/views/cards.tpl b/views/cards.tpl new file mode 100644 index 0000000..dbf5ea6 --- /dev/null +++ b/views/cards.tpl @@ -0,0 +1,13 @@ +<!DOCTYPE HTML> +<html> +<body> +<ul> +% for card_id in card_ids: +<li><a href="{{ web_path }}/cards/{{card_id}}/view">{{card_id}}</a> (<a href="{{ web_path }}/cards/{{card_id}}/form">edit</a>)</li> +% end +</ul> +<form action="{{ web_path }}/cards/" method="GET"> +add another? name: <input type="text" name="card_id" /> +</form> +</body> +</html> diff --git a/views/delete_card.tpl b/views/delete_card.tpl new file mode 100644 index 0000000..45b6449 --- /dev/null +++ b/views/delete_card.tpl @@ -0,0 +1,9 @@ +<!DOCTYPE HTML> +<html> +<body> +<form action="{{ web_path }}/cards/{{ card_id }}/delete" method="POST"> +<input type="submit" value="delete {{card_id}}?" /> +</form> +<a href="{{ web_path }}/cards">Nah, better not â¦</a> +</body> +</html> diff --git a/views/intro.tpl b/views/intro.tpl new file mode 100644 index 0000000..e24a7a0 --- /dev/null +++ b/views/intro.tpl @@ -0,0 +1,5 @@ +<html> +<body> +Hey there! +</body> +</html> -- 2.30.2