first go about

This commit is contained in:
root 2020-10-05 17:49:46 +01:00
commit c8d4d9a660
7 changed files with 293 additions and 0 deletions

BIN
app.db Normal file

Binary file not shown.

136
app.py Normal file
View File

@ -0,0 +1,136 @@
from flask import Flask, \
render_template as Render,\
redirect as Redirect, \
url_for as MethodUri, \
abort as Abort
from flask_sqlalchemy import SQLAlchemy as DBM
from enum import Enum
from time import sleep
# Init
app=Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI']="sqlite:///app.db"
DB=DBM(app)
#Enums
class WorkState(Enum):
OTHER = 0
IDEA = 1
CONFIRMED = 2
PAID = 3
INPROGRESS = 4
FINISHED = 5
class TxProcessor(Enum):
OTHER = 0
PAYPAL = 1
class TxType(Enum):
OTHER = 0
NORMAL = 1
YCH = 2
YCHAUCTION = 3
class Currency(Enum):
OTHER = 0
GBP = 1
USD = 2
EUR = 3
CAD = 4
class LinkType(Enum):
OTHER = 0
WIPSKETCH = 1
WIPLINES = 2
WIPCOLOUR = 3
WIPSHADING = 4
WIPOTHER = 5
DELIVERABLE = 6
FINAL = 7
#Database stuff
class Artist(DB.Model):
artist_id = DB.Column(DB.Integer, primary_key=True, nullable=False, unique=True)
name = DB.Column(DB.String, nullable=False)
social_twitter = DB.Column(DB.String)
social_telegram = DB.Column(DB.String)
social_mastodon = DB.Column(DB.String)
social_furaffinity = DB.Column(DB.String)
social_weasyl = DB.Column(DB.String)
social_inkbunny = DB.Column(DB.String)
social_sofurry = DB.Column(DB.String)
social_furrynetwork = DB.Column(DB.String)
class Work(DB.Model):
work_id = DB.Column(DB.Integer, primary_key=True, nullable=False, unique=True)
artist_id = DB.Column(DB.Integer, DB.ForeignKey('artist.artist_id'), nullable=False)
state = DB.Column(DB.Enum(WorkState), nullable=False)
purchase_type = DB.Column(DB.Enum(TxType),nullable=False)
work_desc = DB.Column(DB.String)
date_proposed = DB.Column(DB.DateTime)
date_accepted = DB.Column(DB.DateTime)
date_paid = DB.Column(DB.DateTime)
date_inprogress = DB.Column(DB.DateTime)
date_completed = DB.Column(DB.DateTime)
class WorkLink(DB.Model):
link_id = DB.Column(DB.Integer, primary_key=True, nullable=False, unique=True)
work_id = DB.Column(DB.Integer, DB.ForeignKey('work.work_id'), nullable=False)
linktype = DB.Column(DB.Enum(LinkType), nullable=False)
descr = DB.Column(DB.String, nullable=False)
uri = DB.Column(DB.String, nullable=False)
datetime = DB.Column(DB.DateTime, nullable=False)
class Transaction(DB.Model):
transaction_id = DB.Column(DB.Integer, primary_key=True, nullable=False, unique=True)
artist_id = DB.Column(DB.Integer, DB.ForeignKey('artist.artist_id'), nullable=False)
work_id = DB.Column(DB.Integer, DB.ForeignKey('work.work_id'), nullable=False)
processor = DB.Column(DB.Enum(TxProcessor), nullable=False)
processor_txid = DB.Column(DB.String, unique=True, nullable=False)
currency = DB.Column(DB.Enum(Currency), nullable=False)
amount = DB.Column(DB.Float, nullable=False)
datetime = DB.Column(DB.DateTime, nullable=False)
#Debugging stuff
def RecreateDB():
DB.drop_all()
DB.create_all()
def PopulateTestData():
RecreateDB()
tArtist=Artist(name="test artist 1")
DB.session.add(tArtist)
DB.session.commit()
tWork=Work(artist_id=tArtist.artist_id,
state=WorkState.FINISHED, purchase_type=TxType.NORMAL)
tWorkTwo=Work(artist_id=tArtist.artist_id,
state=WorkState.INPROGRESS, purchase_type=TxType.YCHAUCTION)
DB.session.add_all((tWork, tWorkTwo))
DB.session.commit()
#Routes
@app.route('/')
def index():
_idea=Work.query.filter_by(state=WorkState.IDEA).join(Artist)
_conf=Work.query.filter(
(Work.state==WorkState.CONFIRMED) |
(Work.state==WorkState.PAID)).join(Artist)
_inp=Work.query.filter_by(state=WorkState.INPROGRESS).join(Artist)
_cmp=Work.query.filter_by(state=WorkState.FINISHED).join(Artist)
return Render("index.html.j2", ideas=_idea, cnfpaid=_conf, inprog=_inp, done=_cmp)
@app.route('/list/<listname>')
def list(listname=None):
_p=Work.query.filter_by(state=WorkState.FINISHED)
return Render("list.html.j2", workslist=listname, works=_p.all())
@app.route('/add')
def add(): return Render("add.html.j2")
@app.route('/update', methods=['POST'])
def update(): return Redirect(MethodUri('index'))
@app.route('/work/<id>')
def view_work(id=None): return True
@app.route('/artist/<id>')
def view_artist(id=None):
_a=Artist.query.filter_by(artist_id=id).first()
_w=Work.query.filter_by(artist_id=id).all()
_t=Transaction.query.filter_by(artist_id=id).all()
return Render("artist.html.j2", ainfo=_a, works=_w, txes=_t)

