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")
|
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")
|
@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:
|
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.")
|
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["lng"],
|
||||||
coords["lat"],
|
coords["lat"],
|
||||||
coords["alt"]
|
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")
|
@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"])):
|
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)
|
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")
|
@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:
|
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.")
|
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):
|
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 = {"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 ] } } }
|
db_query_count = {"user": current_user.user, "album": album, "location": { "$geoWithin": { "$centerSphere": [ [lng, lat], radius ] } } }
|
||||||
elif q is None:
|
elif q is None and caption is None:
|
||||||
raise HTTPException(status_code=HTTP_422_UNPROCESSABLE_ENTITY, detail="You must provide query or coordinates to look for photos")
|
raise HTTPException(status_code=HTTP_422_UNPROCESSABLE_ENTITY, detail="You must provide query, caption or coordinates to look for photos")
|
||||||
else:
|
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 = {"user": current_user.user, "album": album, "filename": re.compile(q)}
|
||||||
db_query_count = {"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))
|
images = list(col_photos.find(db_query, limit=page_size, skip=skip).sort('dates.uploaded', DESCENDING))
|
||||||
|
|
||||||
|
@ -2,6 +2,7 @@ import re
|
|||||||
import pickle
|
import pickle
|
||||||
from secrets import token_urlsafe
|
from secrets import token_urlsafe
|
||||||
from shutil import move
|
from shutil import move
|
||||||
|
from typing import Union
|
||||||
from magic import Magic
|
from magic import Magic
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
from os import makedirs, path, remove
|
from os import makedirs, path, remove
|
||||||
@ -16,11 +17,11 @@ from pymongo import DESCENDING
|
|||||||
|
|
||||||
from fastapi import HTTPException, UploadFile, Security
|
from fastapi import HTTPException, UploadFile, Security
|
||||||
from fastapi.responses import UJSONResponse, Response
|
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")
|
@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:
|
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.")
|
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(),
|
"uploaded": datetime.utcnow(),
|
||||||
"modified": datetime.utcnow()
|
"modified": datetime.utcnow()
|
||||||
},
|
},
|
||||||
|
"caption": caption,
|
||||||
# "location": [
|
# "location": [
|
||||||
# coords["lng"],
|
# coords["lng"],
|
||||||
# coords["lat"],
|
# 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")
|
@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"])):
|
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)
|
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")
|
@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:
|
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.")
|
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": []}
|
output = {"results": []}
|
||||||
skip = (page-1)*page_size
|
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:
|
for video in videos:
|
||||||
output["results"].append({"id": video["_id"].__str__(), "filename": video["filename"]})
|
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))
|
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)} )
|
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
|
output["next_page"] = f"/albums/{album}/videos/token?token={token}" # type: ignore
|
||||||
|
Loading…
Reference in New Issue
Block a user