Processes a batch of M3U streams using bulk operations with thread-safe DB connections.
(account_id, batch, groups, hash_keys)
| 1160 | |
| 1161 | |
| 1162 | def process_m3u_batch_direct(account_id, batch, groups, hash_keys): |
| 1163 | """Processes a batch of M3U streams using bulk operations with thread-safe DB connections.""" |
| 1164 | from django.db import connections |
| 1165 | |
| 1166 | # Ensure clean database connections for threading |
| 1167 | connections.close_all() |
| 1168 | |
| 1169 | account = M3UAccount.objects.get(id=account_id) |
| 1170 | |
| 1171 | compiled_filters = [ |
| 1172 | ( |
| 1173 | re.compile( |
| 1174 | f.regex_pattern, |
| 1175 | ( |
| 1176 | re.IGNORECASE |
| 1177 | if (f.custom_properties or {}).get( |
| 1178 | "case_sensitive", True |
| 1179 | ) |
| 1180 | == False |
| 1181 | else 0 |
| 1182 | ), |
| 1183 | ), |
| 1184 | f, |
| 1185 | ) |
| 1186 | for f in account.filters.order_by("order") |
| 1187 | ] |
| 1188 | |
| 1189 | streams_to_create = [] |
| 1190 | streams_to_update = [] |
| 1191 | stream_hashes = {} |
| 1192 | |
| 1193 | name_max_length = Stream._meta.get_field('name').max_length |
| 1194 | |
| 1195 | logger.debug(f"Processing batch of {len(batch)} for M3U account {account_id}") |
| 1196 | if compiled_filters: |
| 1197 | logger.debug(f"Using compiled filters: {[f[1].regex_pattern for f in compiled_filters]}") |
| 1198 | for stream_info in batch: |
| 1199 | try: |
| 1200 | name, url = stream_info["name"], stream_info["url"] |
| 1201 | |
| 1202 | # Validate URL length - maximum of 4096 characters |
| 1203 | if url and len(url) > 4096: |
| 1204 | logger.warning(f"Skipping stream '{name}': URL too long ({len(url)} characters, max 4096)") |
| 1205 | continue |
| 1206 | |
| 1207 | # Truncate name if it exceeds the model field limit |
| 1208 | if name and len(name) > name_max_length: |
| 1209 | logger.warning(f"Stream name too long ({len(name)} > {name_max_length}), truncating: {name[:80]}...") |
| 1210 | name = name[:name_max_length] |
| 1211 | |
| 1212 | tvg_id, tvg_logo = get_case_insensitive_attr( |
| 1213 | stream_info["attributes"], "tvg-id", "" |
| 1214 | ), get_case_insensitive_attr(stream_info["attributes"], "tvg-logo", "") |
| 1215 | group_title = get_case_insensitive_attr( |
| 1216 | stream_info["attributes"], "group-title", "Default Group" |
| 1217 | ) |
| 1218 | logger.debug(f"Processing stream: {name} - {url} in group {group_title}") |
| 1219 | include = True |