feat: add support for media asset tags and conditional database handling
All checks were successful
Deploy Development / deploy (push) Successful in 34s
Test Suite / pytest-backend (push) Successful in 24s
Test Suite / lint-backend (push) Successful in 1s
Test Suite / build-frontend (push) Successful in 7s
Test Suite / playwright-tests (push) Successful in 24s
All checks were successful
Deploy Development / deploy (push) Successful in 34s
Test Suite / pytest-backend (push) Successful in 24s
Test Suite / lint-backend (push) Successful in 1s
Test Suite / build-frontend (push) Successful in 7s
Test Suite / playwright-tests (push) Successful in 24s
- Introduced a function to check for the presence of the 'tags' column in the media_assets table, ensuring compatibility with database migrations. - Updated media asset listing and patching functions to conditionally include tags based on the presence of the 'tags' column. - Enhanced error handling for operations involving tags, providing clear feedback when the required database migration has not been performed. - Improved search functionality to account for the presence of tags, optimizing queries based on available database schema.
This commit is contained in:
parent
1bc7ea95fb
commit
084ac38c2e
|
|
@ -102,6 +102,27 @@ _MEDIA_KIND_FILTERS = frozenset({"all", "image", "video", "pdf", "other"})
|
|||
_MAX_TAGS = 40
|
||||
_MAX_TAG_LEN = 48
|
||||
|
||||
_MEDIA_ASSETS_TAGS_COLUMN: Optional[bool] = None
|
||||
|
||||
|
||||
def _media_assets_tags_column_present(cur: Any) -> bool:
|
||||
"""True nach Migration 046; verhindert 500 wenn Code neuer ist als das Schema."""
|
||||
global _MEDIA_ASSETS_TAGS_COLUMN
|
||||
if _MEDIA_ASSETS_TAGS_COLUMN is not None:
|
||||
return _MEDIA_ASSETS_TAGS_COLUMN
|
||||
cur.execute(
|
||||
"""
|
||||
SELECT 1
|
||||
FROM information_schema.columns
|
||||
WHERE table_schema = 'public'
|
||||
AND table_name = 'media_assets'
|
||||
AND column_name = 'tags'
|
||||
LIMIT 1
|
||||
"""
|
||||
)
|
||||
_MEDIA_ASSETS_TAGS_COLUMN = cur.fetchone() is not None
|
||||
return _MEDIA_ASSETS_TAGS_COLUMN
|
||||
|
||||
|
||||
def _normalize_media_tags(raw: Union[list[str], None]) -> list[str]:
|
||||
"""PostgreSQL text[]; Einträge gekürzt und ohne Dubletten (case-insensitive)."""
|
||||
|
|
@ -479,6 +500,9 @@ def list_media_assets(
|
|||
if uploaded_by is not None and not show_uploader:
|
||||
raise HTTPException(status_code=403, detail="Uploader-Filter nicht erlaubt")
|
||||
|
||||
has_tags_col = _media_assets_tags_column_present(cur)
|
||||
tags_select = "ma.tags," if has_tags_col else "ARRAY[]::text[] AS tags,"
|
||||
|
||||
uploaded_sql = ""
|
||||
uploaded_params: list[Any] = []
|
||||
if uploaded_by is not None:
|
||||
|
|
@ -489,12 +513,19 @@ def list_media_assets(
|
|||
search_params: list[Any] = []
|
||||
if needle:
|
||||
like = f"%{needle}%"
|
||||
search_params = [like, like, like, like]
|
||||
search_sql = (
|
||||
" AND (ma.original_filename ILIKE %s OR ma.storage_key ILIKE %s"
|
||||
" OR COALESCE(ma.copyright_notice, '') ILIKE %s"
|
||||
" OR EXISTS (SELECT 1 FROM unnest(ma.tags) AS t WHERE t::text ILIKE %s))"
|
||||
)
|
||||
if has_tags_col:
|
||||
search_params = [like, like, like, like]
|
||||
search_sql = (
|
||||
" AND (ma.original_filename ILIKE %s OR ma.storage_key ILIKE %s"
|
||||
" OR COALESCE(ma.copyright_notice, '') ILIKE %s"
|
||||
" OR EXISTS (SELECT 1 FROM unnest(ma.tags) AS t WHERE t::text ILIKE %s))"
|
||||
)
|
||||
else:
|
||||
search_params = [like, like, like]
|
||||
search_sql = (
|
||||
" AND (ma.original_filename ILIKE %s OR ma.storage_key ILIKE %s"
|
||||
" OR COALESCE(ma.copyright_notice, '') ILIKE %s)"
|
||||
)
|
||||
|
||||
params: list[Any] = (
|
||||
[is_adm, profile_id, profile_id]
|
||||
|
|
@ -507,7 +538,7 @@ def list_media_assets(
|
|||
cur.execute(
|
||||
f"""SELECT ma.id, ma.mime_type, ma.byte_size, ma.original_filename, ma.visibility, ma.club_id,
|
||||
ma.uploaded_by_profile_id, ma.lifecycle_state, ma.created_at, ma.sha256,
|
||||
ma.copyright_notice, ma.storage_key, ma.tags,
|
||||
ma.copyright_notice, ma.storage_key, {tags_select}
|
||||
pr.name AS uploader_name,
|
||||
pr.email AS uploader_email,
|
||||
cl.name AS club_name
|
||||
|
|
@ -682,6 +713,15 @@ def bulk_media_patch(
|
|||
asset = r2d(row)
|
||||
assert_can_edit_media_asset_metadata(cur, tenant, asset)
|
||||
|
||||
if "tags" in patch_fields and not _media_assets_tags_column_present(cur):
|
||||
failed.append(
|
||||
{
|
||||
"id": asset_id,
|
||||
"detail": "Schlagwörter (tags) erfordern DB-Migration 046.",
|
||||
}
|
||||
)
|
||||
continue
|
||||
|
||||
eff = _effective_media_patch_fields(patch_fields, asset)
|
||||
next_vis = str(eff.get("visibility", asset["visibility"])).strip().lower()
|
||||
next_cid = eff["club_id"] if "club_id" in eff else asset.get("club_id")
|
||||
|
|
@ -753,6 +793,12 @@ def patch_media_asset(
|
|||
asset = r2d(row)
|
||||
assert_can_edit_media_asset_metadata(cur, tenant, asset)
|
||||
|
||||
if "tags" in data and not _media_assets_tags_column_present(cur):
|
||||
raise HTTPException(
|
||||
status_code=503,
|
||||
detail="Schlagwörter (tags) erfordern die Datenbank-Migration 046. Bitte Migration ausführen.",
|
||||
)
|
||||
|
||||
eff = _effective_media_patch_fields(data, asset)
|
||||
next_vis = str(eff.get("visibility", asset["visibility"])).strip().lower()
|
||||
next_cid = eff["club_id"] if "club_id" in eff else asset.get("club_id")
|
||||
|
|
@ -789,11 +835,22 @@ def patch_media_asset(
|
|||
tuple(vals),
|
||||
)
|
||||
conn.commit()
|
||||
cur.execute(
|
||||
"""SELECT id, mime_type, byte_size, original_filename, visibility, club_id,
|
||||
uploaded_by_profile_id, lifecycle_state, created_at, sha256, copyright_notice, tags
|
||||
FROM media_assets WHERE id = %s""",
|
||||
(asset_id,),
|
||||
)
|
||||
has_tags = _media_assets_tags_column_present(cur)
|
||||
if has_tags:
|
||||
cur.execute(
|
||||
"""SELECT id, mime_type, byte_size, original_filename, visibility, club_id,
|
||||
uploaded_by_profile_id, lifecycle_state, created_at, sha256, copyright_notice, tags
|
||||
FROM media_assets WHERE id = %s""",
|
||||
(asset_id,),
|
||||
)
|
||||
else:
|
||||
cur.execute(
|
||||
"""SELECT id, mime_type, byte_size, original_filename, visibility, club_id,
|
||||
uploaded_by_profile_id, lifecycle_state, created_at, sha256, copyright_notice
|
||||
FROM media_assets WHERE id = %s""",
|
||||
(asset_id,),
|
||||
)
|
||||
out = r2d(cur.fetchone())
|
||||
return out
|
||||
if not has_tags:
|
||||
out["tags"] = []
|
||||
return out
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user