fixed serve

This commit is contained in:
Felix Breidenstein 2020-10-18 22:45:32 +02:00
parent db555fa3b3
commit 1dc9d35475
10 changed files with 66 additions and 116 deletions

4
cli
View file

@ -5,7 +5,7 @@ import sys
from pathlib import Path from pathlib import Path
import importer import importer
# import serve import serve
import autosort import autosort
import validate import validate
# import info # import info
@ -47,7 +47,7 @@ if __name__ == '__main__':
create_dirs() create_dirs()
# cli.add_command(sort.command) # cli.add_command(sort.command)
cli.add_command(importer.command) cli.add_command(importer.command)
# cli.add_command(serve.command) cli.add_command(serve.command)
cli.add_command(autosort.command) cli.add_command(autosort.command)
cli.add_command(validate.command) cli.add_command(validate.command)
# cli.add_command(info.command) # cli.add_command(info.command)

View file

@ -2,14 +2,16 @@
from sqlalchemy.ext.declarative import declarative_base from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy import Column, Integer, String, DateTime, ForeignKey, Table from sqlalchemy import Column, Integer, String, DateTime, ForeignKey, Table
from sqlalchemy.orm import relationship, backref from sqlalchemy.orm import relationship, backref
from helper import format_amount
from hashlib import md5
Base = declarative_base() Base = declarative_base()
association_table = Table( association_table = Table(
"association", "association",
Base.metadata, Base.metadata,
Column("left_id", Integer, ForeignKey("Transaction.id")), Column("transaction_id", Integer, ForeignKey("Transaction.id")),
Column("right_id", Integer, ForeignKey("Tag.id")), Column("tag_id", Integer, ForeignKey("Tag.id")),
) )
@ -47,3 +49,7 @@ class Tag(Base):
def __repr__(self): def __repr__(self):
return f"<Tag {self.name}>" return f"<Tag {self.name}>"
def color(self):
hash = md5(self.name.encode()).hexdigest()[-6:]
return f"#{hash}"

View file

@ -1,5 +1,5 @@
#! /usr/bin/env python3 #! /usr/bin/env python3
from flask import Flask, render_template, request from flask import Flask, render_template, request, redirect
from helper import get_session, format_amount from helper import get_session, format_amount
from datetime import datetime from datetime import datetime
from sqlalchemy import func from sqlalchemy import func
@ -12,84 +12,58 @@ app = Flask(__name__)
@app.route("/") @app.route("/")
def index(): def index():
fom = datetime.today().replace(day=1) return render_template("index.html")
sum_of_categories = (
session.query(Transaction.category_id, func.sum(Transaction.amount).label("total"))
.filter(Transaction.date > fom)
.group_by(Transaction.category_id)
.all()
)
categories = []
for s in sum_of_categories:
if s.category_id:
categories.append(
{"name": session.query(Category).get(s.category_id).full_name(), "amount": format_amount(s.total)}
)
else:
categories.append({"name": "Unsorted", "amount": format_amount(s.total)})
categories = sorted(categories, key=lambda i: i["name"])
return render_template("index.html", categories=categories)
@app.route("/categories") @app.route("/tags")
def categories(): def tags():
categories = session.query(Category).all() tags = session.query(Tag).all()
categories = [c for c in categories if c.is_child()] return render_template("tags.html", tags=tags)
categories = sorted(categories, key=lambda i: i.full_name())
return render_template("categories.html", categories=categories)
@app.route("/graph") @app.route("/tag/<name>")
def graph(): def tag(name):
data = [] tag = session.query(Tag).filter(Tag.name == name).first()
return render_template("graph.html", data=data) transactions = session.query(Transaction).filter(Transaction.tags.any(id=tag.id)).all()
return render_template("tag.html", tag=tag, transactions=transactions)
@app.route("/category/<name>") @app.route("/tag/<name>/delete")
def category(name): def delete_tag(name):
c = session.query(Category).filter(Category.name == name).first() x = session.query(Tag).filter(Tag.name == name).first()
if c: if x:
transactions = session.query(Transaction).filter(Transaction.category_id == c.id).all() session.delete(x)
else:
transactions = []
return render_template("category.html", category=c, transactions=transactions)
@app.route("/category/<name>/delete")
def delete_category(name):
c = session.query(Category).filter(Category.name == name).first()
if c:
session.delete(c)
session.commit() session.commit()
return redirect("/categories") return redirect("/tags")
@app.route("/transactions") @app.route("/transactions")
def transactions(): def transactions():
transactions = session.query(Transaction)
if request.args.get("unsorted", None): if request.args.get("unsorted", None):
print("Unsorted") transactions = transactions.filter(Transaction.tags == None)
transactions = session.query(Transaction).filter(Transaction.category_id == None).all()
else: transactions = transactions.all()
print("all")
transactions = session.query(Transaction).all() tags = session.query(Tag).all()
categories = session.query(Category).all() return render_template("transactions.html", transactions=transactions, tags=tags)
childs = [c for c in categories if c.is_child()]
return render_template("transactions.html", transactions=transactions, categories=childs)
@app.route("/bulksort") @app.route("/bulksort", methods=["POST"])
def buksort(): def buksort():
cid = request.forms.get("category") tag_id = request.form.get("tag")
transaction_ids = request.forms.getall("transaction") tag = session.query(Tag).get(tag_id)
transaction_ids = request.form.getlist("transaction")
for id in transaction_ids: for id in transaction_ids:
t = session.query(Transaction).get(id) t = session.query(Transaction).get(id)
t.category__id = cid t.tags.append(tag)
session.add(t) session.add(t)
print(f"Sorted {len(transaction_ids)} transactions into category {cid}")
session.commit() session.commit()
return redirect("/transactions") return redirect("/transactions")

