mirror of
				https://github.com/zulip/zulip.git
				synced 2025-11-04 14:03:30 +00:00 
			
		
		
		
	Extract topic.py library.
We start by including functions that do custom queries for topic history. The goal of this library is partly to quarantine the legacy "subject" column on Message.
This commit is contained in:
		@@ -217,90 +217,6 @@ def realm_user_count(realm: Realm) -> int:
 | 
			
		||||
def activity_change_requires_seat_update(user: UserProfile) -> bool:
 | 
			
		||||
    return user.realm.has_seat_based_plan and not user.is_bot
 | 
			
		||||
 | 
			
		||||
def generate_topic_history_from_db_rows(rows: List[Tuple[str, int]]) -> List[Dict[str, Any]]:
 | 
			
		||||
    canonical_topic_names = {}  # type: Dict[str, Tuple[int, str]]
 | 
			
		||||
 | 
			
		||||
    # Sort rows by max_message_id so that if a topic
 | 
			
		||||
    # has many different casings, we use the most
 | 
			
		||||
    # recent row.
 | 
			
		||||
    rows = sorted(rows, key=lambda tup: tup[1])
 | 
			
		||||
 | 
			
		||||
    for (topic_name, max_message_id) in rows:
 | 
			
		||||
        canonical_name = topic_name.lower()
 | 
			
		||||
        canonical_topic_names[canonical_name] = (max_message_id, topic_name)
 | 
			
		||||
 | 
			
		||||
    history = []
 | 
			
		||||
    for canonical_topic, (max_message_id, topic_name) in canonical_topic_names.items():
 | 
			
		||||
        history.append(dict(
 | 
			
		||||
            name=topic_name,
 | 
			
		||||
            max_id=max_message_id)
 | 
			
		||||
        )
 | 
			
		||||
    return sorted(history, key=lambda x: -x['max_id'])
 | 
			
		||||
 | 
			
		||||
def get_topic_history_for_stream(user_profile: UserProfile,
 | 
			
		||||
                                 recipient: Recipient,
 | 
			
		||||
                                 public_history: bool) -> List[Dict[str, Any]]:
 | 
			
		||||
    cursor = connection.cursor()
 | 
			
		||||
    if public_history:
 | 
			
		||||
        query = '''
 | 
			
		||||
        SELECT
 | 
			
		||||
            "zerver_message"."subject" as topic,
 | 
			
		||||
            max("zerver_message".id) as max_message_id
 | 
			
		||||
        FROM "zerver_message"
 | 
			
		||||
        WHERE (
 | 
			
		||||
            "zerver_message"."recipient_id" = %s
 | 
			
		||||
        )
 | 
			
		||||
        GROUP BY (
 | 
			
		||||
            "zerver_message"."subject"
 | 
			
		||||
        )
 | 
			
		||||
        ORDER BY max("zerver_message".id) DESC
 | 
			
		||||
        '''
 | 
			
		||||
        cursor.execute(query, [recipient.id])
 | 
			
		||||
    else:
 | 
			
		||||
        query = '''
 | 
			
		||||
        SELECT
 | 
			
		||||
            "zerver_message"."subject" as topic,
 | 
			
		||||
            max("zerver_message".id) as max_message_id
 | 
			
		||||
        FROM "zerver_message"
 | 
			
		||||
        INNER JOIN "zerver_usermessage" ON (
 | 
			
		||||
            "zerver_usermessage"."message_id" = "zerver_message"."id"
 | 
			
		||||
        )
 | 
			
		||||
        WHERE (
 | 
			
		||||
            "zerver_usermessage"."user_profile_id" = %s AND
 | 
			
		||||
            "zerver_message"."recipient_id" = %s
 | 
			
		||||
        )
 | 
			
		||||
        GROUP BY (
 | 
			
		||||
            "zerver_message"."subject"
 | 
			
		||||
        )
 | 
			
		||||
        ORDER BY max("zerver_message".id) DESC
 | 
			
		||||
        '''
 | 
			
		||||
        cursor.execute(query, [user_profile.id, recipient.id])
 | 
			
		||||
    rows = cursor.fetchall()
 | 
			
		||||
    cursor.close()
 | 
			
		||||
 | 
			
		||||
    return generate_topic_history_from_db_rows(rows)
 | 
			
		||||
 | 
			
		||||
