Photos/videos captions implemented
This commit is contained in:
parent
d800bbbda5
commit
9a48835fe4
@ -44,7 +44,7 @@ async def compress_image(image_path: str):
|
||||
logWrite(f"Compressed '{path.split(image_path)[-1]}' from {size_before} Kb to {size_after} Kb")
|
||||
|
||||
@app.post("/albums/{album}/photos", response_class=UJSONResponse, response_model=Photo, description="Upload a photo to album")
|
||||
async def photo_upload(file: UploadFile, album: str, ignore_duplicates: bool = False, compress: bool = True, current_user: User = Security(get_current_active_user, scopes=["photos.write"])):
|
||||
async def photo_upload(file: UploadFile, album: str, ignore_duplicates: bool = False, compress: bool = True, caption: Union[str, None] = None, current_user: User = Security(get_current_active_user, scopes=["photos.write"])):
|
||||
|
||||
if col_albums.find_one( {"user": current_user.user, "name": album} ) is None:
|
||||
return HTTPException(status_code=HTTP_404_NOT_FOUND, detail=f"Provided album '{album}' does not exist.")
|
||||
@ -91,7 +91,8 @@ async def photo_upload(file: UploadFile, album: str, ignore_duplicates: bool = F
|
||||
coords["lng"],
|
||||
coords["lat"],
|
||||
coords["alt"]
|
||||
]
|
||||
],
|
||||
"caption": caption
|
||||
}
|
||||
)
|
||||
|
||||
@ -159,6 +160,25 @@ async def photo_move(id: str, album: str, current_user: User = Security(get_curr
|
||||
}
|
||||
)
|
||||
|
||||
@app.patch("/photos/{id}", description="Change properties of a photo")
|
||||
async def photo_patch(id: str, caption: str, current_user: User = Security(get_current_active_user, scopes=["photos.write"])):
|
||||
|
||||
try:
|
||||
image = col_photos.find_one( {"_id": ObjectId(id)} )
|
||||
if image is None:
|
||||
raise InvalidId(id)
|
||||
except InvalidId:
|
||||
return HTTPException(status_code=HTTP_404_NOT_FOUND, detail="Could not find an image with such id.")
|
||||
|
||||
col_photos.find_one_and_update( {"_id": ObjectId(id)}, {"$set": {"caption": caption, "dates.modified": datetime.utcnow()}} )
|
||||
|
||||
return UJSONResponse(
|
||||
{
|
||||
"id": image["_id"].__str__(),
|
||||
"caption": caption
|
||||
}
|
||||
)
|
||||
|
||||
@app.delete("/photos/{id}", description="Delete a photo by id")
|
||||
async def photo_delete(id: str, current_user: User = Security(get_current_active_user, scopes=["photos.write"])):
|
||||
|
||||
@ -179,7 +199,7 @@ async def photo_delete(id: str, current_user: User = Security(get_current_active
|
||||
return Response(status_code=HTTP_204_NO_CONTENT)
|
||||
|
||||
@app.get("/albums/{album}/photos", response_class=UJSONResponse, response_model=SearchResults, description="Find a photo by filename")
|
||||
async def photo_find(album: str, q: Union[str, None] = None, page: int = 1, page_size: int = 100, lat: Union[float, None] = None, lng: Union[float, None] = None, radius: Union[int, None] = None, current_user: User = Security(get_current_active_user, scopes=["photos.list"])):
|
||||
async def photo_find(album: str, q: Union[str, None] = None, caption: Union[str, None] = None, page: int = 1, page_size: int = 100, lat: Union[float, None] = None, lng: Union[float, None] = None, radius: Union[int, None] = None, current_user: User = Security(get_current_active_user, scopes=["photos.list"])):
|
||||
|
||||
if col_albums.find_one( {"user": current_user.user, "name": album} ) is None:
|
||||
return HTTPException(status_code=HTTP_404_NOT_FOUND, detail=f"Provided album '{album}' does not exist.")
|
||||
@ -195,11 +215,17 @@ async def photo_find(album: str, q: Union[str, None] = None, page: int = 1, page
|
||||
if (lat is not None) and (lng is not None):
|
||||
db_query = {"user": current_user.user, "album": album, "location": { "$nearSphere": {"$geometry": {"type": "Point", "coordinates": [lng, lat]}, "$maxDistance": radius} } }
|
||||
db_query_count = {"user": current_user.user, "album": album, "location": { "$geoWithin": { "$centerSphere": [ [lng, lat], radius ] } } }
|
||||
elif q is None:
|
||||
raise HTTPException(status_code=HTTP_422_UNPROCESSABLE_ENTITY, detail="You must provide query or coordinates to look for photos")
|
||||
else:
|
||||
elif q is None and caption is None:
|
||||
raise HTTPException(status_code=HTTP_422_UNPROCESSABLE_ENTITY, detail="You must provide query, caption or coordinates to look for photos")
|
||||
elif q is None and caption is not None:
|
||||
db_query = {"user": current_user.user, "album": album, "caption": re.compile(caption)}
|
||||
db_query_count = {"user": current_user.user, "album": album, "caption": re.compile(caption)}
|
||||
elif q is not None and caption is None:
|
||||
db_query = {"user": current_user.user, "album": album, "filename": re.compile(q)}
|
||||
db_query_count = {"user": current_user.user, "album": album, "filename": re.compile(q)}
|
||||
else:
|
||||
db_query = {"user": current_user.user, "album": album, "filename": re.compile(q), "caption": re.compile(caption)} # type: ignore
|
||||
db_query_count = {"user": current_user.user, "album": album, "filename": re.compile(q), "caption": re.compile(caption)} # type: ignore
|
||||
|
||||
images = list(col_photos.find(db_query, limit=page_size, skip=skip).sort('dates.uploaded', DESCENDING))
|
||||
|
||||
|
@ -2,6 +2,7 @@ import re
|
||||
import pickle
|
||||
from secrets import token_urlsafe
|
||||
from shutil import move
|
||||
from typing import Union
|
||||
from magic import Magic
|
||||
from datetime import datetime
|
||||
from os import makedirs, path, remove
|
||||
@ -16,11 +17,11 @@ from pymongo import DESCENDING
|
||||
|
||||
from fastapi import HTTPException, UploadFile, Security
|
||||
from fastapi.responses import UJSONResponse, Response
|
||||
from starlette.status import HTTP_204_NO_CONTENT, HTTP_400_BAD_REQUEST, HTTP_401_UNAUTHORIZED, HTTP_404_NOT_FOUND
|
||||
from starlette.status import HTTP_204_NO_CONTENT, HTTP_400_BAD_REQUEST, HTTP_401_UNAUTHORIZED, HTTP_404_NOT_FOUND, HTTP_422_UNPROCESSABLE_ENTITY
|
||||
|
||||
|
||||
@app.post("/albums/{album}/videos", response_class=UJSONResponse, response_model=Video, description="Upload a video to album")
|
||||
async def video_upload(file: UploadFile, album: str, current_user: User = Security(get_current_active_user, scopes=["videos.write"])):
|
||||
async def video_upload(file: UploadFile, album: str, caption: Union[str, None] = None, current_user: User = Security(get_current_active_user, scopes=["videos.write"])):
|
||||
|
||||
if col_albums.find_one( {"user": current_user.user, "name": album} ) is None:
|
||||
return HTTPException(status_code=HTTP_404_NOT_FOUND, detail=f"Provided album '{album}' does not exist.")
|
||||
@ -62,6 +63,7 @@ async def video_upload(file: UploadFile, album: str, current_user: User = Securi
|
||||
"uploaded": datetime.utcnow(),
|
||||
"modified": datetime.utcnow()
|
||||
},
|
||||
"caption": caption,
|
||||
# "location": [
|
||||
# coords["lng"],
|
||||
# coords["lat"],
|
||||
@ -130,6 +132,25 @@ async def video_move(id: str, album: str, current_user: User = Security(get_curr
|
||||
}
|
||||
)
|
||||
|
||||
@app.patch("/videos/{id}", description="Change properties of a video")
|
||||
async def video_patch(id: str, caption: str, current_user: User = Security(get_current_active_user, scopes=["videos.write"])):
|
||||
|
||||
try:
|
||||
video = col_videos.find_one( {"_id": ObjectId(id)} )
|
||||
if video is None:
|
||||
raise InvalidId(id)
|
||||
except InvalidId:
|
||||
return HTTPException(status_code=HTTP_404_NOT_FOUND, detail="Could not find an video with such id.")
|
||||
|
||||
col_videos.find_one_and_update( {"_id": ObjectId(id)}, {"$set": {"caption": caption, "dates.modified": datetime.utcnow()}} )
|
||||
|
||||
return UJSONResponse(
|
||||
{
|
||||
"id": video["_id"].__str__(),
|
||||
"filename": caption
|
||||
}
|
||||
)
|
||||
|
||||
@app.delete("/videos/{id}", description="Delete a video by id")
|
||||
async def video_delete(id: str, current_user: User = Security(get_current_active_user, scopes=["videos.write"])):
|
||||
|
||||
@ -147,7 +168,7 @@ async def video_delete(id: str, current_user: User = Security(get_current_active
|
||||
return Response(status_code=HTTP_204_NO_CONTENT)
|
||||
|
||||
@app.get("/albums/{album}/videos", response_class=UJSONResponse, response_model=SearchResults, description="Find a video by filename")
|
||||
async def video_find(q: str, album: str, page: int = 1, page_size: int = 100, current_user: User = Security(get_current_active_user, scopes=["videos.list"])):
|
||||
async def video_find(album: str, q: Union[str, None] = None, caption: Union[str, None] = None, page: int = 1, page_size: int = 100, current_user: User = Security(get_current_active_user, scopes=["videos.list"])):
|
||||
|
||||
if col_albums.find_one( {"user": current_user.user, "name": album} ) is None:
|
||||
return HTTPException(status_code=HTTP_404_NOT_FOUND, detail=f"Provided album '{album}' does not exist.")
|
||||
@ -157,12 +178,26 @@ async def video_find(q: str, album: str, page: int = 1, page_size: int = 100, cu
|
||||
|
||||
output = {"results": []}
|
||||
skip = (page-1)*page_size
|
||||
videos = list(col_videos.find({"user": current_user.user, "album": album, "filename": re.compile(q)}, limit=page_size, skip=skip).sort('dates.uploaded', DESCENDING))
|
||||
|
||||
if q is None and caption is None:
|
||||
raise HTTPException(status_code=HTTP_422_UNPROCESSABLE_ENTITY, detail="You must provide query or caption to look for videos")
|
||||
|
||||
if q is None and caption is not None:
|
||||
db_query = {"user": current_user.user, "album": album, "caption": re.compile(caption)}
|
||||
db_query_count = {"user": current_user.user, "album": album, "caption": re.compile(caption)}
|
||||
elif q is not None and caption is None:
|
||||
db_query = list(col_videos.find({"user": current_user.user, "album": album, "filename": re.compile(q)}, limit=page_size, skip=skip).sort('dates.uploaded', DESCENDING))
|
||||
db_query_count = {"user": current_user.user, "album": album, "caption": re.compile(q)}
|
||||
else:
|
||||
db_query = list(col_videos.find({"user": current_user.user, "album": album, "filename": re.compile(q), "caption": re.compile(caption)}, limit=page_size, skip=skip).sort('dates.uploaded', DESCENDING)) # type: ignore
|
||||
db_query_count = {"user": current_user.user, "album": album, "filename": re.compile(q), "caption": re.compile(caption)} # type: ignore
|
||||
|
||||
videos = list(col_videos.find(db_query, limit=page_size, skip=skip).sort('dates.uploaded', DESCENDING))
|
||||
|
||||
for video in videos:
|
||||
output["results"].append({"id": video["_id"].__str__(), "filename": video["filename"]})
|
||||
|
||||
if col_videos.count_documents( {"user": current_user.user, "album": album, "filename": re.compile(q)} ) > page*page_size:
|
||||
if col_videos.count_documents( db_query_count ) > page*page_size:
|
||||
token = str(token_urlsafe(32))
|
||||
col_tokens.insert_one( {"token": token, "query": q, "album": album, "page": page+1, "page_size": page_size, "user": pickle.dumps(current_user)} )
|
||||
output["next_page"] = f"/albums/{album}/videos/token?token={token}" # type: ignore
|
||||
|
Loading…
Reference in New Issue
Block a user