Represents a single stream (e.g. from an M3U source or custom URL).
| 53 | |
| 54 | |
| 55 | class Stream(models.Model): |
| 56 | """ |
| 57 | Represents a single stream (e.g. from an M3U source or custom URL). |
| 58 | """ |
| 59 | |
| 60 | name = models.CharField(max_length=512, default="Default Stream", db_index=True) |
| 61 | url = models.URLField(max_length=4096, blank=True, null=True) |
| 62 | m3u_account = models.ForeignKey( |
| 63 | M3UAccount, |
| 64 | on_delete=models.CASCADE, |
| 65 | null=True, |
| 66 | blank=True, |
| 67 | related_name="streams", |
| 68 | ) |
| 69 | logo_url = models.TextField(blank=True, null=True) |
| 70 | tvg_id = models.CharField(max_length=255, blank=True, null=True) |
| 71 | local_file = models.FileField(upload_to="uploads/", blank=True, null=True) |
| 72 | current_viewers = models.PositiveIntegerField(default=0) |
| 73 | updated_at = models.DateTimeField(auto_now=True) |
| 74 | channel_group = models.ForeignKey( |
| 75 | ChannelGroup, |
| 76 | on_delete=models.SET_NULL, |
| 77 | null=True, |
| 78 | blank=True, |
| 79 | related_name="streams", |
| 80 | ) |
| 81 | stream_profile = models.ForeignKey( |
| 82 | StreamProfile, |
| 83 | null=True, |
| 84 | blank=True, |
| 85 | on_delete=models.SET_NULL, |
| 86 | related_name="streams", |
| 87 | ) |
| 88 | is_custom = models.BooleanField( |
| 89 | default=False, |
| 90 | help_text="Whether this is a user-created stream or from an M3U account", |
| 91 | ) |
| 92 | stream_hash = models.CharField( |
| 93 | max_length=255, |
| 94 | null=True, |
| 95 | unique=True, |
| 96 | help_text="Unique hash for this stream from the M3U account", |
| 97 | db_index=True, |
| 98 | ) |
| 99 | last_seen = models.DateTimeField(db_index=True, default=timezone.now) |
| 100 | is_stale = models.BooleanField( |
| 101 | default=False, |
| 102 | db_index=True, |
| 103 | help_text="Whether this stream is stale (not seen in recent refresh, pending deletion)" |
| 104 | ) |
| 105 | is_adult = models.BooleanField( |
| 106 | default=False, |
| 107 | db_index=True, |
| 108 | help_text="Whether this stream contains adult content" |
| 109 | ) |
| 110 | custom_properties = models.JSONField(default=dict, blank=True, null=True) |
| 111 | |
| 112 | stream_id = models.IntegerField( |
no outgoing calls