def get_topic_history_for_web_public_stream(recipient: Recipient) -> List[Dict[str, Any]]:
 | 
			
		||||
    cursor = connection.cursor()
 | 
			
		||||
    query = '''
 | 
			
		||||
    SELECT
 | 
			
		||||
        "zerver_message"."subject" as topic,
 | 
			
		||||
        max("zerver_message".id) as max_message_id
 | 
			
		||||
    FROM "zerver_message"
 | 
			
		||||
    WHERE (
 | 
			
		||||
        "zerver_message"."recipient_id" = %s
 | 
			
		||||
    )
 | 
			
		||||
    GROUP BY (
 | 
			
		||||
        "zerver_message"."subject"
 | 
			
		||||
    )
 | 
			
		||||
    ORDER BY max("zerver_message".id) DESC
 | 
			
		||||
    '''
 | 
			
		||||
    cursor.execute(query, [recipient.id])
 | 
			
		||||
    rows = cursor.fetchall()
 | 
			
		||||
    cursor.close()
 | 
			
		||||
 | 
			
		||||
    return generate_topic_history_from_db_rows(rows)
 | 
			
		||||
 | 
			
		||||
def send_signup_message(sender: UserProfile, admin_realm_signup_notifications_stream: str,
 | 
			
		||||
                        user_profile: UserProfile, internal: bool=False,
 | 
			
		||||
                        realm: Optional[Realm]=None) -> None:
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										89
									
								
								zerver/lib/topic.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										89
									
								
								zerver/lib/topic.py
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,89 @@
 | 
			
		||||
from django.db import connection
 | 
			
		||||
 | 
			
		||||
from zerver.models import UserProfile, Recipient
 | 
			
		||||
 | 
			
		||||
from typing import Any, Dict, List, Tuple
 | 
			
		||||
 | 
			
		||||
def generate_topic_history_from_db_rows(rows: List[Tuple[str, int]]) -> List[Dict[str, Any]]:
 | 
			
		||||
    canonical_topic_names = {}  # type: Dict[str, Tuple[int, str]]
 | 
			
		||||
 | 
			
		||||
    # Sort rows by max_message_id so that if a topic
 | 
			
		||||
    # has many different casings, we use the most
 | 
			
		||||
    # recent row.
 | 
			
		||||
    rows = sorted(rows, key=lambda tup: tup[1])
 | 
			
		||||
 | 
			
		||||
    for (topic_name, max_message_id) in rows:
 | 
			
		||||
        canonical_name = topic_name.lower()
 | 
			
		||||
        canonical_topic_names[canonical_name] = (max_message_id, topic_name)
 | 
			
		||||
 | 
			
		||||
    history = []
 | 
			
		||||
    for canonical_topic, (max_message_id, topic_name) in canonical_topic_names.items():
 | 
			
		||||
        history.append(dict(
 | 
			
		||||
            name=topic_name,
 | 
			
		||||
            max_id=max_message_id)
 | 
			
		||||
        )
 | 
			
		||||
    return sorted(history, key=lambda x: -x['max_id'])
 | 
			
		||||
 | 
			
		||||
def get_topic_history_for_stream(user_profile: UserProfile,
 | 
			
		||||
                                 recipient: Recipient,
 | 
			
		||||
                                 public_history: bool) -> List[Dict[str, Any]]:
 | 
			
		||||
    cursor = connection.cursor()
 | 
			
		||||
    if public_history:
 | 
			
		||||
        query = '''
 | 
			
		||||
        SELECT
 | 
			
		||||
            "zerver_message"."subject" as topic,
 | 
			
		||||
            max("zerver_message".id) as max_message_id
 | 
			
		||||
        FROM "zerver_message"
 | 
			
		||||
        WHERE (
 | 
			
		||||
            "zerver_message"."recipient_id" = %s
 | 
			
		||||
        )
 | 
			
		||||
        GROUP BY (
 | 
			
		||||
            "zerver_message"."subject"
 | 
			
		||||
        )
 | 
			
		||||
        ORDER BY max("zerver_message".id) DESC
 | 
			
		||||
        '''
 | 
			
		||||
        cursor.execute(query, [recipient.id])
 | 
			
		||||
    else:
 | 
			
		||||
        query = '''
 | 
			
		||||
        SELECT
 | 
			
		||||
            "zerver_message"."subject" as topic,
 | 
			
		||||
            max("zerver_message".id) as max_message_id
 | 
			
		||||
        FROM "zerver_message"
 | 
			
		||||
        INNER JOIN "zerver_usermessage" ON (
 | 
			
		||||
            "zerver_usermessage"."message_id" = "zerver_message"."id"
 | 
			
		||||
        )
 | 
			
		||||
        WHERE (
 | 
			
		||||
            "zerver_usermessage"."user_profile_id" = %s AND
 | 
			
		||||
            "zerver_message"."recipient_id" = %s
 | 
			
		||||
        )
 | 
			
		||||
        GROUP BY (
 | 
			
		||||
            "zerver_message"."subject"
 | 
			
		||||
        )
 | 
			
		||||
        ORDER BY max("zerver_message".id) DESC
 | 
			
		||||
        '''
 | 
			
		||||
        cursor.execute(query, [user_profile.id, recipient.id])
 | 
			
		||||
    rows = cursor.fetchall()
 | 
			
		||||
    cursor.close()
 | 
			
		||||
 | 
			
		||||
    return generate_topic_history_from_db_rows(rows)
 | 
			
		||||
 | 
			
		||||
