From 133a8f939cdfa69dd6a7caeafed158aa38d20092 Mon Sep 17 00:00:00 2001 From: hernani Date: Fri, 16 Apr 2010 17:31:04 +0000 Subject: [PATCH] convertd comments to nodes git-svn-id: http://svn.osqa.net/svnroot/osqa/trunk@40 0cfe37f9-358a-4d5e-be75-b63607b5c754 --- forum/activity.py | 35 +- ..._repute_node__add_field_repute_canceled.py | 312 ++++++++++++++++ forum/migrations/0018_comments_to_node.py | 352 ++++++++++++++++++ forum/models/__init__.py | 5 +- forum/models/base.py | 20 +- forum/models/comment.py | 50 +++ forum/models/meta.py | 87 +---- forum/models/node.py | 40 +- forum/models/question.py | 15 +- forum/models/repute.py | 8 +- forum/models/user.py | 10 +- forum/reputation.py | 4 +- .../default/templates/node/comments.html | 2 +- .../skins/default/templates/users/stats.html | 11 +- forum/subscriptions.py | 22 +- forum/templatetags/node_tags.py | 4 +- forum/views/commands.py | 7 +- 17 files changed, 817 insertions(+), 167 deletions(-) create mode 100644 forum/migrations/0017_auto__add_field_repute_node__add_field_repute_canceled.py create mode 100644 forum/migrations/0018_comments_to_node.py create mode 100644 forum/models/comment.py diff --git a/forum/activity.py b/forum/activity.py index a58307b..1687798 100644 --- a/forum/activity.py +++ b/forum/activity.py @@ -1,35 +1,32 @@ import datetime from django.db.models.signals import post_save from forum.models import * -from forum.models.base import marked_deleted -from forum.models.meta import vote_canceled +from forum.models.base import marked_deleted, mark_canceled +from forum.models.node import node_create from forum.models.answer import answer_accepted from forum.authentication import user_updated from forum.const import * -def record_ask_event(instance, created, **kwargs): - if created: - activity = Activity(user=instance.author, active_at=instance.added_at, content_object=instance, activity_type=TYPE_ACTIVITY_ASK_QUESTION) - activity.save() +def record_ask_event(instance, **kwargs): + activity = Activity(user=instance.author, active_at=instance.added_at, content_object=instance, activity_type=TYPE_ACTIVITY_ASK_QUESTION) + activity.save() -post_save.connect(record_ask_event, sender=Question) +node_create.connect(record_ask_event, sender=Question) -def record_answer_event(instance, created, **kwargs): - if created: - activity = Activity(user=instance.author, active_at=instance.added_at, content_object=instance, activity_type=TYPE_ACTIVITY_ANSWER) - activity.save() +def record_answer_event(instance, **kwargs): + activity = Activity(user=instance.author, active_at=instance.added_at, content_object=instance, activity_type=TYPE_ACTIVITY_ANSWER) + activity.save() -post_save.connect(record_answer_event, sender=Answer) +node_create.connect(record_answer_event, sender=Answer) -def record_comment_event(instance, created, **kwargs): - if created: - act_type = (instance.content_object.__class__ is Question) and TYPE_ACTIVITY_COMMENT_QUESTION or TYPE_ACTIVITY_COMMENT_ANSWER - activity = Activity(user=instance.user, active_at=instance.added_at, content_object=instance, activity_type=act_type) - activity.save() +def record_comment_event(instance, **kwargs): + act_type = (instance.content_object.__class__ is Question) and TYPE_ACTIVITY_COMMENT_QUESTION or TYPE_ACTIVITY_COMMENT_ANSWER + activity = Activity(user=instance.user, active_at=instance.added_at, content_object=instance, activity_type=act_type) + activity.save() -post_save.connect(record_comment_event, sender=Comment) +node_create.connect(record_comment_event, sender=Comment) def record_revision_event(instance, created, **kwargs): @@ -80,7 +77,7 @@ def record_cancel_vote(instance, **kwargs): activity = Activity(user=instance.user, active_at=datetime.datetime.now(), content_object=instance, activity_type=act_type) activity.save() -vote_canceled.connect(record_cancel_vote) +mark_canceled.connect(record_cancel_vote, sender=Vote) def record_delete_post(instance, **kwargs): diff --git a/forum/migrations/0017_auto__add_field_repute_node__add_field_repute_canceled.py b/forum/migrations/0017_auto__add_field_repute_node__add_field_repute_canceled.py new file mode 100644 index 0000000..cb14267 --- /dev/null +++ b/forum/migrations/0017_auto__add_field_repute_node__add_field_repute_canceled.py @@ -0,0 +1,312 @@ +# encoding: 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 field 'Repute.node' + db.add_column(u'repute', 'node', self.gf('django.db.models.fields.related.ForeignKey')(related_name='reputes', null=True, to=orm['forum.Node']), keep_default=False) + + # Adding field 'Repute.canceled' + db.add_column(u'repute', 'canceled', self.gf('django.db.models.fields.BooleanField')(default=False, blank=True), keep_default=False) + + + def backwards(self, orm): + + # Deleting field 'Repute.node' + db.delete_column(u'repute', 'node_id') + + # Deleting field 'Repute.canceled' + db.delete_column(u'repute', 'canceled') + + + 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']", 'blank': 'True'}) + }, + 'auth.permission': { + 'Meta': {'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']", 'blank': 'True'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True', 'blank': 'True'}), + 'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}), + 'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}), + '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']", 'blank': 'True'}), + 'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'}) + }, + 'contenttypes.contenttype': { + 'Meta': {'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'}) + }, + 'forum.activity': { + 'Meta': {'object_name': 'Activity', 'db_table': "u'activity'"}, + 'active_at': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), + 'activity_type': ('django.db.models.fields.SmallIntegerField', [], {}), + 'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'is_auditted': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}), + 'object_id': ('django.db.models.fields.PositiveIntegerField', [], {}), + 'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['forum.User']"}) + }, + 'forum.anonymousnode': { + 'Meta': {'object_name': 'AnonymousNode', '_ormbases': ['forum.Node']}, + 'convertible_to': ('django.db.models.fields.CharField', [], {'default': "'node'", 'max_length': '16'}), + 'node_ptr': ('django.db.models.fields.related.OneToOneField', [], {'to': "orm['forum.Node']", 'unique': 'True', 'primary_key': 'True'}), + 'validation_hash': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'anonymous_content'", 'to': "orm['forum.Node']"}) + }, + 'forum.answer': { + 'Meta': {'object_name': 'Answer', 'db_table': "u'answer'"}, + 'accepted': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}), + 'accepted_at': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}), + 'accepted_by': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['forum.User']", 'null': 'True'}), + 'node_ptr': ('django.db.models.fields.related.OneToOneField', [], {'to': "orm['forum.Node']", 'unique': 'True', 'primary_key': 'True'}), + 'wiki': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}), + 'wikified_at': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}) + }, + 'forum.authkeyuserassociation': { + 'Meta': {'object_name': 'AuthKeyUserAssociation'}, + 'added_at': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'key': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '255'}), + 'provider': ('django.db.models.fields.CharField', [], {'max_length': '64'}), + 'user': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'auth_keys'", 'to': "orm['forum.User']"}) + }, + 'forum.award': { + 'Meta': {'unique_together': "(('content_type', 'object_id', 'user', 'badge'),)", 'object_name': 'Award', 'db_table': "u'award'"}, + 'awarded_at': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), + 'badge': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'award_badge'", 'to': "orm['forum.Badge']"}), + 'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'notified': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}), + 'object_id': ('django.db.models.fields.PositiveIntegerField', [], {}), + 'user': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'awards'", 'to': "orm['forum.User']"}) + }, + 'forum.badge': { + 'Meta': {'unique_together': "(('name', 'type'),)", 'object_name': 'Badge', 'db_table': "u'badge'"}, + 'awarded_count': ('django.db.models.fields.PositiveIntegerField', [], {'default': '0'}), + 'awarded_to': ('django.db.models.fields.related.ManyToManyField', [], {'related_name': "'badges'", 'through': "'Award'", 'to': "orm['forum.User']"}), + 'description': ('django.db.models.fields.CharField', [], {'max_length': '300'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'multiple': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '50'}), + 'slug': ('django.db.models.fields.SlugField', [], {'db_index': 'True', 'max_length': '50', 'blank': 'True'}), + 'type': ('django.db.models.fields.SmallIntegerField', [], {}) + }, + 'forum.comment': { + 'Meta': {'object_name': 'Comment', 'db_table': "u'comment'"}, + 'added_at': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), + 'comment': ('django.db.models.fields.CharField', [], {'max_length': '300'}), + 'deleted': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}), + 'deleted_at': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}), + 'deleted_by': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'deleted_comments'", 'null': 'True', 'to': "orm['forum.User']"}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'liked_by': ('django.db.models.fields.related.ManyToManyField', [], {'related_name': "'comments_liked'", 'through': "'LikedComment'", 'to': "orm['forum.User']"}), + 'node': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'comments'", 'null': 'True', 'to': "orm['forum.Node']"}), + 'score': ('django.db.models.fields.IntegerField', [], {'default': '0'}), + 'user': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'comments'", 'to': "orm['forum.User']"}) + }, + 'forum.favoritequestion': { + 'Meta': {'unique_together': "(('question', 'user'),)", 'object_name': 'FavoriteQuestion', 'db_table': "u'favorite_question'"}, + 'added_at': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'question': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['forum.Question']"}), + 'user': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'user_favorite_questions'", 'to': "orm['forum.User']"}) + }, + 'forum.flaggeditem': { + 'Meta': {'object_name': 'FlaggedItem', 'db_table': "u'flagged_item'"}, + 'canceled': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}), + 'flagged_at': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'node': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'flaggeditems'", 'null': 'True', 'to': "orm['forum.Node']"}), + 'reason': ('django.db.models.fields.CharField', [], {'max_length': '300', 'null': 'True'}), + 'user': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'flaggeditems'", 'to': "orm['forum.User']"}) + }, + 'forum.keyvalue': { + 'Meta': {'object_name': 'KeyValue'}, + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'key': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '255'}), + 'value': ('forum.models.utils.PickledObjectField', [], {}) + }, + 'forum.likedcomment': { + 'Meta': {'object_name': 'LikedComment'}, + 'added_at': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), + 'canceled': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}), + 'comment': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['forum.Comment']"}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['forum.User']"}) + }, + 'forum.markedtag': { + 'Meta': {'object_name': 'MarkedTag'}, + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'reason': ('django.db.models.fields.CharField', [], {'max_length': '16'}), + 'tag': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'user_selections'", 'to': "orm['forum.Tag']"}), + 'user': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'tag_selections'", 'to': "orm['forum.User']"}) + }, + 'forum.node': { + 'Meta': {'object_name': 'Node'}, + 'active_revision': ('django.db.models.fields.related.OneToOneField', [], {'related_name': "'active'", 'unique': 'True', 'null': 'True', 'to': "orm['forum.NodeRevision']"}), + 'added_at': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), + 'author': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'nodes'", 'to': "orm['forum.User']"}), + 'body': ('django.db.models.fields.TextField', [], {}), + 'comment_count': ('django.db.models.fields.PositiveIntegerField', [], {'default': '0'}), + 'deleted': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}), + 'deleted_at': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}), + 'deleted_by': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'deleted_nodes'", 'null': 'True', 'to': "orm['forum.User']"}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'last_edited_at': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}), + 'last_edited_by': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'last_edited_nodes'", 'null': 'True', 'to': "orm['forum.User']"}), + 'node_type': ('django.db.models.fields.CharField', [], {'default': "'node'", 'max_length': '16'}), + 'offensive_flag_count': ('django.db.models.fields.SmallIntegerField', [], {'default': '0'}), + 'parent': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'children'", 'null': 'True', 'to': "orm['forum.Node']"}), + 'score': ('django.db.models.fields.IntegerField', [], {'default': '0'}), + 'tagnames': ('django.db.models.fields.CharField', [], {'max_length': '125'}), + 'tags': ('django.db.models.fields.related.ManyToManyField', [], {'related_name': "'nodes'", 'to': "orm['forum.Tag']"}), + 'title': ('django.db.models.fields.CharField', [], {'max_length': '300'}), + 'vote_down_count': ('django.db.models.fields.IntegerField', [], {'default': '0'}), + 'vote_up_count': ('django.db.models.fields.IntegerField', [], {'default': '0'}) + }, + 'forum.noderevision': { + 'Meta': {'unique_together': "(('node', 'revision'),)", 'object_name': 'NodeRevision'}, + 'author': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'noderevisions'", 'to': "orm['forum.User']"}), + 'body': ('django.db.models.fields.TextField', [], {}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'node': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'revisions'", 'to': "orm['forum.Node']"}), + 'revised_at': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), + 'revision': ('django.db.models.fields.PositiveIntegerField', [], {}), + 'summary': ('django.db.models.fields.CharField', [], {'max_length': '300'}), + 'tagnames': ('django.db.models.fields.CharField', [], {'max_length': '125'}), + 'title': ('django.db.models.fields.CharField', [], {'max_length': '300'}) + }, + 'forum.question': { + 'Meta': {'object_name': 'Question', 'db_table': "u'question'"}, + 'accepted_answer': ('django.db.models.fields.related.OneToOneField', [], {'related_name': "'question_accepting'", 'unique': 'True', 'null': 'True', 'to': "orm['forum.Answer']"}), + 'answer_count': ('django.db.models.fields.PositiveIntegerField', [], {'default': '0'}), + 'close_reason': ('django.db.models.fields.SmallIntegerField', [], {'null': 'True', 'blank': 'True'}), + 'closed': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}), + 'closed_at': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}), + 'closed_by': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'closed_questions'", 'null': 'True', 'to': "orm['forum.User']"}), + 'favorited_by': ('django.db.models.fields.related.ManyToManyField', [], {'related_name': "'favorite_questions'", 'through': "'FavoriteQuestion'", 'to': "orm['forum.User']"}), + 'favourite_count': ('django.db.models.fields.IntegerField', [], {'default': '0'}), + 'last_activity_at': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), + 'last_activity_by': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'last_active_in_questions'", 'to': "orm['forum.User']"}), + 'node_ptr': ('django.db.models.fields.related.OneToOneField', [], {'to': "orm['forum.Node']", 'unique': 'True'}), + 'subscribers': ('django.db.models.fields.related.ManyToManyField', [], {'related_name': "'subscriptions'", 'through': "'QuestionSubscription'", 'to': "orm['forum.User']"}), + 'view_count': ('django.db.models.fields.IntegerField', [], {'default': '0'}), + 'wiki': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}), + 'wikified_at': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}) + }, + 'forum.questionsubscription': { + 'Meta': {'object_name': 'QuestionSubscription'}, + 'auto_subscription': ('django.db.models.fields.BooleanField', [], {'default': 'True', 'blank': 'True'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'last_view': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime(2010, 4, 16, 14, 18, 46, 625000)'}), + 'question': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['forum.Question']"}), + 'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['forum.User']"}) + }, + 'forum.repute': { + 'Meta': {'object_name': 'Repute', 'db_table': "u'repute'"}, + 'canceled': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'node': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'reputes'", 'null': 'True', 'to': "orm['forum.Node']"}), + 'question': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['forum.Question']"}), + 'reputation_type': ('django.db.models.fields.SmallIntegerField', [], {}), + 'reputed_at': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), + 'user': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'reputes'", 'to': "orm['forum.User']"}), + 'user_previous_rep': ('django.db.models.fields.IntegerField', [], {'default': '0'}), + 'value': ('django.db.models.fields.SmallIntegerField', [], {'default': '0'}) + }, + 'forum.subscriptionsettings': { + 'Meta': {'object_name': 'SubscriptionSettings'}, + 'all_questions': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}), + 'all_questions_watched_tags': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}), + 'enable_notifications': ('django.db.models.fields.BooleanField', [], {'default': 'True', 'blank': 'True'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'member_joins': ('django.db.models.fields.CharField', [], {'default': "'n'", 'max_length': '1'}), + 'new_question': ('django.db.models.fields.CharField', [], {'default': "'d'", 'max_length': '1'}), + 'new_question_watched_tags': ('django.db.models.fields.CharField', [], {'default': "'i'", 'max_length': '1'}), + 'notify_accepted': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}), + 'notify_answers': ('django.db.models.fields.BooleanField', [], {'default': 'True', 'blank': 'True'}), + 'notify_comments': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}), + 'notify_comments_own_post': ('django.db.models.fields.BooleanField', [], {'default': 'True', 'blank': 'True'}), + 'notify_reply_to_comments': ('django.db.models.fields.BooleanField', [], {'default': 'True', 'blank': 'True'}), + 'questions_answered': ('django.db.models.fields.BooleanField', [], {'default': 'True', 'blank': 'True'}), + 'questions_asked': ('django.db.models.fields.BooleanField', [], {'default': 'True', 'blank': 'True'}), + 'questions_commented': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}), + 'questions_viewed': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}), + 'subscribed_questions': ('django.db.models.fields.CharField', [], {'default': "'i'", 'max_length': '1'}), + 'user': ('django.db.models.fields.related.OneToOneField', [], {'related_name': "'subscription_settings'", 'unique': 'True', 'to': "orm['forum.User']"}) + }, + 'forum.tag': { + 'Meta': {'object_name': 'Tag', 'db_table': "u'tag'"}, + 'created_by': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'created_tags'", 'to': "orm['forum.User']"}), + 'deleted': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}), + 'deleted_at': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}), + 'deleted_by': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'deleted_tags'", 'null': 'True', 'to': "orm['forum.User']"}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'marked_by': ('django.db.models.fields.related.ManyToManyField', [], {'related_name': "'marked_tags'", 'through': "'MarkedTag'", 'to': "orm['forum.User']"}), + 'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '255'}), + 'used_count': ('django.db.models.fields.PositiveIntegerField', [], {'default': '0'}) + }, + 'forum.user': { + 'Meta': {'object_name': 'User', '_ormbases': ['auth.User']}, + 'about': ('django.db.models.fields.TextField', [], {'blank': 'True'}), + 'bronze': ('django.db.models.fields.SmallIntegerField', [], {'default': '0'}), + 'date_of_birth': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}), + 'email_isvalid': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}), + 'email_key': ('django.db.models.fields.CharField', [], {'max_length': '32', 'null': 'True'}), + 'gold': ('django.db.models.fields.SmallIntegerField', [], {'default': '0'}), + 'hide_ignored_questions': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}), + 'is_approved': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}), + 'last_seen': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), + 'location': ('django.db.models.fields.CharField', [], {'max_length': '100', 'blank': 'True'}), + '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'}), + 'silver': ('django.db.models.fields.SmallIntegerField', [], {'default': '0'}), + 'user_ptr': ('django.db.models.fields.related.OneToOneField', [], {'to': "orm['auth.User']", 'unique': 'True', 'primary_key': 'True'}), + 'website': ('django.db.models.fields.URLField', [], {'max_length': '200', 'blank': 'True'}) + }, + 'forum.validationhash': { + 'Meta': {'unique_together': "(('user', 'type'),)", 'object_name': 'ValidationHash'}, + 'expiration': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime(2010, 4, 17, 14, 18, 46, 835000)'}), + 'hash_code': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '255'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'seed': ('django.db.models.fields.CharField', [], {'max_length': '12'}), + 'type': ('django.db.models.fields.CharField', [], {'max_length': '12'}), + 'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['forum.User']"}) + }, + 'forum.vote': { + 'Meta': {'object_name': 'Vote', 'db_table': "u'vote'"}, + 'canceled': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'node': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'votes'", 'null': 'True', 'to': "orm['forum.Node']"}), + 'user': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'votes'", 'to': "orm['forum.User']"}), + 'vote': ('django.db.models.fields.SmallIntegerField', [], {}), + 'voted_at': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}) + } + } + + complete_apps = ['forum'] diff --git a/forum/migrations/0018_comments_to_node.py b/forum/migrations/0018_comments_to_node.py new file mode 100644 index 0000000..1b10aee --- /dev/null +++ b/forum/migrations/0018_comments_to_node.py @@ -0,0 +1,352 @@ +# encoding: utf-8 +import datetime +from south.db import db +from south.v2 import DataMigration +from django.db import models +from forum.migrations import ProgressBar + +class Migration(DataMigration): + + def forwards(self, orm): + c_count = orm.Comment.objects.count() + print "\nConverting %d comments:" % c_count + progress = ProgressBar(c_count) + + for c in orm.Comment.objects.all(): + node = orm.Node( + node_type='comment', + author=c.user, + added_at=c.added_at, + score=c.score, + vote_up_count=c.score, + vote_down_count=0, + offensive_flag_count=0, + last_edited_at=c.added_at, + last_edited_by=c.user, + body=c.comment, + deleted=c.deleted, + deleted_by=c.deleted_by, + deleted_at=c.deleted_at, + parent=c.node, + ) + node.save() + + revision = orm.NodeRevision( + summary="Initial revsion", + revision=1, + revised_at=c.added_at, + body=c.comment, + author=c.user, + node=node, + ) + + revision.save() + + node.active_revision = revision + node.save() + + for v in orm.LikedComment.objects.filter(comment=c): + vote = orm.Vote( + node=node, + vote=1, + voted_at=v.added_at, + canceled=v.canceled, + user=v.user, + ) + + vote.save() + + progress.update() + + print "\n...done\n" + + + 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']", 'blank': 'True'}) + }, + 'auth.permission': { + 'Meta': {'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']", 'blank': 'True'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True', 'blank': 'True'}), + 'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}), + 'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}), + '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']", 'blank': 'True'}), + 'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'}) + }, + 'contenttypes.contenttype': { + 'Meta': {'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'}) + }, + 'forum.activity': { + 'Meta': {'object_name': 'Activity', 'db_table': "u'activity'"}, + 'active_at': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), + 'activity_type': ('django.db.models.fields.SmallIntegerField', [], {}), + 'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'is_auditted': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}), + 'object_id': ('django.db.models.fields.PositiveIntegerField', [], {}), + 'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['forum.User']"}) + }, + 'forum.anonymousnode': { + 'Meta': {'object_name': 'AnonymousNode', '_ormbases': ['forum.Node']}, + 'convertible_to': ('django.db.models.fields.CharField', [], {'default': "'node'", 'max_length': '16'}), + 'node_ptr': ('django.db.models.fields.related.OneToOneField', [], {'to': "orm['forum.Node']", 'unique': 'True', 'primary_key': 'True'}), + 'validation_hash': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'anonymous_content'", 'to': "orm['forum.Node']"}) + }, + 'forum.answer': { + 'Meta': {'object_name': 'Answer', 'db_table': "u'answer'"}, + 'accepted': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}), + 'accepted_at': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}), + 'accepted_by': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['forum.User']", 'null': 'True'}), + 'node_ptr': ('django.db.models.fields.related.OneToOneField', [], {'to': "orm['forum.Node']", 'unique': 'True', 'primary_key': 'True'}), + 'wiki': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}), + 'wikified_at': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}) + }, + 'forum.authkeyuserassociation': { + 'Meta': {'object_name': 'AuthKeyUserAssociation'}, + 'added_at': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'key': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '255'}), + 'provider': ('django.db.models.fields.CharField', [], {'max_length': '64'}), + 'user': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'auth_keys'", 'to': "orm['forum.User']"}) + }, + 'forum.award': { + 'Meta': {'unique_together': "(('content_type', 'object_id', 'user', 'badge'),)", 'object_name': 'Award', 'db_table': "u'award'"}, + 'awarded_at': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), + 'badge': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'award_badge'", 'to': "orm['forum.Badge']"}), + 'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'notified': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}), + 'object_id': ('django.db.models.fields.PositiveIntegerField', [], {}), + 'user': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'awards'", 'to': "orm['forum.User']"}) + }, + 'forum.badge': { + 'Meta': {'unique_together': "(('name', 'type'),)", 'object_name': 'Badge', 'db_table': "u'badge'"}, + 'awarded_count': ('django.db.models.fields.PositiveIntegerField', [], {'default': '0'}), + 'awarded_to': ('django.db.models.fields.related.ManyToManyField', [], {'related_name': "'badges'", 'through': "'Award'", 'to': "orm['forum.User']"}), + 'description': ('django.db.models.fields.CharField', [], {'max_length': '300'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'multiple': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '50'}), + 'slug': ('django.db.models.fields.SlugField', [], {'db_index': 'True', 'max_length': '50', 'blank': 'True'}), + 'type': ('django.db.models.fields.SmallIntegerField', [], {}) + }, + 'forum.comment': { + 'Meta': {'object_name': 'Comment', 'db_table': "u'comment'"}, + 'added_at': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), + 'comment': ('django.db.models.fields.CharField', [], {'max_length': '300'}), + 'deleted': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}), + 'deleted_at': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}), + 'deleted_by': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'deleted_comments'", 'null': 'True', 'to': "orm['forum.User']"}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'liked_by': ('django.db.models.fields.related.ManyToManyField', [], {'related_name': "'comments_liked'", 'through': "'LikedComment'", 'to': "orm['forum.User']"}), + 'node': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'comments'", 'null': 'True', 'to': "orm['forum.Node']"}), + 'score': ('django.db.models.fields.IntegerField', [], {'default': '0'}), + 'user': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'comments'", 'to': "orm['forum.User']"}) + }, + 'forum.favoritequestion': { + 'Meta': {'unique_together': "(('question', 'user'),)", 'object_name': 'FavoriteQuestion', 'db_table': "u'favorite_question'"}, + 'added_at': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'question': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['forum.Question']"}), + 'user': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'user_favorite_questions'", 'to': "orm['forum.User']"}) + }, + 'forum.flaggeditem': { + 'Meta': {'object_name': 'FlaggedItem', 'db_table': "u'flagged_item'"}, + 'canceled': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}), + 'flagged_at': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'node': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'flaggeditems'", 'null': 'True', 'to': "orm['forum.Node']"}), + 'reason': ('django.db.models.fields.CharField', [], {'max_length': '300', 'null': 'True'}), + 'user': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'flaggeditems'", 'to': "orm['forum.User']"}) + }, + 'forum.keyvalue': { + 'Meta': {'object_name': 'KeyValue'}, + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'key': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '255'}), + 'value': ('forum.models.utils.PickledObjectField', [], {}) + }, + 'forum.likedcomment': { + 'Meta': {'object_name': 'LikedComment'}, + 'added_at': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), + 'canceled': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}), + 'comment': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['forum.Comment']"}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['forum.User']"}) + }, + 'forum.markedtag': { + 'Meta': {'object_name': 'MarkedTag'}, + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'reason': ('django.db.models.fields.CharField', [], {'max_length': '16'}), + 'tag': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'user_selections'", 'to': "orm['forum.Tag']"}), + 'user': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'tag_selections'", 'to': "orm['forum.User']"}) + }, + 'forum.node': { + 'Meta': {'object_name': 'Node'}, + 'active_revision': ('django.db.models.fields.related.OneToOneField', [], {'related_name': "'active'", 'unique': 'True', 'null': 'True', 'to': "orm['forum.NodeRevision']"}), + 'added_at': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), + 'author': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'nodes'", 'to': "orm['forum.User']"}), + 'body': ('django.db.models.fields.TextField', [], {}), + 'comment_count': ('django.db.models.fields.PositiveIntegerField', [], {'default': '0'}), + 'deleted': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}), + 'deleted_at': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}), + 'deleted_by': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'deleted_nodes'", 'null': 'True', 'to': "orm['forum.User']"}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'last_edited_at': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}), + 'last_edited_by': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'last_edited_nodes'", 'null': 'True', 'to': "orm['forum.User']"}), + 'node_type': ('django.db.models.fields.CharField', [], {'default': "'node'", 'max_length': '16'}), + 'offensive_flag_count': ('django.db.models.fields.SmallIntegerField', [], {'default': '0'}), + 'parent': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'children'", 'null': 'True', 'to': "orm['forum.Node']"}), + 'score': ('django.db.models.fields.IntegerField', [], {'default': '0'}), + 'tagnames': ('django.db.models.fields.CharField', [], {'max_length': '125'}), + 'tags': ('django.db.models.fields.related.ManyToManyField', [], {'related_name': "'nodes'", 'to': "orm['forum.Tag']"}), + 'title': ('django.db.models.fields.CharField', [], {'max_length': '300'}), + 'vote_down_count': ('django.db.models.fields.IntegerField', [], {'default': '0'}), + 'vote_up_count': ('django.db.models.fields.IntegerField', [], {'default': '0'}) + }, + 'forum.noderevision': { + 'Meta': {'unique_together': "(('node', 'revision'),)", 'object_name': 'NodeRevision'}, + 'author': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'noderevisions'", 'to': "orm['forum.User']"}), + 'body': ('django.db.models.fields.TextField', [], {}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'node': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'revisions'", 'to': "orm['forum.Node']"}), + 'revised_at': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), + 'revision': ('django.db.models.fields.PositiveIntegerField', [], {}), + 'summary': ('django.db.models.fields.CharField', [], {'max_length': '300'}), + 'tagnames': ('django.db.models.fields.CharField', [], {'max_length': '125'}), + 'title': ('django.db.models.fields.CharField', [], {'max_length': '300'}) + }, + 'forum.question': { + 'Meta': {'object_name': 'Question', 'db_table': "u'question'"}, + 'accepted_answer': ('django.db.models.fields.related.OneToOneField', [], {'related_name': "'question_accepting'", 'unique': 'True', 'null': 'True', 'to': "orm['forum.Answer']"}), + 'answer_count': ('django.db.models.fields.PositiveIntegerField', [], {'default': '0'}), + 'close_reason': ('django.db.models.fields.SmallIntegerField', [], {'null': 'True', 'blank': 'True'}), + 'closed': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}), + 'closed_at': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}), + 'closed_by': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'closed_questions'", 'null': 'True', 'to': "orm['forum.User']"}), + 'favorited_by': ('django.db.models.fields.related.ManyToManyField', [], {'related_name': "'favorite_questions'", 'through': "'FavoriteQuestion'", 'to': "orm['forum.User']"}), + 'favourite_count': ('django.db.models.fields.IntegerField', [], {'default': '0'}), + 'last_activity_at': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), + 'last_activity_by': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'last_active_in_questions'", 'to': "orm['forum.User']"}), + 'node_ptr': ('django.db.models.fields.related.OneToOneField', [], {'to': "orm['forum.Node']", 'unique': 'True'}), + 'subscribers': ('django.db.models.fields.related.ManyToManyField', [], {'related_name': "'subscriptions'", 'through': "'QuestionSubscription'", 'to': "orm['forum.User']"}), + 'view_count': ('django.db.models.fields.IntegerField', [], {'default': '0'}), + 'wiki': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}), + 'wikified_at': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}) + }, + 'forum.questionsubscription': { + 'Meta': {'object_name': 'QuestionSubscription'}, + 'auto_subscription': ('django.db.models.fields.BooleanField', [], {'default': 'True', 'blank': 'True'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'last_view': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime(2010, 4, 16, 14, 19, 21, 765000)'}), + 'question': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['forum.Question']"}), + 'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['forum.User']"}) + }, + 'forum.repute': { + 'Meta': {'object_name': 'Repute', 'db_table': "u'repute'"}, + 'canceled': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'node': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'reputes'", 'null': 'True', 'to': "orm['forum.Node']"}), + 'question': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['forum.Question']"}), + 'reputation_type': ('django.db.models.fields.SmallIntegerField', [], {}), + 'reputed_at': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), + 'user': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'reputes'", 'to': "orm['forum.User']"}), + 'user_previous_rep': ('django.db.models.fields.IntegerField', [], {'default': '0'}), + 'value': ('django.db.models.fields.SmallIntegerField', [], {'default': '0'}) + }, + 'forum.subscriptionsettings': { + 'Meta': {'object_name': 'SubscriptionSettings'}, + 'all_questions': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}), + 'all_questions_watched_tags': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}), + 'enable_notifications': ('django.db.models.fields.BooleanField', [], {'default': 'True', 'blank': 'True'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'member_joins': ('django.db.models.fields.CharField', [], {'default': "'n'", 'max_length': '1'}), + 'new_question': ('django.db.models.fields.CharField', [], {'default': "'d'", 'max_length': '1'}), + 'new_question_watched_tags': ('django.db.models.fields.CharField', [], {'default': "'i'", 'max_length': '1'}), + 'notify_accepted': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}), + 'notify_answers': ('django.db.models.fields.BooleanField', [], {'default': 'True', 'blank': 'True'}), + 'notify_comments': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}), + 'notify_comments_own_post': ('django.db.models.fields.BooleanField', [], {'default': 'True', 'blank': 'True'}), + 'notify_reply_to_comments': ('django.db.models.fields.BooleanField', [], {'default': 'True', 'blank': 'True'}), + 'questions_answered': ('django.db.models.fields.BooleanField', [], {'default': 'True', 'blank': 'True'}), + 'questions_asked': ('django.db.models.fields.BooleanField', [], {'default': 'True', 'blank': 'True'}), + 'questions_commented': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}), + 'questions_viewed': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}), + 'subscribed_questions': ('django.db.models.fields.CharField', [], {'default': "'i'", 'max_length': '1'}), + 'user': ('django.db.models.fields.related.OneToOneField', [], {'related_name': "'subscription_settings'", 'unique': 'True', 'to': "orm['forum.User']"}) + }, + 'forum.tag': { + 'Meta': {'object_name': 'Tag', 'db_table': "u'tag'"}, + 'created_by': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'created_tags'", 'to': "orm['forum.User']"}), + 'deleted': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}), + 'deleted_at': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}), + 'deleted_by': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'deleted_tags'", 'null': 'True', 'to': "orm['forum.User']"}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'marked_by': ('django.db.models.fields.related.ManyToManyField', [], {'related_name': "'marked_tags'", 'through': "'MarkedTag'", 'to': "orm['forum.User']"}), + 'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '255'}), + 'used_count': ('django.db.models.fields.PositiveIntegerField', [], {'default': '0'}) + }, + 'forum.user': { + 'Meta': {'object_name': 'User', '_ormbases': ['auth.User']}, + 'about': ('django.db.models.fields.TextField', [], {'blank': 'True'}), + 'bronze': ('django.db.models.fields.SmallIntegerField', [], {'default': '0'}), + 'date_of_birth': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}), + 'email_isvalid': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}), + 'email_key': ('django.db.models.fields.CharField', [], {'max_length': '32', 'null': 'True'}), + 'gold': ('django.db.models.fields.SmallIntegerField', [], {'default': '0'}), + 'hide_ignored_questions': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}), + 'is_approved': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}), + 'last_seen': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), + 'location': ('django.db.models.fields.CharField', [], {'max_length': '100', 'blank': 'True'}), + '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'}), + 'silver': ('django.db.models.fields.SmallIntegerField', [], {'default': '0'}), + 'user_ptr': ('django.db.models.fields.related.OneToOneField', [], {'to': "orm['auth.User']", 'unique': 'True', 'primary_key': 'True'}), + 'website': ('django.db.models.fields.URLField', [], {'max_length': '200', 'blank': 'True'}) + }, + 'forum.validationhash': { + 'Meta': {'unique_together': "(('user', 'type'),)", 'object_name': 'ValidationHash'}, + 'expiration': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime(2010, 4, 17, 14, 19, 21, 837000)'}), + 'hash_code': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '255'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'seed': ('django.db.models.fields.CharField', [], {'max_length': '12'}), + 'type': ('django.db.models.fields.CharField', [], {'max_length': '12'}), + 'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['forum.User']"}) + }, + 'forum.vote': { + 'Meta': {'object_name': 'Vote', 'db_table': "u'vote'"}, + 'canceled': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'node': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'votes'", 'null': 'True', 'to': "orm['forum.Node']"}), + 'user': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'votes'", 'to': "orm['forum.User']"}), + 'vote': ('django.db.models.fields.SmallIntegerField', [], {}), + 'voted_at': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}) + } + } + + complete_apps = ['forum'] diff --git a/forum/models/__init__.py b/forum/models/__init__.py index e835307..df42a5b 100644 --- a/forum/models/__init__.py +++ b/forum/models/__init__.py @@ -1,10 +1,11 @@ from question import Question ,QuestionRevision, FavoriteQuestion, QuestionSubscription from answer import Answer, AnswerRevision from tag import Tag, MarkedTag -from meta import Vote, Comment, FlaggedItem, LikedComment +from meta import Vote, FlaggedItem from user import User, Activity, ValidationHash, AuthKeyUserAssociation, SubscriptionSettings from repute import Badge, Award, Repute from node import Node, NodeRevision, NodeMetaClass, AnonymousNode +from comment import Comment from utils import KeyValue try: @@ -27,7 +28,7 @@ __all__ = [ 'Node', 'NodeRevision', 'AnonymousNode', 'Question', 'FavoriteQuestion', 'QuestionSubscription', 'QuestionRevision', 'Answer', 'AnswerRevision', - 'Tag', 'Comment', 'Vote', 'FlaggedItem', 'MarkedTag', 'LikedComment', 'Badge', 'Award', 'Repute', + 'Tag', 'Comment', 'Vote', 'FlaggedItem', 'MarkedTag', 'Badge', 'Award', 'Repute', 'Activity', 'ValidationHash', 'AuthKeyUserAssociation', 'SubscriptionSettings', 'KeyValue', 'User', ] diff --git a/forum/models/base.py b/forum/models/base.py index 13eae22..7974af6 100644 --- a/forum/models/base.py +++ b/forum/models/base.py @@ -79,6 +79,7 @@ class BaseModel(models.Model): class ActiveObjectManager(models.Manager): + use_for_related_fields = True def get_query_set(self): return super(ActiveObjectManager, self).get_query_set().filter(canceled=False) @@ -158,8 +159,25 @@ class DeletableContent(models.Model): else: return False +mark_canceled = django.dispatch.Signal(providing_args=['instance']) + +class CancelableContent(models.Model): + canceled = models.BooleanField(default=False) + + def cancel(self): + if not self.canceled: + self.canceled = True + self.save() + mark_canceled.send(sender=self.__class__, instance=self) + return True + + return False + + class Meta: + abstract = True + app_label = 'forum' + -from meta import Comment, Vote, FlaggedItem from node import Node, NodeRevision class QandA(Node): diff --git a/forum/models/comment.py b/forum/models/comment.py new file mode 100644 index 0000000..071126e --- /dev/null +++ b/forum/models/comment.py @@ -0,0 +1,50 @@ +from base import * +import re + +class Comment(Node): + class Meta(Node.Meta): + ordering = ('-added_at',) + proxy = True + + def _update_parent_comment_count(self, diff): + parent = self.parent + parent.comment_count = parent.comment_count + diff + parent.save() + + @property + def comment(self): + return self.body + + @property + def content_object(self): + return self.parent.leaf + + def save(self, *args, **kwargs): + super(Comment,self).save(*args, **kwargs) + + if self._is_new: + self._update_parent_comment_count(1) + + try: + ping_google() + except Exception: + logging.debug('problem pinging google did you register you sitemap with google?') + + def mark_deleted(self, user): + if super(Comment, self).mark_deleted(user): + self._update_parent_comment_count(-1) + + def unmark_deleted(self): + if super(Comment, self).unmark_deleted(): + self._update_parent_comment_count(1) + + def is_reply_to(self, user): + inreply = re.search('@\w+', self.comment) + if inreply is not None: + return user.username.startswith(inreply.group(0)) + + return False + + def __unicode__(self): + return self.body + diff --git a/forum/models/meta.py b/forum/models/meta.py index 7e82137..c01c018 100644 --- a/forum/models/meta.py +++ b/forum/models/meta.py @@ -1,7 +1,6 @@ from base import * -import re -class Vote(MetaContent, UserContent): +class Vote(MetaContent, CancelableContent, UserContent): VOTE_UP = +1 VOTE_DOWN = -1 VOTE_CHOICES = ( @@ -11,7 +10,6 @@ class Vote(MetaContent, UserContent): vote = models.SmallIntegerField(choices=VOTE_CHOICES) voted_at = models.DateTimeField(default=datetime.datetime.now) - canceled = models.BooleanField(default=False) active = ActiveObjectManager() @@ -27,28 +25,23 @@ class Vote(MetaContent, UserContent): post.__dict__[field] = post.__dict__[field] + diff post.save() + def cancel(self): + if super(Vote, self).cancel(): + self._update_post_vote_count(-1) + def save(self, *args, **kwargs): super(Vote, self).save(*args, **kwargs) if self._is_new: self._update_post_vote_count(1) - def cancel(self): - if not self.canceled: - self.canceled = True - self.save() - self._update_post_vote_count(-1) - vote_canceled.send(sender=Vote, instance=self) - def is_upvote(self): return self.vote == self.VOTE_UP def is_downvote(self): return self.vote == self.VOTE_DOWN -vote_canceled = django.dispatch.Signal(providing_args=['instance']) class FlaggedItem(MetaContent, UserContent): - """A flag on a Question or Answer indicating offensive content.""" flagged_at = models.DateTimeField(default=datetime.datetime.now) reason = models.CharField(max_length=300, null=True) canceled = models.BooleanField(default=False) @@ -78,75 +71,5 @@ class FlaggedItem(MetaContent, UserContent): self._update_post_flag_count(-1) -class Comment(MetaContent, UserContent, DeletableContent): - comment = models.CharField(max_length=300) - added_at = models.DateTimeField(default=datetime.datetime.now) - score = models.IntegerField(default=0) - liked_by = models.ManyToManyField(User, through='LikedComment', related_name='comments_liked') - - class Meta(MetaContent.Meta): - ordering = ('-added_at',) - db_table = u'comment' - - def _update_post_comment_count(self, diff): - post = self.node.leaf - post.comment_count = post.comment_count + diff - post.save() - - def save(self, *args, **kwargs): - super(Comment,self).save(*args, **kwargs) - - if self._is_new: - self._update_post_comment_count(1) - - try: - ping_google() - except Exception: - logging.debug('problem pinging google did you register you sitemap with google?') - - def mark_deleted(self, user): - if super(Comment, self).mark_deleted(user): - self._update_post_comment_count(-1) - - def unmark_deleted(self): - if super(Comment, self).unmark_deleted(): - self._update_post_comment_count(1) - - def is_reply_to(self, user): - inreply = re.search('@\w+', self.comment) - if inreply is not None: - return user.username.startswith(inreply.group(0)) - - return False - - def __unicode__(self): - return self.comment - - -class LikedComment(models.Model): - comment = models.ForeignKey(Comment) - user = models.ForeignKey(User) - added_at = models.DateTimeField(default=datetime.datetime.now) - canceled = models.BooleanField(default=False) - - active = ActiveObjectManager() - - class Meta: - app_label = 'forum' - - def _update_comment_score(self, diff): - self.comment.score = self.comment.score + diff - self.comment.save() - - def save(self, *args, **kwargs): - super(LikedComment, self).save(*args, **kwargs) - if self._is_new: - self._update_comment_score(1) - - def cancel(self): - if not self.canceled: - self.canceled = True - self.save() - self._update_comment_score(-1) diff --git a/forum/models/node.py b/forum/models/node.py index 932452d..530981b 100644 --- a/forum/models/node.py +++ b/forum/models/node.py @@ -12,6 +12,10 @@ class NodeContent(models.Model): author = models.ForeignKey(User, related_name='%(class)ss') body = models.TextField() + @property + def user(self): + return self.author + @property def html(self): return mark_safe(sanitize_html(markdown.markdown(self.body))) @@ -20,10 +24,6 @@ class NodeContent(models.Model): def headline(self): return self.title - @property - def summary(self): - return strip_tags(self.html)[:300] - def tagname_list(self): if self.tagnames: return [name for name in self.tagnames.split(u' ')] @@ -58,17 +58,17 @@ class NodeMetaClass(models.Model.__metaclass__): name = node_cls.__name__.lower() def children(self): - return node_cls.objects.filter(parent=self) + if node_cls._meta.proxy: + return node_cls.objects.filter(node_type=name, parent=self) + else: + return node_cls.objects.filter(parent=self) def parent(self): p = self.__dict__.get('_%s_cache' % name, None) - if p is None: - try: - p = self.parent.leaf - self.__dict__['_%s_cache' % name] = p - except Exception, e: - pass + if p is None and (self.parent is not None) and self.parent.node_type == name: + p = self.parent.leaf + self.__dict__['_%s_cache' % name] = p return p @@ -76,6 +76,8 @@ class NodeMetaClass(models.Model.__metaclass__): Node.add_to_class(name, property(parent)) +node_create = django.dispatch.Signal(providing_args=['instance']) + class Node(BaseModel, NodeContent, DeletableContent): __metaclass__ = NodeMetaClass @@ -90,7 +92,7 @@ class Node(BaseModel, NodeContent, DeletableContent): vote_up_count = models.IntegerField(default=0) vote_down_count = models.IntegerField(default=0) - comment_count = models.PositiveIntegerField(default=0) + comment_count = models.PositiveIntegerField(default=0) offensive_flag_count = models.SmallIntegerField(default=0) last_edited_at = models.DateTimeField(null=True, blank=True) @@ -102,6 +104,10 @@ class Node(BaseModel, NodeContent, DeletableContent): def leaf(self): return NodeMetaClass.types[self.node_type].objects.get(id=self.id) + @property + def summary(self): + return strip_tags(self.html)[:300] + def create_revision(self, user, **kwargs): revision = NodeRevision(author=user, **kwargs) @@ -120,13 +126,17 @@ class Node(BaseModel, NodeContent, DeletableContent): self.title = revision.title self.tagnames = revision.tagnames self.body = revision.body - - self.last_edited_at = datetime.datetime.now() - self.last_edited_by = user + + old_revision = self.active_revision self.active_revision = revision self.save() + if not old_revision: + self.last_edited_at = datetime.datetime.now() + self.last_edited_by = user + node_create.send(sender=self.__class__, instance=self) + def get_tag_list_if_changed(self): dirty = self.get_dirty_fields() diff --git a/forum/models/question.py b/forum/models/question.py index 485576d..da8083f 100644 --- a/forum/models/question.py +++ b/forum/models/question.py @@ -17,7 +17,7 @@ class Question(QandA): view_count = models.IntegerField(default=0) favourite_count = models.IntegerField(default=0) last_activity_at = models.DateTimeField(default=datetime.datetime.now) - last_activity_by = models.ForeignKey(User, related_name='last_active_in_questions') + last_activity_by = models.ForeignKey(User, related_name='last_active_in_questions', null=True) favorited_by = models.ManyToManyField(User, through='FavoriteQuestion', related_name='favorite_questions') @@ -38,12 +38,10 @@ class Question(QandA): def answer_accepted(self): return self.accepted_answer is not None - def delete(self): - super(Question, self).delete() - try: - ping_google() - except Exception: - logging.debug('problem pinging google did you register you sitemap with google?') + def save(self, *args, **kwargs): + if not self.last_activity_by: + self.last_activity_by = self.author + super(Question, self).save(*args, **kwargs) def update_last_activity(self, user): self.last_activity_by = user @@ -78,9 +76,6 @@ class Question(QandA): def get_revision_url(self): return reverse('question_revisions', args=[self.id]) - def get_latest_revision(self): - return self.revisions.all()[0] - def get_related_questions(self, count=10): cache_key = '%s.related_questions:%d:%d' % (settings.APP_URL, count, self.id) related_list = cache.get(cache_key) diff --git a/forum/models/repute.py b/forum/models/repute.py index 4094351..6457de2 100644 --- a/forum/models/repute.py +++ b/forum/models/repute.py @@ -87,8 +87,7 @@ class Award(GenericContent, UserContent): db_table = u'award' -class Repute(UserContent): - """The reputation histories for user""" +class Repute(MetaContent, CancelableContent, UserContent): value = models.SmallIntegerField(default=0) question = models.ForeignKey('Question') reputed_at = models.DateTimeField(default=datetime.datetime.now) @@ -112,6 +111,11 @@ class Repute(UserContent): def reputation(self): return self.user_previous_rep + self.value + def cancel(self): + if super(Repute, self).cancel(): + self.user.reputation = self.user.reputation - self.value + self.user.save() + def save(self, *args, **kwargs): self.user_previous_rep = self.user.reputation self.user.reputation = self.user.reputation + self.value diff --git a/forum/models/user.py b/forum/models/user.py index 5366631..ab59414 100644 --- a/forum/models/user.py +++ b/forum/models/user.py @@ -240,12 +240,14 @@ class Activity(GenericContent): @property def node(self): if self.activity_type in (const.TYPE_ACTIVITY_ANSWER, const.TYPE_ACTIVITY_ASK_QUESTION, - const.TYPE_ACTIVITY_MARK_ANSWER, const.TYPE_ACTIVITY_UPDATE_QUESTION): + const.TYPE_ACTIVITY_MARK_ANSWER): return self.content_object - if self.activity_type in (const.TYPE_ACTIVITY_COMMENT_QUESTION, - const.TYPE_ACTIVITY_COMMENT_ANSWER, const.TYPE_ACTIVITY_UPDATE_ANSWER): - return self.content_object.node.leaf + if self.activity_type in (const.TYPE_ACTIVITY_COMMENT_QUESTION, const.TYPE_ACTIVITY_COMMENT_ANSWER): + return self.content_object.parent.leaf + + if self.activity_type in (const.TYPE_ACTIVITY_UPDATE_ANSWER, const.TYPE_ACTIVITY_UPDATE_QUESTION): + return self.content_object.node.leaf raise NotImplementedError() diff --git a/forum/reputation.py b/forum/reputation.py index 4a0fe7e..8ee3469 100644 --- a/forum/reputation.py +++ b/forum/reputation.py @@ -1,5 +1,5 @@ from django.db.models.signals import post_save -from forum.models.meta import vote_canceled +from forum.models.base import mark_canceled from forum.models.answer import answer_accepted, answer_accepted_canceled from forum.models import * @@ -93,7 +93,7 @@ def on_vote_canceled(instance, **kwargs): post.author.reputes.create(value=repute_value, question=question, reputation_type=repute_type) -vote_canceled.connect(on_vote_canceled) +mark_canceled.connect(on_vote_canceled, sender=Vote) diff --git a/forum/skins/default/templates/node/comments.html b/forum/skins/default/templates/node/comments.html index 022f19c..e91db87 100644 --- a/forum/skins/default/templates/node/comments.html +++ b/forum/skins/default/templates/node/comments.html @@ -9,7 +9,7 @@ {% if comment.score %}{{ comment.score }}{% endif %} - {{ comment.comment }} + {{ comment.body }} diff --git a/forum/skins/default/templates/users/stats.html b/forum/skins/default/templates/users/stats.html index 96a1f36..6381b59 100644 --- a/forum/skins/default/templates/users/stats.html +++ b/forum/skins/default/templates/users/stats.html @@ -45,17 +45,8 @@ {% endfor %} diff --git a/forum/subscriptions.py b/forum/subscriptions.py index 4c57256..4966ec6 100644 --- a/forum/subscriptions.py +++ b/forum/subscriptions.py @@ -3,6 +3,7 @@ import re import datetime from forum.models import User, Question, Comment, QuestionSubscription, SubscriptionSettings, Answer from forum.models.user import activity_record +from forum.models.node import node_create from forum.utils.mail import send_email from forum.views.readers import question_view from django.utils.translation import ugettext as _ @@ -25,9 +26,7 @@ def apply_default_filters(queryset, excluded_id): def create_recipients_dict(usr_list): return [(s['username'], s['email'], {'username': s['username']}) for s in usr_list] -def question_posted(instance, created, **kwargs): - if not created: return - +def question_posted(instance, **kwargs): question = instance subscribers = User.objects.values('email', 'username').filter( @@ -57,12 +56,10 @@ def question_posted(instance, created, **kwargs): for user in new_subscribers: create_subscription_if_not_exists(question, user) -#post_save.connect(question_posted, sender=Question) - +node_create.connect(question_posted, sender=Question) -def answer_posted(instance, created, **kwargs): - if not created: return +def answer_posted(instance, **kwargs): answer = instance question = answer.question @@ -82,11 +79,11 @@ def answer_posted(instance, created, **kwargs): if answer.author.subscription_settings.questions_answered: create_subscription_if_not_exists(question, answer.author) -post_save.connect(answer_posted, sender=Answer) +node_create.connect(answer_posted, sender=Answer) -def comment_posted(sender, instance, **kwargs): - comment = instance.content_object +def comment_posted(instance, **kwargs): + comment = instance post = comment.content_object if post.__class__ == Question: @@ -107,7 +104,7 @@ def comment_posted(sender, instance, **kwargs): ) subscribers = subscribers.filter( - q_filter, subscription_settings__subscribed_questions='i', subscription_settings__enable_notifications=True + q_filter, subscription_settings__subscribed_questions='i', subscription_settings__enable_notifications=True ).exclude(id=comment.user.id).distinct() recipients = create_recipients_dict(subscribers) @@ -122,8 +119,7 @@ def comment_posted(sender, instance, **kwargs): if comment.user.subscription_settings.questions_commented: create_subscription_if_not_exists(question, comment.user) -activity_record.connect(comment_posted, sender=const.TYPE_ACTIVITY_COMMENT_QUESTION, weak=False) -activity_record.connect(comment_posted, sender=const.TYPE_ACTIVITY_COMMENT_ANSWER, weak=False) +node_create.connect(comment_posted, sender=Comment) def answer_accepted(instance, created, **kwargs): diff --git a/forum/templatetags/node_tags.py b/forum/templatetags/node_tags.py index 4b48f2e..8a6b069 100644 --- a/forum/templatetags/node_tags.py +++ b/forum/templatetags/node_tags.py @@ -1,6 +1,6 @@ from datetime import datetime, timedelta -from forum.models import Question, FavoriteQuestion, LikedComment +from forum.models import Question, FavoriteQuestion from django.utils.translation import ugettext as _ from django.core.urlresolvers import reverse from django import template @@ -107,7 +107,7 @@ def comments(post, user): if context['can_like']: try: - LikedComment.active.get(comment=c, user=user) + c.votes.get(user=user) context['likes'] = True except: context['likes'] = False diff --git a/forum/views/commands.py b/forum/views/commands.py index 89f3fb8..e2942bd 100644 --- a/forum/views/commands.py +++ b/forum/views/commands.py @@ -232,17 +232,16 @@ def comment(request, id): if not user.can_comment(post): raise NotEnoughRepPointsException( _('comment')) - comment = Comment(user=user, node=post) + comment = Comment(parent=post) comment_text = request.POST.get('comment', '').strip() if not len(comment_text): raise Exception(_("Comment is empty")) - comment.comment=comment_text - comment.save() + comment.create_revision(user, body=comment_text) - if comment._is_new: + if comment.active_revision.revision == 1: return { 'commands': { 'insert_comment': [ -- 2.39.5