Exclude muted streams in exclude_muting_conditions().

If we call exclude_muting_conditions() with a non-stream
narrow, it will now include a condition to exclude streams
that are not in your home view.  As of now, this code only
executes during testing, but it sets the stage for doing
better in:home queries on the back end.

(imported from commit bbd764bd0e9588a50e4a82c915e82a2c1b99d73e)
This commit is contained in:
Steve Howell 2014-02-25 16:22:35 -05:00 committed by Jessica McKellar
parent 5bb922200a
commit c9140a6def
2 changed files with 47 additions and 6 deletions

View File

@ -2,7 +2,7 @@
from __future__ import absolute_import
from django.db.models import Q
from sqlalchemy.sql import (
select, column, compiler
and_, select, column, compiler
)
from zerver.lib import bugdown
from zerver.decorator import JsonableError
@ -23,7 +23,7 @@ from zerver.lib.test_helpers import (
from zerver.models import (
MAX_MESSAGE_LENGTH, MAX_SUBJECT_LENGTH,
Client, Message, Realm, Recipient, Stream, UserMessage, UserProfile,
Client, Message, Realm, Recipient, Stream, Subscription, UserMessage, UserProfile,
get_display_recipient, get_recipient, get_realm, get_stream, get_user_profile_by_email,
)
@ -52,6 +52,13 @@ def get_recipient_id_for_stream_name(realm, stream_name):
stream = get_stream(stream_name, realm)
return get_recipient(Recipient.STREAM, stream.id).id
def mute_stream(realm, user_profile, stream_name):
stream = Stream.objects.get(realm=realm, name=stream_name)
recipient = Recipient.objects.get(type_id=stream.id, type=Recipient.STREAM)
subscription = Subscription.objects.get(recipient=recipient, user_profile=user_profile)
subscription.in_home_view = False
subscription.save()
class IncludeHistoryTest(AuthedTestCase):
def test_ok_to_include_history(self):
realm = get_realm('zulip.com')
@ -1037,6 +1044,27 @@ class GetOldMessagesTest(AuthedTestCase):
self.assertEqual(params['recipient_id_1'], get_recipient_id_for_stream_name(realm, 'Scotland'))
self.assertEqual(params['upper_1'], 'golf')
mute_stream(realm, user_profile, 'Verona')
narrow = []
muting_conditions = exclude_muting_conditions(user_profile, narrow)
query = select([column("id")], None, "zerver_message")
query = query.where(and_(*muting_conditions))
expected_query = '''
SELECT id
FROM zerver_message
WHERE recipient_id NOT IN (:recipient_id_1)
AND NOT
(recipient_id = :recipient_id_2 AND upper(subject) = upper(:upper_1) OR
recipient_id = :recipient_id_3 AND upper(subject) = upper(:upper_2))'''
self.assertEqual(fix_ws(query), fix_ws(expected_query))
params = get_sqlalchemy_query_params(query)
self.assertEqual(params['recipient_id_1'], get_recipient_id_for_stream_name(realm, 'Verona'))
self.assertEqual(params['recipient_id_2'], get_recipient_id_for_stream_name(realm, 'Scotland'))
self.assertEqual(params['upper_1'], 'golf')
self.assertEqual(params['recipient_id_3'], get_recipient_id_for_stream_name(realm, 'devel'))
self.assertEqual(params['upper_2'], 'css')
def test_get_old_messages_queries(self):
self.common_check_get_old_messages_query({'anchor': 0, 'num_before': 0, 'num_after': 10},
'SELECT anon_1.message_id, anon_1.flags \nFROM (SELECT message_id, flags \nFROM zerver_usermessage \nWHERE user_profile_id = 4 AND message_id >= 0 ORDER BY message_id ASC \n LIMIT 11) AS anon_1 ORDER BY message_id ASC')

View File

@ -21,7 +21,7 @@ from zerver.lib.response import json_success, json_error
from zerver.lib.utils import statsd
from zerver.lib.validator import \
check_list, check_int, check_dict, check_string, check_bool
from zerver.models import Message, UserProfile, Stream, \
from zerver.models import Message, UserProfile, Stream, Subscription, \
Recipient, UserMessage, bulk_get_recipients, get_recipient, \
get_user_profile_by_email, get_stream, valid_stream_name, \
parse_usermessage_flags, to_dict_cache_key_id, extract_message_dict, \
@ -374,13 +374,26 @@ def get_stream_name_from_narrow(narrow):
return None
def exclude_muting_conditions(user_profile, narrow):
conditions = []
stream_name = get_stream_name_from_narrow(narrow)
if stream_name is None:
rows = Subscription.objects.filter(
user_profile=user_profile,
active=True,
in_home_view=False,
recipient__type=Recipient.STREAM
).values('recipient_id')
muted_recipient_ids = map(lambda row: row['recipient_id'], rows)
condition = not_(column("recipient_id").in_(muted_recipient_ids))
conditions.append(condition)
muted_topics = ujson.loads(user_profile.muted_topics)
if muted_topics:
if stream_name is not None:
muted_topics = [m for m in muted_topics if m[0].lower() == stream_name]
if not muted_topics:
return []
return conditions
muted_streams = bulk_get_streams(user_profile.realm,
[muted[0] for muted in muted_topics])
@ -398,9 +411,9 @@ def exclude_muting_conditions(user_profile, narrow):
return and_(stream_cond, topic_cond)
condition = not_(or_(*map(mute_cond, muted_topics)))
return [condition]
return conditions + [condition]
return []
return conditions
@has_request_variables
def get_old_messages_backend(request, user_profile,