0
static/style.css Normal file
View file

View file

@ -8,6 +8,7 @@
<title>Schmeckels</title> <title>Schmeckels</title>
<link href="https://unpkg.com/tailwindcss/dist/tailwind.min.css" rel="stylesheet"> <link href="https://unpkg.com/tailwindcss/dist/tailwind.min.css" rel="stylesheet">
<link href="https://unpkg.com/@tailwindcss/custom-forms/dist/custom-forms.min.css" rel="stylesheet"> <link href="https://unpkg.com/@tailwindcss/custom-forms/dist/custom-forms.min.css" rel="stylesheet">
<link href="/static/style.css" rel="stylesheet">
</head> </head>
<body class="bg-grey-100 font-sans leading-normal tracking-normal"> <body class="bg-grey-100 font-sans leading-normal tracking-normal">
@ -16,17 +17,14 @@
<li class="ml-12 mr-12"> <li class="ml-12 mr-12">
<a class="text-blue-500 hover:text-blue-800" href="/">SCHMECKELS</a> <a class="text-blue-500 hover:text-blue-800" href="/">SCHMECKELS</a>
</li> </li>
<li class="mr-2"> <li class="mx-4">
<a class="text-blue-500 hover:text-blue-800" href="/transactions">Transactions</a> <a class="text-blue-500 hover:text-blue-800" href="/transactions">Transactions</a>
</li> </li>
<li class="mr-2"> <li class="mx-4">
<a class="text-blue-500 hover:text-blue-800" href="/transactions?unsorted=1">Unsorted Transactions</a> <a class="text-blue-500 hover:text-blue-800" href="/transactions?unsorted=1">Unsorted Transactions</a>
</li> </li>
<li class="mr-2"> <li class="mx-4">
<a class="text-blue-500 hover:text-blue-800" href="/categories">Categories</a> <a class="text-blue-500 hover:text-blue-800" href="/tags">Tags</a>
</li>
<li class="mr-2">
<a class="text-blue-500 hover:text-blue-800" href="/graph">Monthly Graph</a>
</li> </li>
</ul> </ul>
</div> </div>

View file

@ -1,7 +0,0 @@
{% extends "base.html" %}
{% block main %}
<h1 class="text-2xl font-bold text-indigo-500">Last 12 months</h1>
{% endblock %}

View file

@ -1,28 +1,7 @@
{% extends "base.html" %} {% extends "base.html" %}
{% block main %} {% block main %}
<h1 class="text-2xl font-bold text-indigo-500">Monatsübersicht</h1> <h1 class="text-2xl font-bold text-indigo-500">Start</h1>
{% if categories|length > 0 %}
<table class="table-auto border-none">
<thead>
<tr>
<th class="px-4 py-2">Categorie</th>
<th class="px-4 py-2 text-right">Summe</th>
</tr>kk
</thead>
<tbody>
{% for c in categories %}
<tr>
<td class="border px-4 py-2">{{ c["name"] }}</td>
<td class="border px-4 py-2 text-right {{ 'text-red-500' if c['amount'][0] == "-" else 'text-green-500' }}">{{ c["amount"] }} €</td>
</tr>
{% endfor %}
</tbody>
{% else %}
No transactions this month
{% endif %}
{% endblock %} {% endblock %}

View file

