diff --git a/.idea/.gitignore b/.idea/.gitignore
deleted file mode 100644
index ab1f416..0000000
--- a/.idea/.gitignore
+++ /dev/null
@@ -1,10 +0,0 @@
-# Default ignored files
-/shelf/
-/workspace.xml
-# Ignored default folder with query files
-/queries/
-# Datasource local storage ignored files
-/dataSources/
-/dataSources.local.xml
-# Editor-based HTTP Client requests
-/httpRequests/
diff --git a/.idea/Pathl.Stona.iml b/.idea/Pathl.Stona.iml
new file mode 100644
index 0000000..024b922
--- /dev/null
+++ b/.idea/Pathl.Stona.iml
@@ -0,0 +1,21 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/Strona AI.iml b/.idea/Strona AI.iml
deleted file mode 100644
index a55366f..0000000
--- a/.idea/Strona AI.iml
+++ /dev/null
@@ -1,10 +0,0 @@
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/.idea/misc.xml b/.idea/misc.xml
index 3769195..6b805dc 100644
--- a/.idea/misc.xml
+++ b/.idea/misc.xml
@@ -1,7 +1,7 @@
-
+
-
+
\ No newline at end of file
diff --git a/.idea/modules.xml b/.idea/modules.xml
index 34f09f4..1653e50 100644
--- a/.idea/modules.xml
+++ b/.idea/modules.xml
@@ -2,7 +2,7 @@
-
+
\ No newline at end of file
diff --git a/.idea/vcs.xml b/.idea/vcs.xml
index 94a25f7..35eb1dd 100644
--- a/.idea/vcs.xml
+++ b/.idea/vcs.xml
@@ -1,6 +1,6 @@
-
+
\ No newline at end of file
diff --git a/.idea/workspace.xml b/.idea/workspace.xml
new file mode 100644
index 0000000..aadd831
--- /dev/null
+++ b/.idea/workspace.xml
@@ -0,0 +1,107 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 1769791641577
+
+
+ 1769791641577
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/__pycache__/app.cpython-313.pyc b/__pycache__/app.cpython-313.pyc
new file mode 100644
index 0000000..1af1a6c
Binary files /dev/null and b/__pycache__/app.cpython-313.pyc differ
diff --git a/apks/__pycache__/mk.cpython-313.pyc b/apks/__pycache__/mk.cpython-313.pyc
new file mode 100644
index 0000000..c341966
Binary files /dev/null and b/apks/__pycache__/mk.cpython-313.pyc differ
diff --git a/apks/mk.py b/apks/mk.py
new file mode 100644
index 0000000..6cddd28
--- /dev/null
+++ b/apks/mk.py
@@ -0,0 +1,5 @@
+def add(a, b):
+ return a + b
+
+def sub(a, b):
+ return a - b
diff --git a/app.py b/app.py
index 72eb3fb..9a658a4 100644
--- a/app.py
+++ b/app.py
@@ -1,17 +1,27 @@
-from flask import Flask, request, render_template, jsonify, send_from_directory
-import os, json, importlib.util
-from werkzeug.utils import secure_filename
-import markdown
-app = Flask(__name__)
-UPLOAD_FOLDER = "models"
-os.makedirs(UPLOAD_FOLDER, exist_ok=True)
-ADMIN_KEY = "supersecretadminkey"
+from flask import Flask, request, render_template, jsonify, send_file
+import os, json, importlib, importlib.util, sys, re
+from markdown import markdown
+app = Flask(__name__)
+
+# FOLDERS
+UPLOAD_FOLDER = "scripts"
+MODELS_FOLDER = "models"
+APKS_FOLDER = "apks"
+os.makedirs(UPLOAD_FOLDER, exist_ok=True)
+os.makedirs(MODELS_FOLDER, exist_ok=True)
+sys.path.insert(0, os.path.join(os.getcwd(), APKS_FOLDER))
+
+# GLOBAL MODELS
MODELS = {}
+# ---- Load models at startup ----
def load_models():
- for folder in os.listdir(UPLOAD_FOLDER):
- path = os.path.join(UPLOAD_FOLDER, folder)
+ global MODELS
+ MODELS = {}
+
+ for folder in os.listdir(MODELS_FOLDER):
+ path = os.path.join(MODELS_FOLDER, folder)
if not os.path.isdir(path):
continue
meta_path = os.path.join(path, "meta.json")
@@ -38,7 +48,8 @@ def load_models():
load_models()
-# ---- DASHBOARD ----
+
+# ---------------- DASHBOARD ----------------
@app.route("/")
def dashboard():
models_with_md = {}
@@ -47,16 +58,81 @@ def dashboard():
try:
md_path = os.path.join(model["path"], model["meta"]["description_file"])
with open(md_path, "r", encoding="utf-8") as f:
- md_text = f.read()
- # konwersja Markdown -> HTML
- md_content = markdown.markdown(md_text)
- except Exception:
+ md_content = markdown(f.read())
+ except:
md_content = "
Brak opisu.
"
-
models_with_md[name] = {**model, "md_content": md_content}
return render_template("user.html", models=models_with_md)
-# ---- PREDICT ----
+
+
+# ---------------- EDITOR ----------------
+@app.route("/editor/")
+def editor(model_name):
+ return render_template("editor.html", model_name=model_name)
+
+
+# ---------------- RUN SCRIPT (MKScript) ----------------
+@app.route("/run_script", methods=["POST"])
+def run_script():
+ code = request.json.get("code", "")
+ output = []
+ variables = {}
+ modules = {}
+
+ try:
+ lines = code.split(";")
+ for line in lines:
+ line = line.strip()
+ if not line:
+ continue
+
+ # use mk
+ if line.startswith("use "):
+ name = line.split()[1]
+ mod = importlib.import_module(name)
+ modules[name] = mod
+ variables[name] = mod
+ continue
+
+ # print(...)
+ if line.startswith("print"):
+ inside = line[line.find("(")+1:line.rfind(")")]
+ output.append(str(eval_expr(inside, variables)))
+ continue
+
+ # typy int/float/bool
+ if any(line.startswith(t) for t in ["int ", "float ", "bool "]):
+ _, rest = line.split(" ", 1)
+ var, expr = rest.split("=")
+ variables[var.strip()] = eval_expr(expr.strip(), variables)
+ continue
+
+ # wywołanie funkcji np mk.add(1,2)
+ if "." in line and "(" in line:
+ obj, rest = line.split(".", 1)
+ fname = rest[:rest.find("(")]
+ args = rest[rest.find("(")+1:rest.find(")")]
+ args = [eval_expr(a.strip(), variables) for a in args.split(",")]
+ result = getattr(modules[obj], fname)(*args)
+ variables["_"] = result
+ continue
+
+ except Exception as e:
+ return jsonify({"error": str(e)})
+
+ return jsonify({
+ "output": output,
+ "variables": {k: str(v) for k, v in variables.items()}
+ })
+
+
+def eval_expr(expr, variables):
+ expr = expr.replace("true", "True").replace("false", "False")
+ return eval(expr, {}, variables)
+
+
+# ---------------- PREDICT ----------------
@app.route("/predict/", methods=["POST"])
def predict(model_name):
model_entry = MODELS.get(model_name)
@@ -65,9 +141,7 @@ def predict(model_name):
func = model_entry["func"]
inputs = model_entry["inputs"]
- kwargs = {}
- for inp in inputs:
- kwargs[inp] = request.form.get(inp)
+ kwargs = {inp: request.form.get(inp) for inp in inputs}
try:
for k in kwargs:
@@ -81,64 +155,28 @@ def predict(model_name):
return jsonify({"output": str(output)})
-# ---- ADD MODEL ----
-@app.route("/add_model", methods=["POST"])
-def add_model():
- admin_key = request.form.get("admin_key")
- if admin_key != ADMIN_KEY:
- return "Brak dostępu", 403
- name = request.form["name"]
- function_name = request.form["function_name"]
- inputs = request.form.getlist("inputs")
- model_py = request.files["model_py"]
- description_file = request.files["description"]
+# ---------------- DOWNLOAD SCRIPT ----------------
+@app.route("/download_script/")
+def download_script(filename):
+ path = os.path.join(UPLOAD_FOLDER, filename)
+ if os.path.exists(path):
+ return send_file(path, as_attachment=True)
+ return "Plik nie istnieje", 404
- folder_name = secure_filename(name)
- folder_path = os.path.join(UPLOAD_FOLDER, folder_name)
- os.makedirs(folder_path, exist_ok=True)
- # zapis plików
- model_py.save(os.path.join(folder_path, "model.py"))
- description_file.save(os.path.join(folder_path, "description.md"))
+# ---------------- UPLOAD SCRIPT ----------------
+@app.route("/upload_script", methods=["POST"])
+def upload_script():
+ file = request.files.get("file")
+ if not file:
+ return "Nie przesłano pliku", 400
+ filename = file.filename
+ path = os.path.join(UPLOAD_FOLDER, filename)
+ file.save(path)
+ return "OK"
- # meta.json
- meta = {
- "name": name,
- "function_name": function_name,
- "inputs": inputs,
- "description_file": "description.md",
- "downloadable": True, # można pobrać pliki
- "type": request.form.get("type", "algorithmic")
- }
- with open(os.path.join(folder_path, "meta.json"), "w") as f:
- json.dump(meta, f)
-
- # załaduj od razu
- spec = importlib.util.spec_from_file_location("model_module", os.path.join(folder_path, "model.py"))
- module = importlib.util.module_from_spec(spec)
- spec.loader.exec_module(module)
- func = getattr(module, function_name)
-
- MODELS[folder_name] = {
- "func": func,
- "inputs": inputs,
- "meta": meta,
- "path": folder_path
- }
-
- return "Dodano model!"
-
-# ---- DOWNLOAD FILE ----
-@app.route("/download//")
-def download_file(model_name, file_name):
- model_entry = MODELS.get(model_name)
- if not model_entry:
- return "Model nie istnieje", 404
- folder_path = model_entry["path"]
- if file_name not in ["model.py", "description.md", "meta.json"]:
- return "Nieprawidłowy plik", 400
- return send_from_directory(folder_path, file_name, as_attachment=True)
+# ---------------- MAIN ----------------
if __name__ == "__main__":
- app.run(debug=True)
+ app.run(port=4500)
diff --git a/interpreter.py b/interpreter.py
new file mode 100644
index 0000000..57c2a0d
--- /dev/null
+++ b/interpreter.py
@@ -0,0 +1,73 @@
+import re, importlib
+
+variables = {}
+modules = {}
+functions = {}
+
+# Rejestracja “handlerów” dla linii
+handlers = []
+
+def eval_expr(expr):
+ """Bezpieczne obliczanie wyrażeń z użyciem zmiennych"""
+ expr = expr.replace("true", "True").replace("false", "False")
+ return eval(expr, {}, variables)
+
+def handle_use(line):
+ if line.startswith("use "):
+ name = line.split()[1]
+ modules[name] = importlib.import_module(f"apks.{name}")
+ variables[name] = modules[name]
+ return True
+ return False
+
+def handle_print(line):
+ if line.startswith("print"):
+ inside = re.search(r"\((.*)\)", line).group(1)
+ print(eval_expr(inside))
+ return True
+ return False
+
+def handle_var(line):
+ for t in ["int ", "float ", "bool ", "string "]:
+ if line.startswith(t):
+ _, rest = line.split(" ", 1)
+ var, expr = rest.split("=")
+ val = expr.strip()
+ if t.strip() == "string":
+ val = val.strip('"').strip("'")
+ else:
+ val = eval_expr(val)
+ variables[var.strip()] = val
+ return True
+ return False
+
+def handle_func_call(line):
+ if "." in line and "(" in line:
+ obj, rest = line.split(".", 1)
+ fname = rest[:rest.find("(")]
+ args_str = rest[rest.find("(")+1:rest.rfind(")")]
+ args = [eval_expr(a.strip()) for a in args_str.split(",") if a.strip()]
+ result = getattr(modules[obj], fname)(*args)
+ variables["_"] = result # ostatni wynik
+ return True
+ return False
+
+# Dodajemy wszystkie handlery do listy
+handlers.extend([handle_use, handle_print, handle_var, handle_func_call])
+
+def run(code):
+ """Interpreter MKScript"""
+ lines = code.split(";")
+ for line in lines:
+ line = line.strip()
+ if not line or line.startswith("//"): # komentarze
+ continue
+
+ # uruchamiamy wszystkie handlery aż któryś obsłuży linię
+ handled = False
+ for h in handlers:
+ if h(line):
+ handled = True
+ break
+ if not handled:
+ print(f"Nieznana linia: {line}")
diff --git a/models/Power/__pycache__/model.cpython-313.pyc b/models/Power/__pycache__/model.cpython-313.pyc
index ecf8832..00addeb 100644
Binary files a/models/Power/__pycache__/model.cpython-313.pyc and b/models/Power/__pycache__/model.cpython-313.pyc differ
diff --git a/static/style.css b/static/style.css
index 32ef883..087bb67 100644
--- a/static/style.css
+++ b/static/style.css
@@ -1,4 +1,6 @@
-/* Reset podstawowy */
+/* =========================
+ RESET PODSTAWOWY
+========================= */
* {
margin: 0;
padding: 0;
@@ -6,14 +8,18 @@
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
}
-/* Body */
+/* =========================
+ BODY
+========================= */
body {
background: #f4f7fc;
color: #333;
padding: 20px;
}
-/* Nagłówek */
+/* =========================
+ NAGŁÓWEK
+========================= */
h2 {
text-align: center;
margin-bottom: 30px;
@@ -21,20 +27,26 @@ h2 {
font-size: 2em;
}
-/* Kontener modeli */
+/* =========================
+ KONTENER MODELI
+========================= */
#models-container {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(320px, 1fr));
gap: 20px;
}
-/* Karta modelu */
+/* =========================
+ KARTA MODELU
+========================= */
.model-card {
+ position: relative;
background: #ffffff;
border-radius: 15px;
padding: 20px;
box-shadow: 0 6px 18px rgba(0,0,0,0.08);
transition: transform 0.2s, box-shadow 0.2s;
+ overflow: hidden;
}
.model-card:hover {
@@ -42,7 +54,76 @@ h2 {
box-shadow: 0 12px 24px rgba(0,0,0,0.12);
}
-/* Nazwa modelu */
+/* =========================
+ 3 KROPKI (MENU)
+========================= */
+.menu-btn {
+ position: absolute;
+ top: 12px;
+ right: 14px;
+ cursor: pointer;
+ font-size: 22px;
+ color: #777;
+ user-select: none;
+}
+
+.menu-btn:hover {
+ color: #000;
+}
+
+/* =========================
+ BOCZNY PANEL (SLIDE)
+========================= */
+.side-menu {
+ position: absolute;
+ top: 0;
+ right: -260px;
+ width: 250px;
+ height: 100%;
+ background: #111;
+ color: #fff;
+ padding: 20px;
+ transition: right 0.3s ease;
+ z-index: 20;
+ display: flex;
+ flex-direction: column;
+ gap: 10px;
+}
+
+.side-menu.open {
+ right: 0;
+}
+
+.side-menu h4 {
+ margin-bottom: 10px;
+ border-bottom: 1px solid #333;
+ padding-bottom: 5px;
+}
+
+.side-menu input {
+ padding: 8px;
+ border-radius: 6px;
+ border: none;
+ font-size: 0.9em;
+}
+
+.side-menu button {
+ padding: 8px;
+ border-radius: 8px;
+ border: none;
+ cursor: pointer;
+ font-weight: bold;
+ background: #6c63ff;
+ color: white;
+}
+
+.side-menu button:hover {
+ background: #574fd6;
+}
+
+/* =========================
+ NAZWA MODELU
+========================= */
.model-card h3 {
margin-bottom: 15px;
color: #1a1a1a;
@@ -51,7 +132,9 @@ h2 {
padding-bottom: 5px;
}
-/* Opis modelu (.md) */
+/* =========================
+ OPIS MODELU (Markdown)
+========================= */
.description {
font-style: italic;
color: #555;
@@ -59,7 +142,9 @@ h2 {
line-height: 1.5;
}
-/* Formularz */
+/* =========================
+ FORMULARZ
+========================= */
form.predict-form {
display: flex;
flex-direction: column;
@@ -84,7 +169,9 @@ form.predict-form input:focus {
outline: none;
}
-/* Przycisk */
+/* =========================
+ PRZYCISK
+========================= */
form.predict-form button {
padding: 10px 15px;
background: #6c63ff;
@@ -101,14 +188,18 @@ form.predict-form button:hover {
transform: translateY(-2px);
}
-/* Output */
+/* =========================
+ OUTPUT
+========================= */
.output {
margin-top: 10px;
font-weight: bold;
color: #1a73e8;
}
-/* Download linki */
+/* =========================
+ DOWNLOAD
+========================= */
.download {
margin-top: 15px;
font-size: 0.9em;
@@ -126,7 +217,9 @@ form.predict-form button:hover {
text-decoration: underline;
}
-/* Linie oddzielające karty */
+/* =========================
+ LINIE
+========================= */
hr {
border: none;
height: 1px;
@@ -134,7 +227,9 @@ hr {
margin: 20px 0;
}
-/* Responsywność */
+/* =========================
+ RESPONSYWNOŚĆ
+========================= */
@media (max-width: 600px) {
h2 {
font-size: 1.5em;
@@ -144,7 +239,18 @@ hr {
padding: 15px;
}
- form.predict-form input, form.predict-form button {
+ form.predict-form input,
+ form.predict-form button {
font-size: 0.9em;
}
}
+.side-menu {
+ pointer-events: none;
+}
+
+.side-menu.open {
+ pointer-events: auto;
+}
+.side-menu {
+ position: fixed;
+}
diff --git a/templates/editor.html b/templates/editor.html
new file mode 100644
index 0000000..0df8cb8
--- /dev/null
+++ b/templates/editor.html
@@ -0,0 +1,169 @@
+
+
+
+
+MKScript Editor – {{model_name}}
+
+
+
+
+
+
+
+
+
+MKScript Editor – {{model_name}}
+
+
+
+
+
+
+
+
+
← Wróć
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/templates/user.html b/templates/user.html
index e22d990..73f1fed 100644
--- a/templates/user.html
+++ b/templates/user.html
@@ -1,42 +1,71 @@
-
+
+
AI Models
-
-
+
+
Lista modeli AI
+
- {% for name, model in models.items() %}
-
-
{{name}}
-
- {{ model.md_content | safe }}
-
+{% for name, model in models.items() %}
+
+
+
-
-
- {% if model.meta.downloadable %}
-
- {% endif %}
+
+
+
+
+
+
+ {% if model.meta.downloadable %}
+
-
- {% endfor %}
+ {% endif %}
+
+
+{% endfor %}
+