From 9d3b42a300ba1f994fc8bc46a585f78207651904 Mon Sep 17 00:00:00 2001 From: Alex Wellnitz Date: Thu, 19 Sep 2024 12:24:21 +0200 Subject: [PATCH] feat: init commit --- .gitignore | 5 + README.md | 14 ++ main.py | 63 +++++++++ templates/index.html | 222 ++++++++++++++++++++++++++++++++ templates/static/color-modes.js | 92 +++++++++++++ templates/static/main.js | 3 + templates/static/styles.css | 86 +++++++++++++ 7 files changed, 485 insertions(+) create mode 100644 .gitignore create mode 100644 README.md create mode 100644 main.py create mode 100644 templates/index.html create mode 100644 templates/static/color-modes.js create mode 100644 templates/static/main.js create mode 100644 templates/static/styles.css diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..31546f0 --- /dev/null +++ b/.gitignore @@ -0,0 +1,5 @@ +.venv/ +__pycache__/ +results/ +profiles/ +simc/ diff --git a/README.md b/README.md new file mode 100644 index 0000000..b47635a --- /dev/null +++ b/README.md @@ -0,0 +1,14 @@ +# SIM Free + +## Description + +### Installation +```bash +python -m venv .venv +source .venv/bin/activate +``` + +### Run +```bash +fastapi run main.py +``` diff --git a/main.py b/main.py new file mode 100644 index 0000000..e06da60 --- /dev/null +++ b/main.py @@ -0,0 +1,63 @@ +import os +import logging +import uuid +from simcrunner import Simc, JsonExport, Arguments, Profile + +from typing import Union, Annotated +from fastapi import FastAPI, Form +from fastapi.staticfiles import StaticFiles +from pydantic import BaseModel +from starlette.responses import FileResponse +from simcrunner.simc import HtmlExport + +# SIMC Settings +logging.basicConfig(level=logging.INFO) +simc_path = os.path.join('tests', 'simc') +runner = Simc(simc_path=simc_path) + +app = FastAPI() +app.mount("/static", StaticFiles(directory="templates/static"), name="static") + +# ROUTES +@app.get("/") +def read_root(): + index_path = os.path.join('templates', 'index.html') + return FileResponse(index_path) + +@app.post("/sim/current_gear") +async def simulate_current_gear(simcprofile: Annotated[str, Form()]): + + sim_args = create_sim_arguments(simcprofile) + export_path = create_html_export() + html_export = HtmlExport(export_path) + + (runner + .add_args(sim_args) + .add_args('target_error=0.05', threads=4) + .add_args(html_export) + .run()) + + return FileResponse(export_path) + +# HELPER Functions +def create_profile(profile_path: str, profile_data: str): + with open(profile_path, 'w') as file: + # Write content to the file + file.write(profile_data) + +def create_html_export(): + rand_uuid = uuid.uuid4() + export_path = os.path.join('results', str(rand_uuid)+'.html') + + return export_path + +def create_sim_arguments(profile_data: str): + rand_uuid = uuid.uuid4() + profile_path = os.path.join('profiles', str(rand_uuid)+'.simc') + + create_profile(profile_path, profile_data) + + profile = Profile(profile_path) + args = Arguments(profile, iterations=1000) + + return args diff --git a/templates/index.html b/templates/index.html new file mode 100644 index 0000000..7a435a5 --- /dev/null +++ b/templates/index.html @@ -0,0 +1,222 @@ + + + + + + SIM-Free + + + + + + + + + + + +
+
+
+ +

Simulate form

+

+ Copy/paste the text from the SimulationCraft addon. +

+
+ +
+
+

Sim Data

