From: Max Value Date: Mon, 4 May 2026 11:59:34 +0000 (+0100) Subject: Renaming and adding Delta Velorum X-Git-Url: https://git.ozva.co.uk/?a=commitdiff_plain;h=e80d87e11c4027af8b08362dc78f4e543ffb8272;p=delta-velorum Renaming and adding Delta Velorum --- diff --git a/Makefile b/Makefile index 0709a5c..dcd7bf1 100644 --- a/Makefile +++ b/Makefile @@ -1,6 +1,6 @@ main : .venv/touchfile npx tsc - .venv/bin/flask --app director run --debug + .venv/bin/flask --app argo run --debug .venv/touchfile : requirements.txt python3 -m venv .venv diff --git a/argo/__init__.py b/argo/__init__.py new file mode 100644 index 0000000..2b0c685 --- /dev/null +++ b/argo/__init__.py @@ -0,0 +1,65 @@ +from werkzeug.security import generate_password_hash, check_password_hash +from flask import Flask, render_template, send_from_directory, request +from flask_socketio import SocketIO, emit +from flask_httpauth import HTTPBasicAuth +from flask_cors import CORS +import json +import os + +from .utils import deindex + +STAR = os.getenv("DELTA_VELORUM", "B") +import argo.admin as admin + +from argo.database.read import read_views as database_read_views + +app = Flask(__name__, instance_relative_config=False) +socketio = SocketIO(app, logger=False, engineio_logger=False) +auth = HTTPBasicAuth() +CORS(app) + +# import authentication data + +with open(f"{app.root_path}/../../secrets.json", "r", encoding="utf-8") as f: + users = json.loads(f.read()) +users = {k: generate_password_hash(v) for (k, v) in users.items()} + +# password verifier + +def verify_password(username, password): + if username in users and check_password_hash(users.get(username), password): + return username + +auth.verify_password(verify_password) + +# root movements + +@app.route("/", methods=['get']) +def index(): + return render_template("index.html") + +@socketio.on('connect') +def connecting(): + emit("update", database_read_views(), json=True, namespace="/", broadcast=True) + +# info screen pages + +@app.route("/info/", methods=["get"]) +def info(screen): + return render_template(f"info/{screen}.html") + +# admin screen pages + +app.route("/admin", methods=["get"])(auth.login_required(admin.admin_main)) +app.route("/admin/", methods=["get", "post"])(auth.login_required(admin.admin_table)) + +# script pages + +@app.route("/script/", methods=["get"]) +def script(filename): + return send_from_directory(os.path.join(app.root_path, "build"), filename) + +@app.route("/db", methods=["get"]) +@auth.login_required +def download_db(): + return send_from_directory(f"{app.root_path}/../data", "main.db") diff --git a/argo/admin.py b/argo/admin.py new file mode 100644 index 0000000..dac3bb5 --- /dev/null +++ b/argo/admin.py @@ -0,0 +1,40 @@ +from flask import render_template, request +from flask_socketio import emit +import time + +from argo.database.read import read_indexes as database_read_indexes +from argo.database.read import read_views as database_read_views +from argo.database.write import write as database_write +from argo.database.read import read as database_read + +from argo import STAR + +def admin_main(): + return render_template( + "admin.html", + indexes=database_read_indexes(), + star=STAR + ) + +def admin_table(table_name): + start = time.time() + + if request.method == "POST": + database_write(request.form) + + emit( + "update", + database_read_views(table_name), + json=True, namespace="/", broadcast=True + ) + + end = time.time() + + return render_template( + "table.html", + indexes=database_read_indexes(), + table=database_read(table_name), + table_name=table_name, + time_taken = end - start, + star=STAR + ) diff --git a/argo/database/__init__.py b/argo/database/__init__.py new file mode 100644 index 0000000..e408c87 --- /dev/null +++ b/argo/database/__init__.py @@ -0,0 +1,14 @@ +""" + package to read and write to the database + + check if file exists and pragam check the database on init +""" + +from .utils import integrity_check, optimize +import sqlite3 +import os + +assert os.path.exists("./data/main.db"), "Database missing" +assert integrity_check(), "Database integrity error" + +optimize() diff --git a/argo/database/read.py b/argo/database/read.py new file mode 100644 index 0000000..b180b39 --- /dev/null +++ b/argo/database/read.py @@ -0,0 +1,69 @@ +import sqlite3 + +from .utils import list_all, list_views + +def read_all_current(): + tables = list_all() + indexes = read_indexes() + + with sqlite3.connect("./data/main.db") as connection: + cursor = connection.cursor() + + data = {} + for table in tables: + if table == "indexes": continue + + if "__view" in table: + index_table = table.split("__view")[0] + else: index_table = table + + cursor.execute(f"SELECT * FROM {table};") + + names = list(map(lambda x: f"{table}~~{x[0]}", cursor.description)) + row = cursor.fetchall()[indexes[f"int--{index_table}"]] + + data.update(dict(zip(names, row))) + + return data + +def read(table): + """ + reads a table by name + """ + with sqlite3.connect("./data/main.db") as connection: + cursor = connection.cursor() + + cursor.execute(f"SELECT * FROM {table};") + + names = list(map(lambda x: x[0], cursor.description)) + rows = [dict(zip(names, row)) for row in cursor.fetchall()] + + return rows + +def read_views(table=None): + """ + Reads views. If a table is specified, it reads all views related to that + table. If not it reads all views. + """ + if table is None: + related = list_views() + else: + related = [view for view in list_views() if view.split("__view")[0] == table] + + data = {} + for view in related: + for key, value in read(view)[0].items(): + data.update({f"{view.replace('__view', '')}~~{key}": value}) + + return data + +def read_indexes(): + with sqlite3.connect("./data/main.db") as connection: + cursor = connection.cursor() + + cursor.execute("SELECT * FROM indexes;") + + names = list(map(lambda x: x[0], cursor.description)) + indexes = [dict(zip(names, row)) for row in cursor.fetchall()][0] + + return indexes diff --git a/argo/database/utils.py b/argo/database/utils.py new file mode 100644 index 0000000..6866761 --- /dev/null +++ b/argo/database/utils.py @@ -0,0 +1,37 @@ +import sqlite3 + +def integrity_check(): + """ + check the database is ok and return true if it is + """ + with sqlite3.connect("./data/main.db") as connection: + cursor = connection.cursor() + integrity = cursor.execute('PRAGMA integrity_check') + + return integrity.fetchone()[0] == "ok" + +def optimize(): + """ + check the database is ok and return true if it is + """ + with sqlite3.connect("./data/main.db") as connection: + cursor = connection.cursor() + integrity = cursor.execute('PRAGMA optimize') + +def list_all(): + """ + get a list of all the tables and views in the database + """ + with sqlite3.connect("./data/main.db") as connection: + cursor = connection.cursor() + cursor.execute("SELECT name FROM sqlite_master WHERE type IN ('table', 'view');") + return [table[0] for table in cursor.fetchall()] + +def list_views(): + """ + get a list of all the views in the database + """ + with sqlite3.connect("./data/main.db") as connection: + cursor = connection.cursor() + cursor.execute("SELECT name FROM sqlite_master WHERE type='view';") + return [table[0] for table in cursor.fetchall()] diff --git a/argo/database/write.py b/argo/database/write.py new file mode 100644 index 0000000..eea0126 --- /dev/null +++ b/argo/database/write.py @@ -0,0 +1,20 @@ +import sqlite3 + +from .utils import list_all +from .read import read + +def write(data): + + with sqlite3.connect("./data/main.db") as connection: + cursor = connection.cursor() + + for key in data: + table, index, feild = key.split("~~") + + cursor.execute(f""" + UPDATE {table} + SET '{feild}' = '{data[key]}' + WHERE ROWID = {int(index) + 1}; + """) + + connection.commit() diff --git a/argo/src/admin.ts b/argo/src/admin.ts new file mode 100644 index 0000000..22e72e3 --- /dev/null +++ b/argo/src/admin.ts @@ -0,0 +1,40 @@ +const outlineStyle: string = "4px solid green"; +const outlineTime: number = 500; // ms + +export function setupTrigger() { + // setup all trigger buttons to send post request on click + const el: HTMLCollectionOf = + document.getElementsByClassName("trigger"); + + for (let e of el) { + e.addEventListener("click", (event) => { + if (event.target instanceof HTMLElement) { + let time: number = Math.round(Date.now() / 1000); + let body: FormData = new FormData(); + let delay = document.getElementById(`${event.target.getAttribute('name')}+delay`); + + if (delay instanceof HTMLInputElement) { + body.set(`${event.target.getAttribute('name')}`, `${time}+${delay.value}`); + + fetch("", { + method: "POST", + body: body + }); + + // trigger the button to turn green for approx same time (or 1s) + let timeout: number = delay.value as unknown as number * 1000; + if (timeout < outlineTime) { timeout = outlineTime; } + + if ( event.target instanceof HTMLElement) { + event.target.style.outline = outlineStyle; + setTimeout(function () { + if ( event.target instanceof HTMLElement) { + event.target.style.outline = "none" + } + }, timeout); + } + } + } + }) + } +} diff --git a/argo/src/discount.ts b/argo/src/discount.ts new file mode 100644 index 0000000..d05bd20 --- /dev/null +++ b/argo/src/discount.ts @@ -0,0 +1,25 @@ +export function renderDiscount(): void { + const el: HTMLCollectionOf = + document.getElementsByClassName("discount"); + + for (let e of el) { + if (e instanceof HTMLElement) { + if (typeof e.dataset.raw === "string") { + e.innerHTML = `${e.dataset.raw}%`; + } + } + } +} + +export function renderReverseDiscount(): void { + const el: HTMLCollectionOf = + document.getElementsByClassName("reverseDiscount"); + + for (let e of el) { + if (e instanceof HTMLElement) { + if (typeof e.dataset.raw === "string") { + e.innerHTML = `${100 - Number(e.dataset.raw)}%`; + } + } + } +} diff --git a/argo/src/price.ts b/argo/src/price.ts new file mode 100644 index 0000000..0d926c5 --- /dev/null +++ b/argo/src/price.ts @@ -0,0 +1,12 @@ +export default function renderPrice(): void { + const el: HTMLCollectionOf = + document.getElementsByClassName("price"); + + for (let e of el) { + if (e instanceof HTMLElement) { + if (typeof e.dataset.raw === "string") { + e.innerHTML = String(parseFloat(e.dataset.raw).toFixed(2)); + } + } + } +} diff --git a/argo/src/show_until.ts b/argo/src/show_until.ts new file mode 100644 index 0000000..6658b09 --- /dev/null +++ b/argo/src/show_until.ts @@ -0,0 +1,16 @@ +export default function renderShowUntil(): void { + const el: HTMLCollectionOf = + document.getElementsByClassName("showUntil"); + + for (let e of el) { + if (e instanceof HTMLElement) { + if (typeof e.dataset.raw === "string") { + let duration: number = (eval(e.dataset.raw) * 1000) - Date.now(); + if (duration > 0) { + e.classList.add("showUntil-showing") + setTimeout(function () {e.classList.remove("showUntil-showing")}, duration) + } + } + } + } +} diff --git a/argo/src/sound.ts b/argo/src/sound.ts new file mode 100644 index 0000000..b387907 --- /dev/null +++ b/argo/src/sound.ts @@ -0,0 +1,30 @@ +export function setupSounds() { + const el: HTMLCollectionOf = + document.getElementsByClassName("sound"); + + const context = new AudioContext(); + if (el.length > 0) { + for (let e of el) { + if (e instanceof HTMLMediaElement) { + const track = context.createMediaElementSource(e); + track.connect(context.destination); + } + } + } +} + +export function playSounds() { + const el: HTMLCollectionOf = + document.getElementsByClassName("sound"); + + for (let e of el) { + if (e instanceof HTMLMediaElement) { + if (typeof e.dataset.raw === "string") { + if (e.dataset.rawLast != e.dataset.raw) { + e.play(); + } + e.dataset.rawLast = e.dataset.raw; + } + } + } +} diff --git a/argo/src/state.ts b/argo/src/state.ts new file mode 100644 index 0000000..d206f25 --- /dev/null +++ b/argo/src/state.ts @@ -0,0 +1,18 @@ +export default function renderState(): void { + const el: HTMLCollectionOf = + document.getElementsByClassName("state"); + + for (let e of el) { + if (e instanceof HTMLElement) { + if (typeof e.dataset.raw === "string") { + for (let className of e.classList) { + if (className.startsWith("state-")) { + e.classList.remove(className); + } + } + + e.classList.add(`state-${e.dataset.raw}`); + } + } + } +} diff --git a/argo/src/style.ts b/argo/src/style.ts new file mode 100644 index 0000000..380559e --- /dev/null +++ b/argo/src/style.ts @@ -0,0 +1,31 @@ +export function setupStyle(): void { + const el: HTMLCollectionOf = + document.getElementsByClassName("style"); + + for (let i = 0; i < el.length; i++) { + const stylesheet = new CSSStyleSheet(); + document.adoptedStyleSheets.push(stylesheet); + } +} + +export function renderStyle(): void { + const el: HTMLCollectionOf = + document.getElementsByClassName("style"); + + for (let [i, e] of Array.from(el).entries()) { + if (e instanceof HTMLElement) { + let variable; + for (let className of e.classList) { + if (className.includes("--")) { + variable = className.split("--")[1]; + } + } + + if (typeof e.dataset.raw === "string") { + document.adoptedStyleSheets[i].replace(` + :root {--${variable}: ${e.dataset.raw};} + `); + } + } + } +} diff --git a/argo/src/text.ts b/argo/src/text.ts new file mode 100644 index 0000000..7695065 --- /dev/null +++ b/argo/src/text.ts @@ -0,0 +1,10 @@ +export default function renderText(): void { + const el = document.querySelectorAll(".text,.title"); + for (let e of el) { + if (e instanceof HTMLElement) { + if (typeof e.dataset.raw === "string") { + e.innerHTML = e.dataset.raw; + } + } + } +} diff --git a/argo/src/time.ts b/argo/src/time.ts new file mode 100644 index 0000000..84b69f3 --- /dev/null +++ b/argo/src/time.ts @@ -0,0 +1,51 @@ +import { timeSince, timeUntil, timeFormatBroadcast } from "./utils.js"; + +const timeUpdate: number = 1000; // ms + +export function setupTimeSince(): void { + const el: HTMLCollectionOf = + document.getElementsByClassName("since"); + + if (el.length > 0) { + setInterval( + function () { + const el: HTMLCollectionOf = + document.getElementsByClassName("since"); + + for (let e of el) { + if (e instanceof HTMLElement) { + if (typeof e.dataset.raw === "string") { + let [hours, minutes, seconds] = timeSince(eval(e.dataset.raw)) + e.innerHTML = timeFormatBroadcast(hours, minutes, seconds); + } + } + } + }, + timeUpdate + ); + } +} + +export function setupTimeUntil(): void { + const el: HTMLCollectionOf = + document.getElementsByClassName("until"); + + if (el.length > 0) { + setInterval( + function () { + const el: HTMLCollectionOf = + document.getElementsByClassName("until"); + + for (let e of el) { + if (e instanceof HTMLElement) { + if (typeof e.dataset.raw === "string") { + let [hours, minutes, seconds] = timeUntil(eval(e.dataset.raw)) + e.innerHTML = timeFormatBroadcast(hours, minutes, seconds); + } + } + } + }, + timeUpdate + ); + } +} diff --git a/argo/src/until.ts b/argo/src/until.ts new file mode 100644 index 0000000..e69de29 diff --git a/argo/src/update.ts b/argo/src/update.ts new file mode 100644 index 0000000..f122da3 --- /dev/null +++ b/argo/src/update.ts @@ -0,0 +1,43 @@ +import { io } from "socket.io-client"; + +import { renderDiscount, renderReverseDiscount } from "./discount.js"; +import { setupTimeSince, setupTimeUntil } from "./time.js"; +import { setupSounds, playSounds } from "./sound.js"; +import { setupStyle, renderStyle } from "./style.js"; +import renderShowUntil from "./show_until.js"; +import renderState from "./state.js"; +import renderPrice from "./price.js" +import renderText from "./text.js"; + +export default function setupUpdate(): void { + setupTimeSince(); + setupTimeUntil(); + setupSounds(); + setupStyle(); + + const socket = io(); + socket.on("update", (data) => { + const start = performance.now() + + for (const [key, value] of Object.entries(data)) { + const el = document.querySelectorAll(`.update[class~='${key}']`); + + for (let e of el) { + if (e instanceof HTMLElement) { + e.dataset.raw = value as unknown as string; + } + } + } + + renderReverseDiscount(); + renderShowUntil(); + renderDiscount(); + renderState(); + renderPrice(); + renderStyle(); + renderText(); + playSounds(); + + console.log(`Updated in ${performance.now() - start}ms`); + }); +} diff --git a/argo/src/utils.ts b/argo/src/utils.ts new file mode 100644 index 0000000..684ee85 --- /dev/null +++ b/argo/src/utils.ts @@ -0,0 +1,35 @@ +export function timeUntil(end: number): number[] { + let current: number = Date.now() / 1000; + var time: number = end - current; + + if (Math.sign(time) == -1) {time = 0;} + + let hours: number = Math.floor(time / 3600); + time %= 3600; + let minutes: number = Math.floor(time / 60); + let seconds: number = Math.floor(time % 60); + + return [hours, minutes, seconds] +} + +export function timeSince(end: number): number[] { + let current: number = Date.now() / 1000; + var time: number = current - end; + + if (Math.sign(time) == -1) {time = 0;} + + let hours: number = Math.floor(time / 3600); + time %= 3600; + let minutes: number = Math.floor(time / 60); + let seconds: number = Math.floor(time % 60); + + return [hours, minutes, seconds] +} + +export function timeFormatBroadcast(hours: number, minutes: number, seconds: number): string { + var hoursString = hours.toString().padStart(2, "0"); + var minutesString = minutes.toString().padStart(2, "0"); + var secondsString = seconds.toString().padStart(2, "0"); + + return `${hoursString}h ${minutesString}' ${secondsString}"` +} diff --git a/argo/static/admin.css b/argo/static/admin.css new file mode 100644 index 0000000..8ec2ddc --- /dev/null +++ b/argo/static/admin.css @@ -0,0 +1,79 @@ +/* PAGE POSITIONING */ + +:root { + --nav-background: lightgray; +} + +body > * { + padding: 15px; + overflow: scroll +} +nav { + position: absolute; + top: 0; bottom: 0; left: 0; + right: max(80%, calc(100vw - 350px)); + background-color: var(--nav-background); +} +main { + position: absolute; + top: 0; bottom: 0; right: 0; + left: min(20%, calc(350px)); +} + +/* THE OPTIONS GRID */ + +.optionsGrid { + display: grid; + grid-template-columns: 50px auto auto auto; +} +.optionsGrid > * { + padding: 10px; + border: 1px solid gray; + margin-top: -1px; + margin-right: -1px; +} +.optionsGridSpacer { border: none; } + + +:target { + outline: 4px solid blue; + z-index: 1; +} +.currentValue { color: red; } +.currentValue[type="radio"] { background-color: red; } + +i { + font-style: normal; + color: white; + text-shadow: + 1px 1px 0 black, + -1px 1px 0 black, + 1px -1px 0 black, + -1px -1px 0 black, + 0px 1px 0 black, + 0px -1px 0 black, + 1px 0px 0 black, + -1px 0px 0 black; +} + +/* PRINT MODE + need to work on this a little bit, currently just hides things that + shouldnt be printed and thats all. Should be able to potentially display + extra elements or manipulate the page in a way that make it easy to read + or annotate on the page. + */ + +@media ( max-width: 1000px ) { + nav { position: static; } + main { position: static; } +} + +@media print { + nav, [type="radio"] { display: none } + [type="submit"] { opacity: 0; } + main { position: static; } + .currentValue { color: black; } + .optionsGrid { grid-template-columns: 0 auto 0 auto; } + .optionsGrid > * { padding: 0; } + .optionsGridSpacer { padding: 20px; } +} diff --git a/argo/static/andika.css b/argo/static/andika.css new file mode 100644 index 0000000..0f268e5 --- /dev/null +++ b/argo/static/andika.css @@ -0,0 +1,55 @@ +/* +This file is from the Andika project (https://software.sil.org/andika/). +Copyright (c) 2004-2025 SIL Global (https://www.sil.org/) with Reserved +Font Names "Andika" and "SIL". This Font Software is licensed under the SIL +Open Font License, Version 1.1 (https://openfontlicense.org). +*/ + +@font-face { + font-family: "Andika"; + font-weight: 400; + src: url(/static/fonts/Andika-Regular.woff2); +} +@font-face { + font-family: "Andika"; + font-weight: 500; + src: url(/static/fonts/Andika-Medium.woff2); +} +@font-face { + font-family: "Andika"; + font-weight: 600; + src: url(/static/fonts/Andika-SemiBold.woff2); +} +@font-face { + font-family: "Andika"; + font-weight: 700; + src: url(/static/fonts/Andika-Bold.woff2); +} +@font-face { + font-family: "Andika"; + font-weight: 400; + font-style: italic; + src: url(/static/fonts/Andika-Italic.woff2); +} +@font-face { + font-family: "Andika"; + font-weight: 500; + font-style: italic; + src: url(/static/fonts/Andika-MediumItalic.woff2); +} +@font-face { + font-family: "Andika"; + font-weight: 600; + font-style: italic; + src: url(/static/fonts/Andika-SemiBoldItalic.woff2); +} +@font-face { + font-family: "Andika"; + font-weight: 700; + font-style: italic; + src: url(/static/fonts/Andika-BoldItalic.woff2); +} + +:root { + font-family: "Andika", sans-serif; +} diff --git a/argo/static/fonts/Andika-Bold.woff2 b/argo/static/fonts/Andika-Bold.woff2 new file mode 100644 index 0000000..866d64a Binary files /dev/null and b/argo/static/fonts/Andika-Bold.woff2 differ diff --git a/argo/static/fonts/Andika-BoldItalic.woff2 b/argo/static/fonts/Andika-BoldItalic.woff2 new file mode 100644 index 0000000..6941dca Binary files /dev/null and b/argo/static/fonts/Andika-BoldItalic.woff2 differ diff --git a/argo/static/fonts/Andika-Italic.woff2 b/argo/static/fonts/Andika-Italic.woff2 new file mode 100644 index 0000000..29d7283 Binary files /dev/null and b/argo/static/fonts/Andika-Italic.woff2 differ diff --git a/argo/static/fonts/Andika-Medium.woff2 b/argo/static/fonts/Andika-Medium.woff2 new file mode 100644 index 0000000..e47adf4 Binary files /dev/null and b/argo/static/fonts/Andika-Medium.woff2 differ diff --git a/argo/static/fonts/Andika-MediumItalic.woff2 b/argo/static/fonts/Andika-MediumItalic.woff2 new file mode 100644 index 0000000..928f4e3 Binary files /dev/null and b/argo/static/fonts/Andika-MediumItalic.woff2 differ diff --git a/argo/static/fonts/Andika-Regular.woff2 b/argo/static/fonts/Andika-Regular.woff2 new file mode 100644 index 0000000..d3e1a0d Binary files /dev/null and b/argo/static/fonts/Andika-Regular.woff2 differ diff --git a/argo/static/fonts/Andika-SemiBold.woff2 b/argo/static/fonts/Andika-SemiBold.woff2 new file mode 100644 index 0000000..09b7ebd Binary files /dev/null and b/argo/static/fonts/Andika-SemiBold.woff2 differ diff --git a/argo/static/fonts/Andika-SemiBoldItalic.woff2 b/argo/static/fonts/Andika-SemiBoldItalic.woff2 new file mode 100644 index 0000000..69ae382 Binary files /dev/null and b/argo/static/fonts/Andika-SemiBoldItalic.woff2 differ diff --git a/argo/static/info.css b/argo/static/info.css new file mode 100644 index 0000000..c8c37b9 --- /dev/null +++ b/argo/static/info.css @@ -0,0 +1,39 @@ +:root { + font-family: sans-serif; + color: white; + background-color: black; +} + +.infoA { font-size: var(--aFontSize); } +.infoB { font-size: var(--bFontSize); } +.infoC { font-size: var(--cFontSize); } + +.title { text-transform: capitalize; } + +/* INFO A */ +.infoA div > * { padding: 20px; } +.infoA div { + position: absolute; + top: 0; left: 0; bottom: 0; right: 0; + display: grid; + grid: none / 1fr; +} + +/* INFO B */ +.infoB div > * { padding: 20px; } +.infoB div { + position: absolute; + top: 0; left: 0; bottom: 0; right: 0; + display: grid; + grid: none / 1fr 1fr; +} + +/* INFO C */ +.infoC div > * { padding: 20px; text-align: center; } +.infoC div { + position: absolute; + top: 0; left: 0; bottom: 0; right: 0; + display: grid; + grid: none / 6fr 1fr 6fr; +} + diff --git a/argo/static/media/sfx/banner_shout.wav b/argo/static/media/sfx/banner_shout.wav new file mode 100644 index 0000000..4525408 Binary files /dev/null and b/argo/static/media/sfx/banner_shout.wav differ diff --git a/argo/static/media/sfx/clock.wav b/argo/static/media/sfx/clock.wav new file mode 100644 index 0000000..a760531 Binary files /dev/null and b/argo/static/media/sfx/clock.wav differ diff --git a/argo/static/media/sfx/shout.wav b/argo/static/media/sfx/shout.wav new file mode 100644 index 0000000..4a6849d Binary files /dev/null and b/argo/static/media/sfx/shout.wav differ diff --git a/argo/static/media/sfx/state_change.wav b/argo/static/media/sfx/state_change.wav new file mode 100644 index 0000000..9a34860 Binary files /dev/null and b/argo/static/media/sfx/state_change.wav differ diff --git a/argo/static/media/velo.jpg b/argo/static/media/velo.jpg new file mode 100644 index 0000000..1394cb8 Binary files /dev/null and b/argo/static/media/velo.jpg differ diff --git a/argo/static/style.css b/argo/static/style.css new file mode 100644 index 0000000..3295c95 --- /dev/null +++ b/argo/static/style.css @@ -0,0 +1,5 @@ +:root { + font-size: var(--baseFontSize); + font-weight: 600; +} +.title { text-transform: capitalize; } diff --git a/argo/static/style/banner_box.css b/argo/static/style/banner_box.css new file mode 100644 index 0000000..83213b6 --- /dev/null +++ b/argo/static/style/banner_box.css @@ -0,0 +1,20 @@ +body:not(.state-sold, .state-move) .styleBannerBox { + padding: 0; margin: 0; +} +.styleBannerBox { + opacity: 0; max-height: 0; + transform: translateX(-20px); + /* should do some tweeking for the below */ + transition: + opacity var(--baseAnimationLength), + max-height var(--baseAnimationLength) cubic-bezier(1,0,0,1), + padding var(--baseAnimationLength), + margin var(--baseAnimationLength), + transform var(--baseAnimationLength); + overflow: hidden; +} +body.state-sold .styleBannerBox, +body.state-move .styleBannerBox { + opacity: 1; max-height: 50vh; + transform: translateX(0px); +} diff --git a/argo/static/style/box.css b/argo/static/style/box.css new file mode 100644 index 0000000..35a7a24 --- /dev/null +++ b/argo/static/style/box.css @@ -0,0 +1,59 @@ +:root { + --boxHPad: 6px; + --boxVPad: 2px; + --boxHMar: 0px; + --boxVMar: 5px; +} +.boxA { + width: calc(100% - 2 * (var(--boxHMar) + var(--boxHPad) + var(--borderASize))); + + color: var(--textAColor); + text-shadow: var(--textAShadow); + + background: var(--backgroundA); + box-shadow: inset 0 0 var(--innerGlowSize) var(--innerGlowColor); + border: var(--borderASize) solid var(--borderAColor); + + border-radius: var(--borderARadius); + padding: var(--boxVPad) var(--boxHPad) var(--boxVPad) var(--boxHPad); + margin: var(--boxVMar) var(--boxHMar) var(--boxVMar) var(--boxHMar); +} +.boxA.styleExpand.showUntil:not(.showUntil-showing) { + margin-bottom: calc(-2 * var(--borderASize)); +} + +.boxB { + width: calc(100% - 2 * (var(--boxHMar) + var(--boxHPad) + var(--borderBSize))); + + color: var(--textBColor); + text-shadow: var(--textBShadow); + + background: var(--backgroundB); + box-shadow: inset 0 0 var(--innerGlowSize) var(--innerGlowColor); + border: var(--borderBSize) solid var(--borderBColor); + + border-radius: var(--borderBRadius); + padding: var(--boxVPad) var(--boxHPad) var(--boxVPad) var(--boxHPad); + margin: var(--boxVMar) var(--boxHMar) var(--boxVMar) var(--boxHMar); +} +.boxB.styleExpand.showUntil:not(.showUntil-showing) { + margin-bottom: calc(-2 * var(--borderBSize)); +} + +.boxC { + width: calc(100% - 2 * (var(--boxHMar) + var(--boxHPad) + var(--borderCSize))); + + color: var(--textCColor); + text-shadow: var(--textCShadow); + + background: var(--backgroundC); + box-shadow: inset 0 0 var(--innerGlowSize) var(--innerGlowColor); + border: var(--borderCSize) solid var(--borderCColor); + + border-radius: var(--borderCRadius); + padding: var(--boxVPad) var(--boxHPad) var(--boxVPad) var(--boxHPad); + margin: var(--boxVMar) var(--boxHMar) var(--boxVMar) var(--boxHMar); +} +.boxC.styleExpand.showUntil:not(.showUntil-showing) { + margin: 0 0 calc(-2 * var(--borderCSize)) 0; +} diff --git a/argo/static/style/center_shout.css b/argo/static/style/center_shout.css new file mode 100644 index 0000000..21b5949 --- /dev/null +++ b/argo/static/style/center_shout.css @@ -0,0 +1,29 @@ +.styleCenterShout { + position: absolute; + top: 0; left: 0; bottom: 0; right: 0; + + display: flex; + align-items: center; justify-content: center; + + text-transform: uppercase; +} +.styleCenterShout > div { background-color: red; } + +.styleCenterShout.showUntil > div { + transform: translateX(-100px); + opacity: 0; + transition: + transform var(--baseAnimationLength), + opacity var(--baseAnimationLength); +} +.styleCenterShout.showUntil > div > span { + display: block; + transform: translateX(200px); + transition: transform var(--baseAnimationLength); + + text-transform: uppercase; +} +.styleCenterShout.showUntil-showing * { + opacity: 1 !important; + transform: translateX(0px) !important; +} diff --git a/argo/static/style/discount_box.css b/argo/static/style/discount_box.css new file mode 100644 index 0000000..2c84661 --- /dev/null +++ b/argo/static/style/discount_box.css @@ -0,0 +1,30 @@ +.styleDiscountBox > em { + display: block; + font-size: 0.7em; + line-height: 1.4em; +} +.styleDiscountBox > div { + font-size: 1.2em; +} + +body:not(.state-discount, .state-move) .styleDiscountBox { + padding: 0; margin: 0; +} +.styleDiscountBox { + opacity: 0; max-height: 0; + transform: translateX(-20px); + /* should do some tweeking for the below */ + transition: + opacity var(--baseAnimationLength), + max-height var(--baseAnimationLength) cubic-bezier(1,0,0,1), + padding var(--baseAnimationLength), + margin var(--baseAnimationLength), + transform var(--baseAnimationLength); + overflow: hidden; +} +body.state-discount .styleDiscountBox, +body.state-move .styleDiscountBox { + opacity: 1; max-height: 50vh; + transform: translateX(0px); +} + diff --git a/argo/static/style/item_box.css b/argo/static/style/item_box.css new file mode 100644 index 0000000..f40ef48 --- /dev/null +++ b/argo/static/style/item_box.css @@ -0,0 +1,29 @@ +body:not( + .state-product, + .state-price, + .state-discount, + .state-move, + .state-sold +) .styleItemBox { + padding: 0; margin: 0; +} +.styleItemBox { + opacity: 0; max-height: 0; + transform: translateX(-20px); + /* should do some tweeking for the below */ + transition: + opacity var(--baseAnimationLength), + max-height var(--baseAnimationLength) cubic-bezier(1,0,0,1), + padding var(--baseAnimationLength), + margin var(--baseAnimationLength), + transform var(--baseAnimationLength); + overflow: hidden; +} +body.state-product .styleItemBox, +body.state-price .styleItemBox, +body.state-discount .styleItemBox, +body.state-move .styleItemBox, +body.state-sold .styleItemBox { + opacity: 1; max-height: 50vh; + transform: translateX(0px); +} diff --git a/argo/static/style/logo_box.css b/argo/static/style/logo_box.css new file mode 100644 index 0000000..c070292 --- /dev/null +++ b/argo/static/style/logo_box.css @@ -0,0 +1,23 @@ +body:not( + .state-crawler, + .state-product +) .styleLogoBox { + padding: 0; margin: 0; +} +.styleLogoBox { + opacity: 0; max-height: 0; + transform: translateX(-20px); + /* should do some tweeking for the below */ + transition: + opacity var(--baseAnimationLength), + max-height var(--baseAnimationLength) cubic-bezier(1,0,0,1), + padding var(--baseAnimationLength), + margin var(--baseAnimationLength), + transform var(--baseAnimationLength); + overflow: hidden; +} +body.state-product .styleLogoBox, +body.state-crawler .styleLogoBox { + opacity: 1; max-height: 50vh; + transform: translateX(0px); +} diff --git a/argo/static/style/pricing_box.css b/argo/static/style/pricing_box.css new file mode 100644 index 0000000..57d2fff --- /dev/null +++ b/argo/static/style/pricing_box.css @@ -0,0 +1,21 @@ +body:not(.state-price, .state-discount, .state-move) .stylePricingBox { + padding: 0; margin: 0; +} +.stylePricingBox { + opacity: 0; max-height: 0; + transform: translateX(-20px); + /* should do some tweeking for the below */ + transition: + opacity var(--baseAnimationLength), + max-height var(--baseAnimationLength) cubic-bezier(1,0,0,1), + padding var(--baseAnimationLength), + margin var(--baseAnimationLength), + transform var(--baseAnimationLength); + overflow: hidden; +} +body.state-price .stylePricingBox, +body.state-discount .stylePricingBox, +body.state-move .stylePricingBox { + opacity: 1; max-height: 50vh; + transform: translateX(0px); +} diff --git a/argo/static/style/qty_box.css b/argo/static/style/qty_box.css new file mode 100644 index 0000000..b774fa3 --- /dev/null +++ b/argo/static/style/qty_box.css @@ -0,0 +1,24 @@ +.styleQtyBox { + font-size: 0.7em; +} + +body:not(.state-sold, .state-move) .styleQtyBox { + padding: 0; margin: 0; +} +.styleQtyBox { + opacity: 0; max-height: 0; + transform: translateX(-20px); + /* should do some tweeking for the below */ + transition: + opacity var(--baseAnimationLength), + max-height var(--baseAnimationLength) cubic-bezier(1,0,0,1), + padding var(--baseAnimationLength), + margin var(--baseAnimationLength), + transform var(--baseAnimationLength); + overflow: hidden; +} +body.state-sold .styleQtyBox, +body.state-move .styleQtyBox { + opacity: 1; max-height: 50vh; + transform: translateX(0px); +} diff --git a/argo/static/style/show_until.css b/argo/static/style/show_until.css new file mode 100644 index 0000000..451952f --- /dev/null +++ b/argo/static/style/show_until.css @@ -0,0 +1,19 @@ +.styleExpand.showUntil:not(.showUntil-showing) { + padding: 0; margin: 0; +} +.styleExpand.showUntil { + opacity: 0; max-height: 0; + transform: translateX(-20px); + /* should do some tweeking for the below */ + transition: + opacity var(--baseAnimationLength), + max-height var(--baseAnimationLength) cubic-bezier(1,0,0,1), + padding var(--baseAnimationLength), + margin var(--baseAnimationLength), + transform var(--baseAnimationLength); + overflow: hidden; +} +.styleExpand.showUntil.showUntil-showing { + opacity: 1; max-height: 50vh; + transform: translateX(0px); +} diff --git a/argo/static/style/side_box.css b/argo/static/style/side_box.css new file mode 100644 index 0000000..066842e --- /dev/null +++ b/argo/static/style/side_box.css @@ -0,0 +1,12 @@ +.styleSideBox { + width: var(--sideBoxWidth); + + display: flex; + flex-direction: column; + + margin: 50px; +} +.styleSideBox > * { + margin-bottom: 5px; + width: 100%; +} diff --git a/argo/static/style/side_timer_box.css b/argo/static/style/side_timer_box.css new file mode 100644 index 0000000..dfd48d4 --- /dev/null +++ b/argo/static/style/side_timer_box.css @@ -0,0 +1,4 @@ +.styleSideTimerBox { + display: inline; + width: fit-content !important; +} diff --git a/argo/templates/admin.html b/argo/templates/admin.html new file mode 100644 index 0000000..5a5bc22 --- /dev/null +++ b/argo/templates/admin.html @@ -0,0 +1,55 @@ +{# + + builds the admin page + +#} + + + + δ Velorum + + + + + + +
+

