Skip to content

Commit

Permalink
push
Browse files Browse the repository at this point in the history
  • Loading branch information
dracxi committed Jan 21, 2024
1 parent 6c7f216 commit e738d3b
Show file tree
Hide file tree
Showing 13 changed files with 562 additions and 0 deletions.
3 changes: 3 additions & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"python.analysis.typeCheckingMode": "basic"
}
14 changes: 14 additions & 0 deletions database.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker
from models import Base

DATABASE_URL = "sqlite:///./images.db"
engine = create_engine(DATABASE_URL)
SessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine)

def get_db():
db = SessionLocal()
try:
yield db
finally:
db.close()
Binary file added images.db
Binary file not shown.
81 changes: 81 additions & 0 deletions main.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
from pathlib import Path
import os
from fastapi import Depends, FastAPI, HTTPException, UploadFile, Request, File
from fastapi.staticfiles import StaticFiles
from fastapi.templating import Jinja2Templates
from sqlalchemy.orm import Session
from PIL import Image
from database import get_db, engine
from models import ImageInfo, Base


Base.metadata.create_all(bind=engine)

app = FastAPI()
upload_folder = Path("uploads")
upload_folder.mkdir(exist_ok=True)
app.mount("/static", StaticFiles(directory="static"), name="static")
app.mount("/uploads", StaticFiles(directory="uploads"), name="uploads")
templates = Jinja2Templates(directory="templates")


@app.get("/")
def homepage(request: Request):
return templates.TemplateResponse("index.html", {"request": request})


@app.post("/upload")
async def create_upload_file(code: str, img: UploadFile = File(...), db: Session = Depends(get_db)):
existing_record = db.query(ImageInfo).filter(
ImageInfo.code == code).first()
if existing_record:
return {"success": False, "data": "Code is Taken"}
valid_extensions = (".jpg", ".jpeg", ".png", ".gif", ".bmp")
contents = await img.read()
filename = f"uploads/{code}_{img.filename}"
if not filename.lower().endswith(valid_extensions):
return {"success": False, "data": "Not a valid file extensions"}
with open(filename, "wb") as f:
f.write(contents)
img = Image.open(filename) # type: ignore
filesize = str(round(os.path.getsize(filename)/1000 ,1)) + " kb"
width, height = img.size # type: ignore
print()
db_img = ImageInfo(code=code, filename=filename,
width=width, height=height,size = filesize)
db.add(db_img)
db.commit()
return {
"success": True,
"data": {
"code": code,
"filename": filename,
"created_at": db_img.created_at,
},
}


@app.get("/{code}")
def view_image(request: Request, code: str, db: Session = Depends(get_db)):
image_info = db.query(ImageInfo).filter(ImageInfo.code == code).first()
if image_info is None:
raise HTTPException(status_code=404, detail="Image not found")
image_url = f"{request.url.scheme}://{request.headers['host']}/{image_info.filename}"
return templates.TemplateResponse("view_image.html", {"request": request, "image_info": image_info, 'image_url': image_url})


@app.get("/image/{code}")
async def read_image(code: str, db: Session = Depends(get_db)):
image_info = db.query(ImageInfo).filter(ImageInfo.code == code).first()
if image_info is None:
return {"success":False, "data":"Image not found"}
return {
"success":True,
"data": {
"code": image_info.code,
"filename": image_info.filename,
"Resolution": {"width": image_info.width, "height": image_info.height},
"size": image_info.size,
"created_at": image_info.created_at,
},
}
17 changes: 17 additions & 0 deletions models.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
from datetime import datetime
from pydantic import BaseModel
from sqlalchemy import Column, String, DateTime, Integer
from sqlalchemy.ext.declarative import declarative_base

Base = declarative_base()