+
+
+
+
+ + +
+
+
+ +
+ +
+
+
+
+
+ + +
+ + + + diff --git a/templates/static/color-modes.js b/templates/static/color-modes.js new file mode 100644 index 0000000..059a140 --- /dev/null +++ b/templates/static/color-modes.js @@ -0,0 +1,92 @@ +/*! + * Color mode toggler for Bootstrap's docs (https://getbootstrap.com/) + * Copyright 2011-2024 The Bootstrap Authors + * Licensed under the Creative Commons Attribution 3.0 Unported License. + */ + +(() => { + "use strict"; + + const getStoredTheme = () => localStorage.getItem("theme"); + const setStoredTheme = (theme) => localStorage.setItem("theme", theme); + + const getPreferredTheme = () => { + const storedTheme = getStoredTheme(); + if (storedTheme) { + return storedTheme; + } + + return window.matchMedia("(prefers-color-scheme: dark)").matches + ? "dark" + : "light"; + }; + + const setTheme = (theme) => { + if (theme === "auto") { + document.documentElement.setAttribute( + "data-bs-theme", + window.matchMedia("(prefers-color-scheme: dark)").matches + ? "dark" + : "light", + ); + } else { + document.documentElement.setAttribute("data-bs-theme", theme); + } + }; + + setTheme(getPreferredTheme()); + + const showActiveTheme = (theme, focus = false) => { + const themeSwitcher = document.querySelector("#bd-theme"); + + if (!themeSwitcher) { + return; + } + + const themeSwitcherText = document.querySelector("#bd-theme-text"); + const activeThemeIcon = document.querySelector(".theme-icon-active use"); + const btnToActive = document.querySelector( + `[data-bs-theme-value="${theme}"]`, + ); + const svgOfActiveBtn = btnToActive + .querySelector("svg use") + .getAttribute("href"); + + document.querySelectorAll("[data-bs-theme-value]").forEach((element) => { + element.classList.remove("active"); + element.setAttribute("aria-pressed", "false"); + }); + + btnToActive.classList.add("active"); + btnToActive.setAttribute("aria-pressed", "true"); + activeThemeIcon.setAttribute("href", svgOfActiveBtn); + const themeSwitcherLabel = `${themeSwitcherText.textContent} (${btnToActive.dataset.bsThemeValue})`; + themeSwitcher.setAttribute("aria-label", themeSwitcherLabel); + + if (focus) { + themeSwitcher.focus(); + } + }; + + window + .matchMedia("(prefers-color-scheme: dark)") + .addEventListener("change", () => { + const storedTheme = getStoredTheme(); + if (storedTheme !== "light" && storedTheme !== "dark") { + setTheme(getPreferredTheme()); + } + }); + + window.addEventListener("DOMContentLoaded", () => { + showActiveTheme(getPreferredTheme()); + + document.querySelectorAll("[data-bs-theme-value]").forEach((toggle) => { + toggle.addEventListener("click", () => { + const theme = toggle.getAttribute("data-bs-theme-value"); + setStoredTheme(theme); + setTheme(theme); + showActiveTheme(theme, true); + }); + }); + }); +})(); diff --git a/templates/static/main.js b/templates/static/main.js new file mode 100644 index 0000000..fc5b111 --- /dev/null +++ b/templates/static/main.js @@ -0,0 +1,3 @@ +// +// Place any custom JS here +// diff --git a/templates/static/styles.css b/templates/static/styles.css new file mode 100644 index 0000000..7980e26 --- /dev/null +++ b/templates/static/styles.css @@ -0,0 +1,86 @@ +/* + * Custom CSS + */ + +:root { + --bs-body-bg: var(--bs-gray-100); +} + +.bd-placeholder-img { + font-size: 1.125rem; + text-anchor: middle; + -webkit-user-select: none; + -moz-user-select: none; + user-select: none; +} + +@media (min-width: 768px) { + .bd-placeholder-img-lg { + font-size: 3.5rem; + } +} + +.b-example-divider { + width: 100%; + height: 3rem; + background-color: rgba(0, 0, 0, 0.1); + border: solid rgba(0, 0, 0, 0.15); + border-width: 1px 0; + box-shadow: + inset 0 0.5em 1.5em rgba(0, 0, 0, 0.1), + inset 0 0.125em 0.5em rgba(0, 0, 0, 0.15); +} + +.b-example-vr { + flex-shrink: 0; + width: 1.5rem; + height: 100vh; +} + +.bi { + vertical-align: -0.125em; + fill: currentColor; +} + +.nav-scroller { + position: relative; + z-index: 2; + height: 2.75rem; + overflow-y: hidden; +} + +.nav-scroller .nav { + display: flex; + flex-wrap: nowrap; + padding-bottom: 1rem; + margin-top: -1px; + overflow-x: auto; + text-align: center; + white-space: nowrap; + -webkit-overflow-scrolling: touch; +} + +.btn-bd-primary { + --bd-violet-bg: #712cf9; + --bd-violet-rgb: 112.520718, 44.062154, 249.437846; + + --bs-btn-font-weight: 600; + --bs-btn-color: var(--bs-white); + --bs-btn-bg: var(--bd-violet-bg); + --bs-btn-border-color: var(--bd-violet-bg); + --bs-btn-hover-color: var(--bs-white); + --bs-btn-hover-bg: #6528e0; + --bs-btn-hover-border-color: #6528e0; + --bs-btn-focus-shadow-rgb: var(--bd-violet-rgb); + --bs-btn-active-color: var(--bs-btn-hover-color); + --bs-btn-active-bg: #5a23c8; + --bs-btn-active-border-color: #5a23c8; +} + +.bd-mode-toggle { + z-index: 1500; +} + +.bd-mode-toggle .dropdown-menu .active .bi { + display: block !important; +}