diff --git a/app/backend/routes/product.py b/app/backend/routes/product.py index daaaf9e04e839ec2e81e611462bff2ff57f29973..8c16bf78de6e50c0763fe3cb2f7cef1aaeb582b7 100644 --- a/app/backend/routes/product.py +++ b/app/backend/routes/product.py @@ -1,10 +1,11 @@ from fastapi import APIRouter, Depends, HTTPException, UploadFile, File, Form from sqlmodel import Session from datetime import datetime -from backend.models.models import Product, ProductImage, User -from backend.schemas.product import ProductRead, ProductImageRead +from backend.models.models import Product, ProductImage, User, Shop +from backend.schemas.product import ProductRead, ProductUpdate from backend.database import get_session from backend.routes.auth import get_current_user +from core.config import settings import shutil import os @@ -22,7 +23,7 @@ def create_product( stock: int = Form(...), shop_id: int = Form(...), category_id: int = Form(None), - images: UploadFile = File(None), # Ensuring image is correctly set + images: list[UploadFile] = File(None), session: Session = Depends(get_session), ): product = Product( @@ -38,16 +39,33 @@ def create_product( session.commit() session.refresh(product) - # Handling image upload - if images and images.filename: - file_ext = os.path.splitext(images.filename)[1] # Get file extension - file_name = f"product_{product.id}{file_ext}" - file_location = os.path.join(static_dir, file_name) - - with open(file_location, "wb") as buffer: - shutil.copyfileobj(images.file, buffer) - - # Save image record in ProductImage + # Get the shop to create the correct directory + shop = session.get(Shop, shop_id) + if not shop: + raise HTTPException(status_code=404, detail="Shop not found") + + shop_dir = os.path.join(settings.static_dir, f"shop_{shop.name}") + os.makedirs(shop_dir, exist_ok=True) + + product_dir = os.path.join(shop_dir, f"product_{product.name}") + os.makedirs(product_dir, exist_ok=True) + + # Handling multiple image uploads + if images: + for image in images: + if image.filename: + file_location = os.path.join(product_dir, image.filename) + with open(file_location, "wb") as buffer: + shutil.copyfileobj(image.file, buffer) + + # Save image record in ProductImage + product_image = ProductImage( + product_id=product.id, image_url=file_location + ) + session.add(product_image) + session.commit() + else: # Save default image + file_location = os.path.join(settings.static_dir, "default/default_product.png") product_image = ProductImage(product_id=product.id, image_url=file_location) session.add(product_image) session.commit() @@ -69,44 +87,57 @@ def read_product(product_id: int, session: Session = Depends(get_session)): return product -@router.put("/{product_id}", response_model=ProductRead) +@router.put("/{product_id}", response_model=ProductUpdate) def update_product( product_id: int, - name: str = Form(None), - description: str = Form(None), - price: float = Form(None), - stock: int = Form(None), - category_id: int = Form(None), - file: UploadFile = File(None), + name: str = Form(...), + description: str = Form(...), + price: float = Form(...), + stock: int = Form(...), + category_id: int = Form(...), + images: list[UploadFile] = File(...), session: Session = Depends(get_session), ): product = session.get(Product, product_id) if not product: raise HTTPException(status_code=404, detail="Product not found") - - if name: - product.name = name - if description: - product.description = description - if price is not None: - product.price = price - if stock is not None: - product.stock = stock - if category_id is not None: - product.category_id = category_id + + # if name: + # product.name = name + # if description: + # product.description = description + # if price is not None: + # product.price = price + # if stock is not None: + # product.stock = stock + # if category_id is not None: + # product.category_id = category_id session.add(product) session.commit() session.refresh(product) - if file and file.filename: - file_location = os.path.join(static_dir, f"product_{product.id}_{file.filename}") - with open(file_location, "wb") as buffer: - shutil.copyfileobj(file.file, buffer) - - image = ProductImage(product_id=product.id, image_url=file_location) - session.add(image) - session.commit() + # Get the shop to create the correct directory + shop = session.get(Shop, product.shop_id) + if not shop: + raise HTTPException(status_code=404, detail="Shop not found") + + shop_dir = os.path.join(settings.static_dir, f"shop_{shop.name}") + os.makedirs(shop_dir, exist_ok=True) + + product_dir = os.path.join(shop_dir, f"product_{product.name}") + os.makedirs(product_dir, exist_ok=True) + + if images: + for file in images: + if file.filename: + file_location = os.path.join(product_dir, file.filename) + with open(file_location, "wb") as buffer: + shutil.copyfileobj(file.file, buffer) + + image = ProductImage(product_id=product.id, image_url=file_location) + session.add(image) + session.commit() return product @@ -119,41 +150,3 @@ def delete_product(product_id: int, session: Session = Depends(get_session)): session.delete(product) session.commit() return {"message": "Product deleted successfully"} - - -@router.post("/ProductImage/", response_model=ProductImageRead) -def upload_product_image( - product_id: int = Form(...), - file: UploadFile = File(...), - session: Session = Depends(get_session), -): - product = session.get(Product, product_id) - if not product: - raise HTTPException(status_code=404, detail="Product not found") - - file_location = os.path.join(static_dir, f"product_{product.id}_{file.filename}") - with open(file_location, "wb") as buffer: - shutil.copyfileobj(file.file, buffer) - - image = ProductImage(product_id=product.id, image_url=file_location) - session.add(image) - session.commit() - return image - - -@router.get("/ProductImage/{product_id}", response_model=list[ProductImageRead]) -def get_product_images(product_id: int, session: Session = Depends(get_session)): - images = session.query(ProductImage).filter(ProductImage.product_id == product_id).all() - if not images: - raise HTTPException(status_code=404, detail="No images found for this product") - return images - - -@router.delete("/ProductImage/{image_id}") -def delete_product_image(image_id: int, session: Session = Depends(get_session)): - image = session.get(ProductImage, image_id) - if not image: - raise HTTPException(status_code=404, detail="Image not found") - session.delete(image) - session.commit() - return {"message": "Product image deleted successfully"} diff --git a/app/backend/routes/shop.py b/app/backend/routes/shop.py index 6641eb36a99fef3eeb2a3580430a4d4dbe8d951f..e6f364d49b56ec0afb917e0361fa8014aa2ca0c1 100644 --- a/app/backend/routes/shop.py +++ b/app/backend/routes/shop.py @@ -4,14 +4,12 @@ from backend.models.models import Shop, User from backend.schemas.shop import ShopCreate, ShopRead from backend.database import get_session from backend.routes.auth import get_current_user +from core.config import settings import shutil import os router = APIRouter() -static_dir = os.path.join("app", "static") -os.makedirs(static_dir, exist_ok=True) - @router.post("/", response_model=ShopRead) def create_shop( @@ -19,32 +17,30 @@ def create_shop( description: str = Form(None), file: UploadFile = File(None), session: Session = Depends(get_session), - current_user: User = Depends(get_current_user), - #owner_id = int, - + # current_user: User = Depends(get_current_user), + owner_id=int, ): - shop = ShopCreate(name=name, description=description, owner_id=current_user.id) - #shop = ShopCreate(name=name, description=description, owner_id=owner_id) + # shop = ShopCreate(name=name, description=description, owner_id=current_user.id) + shop = ShopCreate(name=name, description=description, owner_id=owner_id) db_shop = Shop.from_orm(shop) + session.add(db_shop) + session.commit() + session.refresh(db_shop) + + shop_dir = os.path.join(settings.static_dir, f"shop_{db_shop.name}") + os.makedirs(shop_dir, exist_ok=True) + if file and file.filename: - # Save the image to the static directory - file_location = os.path.join(static_dir, f"{db_shop.name}_{file.filename}") + file_location = os.path.join(shop_dir, file.filename) with open(file_location, "wb") as buffer: shutil.copyfileobj(file.file, buffer) - db_shop.image_url = file_location else: - # Set a default image URL if no file is uploaded - db_shop.image_url = os.path.join(static_dir, "default_shop_image.png") + db_shop.image_url = os.path.join( + settings.static_dir, "default/default_shop.png" + ) - session.add(db_shop) - session.commit() - session.refresh(db_shop) - - # if file: - # # Delete the image file after session commit - # os.remove(file_location) return db_shop @@ -79,25 +75,23 @@ def update_shop( if description: db_shop.description = description + shop_dir = os.path.join(settings.static_dir, f"shop_{db_shop.name}") + os.makedirs(shop_dir, exist_ok=True) + if file and file.filename: - # Save the image to the static directory - file_location = os.path.join(static_dir, f"{db_shop.name}_{file.filename}") + file_location = os.path.join(shop_dir, file.filename) with open(file_location, "wb") as buffer: shutil.copyfileobj(file.file, buffer) - db_shop.image_url = file_location else: - # Set a default image URL if no file is uploaded - db_shop.image_url = os.path.join(static_dir, "default_shop_image.png") + db_shop.image_url = os.path.join( + settings.static_dir, "default/default_shop.png" + ) session.add(db_shop) session.commit() session.refresh(db_shop) - if file: - # Delete the image file after session commit - os.remove(file_location) - return db_shop diff --git a/app/core/config.py b/app/core/config.py index 9666c8a4a488a66f56b3f690756a9d3aac9d3985..7e46517e091343dbc570e8b530b041ae3991dd5f 100644 --- a/app/core/config.py +++ b/app/core/config.py @@ -1,5 +1,6 @@ from pathlib import Path from pydantic_settings import BaseSettings, SettingsConfigDict +import os class Settings(BaseSettings): @@ -16,6 +17,10 @@ class Settings(BaseSettings): def database_url(self) -> str: return f"mysql+pymysql://{self.database_username}:{self.database_password}@{self.database_host}/{self.database_name}" + @property + def static_dir(self) -> str: + return os.path.join("app", "static") + model_config = SettingsConfigDict( env_file=str(Path(__file__).resolve().parent.parent / ".env"), env_file_encoding="utf-8", diff --git a/app/static/default/default_product.png b/app/static/default/default_product.png new file mode 100644 index 0000000000000000000000000000000000000000..f8a26b2d08887153a17797e6762ee17d71a89d08 Binary files /dev/null and b/app/static/default/default_product.png differ diff --git a/app/static/default/default_shop.png b/app/static/default/default_shop.png new file mode 100644 index 0000000000000000000000000000000000000000..ed0ec74950384a12f8f40a8e3bba9d1247c4c562 Binary files /dev/null and b/app/static/default/default_shop.png differ