@ -2,16 +2,15 @@
{% block main %} {% block main %}
<h1>Transaktionen aus {{ category.full_name() }}</h1> <h1>Transaktionen aus {{ tag.name }}</h1>
<table class="table-auto"> <table class="table-auto">
<thead> <thead>
<tr> <tr>
<th class="px-4 py-2">Date</th> <th class="px-4 py-2">Datum</th>
<th class="px-4 py-2">Sender/Empfänger</th> <th class="px-4 py-2">Sender/Empfänger</th>
<th class="px-4 py-2">Verwendungszweck</th> <th class="px-4 py-2">Verwendungszweck</th>
<th class="px-4 py-2">Betrag</th> <th class="px-4 py-2">Betrag</th>
<th class="px-4 py-2"></th>
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
@ -21,8 +20,9 @@
<td class="border px-4 py-2">{{ t.name }}</td> <td class="border px-4 py-2">{{ t.name }}</td>
<td class="border px-4 py-2">{{ t.description }}</td> <td class="border px-4 py-2">{{ t.description }}</td>
<td class="border px-4 py-2 {{ 'text-green-500' if t.is_positive() else 'text-red-500' }}">{{ t.pretty_amount() }}</td> <td class="border px-4 py-2 {{ 'text-green-500' if t.is_positive() else 'text-red-500' }}">{{ t.pretty_amount() }}</td>
<td class="border px-4 py-2"><a href="#">Remove category</a></td>
</tr> </tr>
{% endfor %} {% endfor %}
</tbody> </tbody>
</table> </table>
{% endblock %}

View file

@ -2,16 +2,16 @@
{% block main %} {% block main %}
<h1 class="text-2xl font-bold text-indigo-500">Category overview</h1> <h1 class="text-2xl font-bold text-indigo-500">Tag overview</h1>
<ul> <ul>
{% for c in categories %} {% for tag in tags %}
<li class="p-2"> <li class="p-2">
{{ c.full_name() }} <span style="background-color: {{ tag.color() }};" class="text-white rounded p-1" >{{ tag.name }}</span>
<a class="float-right" href="/category/{{ c.name }}"> <a class="float-right" href="/tag/{{ tag.name }}">
<button class="bg-blue-500 hover:bg-blue-700 text-white font-bold mx-2 y-1 px-2 rounded"> Transactions </button> <button class="bg-blue-500 hover:bg-blue-700 text-white font-bold mx-2 y-1 px-2 rounded"> Transactions </button>
</a> </a>
<a class="float-right" href="/category/{{ c.name }}/delete"> <a class="float-right" href="/tag/{{ tag.name }}/delete">
<button class="bg-red-500 hover:bg-red-700 text-white font-bold y-1 px-2 rounded"> Delete </button> <button class="bg-red-500 hover:bg-red-700 text-white font-bold y-1 px-2 rounded"> Delete </button>
</a> </a>
</li> </li>

View file

@ -3,9 +3,9 @@
{% block main %} {% block main %}
<form action="/bulksort" method="POST"> <form action="/bulksort" method="POST">
<select name="category"> <select name="tag">
{% for c in categories %} {% for tag in tags %}
<option value="{{ c.id }}">{{ c.full_name() }}</option> <option value="{{ tag.id }}">{{ tag.name }}</option>
{% endfor %} {% endfor %}
</select> </select>
<input type="submit"> <input type="submit">
@ -28,11 +28,11 @@
<td class="border px-4 py-2">{{ t.name }}<br/> <span class="text-gray-500">{{t.iban}}</span></td> <td class="border px-4 py-2">{{ t.name }}<br/> <span class="text-gray-500">{{t.iban}}</span></td>
<td class="border px-4 py-2">{{ t.description }}</td> <td class="border px-4 py-2">{{ t.description }}</td>
<td class="border px-4 py-2 text-right {{ 'text-green-500' if t.is_positive() else 'text-red-500' }}">{{ t.pretty_amount() }} €</td> <td class="border px-4 py-2 text-right {{ 'text-green-500' if t.is_positive() else 'text-red-500' }}">{{ t.pretty_amount() }} €</td>
{% if t.category %} <td class="border px-4 py-2">
<td class="border px-4 py-2"> <a href="/category/{{ t.category.name }}"> {{ t.category.full_name()}}</a></td> {% for tag in t.tags %}
{% else %} <span style="background-color: {{ tag.color() }};" class="text-white rounded p-1" >{{ tag.name }}</span>
<td class="border px-4 py-2"> - </td> {% endfor %}
{% endif %} </td>
</tr> </tr>
{% endfor %} {% endfor %}
</tbody> </tbody>