Dispatcharr/apps/m3u/forms.py
SergeantPanda 46695588f7 fix(m3u): enhance custom properties handling and DB connection management
- Implemented `ensure_custom_properties_dict()` to normalize custom properties across various models and serializers, addressing issues with legacy JSON-encoded strings.
- Updated M3U account and channel group models to ensure custom properties are consistently stored as dictionaries during save operations.
- Enhanced Celery task management by ensuring old DB connections are closed before and after tasks, improving reliability and preventing errors during account refresh operations. (Fixes #1338)
2026-06-18 14:59:09 -05:00

83 lines
2.7 KiB
Python

# apps/m3u/forms.py
from django import forms
from .models import M3UAccount, M3UFilter
from core.utils import ensure_custom_properties_dict
import re
class M3UAccountForm(forms.ModelForm):
enable_vod = forms.BooleanField(
required=False,
initial=False,
label="Enable VOD Content",
help_text="Parse and import VOD (movies/series) content for XtreamCodes accounts"
)
class Meta:
model = M3UAccount
fields = [
'name',
'server_url',
'uploaded_file',
'server_group',
'max_streams',
'is_active',
'enable_vod',
]
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
# Set initial value for enable_vod from custom_properties
if self.instance and self.instance.custom_properties:
custom_props = self.instance.custom_properties
if not isinstance(custom_props, dict):
custom_props = ensure_custom_properties_dict(custom_props)
self.fields['enable_vod'].initial = custom_props.get('enable_vod', False)
def save(self, commit=True):
instance = super().save(commit=False)
# Handle enable_vod field
enable_vod = self.cleaned_data.get('enable_vod', False)
custom_props = instance.custom_properties or {}
if not isinstance(custom_props, dict):
custom_props = ensure_custom_properties_dict(custom_props)
# Update VOD preference
custom_props['enable_vod'] = enable_vod
instance.custom_properties = custom_props
if commit:
instance.save()
return instance
def clean_uploaded_file(self):
uploaded_file = self.cleaned_data.get('uploaded_file')
if uploaded_file:
if not uploaded_file.name.endswith('.m3u'):
raise forms.ValidationError("The uploaded file must be an M3U file.")
return uploaded_file
def clean(self):
cleaned_data = super().clean()
url = cleaned_data.get('server_url')
file = cleaned_data.get('uploaded_file')
# Ensure either `server_url` or `uploaded_file` is provided
if not url and not file:
raise forms.ValidationError("Either an M3U URL or a file upload is required.")
return cleaned_data
class M3UFilterForm(forms.ModelForm):
class Meta:
model = M3UFilter
fields = ['m3u_account', 'filter_type', 'regex_pattern', 'exclude']
def clean_regex_pattern(self):
pattern = self.cleaned_data['regex_pattern']
try:
re.compile(pattern)
except re.error:
raise forms.ValidationError("Invalid regex pattern")
return pattern