mirror of
https://github.com/zulip/zulip.git
synced 2025-11-05 22:43:42 +00:00
Send client information for initial presence and process time differential
(imported from commit 99a51b7cc8b6c51c4e82757a984d07603b2980e3)
This commit is contained in:
@@ -23,7 +23,7 @@ from django.utils import timezone
|
||||
from zephyr.lib.create_user import create_user
|
||||
from zephyr.lib import bugdown
|
||||
from zephyr.lib.cache import cache_with_key, user_profile_by_id_cache_key, \
|
||||
user_profile_by_email_cache_key
|
||||
user_profile_by_email_cache_key, status_dict_cache_key
|
||||
from zephyr.decorator import get_user_profile_by_email, json_to_list, JsonableError
|
||||
from zephyr.lib.event_queue import request_event_queue, get_user_events
|
||||
|
||||
@@ -38,6 +38,7 @@ import datetime
|
||||
import os
|
||||
import platform
|
||||
import logging
|
||||
from collections import defaultdict
|
||||
from os import path
|
||||
|
||||
# Store an event in the log for re-importing messages
|
||||
@@ -581,8 +582,9 @@ def process_user_activity_event(event):
|
||||
return do_update_user_activity(user_profile, client, query, log_time)
|
||||
|
||||
def send_presence_changed(user_profile, presence):
|
||||
presence_dict = presence.to_dict()
|
||||
notice = dict(event=dict(type="presence", email=user_profile.email,
|
||||
presence=presence.to_dict()),
|
||||
presence={presence_dict['client']: presence.to_dict()}),
|
||||
users=[up.id for up in
|
||||
UserProfile.objects.select_related()
|
||||
.filter(realm=user_profile.realm,
|
||||
@@ -602,8 +604,9 @@ def do_update_user_presence(user_profile, client, log_time, status):
|
||||
client = client)
|
||||
created = False
|
||||
|
||||
became_online = (status == UserPresence.ACTIVE and
|
||||
presence.status == UserPresence.IDLE)
|
||||
stale_status = (log_time - presence.timestamp) > datetime.timedelta(minutes=10)
|
||||
was_idle = presence.status == UserPresence.IDLE
|
||||
became_online = (status == UserPresence.ACTIVE) and (stale_status or was_idle)
|
||||
|
||||
presence.timestamp = log_time
|
||||
presence.status = status
|
||||
@@ -765,6 +768,21 @@ def gather_subscriptions(user_profile):
|
||||
|
||||
return sorted(result)
|
||||
|
||||
@cache_with_key(status_dict_cache_key, timeout=60)
|
||||
def get_status_dict(requesting_user_profile):
|
||||
user_statuses = defaultdict(dict)
|
||||
|
||||
# Return no status info for MIT
|
||||
if requesting_user_profile.realm.domain == 'mit.edu':
|
||||
return user_statuses
|
||||
|
||||
for presence in UserPresence.objects.filter(user_profile__realm=requesting_user_profile.realm) \
|
||||
.select_related('user_profile', 'client'):
|
||||
user_statuses[presence.user_profile.email][presence.client.name] = presence.to_dict()
|
||||
|
||||
return user_statuses
|
||||
|
||||
|
||||
def do_events_register(user_profile, apply_markdown=True, event_types=None):
|
||||
queue_id = request_event_queue(user_profile, apply_markdown, event_types)
|
||||
if queue_id is None:
|
||||
@@ -796,11 +814,7 @@ def do_events_register(user_profile, apply_markdown=True, event_types=None):
|
||||
if event_types is None or "subscription" in event_types:
|
||||
ret['subscriptions'] = gather_subscriptions(user_profile)
|
||||
if event_types is None or "presence" in event_types:
|
||||
presences = dict((presence.user_profile.email, presence.to_dict())
|
||||
for presence in UserPresence.objects.select_related()
|
||||
.filter(user_profile__realm=user_profile.realm,
|
||||
user_profile__is_active=True))
|
||||
ret['presences'] = presences
|
||||
ret['presences'] = get_status_dict(user_profile)
|
||||
|
||||
# Apply events that came in while we were fetching initial data
|
||||
events = get_user_events(user_profile, queue_id, -1)
|
||||
@@ -824,7 +838,7 @@ def do_events_register(user_profile, apply_markdown=True, event_types=None):
|
||||
ret['subscriptions'] = filter(lambda s: s['name'] != sub['name'],
|
||||
ret['subscriptions'])
|
||||
elif event['type'] == "presence":
|
||||
ret['presences'][event['email']] = event['presence']
|
||||
ret['presences'][event['email']][event['presence']['client']] = event['presence']
|
||||
|
||||
if events:
|
||||
ret['last_event_id'] = events[-1]['id']
|
||||
|
||||
@@ -73,3 +73,10 @@ def update_user_profile_cache(sender, **kwargs):
|
||||
items_for_memcached[user_profile_by_email_cache_key(user_profile.email)] = (user_profile,)
|
||||
items_for_memcached[user_profile_by_id_cache_key(user_profile.id)] = (user_profile,)
|
||||
djcache.set_many(items_for_memcached)
|
||||
|
||||
def status_dict_cache_key(user_profile):
|
||||
return "status_dict:%d" % (user_profile.realm_id,)
|
||||
|
||||
def update_user_presence_cache(sender, **kwargs):
|
||||
user_profile = kwargs['instance'].user_profile
|
||||
djcache.delete(status_dict_cache_key(user_profile))
|
||||
|
||||
@@ -2,7 +2,8 @@ from django.db import models
|
||||
from django.conf import settings
|
||||
from django.contrib.auth.models import AbstractBaseUser, UserManager
|
||||
from zephyr.lib.cache import cache_with_key, update_user_profile_cache, \
|
||||
user_profile_by_id_cache_key, user_profile_by_email_cache_key
|
||||
user_profile_by_id_cache_key, user_profile_by_email_cache_key, \
|
||||
update_user_presence_cache
|
||||
from zephyr.lib.utils import make_safe_digest
|
||||
import os
|
||||
from django.db import transaction, IntegrityError
|
||||
@@ -444,7 +445,8 @@ class UserPresence(models.Model):
|
||||
elif self.status == UserPresence.IDLE:
|
||||
presence_val = 'idle'
|
||||
|
||||
return {'status' : presence_val,
|
||||
return {'client' : self.client.name,
|
||||
'status' : presence_val,
|
||||
'timestamp': datetime_to_timestamp(self.timestamp)}
|
||||
|
||||
@staticmethod
|
||||
@@ -461,6 +463,10 @@ class UserPresence(models.Model):
|
||||
class Meta:
|
||||
unique_together = ("user_profile", "client")
|
||||
|
||||
# Flush the cached user status_dict whenever a user's presence
|
||||
# changes
|
||||
post_save.connect(update_user_presence_cache, sender=UserPresence)
|
||||
|
||||
class DefaultStream(models.Model):
|
||||
realm = models.ForeignKey(Realm)
|
||||
stream = models.ForeignKey(Stream)
|
||||
|
||||
@@ -72,6 +72,24 @@ function update_users() {
|
||||
ui.set_presence_list(users, user_info);
|
||||
}
|
||||
|
||||
function status_from_timestamp(time_now, presence) {
|
||||
if (presence.website === undefined) {
|
||||
return 'idle';
|
||||
}
|
||||
|
||||
var age = time_now - presence.website.timestamp;
|
||||
|
||||
var status = 'idle';
|
||||
if (presence.website.status === ACTIVE && age >= 0) {
|
||||
if (age < AWAY_THRESHOLD_SECS) {
|
||||
status = 'active';
|
||||
} else if (age < IDLE_THRESHOLD_SECS) {
|
||||
status = 'away';
|
||||
}
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
function focus_ping() {
|
||||
if (!has_focus) {
|
||||
return;
|
||||
@@ -90,23 +108,8 @@ function focus_ping() {
|
||||
|
||||
// Ping returns the active peer list
|
||||
$.each(data.presences, function (this_email, presence) {
|
||||
var age = -1;
|
||||
|
||||
if (presence.website !== undefined && presence.website.timestamp !== undefined) {
|
||||
age = now - presence.website.timestamp;
|
||||
}
|
||||
|
||||
if (page_params.email !== this_email) {
|
||||
var status = 'idle';
|
||||
if (presence.website !== undefined
|
||||
&& presence.website.status === ACTIVE && age >= 0) {
|
||||
if (age < AWAY_THRESHOLD_SECS) {
|
||||
status = 'active';
|
||||
} else if (age < IDLE_THRESHOLD_SECS) {
|
||||
status = 'away';
|
||||
}
|
||||
}
|
||||
user_info[this_email] = status;
|
||||
user_info[this_email] = status_from_timestamp(now, presence);
|
||||
}
|
||||
});
|
||||
update_users();
|
||||
@@ -130,14 +133,17 @@ exports.initialize = function () {
|
||||
keepTracking: true});
|
||||
|
||||
ping_timer = setInterval(focus_ping, ACTIVE_PING_INTERVAL_MS);
|
||||
|
||||
focus_ping();
|
||||
};
|
||||
|
||||
exports.set_user_status = function (user_email, status) {
|
||||
exports.set_user_status = function (user_email, presence) {
|
||||
if (user_email === page_params.email) {
|
||||
return;
|
||||
}
|
||||
var now = new Date().getTime() / 1000;
|
||||
user_info[user_email] = status_from_timestamp(now, presence);
|
||||
|
||||
user_info[user_email] = status;
|
||||
update_users();
|
||||
};
|
||||
|
||||
|
||||
@@ -61,7 +61,7 @@ $(function () {
|
||||
"full_name": "Humbug Feedback Bot"}]);
|
||||
|
||||
$.each(page_params.initial_presences, function (email, presence) {
|
||||
activity.set_user_status(email, presence.status);
|
||||
activity.set_user_status(email, presence);
|
||||
});
|
||||
|
||||
});
|
||||
@@ -694,7 +694,7 @@ function get_updates(options) {
|
||||
}
|
||||
break;
|
||||
case 'presence':
|
||||
activity.set_user_status(event.email, event.presence.status);
|
||||
activity.set_user_status(event.email, event.presence);
|
||||
break;
|
||||
}
|
||||
});
|
||||
|
||||
@@ -26,7 +26,8 @@ from zephyr.lib.actions import do_add_subscription, do_remove_subscription, \
|
||||
log_subscription_property_change, internal_send_message, \
|
||||
create_stream_if_needed, gather_subscriptions, subscribed_to_stream, \
|
||||
update_user_presence, set_stream_color, get_stream_colors, update_message_flags, \
|
||||
recipient_for_emails, extract_recipients, do_events_register, do_finish_tutorial
|
||||
recipient_for_emails, extract_recipients, do_events_register, do_finish_tutorial, \
|
||||
get_status_dict
|
||||
from zephyr.forms import RegistrationForm, HomepageForm, ToSForm, is_unique, \
|
||||
is_inactive, isnt_mit
|
||||
from django.views.decorators.csrf import csrf_exempt
|
||||
@@ -1459,21 +1460,8 @@ def api_beanstalk_webhook(request, user_profile, payload=POST(converter=json_to_
|
||||
return json_error(ret)
|
||||
return json_success()
|
||||
|
||||
@cache_with_key(lambda user_profile: user_profile.realm_id, timeout=60)
|
||||
def get_status_list(requesting_user_profile):
|
||||
user_statuses = defaultdict(dict)
|
||||
|
||||
# Return no status info for MIT
|
||||
if requesting_user_profile.realm.domain == 'mit.edu':
|
||||
return {'presences': user_statuses}
|
||||
|
||||
for presence in UserPresence.objects.filter(
|
||||
user_profile__realm=requesting_user_profile.realm).select_related(
|
||||
'user_profile', 'client'):
|
||||
|
||||
user_statuses[presence.user_profile.email][presence.client.name] = presence.to_dict()
|
||||
|
||||
return {'presences': user_statuses}
|
||||
return {'presences': get_status_dict(requesting_user_profile)}
|
||||
|
||||
@authenticated_json_post_view
|
||||
@has_request_variables
|
||||
|
||||
Reference in New Issue
Block a user