phase 3
This commit is contained in:
@@ -13,22 +13,6 @@ class AssetStatus(models.TextChoices):
|
||||
ERROR = "error", "Error"
|
||||
|
||||
class JobStatus(models.TextChoices):
|
||||
PENDING = "pending", "Pending"
|
||||
PROCESSING = "processing", "Processing"
|
||||
COMPLETED = "completed", "Completed"
|
||||
FAILED = "failed", "Failed"
|
||||
CANCELLED = "cancelled", "Cancelled"
|
||||
|
||||
class ChunkJobStatus(models.TextChoices):
|
||||
PENDING = "pending", "Pending"
|
||||
CHUNKING = "chunking", "Chunking"
|
||||
PROCESSING = "processing", "Processing"
|
||||
COLLECTING = "collecting", "Collecting"
|
||||
COMPLETED = "completed", "Completed"
|
||||
FAILED = "failed", "Failed"
|
||||
CANCELLED = "cancelled", "Cancelled"
|
||||
|
||||
class DetectJobStatus(models.TextChoices):
|
||||
PENDING = "pending", "Pending"
|
||||
RUNNING = "running", "Running"
|
||||
PAUSED = "paused", "Paused"
|
||||
@@ -111,81 +95,17 @@ class TranscodePreset(models.Model):
|
||||
return self.name
|
||||
|
||||
|
||||
class TranscodeJob(models.Model):
|
||||
"""A transcoding or trimming job in the queue."""
|
||||
|
||||
id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
|
||||
source_asset_id = models.UUIDField()
|
||||
preset_id = models.UUIDField(null=True, blank=True)
|
||||
preset_snapshot = models.JSONField(default=dict, blank=True)
|
||||
trim_start = models.FloatField(null=True, blank=True, default=None)
|
||||
trim_end = models.FloatField(null=True, blank=True, default=None)
|
||||
output_filename = models.CharField(max_length=500)
|
||||
output_path = models.CharField(max_length=1000, null=True, blank=True)
|
||||
output_asset_id = models.UUIDField(null=True, blank=True)
|
||||
status = models.CharField(max_length=20, choices=JobStatus.choices, default=JobStatus.PENDING)
|
||||
progress = models.FloatField(default=0.0)
|
||||
current_frame = models.IntegerField(null=True, blank=True, default=None)
|
||||
current_time = models.FloatField(null=True, blank=True, default=None)
|
||||
speed = models.CharField(max_length=255, null=True, blank=True)
|
||||
error_message = models.TextField(blank=True, default='')
|
||||
celery_task_id = models.CharField(max_length=255, null=True, blank=True)
|
||||
execution_arn = models.CharField(max_length=255, null=True, blank=True)
|
||||
priority = models.IntegerField(default=0)
|
||||
created_at = models.DateTimeField(auto_now_add=True)
|
||||
started_at = models.DateTimeField(null=True, blank=True)
|
||||
completed_at = models.DateTimeField(null=True, blank=True)
|
||||
|
||||
class Meta:
|
||||
ordering = ["-created_at"]
|
||||
|
||||
def __str__(self):
|
||||
return str(self.id)
|
||||
|
||||
|
||||
class ChunkJob(models.Model):
|
||||
"""A chunk pipeline job — splits a media file into chunks and processes them"""
|
||||
|
||||
id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
|
||||
source_asset_id = models.UUIDField()
|
||||
chunk_duration = models.FloatField(default=10.0)
|
||||
num_workers = models.IntegerField(default=4)
|
||||
max_retries = models.IntegerField(default=3)
|
||||
processor_type = models.CharField(max_length=255)
|
||||
status = models.CharField(max_length=20, choices=ChunkJobStatus.choices, default=ChunkJobStatus.PENDING)
|
||||
progress = models.FloatField(default=0.0)
|
||||
total_chunks = models.IntegerField(default=0)
|
||||
processed_chunks = models.IntegerField(default=0)
|
||||
failed_chunks = models.IntegerField(default=0)
|
||||
retry_count = models.IntegerField(default=0)
|
||||
error_message = models.TextField(blank=True, default='')
|
||||
throughput_mbps = models.FloatField(null=True, blank=True, default=None)
|
||||
elapsed_seconds = models.FloatField(null=True, blank=True, default=None)
|
||||
celery_task_id = models.CharField(max_length=255, null=True, blank=True)
|
||||
priority = models.IntegerField(default=0)
|
||||
created_at = models.DateTimeField(auto_now_add=True)
|
||||
started_at = models.DateTimeField(null=True, blank=True)
|
||||
completed_at = models.DateTimeField(null=True, blank=True)
|
||||
|
||||
class Meta:
|
||||
ordering = ["-created_at"]
|
||||
|
||||
def __str__(self):
|
||||
return str(self.id)
|
||||
|
||||
|
||||
class DetectJob(models.Model):
|
||||
"""A detection pipeline job."""
|
||||
class Job(models.Model):
|
||||
"""A pipeline job."""
|
||||
|
||||
id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
|
||||
source_asset_id = models.UUIDField()
|
||||
video_path = models.CharField(max_length=1000)
|
||||
profile_name = models.CharField(max_length=255)
|
||||
parent_job_id = models.UUIDField(null=True, blank=True)
|
||||
parent_id = models.UUIDField(null=True, blank=True)
|
||||
run_type = models.CharField(max_length=20, choices=RunType.choices, default=RunType.INITIAL)
|
||||
replay_from_stage = models.CharField(max_length=255, null=True, blank=True)
|
||||
config_overrides = models.JSONField(default=dict, blank=True)
|
||||
status = models.CharField(max_length=20, choices=DetectJobStatus.choices, default=DetectJobStatus.PENDING)
|
||||
status = models.CharField(max_length=20, choices=JobStatus.choices, default=JobStatus.PENDING)
|
||||
current_stage = models.CharField(max_length=255, null=True, blank=True)
|
||||
progress = models.FloatField(default=0.0)
|
||||
error_message = models.TextField(blank=True, default='')
|
||||
@@ -206,26 +126,17 @@ class DetectJob(models.Model):
|
||||
return str(self.id)
|
||||
|
||||
|
||||
class StageCheckpoint(models.Model):
|
||||
"""A checkpoint saved after a pipeline stage completes."""
|
||||
class Timeline(models.Model):
|
||||
"""The frame sequence from a source video."""
|
||||
|
||||
id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
|
||||
job_id = models.UUIDField()
|
||||
stage = models.CharField(max_length=255)
|
||||
stage_index = models.IntegerField()
|
||||
source_asset_id = models.UUIDField(null=True, blank=True)
|
||||
source_video = models.CharField(max_length=255)
|
||||
profile_name = models.CharField(max_length=255)
|
||||
fps = models.FloatField(default=2.0)
|
||||
frames_prefix = models.CharField(max_length=255)
|
||||
frames_manifest = models.JSONField(default=dict, blank=True)
|
||||
frames_meta = models.JSONField(default=list, blank=True)
|
||||
filtered_frame_sequences = models.JSONField(default=list, blank=True)
|
||||
boxes_by_frame = models.JSONField(default=dict, blank=True)
|
||||
text_candidates = models.JSONField(default=list, blank=True)
|
||||
unresolved_candidates = models.JSONField(default=list, blank=True)
|
||||
detections = models.JSONField(default=list, blank=True)
|
||||
stats = models.JSONField(default=dict, blank=True)
|
||||
config_snapshot = models.JSONField(default=dict, blank=True)
|
||||
config_overrides = models.JSONField(default=dict, blank=True)
|
||||
video_path = models.CharField(max_length=1000)
|
||||
profile_name = models.CharField(max_length=255)
|
||||
created_at = models.DateTimeField(auto_now_add=True)
|
||||
|
||||
class Meta:
|
||||
@@ -235,15 +146,36 @@ class StageCheckpoint(models.Model):
|
||||
return str(self.id)
|
||||
|
||||
|
||||
class KnownBrand(models.Model):
|
||||
class Checkpoint(models.Model):
|
||||
"""A snapshot of pipeline state on a timeline."""
|
||||
|
||||
id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
|
||||
timeline_id = models.UUIDField()
|
||||
parent_id = models.UUIDField(null=True, blank=True)
|
||||
stage_outputs = models.JSONField(default=dict, blank=True)
|
||||
config_overrides = models.JSONField(default=dict, blank=True)
|
||||
stats = models.JSONField(default=dict, blank=True)
|
||||
is_scenario = models.BooleanField(default=False)
|
||||
scenario_label = models.CharField(max_length=255)
|
||||
created_at = models.DateTimeField(auto_now_add=True)
|
||||
|
||||
class Meta:
|
||||
ordering = ["-created_at"]
|
||||
|
||||
def __str__(self):
|
||||
return str(self.id)
|
||||
|
||||
|
||||
class Brand(models.Model):
|
||||
"""A brand discovered or registered in the system."""
|
||||
|
||||
id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
|
||||
canonical_name = models.CharField(max_length=255)
|
||||
aliases = models.JSONField(default=list, blank=True)
|
||||
first_source = models.CharField(max_length=20, choices=BrandSource.choices, default=BrandSource.OCR)
|
||||
total_occurrences = models.IntegerField(default=0)
|
||||
source = models.CharField(max_length=20, choices=BrandSource.choices, default=BrandSource.OCR)
|
||||
confirmed = models.BooleanField(default=False)
|
||||
airings = models.JSONField(default=list, blank=True)
|
||||
total_airings = models.IntegerField(default=0)
|
||||
created_at = models.DateTimeField(auto_now_add=True)
|
||||
updated_at = models.DateTimeField(auto_now=True)
|
||||
|
||||
@@ -253,24 +185,3 @@ class KnownBrand(models.Model):
|
||||
def __str__(self):
|
||||
return str(self.id)
|
||||
|
||||
|
||||
class SourceBrandSighting(models.Model):
|
||||
"""A brand seen in a specific source (video/asset)."""
|
||||
|
||||
id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
|
||||
source_asset_id = models.UUIDField()
|
||||
brand_id = models.UUIDField()
|
||||
brand_name = models.CharField(max_length=255)
|
||||
first_seen_timestamp = models.FloatField(default=0.0)
|
||||
last_seen_timestamp = models.FloatField(default=0.0)
|
||||
occurrences = models.IntegerField(default=0)
|
||||
detection_source = models.CharField(max_length=20, choices=BrandSource.choices, default=BrandSource.OCR)
|
||||
avg_confidence = models.FloatField(default=0.0)
|
||||
created_at = models.DateTimeField(auto_now_add=True)
|
||||
|
||||
class Meta:
|
||||
ordering = ["-created_at"]
|
||||
|
||||
def __str__(self):
|
||||
return str(self.id)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user