Verified Commit 53435183 authored by Sli's avatar Sli
Browse files

server: add database importation from json

parent 81a1cf47
{
"event_date":
{
"year": 2019,
"month": 11,
"day": 16
},
"counters":
[
"Central",
"Fosse",
"Assidu",
"Libanais",
"Pop-corn",
"Bulle"
],
"products":
[
{
"name": "Bi\u00e8re \u00e2ne mort",
"price": 2.7,
"category": "boissons.bi\u00e8re",
"counters":
[
"Central",
"Fosse"
],
"happy_hours":
[
{
"start":
{
"hour": 21,
"minute": 30
},
"end":
{
"hour": 22,
"minute": 30
},
"price": 2.2
}
]
},
{
"name": "Bi\u00e8re Saison",
"price": 3,
"category": "boissons.bi\u00e8re",
"counters":
[
"Central",
"Fosse"
],
"happy_hours":
[
{
"start":
{
"hour": 21,
"minute": 30
},
"end":
{
"hour": 22,
"minute": 30
},
"price": 2.4
}
]
},
{
"name": "Kastel red",
"price": 3,
"category": "boissons.bi\u00e8re",
"counters":
[
"Central",
"Fosse"
],
"happy_hours":
[
{
"start":
{
"hour": 21,
"minute": 30
},
"end":
{
"hour": 22,
"minute": 30
},
"price": 2.4
}
]
},
{
"name": "Cr\u00e9mant",
"price": 3.5,
"category": "boissons.Verre",
"counters":
[
"Central",
"Assidu"
],
"happy_hours":
[
{
"start":
{
"hour": 21,
"minute": 30
},
"end":
{
"hour": 22,
"minute": 30
},
"price": 2.8
}
]
},
{
"name": "Charmes (moelleux, vin blanc)",
"price": 3.7,
"category": "boissons.Verre",
"counters":
[
"Central",
"Assidu"
],
"happy_hours":
[
{
"start":
{
"hour": 21,
"minute": 30
},
"end":
{
"hour": 22,
"minute": 30
},
"price": 3
}
]
},
{
"name": "Champagne",
"price": 5,
"category": "boissons.Verre",
"counters":
[
"Central",
"Assidu"
],
"happy_hours":
[
{
"start":
{
"hour": 21,
"minute": 30
},
"end":
{
"hour": 22,
"minute": 30
},
"price": 4
}
]
},
{
"name": "Sirop",
"price": 1,
"category": "boissons.Verre",
"counters":
[
"Central",
"Fosse",
"Assidu"
],
"happy_hours":
[
{
"start":
{
"hour": 21,
"minute": 30
},
"end":
{
"hour": 22,
"minute": 30
},
"price": 0.8
}
]
},
{
"name": "Jus de pomme",
"price": 2,
"category": "boissons.Verre",
"counters":
[
"Central",
"Fosse",
"Assidu"
],
"happy_hours":
[
{
"start":
{
"hour": 21,
"minute": 30
},
"end":
{
"hour": 22,
"minute": 30
},
"price": 1.6
}
]
},
{
"name": "Limonade",
"price": 2,
"category": "boissons.Verre",
"counters":
[
"Central",
"Fosse",
"Assidu"
],
"happy_hours":
[
{
"start":
{
"hour": 21,
"minute": 30
},
"end":
{
"hour": 22,
"minute": 30
},
"price": 1.6
}
]
},
{
"name": "Cr\u00e9mant Bouteille",
"price": 15.5,
"category": "boissons.Bouteille",
"counters":
[
"Central",
"Assidu"
]
},
{
"name": "Champagne Bouteille",
"price": 25,
"category": "boissons.Bouteille",
"counters":
[
"Central",
"Assidu"
]
},
{
"name": "Charmes Bouteille (moelleux, vin blanc)",
"price": 16,
"category": "boissons.Bouteille",
"counters":
[
"Central",
"Assidu"
]
},
{
"name": "Petite assiette",
"price": 5,
"category": "nourriture.assiette",
"counters":
[
"Libanais"
]
},
{
"name": "Grande assiette",
"price": 10,
"category": "nourriture.assiette",
"counters":
[
"Libanais"
]
},
{
"name": "Dessert",
"price": 3,
"category": "nourriture.sucr\u00e9",
"counters":
[
"Libanais"
]
},
{
"name": "Pop-corn",
"price": 1.5,
"category": "nourriture.sucr\u00e9",
"counters":
[
"Pop-corn"
]
},
{
"name": "Consigne",
"price": 1,
"category": "Consigne.consigne",
"counters":
[
"Central",
"Assidu",
"Fosse",
"Libanais",
"Pop-corn"
]
},
{
"name": "D\u00e9consigne",
"price": -1,
"category": "Consigne.consigne",
"counters":
[
"Central",
"Assidu",
"Fosse",
"Libanais",
"Pop-corn"
]
}
]
}
\ No newline at end of file
......@@ -6,6 +6,6 @@ source env/bin/activate
pip install -r requirements.txt
./manage.py protoc # Generate protobuf files
./manage.py setup # Generate database
./manage.py setup --import 2019.json # Generate database
./manage.py runserver
```
\ No newline at end of file
This diff is collapsed.
#!/usr/bin/env python3
# -*- coding:utf-8 -*
import os
import sys
import click
......@@ -33,17 +34,47 @@ def protoc():
@setup_group.command(name="setup", help="Generate database")
@click.option("--import", "-i", default=None, help="Import initial data from json file")
@click.option(
"--schema",
"-s",
default="db_import_schema.json",
help="Location of the schema used to validate the json of the import command",
)
def setup(**kwargs):
import json
from datetime import datetime
from random import randint
from slugify import slugify
import jsonschema
from server import settings, db, Model, engine, com_pb2, models
def datetime_helper(event_date, hour, minute):
# Does not handle midnight and after
return datetime(
year=event_date.year,
month=event_date.month,
day=event_date.day,
hour=hour,
minute=minute,
)
def generate_code(generated_codes, name):
code = slugify(name).upper()
while generated_codes.get(code, ""):
code += str(randint(0, 9))
generated_codes[code] = code
return code
if os.path.exists(settings.DB_PATH):
print("Deleting database")
print("--- Deleting database ---")
os.remove(settings.DB_PATH)
print("Creating database")
print("--- Creating database ---")
Model.metadata.create_all(bind=engine)
print("Creating payment methods")
print("--- Creating payment methods ---")
db.add(models.PaymentMethod(id=com_pb2.PaymentMethod.UNKNOWN, name="inconnu"))
db.add(models.PaymentMethod(id=com_pb2.PaymentMethod.CASH, name="espèces"))
db.add(models.PaymentMethod(id=com_pb2.PaymentMethod.CARD, name="carte"))
......@@ -53,10 +84,101 @@ def setup(**kwargs):
db.add(models.PaymentMethod(id=com_pb2.PaymentMethod.OTHER, name="autre"))
if kwargs["import"] is not None:
print("TODO: import data from %s" % kwargs["import"])
# Load user json
print("Importing data from %s" % kwargs["import"])
try:
f = open(kwargs["import"], "r")
except OSError as e:
print("Error opening %s: %s" % (kwargs["import"], e), file=sys.stderr)
return
try:
data = json.load(f)
except json.decoder.JSONDecodeError as e:
print("Error loading %s: %s" % (kwargs["import"], e), file=sys.stderr)
return
f.close()
print(kwargs["schema"])
# Load schema for validation
print("Matching against schema")
try:
f = open(kwargs["schema"], "r")
except OSError as e:
print("Error opening %s: %s" % (kwargs["import"], e), file=sys.stderr)
return
try:
schema = json.load(f)
except json.decoder.JSONDecodeError as e:
print("Error loading %s: %s" % (kwargs["import"], e), file=sys.stderr)
return
f.close()
try:
jsonschema.validate(data, schema)
except jsonschema.exceptions.ValidationError as e:
print("Your json is incorrect: %s" % e, file=sys.stderr)
return
generated_codes = {}
event_date = data.get("event_date", {})
event_date = datetime(
year=event_date["year"], month=event_date["month"], day=event_date["day"]
)
print("--- Event date is : %s ---", event_date)
print("--- Creating counters ---")
for counter in data.get("counters", []):
print("Creating counter %s" % counter)
db.add(models.Counter(name=counter))
db.commit()
print("--- Creating products ---")
for product in data.get("products", []):
p = models.Product(
name=product["name"].capitalize(),
code=generate_code(generated_codes, product["name"]),
category=".".join(
[cat.capitalize() for cat in product.get("category", "").split(".")]
),
default_price=product["price"],
)
print("Creating product %s" % p.name)
db.add(p)
db.commit()
# Get associated counters
for counter in (
db.query(models.Counter)
.filter(models.Counter.name.in_(product.get("counters", [])))
.all()
):
db.add(
models.ProductAvailableInCounter(
counter_id=counter.id, product_id=p.id
)
)
for happy_hour in product.get("happy_hours", []):
h = models.HappyHour(
start=datetime_helper(
event_date,
happy_hour["start"]["hour"],
happy_hour["start"]["minute"],
),
end=datetime_helper(
event_date,
happy_hour["end"]["hour"],
happy_hour["end"]["minute"],
),
price=happy_hour["price"],
product_id=p.id,
)
db.add(h)
db.commit()
db.commit()
print("Database successfully created")
print("--- Database successfully created ---")
if __name__ == "__main__":
......
grpcio==1.28.1
grpcio-tools==1.28.1
SQLAlchemy==1.3.17
click==7.1.2
\ No newline at end of file
click==7.1.2
jsonschema
python-slugify
\ No newline at end of file
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment