mirror of
https://github.com/almet/copanier.git
synced 2025-04-28 11:32:38 +02:00
190 lines
4.5 KiB
Python
190 lines
4.5 KiB
Python
import os
|
|
from time import perf_counter
|
|
|
|
import ujson as json
|
|
import hupper
|
|
import minicli
|
|
from bson import ObjectId
|
|
from jinja2 import Environment, PackageLoader, select_autoescape
|
|
from pymongo import MongoClient
|
|
from roll import Roll, Response
|
|
from roll.extensions import cors, options, traceback, simple_server
|
|
|
|
from .base import Document, Str, Float, Array, Email, Int, Reference, Datetime, Mapping
|
|
|
|
|
|
class Response(Response):
|
|
def html(self, template_name, *args, **kwargs):
|
|
self.headers["Content-Type"] = "text/html; charset=utf-8"
|
|
context = app.context()
|
|
context.update(kwargs)
|
|
context["request"] = self.request
|
|
if self.request.cookies.get("message"):
|
|
context["message"] = json.loads(self.request.cookies["message"])
|
|
self.cookies.set("message", "")
|
|
self.body = env.get_template(template_name).render(*args, **context)
|
|
|
|
|
|
class Roll(Roll):
|
|
Response = Response
|
|
|
|
_context_func = []
|
|
|
|
def context(self):
|
|
context = {}
|
|
for func in self._context_func:
|
|
context.update(func())
|
|
return context
|
|
|
|
def register_context(self, func):
|
|
self._context_func.append(func)
|
|
|
|
|
|
env = Environment(
|
|
loader=PackageLoader("kaba", "templates"), autoescape=select_autoescape(["kaba"])
|
|
)
|
|
|
|
|
|
class Producer(Document):
|
|
__collection__ = "producers"
|
|
name = Str(required=True)
|
|
|
|
@property
|
|
def products(self):
|
|
return Product.find(producer=self._id)
|
|
|
|
|
|
class Product(Document):
|
|
__collection__ = "products"
|
|
producer = Reference(Producer, required=True)
|
|
name = Str(required=True)
|
|
ref = Str(required=True)
|
|
description = Str()
|
|
price = Float(required=True)
|
|
|
|
|
|
class Person(Document):
|
|
__collection__ = "persons"
|
|
first_name = Str()
|
|
last_name = Str()
|
|
email = Email()
|
|
|
|
|
|
class ProductOrder(Document):
|
|
ref = Str()
|
|
wanted = Int()
|
|
ordered = Int()
|
|
|
|
|
|
class PersonOrder(Document):
|
|
person = Str()
|
|
products = Array(ProductOrder)
|
|
|
|
|
|
class Order(Document):
|
|
__collection__ = "orders"
|
|
when = Datetime(required=True)
|
|
where = Str()
|
|
producer = Reference(Producer, required=True)
|
|
products = Array(Product)
|
|
orders = Mapping(Str, PersonOrder)
|
|
|
|
|
|
app = Roll()
|
|
cors(app, methods="*", headers="*")
|
|
options(app)
|
|
|
|
|
|
@app.listen("request")
|
|
async def attach_request(request, response):
|
|
response.request = request
|
|
|
|
|
|
@app.listen("startup")
|
|
async def on_startup():
|
|
connect()
|
|
|
|
|
|
@app.route("/", methods=["GET"])
|
|
async def home(request, response):
|
|
response.html("home.html", {"orders": Order.find()})
|
|
|
|
|
|
@app.route("/commande/{order_id}", methods=["GET"])
|
|
async def get_order(request, response, order_id):
|
|
order = Order.find_one(_id=ObjectId(order_id))
|
|
response.html(
|
|
"order.html",
|
|
{"order": order, "person": request.query.get("email"), "person_order": None},
|
|
)
|
|
|
|
|
|
@app.route("/commande/{order_id}", methods=["POST"])
|
|
async def place_order(request, response, order_id):
|
|
order = Order.find_one(_id=ObjectId(order_id))
|
|
email = request.query.get("email")
|
|
person_order = PersonOrder(person=email)
|
|
form = request.form
|
|
for product in order.products:
|
|
quantity = form.int(product.ref, 0)
|
|
if quantity:
|
|
person_order.products.append(ProductOrder(ref=product.ref, wanted=quantity))
|
|
if not order.orders:
|
|
order.orders = {}
|
|
order.orders[email] = person_order
|
|
order.replace_one()
|
|
response.headers["Location"] = request.url.decode()
|
|
response.status = 302
|
|
|
|
|
|
def connect():
|
|
db = os.environ.get("KABA_DB", "mongodb://localhost/kaba")
|
|
client = MongoClient(db)
|
|
db = client.get_database()
|
|
Producer.bind(db)
|
|
Product.bind(db)
|
|
Order.bind(db)
|
|
Person.bind(db)
|
|
return client
|
|
|
|
|
|
@minicli.cli()
|
|
def shell():
|
|
"""Run an ipython already connected to Mongo."""
|
|
try:
|
|
from IPython import start_ipython
|
|
except ImportError:
|
|
print('IPython is not installed. Type "pip install ipython"')
|
|
else:
|
|
start_ipython(
|
|
argv=[],
|
|
user_ns={
|
|
"Producer": Producer,
|
|
"app": app,
|
|
"Product": Product,
|
|
"Person": Person,
|
|
"Order": Order,
|
|
},
|
|
)
|
|
|
|
|
|
@minicli.wrap
|
|
def cli_wrapper():
|
|
connect()
|
|
start = perf_counter()
|
|
yield
|
|
elapsed = perf_counter() - start
|
|
print(f"Done in {elapsed:.5f} seconds.")
|
|
|
|
|
|
@minicli.cli
|
|
def serve(reload=False):
|
|
"""Run a web server (for development only)."""
|
|
if reload:
|
|
hupper.start_reloader("kaba.serve")
|
|
traceback(app)
|
|
simple_server(app, port=2244)
|
|
|
|
|
|
def main():
|
|
minicli.run()
|