def get_topic_history_for_web_public_stream(recipient: Recipient) -> List[Dict[str, Any]]:
 | 
			
		||||
    cursor = connection.cursor()
 | 
			
		||||
    query = '''
 | 
			
		||||
    SELECT
 | 
			
		||||
        "zerver_message"."subject" as topic,
 | 
			
		||||
        max("zerver_message".id) as max_message_id
 | 
			
		||||
    FROM "zerver_message"
 | 
			
		||||
    WHERE (
 | 
			
		||||
        "zerver_message"."recipient_id" = %s
 | 
			
		||||
    )
 | 
			
		||||
    GROUP BY (
 | 
			
		||||
        "zerver_message"."subject"
 | 
			
		||||
    )
 | 
			
		||||
    ORDER BY max("zerver_message".id) DESC
 | 
			
		||||
    '''
 | 
			
		||||
    cursor.execute(query, [recipient.id])
 | 
			
		||||
    rows = cursor.fetchall()
 | 
			
		||||
    cursor.close()
 | 
			
		||||
 | 
			
		||||
    return generate_topic_history_from_db_rows(rows)
 | 
			
		||||
@@ -6,10 +6,10 @@ from django.template import loader
 | 
			
		||||
from zerver.lib.streams import get_stream_by_id
 | 
			
		||||
 | 
			
		||||
from zerver.models import Message, UserProfile, get_stream_recipient
 | 
			
		||||
from zerver.lib.actions import get_topic_history_for_web_public_stream
 | 
			
		||||
from zerver.lib.avatar import get_gravatar_url
 | 
			
		||||
from zerver.lib.response import json_success
 | 
			
		||||
from zerver.lib.timestamp import datetime_to_timestamp
 | 
			
		||||
from zerver.lib.topic import get_topic_history_for_web_public_stream
 | 
			
		||||
from zerver.lib.exceptions import JsonableError
 | 
			
		||||
 | 
			
		||||
def archive(request: HttpRequest,
 | 
			
		||||
 
 | 
			
		||||
@@ -18,7 +18,7 @@ from zerver.lib.actions import bulk_remove_subscriptions, \
 | 
			
		||||
    bulk_add_subscriptions, do_send_messages, get_subscriber_emails, do_rename_stream, \
 | 
			
		||||
    do_deactivate_stream, do_change_stream_invite_only, do_add_default_stream, \
 | 
			
		||||
    do_change_stream_description, do_get_streams, \
 | 
			
		||||
    do_remove_default_stream, get_topic_history_for_stream, \
 | 
			
		||||
    do_remove_default_stream, \
 | 
			
		||||
    do_create_default_stream_group, do_add_streams_to_default_stream_group, \
 | 
			
		||||
    do_remove_streams_from_default_stream_group, do_remove_default_stream_group, \
 | 
			
		||||
    do_change_default_stream_group_description, do_change_default_stream_group_name, \
 | 
			
		||||
@@ -27,6 +27,7 @@ from zerver.lib.response import json_success, json_error, json_response
 | 
			
		||||
from zerver.lib.streams import access_stream_by_id, access_stream_by_name, \
 | 
			
		||||
    check_stream_name, check_stream_name_available, filter_stream_authorization, \
 | 
			
		||||
    list_to_streams, access_stream_for_delete_or_update, access_default_stream_group_by_id
 | 
			
		||||
from zerver.lib.topic import get_topic_history_for_stream
 | 
			
		||||
from zerver.lib.validator import check_string, check_int, check_list, check_dict, \
 | 
			
		||||
    check_bool, check_variable_type, check_capped_string
 | 
			
		||||
from zerver.models import UserProfile, Stream, Realm, Subscription, \
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user