Added custom properties to programme

This commit is contained in:
SergeantPanda 2025-04-03 14:31:04 -05:00
parent d2dbbcc136
commit 990a9ec7b7
2 changed files with 171 additions and 3 deletions

View file

@ -177,15 +177,97 @@ def parse_programs_for_tvg_id(epg_id):
end_time = parse_xmltv_time(prog.get('stop'))
title = prog.findtext('title', default='No Title')
desc = prog.findtext('desc', default='')
sub_title = prog.findtext('sub-title', default='')
# Extract custom properties
custom_props = {}
# Extract categories
categories = []
for cat_elem in prog.findall('category'):
if cat_elem.text and cat_elem.text.strip():
categories.append(cat_elem.text.strip())
if categories:
custom_props['categories'] = categories
# Extract episode numbers
for ep_num in prog.findall('episode-num'):
system = ep_num.get('system', '')
if system == 'xmltv_ns' and ep_num.text:
# Parse XMLTV episode-num format (season.episode.part)
parts = ep_num.text.split('.')
if len(parts) >= 2:
if parts[0].strip() != '':
try:
season = int(parts[0]) + 1 # XMLTV format is zero-based
custom_props['season'] = season
except ValueError:
pass
if parts[1].strip() != '':
try:
episode = int(parts[1]) + 1 # XMLTV format is zero-based
custom_props['episode'] = episode
except ValueError:
pass
elif system == 'onscreen' and ep_num.text:
# Just store the raw onscreen format
custom_props['onscreen_episode'] = ep_num.text.strip()
# Extract ratings
for rating_elem in prog.findall('rating'):
if rating_elem.findtext('value'):
custom_props['rating'] = rating_elem.findtext('value').strip()
if rating_elem.get('system'):
custom_props['rating_system'] = rating_elem.get('system')
break # Just use the first rating
# Extract credits (actors, directors, etc.)
credits_elem = prog.find('credits')
if credits_elem is not None:
credits = {}
for credit_type in ['director', 'actor', 'writer', 'presenter', 'producer']:
elements = credits_elem.findall(credit_type)
if elements:
names = [e.text.strip() for e in elements if e.text and e.text.strip()]
if names:
credits[credit_type] = names
if credits:
custom_props['credits'] = credits
# Extract other common program metadata
if prog.findtext('date'):
custom_props['year'] = prog.findtext('date').strip()[:4] # Just the year part
if prog.findtext('country'):
custom_props['country'] = prog.findtext('country').strip()
for icon_elem in prog.findall('icon'):
if icon_elem.get('src'):
custom_props['icon'] = icon_elem.get('src')
break # Just use the first icon
for kw in ['previously-shown', 'premiere', 'new']:
if prog.find(kw) is not None:
custom_props[kw.replace('-', '_')] = True
# Convert custom_props to JSON string if not empty
custom_properties_json = None
if custom_props:
import json
try:
custom_properties_json = json.dumps(custom_props)
except Exception as e:
logger.error(f"Error serializing custom properties to JSON: {e}", exc_info=True)
programs_to_create.append(ProgramData(
epg=epg,
start_time=start_time,
title=title,
end_time=end_time,
title=title,
description=desc,
sub_title='',
sub_title=sub_title,
tvg_id=epg.tvg_id,
custom_properties=custom_properties_json
))
ProgramData.objects.bulk_create(programs_to_create)

View file

@ -105,7 +105,93 @@ def generate_epg(request, profile_name=None):
stop_str = prog.end_time.strftime("%Y%m%d%H%M%S %z")
xml_lines.append(f' <programme start="{start_str}" stop="{stop_str}" channel="{channel_id}">')
xml_lines.append(f' <title>{prog.title}</title>')
xml_lines.append(f' <desc>{prog.description}</desc>')
# Add subtitle if available
if prog.sub_title:
xml_lines.append(f' <sub-title>{prog.sub_title}</sub-title>')
# Add description if available
if prog.description:
xml_lines.append(f' <desc>{prog.description}</desc>')
# Process custom properties if available
if prog.custom_properties:
try:
import json
custom_data = json.loads(prog.custom_properties)
# Add categories if available
if 'categories' in custom_data and custom_data['categories']:
for category in custom_data['categories']:
xml_lines.append(f' <category>{category}</category>')
# Handle episode numbering - multiple formats supported
# Standard episode number if available
if 'episode' in custom_data:
xml_lines.append(f' <episode-num system="onscreen">E{custom_data["episode"]}</episode-num>')
# Handle onscreen episode format (like S06E128)
if 'onscreen_episode' in custom_data:
xml_lines.append(f' <episode-num system="onscreen">{custom_data["onscreen_episode"]}</episode-num>')
# Add season and episode numbers in xmltv_ns format if available
if 'season' in custom_data and 'episode' in custom_data:
season = int(custom_data['season']) - 1 if str(custom_data['season']).isdigit() else 0
episode = int(custom_data['episode']) - 1 if str(custom_data['episode']).isdigit() else 0
xml_lines.append(f' <episode-num system="xmltv_ns">{season}.{episode}.</episode-num>')
# Add rating if available
if 'rating' in custom_data:
rating_system = custom_data.get('rating_system', 'TV Parental Guidelines')
xml_lines.append(f' <rating system="{rating_system}">')
xml_lines.append(f' <value>{custom_data["rating"]}</value>')
xml_lines.append(f' </rating>')
# Add actors/directors/writers if available
if 'credits' in custom_data:
xml_lines.append(f' <credits>')
for role, people in custom_data['credits'].items():
if isinstance(people, list):
for person in people:
xml_lines.append(f' <{role}>{person}</{role}>')
else:
xml_lines.append(f' <{role}>{people}</{role}>')
xml_lines.append(f' </credits>')
# Add program date/year if available
if 'year' in custom_data:
xml_lines.append(f' <date>{custom_data["year"]}</date>')
# Add country if available
if 'country' in custom_data:
xml_lines.append(f' <country>{custom_data["country"]}</country>')
# Add icon if available
if 'icon' in custom_data:
xml_lines.append(f' <icon src="{custom_data["icon"]}" />')
# Add special flags as proper tags
if custom_data.get('previously_shown', False):
xml_lines.append(f' <previously-shown />')
if custom_data.get('premiere', False):
xml_lines.append(f' <premiere />')
if custom_data.get('new', False):
xml_lines.append(f' <new />')
# Define all properties we specifically handle to avoid adding them as comments
skip_keys = [
'categories', 'episode', 'season', 'rating', 'rating_system', 'credits',
'year', 'country', 'icon', 'previously_shown', 'premiere', 'new',
'onscreen_episode'
]
# Don't add comments for standard properties - XMLTV clients don't need them
# and they just clutter the output
except Exception as e:
xml_lines.append(f' <!-- Error parsing custom properties: {str(e)} -->')
xml_lines.append(' </programme>')
xml_lines.append('</tv>')