Files
ALwrity/ToBeMigrated/database/twitter_models.py
2025-08-06 16:29:49 +05:30

791 lines
28 KiB
Python

"""
Twitter Database Models for ALwrity
===================================
This module defines SQLAlchemy models for storing Twitter-related data including:
- User profiles and authentication
- Tweet content and metadata
- Analytics and engagement metrics
- Scheduling and automation data
- Performance tracking and insights
This allows the application to store Twitter data locally and reduce API calls
while providing rich analytics and historical data to users.
"""
from sqlalchemy import (
create_engine, Column, Integer, String, Text, DateTime, Boolean, Float,
Enum, ForeignKey, JSON, BigInteger, Index, UniqueConstraint
)
from sqlalchemy.orm import declarative_base, relationship, sessionmaker
from datetime import datetime, timedelta
import enum
from dataclasses import dataclass
from typing import List, Dict, Any, Optional
import json
Base = declarative_base()
# --- ENUMS ---
class TwitterAccountType(enum.Enum):
PERSONAL = "personal"
BUSINESS = "business"
CREATOR = "creator"
BRAND = "brand"
class TweetType(enum.Enum):
ORIGINAL = "original"
REPLY = "reply"
RETWEET = "retweet"
QUOTE_TWEET = "quote_tweet"
THREAD = "thread"
class TweetStatus(enum.Enum):
DRAFT = "draft"
SCHEDULED = "scheduled"
POSTED = "posted"
FAILED = "failed"
DELETED = "deleted"
class EngagementType(enum.Enum):
LIKE = "like"
RETWEET = "retweet"
REPLY = "reply"
QUOTE_TWEET = "quote_tweet"
BOOKMARK = "bookmark"
IMPRESSION = "impression"
PROFILE_CLICK = "profile_click"
URL_CLICK = "url_click"
HASHTAG_CLICK = "hashtag_click"
MENTION_CLICK = "mention_click"
class AnalyticsTimeframe(enum.Enum):
HOURLY = "hourly"
DAILY = "daily"
WEEKLY = "weekly"
MONTHLY = "monthly"
class ContentCategory(enum.Enum):
EDUCATIONAL = "educational"
PROMOTIONAL = "promotional"
PERSONAL = "personal"
NEWS = "news"
ENTERTAINMENT = "entertainment"
QUESTION = "question"
POLL = "poll"
THREAD = "thread"
# --- DATACLASSES ---
@dataclass
class TwitterCredentials:
"""Dataclass for Twitter API credentials"""
api_key: str = ""
api_secret: str = ""
access_token: str = ""
access_token_secret: str = ""
bearer_token: str = ""
def to_dict(self) -> Dict[str, str]:
return {
'api_key': self.api_key,
'api_secret': self.api_secret,
'access_token': self.access_token,
'access_token_secret': self.access_token_secret,
'bearer_token': self.bearer_token
}
@classmethod
def from_dict(cls, data: Dict[str, str]) -> 'TwitterCredentials':
return cls(
api_key=data.get('api_key', ''),
api_secret=data.get('api_secret', ''),
access_token=data.get('access_token', ''),
access_token_secret=data.get('access_token_secret', ''),
bearer_token=data.get('bearer_token', '')
)
@dataclass
class TweetMetrics:
"""Dataclass for tweet performance metrics"""
likes: int = 0
retweets: int = 0
replies: int = 0
quotes: int = 0
bookmarks: int = 0
impressions: int = 0
profile_clicks: int = 0
url_clicks: int = 0
hashtag_clicks: int = 0
engagement_rate: float = 0.0
reach: int = 0
def to_dict(self) -> Dict[str, Any]:
return {
'likes': self.likes,
'retweets': self.retweets,
'replies': self.replies,
'quotes': self.quotes,
'bookmarks': self.bookmarks,
'impressions': self.impressions,
'profile_clicks': self.profile_clicks,
'url_clicks': self.url_clicks,
'hashtag_clicks': self.hashtag_clicks,
'engagement_rate': self.engagement_rate,
'reach': self.reach
}
# --- MODELS ---
class TwitterUser(Base):
"""
Stores Twitter user profile information and authentication data.
This reduces API calls for user profile information.
"""
__tablename__ = "twitter_users"
id = Column(Integer, primary_key=True)
user_id = Column(String, nullable=False, unique=True) # ALwrity user ID
twitter_user_id = Column(BigInteger, nullable=False, unique=True) # Twitter user ID
username = Column(String, nullable=False, index=True) # @username
display_name = Column(String, nullable=False)
bio = Column(Text)
location = Column(String)
website = Column(String)
profile_image_url = Column(String)
banner_image_url = Column(String)
# Account metrics
followers_count = Column(Integer, default=0)
following_count = Column(Integer, default=0)
tweet_count = Column(Integer, default=0)
listed_count = Column(Integer, default=0)
# Account details
account_type = Column(Enum(TwitterAccountType), default=TwitterAccountType.PERSONAL)
verified = Column(Boolean, default=False)
protected = Column(Boolean, default=False)
created_at_twitter = Column(DateTime) # When Twitter account was created
# Authentication and API data
credentials_encrypted = Column(Text) # Encrypted JSON of TwitterCredentials
api_rate_limit_remaining = Column(Integer, default=0)
api_rate_limit_reset = Column(DateTime)
last_api_call = Column(DateTime)
# Metadata
is_active = Column(Boolean, default=True)
last_sync = Column(DateTime, default=datetime.utcnow)
created_at = Column(DateTime, default=datetime.utcnow)
updated_at = Column(DateTime, default=datetime.utcnow, onupdate=datetime.utcnow)
# Relationships
tweets = relationship("Tweet", back_populates="user", cascade="all, delete-orphan")
analytics = relationship("TwitterAnalytics", back_populates="user", cascade="all, delete-orphan")
scheduled_tweets = relationship("ScheduledTweet", back_populates="user", cascade="all, delete-orphan")
engagement_data = relationship("EngagementData", back_populates="user", cascade="all, delete-orphan")
audience_insights = relationship("AudienceInsight", back_populates="user", cascade="all, delete-orphan")
# Indexes
__table_args__ = (
Index('idx_twitter_user_username', 'username'),
Index('idx_twitter_user_sync', 'last_sync'),
Index('idx_twitter_user_active', 'is_active'),
)
class Tweet(Base):
"""
Stores tweet content, metadata, and performance data.
Includes both posted tweets and drafts.
"""
__tablename__ = "tweets"
id = Column(Integer, primary_key=True)
user_id = Column(Integer, ForeignKey("twitter_users.id"), nullable=False)
tweet_id = Column(BigInteger, unique=True, index=True) # Twitter tweet ID (null for drafts)
# Content
text = Column(Text, nullable=False)
hashtags = Column(JSON, default=list) # List of hashtags
mentions = Column(JSON, default=list) # List of mentioned users
urls = Column(JSON, default=list) # List of URLs in tweet
media_urls = Column(JSON, default=list) # List of media URLs
# Tweet metadata
tweet_type = Column(Enum(TweetType), default=TweetType.ORIGINAL)
status = Column(Enum(TweetStatus), default=TweetStatus.DRAFT)
category = Column(Enum(ContentCategory))
# Engagement metrics (updated periodically)
likes_count = Column(Integer, default=0)
retweets_count = Column(Integer, default=0)
replies_count = Column(Integer, default=0)
quotes_count = Column(Integer, default=0)
bookmarks_count = Column(Integer, default=0)
impressions_count = Column(Integer, default=0)
# Performance metrics
engagement_rate = Column(Float, default=0.0)
reach = Column(Integer, default=0)
click_through_rate = Column(Float, default=0.0)
# AI and generation data
ai_generated = Column(Boolean, default=False)
ai_model_used = Column(String) # Which AI model generated this
ai_prompt = Column(Text) # Original prompt used
ai_confidence_score = Column(Float) # AI confidence in content quality
generation_metadata = Column(JSON, default=dict) # Additional AI metadata
# Scheduling and posting
scheduled_for = Column(DateTime)
posted_at = Column(DateTime)
last_metrics_update = Column(DateTime)
# Thread information
thread_id = Column(String) # For grouping thread tweets
thread_position = Column(Integer) # Position in thread (1, 2, 3...)
parent_tweet_id = Column(BigInteger) # For replies
# Metadata
created_at = Column(DateTime, default=datetime.utcnow)
updated_at = Column(DateTime, default=datetime.utcnow, onupdate=datetime.utcnow)
# Relationships
user = relationship("TwitterUser", back_populates="tweets")
analytics = relationship("TweetAnalytics", back_populates="tweet", cascade="all, delete-orphan")
# Indexes
__table_args__ = (
Index('idx_tweet_user_status', 'user_id', 'status'),
Index('idx_tweet_posted_at', 'posted_at'),
Index('idx_tweet_engagement', 'engagement_rate'),
Index('idx_tweet_thread', 'thread_id'),
)
class ScheduledTweet(Base):
"""
Stores scheduled tweets with automation settings.
"""
__tablename__ = "scheduled_tweets"
id = Column(Integer, primary_key=True)
user_id = Column(Integer, ForeignKey("twitter_users.id"), nullable=False)
tweet_id = Column(Integer, ForeignKey("tweets.id"), nullable=False)
# Scheduling details
scheduled_time = Column(DateTime, nullable=False)
timezone = Column(String, default="UTC")
recurrence_pattern = Column(String) # cron-like pattern for recurring tweets
# Automation settings
auto_optimize_time = Column(Boolean, default=False) # AI-optimize posting time
auto_add_hashtags = Column(Boolean, default=False)
auto_add_emojis = Column(Boolean, default=False)
# Status and execution
status = Column(Enum(TweetStatus), default=TweetStatus.SCHEDULED)
attempts = Column(Integer, default=0)
last_attempt = Column(DateTime)
error_message = Column(Text)
# Metadata
created_at = Column(DateTime, default=datetime.utcnow)
updated_at = Column(DateTime, default=datetime.utcnow, onupdate=datetime.utcnow)
# Relationships
user = relationship("TwitterUser", back_populates="scheduled_tweets")
tweet = relationship("Tweet")
# Indexes
__table_args__ = (
Index('idx_scheduled_time', 'scheduled_time'),
Index('idx_scheduled_status', 'status'),
)
class TwitterAnalytics(Base):
"""
Stores aggregated Twitter analytics data for users.
Updated periodically to track account performance over time.
"""
__tablename__ = "twitter_analytics"
id = Column(Integer, primary_key=True)
user_id = Column(Integer, ForeignKey("twitter_users.id"), nullable=False)
# Time period
date = Column(DateTime, nullable=False)
timeframe = Column(Enum(AnalyticsTimeframe), nullable=False)
# Account metrics
followers_gained = Column(Integer, default=0)
followers_lost = Column(Integer, default=0)
net_follower_change = Column(Integer, default=0)
following_change = Column(Integer, default=0)
# Content metrics
tweets_posted = Column(Integer, default=0)
total_impressions = Column(Integer, default=0)
total_engagements = Column(Integer, default=0)
total_likes = Column(Integer, default=0)
total_retweets = Column(Integer, default=0)
total_replies = Column(Integer, default=0)
total_quotes = Column(Integer, default=0)
# Performance metrics
average_engagement_rate = Column(Float, default=0.0)
top_tweet_id = Column(BigInteger) # Best performing tweet
top_tweet_engagement = Column(Integer, default=0)
# Audience metrics
profile_visits = Column(Integer, default=0)
mention_count = Column(Integer, default=0)
hashtag_performance = Column(JSON, default=dict) # Top hashtags and their performance
# Metadata
created_at = Column(DateTime, default=datetime.utcnow)
updated_at = Column(DateTime, default=datetime.utcnow, onupdate=datetime.utcnow)
# Relationships
user = relationship("TwitterUser", back_populates="analytics")
# Indexes
__table_args__ = (
Index('idx_analytics_user_date', 'user_id', 'date'),
Index('idx_analytics_timeframe', 'timeframe'),
UniqueConstraint('user_id', 'date', 'timeframe', name='uq_user_date_timeframe'),
)
class TweetAnalytics(Base):
"""
Stores detailed analytics for individual tweets.
Updated periodically to track tweet performance over time.
"""
__tablename__ = "tweet_analytics"
id = Column(Integer, primary_key=True)
tweet_id = Column(Integer, ForeignKey("tweets.id"), nullable=False)
# Time period
recorded_at = Column(DateTime, nullable=False, default=datetime.utcnow)
# Engagement metrics
likes = Column(Integer, default=0)
retweets = Column(Integer, default=0)
replies = Column(Integer, default=0)
quotes = Column(Integer, default=0)
bookmarks = Column(Integer, default=0)
# Reach metrics
impressions = Column(Integer, default=0)
reach = Column(Integer, default=0)
profile_clicks = Column(Integer, default=0)
# Click metrics
url_clicks = Column(Integer, default=0)
hashtag_clicks = Column(Integer, default=0)
mention_clicks = Column(Integer, default=0)
media_views = Column(Integer, default=0)
# Calculated metrics
engagement_rate = Column(Float, default=0.0)
click_through_rate = Column(Float, default=0.0)
virality_score = Column(Float, default=0.0) # Custom metric for viral potential
# Metadata
created_at = Column(DateTime, default=datetime.utcnow)
# Relationships
tweet = relationship("Tweet", back_populates="analytics")
# Indexes
__table_args__ = (
Index('idx_tweet_analytics_recorded', 'recorded_at'),
Index('idx_tweet_analytics_engagement', 'engagement_rate'),
)
class EngagementData(Base):
"""
Stores individual engagement events for detailed analysis.
"""
__tablename__ = "engagement_data"
id = Column(Integer, primary_key=True)
user_id = Column(Integer, ForeignKey("twitter_users.id"), nullable=False)
tweet_id = Column(Integer, ForeignKey("tweets.id"))
# Engagement details
engagement_type = Column(Enum(EngagementType), nullable=False)
engaging_user_id = Column(BigInteger) # Twitter ID of user who engaged
engaging_username = Column(String)
# Metadata
occurred_at = Column(DateTime, nullable=False)
created_at = Column(DateTime, default=datetime.utcnow)
# Relationships
user = relationship("TwitterUser", back_populates="engagement_data")
tweet = relationship("Tweet")
# Indexes
__table_args__ = (
Index('idx_engagement_user_type', 'user_id', 'engagement_type'),
Index('idx_engagement_occurred', 'occurred_at'),
)
class AudienceInsight(Base):
"""
Stores audience demographics and behavior insights.
"""
__tablename__ = "audience_insights"
id = Column(Integer, primary_key=True)
user_id = Column(Integer, ForeignKey("twitter_users.id"), nullable=False)
# Time period
date = Column(DateTime, nullable=False)
# Demographics (aggregated data)
top_locations = Column(JSON, default=list) # Top follower locations
age_demographics = Column(JSON, default=dict) # Age distribution
gender_demographics = Column(JSON, default=dict) # Gender distribution
language_demographics = Column(JSON, default=dict) # Language distribution
# Behavior insights
most_active_hours = Column(JSON, default=list) # When audience is most active
top_interests = Column(JSON, default=list) # Audience interests
engagement_patterns = Column(JSON, default=dict) # How audience engages
# Content preferences
preferred_content_types = Column(JSON, default=dict)
top_hashtags_used = Column(JSON, default=list)
response_rate_by_content = Column(JSON, default=dict)
# Metadata
created_at = Column(DateTime, default=datetime.utcnow)
updated_at = Column(DateTime, default=datetime.utcnow, onupdate=datetime.utcnow)
# Relationships
user = relationship("TwitterUser", back_populates="audience_insights")
# Indexes
__table_args__ = (
Index('idx_audience_user_date', 'user_id', 'date'),
)
class HashtagPerformance(Base):
"""
Tracks performance of hashtags used by the user.
"""
__tablename__ = "hashtag_performance"
id = Column(Integer, primary_key=True)
user_id = Column(Integer, ForeignKey("twitter_users.id"), nullable=False)
# Hashtag details
hashtag = Column(String, nullable=False, index=True)
usage_count = Column(Integer, default=0)
# Performance metrics
total_impressions = Column(Integer, default=0)
total_engagements = Column(Integer, default=0)
average_engagement_rate = Column(Float, default=0.0)
# Best performing tweet with this hashtag
best_tweet_id = Column(Integer, ForeignKey("tweets.id"))
best_tweet_engagement = Column(Integer, default=0)
# Time tracking
first_used = Column(DateTime)
last_used = Column(DateTime)
# Metadata
created_at = Column(DateTime, default=datetime.utcnow)
updated_at = Column(DateTime, default=datetime.utcnow, onupdate=datetime.utcnow)
# Relationships
user = relationship("TwitterUser")
best_tweet = relationship("Tweet")
# Indexes
__table_args__ = (
Index('idx_hashtag_user_performance', 'user_id', 'average_engagement_rate'),
UniqueConstraint('user_id', 'hashtag', name='uq_user_hashtag'),
)
class ContentTemplate(Base):
"""
Stores reusable tweet templates and AI prompts.
"""
__tablename__ = "content_templates"
id = Column(Integer, primary_key=True)
user_id = Column(Integer, ForeignKey("twitter_users.id"), nullable=False)
# Template details
name = Column(String, nullable=False)
description = Column(Text)
template_text = Column(Text, nullable=False)
category = Column(Enum(ContentCategory))
# Template variables and settings
variables = Column(JSON, default=list) # List of template variables
default_hashtags = Column(JSON, default=list)
suggested_times = Column(JSON, default=list) # Best times to post this type
# AI settings
ai_prompt = Column(Text) # AI prompt for generating content
ai_tone = Column(String) # Tone for AI generation
ai_target_audience = Column(String)
# Usage tracking
usage_count = Column(Integer, default=0)
last_used = Column(DateTime)
average_performance = Column(Float, default=0.0)
# Metadata
is_active = Column(Boolean, default=True)
created_at = Column(DateTime, default=datetime.utcnow)
updated_at = Column(DateTime, default=datetime.utcnow, onupdate=datetime.utcnow)
# Relationships
user = relationship("TwitterUser")
# Indexes
__table_args__ = (
Index('idx_template_user_category', 'user_id', 'category'),
Index('idx_template_performance', 'average_performance'),
)
class TwitterSettings(Base):
"""
Stores user-specific Twitter settings and preferences.
"""
__tablename__ = "twitter_settings"
id = Column(Integer, primary_key=True)
user_id = Column(Integer, ForeignKey("twitter_users.id"), nullable=False, unique=True)
# Posting preferences
default_hashtags = Column(JSON, default=list)
auto_add_hashtags = Column(Boolean, default=False)
auto_add_emojis = Column(Boolean, default=False)
max_hashtags_per_tweet = Column(Integer, default=2)
# Scheduling preferences
preferred_posting_times = Column(JSON, default=list)
timezone = Column(String, default="UTC")
auto_optimize_timing = Column(Boolean, default=False)
# AI preferences
ai_tone_preference = Column(String, default="casual")
ai_target_audience = Column(String, default="general")
ai_creativity_level = Column(Float, default=0.7) # 0-1 scale
# Analytics preferences
analytics_frequency = Column(String, default="daily") # hourly, daily, weekly
track_competitor_hashtags = Column(JSON, default=list)
notification_preferences = Column(JSON, default=dict)
# Content preferences
content_categories = Column(JSON, default=list) # Preferred content types
avoid_topics = Column(JSON, default=list) # Topics to avoid
brand_keywords = Column(JSON, default=list) # Brand-related keywords
# Automation settings
auto_retweet_keywords = Column(JSON, default=list)
auto_like_keywords = Column(JSON, default=list)
auto_follow_back = Column(Boolean, default=False)
# Metadata
created_at = Column(DateTime, default=datetime.utcnow)
updated_at = Column(DateTime, default=datetime.utcnow, onupdate=datetime.utcnow)
# Relationships
user = relationship("TwitterUser")
# --- DATABASE FUNCTIONS ---
def get_twitter_engine(db_url: str = "sqlite:///twitter_data.db"):
"""Create and return database engine for Twitter data."""
return create_engine(db_url, echo=False)
def init_twitter_db(engine):
"""Initialize Twitter database tables."""
Base.metadata.create_all(engine)
def get_twitter_session(engine):
"""Create and return database session for Twitter data."""
Session = sessionmaker(bind=engine)
return Session()
def create_twitter_user(session, user_data: Dict[str, Any]) -> TwitterUser:
"""Create a new Twitter user record."""
twitter_user = TwitterUser(
user_id=user_data['user_id'],
twitter_user_id=user_data['twitter_user_id'],
username=user_data['username'],
display_name=user_data['display_name'],
bio=user_data.get('bio', ''),
location=user_data.get('location', ''),
website=user_data.get('website', ''),
profile_image_url=user_data.get('profile_image_url', ''),
banner_image_url=user_data.get('banner_image_url', ''),
followers_count=user_data.get('followers_count', 0),
following_count=user_data.get('following_count', 0),
tweet_count=user_data.get('tweet_count', 0),
verified=user_data.get('verified', False),
protected=user_data.get('protected', False),
created_at_twitter=user_data.get('created_at_twitter'),
credentials_encrypted=user_data.get('credentials_encrypted', ''),
)
session.add(twitter_user)
session.commit()
return twitter_user
def update_user_metrics(session, user_id: int, metrics: Dict[str, Any]):
"""Update user metrics from Twitter API."""
user = session.query(TwitterUser).filter_by(id=user_id).first()
if user:
user.followers_count = metrics.get('followers_count', user.followers_count)
user.following_count = metrics.get('following_count', user.following_count)
user.tweet_count = metrics.get('tweet_count', user.tweet_count)
user.last_sync = datetime.utcnow()
session.commit()
def create_tweet_record(session, tweet_data: Dict[str, Any]) -> Tweet:
"""Create a new tweet record."""
# Handle both 'text' and 'content' field names for compatibility
text_content = tweet_data.get('text') or tweet_data.get('content')
if not text_content:
raise ValueError("Tweet must have either 'text' or 'content' field")
tweet = Tweet(
user_id=tweet_data['user_id'],
tweet_id=tweet_data.get('tweet_id'),
text=text_content,
hashtags=tweet_data.get('hashtags', []),
mentions=tweet_data.get('mentions', []),
urls=tweet_data.get('urls', []),
media_urls=tweet_data.get('media_urls', []),
tweet_type=TweetType(tweet_data.get('tweet_type', 'original')),
status=TweetStatus(tweet_data.get('status', 'draft')),
category=ContentCategory(tweet_data['category']) if tweet_data.get('category') else None,
ai_generated=tweet_data.get('ai_generated', False),
ai_model_used=tweet_data.get('ai_model_used'),
ai_prompt=tweet_data.get('ai_prompt'),
ai_confidence_score=tweet_data.get('ai_confidence_score'),
generation_metadata=tweet_data.get('generation_metadata', {}),
scheduled_for=tweet_data.get('scheduled_for'),
posted_at=tweet_data.get('posted_at'),
thread_id=tweet_data.get('thread_id'),
thread_position=tweet_data.get('thread_position'),
parent_tweet_id=tweet_data.get('parent_tweet_id'),
)
session.add(tweet)
session.commit()
return tweet
def update_tweet_metrics(session, tweet_id: int, metrics: TweetMetrics):
"""Update tweet metrics from Twitter API."""
tweet = session.query(Tweet).filter_by(id=tweet_id).first()
if tweet:
tweet.likes_count = metrics.likes
tweet.retweets_count = metrics.retweets
tweet.replies_count = metrics.replies
tweet.quotes_count = metrics.quotes
tweet.bookmarks_count = metrics.bookmarks
tweet.impressions_count = metrics.impressions
tweet.engagement_rate = metrics.engagement_rate
tweet.reach = metrics.reach
tweet.last_metrics_update = datetime.utcnow()
session.commit()
# Also create analytics record
analytics = TweetAnalytics(
tweet_id=tweet_id,
likes=metrics.likes,
retweets=metrics.retweets,
replies=metrics.replies,
quotes=metrics.quotes,
bookmarks=metrics.bookmarks,
impressions=metrics.impressions,
reach=metrics.reach,
engagement_rate=metrics.engagement_rate,
click_through_rate=metrics.url_clicks / max(metrics.impressions, 1) * 100,
virality_score=calculate_virality_score(metrics)
)
session.add(analytics)
session.commit()
def calculate_virality_score(metrics: TweetMetrics) -> float:
"""Calculate a custom virality score based on engagement metrics."""
if metrics.impressions == 0:
return 0.0
# Weight different engagement types
engagement_score = (
metrics.likes * 1.0 +
metrics.retweets * 3.0 + # Retweets are more valuable
metrics.replies * 2.0 +
metrics.quotes * 2.5 +
metrics.bookmarks * 1.5
)
# Normalize by impressions and scale
virality = (engagement_score / metrics.impressions) * 100
return min(virality, 100.0) # Cap at 100
def get_user_analytics_summary(session, user_id: int, days: int = 30) -> Dict[str, Any]:
"""Get analytics summary for a user over specified days."""
from sqlalchemy import func
start_date = datetime.utcnow() - timedelta(days=days)
# Get tweet metrics
tweet_stats = session.query(
func.count(Tweet.id).label('total_tweets'),
func.avg(Tweet.engagement_rate).label('avg_engagement'),
func.sum(Tweet.likes_count).label('total_likes'),
func.sum(Tweet.retweets_count).label('total_retweets'),
func.sum(Tweet.impressions_count).label('total_impressions')
).filter(
Tweet.user_id == user_id,
Tweet.posted_at >= start_date,
Tweet.status == TweetStatus.POSTED
).first()
# Get follower growth
user = session.query(TwitterUser).filter_by(id=user_id).first()
return {
'total_tweets': tweet_stats.total_tweets or 0,
'average_engagement_rate': float(tweet_stats.avg_engagement or 0),
'total_likes': tweet_stats.total_likes or 0,
'total_retweets': tweet_stats.total_retweets or 0,
'total_impressions': tweet_stats.total_impressions or 0,
'current_followers': user.followers_count if user else 0,
'period_days': days
}
# Export all models and functions
__all__ = [
# Models
'TwitterUser', 'Tweet', 'ScheduledTweet', 'TwitterAnalytics', 'TweetAnalytics',
'EngagementData', 'AudienceInsight', 'HashtagPerformance', 'ContentTemplate',
'TwitterSettings',
# Enums
'TwitterAccountType', 'TweetType', 'TweetStatus', 'EngagementType',
'AnalyticsTimeframe', 'ContentCategory',
# Dataclasses
'TwitterCredentials', 'TweetMetrics',
# Functions
'get_twitter_engine', 'init_twitter_db', 'get_twitter_session',
'create_twitter_user', 'update_user_metrics', 'create_tweet_record',
'update_tweet_metrics', 'calculate_virality_score', 'get_user_analytics_summary'
]