read and create generic strategy

This commit is contained in:
null 2024-03-08 09:37:27 +01:00
parent 0122e9ed54
commit 1c22fb7b34
4 changed files with 150 additions and 48 deletions

View File

@ -1,11 +1,13 @@
from dataclasses import dataclass
from dataclasses import dataclass, fields
from datetime import datetime
from typing import Optional
@dataclass
class Strategy():
id: str
enabled: bool
fulfilled: bool
created: str
createdAt: Optional[str]
@classmethod
def get_table_name(cls):
@ -14,3 +16,30 @@ class Strategy():
@classmethod
def get_route_prefix(cls):
return "/strategies/" + cls.__name__.lower()
@staticmethod
def get_computed_properties():
return ["id", "createdAt"]
@staticmethod
def compute_properties():
return {
"createdAt": datetime.utcnow().isoformat() + "Z"
}
@classmethod
def get_order(cls):
return [field.name for field in fields(cls)]
@classmethod
def format(cls, fields):
for key, value in fields.items():
if key in cls.get_formatters():
fields[key] = cls.get_formatters()[key](value)
return fields
@staticmethod
def get_formatters():
return {
"createdAt": lambda str: datetime.fromisoformat(str).strftime('%Y-%m-%d %H:%M')
}

View File

@ -1,8 +1,12 @@
from db import get_connection, getRethinkDB
from dataclasses import fields
from typing import List, Type
from flask import jsonify, request, redirect, render_template
r = getRethinkDB()
def get_bool_attribute_names(cls: Type) -> List[str]:
return [field.name for field in fields(cls) if field.type == bool]
def create_routes(cls, app):
print("creating routes for " + cls.__name__)
@ -15,11 +19,34 @@ def create_routes(cls, app):
@app.route(cls.get_route_prefix() + "/", methods=['GET'])
def get():
cursor = r.table(table_name).run(get_connection())
items = list(cursor)
fields = list(cursor)
return render_template(cls.get_route_prefix() + "/index.html", data={
"title": cls.__name__,
"headers": [field.name for field in fields(cls)],
"items": items,
"prefix": cls.get_route_prefix()
"fields": [cls.format(field) for field in fields],
"prefix": cls.get_route_prefix(),
"order": cls.get_order()
})
@app.route(cls.get_route_prefix() + "/create", methods=['GET'])
def get_create():
return render_template(cls.get_route_prefix() + "/create.html", data={
"name": cls.__name__,
"prefix": cls.get_route_prefix(),
"computed": cls.get_computed_properties(),
"fields": {field.name: field.type.__name__ for field in fields(cls)}
})
@app.route(cls.get_route_prefix() + "/create", methods=['POST'])
def post_create():
if request.headers['Content-Type'] == 'application/x-www-form-urlencoded':
data = request.form.to_dict()
data.update(cls.compute_properties())
for key in get_bool_attribute_names(cls):
data[key] = key in request.form
r.table(table_name).insert(data).run(get_connection())
return 201

View File

@ -0,0 +1,40 @@
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" type="text/css" href="{{ url_for('static', filename='css/styles.css') }}">
<style>
body {
background-color: white;
overflow: hidden;
}
</style>
</head>
<body>
<h2>Create a {{ data.name }}</h2>
<form method="POST" action="{{ data.prefix }}/create?submitted">
<fieldset>
{% for key, value in data.fields.items() %}
{% if key is not in data.computed %}
<label for="{{ key }}">{{ key }}</label>
{% if value == "str" %}
<input type="text" name="{{ key }}">
{% elif value == "float" %}
<input type="number" step="any" name="{{ key }}">
{% elif value == "bool" %}
<input type="checkbox" name="{{ key }}">
{% endif %}
{% endif %}
{% endfor %}
</fieldset>
<fieldset>
<button value="cancel" formmethod="dialog" onclick="window.top.postMessage('close', '*')">Cancel</button>
<button type="submit">Submit</button>
</fieldset>
</form>
</body>
</html>

View File

@ -1,4 +1,3 @@
<!DOCTYPE html>
<html lang="en">
@ -8,20 +7,25 @@
<title>Trading Zone Website</title>
<link rel="icon" href="{{ url_for('static', filename='favicon.ico') }}">
<link rel="stylesheet" type="text/css" href="{{ url_for('static', filename='css/styles.css') }}">
<script type="text/javascript" src="{{ url_for('static', filename='js/main.js') }}" ></script>
<script type="text/javascript" src="{{ url_for('static', filename='js/main.js') }}"></script>
</head>
<body>
<div class="container">
<table id="conditionTable">
<dialog>
<iframe frameborder="0"></iframe>
</dialog>
<table>
<thead>
<tr>
<td colspan="{{ data.headers | length }}"><h2>{{ data.title }}</h2></td>
<td colspan="{{ data.order | length }}">
<h2>{{ data.title }}</h2>
</td>
</tr>
{% if data.items %}
{% if data.fields %}
<tr>
{% for header in data.headers %}
<th>{{ header }}</th>
{% for key in data.order %}
<th>{{ key }}</th>
{% endfor %}
</tr>
{% else %}
@ -31,15 +35,17 @@
{% endif %}
</thead>
<tbody>
{% for item in data["items"] %}
<tr onclick="onOpenDialog('{{ data.prefix }}/{{ item.id }}')">
<td>{{ item }}</td>
{% for field in data.fields %}
<tr onclick="onOpenDialog('{{ data.prefix }}/{{ field.id }}')">
{% for key in data.order%}
<td>{{ field[key] }}</td>
{% endfor %}
</tr>
{% endfor %}
</tbody>
<tfoot>
<tr>
<td colspan="{{ data.headers | length }}" style="text-align: right;"> <!-- Adjust colspan as per your total columns -->
<td colspan="{{ data.order | length }}" style="text-align: right;">
<button onclick="onOpenDialog('{{ data.prefix }}/create')">Add Item</button>
</td>
</tr>