δ Velorum {{ star }} “Alsephina” + {{ {"Aa": "The Ship", "Ab": "The Liferaft", "B": "Unknown"}[star] }} +

+ +
+ +
+
+ + +
+ + + + +
+ + diff --git a/argo/templates/admin/color.html b/argo/templates/admin/color.html new file mode 100644 index 0000000..1ecd886 --- /dev/null +++ b/argo/templates/admin/color.html @@ -0,0 +1,6 @@ + + + + {{ value }} + + diff --git a/argo/templates/admin/float.html b/argo/templates/admin/float.html new file mode 100644 index 0000000..12f8b00 --- /dev/null +++ b/argo/templates/admin/float.html @@ -0,0 +1,3 @@ + + +{{ value }} diff --git a/argo/templates/admin/number.html b/argo/templates/admin/number.html new file mode 100644 index 0000000..7ffe0c7 --- /dev/null +++ b/argo/templates/admin/number.html @@ -0,0 +1,3 @@ + + +{{ value }} diff --git a/argo/templates/admin/text.html b/argo/templates/admin/text.html new file mode 100644 index 0000000..3878cc8 --- /dev/null +++ b/argo/templates/admin/text.html @@ -0,0 +1,4 @@ + + +{{ value }} + diff --git a/argo/templates/admin/textarea.html b/argo/templates/admin/textarea.html new file mode 100644 index 0000000..a9ce85b --- /dev/null +++ b/argo/templates/admin/textarea.html @@ -0,0 +1,4 @@ + + diff --git a/argo/templates/admin/trigger.html b/argo/templates/admin/trigger.html new file mode 100644 index 0000000..322450d --- /dev/null +++ b/argo/templates/admin/trigger.html @@ -0,0 +1,7 @@ + + + + seconds delay (This does not update the triggered data.) + diff --git a/argo/templates/index.html b/argo/templates/index.html new file mode 100644 index 0000000..af8760e --- /dev/null +++ b/argo/templates/index.html @@ -0,0 +1,155 @@ + + + + + + + {# ELEMENT STYLING IMPORTS #} + + + + + + + + + + + {# HELPER IMPORTS #} + + + + + + + + + + {# GLOBAL STYLING ELEMENTS #} + + + + + {# DYNAMIC STYLING ELEMENTS #} + + + + + + + + + + + + + + + + + + + + + + + + + + + {# SFX ELEMENTS #} + + + + + + {# CENTER SHOUT #} +
+
+ +
+
+ + {# SIDE BOX + includes (top to bottom): + - LOGO BOX (show during: crawler, product) + - BANNER BOX (show during: move, sold) + - ITEM BOX (show during: product, price, discount, move, sold) + - PRICING BOX (show during: price, discount, move) + - DISCOUNT BOX (show during: discount, move) + - BANNER SHOUT BOX (show AD) + - QTY BOX (show during: move, sold) + - TIMER 1 BOX (show AD) + - TIMER 2 BOX (show AD) + + these are switched on and off using the state class from the + body tag. + #} +
+ + {# LOGO BOX #} +
+ LOGO BOX +
+ + {# BANNER BOX #} +
+ BANNER BOX +
+ + {# ITEM BOX #} +
+
+ ITEM BOX +
+
+ + {# PRICING BOX #} +
+ PRICING BOX +
+ + {# DISOUNT BOX #} +
+ Now only... +
+ + OFF! +
+
+ + {# BANNER SHOUT BOX #} +
+ +
+ + {# QTY BOX #} +
+ Sold: + ... + only + + LEFT +
+ + {# TIMER BOX #} +
+ TIMER 1! +
+
+ TIMER 2! +
+
+ + diff --git a/argo/templates/info/a.html b/argo/templates/info/a.html new file mode 100644 index 0000000..fa6e8cc --- /dev/null +++ b/argo/templates/info/a.html @@ -0,0 +1,33 @@ + + + + + + + + + + +
+ +
+ +
+ + + + +
+ + diff --git a/argo/templates/info/b.html b/argo/templates/info/b.html new file mode 100644 index 0000000..c06b48e --- /dev/null +++ b/argo/templates/info/b.html @@ -0,0 +1,51 @@ + + + + + + + + + + +
+ + (was ) + + + + + left of + + total + + + + off + + + + full price + + + + Target: ( left to drop) + + + + Max: ( left to drop) + +
+ + diff --git a/argo/templates/info/c.html b/argo/templates/info/c.html new file mode 100644 index 0000000..b35ba79 --- /dev/null +++ b/argo/templates/info/c.html @@ -0,0 +1,36 @@ + + + + + + + + + + +
+ Current product:
+ + Next product:
+ + Current state: + + Next state: + + + T- + +
+ + diff --git a/argo/templates/table.html b/argo/templates/table.html new file mode 100644 index 0000000..98dd490 --- /dev/null +++ b/argo/templates/table.html @@ -0,0 +1,99 @@ +{# + + builds the admin page + +#} + + + + δ Velorum + + + + + + +
+

δ Velorum {{ star }} Table: {{ table_name }}

+
+ + + {% for row in table %} + + {# CREATE RADIO BUTTON FOR ROW #} + + + {% if loop.index0 == indexes["int--" ~ table_name] %} + + {% else %} + + {% endif %} + + + {# CREATE FEILDS #} + + {% set group = loop.index0 %} + {% for feild in row %} + + {# SELECT ELEMENT FROM TYPE #} + + {% set type, label = feild.split('--') %} + {% set value = row[feild] %} + {% set name = table_name ~ "~~" ~ group ~ "~~" ~ feild %} + + {% if type == "textarea" %} + {% include "admin/textarea.html" %} + {% elif type == "text" %} + {% include "admin/text.html" %} + {% elif type == "number" %} + {% include "admin/number.html" %} + {% elif type == "float" %} + {% include "admin/float.html" %} + {% elif type == "trigger" %} + {% include "admin/trigger.html" %} + {% elif type == "color" %} + {% include "admin/color.html" %} + {% endif %} + {% endfor %} + + + {% endfor %} + +
+ + + Note: Tables are rendered statically, it is not safe to opperate the same interface in two places at once. +
+ Processed {{ table|length * table[0]|length }} feilds in + {% if (time_taken * 1000)|round(2) > 20 %} + {{ (time_taken * 1000)|round(2) }}ms + {% else %} + {{ (time_taken * 1000)|round(2) }}ms + {% endif %} +
+
+ + diff --git a/argo/utils.py b/argo/utils.py new file mode 100644 index 0000000..d2fc032 --- /dev/null +++ b/argo/utils.py @@ -0,0 +1,10 @@ +def deindex(data, indexes): + deindexed = {} + for key in data: + table, index, feild = key.split("~~") + if table != "indexes" and int(index) == indexes[f"int--{table}"]: + deindexed.update({ + f"{table}~~{feild}": data[key] + }) + + return deindexed diff --git a/director/__init__.py b/director/__init__.py deleted file mode 100644 index 706cd5e..0000000 --- a/director/__init__.py +++ /dev/null @@ -1,64 +0,0 @@ -from werkzeug.security import generate_password_hash, check_password_hash -from flask import Flask, render_template, send_from_directory, request -from flask_socketio import SocketIO, emit -from flask_httpauth import HTTPBasicAuth -from flask_cors import CORS -import json -import os - -from .utils import deindex - -import director.admin as admin - -from director.database.read import read_views as database_read_views - -app = Flask(__name__, instance_relative_config=False) -socketio = SocketIO(app, logger=False, engineio_logger=False) -auth = HTTPBasicAuth() -CORS(app) - -# import authentication data - -with open(f"{app.root_path}/../../secrets.json", "r", encoding="utf-8") as f: - users = json.loads(f.read()) -users = {k: generate_password_hash(v) for (k, v) in users.items()} - -# password verifier - -def verify_password(username, password): - if username in users and check_password_hash(users.get(username), password): - return username - -auth.verify_password(verify_password) - -# root movements - -@app.route("/", methods=['get']) -def index(): - return render_template("index.html") - -@socketio.on('connect') -def connecting(): - emit("update", database_read_views(), json=True, namespace="/", broadcast=True) - -# info screen pages - -@app.route("/info/", methods=["get"]) -def info(screen): - return render_template(f"info/{screen}.html") - -# admin screen pages - -app.route("/admin", methods=["get"])(auth.login_required(admin.admin_main)) -app.route("/admin/", methods=["get", "post"])(auth.login_required(admin.admin_table)) - -# script pages - -@app.route("/script/", methods=["get"]) -def script(filename): - return send_from_directory(os.path.join(app.root_path, "build"), filename) - -@app.route("/db", methods=["get"]) -@auth.login_required -def download_db(): - return send_from_directory(f"{app.root_path}/../data", "main.db") diff --git a/director/admin.py b/director/admin.py deleted file mode 100644 index 400f09d..0000000 --- a/director/admin.py +++ /dev/null @@ -1,33 +0,0 @@ -from flask import render_template, request -from flask_socketio import emit -import time - -from director.database.read import read_indexes as database_read_indexes -from director.database.read import read_views as database_read_views -from director.database.write import write as database_write -from director.database.read import read as database_read - -def admin_main(): - return render_template("admin.html", indexes=database_read_indexes()) - -def admin_table(table_name): - start = time.time() - - if request.method == "POST": - database_write(request.form) - - emit( - "update", - database_read_views(table_name), - json=True, namespace="/", broadcast=True - ) - - end = time.time() - - return render_template( - "table.html", - indexes=database_read_indexes(), - table=database_read(table_name), - table_name=table_name, - time_taken = end - start - ) diff --git a/director/database/__init__.py b/director/database/__init__.py deleted file mode 100644 index e408c87..0000000 --- a/director/database/__init__.py +++ /dev/null @@ -1,14 +0,0 @@ -""" - package to read and write to the database - - check if file exists and pragam check the database on init -""" - -from .utils import integrity_check, optimize -import sqlite3 -import os - -assert os.path.exists("./data/main.db"), "Database missing" -assert integrity_check(), "Database integrity error" - -optimize() diff --git a/director/database/read.py b/director/database/read.py deleted file mode 100644 index b180b39..0000000 --- a/director/database/read.py +++ /dev/null @@ -1,69 +0,0 @@ -import sqlite3 - -from .utils import list_all, list_views - -def read_all_current(): - tables = list_all() - indexes = read_indexes() - - with sqlite3.connect("./data/main.db") as connection: - cursor = connection.cursor() - - data = {} - for table in tables: - if table == "indexes": continue - - if "__view" in table: - index_table = table.split("__view")[0] - else: index_table = table - - cursor.execute(f"SELECT * FROM {table};") - - names = list(map(lambda x: f"{table}~~{x[0]}", cursor.description)) - row = cursor.fetchall()[indexes[f"int--{index_table}"]] - - data.update(dict(zip(names, row))) - - return data - -def read(table): - """ - reads a table by name - """ - with sqlite3.connect("./data/main.db") as connection: - cursor = connection.cursor() - - cursor.execute(f"SELECT * FROM {table};") - - names = list(map(lambda x: x[0], cursor.description)) - rows = [dict(zip(names, row)) for row in cursor.fetchall()] - - return rows - -def read_views(table=None): - """ - Reads views. If a table is specified, it reads all views related to that - table. If not it reads all views. - """ - if table is None: - related = list_views() - else: - related = [view for view in list_views() if view.split("__view")[0] == table] - - data = {} - for view in related: - for key, value in read(view)[0].items(): - data.update({f"{view.replace('__view', '')}~~{key}": value}) - - return data - -def read_indexes(): - with sqlite3.connect("./data/main.db") as connection: - cursor = connection.cursor() - - cursor.execute("SELECT * FROM indexes;") - - names = list(map(lambda x: x[0], cursor.description)) - indexes = [dict(zip(names, row)) for row in cursor.fetchall()][0] - - return indexes diff --git a/director/database/utils.py b/director/database/utils.py deleted file mode 100644 index 6866761..0000000 --- a/director/database/utils.py +++ /dev/null @@ -1,37 +0,0 @@ -import sqlite3 - -def integrity_check(): - """ - check the database is ok and return true if it is - """ - with sqlite3.connect("./data/main.db") as connection: - cursor = connection.cursor() - integrity = cursor.execute('PRAGMA integrity_check') - - return integrity.fetchone()[0] == "ok" - -def optimize(): - """ - check the database is ok and return true if it is - """ - with sqlite3.connect("./data/main.db") as connection: - cursor = connection.cursor() - integrity = cursor.execute('PRAGMA optimize') - -def list_all(): - """ - get a list of all the tables and views in the database - """ - with sqlite3.connect("./data/main.db") as connection: - cursor = connection.cursor() - cursor.execute("SELECT name FROM sqlite_master WHERE type IN ('table', 'view');") - return [table[0] for table in cursor.fetchall()] - -def list_views(): - """ - get a list of all the views in the database - """ - with sqlite3.connect("./data/main.db") as connection: - cursor = connection.cursor() - cursor.execute("SELECT name FROM sqlite_master WHERE type='view';") - return [table[0] for table in cursor.fetchall()] diff --git a/director/database/write.py b/director/database/write.py deleted file mode 100644 index eea0126..0000000 --- a/director/database/write.py +++ /dev/null @@ -1,20 +0,0 @@ -import sqlite3 - -from .utils import list_all -from .read import read - -def write(data): - - with sqlite3.connect("./data/main.db") as connection: - cursor = connection.cursor() - - for key in data: - table, index, feild = key.split("~~") - - cursor.execute(f""" - UPDATE {table} - SET '{feild}' = '{data[key]}' - WHERE ROWID = {int(index) + 1}; - """) - - connection.commit() diff --git a/director/src/admin.ts b/director/src/admin.ts deleted file mode 100644 index 22e72e3..0000000 --- a/director/src/admin.ts +++ /dev/null @@ -1,40 +0,0 @@ -const outlineStyle: string = "4px solid green"; -const outlineTime: number = 500; // ms - -export function setupTrigger() { - // setup all trigger buttons to send post request on click - const el: HTMLCollectionOf = - document.getElementsByClassName("trigger"); - - for (let e of el) { - e.addEventListener("click", (event) => { - if (event.target instanceof HTMLElement) { - let time: number = Math.round(Date.now() / 1000); - let body: FormData = new FormData(); - let delay = document.getElementById(`${event.target.getAttribute('name')}+delay`); - - if (delay instanceof HTMLInputElement) { - body.set(`${event.target.getAttribute('name')}`, `${time}+${delay.value}`); - - fetch("", { - method: "POST", - body: body - }); - - // trigger the button to turn green for approx same time (or 1s) - let timeout: number = delay.value as unknown as number * 1000; - if (timeout < outlineTime) { timeout = outlineTime; } - - if ( event.target instanceof HTMLElement) { - event.target.style.outline = outlineStyle; - setTimeout(function () { - if ( event.target instanceof HTMLElement) { - event.target.style.outline = "none" - } - }, timeout); - } - } - } - }) - } -} diff --git a/director/src/discount.ts b/director/src/discount.ts deleted file mode 100644 index d05bd20..0000000 --- a/director/src/discount.ts +++ /dev/null @@ -1,25 +0,0 @@ -export function renderDiscount(): void { - const el: HTMLCollectionOf = - document.getElementsByClassName("discount"); - - for (let e of el) { - if (e instanceof HTMLElement) { - if (typeof e.dataset.raw === "string") { - e.innerHTML = `${e.dataset.raw}%`; - } - } - } -} - -export function renderReverseDiscount(): void { - const el: HTMLCollectionOf = - document.getElementsByClassName("reverseDiscount"); - - for (let e of el) { - if (e instanceof HTMLElement) { - if (typeof e.dataset.raw === "string") { - e.innerHTML = `${100 - Number(e.dataset.raw)}%`; - } - } - } -} diff --git a/director/src/price.ts b/director/src/price.ts deleted file mode 100644 index 0d926c5..0000000 --- a/director/src/price.ts +++ /dev/null @@ -1,12 +0,0 @@ -export default function renderPrice(): void { - const el: HTMLCollectionOf = - document.getElementsByClassName("price"); - - for (let e of el) { - if (e instanceof HTMLElement) { - if (typeof e.dataset.raw === "string") { - e.innerHTML = String(parseFloat(e.dataset.raw).toFixed(2)); - } - } - } -} diff --git a/director/src/show_until.ts b/director/src/show_until.ts deleted file mode 100644 index 6658b09..0000000 --- a/director/src/show_until.ts +++ /dev/null @@ -1,16 +0,0 @@ -export default function renderShowUntil(): void { - const el: HTMLCollectionOf = - document.getElementsByClassName("showUntil"); - - for (let e of el) { - if (e instanceof HTMLElement) { - if (typeof e.dataset.raw === "string") { - let duration: number = (eval(e.dataset.raw) * 1000) - Date.now(); - if (duration > 0) { - e.classList.add("showUntil-showing") - setTimeout(function () {e.classList.remove("showUntil-showing")}, duration) - } - } - } - } -} diff --git a/director/src/sound.ts b/director/src/sound.ts deleted file mode 100644 index b387907..0000000 --- a/director/src/sound.ts +++ /dev/null @@ -1,30 +0,0 @@ -export function setupSounds() { - const el: HTMLCollectionOf = - document.getElementsByClassName("sound"); - - const context = new AudioContext(); - if (el.length > 0) { - for (let e of el) { - if (e instanceof HTMLMediaElement) { - const track = context.createMediaElementSource(e); - track.connect(context.destination); - } - } - } -} - -export function playSounds() { - const el: HTMLCollectionOf = - document.getElementsByClassName("sound"); - - for (let e of el) { - if (e instanceof HTMLMediaElement) { - if (typeof e.dataset.raw === "string") { - if (e.dataset.rawLast != e.dataset.raw) { - e.play(); - } - e.dataset.rawLast = e.dataset.raw; - } - } - } -} diff --git a/director/src/state.ts b/director/src/state.ts deleted file mode 100644 index d206f25..0000000 --- a/director/src/state.ts +++ /dev/null @@ -1,18 +0,0 @@ -export default function renderState(): void { - const el: HTMLCollectionOf = - document.getElementsByClassName("state"); - - for (let e of el) { - if (e instanceof HTMLElement) { - if (typeof e.dataset.raw === "string") { - for (let className of e.classList) { - if (className.startsWith("state-")) { - e.classList.remove(className); - } - } - - e.classList.add(`state-${e.dataset.raw}`); - } - } - } -} diff --git a/director/src/style.ts b/director/src/style.ts deleted file mode 100644 index 380559e..0000000 --- a/director/src/style.ts +++ /dev/null @@ -1,31 +0,0 @@ -export function setupStyle(): void { - const el: HTMLCollectionOf = - document.getElementsByClassName("style"); - - for (let i = 0; i < el.length; i++) { - const stylesheet = new CSSStyleSheet(); - document.adoptedStyleSheets.push(stylesheet); - } -} - -export function renderStyle(): void { - const el: HTMLCollectionOf = - document.getElementsByClassName("style"); - - for (let [i, e] of Array.from(el).entries()) { - if (e instanceof HTMLElement) { - let variable; - for (let className of e.classList) { - if (className.includes("--")) { - variable = className.split("--")[1]; - } - } - - if (typeof e.dataset.raw === "string") { - document.adoptedStyleSheets[i].replace(` - :root {--${variable}: ${e.dataset.raw};} - `); - } - } - } -} diff --git a/director/src/text.ts b/director/src/text.ts deleted file mode 100644 index 7695065..0000000 --- a/director/src/text.ts +++ /dev/null @@ -1,10 +0,0 @@ -export default function renderText(): void { - const el = document.querySelectorAll(".text,.title"); - for (let e of el) { - if (e instanceof HTMLElement) { - if (typeof e.dataset.raw === "string") { - e.innerHTML = e.dataset.raw; - } - } - } -} diff --git a/director/src/time.ts b/director/src/time.ts deleted file mode 100644 index 84b69f3..0000000 --- a/director/src/time.ts +++ /dev/null @@ -1,51 +0,0 @@ -import { timeSince, timeUntil, timeFormatBroadcast } from "./utils.js"; - -const timeUpdate: number = 1000; // ms - -export function setupTimeSince(): void { - const el: HTMLCollectionOf = - document.getElementsByClassName("since"); - - if (el.length > 0) { - setInterval( - function () { - const el: HTMLCollectionOf = - document.getElementsByClassName("since"); - - for (let e of el) { - if (e instanceof HTMLElement) { - if (typeof e.dataset.raw === "string") { - let [hours, minutes, seconds] = timeSince(eval(e.dataset.raw)) - e.innerHTML = timeFormatBroadcast(hours, minutes, seconds); - } - } - } - }, - timeUpdate - ); - } -} - -export function setupTimeUntil(): void { - const el: HTMLCollectionOf = - document.getElementsByClassName("until"); - - if (el.length > 0) { - setInterval( - function () { - const el: HTMLCollectionOf = - document.getElementsByClassName("until"); - - for (let e of el) { - if (e instanceof HTMLElement) { - if (typeof e.dataset.raw === "string") { - let [hours, minutes, seconds] = timeUntil(eval(e.dataset.raw)) - e.innerHTML = timeFormatBroadcast(hours, minutes, seconds); - } - } - } - }, - timeUpdate - ); - } -} diff --git a/director/src/until.ts b/director/src/until.ts deleted file mode 100644 index e69de29..0000000 diff --git a/director/src/update.ts b/director/src/update.ts deleted file mode 100644 index f122da3..0000000 --- a/director/src/update.ts +++ /dev/null @@ -1,43 +0,0 @@ -import { io } from "socket.io-client"; - -import { renderDiscount, renderReverseDiscount } from "./discount.js"; -import { setupTimeSince, setupTimeUntil } from "./time.js"; -import { setupSounds, playSounds } from "./sound.js"; -import { setupStyle, renderStyle } from "./style.js"; -import renderShowUntil from "./show_until.js"; -import renderState from "./state.js"; -import renderPrice from "./price.js" -import renderText from "./text.js"; - -export default function setupUpdate(): void { - setupTimeSince(); - setupTimeUntil(); - setupSounds(); - setupStyle(); - - const socket = io(); - socket.on("update", (data) => { - const start = performance.now() - - for (const [key, value] of Object.entries(data)) { - const el = document.querySelectorAll(`.update[class~='${key}']`); - - for (let e of el) { - if (e instanceof HTMLElement) { - e.dataset.raw = value as unknown as string; - } - } - } - - renderReverseDiscount(); - renderShowUntil(); - renderDiscount(); - renderState(); - renderPrice(); - renderStyle(); - renderText(); - playSounds(); - - console.log(`Updated in ${performance.now() - start}ms`); - }); -} diff --git a/director/src/utils.ts b/director/src/utils.ts deleted file mode 100644 index 684ee85..0000000 --- a/director/src/utils.ts +++ /dev/null @@ -1,35 +0,0 @@ -export function timeUntil(end: number): number[] { - let current: number = Date.now() / 1000; - var time: number = end - current; - - if (Math.sign(time) == -1) {time = 0;} - - let hours: number = Math.floor(time / 3600); - time %= 3600; - let minutes: number = Math.floor(time / 60); - let seconds: number = Math.floor(time % 60); - - return [hours, minutes, seconds] -} - -export function timeSince(end: number): number[] { - let current: number = Date.now() / 1000; - var time: number = current - end; - - if (Math.sign(time) == -1) {time = 0;} - - let hours: number = Math.floor(time / 3600); - time %= 3600; - let minutes: number = Math.floor(time / 60); - let seconds: number = Math.floor(time % 60); - - return [hours, minutes, seconds] -} - -export function timeFormatBroadcast(hours: number, minutes: number, seconds: number): string { - var hoursString = hours.toString().padStart(2, "0"); - var minutesString = minutes.toString().padStart(2, "0"); - var secondsString = seconds.toString().padStart(2, "0"); - - return `${hoursString}h ${minutesString}' ${secondsString}"` -} diff --git a/director/static/admin.css b/director/static/admin.css deleted file mode 100644 index cc4422f..0000000 --- a/director/static/admin.css +++ /dev/null @@ -1,66 +0,0 @@ -/* PAGE POSITIONING */ - -:root { - --nav-background: lightgray; -} - -body > * { - padding: 15px; - overflow: scroll -} -nav { - position: absolute; - top: 0; bottom: 0; left: 0; - right: max(80%, calc(100vw - 350px)); - background-color: var(--nav-background); -} -main { - position: absolute; - top: 0; bottom: 0; right: 0; - left: min(20%, calc(350px)); -} - -/* THE OPTIONS GRID */ - -.optionsGrid { - display: grid; - grid-template-columns: 50px auto auto auto; -} -.optionsGrid > * { - padding: 10px; - border: 1px solid gray; - margin-top: -1px; - margin-right: -1px; -} -.optionsGridSpacer { border: none; } - - -:target { - outline: 4px solid blue; - z-index: 1; -} -.currentValue { color: red; } -.currentValue[type="radio"] { background-color: red; } - - -/* PRINT MODE - need to work on this a little bit, currently just hides things that - shouldnt be printed and thats all. Should be able to potentially display - extra elements or manipulate the page in a way that make it easy to read - or annotate on the page. - */ - -@media ( max-width: 1000px ) { - nav { position: static; } - main { position: static; } -} - -@media print { - nav, [type="radio"] { display: none } - [type="submit"] { opacity: 0; } - main { position: static; } - .currentValue { color: black; } - .optionsGrid { grid-template-columns: 0 auto 0 auto; } - .optionsGrid > * { padding: 0; } - .optionsGridSpacer { padding: 20px; } -} diff --git a/director/static/andika.css b/director/static/andika.css deleted file mode 100644 index 0f268e5..0000000 --- a/director/static/andika.css +++ /dev/null @@ -1,55 +0,0 @@ -/* -This file is from the Andika project (https://software.sil.org/andika/). -Copyright (c) 2004-2025 SIL Global (https://www.sil.org/) with Reserved -Font Names "Andika" and "SIL". This Font Software is licensed under the SIL -Open Font License, Version 1.1 (https://openfontlicense.org). -*/ - -@font-face { - font-family: "Andika"; - font-weight: 400; - src: url(/static/fonts/Andika-Regular.woff2); -} -@font-face { - font-family: "Andika"; - font-weight: 500; - src: url(/static/fonts/Andika-Medium.woff2); -} -@font-face { - font-family: "Andika"; - font-weight: 600; - src: url(/static/fonts/Andika-SemiBold.woff2); -} -@font-face { - font-family: "Andika"; - font-weight: 700; - src: url(/static/fonts/Andika-Bold.woff2); -} -@font-face { - font-family: "Andika"; - font-weight: 400; - font-style: italic; - src: url(/static/fonts/Andika-Italic.woff2); -} -@font-face { - font-family: "Andika"; - font-weight: 500; - font-style: italic; - src: url(/static/fonts/Andika-MediumItalic.woff2); -} -@font-face { - font-family: "Andika"; - font-weight: 600; - font-style: italic; - src: url(/static/fonts/Andika-SemiBoldItalic.woff2); -} -@font-face { - font-family: "Andika"; - font-weight: 700; - font-style: italic; - src: url(/static/fonts/Andika-BoldItalic.woff2); -} - -:root { - font-family: "Andika", sans-serif; -} diff --git a/director/static/fonts/Andika-Bold.woff2 b/director/static/fonts/Andika-Bold.woff2 deleted file mode 100644 index 866d64a..0000000 Binary files a/director/static/fonts/Andika-Bold.woff2 and /dev/null differ diff --git a/director/static/fonts/Andika-BoldItalic.woff2 b/director/static/fonts/Andika-BoldItalic.woff2 deleted file mode 100644 index 6941dca..0000000 Binary files a/director/static/fonts/Andika-BoldItalic.woff2 and /dev/null differ diff --git a/director/static/fonts/Andika-Italic.woff2 b/director/static/fonts/Andika-Italic.woff2 deleted file mode 100644 index 29d7283..0000000 Binary files a/director/static/fonts/Andika-Italic.woff2 and /dev/null differ diff --git a/director/static/fonts/Andika-Medium.woff2 b/director/static/fonts/Andika-Medium.woff2 deleted file mode 100644 index e47adf4..0000000 Binary files a/director/static/fonts/Andika-Medium.woff2 and /dev/null differ diff --git a/director/static/fonts/Andika-MediumItalic.woff2 b/director/static/fonts/Andika-MediumItalic.woff2 deleted file mode 100644 index 928f4e3..0000000 Binary files a/director/static/fonts/Andika-MediumItalic.woff2 and /dev/null differ diff --git a/director/static/fonts/Andika-Regular.woff2 b/director/static/fonts/Andika-Regular.woff2 deleted file mode 100644 index d3e1a0d..0000000 Binary files a/director/static/fonts/Andika-Regular.woff2 and /dev/null differ diff --git a/director/static/fonts/Andika-SemiBold.woff2 b/director/static/fonts/Andika-SemiBold.woff2 deleted file mode 100644 index 09b7ebd..0000000 Binary files a/director/static/fonts/Andika-SemiBold.woff2 and /dev/null differ diff --git a/director/static/fonts/Andika-SemiBoldItalic.woff2 b/director/static/fonts/Andika-SemiBoldItalic.woff2 deleted file mode 100644 index 69ae382..0000000 Binary files a/director/static/fonts/Andika-SemiBoldItalic.woff2 and /dev/null differ diff --git a/director/static/info.css b/director/static/info.css deleted file mode 100644 index c8c37b9..0000000 --- a/director/static/info.css +++ /dev/null @@ -1,39 +0,0 @@ -:root { - font-family: sans-serif; - color: white; - background-color: black; -} - -.infoA { font-size: var(--aFontSize); } -.infoB { font-size: var(--bFontSize); } -.infoC { font-size: var(--cFontSize); } - -.title { text-transform: capitalize; } - -/* INFO A */ -.infoA div > * { padding: 20px; } -.infoA div { - position: absolute; - top: 0; left: 0; bottom: 0; right: 0; - display: grid; - grid: none / 1fr; -} - -/* INFO B */ -.infoB div > * { padding: 20px; } -.infoB div { - position: absolute; - top: 0; left: 0; bottom: 0; right: 0; - display: grid; - grid: none / 1fr 1fr; -} - -/* INFO C */ -.infoC div > * { padding: 20px; text-align: center; } -.infoC div { - position: absolute; - top: 0; left: 0; bottom: 0; right: 0; - display: grid; - grid: none / 6fr 1fr 6fr; -} - diff --git a/director/static/media/sfx/banner_shout.wav b/director/static/media/sfx/banner_shout.wav deleted file mode 100644 index 4525408..0000000 Binary files a/director/static/media/sfx/banner_shout.wav and /dev/null differ diff --git a/director/static/media/sfx/clock.wav b/director/static/media/sfx/clock.wav deleted file mode 100644 index a760531..0000000 Binary files a/director/static/media/sfx/clock.wav and /dev/null differ diff --git a/director/static/media/sfx/shout.wav b/director/static/media/sfx/shout.wav deleted file mode 100644 index 4a6849d..0000000 Binary files a/director/static/media/sfx/shout.wav and /dev/null differ diff --git a/director/static/media/sfx/state_change.wav b/director/static/media/sfx/state_change.wav deleted file mode 100644 index 9a34860..0000000 Binary files a/director/static/media/sfx/state_change.wav and /dev/null differ diff --git a/director/static/style.css b/director/static/style.css deleted file mode 100644 index 3295c95..0000000 --- a/director/static/style.css +++ /dev/null @@ -1,5 +0,0 @@ -:root { - font-size: var(--baseFontSize); - font-weight: 600; -} -.title { text-transform: capitalize; } diff --git a/director/static/style/banner_box.css b/director/static/style/banner_box.css deleted file mode 100644 index 83213b6..0000000 --- a/director/static/style/banner_box.css +++ /dev/null @@ -1,20 +0,0 @@ -body:not(.state-sold, .state-move) .styleBannerBox { - padding: 0; margin: 0; -} -.styleBannerBox { - opacity: 0; max-height: 0; - transform: translateX(-20px); - /* should do some tweeking for the below */ - transition: - opacity var(--baseAnimationLength), - max-height var(--baseAnimationLength) cubic-bezier(1,0,0,1), - padding var(--baseAnimationLength), - margin var(--baseAnimationLength), - transform var(--baseAnimationLength); - overflow: hidden; -} -body.state-sold .styleBannerBox, -body.state-move .styleBannerBox { - opacity: 1; max-height: 50vh; - transform: translateX(0px); -} diff --git a/director/static/style/box.css b/director/static/style/box.css deleted file mode 100644 index 35a7a24..0000000 --- a/director/static/style/box.css +++ /dev/null @@ -1,59 +0,0 @@ -:root { - --boxHPad: 6px; - --boxVPad: 2px; - --boxHMar: 0px; - --boxVMar: 5px; -} -.boxA { - width: calc(100% - 2 * (var(--boxHMar) + var(--boxHPad) + var(--borderASize))); - - color: var(--textAColor); - text-shadow: var(--textAShadow); - - background: var(--backgroundA); - box-shadow: inset 0 0 var(--innerGlowSize) var(--innerGlowColor); - border: var(--borderASize) solid var(--borderAColor); - - border-radius: var(--borderARadius); - padding: var(--boxVPad) var(--boxHPad) var(--boxVPad) var(--boxHPad); - margin: var(--boxVMar) var(--boxHMar) var(--boxVMar) var(--boxHMar); -} -.boxA.styleExpand.showUntil:not(.showUntil-showing) { - margin-bottom: calc(-2 * var(--borderASize)); -} - -.boxB { - width: calc(100% - 2 * (var(--boxHMar) + var(--boxHPad) + var(--borderBSize))); - - color: var(--textBColor); - text-shadow: var(--textBShadow); - - background: var(--backgroundB); - box-shadow: inset 0 0 var(--innerGlowSize) var(--innerGlowColor); - border: var(--borderBSize) solid var(--borderBColor); - - border-radius: var(--borderBRadius); - padding: var(--boxVPad) var(--boxHPad) var(--boxVPad) var(--boxHPad); - margin: var(--boxVMar) var(--boxHMar) var(--boxVMar) var(--boxHMar); -} -.boxB.styleExpand.showUntil:not(.showUntil-showing) { - margin-bottom: calc(-2 * var(--borderBSize)); -} - -.boxC { - width: calc(100% - 2 * (var(--boxHMar) + var(--boxHPad) + var(--borderCSize))); - - color: var(--textCColor); - text-shadow: var(--textCShadow); - - background: var(--backgroundC); - box-shadow: inset 0 0 var(--innerGlowSize) var(--innerGlowColor); - border: var(--borderCSize) solid var(--borderCColor); - - border-radius: var(--borderCRadius); - padding: var(--boxVPad) var(--boxHPad) var(--boxVPad) var(--boxHPad); - margin: var(--boxVMar) var(--boxHMar) var(--boxVMar) var(--boxHMar); -} -.boxC.styleExpand.showUntil:not(.showUntil-showing) { - margin: 0 0 calc(-2 * var(--borderCSize)) 0; -} diff --git a/director/static/style/center_shout.css b/director/static/style/center_shout.css deleted file mode 100644 index 21b5949..0000000 --- a/director/static/style/center_shout.css +++ /dev/null @@ -1,29 +0,0 @@ -.styleCenterShout { - position: absolute; - top: 0; left: 0; bottom: 0; right: 0; - - display: flex; - align-items: center; justify-content: center; - - text-transform: uppercase; -} -.styleCenterShout > div { background-color: red; } - -.styleCenterShout.showUntil > div { - transform: translateX(-100px); - opacity: 0; - transition: - transform var(--baseAnimationLength), - opacity var(--baseAnimationLength); -} -.styleCenterShout.showUntil > div > span { - display: block; - transform: translateX(200px); - transition: transform var(--baseAnimationLength); - - text-transform: uppercase; -} -.styleCenterShout.showUntil-showing * { - opacity: 1 !important; - transform: translateX(0px) !important; -} diff --git a/director/static/style/discount_box.css b/director/static/style/discount_box.css deleted file mode 100644 index 2c84661..0000000 --- a/director/static/style/discount_box.css +++ /dev/null @@ -1,30 +0,0 @@ -.styleDiscountBox > em { - display: block; - font-size: 0.7em; - line-height: 1.4em; -} -.styleDiscountBox > div { - font-size: 1.2em; -} - -body:not(.state-discount, .state-move) .styleDiscountBox { - padding: 0; margin: 0; -} -.styleDiscountBox { - opacity: 0; max-height: 0; - transform: translateX(-20px); - /* should do some tweeking for the below */ - transition: - opacity var(--baseAnimationLength), - max-height var(--baseAnimationLength) cubic-bezier(1,0,0,1), - padding var(--baseAnimationLength), - margin var(--baseAnimationLength), - transform var(--baseAnimationLength); - overflow: hidden; -} -body.state-discount .styleDiscountBox, -body.state-move .styleDiscountBox { - opacity: 1; max-height: 50vh; - transform: translateX(0px); -} - diff --git a/director/static/style/item_box.css b/director/static/style/item_box.css deleted file mode 100644 index f40ef48..0000000 --- a/director/static/style/item_box.css +++ /dev/null @@ -1,29 +0,0 @@ -body:not( - .state-product, - .state-price, - .state-discount, - .state-move, - .state-sold -) .styleItemBox { - padding: 0; margin: 0; -} -.styleItemBox { - opacity: 0; max-height: 0; - transform: translateX(-20px); - /* should do some tweeking for the below */ - transition: - opacity var(--baseAnimationLength), - max-height var(--baseAnimationLength) cubic-bezier(1,0,0,1), - padding var(--baseAnimationLength), - margin var(--baseAnimationLength), - transform var(--baseAnimationLength); - overflow: hidden; -} -body.state-product .styleItemBox, -body.state-price .styleItemBox, -body.state-discount .styleItemBox, -body.state-move .styleItemBox, -body.state-sold .styleItemBox { - opacity: 1; max-height: 50vh; - transform: translateX(0px); -} diff --git a/director/static/style/logo_box.css b/director/static/style/logo_box.css deleted file mode 100644 index c070292..0000000 --- a/director/static/style/logo_box.css +++ /dev/null @@ -1,23 +0,0 @@ -body:not( - .state-crawler, - .state-product -) .styleLogoBox { - padding: 0; margin: 0; -} -.styleLogoBox { - opacity: 0; max-height: 0; - transform: translateX(-20px); - /* should do some tweeking for the below */ - transition: - opacity var(--baseAnimationLength), - max-height var(--baseAnimationLength) cubic-bezier(1,0,0,1), - padding var(--baseAnimationLength), - margin var(--baseAnimationLength), - transform var(--baseAnimationLength); - overflow: hidden; -} -body.state-product .styleLogoBox, -body.state-crawler .styleLogoBox { - opacity: 1; max-height: 50vh; - transform: translateX(0px); -} diff --git a/director/static/style/pricing_box.css b/director/static/style/pricing_box.css deleted file mode 100644 index 57d2fff..0000000 --- a/director/static/style/pricing_box.css +++ /dev/null @@ -1,21 +0,0 @@ -body:not(.state-price, .state-discount, .state-move) .stylePricingBox { - padding: 0; margin: 0; -} -.stylePricingBox { - opacity: 0; max-height: 0; - transform: translateX(-20px); - /* should do some tweeking for the below */ - transition: - opacity var(--baseAnimationLength), - max-height var(--baseAnimationLength) cubic-bezier(1,0,0,1), - padding var(--baseAnimationLength), - margin var(--baseAnimationLength), - transform var(--baseAnimationLength); - overflow: hidden; -} -body.state-price .stylePricingBox, -body.state-discount .stylePricingBox, -body.state-move .stylePricingBox { - opacity: 1; max-height: 50vh; - transform: translateX(0px); -} diff --git a/director/static/style/qty_box.css b/director/static/style/qty_box.css deleted file mode 100644 index b774fa3..0000000 --- a/director/static/style/qty_box.css +++ /dev/null @@ -1,24 +0,0 @@ -.styleQtyBox { - font-size: 0.7em; -} - -body:not(.state-sold, .state-move) .styleQtyBox { - padding: 0; margin: 0; -} -.styleQtyBox { - opacity: 0; max-height: 0; - transform: translateX(-20px); - /* should do some tweeking for the below */ - transition: - opacity var(--baseAnimationLength), - max-height var(--baseAnimationLength) cubic-bezier(1,0,0,1), - padding var(--baseAnimationLength), - margin var(--baseAnimationLength), - transform var(--baseAnimationLength); - overflow: hidden; -} -body.state-sold .styleQtyBox, -body.state-move .styleQtyBox { - opacity: 1; max-height: 50vh; - transform: translateX(0px); -} diff --git a/director/static/style/show_until.css b/director/static/style/show_until.css deleted file mode 100644 index 451952f..0000000 --- a/director/static/style/show_until.css +++ /dev/null @@ -1,19 +0,0 @@ -.styleExpand.showUntil:not(.showUntil-showing) { - padding: 0; margin: 0; -} -.styleExpand.showUntil { - opacity: 0; max-height: 0; - transform: translateX(-20px); - /* should do some tweeking for the below */ - transition: - opacity var(--baseAnimationLength), - max-height var(--baseAnimationLength) cubic-bezier(1,0,0,1), - padding var(--baseAnimationLength), - margin var(--baseAnimationLength), - transform var(--baseAnimationLength); - overflow: hidden; -} -.styleExpand.showUntil.showUntil-showing { - opacity: 1; max-height: 50vh; - transform: translateX(0px); -} diff --git a/director/static/style/side_box.css b/director/static/style/side_box.css deleted file mode 100644 index 066842e..0000000 --- a/director/static/style/side_box.css +++ /dev/null @@ -1,12 +0,0 @@ -.styleSideBox { - width: var(--sideBoxWidth); - - display: flex; - flex-direction: column; - - margin: 50px; -} -.styleSideBox > * { - margin-bottom: 5px; - width: 100%; -} diff --git a/director/static/style/side_timer_box.css b/director/static/style/side_timer_box.css deleted file mode 100644 index dfd48d4..0000000 --- a/director/static/style/side_timer_box.css +++ /dev/null @@ -1,4 +0,0 @@ -.styleSideTimerBox { - display: inline; - width: fit-content !important; -} diff --git a/director/templates/admin.html b/director/templates/admin.html deleted file mode 100644 index 4c62a4e..0000000 --- a/director/templates/admin.html +++ /dev/null @@ -1,47 +0,0 @@ -{# - - builds the admin page - -#} - - - - - - - - - -
-

Admin

- -
- -
-
- - -
- - -
- - diff --git a/director/templates/admin/color.html b/director/templates/admin/color.html deleted file mode 100644 index 1ecd886..0000000 --- a/director/templates/admin/color.html +++ /dev/null @@ -1,6 +0,0 @@ - - - - {{ value }} - - diff --git a/director/templates/admin/float.html b/director/templates/admin/float.html deleted file mode 100644 index 12f8b00..0000000 --- a/director/templates/admin/float.html +++ /dev/null @@ -1,3 +0,0 @@ - - -{{ value }} diff --git a/director/templates/admin/number.html b/director/templates/admin/number.html deleted file mode 100644 index 7ffe0c7..0000000 --- a/director/templates/admin/number.html +++ /dev/null @@ -1,3 +0,0 @@ - - -{{ value }} diff --git a/director/templates/admin/text.html b/director/templates/admin/text.html deleted file mode 100644 index 3878cc8..0000000 --- a/director/templates/admin/text.html +++ /dev/null @@ -1,4 +0,0 @@ - - -{{ value }} - diff --git a/director/templates/admin/textarea.html b/director/templates/admin/textarea.html deleted file mode 100644 index a9ce85b..0000000 --- a/director/templates/admin/textarea.html +++ /dev/null @@ -1,4 +0,0 @@ - - diff --git a/director/templates/admin/trigger.html b/director/templates/admin/trigger.html deleted file mode 100644 index 322450d..0000000 --- a/director/templates/admin/trigger.html +++ /dev/null @@ -1,7 +0,0 @@ - - - - seconds delay (This does not update the triggered data.) - diff --git a/director/templates/index.html b/director/templates/index.html deleted file mode 100644 index af8760e..0000000 --- a/director/templates/index.html +++ /dev/null @@ -1,155 +0,0 @@ - - - - - - - {# ELEMENT STYLING IMPORTS #} - - - - - - - - - - - {# HELPER IMPORTS #} - - - - - - - - - - {# GLOBAL STYLING ELEMENTS #} - - - - - {# DYNAMIC STYLING ELEMENTS #} - - - - - - - - - - - - - - - - - - - - - - - - - - - {# SFX ELEMENTS #} - - - - - - {# CENTER SHOUT #} -
-
- -
-
- - {# SIDE BOX - includes (top to bottom): - - LOGO BOX (show during: crawler, product) - - BANNER BOX (show during: move, sold) - - ITEM BOX (show during: product, price, discount, move, sold) - - PRICING BOX (show during: price, discount, move) - - DISCOUNT BOX (show during: discount, move) - - BANNER SHOUT BOX (show AD) - - QTY BOX (show during: move, sold) - - TIMER 1 BOX (show AD) - - TIMER 2 BOX (show AD) - - these are switched on and off using the state class from the - body tag. - #} -
- - {# LOGO BOX #} -
- LOGO BOX -
- - {# BANNER BOX #} -
- BANNER BOX -
- - {# ITEM BOX #} -
-
- ITEM BOX -
-
- - {# PRICING BOX #} -
- PRICING BOX -
- - {# DISOUNT BOX #} -
- Now only... -
- - OFF! -
-
- - {# BANNER SHOUT BOX #} -
- -
- - {# QTY BOX #} -
- Sold: - ... - only - - LEFT -
- - {# TIMER BOX #} -
- TIMER 1! -
-
- TIMER 2! -
-
- - diff --git a/director/templates/info/a.html b/director/templates/info/a.html deleted file mode 100644 index fa6e8cc..0000000 --- a/director/templates/info/a.html +++ /dev/null @@ -1,33 +0,0 @@ - - - - - - - - - - -
- -
- -
- - - - -
- - diff --git a/director/templates/info/b.html b/director/templates/info/b.html deleted file mode 100644 index c06b48e..0000000 --- a/director/templates/info/b.html +++ /dev/null @@ -1,51 +0,0 @@ - - - - - - - - - - -
- - (was ) - - - - - left of - - total - - - - off - - - - full price - - - - Target: ( left to drop) - - - - Max: ( left to drop) - -
- - diff --git a/director/templates/info/c.html b/director/templates/info/c.html deleted file mode 100644 index b35ba79..0000000 --- a/director/templates/info/c.html +++ /dev/null @@ -1,36 +0,0 @@ - - - - - - - - - - -
- Current product:
- - Next product:
- - Current state: - - Next state: - - - T- - -
- - diff --git a/director/templates/table.html b/director/templates/table.html deleted file mode 100644 index 38b7a9e..0000000 --- a/director/templates/table.html +++ /dev/null @@ -1,98 +0,0 @@ -{# - - builds the admin page - -#} - - - - - - - - - -
-

Table: {{ table_name }}

-
- - - {% for row in table %} - - {# CREATE RADIO BUTTON FOR ROW #} - - - {% if loop.index0 == indexes["int--" ~ table_name] %} - - {% else %} - - {% endif %} - - - {# CREATE FEILDS #} - - {% set group = loop.index0 %} - {% for feild in row %} - - {# SELECT ELEMENT FROM TYPE #} - - {% set type, label = feild.split('--') %} - {% set value = row[feild] %} - {% set name = table_name ~ "~~" ~ group ~ "~~" ~ feild %} - - {% if type == "textarea" %} - {% include "admin/textarea.html" %} - {% elif type == "text" %} - {% include "admin/text.html" %} - {% elif type == "number" %} - {% include "admin/number.html" %} - {% elif type == "float" %} - {% include "admin/float.html" %} - {% elif type == "trigger" %} - {% include "admin/trigger.html" %} - {% elif type == "color" %} - {% include "admin/color.html" %} - {% endif %} - {% endfor %} - - - {% endfor %} - -
- - - Note: Tables are rendered statically, it is not safe to opperate the same interface in two places at once. -
- Processed {{ table|length * table[0]|length }} feilds in - {% if (time_taken * 1000)|round(2) > 20 %} - {{ (time_taken * 1000)|round(2) }}ms - {% else %} - {{ (time_taken * 1000)|round(2) }}ms - {% endif %} -
-
- - diff --git a/director/utils.py b/director/utils.py deleted file mode 100644 index d2fc032..0000000 --- a/director/utils.py +++ /dev/null @@ -1,10 +0,0 @@ -def deindex(data, indexes): - deindexed = {} - for key in data: - table, index, feild = key.split("~~") - if table != "indexes" and int(index) == indexes[f"int--{table}"]: - deindexed.update({ - f"{table}~~{feild}": data[key] - }) - - return deindexed diff --git a/tsconfig.json b/tsconfig.json index 3c138d2..747a9b3 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,9 +1,9 @@ { - "include": ["./director/src","./director/static"], + "include": ["./argo/src","./argo/static"], "compilerOptions": { - "rootDir": "./director/src", - "outDir": "./director/build", + "rootDir": "./argo/src", + "outDir": "./argo/build", "module": "esnext", "target": "esnext",