from django.conf import settings from django.db import models from core.models import TimeStampedModel, UUIDPrimaryKeyModel class Platform(models.TextChoices): FACEBOOK = "facebook", "Facebook" INSTAGRAM = "instagram", "Instagram" LINKEDIN = "linkedin", "LinkedIn" class SocialAccount(UUIDPrimaryKeyModel, TimeStampedModel): platform = models.CharField(max_length=16, choices=Platform.choices) label = models.CharField(max_length=120) external_id = models.CharField(max_length=255, blank=True) # Fernet-encrypted JSON blob of OAuth tokens encrypted_tokens = models.TextField(blank=True) is_active = models.BooleanField(default=True) owner = models.ForeignKey( settings.AUTH_USER_MODEL, null=True, blank=True, on_delete=models.SET_NULL, related_name="social_accounts", ) class Meta: ordering = ["platform", "label"] def __str__(self) -> str: return f"{self.platform}: {self.label}" class SocialPost(UUIDPrimaryKeyModel, TimeStampedModel): class Status(models.TextChoices): DRAFT = "draft", "Draft" SCHEDULED = "scheduled", "Scheduled" QUEUED = "queued", "Queued" PUBLISHING = "publishing", "Publishing" PUBLISHED = "published", "Published" FAILED = "failed", "Failed" CANCELLED = "cancelled", "Cancelled" body = models.TextField() media = models.JSONField(default=list, blank=True) scheduled_for = models.DateTimeField(null=True, blank=True) status = models.CharField( max_length=16, choices=Status.choices, default=Status.DRAFT ) created_by = models.ForeignKey( settings.AUTH_USER_MODEL, null=True, blank=True, on_delete=models.SET_NULL, ) ollama_prompt = models.TextField(blank=True) error = models.TextField(blank=True) class Meta: ordering = ["-created_at"] def __str__(self) -> str: return f"Post {self.pk} ({self.status})" class SocialPostTarget(UUIDPrimaryKeyModel, TimeStampedModel): class Status(models.TextChoices): PENDING = "pending", "Pending" PUBLISHED = "published", "Published" FAILED = "failed", "Failed" post = models.ForeignKey( SocialPost, on_delete=models.CASCADE, related_name="targets" ) account = models.ForeignKey( SocialAccount, on_delete=models.CASCADE, related_name="targets" ) platform = models.CharField(max_length=16, choices=Platform.choices) status = models.CharField( max_length=16, choices=Status.choices, default=Status.PENDING ) remote_id = models.CharField(max_length=255, blank=True) error = models.TextField(blank=True) class Meta: unique_together = ("post", "account")