mirror of https://github.com/zulip/zulip.git
[schema][manual] Automatically subscribe users to default streams only after tutorial
(imported from commit 6511851c0aee2628bef597bf1310d6f96b0fd1d4)
This commit is contained in:
parent
7ce6154464
commit
8fe82085c4
|
@ -89,6 +89,7 @@ urlpatterns += patterns('zephyr.views',
|
||||||
url(r'^json/update_active_status$', 'json_update_active_status'),
|
url(r'^json/update_active_status$', 'json_update_active_status'),
|
||||||
url(r'^json/get_active_statuses$', 'json_get_active_statuses'),
|
url(r'^json/get_active_statuses$', 'json_get_active_statuses'),
|
||||||
url(r'^json/tutorial_send_message$', 'json_tutorial_send_message'),
|
url(r'^json/tutorial_send_message$', 'json_tutorial_send_message'),
|
||||||
|
url(r'^json/tutorial_status$', 'json_tutorial_status'),
|
||||||
url(r'^json/change_enter_sends$', 'json_change_enter_sends'),
|
url(r'^json/change_enter_sends$', 'json_change_enter_sends'),
|
||||||
url(r'^json/get_profile$', 'json_get_profile'),
|
url(r'^json/get_profile$', 'json_get_profile'),
|
||||||
url(r'^json/report_error$', 'json_report_error'),
|
url(r'^json/report_error$', 'json_report_error'),
|
||||||
|
|
|
@ -5,7 +5,7 @@ from zephyr.models import Realm, Stream, UserProfile, UserActivity, \
|
||||||
Subscription, Recipient, Message, UserMessage, valid_stream_name, \
|
Subscription, Recipient, Message, UserMessage, valid_stream_name, \
|
||||||
DefaultStream, StreamColor, UserPresence, MAX_SUBJECT_LENGTH, \
|
DefaultStream, StreamColor, UserPresence, MAX_SUBJECT_LENGTH, \
|
||||||
MAX_MESSAGE_LENGTH, get_client, get_stream, get_recipient, get_huddle, \
|
MAX_MESSAGE_LENGTH, get_client, get_stream, get_recipient, get_huddle, \
|
||||||
get_user_profile_by_id
|
get_user_profile_by_id, PreregistrationUser
|
||||||
from django.db import transaction, IntegrityError
|
from django.db import transaction, IntegrityError
|
||||||
from django.db.models import F
|
from django.db.models import F
|
||||||
from django.core.exceptions import ValidationError
|
from django.core.exceptions import ValidationError
|
||||||
|
@ -708,6 +708,23 @@ def subscribed_to_stream(user_profile, stream):
|
||||||
except Subscription.DoesNotExist:
|
except Subscription.DoesNotExist:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
def do_finish_tutorial(user_profile):
|
||||||
|
user_profile.tutorial_status = UserProfile.TUTORIAL_FINISHED
|
||||||
|
user_profile.save()
|
||||||
|
|
||||||
|
# We want to add the default subs list iff there were no subs
|
||||||
|
try:
|
||||||
|
prereg_user = PreregistrationUser.objects.get(email=user_profile.email)
|
||||||
|
except PreregistrationUser.DoesNotExist:
|
||||||
|
return
|
||||||
|
|
||||||
|
streams = prereg_user.streams.all()
|
||||||
|
if len(streams) == 0:
|
||||||
|
add_default_subs(user_profile)
|
||||||
|
else:
|
||||||
|
for stream in streams:
|
||||||
|
do_add_subscription(user_profile, stream)
|
||||||
|
|
||||||
def gather_subscriptions(user_profile):
|
def gather_subscriptions(user_profile):
|
||||||
# This is a little awkward because the StreamColor table has foreign keys
|
# This is a little awkward because the StreamColor table has foreign keys
|
||||||
# to Subscription, but not vice versa, and not all Subscriptions have a
|
# to Subscription, but not vice versa, and not all Subscriptions have a
|
||||||
|
|
|
@ -0,0 +1,180 @@
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
import datetime
|
||||||
|
from south.db import db
|
||||||
|
from south.v2 import SchemaMigration
|
||||||
|
from django.db import models
|
||||||
|
from django.conf import settings
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(SchemaMigration):
|
||||||
|
|
||||||
|
def forwards(self, orm):
|
||||||
|
# Adding field 'UserProfile.tutorial_status'
|
||||||
|
db.add_column('zephyr_userprofile', 'tutorial_status',
|
||||||
|
self.gf('django.db.models.fields.CharField')(default='W', max_length=1),
|
||||||
|
keep_default=False)
|
||||||
|
|
||||||
|
|
||||||
|
if "postgres" in settings.DATABASES["default"]["ENGINE"]:
|
||||||
|
db.execute("ALTER TABLE zephyr_userprofile ALTER COLUMN tutorial_status SET DEFAULT 'W'")
|
||||||
|
|
||||||
|
def backwards(self, orm):
|
||||||
|
# Deleting field 'UserProfile.tutorial_status'
|
||||||
|
db.delete_column('zephyr_userprofile', 'tutorial_status')
|
||||||
|
|
||||||
|
|
||||||
|
models = {
|
||||||
|
'auth.group': {
|
||||||
|
'Meta': {'object_name': 'Group'},
|
||||||
|
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||||
|
'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '80'}),
|
||||||
|
'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'})
|
||||||
|
},
|
||||||
|
'auth.permission': {
|
||||||
|
'Meta': {'ordering': "('content_type__app_label', 'content_type__model', 'codename')", 'unique_together': "(('content_type', 'codename'),)", 'object_name': 'Permission'},
|
||||||
|
'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
|
||||||
|
'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}),
|
||||||
|
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||||
|
'name': ('django.db.models.fields.CharField', [], {'max_length': '50'})
|
||||||
|
},
|
||||||
|
'auth.user': {
|
||||||
|
'Meta': {'object_name': 'User'},
|
||||||
|
'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
|
||||||
|
'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}),
|
||||||
|
'first_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
|
||||||
|
'groups': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Group']", 'symmetrical': 'False', 'blank': 'True'}),
|
||||||
|
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||||
|
'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
|
||||||
|
'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
|
||||||
|
'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
|
||||||
|
'last_login': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
|
||||||
|
'last_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
|
||||||
|
'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
|
||||||
|
'user_permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}),
|
||||||
|
'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'})
|
||||||
|
},
|
||||||
|
'contenttypes.contenttype': {
|
||||||
|
'Meta': {'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"},
|
||||||
|
'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
|
||||||
|
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||||
|
'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
|
||||||
|
'name': ('django.db.models.fields.CharField', [], {'max_length': '100'})
|
||||||
|
},
|
||||||
|
'zephyr.client': {
|
||||||
|
'Meta': {'object_name': 'Client'},
|
||||||
|
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||||
|
'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30', 'db_index': 'True'})
|
||||||
|
},
|
||||||
|
'zephyr.defaultstream': {
|
||||||
|
'Meta': {'unique_together': "(('realm', 'stream'),)", 'object_name': 'DefaultStream'},
|
||||||
|
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||||
|
'realm': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['zephyr.Realm']"}),
|
||||||
|
'stream': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['zephyr.Stream']"})
|
||||||
|
},
|
||||||
|
'zephyr.huddle': {
|
||||||
|
'Meta': {'object_name': 'Huddle'},
|
||||||
|
'huddle_hash': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '40', 'db_index': 'True'}),
|
||||||
|
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'})
|
||||||
|
},
|
||||||
|
'zephyr.message': {
|
||||||
|
'Meta': {'object_name': 'Message'},
|
||||||
|
'content': ('django.db.models.fields.TextField', [], {}),
|
||||||
|
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||||
|
'pub_date': ('django.db.models.fields.DateTimeField', [], {'db_index': 'True'}),
|
||||||
|
'recipient': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['zephyr.Recipient']"}),
|
||||||
|
'rendered_content': ('django.db.models.fields.TextField', [], {'null': 'True'}),
|
||||||
|
'rendered_content_version': ('django.db.models.fields.IntegerField', [], {'null': 'True'}),
|
||||||
|
'sender': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['zephyr.UserProfile']"}),
|
||||||
|
'sending_client': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['zephyr.Client']"}),
|
||||||
|
'subject': ('django.db.models.fields.CharField', [], {'max_length': '60', 'db_index': 'True'})
|
||||||
|
},
|
||||||
|
'zephyr.mituser': {
|
||||||
|
'Meta': {'object_name': 'MitUser'},
|
||||||
|
'email': ('django.db.models.fields.EmailField', [], {'unique': 'True', 'max_length': '75'}),
|
||||||
|
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||||
|
'status': ('django.db.models.fields.IntegerField', [], {'default': '0'})
|
||||||
|
},
|
||||||
|
'zephyr.preregistrationuser': {
|
||||||
|
'Meta': {'object_name': 'PreregistrationUser'},
|
||||||
|
'email': ('django.db.models.fields.EmailField', [], {'max_length': '75'}),
|
||||||
|
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||||
|
'invited_at': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'}),
|
||||||
|
'referred_by': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['zephyr.UserProfile']", 'null': 'True'}),
|
||||||
|
'status': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
|
||||||
|
'streams': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['zephyr.Stream']", 'null': 'True', 'symmetrical': 'False'})
|
||||||
|
},
|
||||||
|
'zephyr.realm': {
|
||||||
|
'Meta': {'object_name': 'Realm'},
|
||||||
|
'domain': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '40', 'db_index': 'True'}),
|
||||||
|
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||||
|
'restricted_to_domain': ('django.db.models.fields.BooleanField', [], {'default': 'True'})
|
||||||
|
},
|
||||||
|
'zephyr.recipient': {
|
||||||
|
'Meta': {'unique_together': "(('type', 'type_id'),)", 'object_name': 'Recipient'},
|
||||||
|
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||||
|
'type': ('django.db.models.fields.PositiveSmallIntegerField', [], {'db_index': 'True'}),
|
||||||
|
'type_id': ('django.db.models.fields.IntegerField', [], {'db_index': 'True'})
|
||||||
|
},
|
||||||
|
'zephyr.stream': {
|
||||||
|
'Meta': {'unique_together': "(('name', 'realm'),)", 'object_name': 'Stream'},
|
||||||
|
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||||
|
'invite_only': ('django.db.models.fields.NullBooleanField', [], {'default': 'False', 'null': 'True', 'blank': 'True'}),
|
||||||
|
'name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'db_index': 'True'}),
|
||||||
|
'realm': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['zephyr.Realm']"})
|
||||||
|
},
|
||||||
|
'zephyr.streamcolor': {
|
||||||
|
'Meta': {'object_name': 'StreamColor'},
|
||||||
|
'color': ('django.db.models.fields.CharField', [], {'max_length': '10'}),
|
||||||
|
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||||
|
'subscription': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['zephyr.Subscription']"})
|
||||||
|
},
|
||||||
|
'zephyr.subscription': {
|
||||||
|
'Meta': {'unique_together': "(('user_profile', 'recipient'),)", 'object_name': 'Subscription'},
|
||||||
|
'active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
|
||||||
|
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||||
|
'in_home_view': ('django.db.models.fields.NullBooleanField', [], {'default': 'True', 'null': 'True', 'blank': 'True'}),
|
||||||
|
'recipient': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['zephyr.Recipient']"}),
|
||||||
|
'user_profile': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['zephyr.UserProfile']"})
|
||||||
|
},
|
||||||
|
'zephyr.useractivity': {
|
||||||
|
'Meta': {'unique_together': "(('user_profile', 'client', 'query'),)", 'object_name': 'UserActivity'},
|
||||||
|
'client': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['zephyr.Client']"}),
|
||||||
|
'count': ('django.db.models.fields.IntegerField', [], {}),
|
||||||
|
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||||
|
'last_visit': ('django.db.models.fields.DateTimeField', [], {}),
|
||||||
|
'query': ('django.db.models.fields.CharField', [], {'max_length': '50', 'db_index': 'True'}),
|
||||||
|
'user_profile': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['zephyr.UserProfile']"})
|
||||||
|
},
|
||||||
|
'zephyr.usermessage': {
|
||||||
|
'Meta': {'unique_together': "(('user_profile', 'message'),)", 'object_name': 'UserMessage'},
|
||||||
|
'archived': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
|
||||||
|
'flags': ('django.db.models.fields.BigIntegerField', [], {'default': '0'}),
|
||||||
|
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||||
|
'message': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['zephyr.Message']"}),
|
||||||
|
'user_profile': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['zephyr.UserProfile']"})
|
||||||
|
},
|
||||||
|
'zephyr.userpresence': {
|
||||||
|
'Meta': {'unique_together': "(('user_profile', 'client'),)", 'object_name': 'UserPresence'},
|
||||||
|
'client': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['zephyr.Client']"}),
|
||||||
|
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||||
|
'status': ('django.db.models.fields.PositiveSmallIntegerField', [], {'default': '1'}),
|
||||||
|
'timestamp': ('django.db.models.fields.DateTimeField', [], {}),
|
||||||
|
'user_profile': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['zephyr.UserProfile']"})
|
||||||
|
},
|
||||||
|
'zephyr.userprofile': {
|
||||||
|
'Meta': {'object_name': 'UserProfile'},
|
||||||
|
'api_key': ('django.db.models.fields.CharField', [], {'max_length': '32'}),
|
||||||
|
'enable_desktop_notifications': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
|
||||||
|
'enter_sends': ('django.db.models.fields.NullBooleanField', [], {'default': 'False', 'null': 'True', 'blank': 'True'}),
|
||||||
|
'full_name': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
|
||||||
|
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||||
|
'last_pointer_updater': ('django.db.models.fields.CharField', [], {'max_length': '64'}),
|
||||||
|
'pointer': ('django.db.models.fields.IntegerField', [], {}),
|
||||||
|
'realm': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['zephyr.Realm']"}),
|
||||||
|
'short_name': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
|
||||||
|
'tutorial_status': ('django.db.models.fields.CharField', [], {'default': "'W'", 'max_length': '1'}),
|
||||||
|
'user': ('django.db.models.fields.related.OneToOneField', [], {'to': "orm['auth.User']", 'unique': 'True'})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
complete_apps = ['zephyr']
|
|
@ -0,0 +1,170 @@
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
import datetime
|
||||||
|
from south.db import db
|
||||||
|
from south.v2 import DataMigration
|
||||||
|
from django.db import models
|
||||||
|
|
||||||
|
class Migration(DataMigration):
|
||||||
|
|
||||||
|
def forwards(self, orm):
|
||||||
|
orm.UserProfile.objects.all().update(tutorial_status="F")
|
||||||
|
|
||||||
|
def backwards(self, orm):
|
||||||
|
"Write your backwards methods here."
|
||||||
|
|
||||||
|
models = {
|
||||||
|
'auth.group': {
|
||||||
|
'Meta': {'object_name': 'Group'},
|
||||||
|
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||||
|
'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '80'}),
|
||||||
|
'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'})
|
||||||
|
},
|
||||||
|
'auth.permission': {
|
||||||
|
'Meta': {'ordering': "('content_type__app_label', 'content_type__model', 'codename')", 'unique_together': "(('content_type', 'codename'),)", 'object_name': 'Permission'},
|
||||||
|
'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
|
||||||
|
'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}),
|
||||||
|
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||||
|
'name': ('django.db.models.fields.CharField', [], {'max_length': '50'})
|
||||||
|
},
|
||||||
|
'auth.user': {
|
||||||
|
'Meta': {'object_name': 'User'},
|
||||||
|
'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
|
||||||
|
'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}),
|
||||||
|
'first_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
|
||||||
|
'groups': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Group']", 'symmetrical': 'False', 'blank': 'True'}),
|
||||||
|
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||||
|
'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
|
||||||
|
'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
|
||||||
|
'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
|
||||||
|
'last_login': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
|
||||||
|
'last_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
|
||||||
|
'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
|
||||||
|
'user_permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}),
|
||||||
|
'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'})
|
||||||
|
},
|
||||||
|
'contenttypes.contenttype': {
|
||||||
|
'Meta': {'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"},
|
||||||
|
'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
|
||||||
|
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||||
|
'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
|
||||||
|
'name': ('django.db.models.fields.CharField', [], {'max_length': '100'})
|
||||||
|
},
|
||||||
|
'zephyr.client': {
|
||||||
|
'Meta': {'object_name': 'Client'},
|
||||||
|
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||||
|
'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30', 'db_index': 'True'})
|
||||||
|
},
|
||||||
|
'zephyr.defaultstream': {
|
||||||
|
'Meta': {'unique_together': "(('realm', 'stream'),)", 'object_name': 'DefaultStream'},
|
||||||
|
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||||
|
'realm': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['zephyr.Realm']"}),
|
||||||
|
'stream': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['zephyr.Stream']"})
|
||||||
|
},
|
||||||
|
'zephyr.huddle': {
|
||||||
|
'Meta': {'object_name': 'Huddle'},
|
||||||
|
'huddle_hash': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '40', 'db_index': 'True'}),
|
||||||
|
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'})
|
||||||
|
},
|
||||||
|
'zephyr.message': {
|
||||||
|
'Meta': {'object_name': 'Message'},
|
||||||
|
'content': ('django.db.models.fields.TextField', [], {}),
|
||||||
|
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||||
|
'pub_date': ('django.db.models.fields.DateTimeField', [], {'db_index': 'True'}),
|
||||||
|
'recipient': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['zephyr.Recipient']"}),
|
||||||
|
'rendered_content': ('django.db.models.fields.TextField', [], {'null': 'True'}),
|
||||||
|
'rendered_content_version': ('django.db.models.fields.IntegerField', [], {'null': 'True'}),
|
||||||
|
'sender': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['zephyr.UserProfile']"}),
|
||||||
|
'sending_client': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['zephyr.Client']"}),
|
||||||
|
'subject': ('django.db.models.fields.CharField', [], {'max_length': '60', 'db_index': 'True'})
|
||||||
|
},
|
||||||
|
'zephyr.mituser': {
|
||||||
|
'Meta': {'object_name': 'MitUser'},
|
||||||
|
'email': ('django.db.models.fields.EmailField', [], {'unique': 'True', 'max_length': '75'}),
|
||||||
|
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||||
|
'status': ('django.db.models.fields.IntegerField', [], {'default': '0'})
|
||||||
|
},
|
||||||
|
'zephyr.preregistrationuser': {
|
||||||
|
'Meta': {'object_name': 'PreregistrationUser'},
|
||||||
|
'email': ('django.db.models.fields.EmailField', [], {'max_length': '75'}),
|
||||||
|
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||||
|
'invited_at': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'}),
|
||||||
|
'referred_by': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['zephyr.UserProfile']", 'null': 'True'}),
|
||||||
|
'status': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
|
||||||
|
'streams': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['zephyr.Stream']", 'null': 'True', 'symmetrical': 'False'})
|
||||||
|
},
|
||||||
|
'zephyr.realm': {
|
||||||
|
'Meta': {'object_name': 'Realm'},
|
||||||
|
'domain': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '40', 'db_index': 'True'}),
|
||||||
|
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||||
|
'restricted_to_domain': ('django.db.models.fields.BooleanField', [], {'default': 'True'})
|
||||||
|
},
|
||||||
|
'zephyr.recipient': {
|
||||||
|
'Meta': {'unique_together': "(('type', 'type_id'),)", 'object_name': 'Recipient'},
|
||||||
|
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||||
|
'type': ('django.db.models.fields.PositiveSmallIntegerField', [], {'db_index': 'True'}),
|
||||||
|
'type_id': ('django.db.models.fields.IntegerField', [], {'db_index': 'True'})
|
||||||
|
},
|
||||||
|
'zephyr.stream': {
|
||||||
|
'Meta': {'unique_together': "(('name', 'realm'),)", 'object_name': 'Stream'},
|
||||||
|
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||||
|
'invite_only': ('django.db.models.fields.NullBooleanField', [], {'default': 'False', 'null': 'True', 'blank': 'True'}),
|
||||||
|
'name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'db_index': 'True'}),
|
||||||
|
'realm': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['zephyr.Realm']"})
|
||||||
|
},
|
||||||
|
'zephyr.streamcolor': {
|
||||||
|
'Meta': {'object_name': 'StreamColor'},
|
||||||
|
'color': ('django.db.models.fields.CharField', [], {'max_length': '10'}),
|
||||||
|
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||||
|
'subscription': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['zephyr.Subscription']"})
|
||||||
|
},
|
||||||
|
'zephyr.subscription': {
|
||||||
|
'Meta': {'unique_together': "(('user_profile', 'recipient'),)", 'object_name': 'Subscription'},
|
||||||
|
'active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
|
||||||
|
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||||
|
'in_home_view': ('django.db.models.fields.NullBooleanField', [], {'default': 'True', 'null': 'True', 'blank': 'True'}),
|
||||||
|
'recipient': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['zephyr.Recipient']"}),
|
||||||
|
'user_profile': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['zephyr.UserProfile']"})
|
||||||
|
},
|
||||||
|
'zephyr.useractivity': {
|
||||||
|
'Meta': {'unique_together': "(('user_profile', 'client', 'query'),)", 'object_name': 'UserActivity'},
|
||||||
|
'client': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['zephyr.Client']"}),
|
||||||
|
'count': ('django.db.models.fields.IntegerField', [], {}),
|
||||||
|
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||||
|
'last_visit': ('django.db.models.fields.DateTimeField', [], {}),
|
||||||
|
'query': ('django.db.models.fields.CharField', [], {'max_length': '50', 'db_index': 'True'}),
|
||||||
|
'user_profile': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['zephyr.UserProfile']"})
|
||||||
|
},
|
||||||
|
'zephyr.usermessage': {
|
||||||
|
'Meta': {'unique_together': "(('user_profile', 'message'),)", 'object_name': 'UserMessage'},
|
||||||
|
'archived': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
|
||||||
|
'flags': ('django.db.models.fields.BigIntegerField', [], {'default': '0'}),
|
||||||
|
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||||
|
'message': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['zephyr.Message']"}),
|
||||||
|
'user_profile': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['zephyr.UserProfile']"})
|
||||||
|
},
|
||||||
|
'zephyr.userpresence': {
|
||||||
|
'Meta': {'unique_together': "(('user_profile', 'client'),)", 'object_name': 'UserPresence'},
|
||||||
|
'client': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['zephyr.Client']"}),
|
||||||
|
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||||
|
'status': ('django.db.models.fields.PositiveSmallIntegerField', [], {'default': '1'}),
|
||||||
|
'timestamp': ('django.db.models.fields.DateTimeField', [], {}),
|
||||||
|
'user_profile': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['zephyr.UserProfile']"})
|
||||||
|
},
|
||||||
|
'zephyr.userprofile': {
|
||||||
|
'Meta': {'object_name': 'UserProfile'},
|
||||||
|
'api_key': ('django.db.models.fields.CharField', [], {'max_length': '32'}),
|
||||||
|
'enable_desktop_notifications': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
|
||||||
|
'enter_sends': ('django.db.models.fields.NullBooleanField', [], {'default': 'False', 'null': 'True', 'blank': 'True'}),
|
||||||
|
'full_name': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
|
||||||
|
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||||
|
'last_pointer_updater': ('django.db.models.fields.CharField', [], {'max_length': '64'}),
|
||||||
|
'pointer': ('django.db.models.fields.IntegerField', [], {}),
|
||||||
|
'realm': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['zephyr.Realm']"}),
|
||||||
|
'short_name': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
|
||||||
|
'tutorial_status': ('django.db.models.fields.CharField', [], {'default': "'W'", 'max_length': '1'}),
|
||||||
|
'user': ('django.db.models.fields.related.OneToOneField', [], {'to': "orm['auth.User']", 'unique': 'True'})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
complete_apps = ['zephyr']
|
||||||
|
symmetrical = True
|
|
@ -69,6 +69,19 @@ class UserProfile(AbstractBaseUser):
|
||||||
enable_desktop_notifications = models.BooleanField(default=True)
|
enable_desktop_notifications = models.BooleanField(default=True)
|
||||||
enter_sends = models.NullBooleanField(default=False)
|
enter_sends = models.NullBooleanField(default=False)
|
||||||
|
|
||||||
|
TUTORIAL_WAITING = 'W'
|
||||||
|
TUTORIAL_STARTED = 'S'
|
||||||
|
TUTORIAL_FINISHED = 'F'
|
||||||
|
TUTORIAL_STATES = ((TUTORIAL_WAITING, "Waiting"),
|
||||||
|
(TUTORIAL_STARTED, "Started"),
|
||||||
|
(TUTORIAL_FINISHED, "Finished"))
|
||||||
|
|
||||||
|
tutorial_status = models.CharField(default=TUTORIAL_WAITING, choices=TUTORIAL_STATES, max_length=1)
|
||||||
|
|
||||||
|
def tutorial_stream_name(self):
|
||||||
|
return "tutorial-%s" % \
|
||||||
|
(self.email.split('@')[0],)[:Stream.MAX_NAME_LENGTH]
|
||||||
|
|
||||||
objects = UserManager()
|
objects = UserManager()
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
|
|
|
@ -438,29 +438,66 @@ exports.get_invite_only = function (stream_name) {
|
||||||
return sub.invite_only;
|
return sub.invite_only;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
function populate_subscriptions(subs) {
|
||||||
|
var sub_rows = [];
|
||||||
|
subs.sort(function (a, b) {
|
||||||
|
return a.name.localeCompare(b.name);
|
||||||
|
});
|
||||||
|
subs.forEach(function (elem) {
|
||||||
|
var stream_name = elem.name;
|
||||||
|
var sub = create_sub(stream_name, {color: elem.color, in_home_view: elem.in_home_view,
|
||||||
|
invite_only: elem.invite_only, subscribed: true});
|
||||||
|
add_sub(stream_name, sub);
|
||||||
|
sub_rows.push(sub);
|
||||||
|
});
|
||||||
|
|
||||||
|
return sub_rows;
|
||||||
|
}
|
||||||
|
|
||||||
|
exports.reload_subscriptions = function (opts) {
|
||||||
|
var on_success;
|
||||||
|
opts = $.extend({}, {clear_first: false, custom_callbacks: false}, opts);
|
||||||
|
|
||||||
|
if (! opts.custom_callbacks) {
|
||||||
|
on_success = function (data) {
|
||||||
|
if (data) {
|
||||||
|
populate_subscriptions(data.subscriptions);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
if (opts.clear_first) {
|
||||||
|
stream_info = [];
|
||||||
|
ui.remove_all_narrow_filters();
|
||||||
|
}
|
||||||
|
|
||||||
|
return $.ajax({
|
||||||
|
type: 'POST',
|
||||||
|
url: '/json/subscriptions/list',
|
||||||
|
dataType: 'json',
|
||||||
|
timeout: 10*1000,
|
||||||
|
success: on_success
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
exports.setup_page = function () {
|
exports.setup_page = function () {
|
||||||
util.make_loading_indicator($('#subs_page_loading_indicator'));
|
util.make_loading_indicator($('#subs_page_loading_indicator'));
|
||||||
|
|
||||||
var our_subs;
|
function populate_and_fill(stream_data, subscription_data) {
|
||||||
var all_streams;
|
var all_streams = [];
|
||||||
|
var our_subs = [];
|
||||||
|
|
||||||
function maybe_populate_subscriptions() {
|
/* arguments are [ "success", statusText, jqXHR ] */
|
||||||
// We only execute if both asynchronous queries have returned
|
if (stream_data.length > 2 && stream_data[2]) {
|
||||||
if (our_subs === undefined || all_streams === undefined) {
|
var stream_response = JSON.parse(stream_data[2].responseText);
|
||||||
return;
|
all_streams = stream_response.streams;
|
||||||
|
}
|
||||||
|
if (subscription_data.length > 2 && subscription_data[2]) {
|
||||||
|
var subs_response = JSON.parse(subscription_data[2].responseText);
|
||||||
|
our_subs = subs_response.subscriptions;
|
||||||
}
|
}
|
||||||
|
|
||||||
var sub_rows = [];
|
var sub_rows = populate_subscriptions(our_subs);
|
||||||
our_subs.sort(function (a, b) {
|
|
||||||
return a.name.localeCompare(b.name);
|
|
||||||
});
|
|
||||||
our_subs.forEach(function (elem) {
|
|
||||||
var stream_name = elem.name;
|
|
||||||
var sub = create_sub(stream_name, {color: elem.color, in_home_view: elem.in_home_view,
|
|
||||||
invite_only: elem.invite_only, subscribed: true});
|
|
||||||
add_sub(stream_name, sub);
|
|
||||||
sub_rows.push(sub);
|
|
||||||
});
|
|
||||||
|
|
||||||
all_streams.sort();
|
all_streams.sort();
|
||||||
all_streams.forEach(function (stream) {
|
all_streams.forEach(function (stream) {
|
||||||
|
@ -480,46 +517,35 @@ exports.setup_page = function () {
|
||||||
$('#create_stream_name').focus().select();
|
$('#create_stream_name').focus().select();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function failed_listing(xhr, error) {
|
||||||
|
util.destroy_loading_indicator($('#subs_page_loading_indicator'));
|
||||||
|
ui.report_error("Error listing streams or subscriptions", xhr, $("#subscriptions-status"));
|
||||||
|
}
|
||||||
|
|
||||||
|
var requests = [];
|
||||||
if (should_list_all_streams()) {
|
if (should_list_all_streams()) {
|
||||||
// This query must go first to prevent a race when we are not
|
// This query must go first to prevent a race when we are not
|
||||||
// listing all streams
|
// listing all streams
|
||||||
$.ajax({
|
var req = $.ajax({
|
||||||
type: 'POST',
|
type: 'POST',
|
||||||
url: '/json/get_public_streams',
|
url: '/json/get_public_streams',
|
||||||
dataType: 'json',
|
dataType: 'json',
|
||||||
timeout: 10*1000,
|
timeout: 10*1000
|
||||||
success: function (data) {
|
|
||||||
if (data) {
|
|
||||||
all_streams = data.streams;
|
|
||||||
maybe_populate_subscriptions();
|
|
||||||
}
|
|
||||||
},
|
|
||||||
error: function (xhr) {
|
|
||||||
util.destroy_loading_indicator($('#subs_page_loading_indicator'));
|
|
||||||
ui.report_error("Error listing subscriptions", xhr, $("#subscriptions-status"));
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
requests.push(req);
|
||||||
} else {
|
} else {
|
||||||
all_streams = [];
|
// Handing an object to $.when() means that it counts as a 'success' with the
|
||||||
|
// object delivered directly to the callback
|
||||||
|
requests.push({streams: []});
|
||||||
$('#create_stream_button').val("Subscribe");
|
$('#create_stream_button').val("Subscribe");
|
||||||
}
|
}
|
||||||
|
|
||||||
$.ajax({
|
requests.push(exports.reload_subscriptions({custom_callbacks: true}));
|
||||||
type: 'POST',
|
|
||||||
url: '/json/subscriptions/list',
|
// Trigger finished callback when:
|
||||||
dataType: 'json',
|
// * Both AJAX requests are finished, if we sent themm both
|
||||||
timeout: 10*1000,
|
// * Just one AJAX is finished if should_list_all_streams() is false
|
||||||
success: function (data) {
|
$.when.apply(this, requests).then(populate_and_fill, failed_listing);
|
||||||
if (data) {
|
|
||||||
our_subs = data.subscriptions;
|
|
||||||
maybe_populate_subscriptions();
|
|
||||||
}
|
|
||||||
},
|
|
||||||
error: function (xhr) {
|
|
||||||
util.destroy_loading_indicator($('#subs_page_loading_indicator'));
|
|
||||||
ui.report_error("Error listing subscriptions", xhr, $("#subscriptions-status"));
|
|
||||||
}
|
|
||||||
});
|
|
||||||
};
|
};
|
||||||
|
|
||||||
exports.have = function (stream_name) {
|
exports.have = function (stream_name) {
|
||||||
|
|
|
@ -240,6 +240,13 @@ exports.start = function () {
|
||||||
tutorial_running = true;
|
tutorial_running = true;
|
||||||
add_to_tutorial_stream();
|
add_to_tutorial_stream();
|
||||||
run_tutorial(0);
|
run_tutorial(0);
|
||||||
|
|
||||||
|
$.ajax({
|
||||||
|
type: 'POST',
|
||||||
|
url: '/json/tutorial_status',
|
||||||
|
data: {status: 'started'}
|
||||||
|
});
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// This technique is not actually that awesome, because it's pretty
|
// This technique is not actually that awesome, because it's pretty
|
||||||
|
@ -256,6 +263,17 @@ exports.stop = function () {
|
||||||
if (tutorial_running) {
|
if (tutorial_running) {
|
||||||
subs.tutorial_unsubscribe_me_from(my_tutorial_stream);
|
subs.tutorial_unsubscribe_me_from(my_tutorial_stream);
|
||||||
tutorial_running = false;
|
tutorial_running = false;
|
||||||
|
|
||||||
|
$.ajax({
|
||||||
|
type: 'POST',
|
||||||
|
url: '/json/tutorial_status',
|
||||||
|
data: {status: 'finished'},
|
||||||
|
success: function () {
|
||||||
|
// We need to reload the streams list so the sidebar is populated
|
||||||
|
// with the new streams
|
||||||
|
subs.reload_subscriptions({clear_first: true});
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -1167,6 +1167,10 @@ exports.remove_narrow_filter = function (name, type) {
|
||||||
exports.get_filter_li(type, name).remove();
|
exports.get_filter_li(type, name).remove();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
exports.remove_all_narrow_filters = function () {
|
||||||
|
$("#stream_filters").children().remove();
|
||||||
|
};
|
||||||
|
|
||||||
var presence_descriptions = {
|
var presence_descriptions = {
|
||||||
active: ' is active',
|
active: ' is active',
|
||||||
away: ' was recently active',
|
away: ' was recently active',
|
||||||
|
|
|
@ -25,7 +25,7 @@ from zephyr.lib.actions import do_add_subscription, do_remove_subscription, \
|
||||||
log_subscription_property_change, internal_send_message, \
|
log_subscription_property_change, internal_send_message, \
|
||||||
create_stream_if_needed, gather_subscriptions, subscribed_to_stream, \
|
create_stream_if_needed, gather_subscriptions, subscribed_to_stream, \
|
||||||
update_user_presence, set_stream_color, get_stream_colors, update_message_flags, \
|
update_user_presence, set_stream_color, get_stream_colors, update_message_flags, \
|
||||||
recipient_for_emails, extract_recipients, do_events_register
|
recipient_for_emails, extract_recipients, do_events_register, do_finish_tutorial
|
||||||
from zephyr.forms import RegistrationForm, HomepageForm, ToSForm, is_unique, \
|
from zephyr.forms import RegistrationForm, HomepageForm, ToSForm, is_unique, \
|
||||||
is_inactive, isnt_mit
|
is_inactive, isnt_mit
|
||||||
from django.views.decorators.csrf import csrf_exempt
|
from django.views.decorators.csrf import csrf_exempt
|
||||||
|
@ -212,14 +212,6 @@ def accounts_register(request):
|
||||||
do_change_full_name(user_profile, full_name)
|
do_change_full_name(user_profile, full_name)
|
||||||
else:
|
else:
|
||||||
user_profile = do_create_user(email, password, realm, full_name, short_name)
|
user_profile = do_create_user(email, password, realm, full_name, short_name)
|
||||||
# We want to add the default subs list iff there were no subs
|
|
||||||
# specified when the user was invited.
|
|
||||||
streams = prereg_user.streams.all()
|
|
||||||
if len(streams) == 0:
|
|
||||||
add_default_subs(user_profile)
|
|
||||||
else:
|
|
||||||
for stream in streams:
|
|
||||||
do_add_subscription(user_profile, stream)
|
|
||||||
if prereg_user.referred_by is not None:
|
if prereg_user.referred_by is not None:
|
||||||
# This is a cross-realm private message.
|
# This is a cross-realm private message.
|
||||||
internal_send_message("humbug+signups@humbughq.com",
|
internal_send_message("humbug+signups@humbughq.com",
|
||||||
|
@ -401,9 +393,21 @@ def home(request):
|
||||||
register_ret = do_events_register(user_profile, apply_markdown=True)
|
register_ret = do_events_register(user_profile, apply_markdown=True)
|
||||||
user_has_messages = (register_ret['max_message_id'] != -1)
|
user_has_messages = (register_ret['max_message_id'] != -1)
|
||||||
|
|
||||||
# Brand new users get the tutorial.
|
# Brand new users get the tutorial
|
||||||
# Compute this here, before we set user_profile.pointer below.
|
needs_tutorial = settings.TUTORIAL_ENABLED and \
|
||||||
needs_tutorial = settings.TUTORIAL_ENABLED and user_profile.pointer == -1
|
user_profile.tutorial_status == UserProfile.TUTORIAL_WAITING
|
||||||
|
|
||||||
|
# If the user has previously started (but not completed) the tutorial,
|
||||||
|
# finish it for her and subscribe her to the default streams
|
||||||
|
if user_profile.tutorial_status == UserProfile.TUTORIAL_STARTED:
|
||||||
|
tutorial_stream = user_profile.tutorial_stream_name()
|
||||||
|
try:
|
||||||
|
stream = Stream.objects.get(realm=user_profile.realm, name=tutorial_stream)
|
||||||
|
do_remove_subscription(user_profile, stream)
|
||||||
|
except Stream.DoesNotExist:
|
||||||
|
pass
|
||||||
|
|
||||||
|
do_finish_tutorial(user_profile)
|
||||||
|
|
||||||
if user_profile.pointer == -1 and user_has_messages:
|
if user_profile.pointer == -1 and user_has_messages:
|
||||||
# Put the new user's pointer at the bottom
|
# Put the new user's pointer at the bottom
|
||||||
|
@ -769,8 +773,7 @@ def json_tutorial_send_message(request, user_profile,
|
||||||
realm=user_profile.realm)
|
realm=user_profile.realm)
|
||||||
return json_success()
|
return json_success()
|
||||||
elif message_type_name == 'stream':
|
elif message_type_name == 'stream':
|
||||||
tutorial_stream_name = 'tutorial-%s' % user_profile.email.split('@')[0]
|
tutorial_stream_name = user_profile.tutorial_stream_name()
|
||||||
tutorial_stream_name = tutorial_stream_name[:Stream.MAX_NAME_LENGTH]
|
|
||||||
## TODO: For open realms, we need to use the full name here,
|
## TODO: For open realms, we need to use the full name here,
|
||||||
## so that me@gmail.com and me@hotmail.com don't get the same stream.
|
## so that me@gmail.com and me@hotmail.com don't get the same stream.
|
||||||
internal_send_message(sender_name,
|
internal_send_message(sender_name,
|
||||||
|
@ -782,6 +785,18 @@ def json_tutorial_send_message(request, user_profile,
|
||||||
return json_success()
|
return json_success()
|
||||||
return json_error('Bad data passed in to tutorial_send_message')
|
return json_error('Bad data passed in to tutorial_send_message')
|
||||||
|
|
||||||
|
|
||||||
|
@authenticated_json_post_view
|
||||||
|
@has_request_variables
|
||||||
|
def json_tutorial_status(request, user_profile, status=POST('status')):
|
||||||
|
if status == 'started':
|
||||||
|
user_profile.tutorial_status = UserProfile.TUTORIAL_STARTED
|
||||||
|
user_profile.save()
|
||||||
|
elif status == 'finished':
|
||||||
|
do_finish_tutorial(user_profile)
|
||||||
|
|
||||||
|
return json_success()
|
||||||
|
|
||||||
# We do not @require_login for send_message_backend, since it is used
|
# We do not @require_login for send_message_backend, since it is used
|
||||||
# both from the API and the web service. Code calling
|
# both from the API and the web service. Code calling
|
||||||
# send_message_backend should either check the API key or check that
|
# send_message_backend should either check the API key or check that
|
||||||
|
|
Loading…
Reference in New Issue