mirror of
https://github.com/karl0ss/ai_image_frame_server.git
synced 2025-06-07 19:15:08 +01:00
basic working auth for create_image page
This commit is contained in:
parent
0fc549c199
commit
1a0542861c
1
.gitignore
vendored
1
.gitignore
vendored
@ -9,3 +9,4 @@ output/
|
||||
prompts_log.jsonl
|
||||
publish.sh
|
||||
test.py
|
||||
.vscode/launch.json
|
||||
|
@ -5,23 +5,34 @@ from flask import (
|
||||
request,
|
||||
jsonify,
|
||||
redirect,
|
||||
url_for
|
||||
url_for,
|
||||
session,
|
||||
render_template_string,
|
||||
)
|
||||
import os
|
||||
import time
|
||||
import threading
|
||||
from apscheduler.schedulers.background import BackgroundScheduler
|
||||
from libs.generic import load_config, load_recent_prompts, get_details_from_png, get_current_version, load_models_from_config
|
||||
from libs.generic import (
|
||||
load_config,
|
||||
load_recent_prompts,
|
||||
get_details_from_png,
|
||||
get_current_version,
|
||||
load_models_from_config,
|
||||
)
|
||||
from libs.comfyui import cancel_current_job, create_image, select_model
|
||||
from libs.ollama import create_prompt_on_openwebui
|
||||
|
||||
#workflow test commit
|
||||
# workflow test commit
|
||||
|
||||
user_config = load_config()
|
||||
|
||||
app = Flask(__name__)
|
||||
app.secret_key = os.environ.get('SECRET_KEY')
|
||||
|
||||
image_folder = "./output"
|
||||
|
||||
|
||||
@app.route("/", methods=["GET"])
|
||||
def index() -> str:
|
||||
"""
|
||||
@ -39,18 +50,34 @@ def index() -> str:
|
||||
image=image_filename,
|
||||
prompt=prompt,
|
||||
reload_interval=user_config["frame"]["reload_interval"],
|
||||
version=version
|
||||
version=version,
|
||||
)
|
||||
|
||||
|
||||
@app.route('/login', methods=['GET', 'POST'])
|
||||
def login():
|
||||
if request.method == 'POST':
|
||||
if request.form['password'] == user_config["frame"]["password_for_auth"]:
|
||||
session['authenticated'] = True
|
||||
return render_template("create_image.html", models=load_models_from_config())
|
||||
else:
|
||||
return redirect(url_for('login'))
|
||||
return render_template('login.html')
|
||||
|
||||
|
||||
@app.route("/images", methods=["GET"])
|
||||
def gallery() -> str:
|
||||
images = []
|
||||
for f in os.listdir(image_folder):
|
||||
if f.lower().endswith(('png', 'jpg', 'jpeg', 'gif')):
|
||||
images.append({'filename': f})
|
||||
images = sorted(images, key=lambda x: os.path.getmtime(os.path.join(image_folder, x['filename'])), reverse=True)
|
||||
if f.lower().endswith(("png", "jpg", "jpeg", "gif")):
|
||||
images.append({"filename": f})
|
||||
images = sorted(
|
||||
images,
|
||||
key=lambda x: os.path.getmtime(os.path.join(image_folder, x["filename"])),
|
||||
reverse=True,
|
||||
)
|
||||
return render_template("gallery.html", images=images)
|
||||
|
||||
|
||||
|
||||
@app.route("/image-details/<filename>", methods=["GET"])
|
||||
def image_details(filename):
|
||||
@ -58,16 +85,12 @@ def image_details(filename):
|
||||
if not os.path.exists(path):
|
||||
return {"error": "File not found"}, 404
|
||||
details = get_details_from_png(path)
|
||||
return {
|
||||
"prompt": details["p"],
|
||||
"model": details["m"],
|
||||
"date": details["d"]
|
||||
}
|
||||
|
||||
return {"prompt": details["p"], "model": details["m"], "date": details["d"]}
|
||||
|
||||
@app.route('/images/thumbnails/<path:filename>')
|
||||
|
||||
@app.route("/images/thumbnails/<path:filename>")
|
||||
def serve_thumbnail(filename):
|
||||
return send_from_directory('output/thumbnails', filename)
|
||||
return send_from_directory("output/thumbnails", filename)
|
||||
|
||||
|
||||
@app.route("/images/<filename>", methods=["GET"])
|
||||
@ -105,8 +128,10 @@ def create():
|
||||
|
||||
# Start generation in background
|
||||
threading.Thread(target=lambda: create_image(prompt, model)).start()
|
||||
|
||||
return redirect(url_for("image_queued", prompt=prompt, model=model.split(".")[0]))
|
||||
|
||||
return redirect(
|
||||
url_for("image_queued", prompt=prompt, model=model.split(".")[0])
|
||||
)
|
||||
|
||||
# For GET requests, just show the form to enter prompt
|
||||
return render_template("create_image.html", models=load_models_from_config())
|
||||
@ -118,23 +143,23 @@ def image_queued():
|
||||
model = request.args.get("model", "No model selected.").split(".")[0]
|
||||
return render_template("image_queued.html", prompt=prompt, model=model)
|
||||
|
||||
|
||||
def scheduled_task() -> None:
|
||||
"""Executes the scheduled image generation task."""
|
||||
print(f"Executing scheduled task at {time.strftime('%Y-%m-%d %H:%M:%S')}")
|
||||
create_image(None)
|
||||
|
||||
|
||||
@app.route("/create_image", methods=["GET"])
|
||||
def create_image_endpoint() -> str:
|
||||
"""
|
||||
Renders the create image template with image and prompt.
|
||||
"""
|
||||
|
||||
if user_config["frame"]["create_requires_auth"] == "True" and not session.get('authenticated'):
|
||||
return redirect(url_for("login"))
|
||||
models = load_models_from_config()
|
||||
|
||||
return render_template(
|
||||
"create_image.html", models=models
|
||||
)
|
||||
|
||||
return render_template("create_image.html", models=models)
|
||||
|
||||
|
||||
if user_config["frame"]["auto_regen"] == "True":
|
||||
@ -148,10 +173,9 @@ if user_config["frame"]["auto_regen"] == "True":
|
||||
minute=regen_time[1],
|
||||
id="scheduled_task",
|
||||
max_instances=1, # prevent overlapping
|
||||
replace_existing=True # don't double-schedule
|
||||
replace_existing=True, # don't double-schedule
|
||||
)
|
||||
scheduler.start()
|
||||
|
||||
os.makedirs(image_folder, exist_ok=True)
|
||||
app.run(host="0.0.0.0", port=user_config["frame"]["port"], debug=True)
|
||||
|
||||
|
72
templates/login.html
Normal file
72
templates/login.html
Normal file
@ -0,0 +1,72 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Login</title>
|
||||
<style>
|
||||
* {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
body {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
height: 100vh;
|
||||
background: black;
|
||||
color: white;
|
||||
font-family: Arial, sans-serif;
|
||||
padding: 20px;
|
||||
text-align: center;
|
||||
}
|
||||
.message {
|
||||
font-size: 22px;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
.prompt-text {
|
||||
font-size: 20px;
|
||||
background: #111;
|
||||
padding: 20px;
|
||||
border-radius: 10px;
|
||||
border: 1px solid #333;
|
||||
max-width: 80vw;
|
||||
margin-bottom: 30px;
|
||||
}
|
||||
input[type="password"] {
|
||||
padding: 10px;
|
||||
border-radius: 8px;
|
||||
border: 1px solid #555;
|
||||
background: #222;
|
||||
color: white;
|
||||
font-size: 16px;
|
||||
margin-bottom: 20px;
|
||||
width: 250px;
|
||||
}
|
||||
button {
|
||||
background: #333;
|
||||
color: white;
|
||||
border: none;
|
||||
padding: 10px 20px;
|
||||
border-radius: 8px;
|
||||
font-size: 16px;
|
||||
cursor: pointer;
|
||||
transition: background 0.3s;
|
||||
}
|
||||
button:hover {
|
||||
background: #555;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="message">Please enter the password to continue:</div>
|
||||
<form method="post">
|
||||
<div class="prompt-text">
|
||||
<input type="password" name="password" placeholder="Password" required>
|
||||
</div>
|
||||
<button type="submit">Login</button>
|
||||
</form>
|
||||
</body>
|
||||
</html>
|
@ -3,6 +3,8 @@ reload_interval = 30000
|
||||
auto_regen = True
|
||||
regen_time = 03:00
|
||||
port = 5000
|
||||
create_requires_auth = False
|
||||
password_for_auth = create
|
||||
|
||||
[comfyui]
|
||||
comfyui_url = http://comfyui
|
||||
|
Loading…
x
Reference in New Issue
Block a user