File size: 6,410 Bytes
d57efd6
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
from typing import Annotated, List, Optional
from api.router.user import user_dependency
from fastapi import APIRouter, Depends
from fastapi.responses import JSONResponse
from db.models import User_Meta, Metadata, Category
from db.database import get_db
from sqlalchemy.orm import Session
from sqlalchemy.exc import SQLAlchemyError

router = APIRouter(tags=["Book_Collection"])

db_dependency = Annotated[Session, Depends(get_db)]


@router.get("/book_collection")
async def get_book_collection(
    user: user_dependency,
    db: db_dependency,
):
    """This function will return a BookCollection"""
    if user is None:
        return JSONResponse(status_code=401, content="Authentication Failed")

    try:
        # Fetch all User_Meta entries for the user and their associated Metadata
        user_meta_entries = (
            db.query(User_Meta, Metadata, Category)  # Select User_Meta, Metadata, and Category
            .join(Metadata, Metadata.id == User_Meta.metadata_id)  # Join on metadata_id
            .join(Category, Category.id == Metadata.category_id)  # Join on category_id
            .filter(User_Meta.user_id == user.get("id"))
            .all()
        )

        if not user_meta_entries:
            return {"info": "No book collection found"}

        # Extract relevant data from the user_meta_entries
        results = [
            {
                "user_id": user_meta.user_id,
                "metadata_id": metadata.id,  # Access Metadata fields
                "title": metadata.title,  # Replace with actual field names in Metadata
                "author": metadata.author,  # Replace with actual field names in Metadata
                "category_name": category.category,  # Replace with actual field names in Category
                "year": metadata.year,
                "publisher": metadata.publisher
                # Add other Metadata and Category fields as needed
            }
            for user_meta, metadata, category in user_meta_entries  # Unpack the tuple
        ]

        return {
            "status": "success",
            "book_collection": results,  # Return the list of metadata
        }

    except SQLAlchemyError as e:
        return JSONResponse(status_code=500, content=f"Database error: {str(e)}")
    except Exception as e:
        return JSONResponse(
            status_code=500, content=f"An unexpected error occurred: {str(e)}"
        )


@router.post("/book_collection")
async def request_book_collection(
    user: user_dependency,
    db: db_dependency,
    metadata_id: List[Optional[int]],
):
    if user is None:
        return JSONResponse(status_code=401, content="Authentication Failed")

    try:
        # Create User_Meta instances for each metadata_id
        user_meta_entries = [
            User_Meta(user_id=user.get("id"), metadata_id=mid) for mid in metadata_id
        ]

        # Insert all entries into the database
        db.add_all(user_meta_entries)
        db.commit()  # Commit the transaction

    except SQLAlchemyError as e:
        return JSONResponse(status_code=500, content=f"Database error: {str(e)}")
    except Exception as e:
        return JSONResponse(
            status_code=500, content=f"An unexpected error occurred: {str(e)}"
        )

    return {"status": "success", "user_meta": [entry.id for entry in user_meta_entries]}


@router.put("/book_collection")
async def update_book_collection(
    user: user_dependency,
    db: db_dependency,
    metadata_id: List[Optional[int]],  # Use the Pydantic model
):
    if user is None:
        return JSONResponse(status_code=401, content="Authentication Failed")

    try:
        # Fetch and delete existing User_Meta entries
        db.query(User_Meta).filter(User_Meta.user_id == user.get("id")).delete(
            synchronize_session=False
        )
        db.commit()

        # Insert new User_Meta entries
        user_meta_entries = [
            User_Meta(user_id=user.get("id"), metadata_id=mid) for mid in metadata_id
        ]
        db.add_all(user_meta_entries)
        db.commit()
    except SQLAlchemyError as e:
        db.rollback()
        return JSONResponse(status_code=500, content=f"Database error: {str(e)}")
    except Exception as e:
        return JSONResponse(status_code=500, content=f"Unexpected error: {str(e)}")

    return {"status": "success", "user_meta": [entry.id for entry in user_meta_entries]}


@router.delete("/book_collection/{metadata_id}")
async def delete_book_collection(
    user: user_dependency,
    db: db_dependency,
    metadata_id: int
):
    if user is None:
        return JSONResponse(status_code=401, content="Authentication Failed")

    try:
        # Query to delete the entry based on metadata_id for the authenticated user
        entry_to_delete = db.query(User_Meta).filter(
            User_Meta.user_id == user.get("id"),
            User_Meta.metadata_id == metadata_id
        ).first()

        if not entry_to_delete:
            return JSONResponse(status_code=404, content="Entry not found to delete.")

        # Delete the entry
        db.delete(entry_to_delete)
        db.commit()

    except SQLAlchemyError as e:
        db.rollback()  # Rollback in case of any database error
        return JSONResponse(status_code=500, content=f"Database error: {str(e)}")
    except Exception as e:
        return JSONResponse(
            status_code=500, content=f"An unexpected error occurred: {str(e)}"
        )

    return {
        "status": "success",
        "deleted_entry": entry_to_delete.id,
    }


@router.delete("/all_collections")
async def delete_all_book(
    user: user_dependency,
    db: db_dependency,
):
    if user is None:
        return JSONResponse(status_code=401, content="Authentication Failed")

    try:
        db.query(User_Meta).filter(User_Meta.user_id == user.get("id")).delete(
            synchronize_session="fetch"
        )
        
        db.commit()  # Commit all deletions

        return {
            "status": "success",
            "delete book collection from": user.get("id"),
        }

    except SQLAlchemyError as e:
        db.rollback()  # Rollback in case of any database error
        return JSONResponse(status_code=500, content=f"Database error: {str(e)}")
    except Exception as e:
        return JSONResponse(
            status_code=500, content=f"An unexpected error occurred: {str(e)}"
        )