class ImageInfo(Base):
__tablename__ = "images"
code = Column(String, primary_key=True, index=True)
created_at = Column(DateTime, default=datetime.utcnow)
filename = Column(String)
size = Column(String)
width = Column(Integer)
height = Column(Integer)
class Code(BaseModel):
code: str
24 changes: 24 additions & 0 deletions requirements.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
annotated-types==0.6.0
anyio==4.2.0
click==8.1.7
fastapi==0.109.0
greenlet==3.0.3
h11==0.14.0
httptools==0.6.1
idna==3.6
Jinja2==3.1.3
MarkupSafe==2.1.3
pillow==10.2.0
pydantic==2.5.3
pydantic_core==2.14.6
python-dotenv==1.0.0
python-multipart==0.0.6
PyYAML==6.0.1
sniffio==1.3.0
SQLAlchemy==2.0.25
starlette==0.35.1
typing_extensions==4.9.0
uvicorn==0.25.0
uvloop==0.19.0
watchfiles==0.21.0
websockets==12.0
138 changes: 138 additions & 0 deletions static/css/main.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,138 @@
body {
background-color: slategray;
color: white;
font-family: Arial, sans-serif;
}

#uploadForm {
margin: 50px auto;
max-width: 400px;
padding: 20px;
background-color: #333;
border-radius: 10px;
box-shadow: 0 0 10px rgba(0, 0, 0, 0.5);
}


h1 {
text-align: center;
margin-bottom: 20px;
}


label {
display: block;
margin-bottom: 10px;
}

input[type="text"],
input[type="file"] {
width: 95%;
padding: 10px;
border: none;
background-color: #555;
color: white;
border-radius: 5px;
}


button {
display: block;
width: 100%;
padding: 10px;
margin-top: 20px;
background-color: #555;
color: white;
border: none;
border-radius: 5px;
cursor: pointer;
transition: background-color 0.3s, transform 0.2s;
}

button:hover {
background-color: #777;
transform: scale(1.1);
}

#result {
text-align: center;
margin-top: 20px;
}

#progress-container {
display: none;
text-align: center;
}

#uploadProgress {
width: 100%;
border: none;
}
progress {
width: 40%;
display: block; /* default: inline-block */
margin: 2em auto;
padding: 3px;
border: 0 none;
background: #444;
border-radius: 14px;
}
progress::-moz-progress-bar {
border-radius: 12px;
background: #a4bdec;

}
/* webkit */
@media screen and (-webkit-min-device-pixel-ratio:0) {
progress {
height: 25px;
}
}
progress::-webkit-progress-bar {
background: transparent;
}
progress::-webkit-progress-value {
border-radius: 12px;
background:#a4bdec;
}


/* Animation styles */
@keyframes fadeIn {
from {
opacity: 0;
}
to {
opacity: 1;
}
}

/* Apply animation to form */
#uploadForm {
animation: fadeIn 0.5s ease-in-out;
}

/* Header styles */
header {
text-align: center;
margin-bottom: 20px;
}

/* Footer styles */
footer {
position:fixed;
bottom: 20px;
width: 95% auto;
text-align: center;
padding: 20px;
right: 20px;
left: 20px;
background-color: #333;
border-radius: 10px;
}

footer a {
color: white;
margin: 0 10px;
text-decoration: none;
}
48 changes: 48 additions & 0 deletions static/css/style.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
body {
margin: 0;
}

.fullscreen-image {
display: flex;
align-items: center;
justify-content: center;
height: 100vh;
background-color: #000000;
}

.image {
max-width: 100%;
max-height: 100%;
border: 1px solid #ddd;
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
}

.image-details {
position: absolute;
top: 20px;
left: 20px;
color: #fff;
text-align: left;
}


.image-details p {
margin: 0;
font-size: 16px;
}

.image-details .image-title {
font-size: 24px;
font-weight: bold;
}

.image-details .upload-date {
font-size: 14px;
}
.image-details .imgsize {
font-size: 16px;
}
body {
background-color: #333;
}

Binary file added static/favicon.ico
Binary file not shown.
Loading

0 comments on commit e738d3b

Please sign in to comment.