manga / app.py
vorstcavry's picture
Create app.py
d154ca6 verified
import os
import json
import tempfile
from datetime import datetime
from flask import Flask, request, render_template_string
from huggingface_hub import HfApi, whoami
app = Flask(__name__)
api = HfApi()
# ==========================
# CONFIG
# ==========================
DATASET_REPO = "INDONESIA-AI/manga-dataset"
OWNER_TOKEN = os.environ.get("HF_OWNER_TOKEN")
# ==========================
# VALIDASI USER TOKEN
# ==========================
def get_username(token):
try:
info = whoami(token=token)
return info["name"]
except:
return None
# ==========================
# HTML UI
# ==========================
HTML = """
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Upload Komik</title>
<style>
body{
font-family:Arial;
background:#111;
color:white;
padding:20px;
}
.container{
max-width:600px;
margin:auto;
background:#1e1e1e;
padding:20px;
border-radius:10px;
}
input{
width:100%;
padding:12px;
margin-top:5px;
margin-bottom:15px;
}
button{
width:100%;
padding:14px;
background:#ff4757;
border:none;
color:white;
font-size:18px;
border-radius:8px;
cursor:pointer;
}
button:hover{
background:#ff6b81;
}
</style>
</head>
<body>
<div class="container">
<h2>πŸ“š Upload Komik Publik</h2>
<form method="POST" action="/upload" enctype="multipart/form-data">
<label>HF API Key (identitas uploader)</label>
<input type="text" name="user_token" required>
<label>Judul Komik</label>
<input type="text" name="title" required>
<label>Comic ID (contoh: naruto)</label>
<input type="text" name="comic_id" required>
<label>Chapter (contoh: chapter_1)</label>
<input type="text" name="chapter" required>
<label>Cover Komik</label>
<input type="file" name="cover" required>
<label>Halaman Komik</label>
<input type="file" name="pages" multiple required>
<button type="submit">πŸš€ Upload Komik</button>
</form>
</div>
</body>
</html>
"""
@app.route("/")
def home():
return render_template_string(HTML)
# ==========================
# UPLOAD
# ==========================
@app.route("/upload", methods=["POST"])
def upload():
if not OWNER_TOKEN:
return "❌ OWNER TOKEN belum diset di Space Secrets"
user_token = request.form.get("user_token")
username = get_username(user_token)
if not username:
return "❌ HF API Key tidak valid"
title = request.form["title"]
comic_id = request.form["comic_id"]
chapter = request.form["chapter"]
cover = request.files["cover"]
pages = request.files.getlist("pages")
base_path = f"comics/{comic_id}"
chapter_path = f"{base_path}/{chapter}"
# ========= Upload Cover =========
with tempfile.NamedTemporaryFile(delete=False) as tmp:
cover.save(tmp.name)
api.upload_file(
path_or_fileobj=tmp.name,
path_in_repo=f"{base_path}/cover.jpg",
repo_id=DATASET_REPO,
repo_type="dataset",
token=OWNER_TOKEN,
commit_message=f"Cover upload by {username}"
)
os.remove(tmp.name)
# ========= Upload Pages =========
for i, page in enumerate(pages):
with tempfile.NamedTemporaryFile(delete=False) as tmp:
page.save(tmp.name)
api.upload_file(
path_or_fileobj=tmp.name,
path_in_repo=f"{chapter_path}/page_{i+1}.jpg",
repo_id=DATASET_REPO,
repo_type="dataset",
token=OWNER_TOKEN,
commit_message=f"{username} upload {chapter}"
)
os.remove(tmp.name)
# ========= Metadata =========
info = {
"title": title,
"uploaded_by": username,
"created": datetime.now().isoformat()
}
with tempfile.NamedTemporaryFile(mode="w", delete=False) as tmp:
json.dump(info, tmp)
api.upload_file(
path_or_fileobj=tmp.name,
path_in_repo=f"{base_path}/info.json",
repo_id=DATASET_REPO,
repo_type="dataset",
token=OWNER_TOKEN,
commit_message="Update metadata"
)
os.remove(tmp.name)
return f"""
<h3>βœ… Upload berhasil!</h3>
Uploader: {username}<br>
Comic: {title}<br>
Chapter: {chapter}<br><br>
<a href="/">Upload lagi</a>
"""
# ==========================
# RUN
# ==========================
if __name__ == "__main__":
app.run(host="0.0.0.0", port=7860)