4
plan Normal file
View File

@ -0,0 +1,4 @@
pup.cloud Commissions
components
- web frontend (Flask)
- storage (SQLite, PG, Maria)

3
requirements.txt Normal file
View File

@ -0,0 +1,3 @@
Flask~=1.1.2
Flask-SQLAlchemy~=2.4.4
Jinja2~=2.11.2

87
templates/base.html.j2 Normal file
View File

@ -0,0 +1,87 @@
<!doctype html>
<html lang="en-GB">
<head>
<meta charset="UTF-8" />
<meta name="handheldfriendly" content="true" />
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="description" content="Furry art commission tracker, written in Flask" />
<link rel="stylesheet" type="text/css" href="https://assets.pup.cloud/css/chota.min.css" />
<style>
:root {
--colour-lightpurple: #b58dc5;
--colour-lightblue: #94b9e6;
--colour-green: #6dca81;
--grid-maxWidth: 98%;
}
hr {
height: 0;
background-color: unset;
}
.container {
width: inherit;
padding: 0;
}
div.lanes:nth-child(1 of div.lane) {
margin-left: inherit;
}
div.lanes:nth-child(-1 of div.lane) {
margin-right: inherit;
}
.lane {
border-radius: 4px;
border: 1px solid var(--color-darkGrey);
}
.lane > header {
background-color: var(--color-darkGrey);
color: white;
margin: 0;
margin-bottom: 1rem;
padding: 0.4rem 1rem;
}
.status-confirming {
--card-outline-colour: var(--color-darkGrey);
--card-header-colour: var(--card-outline-colour);
--card-header-text-colour: white;
}
.status-confirmed {
--card-outline-colour: var(--colour-lightpurple);
--card-header-colour: var(--card-outline-colour);
--card-header-text-colour: white;
}
.status-inprogress {
--card-outline-colour: var(--colour-lightblue);
--card-header-colour: var(--card-outline-colour);
--card-header-text-colour: white;
}
.status-completed {
--card-outline-colour: var(--colour-green);
--card-header-colour: var(--card-outline-colour);
--card-header-text-colour: white;
}
.lane > .card {
margin: 1rem;
box-shadow: 0 1px 0 2px var(--card-outline-colour);
padding: 0;
}
.lane > .card > header {
background-color: var(--card-header-colour);
color: var(--card-header-text-colour);
margin: 0;
margin-bottom: 1rem;
padding: 0.4rem 1rem;
}
.lane > .card > section {
padding: 1rem 2rem;
}
</style>
<title>p.c Commissions :: {% block title %}{% endblock %}</title>
{% block head_more %}{% endblock %}
</head>
<body>
{% include "navigation-bar.html.j2" %}
{% block page_body %}{% endblock %}
</body>
</html>

48
templates/index.html.j2 Normal file
View File

@ -0,0 +1,48 @@
{% extends 'base.html.j2' %}
{% block title %}Home{% endblock %}
{% block head_more %}
{% endblock %}
{% block page_body %}
<hr/>
<div class="container">
<div class="row lanes">
<div class="col-3 lane status-confirming">
<header>Ideas</header>
{% for work in ideas %}
<div class="card">
<header>{{ work.work_desc }}</header>
<section>status {{ work.state.name|title }} and artist {{ work.artist.name }}</section>
</div>
{% endfor %}
</div>
<div class="col-3 lane status-confirmed">
<header>Confirmed/Paid</header>
{% for work in cnfpaid %}
<div class="card">
<header>{{ work.work_desc }}</header>
<section>status {{ work.state.name|title }} and artist {{ work.artist.name }}</section>
</div>
{% endfor %}
</div>
<div class="col-3 lane status-inprogress">
<header>In-Progress</header>
{% for work in inprog %}
<div class="card">
<header>{{ work.work_desc }}</header>
<section>status {{ work.state.name|title }} and artist {{ work.artist.name }}</section>
</div>
{% endfor %}
</div>
<div class="col-3 lane status-completed">
<header>Completed</header>
{% for work in done %}
<div class="card">
<header>{{ work.work_desc }}</header>
<section>status {{ work.state.name|title }} and artist {{ work.artist.name }}</section>
</div>
{% endfor %}
</div>
</div>
</div>
{% endblock %}

View File

@ -0,0 +1,15 @@
{% block nav %}
<nav class="nav">
<div class="nav-left">
<a class="brand" href="/">
<img src="https://assets.pup.cloud/img/maffsie_awoo.svg" height=150 alt="" />
p.c Commissions
</a>
<div class="tabs">
<a href="/">Home</a>
<a href="/add"> Add</a>
<a href="/completed">Completed</a>
</div>
</div>
</nav>
{% endblock %}