From 27c52cc8c52157d539bb3c761a53d1b6192c8b64 Mon Sep 17 00:00:00 2001 From: Evgeny Fadeev Date: Mon, 24 Sep 2012 21:43:36 -0400 Subject: hopefully fixed a corner case bug in the login system --- askbot/deps/django_authopenid/backends.py | 12 +- askbot/deps/django_authopenid/views.py | 36 ++++-- .../management/commands/askbot_add_test_content.py | 9 +- ...astvisittime__add_field_message_senders_info.py | 134 ------------------- ...dd_unique_lastvisittime_user_message__add_fi.py | 142 +++++++++++++++++++++ group_messaging/models.py | 14 +- group_messaging/views.py | 25 ++-- 7 files changed, 204 insertions(+), 168 deletions(-) delete mode 100644 group_messaging/migrations/0002_auto__add_lastvisittime__add_field_message_senders_info.py create mode 100644 group_messaging/migrations/0002_auto__add_lastvisittime__add_unique_lastvisittime_user_message__add_fi.py diff --git a/askbot/deps/django_authopenid/backends.py b/askbot/deps/django_authopenid/backends.py index f41427b9..1e8626ac 100644 --- a/askbot/deps/django_authopenid/backends.py +++ b/askbot/deps/django_authopenid/backends.py @@ -119,15 +119,17 @@ class AuthBackend(object): assoc.openid_url = username + '@' + provider_name#has to be this way for external pw logins elif method == 'openid': - provider_name = util.get_provider_name(openid_url) try: - assoc = UserAssociation.objects.get( - openid_url = openid_url, - provider_name = provider_name - ) + assoc = UserAssociation.objects.get(openid_url=openid_url) user = assoc.user except UserAssociation.DoesNotExist: return None + except UserAssociation.MultipleObjectsReturned: + logging.critical( + 'duplicate openid url in the database!!! %s' % openid_url + ) + return None + elif method == 'email': #with this method we do no use user association diff --git a/askbot/deps/django_authopenid/views.py b/askbot/deps/django_authopenid/views.py index e5c7df6c..040d837c 100644 --- a/askbot/deps/django_authopenid/views.py +++ b/askbot/deps/django_authopenid/views.py @@ -810,14 +810,34 @@ def finalize_generic_signin( if request.user.is_authenticated(): #this branch is for adding a new association if user is None: - #register new association - UserAssociation( - user = request.user, - provider_name = login_provider_name, - openid_url = user_identifier, - last_used_timestamp = datetime.datetime.now() - ).save() - return HttpResponseRedirect(redirect_url) + try: + #see if currently logged in user has login with the given provider + assoc = UserAssociation.objects.get( + user=request.user, + provider_name=login_provider_name + ) + logging.critical('switching account or open id changed???') + #did openid url change? or we are dealing with a brand new open id? + message1 = _( + 'If you are trying to sign in to another account, ' + 'please sign out first.' + ) + request.user.message_set.create(message=message1) + message2 = _( + 'Otherwise, please report the incident ' + 'to the site administrator.' + ) + request.user.message_set.create(message=message2) + return HttpResponseRedirect(redirect_url) + except UserAssociation.DoesNotExist: + #register new association + UserAssociation( + user=request.user, + provider_name=login_provider_name, + openid_url=user_identifier, + last_used_timestamp=datetime.datetime.now() + ).save() + return HttpResponseRedirect(redirect_url) elif user != request.user: #prevent theft of account by another pre-existing user diff --git a/askbot/management/commands/askbot_add_test_content.py b/askbot/management/commands/askbot_add_test_content.py index 888f7df0..7867fcec 100644 --- a/askbot/management/commands/askbot_add_test_content.py +++ b/askbot/management/commands/askbot_add_test_content.py @@ -72,12 +72,19 @@ class Command(NoArgsCommand): "Create the users and return an array of created users" users = [] - #add admin with the same password + #add admin with the same password - this user will be admin automatically admin = User.objects.create_user('admin', 'admin@example.com') admin.set_password('admin') + admin.save() self.print_if_verbose("Created User 'admin'") users.append(admin) + #this user will have regular privileges, because it's second + joe = User.objects.create_user('joe', 'joe@example.com') + joe.set_password('joe') + joe.save() + self.print_if_verbose("Created User 'joe'") + # Keeping the created users in array - we will iterate over them # several times, we don't want querying the model each and every time. for i in range(NUM_USERS): diff --git a/group_messaging/migrations/0002_auto__add_lastvisittime__add_field_message_senders_info.py b/group_messaging/migrations/0002_auto__add_lastvisittime__add_field_message_senders_info.py deleted file mode 100644 index b6d82bc8..00000000 --- a/group_messaging/migrations/0002_auto__add_lastvisittime__add_field_message_senders_info.py +++ /dev/null @@ -1,134 +0,0 @@ -# -*- coding: utf-8 -*- -import datetime -from south.db import db -from south.v2 import SchemaMigration -from django.db import models - - -class Migration(SchemaMigration): - - def forwards(self, orm): - # Adding model 'LastVisitTime' - db.create_table('group_messaging_lastvisittime', ( - ('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)), - ('user', self.gf('django.db.models.fields.related.OneToOneField')(to=orm['auth.User'], unique=True)), - ('at', self.gf('django.db.models.fields.DateTimeField')(auto_now_add=True, blank=True)), - )) - db.send_create_signal('group_messaging', ['LastVisitTime']) - - # Adding field 'Message.senders_info' - db.add_column('group_messaging_message', 'senders_info', - self.gf('django.db.models.fields.CharField')(default='', max_length=64), - keep_default=False) - - def backwards(self, orm): - # Deleting model 'LastVisitTime' - db.delete_table('group_messaging_lastvisittime') - - # Deleting field 'Message.senders_info' - db.delete_column('group_messaging_message', 'senders_info') - - 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'}, - 'about': ('django.db.models.fields.TextField', [], {'blank': 'True'}), - 'avatar_type': ('django.db.models.fields.CharField', [], {'default': "'n'", 'max_length': '1'}), - 'bronze': ('django.db.models.fields.SmallIntegerField', [], {'default': '0'}), - 'consecutive_days_visit_count': ('django.db.models.fields.IntegerField', [], {'default': '0'}), - 'country': ('django_countries.fields.CountryField', [], {'max_length': '2', 'blank': 'True'}), - 'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), - 'date_of_birth': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}), - 'display_tag_filter_strategy': ('django.db.models.fields.SmallIntegerField', [], {'default': '0'}), - 'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}), - 'email_isvalid': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), - 'email_key': ('django.db.models.fields.CharField', [], {'max_length': '32', 'null': 'True'}), - 'email_signature': ('django.db.models.fields.TextField', [], {'blank': 'True'}), - 'email_tag_filter_strategy': ('django.db.models.fields.SmallIntegerField', [], {'default': '1'}), - 'first_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}), - 'gold': ('django.db.models.fields.SmallIntegerField', [], {'default': '0'}), - 'gravatar': ('django.db.models.fields.CharField', [], {'max_length': '32'}), - 'groups': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Group']", 'symmetrical': 'False', 'blank': 'True'}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'ignored_tags': ('django.db.models.fields.TextField', [], {'blank': 'True'}), - 'interesting_tags': ('django.db.models.fields.TextField', [], {'blank': 'True'}), - 'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), - 'is_fake': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), - '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'}), - 'last_seen': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), - 'location': ('django.db.models.fields.CharField', [], {'max_length': '100', 'blank': 'True'}), - 'new_response_count': ('django.db.models.fields.IntegerField', [], {'default': '0'}), - 'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}), - 'questions_per_page': ('django.db.models.fields.SmallIntegerField', [], {'default': '10'}), - 'real_name': ('django.db.models.fields.CharField', [], {'max_length': '100', 'blank': 'True'}), - 'reputation': ('django.db.models.fields.PositiveIntegerField', [], {'default': '1'}), - 'seen_response_count': ('django.db.models.fields.IntegerField', [], {'default': '0'}), - 'show_country': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), - 'show_marked_tags': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), - 'silver': ('django.db.models.fields.SmallIntegerField', [], {'default': '0'}), - 'status': ('django.db.models.fields.CharField', [], {'default': "'w'", 'max_length': '2'}), - 'subscribed_tags': ('django.db.models.fields.TextField', [], {'blank': 'True'}), - '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': '255'}), - 'website': ('django.db.models.fields.URLField', [], {'max_length': '200', 'blank': 'True'}) - }, - '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'}) - }, - 'group_messaging.lastvisittime': { - 'Meta': {'object_name': 'LastVisitTime'}, - 'at': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'user': ('django.db.models.fields.related.OneToOneField', [], {'to': "orm['auth.User']", 'unique': 'True'}) - }, - 'group_messaging.message': { - 'Meta': {'object_name': 'Message'}, - 'active_until': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}), - 'headline': ('django.db.models.fields.CharField', [], {'max_length': '80'}), - 'html': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'last_active_at': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}), - 'message_type': ('django.db.models.fields.SmallIntegerField', [], {'default': '0'}), - 'parent': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'children'", 'null': 'True', 'to': "orm['group_messaging.Message']"}), - 'recipients': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Group']", 'symmetrical': 'False'}), - 'root': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'descendants'", 'null': 'True', 'to': "orm['group_messaging.Message']"}), - 'sender': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'sent_messages'", 'to': "orm['auth.User']"}), - 'senders_info': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '64'}), - 'sent_at': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}), - 'text': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}) - }, - 'group_messaging.messagememo': { - 'Meta': {'unique_together': "(('user', 'message'),)", 'object_name': 'MessageMemo'}, - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'message': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['group_messaging.Message']"}), - 'status': ('django.db.models.fields.SmallIntegerField', [], {'default': '0'}), - 'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']"}) - }, - 'group_messaging.senderlist': { - 'Meta': {'object_name': 'SenderList'}, - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'recipient': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.Group']", 'unique': 'True'}), - 'senders': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.User']", 'symmetrical': 'False'}) - } - } - - complete_apps = ['group_messaging'] \ No newline at end of file diff --git a/group_messaging/migrations/0002_auto__add_lastvisittime__add_unique_lastvisittime_user_message__add_fi.py b/group_messaging/migrations/0002_auto__add_lastvisittime__add_unique_lastvisittime_user_message__add_fi.py new file mode 100644 index 00000000..5e92ef2b --- /dev/null +++ b/group_messaging/migrations/0002_auto__add_lastvisittime__add_unique_lastvisittime_user_message__add_fi.py @@ -0,0 +1,142 @@ +# -*- coding: utf-8 -*- +import datetime +from south.db import db +from south.v2 import SchemaMigration +from django.db import models + + +class Migration(SchemaMigration): + + def forwards(self, orm): + # Adding model 'LastVisitTime' + db.create_table('group_messaging_lastvisittime', ( + ('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)), + ('user', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['auth.User'])), + ('message', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['group_messaging.Message'])), + ('at', self.gf('django.db.models.fields.DateTimeField')(auto_now_add=True, blank=True)), + )) + db.send_create_signal('group_messaging', ['LastVisitTime']) + + # Adding unique constraint on 'LastVisitTime', fields ['user', 'message'] + db.create_unique('group_messaging_lastvisittime', ['user_id', 'message_id']) + + # Adding field 'Message.senders_info' + db.add_column('group_messaging_message', 'senders_info', + self.gf('django.db.models.fields.CharField')(default='', max_length=64), + keep_default=False) + + def backwards(self, orm): + # Removing unique constraint on 'LastVisitTime', fields ['user', 'message'] + db.delete_unique('group_messaging_lastvisittime', ['user_id', 'message_id']) + + # Deleting model 'LastVisitTime' + db.delete_table('group_messaging_lastvisittime') + + # Deleting field 'Message.senders_info' + db.delete_column('group_messaging_message', 'senders_info') + + 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'}, + 'about': ('django.db.models.fields.TextField', [], {'blank': 'True'}), + 'avatar_type': ('django.db.models.fields.CharField', [], {'default': "'n'", 'max_length': '1'}), + 'bronze': ('django.db.models.fields.SmallIntegerField', [], {'default': '0'}), + 'consecutive_days_visit_count': ('django.db.models.fields.IntegerField', [], {'default': '0'}), + 'country': ('django_countries.fields.CountryField', [], {'max_length': '2', 'blank': 'True'}), + 'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), + 'date_of_birth': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}), + 'display_tag_filter_strategy': ('django.db.models.fields.SmallIntegerField', [], {'default': '0'}), + 'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}), + 'email_isvalid': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'email_key': ('django.db.models.fields.CharField', [], {'max_length': '32', 'null': 'True'}), + 'email_signature': ('django.db.models.fields.TextField', [], {'blank': 'True'}), + 'email_tag_filter_strategy': ('django.db.models.fields.SmallIntegerField', [], {'default': '1'}), + 'first_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}), + 'gold': ('django.db.models.fields.SmallIntegerField', [], {'default': '0'}), + 'gravatar': ('django.db.models.fields.CharField', [], {'max_length': '32'}), + 'groups': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Group']", 'symmetrical': 'False', 'blank': 'True'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'ignored_tags': ('django.db.models.fields.TextField', [], {'blank': 'True'}), + 'interesting_tags': ('django.db.models.fields.TextField', [], {'blank': 'True'}), + 'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), + 'is_fake': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + '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'}), + 'last_seen': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), + 'location': ('django.db.models.fields.CharField', [], {'max_length': '100', 'blank': 'True'}), + 'new_response_count': ('django.db.models.fields.IntegerField', [], {'default': '0'}), + 'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}), + 'questions_per_page': ('django.db.models.fields.SmallIntegerField', [], {'default': '10'}), + 'real_name': ('django.db.models.fields.CharField', [], {'max_length': '100', 'blank': 'True'}), + 'reputation': ('django.db.models.fields.PositiveIntegerField', [], {'default': '1'}), + 'seen_response_count': ('django.db.models.fields.IntegerField', [], {'default': '0'}), + 'show_country': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'show_marked_tags': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), + 'silver': ('django.db.models.fields.SmallIntegerField', [], {'default': '0'}), + 'status': ('django.db.models.fields.CharField', [], {'default': "'w'", 'max_length': '2'}), + 'subscribed_tags': ('django.db.models.fields.TextField', [], {'blank': 'True'}), + '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': '255'}), + 'website': ('django.db.models.fields.URLField', [], {'max_length': '200', 'blank': 'True'}) + }, + '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'}) + }, + 'group_messaging.lastvisittime': { + 'Meta': {'unique_together': "(('user', 'message'),)", 'object_name': 'LastVisitTime'}, + 'at': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'message': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['group_messaging.Message']"}), + 'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']"}) + }, + 'group_messaging.message': { + 'Meta': {'object_name': 'Message'}, + 'active_until': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}), + 'headline': ('django.db.models.fields.CharField', [], {'max_length': '80'}), + 'html': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'last_active_at': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}), + 'message_type': ('django.db.models.fields.SmallIntegerField', [], {'default': '0'}), + 'parent': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'children'", 'null': 'True', 'to': "orm['group_messaging.Message']"}), + 'recipients': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Group']", 'symmetrical': 'False'}), + 'root': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'descendants'", 'null': 'True', 'to': "orm['group_messaging.Message']"}), + 'sender': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'sent_messages'", 'to': "orm['auth.User']"}), + 'senders_info': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '64'}), + 'sent_at': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}), + 'text': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}) + }, + 'group_messaging.messagememo': { + 'Meta': {'unique_together': "(('user', 'message'),)", 'object_name': 'MessageMemo'}, + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'message': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['group_messaging.Message']"}), + 'status': ('django.db.models.fields.SmallIntegerField', [], {'default': '0'}), + 'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']"}) + }, + 'group_messaging.senderlist': { + 'Meta': {'object_name': 'SenderList'}, + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'recipient': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.Group']", 'unique': 'True'}), + 'senders': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.User']", 'symmetrical': 'False'}) + } + } + + complete_apps = ['group_messaging'] \ No newline at end of file diff --git a/group_messaging/models.py b/group_messaging/models.py index 978693ae..62f720cf 100644 --- a/group_messaging/models.py +++ b/group_messaging/models.py @@ -36,16 +36,16 @@ def create_personal_group(user): class LastVisitTime(models.Model): - """just remembers when each user last - visited his/her messages inbox - updated any time when inbox is visited by the user. - - there is only one value per user - it is necessary - for the quick determination of which threads are "new" + """just remembers when a user has + last visited a given thread """ - user = models.OneToOneField(User) + user = models.ForeignKey(User) + message = models.ForeignKey('Message') at = models.DateTimeField(auto_now_add=True) + class Meta: + unique_together = ('user', 'message') + class SenderListManager(models.Manager): """model manager for the :class:`SenderList`""" diff --git a/group_messaging/views.py b/group_messaging/views.py index 8c06ff99..6511fe6e 100644 --- a/group_messaging/views.py +++ b/group_messaging/views.py @@ -141,12 +141,6 @@ class ThreadsList(InboxView): """returns thread list data""" #get threads and the last visit time threads = Message.objects.get_threads_for_user(request.user) - try: - last_visit = LastVisitTime.objects.get(user=request.user) - except LastVisitTime.DoesNotExist: - timestamp = datetime.datetime(2010, 3, 24)#day of askbot - last_visit = LastVisitTime(user=request.user, at=timestamp) - #for each thread we need to know if there is something #unread for the user - to mark "new" threads as bold @@ -154,21 +148,26 @@ class ThreadsList(InboxView): for thread in threads: thread_data = dict() #determine status - status = 'seen' - if thread.last_active_at > last_visit.at: - status = 'new' - thread_data['status'] = status + thread_data['status'] = 'new' #determine the senders info senders_names = thread.senders_info.split(',') if request.user.username in senders_names: senders_names.remove(request.user.username) thread_data['senders_info'] = ', '.join(senders_names) threads_data[thread.id] = thread_data + threads_data[thread] = thread + + last_visit_times = LastVisitTime.objects.filter( + user=request.user, + message__in=threads + ) + for last_visit in last_visit_times: + thread_data = threads_data[last_visit.thread_id] + if thread_data['thread'].last_active_at <= last_visit.at: + thread_data['status'] = 'seen' #after we have all the data - update the last visit time - last_visit.at = datetime.datetime.now() - last_visit.save() - + last_visit_times.update(at=datetime.datetime.now()) return {'threads': threads, 'threads_data': threads_data} -- cgit v1.2.3-1-g7c22