209 lines
6.9 KiB
Python
209 lines
6.9 KiB
Python
"""
|
|
Service for querying messages from the Zulip database.
|
|
"""
|
|
from datetime import datetime, timedelta
|
|
from sqlalchemy import and_, or_
|
|
from app.db import get_db_session
|
|
from app.models.zulip import Message, Stream, Recipient, UserProfile, IT_RECIPIENT_IDS
|
|
|
|
class ZulipDatabaseService:
|
|
"""Service for querying messages from the Zulip database."""
|
|
|
|
@staticmethod
|
|
def get_messages_from_it_channels(days_ago=None, limit=1000, since=None):
|
|
"""
|
|
Get recent messages from IT channels.
|
|
|
|
Args:
|
|
days_ago (int): Number of days to look back (optional)
|
|
limit (int): Maximum number of messages to return
|
|
since (datetime): Get messages after this datetime (optional)
|
|
|
|
Returns:
|
|
list: List of Message objects
|
|
"""
|
|
session = get_db_session()
|
|
|
|
# Build the query based on parameters
|
|
query = session.query(Message).filter(
|
|
Message.recipient_id.in_(IT_RECIPIENT_IDS)
|
|
)
|
|
|
|
# Add date filter if specified
|
|
if since:
|
|
query = query.filter(Message.date_sent >= since)
|
|
elif days_ago:
|
|
start_date = datetime.now() - timedelta(days=days_ago)
|
|
query = query.filter(Message.date_sent >= start_date)
|
|
|
|
# Get results
|
|
messages = query.order_by(Message.id.desc()).limit(limit).all()
|
|
|
|
return messages
|
|
|
|
@staticmethod
|
|
def get_messages_newer_than_id(message_id, limit=100):
|
|
"""
|
|
Get messages with ID greater than the specified ID.
|
|
|
|
Args:
|
|
message_id (int): Get messages with ID greater than this
|
|
limit (int): Maximum number of messages to return
|
|
|
|
Returns:
|
|
list: List of Message objects
|
|
"""
|
|
session = get_db_session()
|
|
|
|
messages = session.query(Message).filter(
|
|
and_(
|
|
Message.recipient_id.in_(IT_RECIPIENT_IDS),
|
|
Message.id > message_id
|
|
)
|
|
).order_by(Message.id.asc()).limit(limit).all()
|
|
|
|
return messages
|
|
|
|
@staticmethod
|
|
def get_message_by_id(message_id):
|
|
"""
|
|
Get a specific message by ID.
|
|
|
|
Args:
|
|
message_id (int): ID of the message to retrieve
|
|
|
|
Returns:
|
|
Message: Message object or None if not found
|
|
"""
|
|
session = get_db_session()
|
|
return session.query(Message).filter(Message.id == message_id).first()
|
|
|
|
@staticmethod
|
|
def search_messages(search_term, days_ago=365, limit=100):
|
|
"""
|
|
Search for messages containing a specific term.
|
|
|
|
Args:
|
|
search_term (str): Term to search for
|
|
days_ago (int): Number of days to look back
|
|
limit (int): Maximum number of messages to return
|
|
|
|
Returns:
|
|
list: List of Message objects matching the search
|
|
"""
|
|
session = get_db_session()
|
|
start_date = datetime.now() - timedelta(days=days_ago)
|
|
|
|
# Use the tsquery system if available, otherwise fall back to LIKE
|
|
messages = session.query(Message).filter(
|
|
and_(
|
|
Message.recipient_id.in_(IT_RECIPIENT_IDS),
|
|
Message.date_sent >= start_date,
|
|
or_(
|
|
Message.content.ilike(f'%{search_term}%'),
|
|
Message.subject.ilike(f'%{search_term}%')
|
|
)
|
|
)
|
|
).order_by(Message.date_sent.desc()).limit(limit).all()
|
|
|
|
return messages
|
|
|
|
@staticmethod
|
|
def get_channel_name_for_message(message):
|
|
"""
|
|
Get the channel name for a message.
|
|
|
|
Args:
|
|
message (Message): Message object
|
|
|
|
Returns:
|
|
str: Channel name or "Unknown Channel" if not found
|
|
"""
|
|
session = get_db_session()
|
|
|
|
try:
|
|
if not message or not message.recipient_id:
|
|
return "Unknown Channel"
|
|
|
|
# First, get the recipient to determine type
|
|
recipient = session.query(Recipient).filter(
|
|
Recipient.id == message.recipient_id
|
|
).first()
|
|
|
|
if not recipient:
|
|
return "Unknown Channel"
|
|
|
|
# Check recipient type (1 = stream, 2 = user, 3 = huddle)
|
|
if recipient.type != 1:
|
|
# For direct messages or huddles
|
|
return "Direct Message" if recipient.type == 2 else "Group Message"
|
|
|
|
# For stream messages, get the stream name
|
|
stream = session.query(Stream).filter(
|
|
Stream.recipient_id == message.recipient_id
|
|
).first()
|
|
|
|
# Return the name or a default value
|
|
return stream.name if stream and stream.name else "Unknown Channel"
|
|
except Exception as e:
|
|
# Log the error but don't crash - return a default value
|
|
print(f"Error getting channel name for message {message.id if message else 'unknown'}: {e}")
|
|
return "Unknown Channel"
|
|
|
|
@staticmethod
|
|
def get_sender_name_for_message(message):
|
|
"""
|
|
Get the sender name for a message.
|
|
|
|
Args:
|
|
message (Message): Message object
|
|
|
|
Returns:
|
|
str: Sender full name or 'Unknown User' if not found
|
|
"""
|
|
session = get_db_session()
|
|
|
|
try:
|
|
if not message or not message.sender_id:
|
|
return "Unknown User"
|
|
|
|
user = session.query(UserProfile).filter(
|
|
UserProfile.id == message.sender_id
|
|
).first()
|
|
|
|
return user.full_name if user and user.full_name else "Unknown User"
|
|
except Exception as e:
|
|
# Log the error but don't crash - return a default value
|
|
print(f"Error getting sender name for message {message.id if message else 'unknown'}: {e}")
|
|
return "Unknown User"
|
|
|
|
@staticmethod
|
|
def count_messages_up_to_id(message_id, since=None):
|
|
"""
|
|
Count messages with ID less than or equal to the specified ID.
|
|
|
|
Args:
|
|
message_id (int): Count messages with ID <= this
|
|
since (datetime): Only count messages after this datetime (optional)
|
|
|
|
Returns:
|
|
int: Count of messages
|
|
"""
|
|
session = get_db_session()
|
|
|
|
# Build the query
|
|
query = session.query(Message).filter(
|
|
and_(
|
|
Message.recipient_id.in_(IT_RECIPIENT_IDS),
|
|
Message.id <= message_id
|
|
)
|
|
)
|
|
|
|
# Add date filter if specified
|
|
if since:
|
|
query = query.filter(Message.date_sent >= since)
|
|
|
|
# Count the messages
|
|
count = query.count()
|
|
|
|
return count |