139 lines
4.0 KiB
Python
139 lines
4.0 KiB
Python
"""
|
|
Social models - Social media monitoring and sentiment analysis
|
|
|
|
This module implements social media monitoring that:
|
|
- Tracks mentions across platforms
|
|
- Analyzes sentiment
|
|
- Creates PX actions for negative mentions
|
|
- Monitors brand reputation
|
|
"""
|
|
from django.db import models
|
|
|
|
from apps.core.models import TimeStampedModel, UUIDModel
|
|
|
|
|
|
class SocialPlatform(models.TextChoices):
|
|
"""Social media platform choices"""
|
|
TWITTER = 'twitter', 'Twitter/X'
|
|
FACEBOOK = 'facebook', 'Facebook'
|
|
INSTAGRAM = 'instagram', 'Instagram'
|
|
LINKEDIN = 'linkedin', 'LinkedIn'
|
|
YOUTUBE = 'youtube', 'YouTube'
|
|
TIKTOK = 'tiktok', 'TikTok'
|
|
OTHER = 'other', 'Other'
|
|
|
|
|
|
class SentimentType(models.TextChoices):
|
|
"""Sentiment analysis result choices"""
|
|
POSITIVE = 'positive', 'Positive'
|
|
NEUTRAL = 'neutral', 'Neutral'
|
|
NEGATIVE = 'negative', 'Negative'
|
|
|
|
|
|
class SocialMention(UUIDModel, TimeStampedModel):
|
|
"""
|
|
Social media mention - tracks mentions of hospital/brand.
|
|
|
|
Negative sentiment triggers PX action creation.
|
|
"""
|
|
# Platform and source
|
|
platform = models.CharField(
|
|
max_length=50,
|
|
choices=SocialPlatform.choices,
|
|
db_index=True
|
|
)
|
|
post_url = models.URLField(max_length=1000)
|
|
post_id = models.CharField(
|
|
max_length=200,
|
|
unique=True,
|
|
db_index=True,
|
|
help_text="Unique post ID from platform"
|
|
)
|
|
|
|
# Author information
|
|
author_username = models.CharField(max_length=200)
|
|
author_name = models.CharField(max_length=200, blank=True)
|
|
author_followers = models.IntegerField(null=True, blank=True)
|
|
|
|
# Content
|
|
content = models.TextField()
|
|
content_ar = models.TextField(blank=True, help_text="Arabic translation if applicable")
|
|
|
|
# Organization
|
|
hospital = models.ForeignKey(
|
|
'organizations.Hospital',
|
|
on_delete=models.CASCADE,
|
|
null=True,
|
|
blank=True,
|
|
related_name='social_mentions'
|
|
)
|
|
department = models.ForeignKey(
|
|
'organizations.Department',
|
|
on_delete=models.SET_NULL,
|
|
null=True,
|
|
blank=True,
|
|
related_name='social_mentions'
|
|
)
|
|
|
|
# Sentiment analysis
|
|
sentiment = models.CharField(
|
|
max_length=20,
|
|
choices=SentimentType.choices,
|
|
null=True,
|
|
blank=True,
|
|
db_index=True
|
|
)
|
|
sentiment_score = models.DecimalField(
|
|
max_digits=5,
|
|
decimal_places=2,
|
|
null=True,
|
|
blank=True,
|
|
help_text="Sentiment score (-1 to 1, or 0-100 depending on AI service)"
|
|
)
|
|
sentiment_analyzed_at = models.DateTimeField(null=True, blank=True)
|
|
|
|
# Engagement metrics
|
|
likes_count = models.IntegerField(default=0)
|
|
shares_count = models.IntegerField(default=0)
|
|
comments_count = models.IntegerField(default=0)
|
|
|
|
# Timestamps
|
|
posted_at = models.DateTimeField(db_index=True)
|
|
collected_at = models.DateTimeField(auto_now_add=True)
|
|
|
|
# Response tracking
|
|
responded = models.BooleanField(default=False)
|
|
response_text = models.TextField(blank=True)
|
|
responded_at = models.DateTimeField(null=True, blank=True)
|
|
responded_by = models.ForeignKey(
|
|
'accounts.User',
|
|
on_delete=models.SET_NULL,
|
|
null=True,
|
|
blank=True,
|
|
related_name='social_responses'
|
|
)
|
|
|
|
# Action tracking
|
|
action_created = models.BooleanField(default=False)
|
|
px_action = models.ForeignKey(
|
|
'px_action_center.PXAction',
|
|
on_delete=models.SET_NULL,
|
|
null=True,
|
|
blank=True,
|
|
related_name='social_mentions'
|
|
)
|
|
|
|
# Metadata
|
|
metadata = models.JSONField(default=dict, blank=True)
|
|
|
|
class Meta:
|
|
ordering = ['-posted_at']
|
|
indexes = [
|
|
models.Index(fields=['platform', '-posted_at']),
|
|
models.Index(fields=['sentiment', '-posted_at']),
|
|
models.Index(fields=['hospital', 'sentiment', '-posted_at']),
|
|
]
|
|
|
|
def __str__(self):
|
|
return f"{self.platform} - {self.author_username} - {self.posted_at.strftime('%Y-%m-%d')}"
|