launch-calcium's picture
Upload app.py with huggingface_hub
078a3d7 verified
Raw
History Blame Contribute Delete
8.18 kB
import os
import sqlite3
import shutil
import mimetypes
from datetime import datetime, timezone
import gradio as gr
DB_NAME = "files.db"
UPLOAD_DIR = "uploads"
MAX_EMBEDDED_SIZE = 1 * 1024 * 1024 # 1 MB in bytes
def init_db(db_path=DB_NAME):
"""Initialize the SQLite database schema if it doesn't exist."""
conn = sqlite3.connect(db_path)
cursor = conn.cursor()
cursor.execute("""
CREATE TABLE IF NOT EXISTS files (
id INTEGER PRIMARY KEY AUTOINCREMENT,
filename TEXT NOT NULL,
file_type TEXT,
file_size_bytes INTEGER NOT NULL,
upload_timestamp TEXT NOT NULL,
is_large_file INTEGER NOT NULL,
file_content_blob BLOB,
relative_path TEXT
)
""")
conn.commit()
conn.close()
os.makedirs(UPLOAD_DIR, exist_ok=True)
def process_uploaded_files(files, db_path=DB_NAME, upload_dir=UPLOAD_DIR):
"""Process multiple uploaded files and log them into the SQLite database."""
if not files:
return "No files uploaded.", get_records_df(db_path), gr.update()
init_db(db_path)
conn = sqlite3.connect(db_path)
cursor = conn.cursor()
uploaded_count = 0
for file_obj in files:
# file_obj is a Gradio file object or filepath string depending on Gradio version
file_path = file_obj.name if hasattr(file_obj, "name") else str(file_obj)
orig_filename = os.path.basename(file_path)
file_size = os.path.getsize(file_path)
file_type, _ = mimetypes.guess_type(file_path)
if not file_type:
file_type = "application/octet-stream"
timestamp = datetime.now(timezone.utc).strftime("%Y-%m-%d %H:%M:%S")
if file_size > MAX_EMBEDDED_SIZE:
# File > 1MB: save to uploads directory and reference relative path
os.makedirs(upload_dir, exist_ok=True)
dest_filename = f"{int(datetime.now(timezone.utc).timestamp())}_{orig_filename}"
dest_path = os.path.join(upload_dir, dest_filename)
shutil.copy(file_path, dest_path)
cursor.execute("""
INSERT INTO files (filename, file_type, file_size_bytes, upload_timestamp, is_large_file, file_content_blob, relative_path)
VALUES (?, ?, ?, ?, ?, ?, ?)
""", (orig_filename, file_type, file_size, timestamp, 1, None, dest_path))
else:
# File <= 1MB: store binary content directly in database
with open(file_path, "rb") as f:
blob_data = f.read()
cursor.execute("""
INSERT INTO files (filename, file_type, file_size_bytes, upload_timestamp, is_large_file, file_content_blob, relative_path)
VALUES (?, ?, ?, ?, ?, ?, ?)
""", (orig_filename, file_type, file_size, timestamp, 0, blob_data, None))
uploaded_count += 1
conn.commit()
conn.close()
df = get_records_df(db_path)
large_files_dropdown = get_large_files_choices(db_path)
return f"Successfully processed and logged {uploaded_count} file(s).", df, large_files_dropdown
def get_records_df(db_path=DB_NAME):
"""Retrieve database records as a list of lists for Gradio Dataframe."""
if not os.path.exists(db_path):
return []
conn = sqlite3.connect(db_path)
cursor = conn.cursor()
cursor.execute("""
SELECT id, filename, file_type, file_size_bytes, upload_timestamp, is_large_file,
CASE WHEN file_content_blob IS NOT NULL THEN 'Stored in DB (BLOB)' ELSE 'Not Stored (BLOB IS NULL)' END as blob_status,
COALESCE(relative_path, 'N/A') as relative_path
FROM files
ORDER BY id DESC
""")
rows = cursor.fetchall()
conn.close()
return rows
def get_large_files_choices(db_path=DB_NAME):
"""Get list of choices for large file download dropdown."""
if not os.path.exists(db_path):
return gr.update(choices=[], value=None)
conn = sqlite3.connect(db_path)
cursor = conn.cursor()
cursor.execute("""
SELECT id, filename, relative_path
FROM files
WHERE is_large_file = 1 AND relative_path IS NOT NULL
ORDER BY id DESC
""")
rows = cursor.fetchall()
conn.close()
choices = [f"ID {r[0]}: {r[1]} ({r[2]})" for r in rows]
val = choices[0] if choices else None
return gr.update(choices=choices, value=val)
def download_selected_large_file(selected_item, db_path=DB_NAME):
"""Return the file path for the selected large file to allow download."""
if not selected_item:
return None
try:
file_id = int(selected_item.split(":")[0].replace("ID", "").strip())
except Exception:
return None
conn = sqlite3.connect(db_path)
cursor = conn.cursor()
cursor.execute("SELECT relative_path FROM files WHERE id = ?", (file_id,))
row = cursor.fetchone()
conn.close()
if row and row[0] and os.path.exists(row[0]):
return row[0]
return None
def download_database(db_path=DB_NAME):
"""Return database file for downloading."""
if os.path.exists(db_path):
return db_path
return None
# Initialize DB on load
init_db()
# Build Gradio UI
with gr.Blocks(title="Personal SQL DB Generator") as demo:
gr.Markdown("# ๐Ÿ—„๏ธ Personal SQL DB File Generator & Logger")
gr.Markdown(
"Upload multiple files of any type. Files **<= 1MB** are stored directly as binary BLOBs inside the SQLite database. "
"Files **> 1MB** are stored on disk with relative path references stored in the database. "
"You can inspect logged entries, download the complete SQLite `.db` database file, and download big files."
)
with gr.Tab("Upload Files & Log to SQL"):
file_input = gr.File(
label="Select or Drag & Drop Multiple Files",
file_count="multiple",
type="filepath"
)
upload_button = gr.Button("Upload & Log to Database", variant="primary")
status_output = gr.Textbox(label="Status Log", interactive=False)
with gr.Tab("Database Records"):
refresh_button = gr.Button("๐Ÿ”„ Refresh Database Table")
db_table = gr.Dataframe(
headers=["ID", "Filename", "Type", "Size (bytes)", "Timestamp", "Is Large (>1MB)", "BLOB Status", "Relative Path"],
value=get_records_df(),
interactive=False,
wrap=True
)
with gr.Tab("Downloads"):
with gr.Row():
with gr.Column():
gr.Markdown("### ๐Ÿ“ฆ Download SQLite Database")
db_download_btn = gr.Button("Prepare Database File")
db_file_output = gr.File(label="Download SQLite DB (.db)")
with gr.Column():
gr.Markdown("### ๐Ÿ“‚ Download Large Files (>1MB)")
large_files_dropdown = gr.Dropdown(
label="Select Large File to Download",
choices=[c for c in get_large_files_choices()["choices"]] if isinstance(get_large_files_choices(), dict) else [],
interactive=True
)
refresh_dropdown_btn = gr.Button("Refresh Large Files List")
download_large_btn = gr.Button("Prepare Large File Download")
large_file_output = gr.File(label="Download File")
# Event handlers
upload_button.click(
fn=process_uploaded_files,
inputs=[file_input],
outputs=[status_output, db_table, large_files_dropdown]
)
refresh_button.click(
fn=get_records_df,
inputs=[],
outputs=[db_table]
)
db_download_btn.click(
fn=download_database,
inputs=[],
outputs=[db_file_output]
)
refresh_dropdown_btn.click(
fn=get_large_files_choices,
inputs=[],
outputs=[large_files_dropdown]
)
download_large_btn.click(
fn=download_selected_large_file,
inputs=[large_files_dropdown],
outputs=[large_file_output]
)
if __name__ == "__main__":
demo.launch()