Skip to content

Commit

Permalink
[10] Add API endpoints for mask file uploading/deleting
Browse files Browse the repository at this point in the history
PUT and DELETE /api/sources/episode/{episode_id}/mask
  • Loading branch information
CollinHeist committed Nov 6, 2024
1 parent 01c187e commit c4aca9b
Show file tree
Hide file tree
Showing 3 changed files with 87 additions and 3 deletions.
22 changes: 20 additions & 2 deletions app/models/episode.py
Original file line number Diff line number Diff line change
Expand Up @@ -461,6 +461,24 @@ def get_source_file(self, style: Style) -> Path:
).resolve()


def get_mask_file(self) -> Path:
"""
Get the mask image associated with this Episode.
Returns:
Path to the mask file for this Episode.
"""

source_name = (
self.source_file
or f's{self.season_number}e{self.episode_number}-mask.png'
)

return get_preferences().source_directory \
/ self.series.path_safe_name \
/ source_name


@property
def watched_statuses_flat(self) -> dict[str, bool]:
"""
Expand Down Expand Up @@ -525,14 +543,14 @@ def add_watched_status(self,
current = self.watched_statuses.get(key)
self.watched_statuses[key] = status.status
if current != status.status:
log.trace(f'{self} Updating watched status '
log.trace(f'{self} updating watched status '
f'({current} -> {status.status})')

return current != status.status

# Interface has no mappings, add
self.watched_statuses[key] = status.status
log.trace(f'{self} Adding watched status')
log.trace(f'{self} adding watched status')
return True


Expand Down
66 changes: 66 additions & 0 deletions app/routers/sources.py
Original file line number Diff line number Diff line change
Expand Up @@ -765,3 +765,69 @@ def delete_series_backdrop(

file.unlink(missing_ok=True)
request.state.log.debug(f'Deleted file ({file.resolve()})')


@source_router.put('/episode/{episode_id}/mask')
async def upload_episode_mask_image(
request: Request,
episode_id: int,
file: UploadFile,
db: Session = Depends(get_database),
) -> None:
"""
"""

# Get contextual logger
log: Logger = request.state.log

# Get Episode with this ID, raise 404 if DNE
episode = get_episode(db, episode_id, raise_exc=True)

# Send error if no image content was provided
if not (uploaded_file := await file.read()):
raise HTTPException(
status_code=422,
detail='URL or file are required',
)

# If file already exists, warn about overwriting
if (mask_file := episode.get_mask_file()).exists():
log.info(f'{episode} mask image "{mask_file}" exists - replacing')

# Write content directly
mask_file.write_bytes(uploaded_file)
log.debug(f'Wrote {len(uploaded_file)} bytes to {mask_file}')

# Delete associated Card and Loaded entry to initiate future reload
delete_cards(
db,
db.query(CardModel).filter_by(episode_id=episode_id),
db.query(LoadedModel).filter_by(episode_id=episode_id),
log=log,
)


@source_router.delete('/episode/{episode_id}/mask')
def delete_episode_mask_image(
request: Request,
episode_id: int,
db: Session = Depends(get_database),
) -> None:
"""
Delete the mask image for the given Episode.
- episode_id: ID of the Episode whose mask file to delete.
"""

# Get Episode with this ID, raise 404 if DNE
episode = get_episode(db, episode_id, raise_exc=True)

if not (mask_file := episode.get_mask_file()).exists():
raise HTTPException(
status_code=404,
detail='Episode does not have a mask image',
)

mask_file.unlink(missing_ok=True)
request.state.log.debug(f'Deleting {episode} "{mask_file}"')
2 changes: 1 addition & 1 deletion modules/ref/version_webui
Original file line number Diff line number Diff line change
@@ -1 +1 @@
v2.0-alpha.13.0-webui9
v2.0-alpha.13.0-webui10

0 comments on commit c4aca9b

Please sign in to comment.