added .env + delete file + handle error when file didns saved but added to db
This commit is contained in:
26
app/api.py
26
app/api.py
@@ -4,6 +4,10 @@ from sqlalchemy import exists
|
||||
import hashlib
|
||||
from . import db
|
||||
import os
|
||||
from dotenv import load_dotenv
|
||||
import os
|
||||
load_dotenv()
|
||||
FILES_DIR = os.getenv("FILES_DIR")
|
||||
|
||||
def compute_hash(data: bytes, algorithm="sha256") -> str:
|
||||
h = hashlib.new(algorithm)
|
||||
@@ -12,7 +16,6 @@ def compute_hash(data: bytes, algorithm="sha256") -> str:
|
||||
|
||||
app = FastAPI()
|
||||
|
||||
FILES_DIR = "./files"
|
||||
|
||||
@app.get("/")
|
||||
def root():
|
||||
@@ -29,10 +32,13 @@ async def save_file(file: UploadFile = File(...)):
|
||||
if not existed_url:
|
||||
file_url = db.add_file(file.filename, file.content_type, file.size, hash)
|
||||
|
||||
print(f"{FILES_DIR}/{file_url}")
|
||||
with open(f"{FILES_DIR}/{file_url}", "wb") as f:
|
||||
f.write(contents)
|
||||
return {"status": "saved", "filename": file_url}
|
||||
try:
|
||||
with open(f"{FILES_DIR}/{file_url}", "wb") as f:
|
||||
f.write(contents)
|
||||
return {"status": "saved", "filename": file_url}
|
||||
except Exception as e:
|
||||
db.remove_file(file_url)
|
||||
return {"status": "error", "message": f"Could not save file {file_url}: {e}"}
|
||||
else:
|
||||
return {"status": "file_exists", "filename": existed_url}
|
||||
|
||||
@@ -48,6 +54,16 @@ def get_file(filename: str, raw: bool = False):
|
||||
|
||||
return FileResponse(file_path, filename=filename)
|
||||
|
||||
|
||||
@app.delete("/file/{filename}")
|
||||
def delete_file(filename: str):
|
||||
if db.remove_file(filename):
|
||||
file_path = f"{FILES_DIR}/{filename}"
|
||||
if os.path.exists(file_path):
|
||||
os.remove(file_path)
|
||||
return {"status": "deleted"}
|
||||
return {"status": "error", "message": "no file like that"}
|
||||
|
||||
@app.get("/files/")
|
||||
def get_list_of_files():
|
||||
files = db.get_all_files()
|
||||
|
||||
35
app/db.py
35
app/db.py
@@ -4,9 +4,13 @@ from sqlalchemy import create_engine
|
||||
from sqlalchemy.orm import Session, sessionmaker
|
||||
from sqlalchemy import select
|
||||
|
||||
PADDING = 5
|
||||
from dotenv import load_dotenv
|
||||
import os
|
||||
load_dotenv()
|
||||
PADDING = int(os.getenv("FILES_PADDING"))
|
||||
DATABASE_NAME = os.getenv("DATABASE_NAME")
|
||||
|
||||
engine = create_engine("sqlite:///example.db")
|
||||
engine = create_engine(f"sqlite:///{DATABASE_NAME}.db")
|
||||
session = Session(bind=engine)
|
||||
|
||||
class Base(DeclarativeBase): pass
|
||||
@@ -38,6 +42,22 @@ def to_base36(n: int, width: int) -> str:
|
||||
result.append(chars[rem])
|
||||
return "".join(reversed(result)).rjust(width, "0")
|
||||
|
||||
|
||||
def from_base36(s: str) -> int:
|
||||
chars = "0123456789abcdefghijklmnopqrstuvwxyz"
|
||||
char_to_val = {c: i for i, c in enumerate(chars)}
|
||||
|
||||
s = s.lower().lstrip("0")
|
||||
if not s:
|
||||
return 0
|
||||
|
||||
n = 0
|
||||
for ch in s:
|
||||
if ch not in char_to_val:
|
||||
raise ValueError(f"Invalid base36 character: {ch}")
|
||||
n = n * 36 + char_to_val[ch]
|
||||
return n
|
||||
|
||||
Base.metadata.create_all(bind=engine)
|
||||
|
||||
def get_all_files():
|
||||
@@ -83,6 +103,17 @@ def add_file(filename: str, content_type, size: int, hash):
|
||||
|
||||
return url
|
||||
|
||||
|
||||
def remove_file(file_url: str):
|
||||
with Session(autoflush=False, bind=engine) as db:
|
||||
file_id = from_base36(file_url.rsplit(".")[0])
|
||||
file = db.get(File, file_id)
|
||||
if not file:
|
||||
return None
|
||||
db.delete(file)
|
||||
db.commit()
|
||||
return True
|
||||
|
||||
if __name__ == "__main__":
|
||||
for i in get_all_files():
|
||||
print(f"{i.id} {i.name}.{i.extension} ({i.hash}) {i.content_type} {i.size}")
|
||||
|
||||
Reference in New Issue
Block a user