diff --git a/README.md b/README.md new file mode 100644 index 0000000..505bdc4 --- /dev/null +++ b/README.md @@ -0,0 +1,7 @@ +# BEER SG data storer + +This container will store SG data for beer runs in Mongo and then use that data to calculate Alchohol Content of each beer + +It's pretty loose and requires the Data Entry operator to know whats happening + +Luck for me... That's me! \ No newline at end of file diff --git a/flask.Dockerfile b/flask.Dockerfile index 4cdfe2d..7650a39 100644 --- a/flask.Dockerfile +++ b/flask.Dockerfile @@ -1,4 +1,5 @@ -FROM git.aridgwayweb.com/armistace/beer_base_image AS flask +#FROM git.aridgwayweb.com/armistace/beer_base_image AS flask +FROM beer_base_image AS flask COPY requirements.txt . @@ -8,6 +9,6 @@ ENV FLASK_ENV production ENV FLASK_DEBUG 1 -ENTRYPOINT ["flask", "--app", "/pool_data/src/flask/beer_data", "run", "--host=0.0.0.0"] +ENTRYPOINT ["flask", "--app", "/beer_data/src/flask/beer_data", "run", "--host=0.0.0.0"] #ENTRYPOINT ["python", "/pool_data/src/flask/pool_data.py"] diff --git a/requirements.txt b/requirements.txt index aaf30fa..ef76f0b 100644 --- a/requirements.txt +++ b/requirements.txt @@ -7,3 +7,5 @@ Flask-WTF bootstrap-flask waitress bokeh +pandas +duckdb \ No newline at end of file diff --git a/src/flask/add_user.py b/src/flask/add_user.py index 76fb24d..d03f7d2 100644 --- a/src/flask/add_user.py +++ b/src/flask/add_user.py @@ -20,7 +20,7 @@ def main(username, password): "password" : f"{password}" } if user_collection.user_exists(new_record["username"]): - user_collect.update_user(user_collection.existing_record["_id"], new_record["password"]) + user_collection.update_user(user_collection.existing_record["_id"], new_record["password"]) else: user_collection.add_user(new_record["username"], new_record["password"]) diff --git a/src/flask/beer_data.py b/src/flask/beer_data.py index 4664592..755fecd 100644 --- a/src/flask/beer_data.py +++ b/src/flask/beer_data.py @@ -1,11 +1,12 @@ from bokeh.core.enums import SpatialUnitsType -import mongo.build_db as pool_database -import mongo.query_db as pool_database_query +import mongo.build_db as beer_database +import mongo.query_db as beer_database_query +from table import table_builder from flask import Flask, render_template, request, jsonify, redirect, session from flask_wtf import FlaskForm, CSRFProtect from flask_bootstrap import Bootstrap5 -from wtforms import StringField, SubmitField, DateField, IntegerField, PasswordField, DecimalField, RadioField, TextAreaField +from wtforms import StringField, SubmitField, DateField, IntegerField, PasswordField, DecimalField, RadioField, TextAreaField, BooleanField from wtforms.validators import DataRequired, Length, Optional from waitress import serve from bokeh.models.layouts import HBox @@ -14,6 +15,7 @@ from charts import BeerCharts from bokeh.io import output_file, show from bokeh.layouts import row + app = Flask(__name__) app.secret_key = 'testsecret' #this value will change @@ -26,7 +28,7 @@ output_file("/beer_data/src/flask/static/data_plot.html") def create_graphs(): chart = BeerCharts.BeerCharts() sg = chart.line_chart("SG", "sg", 30) - show(row(column(sg))) + show(column(sg)) class userForm(FlaskForm): @@ -39,6 +41,7 @@ class dataForm(FlaskForm): beer_run_type = TextAreaField("Beer Type") Date = DateField("Date:") sg = IntegerField("SG Reading") + final_run = BooleanField("Final Reading?") comment = TextAreaField("Any Comments?", validators=[Optional()]) submit = SubmitField("Write it, Write it REAAAAAAL GOOOD") @@ -48,7 +51,7 @@ def index(): if form.validate_on_submit(): username = form.username.data password = form.password.data - db = pool_database_query.pool_query() + db = beer_database_query.pool_query() if db.user_check(username, password): session['logged_in'] = True return redirect("/updater") @@ -61,18 +64,24 @@ def index(): def updater(): if 'logged_in' not in session: return redirect("/") - create_graphs() - query_db = pool_database_query.pool_query() + predicted_alc_table = table_builder.TableBuilder().table_build() + tr_replace_string = '' + beer_html = predicted_alc_table.to_html(col_space='75px', index=False, + justify='center', border=3).replace('', tr_replace_string) + query_db = beer_database_query.pool_query() query = query_db.get_top(10, "sg") form = dataForm() + + if form.validate_on_submit(): - database = pool_database.pool_data() + database = beer_database.beer_data() new_record = { "date": f'{form.Date.data}', "beer_run_id": f'{form.beer_run_id.data}', "beer_type": f'{form.beer_run_type.data}', "sg" : f'{form.sg.data}', + "final_reading" : F'{form.final_run.data}', "comment": f'{form.comment.data}' } if database.record_exists(new_record["date"], new_record["beer_run_id"]): @@ -82,34 +91,40 @@ def updater(): if database.existing_record[field] != new_record[field]: database.update_re_record(database.existing_record["_id"], field, new_record[field]) else: - database.create_re_record(new_record["beer_run_id"], new_record["beer_type"], new_record["sg"], - new_record["date"], new_record["comment"]) - - return render_template("updater.html", list=query, form=form, success=True, updater_name = new_record["test_user"]) - else: - return render_template("updater.html", list=query, form=form, sucess=False) - -@app.route("/update_db", methods=["POST"]) -def pool_data_update(): - database = pool_database.pool_data() - new_record = request.json - if database.record_exists(new_record["date"], new_record["test_user"]): - for field in database.existing_record: - for new_field in new_record: - if field == new_field: - if database.existing_record[field] != new_record[field]: - database.update_re_record(database.existing_record["_id"], field, new_record[field]) + if new_record["final_reading"] == "True": + final_run_value = True else: - database.create_re_record(new_record["beer_run_id"], new_record["beer_type"], new_record["sg"], - new_record["date"], new_record["comment"]) + final_run_value = False + database.create_re_record(new_record["beer_run_id"], new_record["beer_type"], new_record["sg"], + new_record["date"], final_run_value, new_record["comment"]) + + return render_template("updater.html", beer_data = beer_html + , list=query, form=form, success=True, updater_name = "Saucy Beer Maker") + else: + return render_template("updater.html", beer_data = beer_html + , list=query, form=form, sucess=False) + +# @app.route("/update_db", methods=["POST"]) +# def beer_data_update(): +# database = beer_database.beer_data() +# new_record = request.json +# if database.record_exists(new_record["date"], new_record["test_user"]): +# for field in database.existing_record: +# for new_field in new_record: +# if field == new_field: +# if database.existing_record[field] != new_record[field]: +# database.update_re_record(database.existing_record["_id"], field, new_record[field]) +# else: +# database.create_re_record(new_record["beer_run_id"], new_record["beer_type"], new_record["sg"], +# new_record["date"], new_record["comment"]) -@app.route("/pool_top//") -def user_detail(id): - query_db = pool_database_query.pool_query() - query = query_db.get_top(return_number, field) - return jsonify([row.to_json() for row in query]) +# @app.route("/pool_top//") +# def user_detail(id): +# query_db = beer_database_query.pool_query() +# query = query_db.get_top(return_number, field) +# return jsonify([row.to_json() for row in query]) if __name__ == '__main__': #app.run(host='0.0.0.0') diff --git a/src/flask/chart_test.html b/src/flask/chart_test.html deleted file mode 100644 index 0ce9862..0000000 --- a/src/flask/chart_test.html +++ /dev/null @@ -1,61 +0,0 @@ - - - - - Bokeh Plot - - - - - -
- - - - - \ No newline at end of file diff --git a/src/flask/chart_test.py b/src/flask/chart_test.py deleted file mode 100644 index d30feaa..0000000 --- a/src/flask/chart_test.py +++ /dev/null @@ -1,17 +0,0 @@ -from bokeh.models.layouts import HBox -from bokeh.plotting import column -from charts import PoolCharts -from bokeh.io import output_file, show -from bokeh.layouts import row - -output_file("static/data_plot.html") - -chart = PoolCharts.PoolCharts() - -ph = chart.line_chart("Pool PH", "ph", 50) - -total_chlorine = chart.line_chart("Pool Total Chlorine", "total_chlorine", 50) - -free_chlorine = chart.line_chart("Pool Free Chlorine", "free_chlorine", 50) - -show(column(ph, total_chlorine, free_chlorine)) diff --git a/src/flask/charts/BeerCharts.py b/src/flask/charts/BeerCharts.py index 451b927..3655e22 100644 --- a/src/flask/charts/BeerCharts.py +++ b/src/flask/charts/BeerCharts.py @@ -9,9 +9,12 @@ class BeerCharts(): def __init__(self): self.db = db_conn() + def bar_chart(self, items, data): + return 0 + def line_chart(self, title, field, limit): - data = self.db.pool_db + data = self.db.beer_db data = data.find({}).sort("date", -1).limit(limit) dates = [] data_list = [] diff --git a/src/flask/mongo/build_db.py b/src/flask/mongo/build_db.py index 1e70c46..1b92353 100644 --- a/src/flask/mongo/build_db.py +++ b/src/flask/mongo/build_db.py @@ -15,14 +15,14 @@ class beer_data: #we can get self.db.real_db etc self.db = db_conn() - def record_exists(self, date, test_user): + def record_exists(self, date, beer_run_id): """ This function will accept an address if it find that address in the database it will return True and set set the existing_record variable of the class to the queried record """ - query = { "date" : f"{date}", "test_user": f"{test_user}"} + query = { "date" : f"{date}", "beer_run_id": f"{beer_run_id}"} record = self.db.beer_db.find_one(query) if record: self.existing_record = record @@ -31,7 +31,7 @@ class beer_data: return False - def create_re_record(self, beer_run_id, beer_type, sg, date, comment=""): + def create_re_record(self, beer_run_id, beer_type, sg, date, final_reading=False, comment=""): """ create_re_record creates a whole new record takes the required 7 inputs @@ -51,6 +51,7 @@ class beer_data: "beer_type": f"{beer_type}", "sg": f"{sg}", "date": f"{date}", + "final_reading": f"{final_reading}", "comment": f"{comment}" } diff --git a/src/flask/mongo/get_conn.py b/src/flask/mongo/get_conn.py index 20ad979..9f71b0d 100644 --- a/src/flask/mongo/get_conn.py +++ b/src/flask/mongo/get_conn.py @@ -8,7 +8,7 @@ class db_conn: self.db_host = os.getenv('MONGO_HOST') self.client = self.get_client() self.db = self.client['beer_db'] - self.pool_db = self.db['beer_data'] + self.beer_db = self.db['beer_data'] self.users = self.db['users'] self.inspections = self.db['inspections_db'] diff --git a/src/flask/table/__init__.py b/src/flask/table/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/src/flask/table/table_builder.py b/src/flask/table/table_builder.py new file mode 100644 index 0000000..20df83b --- /dev/null +++ b/src/flask/table/table_builder.py @@ -0,0 +1,54 @@ +import sys + +from mongo.get_conn import db_conn +import pandas as pd +import duckdb + +class TableBuilder(): + def __init__(self) -> None: + self.db = db_conn() + + def table_build(self, limit=10) -> pd.DataFrame: + data = self.db.beer_db + data = data.find({}).sort("date", -1) + df_dict = {} + df_dict["beer_run_id"]=[] + df_dict["sg"] = [] + df_dict["date"] = [] + df_dict["final_reading"] = [] + + for record in data: + df_dict["beer_run_id"].append(record["beer_run_id"]) + df_dict["sg"].append(record["sg"]) + df_dict["date"].append(record["date"]) + df_dict["final_reading"].append(record["final_reading"]) + df = pd.DataFrame(data=df_dict) + sql = f""" + SELECT x.beer_run_id as beer_run_id, + max(sg) as max, + min(sg) as min, + y.date as final_reading_date + FROM df x + JOIN + ( SELECT DISTINCT beer_run_id, date + FROM df + WHERE final_reading = 'True' + ) y ON x.beer_run_id = y.beer_run_id + GROUP BY x.beer_run_id, y.date + ORDER BY x.beer_run_id desc + LIMIT {limit} + """ + df_sum = duckdb.sql(sql).df() + sql = f""" + SELECT x.beer_run_id as "Beer Run", + x.max as "Max", + x.min as "Min", + ROUND(((CAST (max AS INTEGER) - CAST(min AS INTEGER)) / 7.36) + 0.5, 2) AS "Alcohol Prediction", + cast(final_reading_date as DATE) + INTERVAL 14 DAY as "Ready Date" + + FROM df_sum x + """ + df_calc = duckdb.sql(sql).df() + return df_calc + + diff --git a/src/flask/templates/updater.html b/src/flask/templates/updater.html index 8c8c088..b7745a7 100644 --- a/src/flask/templates/updater.html +++ b/src/flask/templates/updater.html @@ -46,17 +46,15 @@ --> - -
-
- -
-
- + +
+ {{ beer_data | safe }} + +
diff --git a/src/flask/test.py b/src/flask/test.py new file mode 100644 index 0000000..8a4794c --- /dev/null +++ b/src/flask/test.py @@ -0,0 +1,5 @@ +import table.table_builder as table_builder + +test = table_builder.TableBuilder() + +print(test.table_build())