fix(vod): enhance metadata extraction for actors and preserve existing values

This commit is contained in:
SergeantPanda 2026-05-29 21:18:16 -05:00
parent ac84916974
commit fc867b7f77

View file

@ -439,16 +439,14 @@ def process_movie_batch(account, batch, categories, relations, scan_start_time=N
trailer = extract_string_from_array_or_string(trailer_raw) if trailer_raw else None
logo_url = movie_data.get('stream_icon') or ''
# Extract optional metadata fields supplied by the XC provider in
# get_vod_streams. Stored in custom_properties so that the
# provider-info endpoint (and the XC vod_info passthrough) can
# return them without a separate per-movie API call.
director = extract_string_from_array_or_string(
movie_data.get('director') or ''
)
actors = extract_string_from_array_or_string(
movie_data.get('actors') or movie_data.get('cast') or ''
)
actors_raw = movie_data.get('actors') or movie_data.get('cast') or ''
if isinstance(actors_raw, list):
actors = ', '.join(s.strip() for s in actors_raw if s and str(s).strip()) or None
else:
actors = actors_raw.strip() if actors_raw else None
release_date = movie_data.get('release_date') or movie_data.get('releasedate') or ''
custom_props = {}
@ -570,12 +568,7 @@ def process_movie_batch(account, batch, categories, relations, scan_start_time=N
for field, value in movie_props.items():
if field == 'custom_properties':
# Merge incoming props into the existing dict so that
# detailed_info and other keys written by advanced refresh
# are not lost when a basic sync runs afterwards.
# For metadata fields (director/actors/release_date), only
# write if the field is empty — advanced refresh may have
# stored richer data that basic sync must not overwrite.
# Merge: preserve advanced-refresh keys; don't overwrite director/actors/release_date if already set.
existing_cp = movie.custom_properties or {}
incoming_cp = value or {}
merged = dict(existing_cp)
@ -601,8 +594,6 @@ def process_movie_batch(account, batch, categories, relations, scan_start_time=N
movie._logo_to_update = new_logo
logo_updated = True
elif movie.logo_id:
# Logo URL exists but logo creation failed or logo not found
# Clear the orphaned logo reference
logger.warning(f"Logo URL provided but logo not found in database for movie '{movie.name}', clearing logo reference")
movie._logo_to_update = None
logo_updated = True
@ -821,7 +812,14 @@ def process_series_batch(account, batch, categories, relations, scan_start_time=
value = series_data.get(key)
if value:
# For string-like fields that might be arrays, extract clean strings
if key in ['poster_path', 'youtube_trailer', 'cast', 'director']:
if key == 'cast':
if isinstance(value, list):
clean_value = ', '.join(s.strip() for s in value if s and str(s).strip()) or None
else:
clean_value = extract_string_from_array_or_string(value)
if clean_value:
additional_metadata[key] = clean_value
elif key in ['poster_path', 'youtube_trailer', 'director']:
clean_value = extract_string_from_array_or_string(value)
if clean_value:
additional_metadata[key] = clean_value
@ -2193,26 +2191,25 @@ def refresh_movie_advanced_data(m3u_movie_relation_id, force_refresh=False):
movie.imdb_id = imdb_id_to_set
updated = True
logger.debug(f"Set imdb_id {imdb_id_to_set} on movie {movie.id}")
# Only update trailer if we have a non-empty value and either no existing value or existing value is empty
if should_update_field(custom_props.get('youtube_trailer'), info.get('trailer')):
custom_props['youtube_trailer'] = extract_string_from_array_or_string(info.get('trailer'))
updated = True
if should_update_field(custom_props.get('youtube_trailer'), info.get('youtube_trailer')):
custom_props['youtube_trailer'] = extract_string_from_array_or_string(info.get('youtube_trailer'))
updated = True
# Only update backdrop_path if we have a non-empty value and either no existing value or existing value is empty
if should_update_field(custom_props.get('backdrop_path'), info.get('backdrop_path')):
backdrop_url = extract_string_from_array_or_string(info.get('backdrop_path'))
custom_props['backdrop_path'] = [backdrop_url] if backdrop_url else None
updated = True
# Only update actors if we have a non-empty value and either no existing value or existing value is empty
if should_update_field(custom_props.get('actors'), info.get('actors')):
custom_props['actors'] = extract_string_from_array_or_string(info.get('actors'))
updated = True
if should_update_field(custom_props.get('actors'), info.get('cast')):
custom_props['actors'] = extract_string_from_array_or_string(info.get('cast'))
updated = True
# Only update director if we have a non-empty value and either no existing value or existing value is empty
for actors_key in ('actors', 'cast'):
actors_raw = info.get(actors_key)
if should_update_field(custom_props.get('actors'), actors_raw):
if isinstance(actors_raw, list):
custom_props['actors'] = ', '.join(s.strip() for s in actors_raw if s and str(s).strip()) or None
else:
custom_props['actors'] = extract_string_from_array_or_string(actors_raw)
updated = True
break
if should_update_field(custom_props.get('director'), info.get('director')):
custom_props['director'] = extract_string_from_array_or_string(info.get('director'))
updated = True