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:
Steve Howell
2018-11-01 14:16:26 +00:00
committed by Tim Abbott
parent 652477daea
commit 50e3f85557
4 changed files with 92 additions and 86 deletions

View File

@@ -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
View 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)

View File

@@ -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,

View File

@@ -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, \