Compare commits
No commits in common. "86de43678c05c9543c3dc85218363098c64d930a" and "61cf469d80a80d47418228d2b3a2ccafe168932d" have entirely different histories.
86de43678c
...
61cf469d80
6 changed files with 6 additions and 123 deletions
10
startup.sh
10
startup.sh
|
@ -22,10 +22,6 @@ cd "$(dirname "$0")"
|
||||||
# Activate virtual environment
|
# Activate virtual environment
|
||||||
source venv/bin/activate
|
source venv/bin/activate
|
||||||
|
|
||||||
# Read the environment mode
|
|
||||||
ENV_MODE=${KEMOVERSE_ENV:-prod}
|
|
||||||
echo "Running in '$ENV_MODE' mode..."
|
|
||||||
|
|
||||||
# Start the bot
|
# Start the bot
|
||||||
echo "Starting bot..."
|
echo "Starting bot..."
|
||||||
python3 bot/bot_app.py &
|
python3 bot/bot_app.py &
|
||||||
|
@ -35,11 +31,7 @@ BOT_PID=$!
|
||||||
|
|
||||||
# Start the website
|
# Start the website
|
||||||
echo "Starting web server..."
|
echo "Starting web server..."
|
||||||
if [ "$ENV_MODE" = "dev" ]; then
|
python3 web/app.py &
|
||||||
python3 web/app.py &
|
|
||||||
else
|
|
||||||
gunicorn -w 4 -b 127.0.0.1:8000 web.wsgi:app &
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Save the web PID too
|
# Save the web PID too
|
||||||
WEB_PID=$!
|
WEB_PID=$!
|
||||||
|
|
10
web/app.py
10
web/app.py
|
@ -28,7 +28,7 @@ from werkzeug.exceptions import HTTPException
|
||||||
app = Flask(__name__)
|
app = Flask(__name__)
|
||||||
|
|
||||||
def get_db_connection():
|
def get_db_connection():
|
||||||
conn = sqlite3.connect(config.DB_PATH, check_same_thread=False)
|
conn = sqlite3.connect(config.DB_PATH)
|
||||||
conn.row_factory = sqlite3.Row
|
conn.row_factory = sqlite3.Row
|
||||||
return conn
|
return conn
|
||||||
|
|
||||||
|
@ -108,9 +108,5 @@ def player_list():
|
||||||
return render_template('player_list.html', players=[])
|
return render_template('player_list.html', players=[])
|
||||||
return render_template('player_list.html', players=players)
|
return render_template('player_list.html', players=players)
|
||||||
|
|
||||||
if __name__ == '__main__' and os.environ.get("KEMOVERSE_ENV") == "dev":
|
if __name__ == '__main__':
|
||||||
app.run(
|
app.run(host=config.BIND_ADDRESS, port=config.WEB_PORT, debug=True)
|
||||||
host=config.BIND_ADDRESS,
|
|
||||||
port=config.WEB_PORT,
|
|
||||||
debug=True,
|
|
||||||
)
|
|
||||||
|
|
13
web/static/js/jszip.min.js
vendored
13
web/static/js/jszip.min.js
vendored
File diff suppressed because one or more lines are too long
|
@ -64,7 +64,6 @@
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<script src="{{ url_for('static', filename='js/jszip.min.js') }}"></script>
|
|
||||||
<script>
|
<script>
|
||||||
const canvas = document.getElementById("cardCanvas");
|
const canvas = document.getElementById("cardCanvas");
|
||||||
const ctx = canvas.getContext("2d");
|
const ctx = canvas.getContext("2d");
|
||||||
|
@ -189,7 +188,7 @@ function drawCard() {
|
||||||
async function drawCardId() {
|
async function drawCardId() {
|
||||||
const id = await generateCardId(packInput.value, nameInput.value, powerInput.value, charmInput.value, witInput.value, artistInput.value);
|
const id = await generateCardId(packInput.value, nameInput.value, powerInput.value, charmInput.value, witInput.value, artistInput.value);
|
||||||
ctx.font = "15px sans-serif";
|
ctx.font = "15px sans-serif";
|
||||||
ctx.fillText("Kemoverse - " + id, canvas.width/2, canvas.height - 30);
|
ctx.fillText("KC-" + id, canvas.width/2, canvas.height - 30);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -222,83 +221,10 @@ function wrapText(text, x, y, maxWidth, lineHeight) {
|
||||||
|
|
||||||
// Download button
|
// Download button
|
||||||
downloadBtn.addEventListener("click", () => {
|
downloadBtn.addEventListener("click", () => {
|
||||||
// Sanitize file name
|
|
||||||
const safeName = (nameInput.value || "card").replace(/[^a-z0-9_\-]/gi, "_");
|
|
||||||
const safePack = (packInput.value || "pack").replace(/[^a-z0-9_\-]/gi, "_");
|
|
||||||
const fileName = `kemoverse_${safePack}_${safeName}.webp`;
|
|
||||||
|
|
||||||
const link = document.createElement("a");
|
const link = document.createElement("a");
|
||||||
link.download = fileName;
|
link.download = "kemoverse-card.webp";
|
||||||
link.href = canvas.toDataURL("image/webp", 0.95);
|
link.href = canvas.toDataURL("image/webp", 0.95);
|
||||||
link.click();
|
link.click();
|
||||||
});
|
});
|
||||||
|
|
||||||
const jsonBtn = document.createElement("button");
|
|
||||||
jsonBtn.textContent = "Download Card Info";
|
|
||||||
jsonBtn.style.marginTop = "0.5rem";
|
|
||||||
jsonBtn.onclick = () => {
|
|
||||||
const cardData = {
|
|
||||||
name: nameInput.value,
|
|
||||||
pack: packInput.value,
|
|
||||||
power: powerInput.value,
|
|
||||||
charm: charmInput.value,
|
|
||||||
wit: witInput.value,
|
|
||||||
flavor: flavorInput.value,
|
|
||||||
artist: artistInput.value,
|
|
||||||
frame: frameSelect.value,
|
|
||||||
id: generateCardId(packInput.value, nameInput.value, powerInput.value, charmInput.value, witInput.value, artistInput.value)
|
|
||||||
};
|
|
||||||
const safeName = (nameInput.value || "card").replace(/[^a-z0-9_\-]/gi, "_");
|
|
||||||
const safePack = (packInput.value || "pack").replace(/[^a-z0-9_\-]/gi, "_");
|
|
||||||
const fileName = `kemoverse_${safePack}_${safeName}.json`;
|
|
||||||
|
|
||||||
const blob = new Blob([JSON.stringify(cardData, null, 2)], {type: "application/json"});
|
|
||||||
const link = document.createElement("a");
|
|
||||||
link.href = URL.createObjectURL(blob);
|
|
||||||
link.download = fileName;
|
|
||||||
link.click();
|
|
||||||
};
|
|
||||||
|
|
||||||
// Place the button below the downloadBtn
|
|
||||||
downloadBtn.parentNode.insertBefore(jsonBtn, downloadBtn.nextSibling);
|
|
||||||
|
|
||||||
const zipBtn = document.createElement("button");
|
|
||||||
zipBtn.textContent = "Download Card ZIP";
|
|
||||||
zipBtn.style.marginTop = "0.5rem";
|
|
||||||
zipBtn.onclick = async () => {
|
|
||||||
const cardData = {
|
|
||||||
name: nameInput.value,
|
|
||||||
pack: packInput.value,
|
|
||||||
power: powerInput.value,
|
|
||||||
charm: charmInput.value,
|
|
||||||
wit: witInput.value,
|
|
||||||
flavor: flavorInput.value,
|
|
||||||
artist: artistInput.value,
|
|
||||||
frame: frameSelect.value,
|
|
||||||
id: await generateCardId(packInput.value, nameInput.value, powerInput.value, charmInput.value, witInput.value, artistInput.value)
|
|
||||||
};
|
|
||||||
const safeName = (nameInput.value || "card").replace(/[^a-z0-9_\-]/gi, "_");
|
|
||||||
const safePack = (packInput.value || "pack").replace(/[^a-z0-9_\-]/gi, "_");
|
|
||||||
const imgFileName = `kemoverse_${safePack}_${safeName}.webp`;
|
|
||||||
const jsonFileName = `kemoverse_${safePack}_${safeName}.json`;
|
|
||||||
|
|
||||||
// Create ZIP
|
|
||||||
const zip = new JSZip();
|
|
||||||
// Add image
|
|
||||||
const imgData = canvas.toDataURL("image/webp", 0.95).split(',')[1];
|
|
||||||
zip.file(imgFileName, imgData, {base64: true});
|
|
||||||
// Add JSON
|
|
||||||
zip.file(jsonFileName, JSON.stringify(cardData, null, 2));
|
|
||||||
|
|
||||||
// Generate and download
|
|
||||||
const content = await zip.generateAsync({type: "blob"});
|
|
||||||
const link = document.createElement("a");
|
|
||||||
link.href = URL.createObjectURL(content);
|
|
||||||
link.download = `kemoverse_${safePack}_${safeName}.zip`;
|
|
||||||
link.click();
|
|
||||||
};
|
|
||||||
|
|
||||||
// Place the button below the downloadBtn
|
|
||||||
downloadBtn.parentNode.insertBefore(zipBtn, downloadBtn.nextSibling);
|
|
||||||
</script>
|
</script>
|
||||||
{% endblock %}
|
{% endblock %}
|
18
web/wsgi.py
18
web/wsgi.py
|
@ -1,18 +0,0 @@
|
||||||
#Kemoverse - a gacha-style bot for the Fediverse.
|
|
||||||
#Copyright © 2025 Waifu
|
|
||||||
#
|
|
||||||
#This program is free software: you can redistribute it and/or modify
|
|
||||||
#it under the terms of the GNU Affero General Public License as
|
|
||||||
#published by the Free Software Foundation, either version 3 of the
|
|
||||||
#License, or (at your option) any later version.
|
|
||||||
#
|
|
||||||
#This program is distributed in the hope that it will be useful,
|
|
||||||
#but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
#MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
#GNU Affero General Public License for more details.
|
|
||||||
#
|
|
||||||
#You should have received a copy of the GNU Affero General Public License
|
|
||||||
#along with this program. If not, see https://www.gnu.org/licenses/.
|
|
||||||
|
|
||||||
from .app import app
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue