From ae662a630a91363f54173a9713de0db900831795 Mon Sep 17 00:00:00 2001 From: Evgeny Fadeev Date: Sun, 8 Jul 2012 04:30:58 -0400 Subject: changed to using just Tag for suggested and approved tags --- .../migrations/0130_auto__add_field_tag_status.py | 335 +++++++++++++++++++ askbot/migrations/0130_auto__add_suggestedtag.py | 357 --------------------- askbot/models/__init__.py | 57 +--- askbot/models/question.py | 30 +- askbot/models/tag.py | 189 +++++++---- askbot/skins/default/templates/moderate_tags.html | 2 +- askbot/views/commands.py | 3 +- askbot/views/meta.py | 7 +- 8 files changed, 491 insertions(+), 489 deletions(-) create mode 100644 askbot/migrations/0130_auto__add_field_tag_status.py delete mode 100644 askbot/migrations/0130_auto__add_suggestedtag.py diff --git a/askbot/migrations/0130_auto__add_field_tag_status.py b/askbot/migrations/0130_auto__add_field_tag_status.py new file mode 100644 index 00000000..f5557546 --- /dev/null +++ b/askbot/migrations/0130_auto__add_field_tag_status.py @@ -0,0 +1,335 @@ +# -*- 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 field 'Tag.status' + db.add_column(u'tag', 'status', + self.gf('django.db.models.fields.SmallIntegerField')(default=1), + keep_default=False) + + # Adding M2M table for field suggested_by on 'Tag' + db.create_table(u'tag_suggested_by', ( + ('id', models.AutoField(verbose_name='ID', primary_key=True, auto_created=True)), + ('tag', models.ForeignKey(orm['askbot.tag'], null=False)), + ('user', models.ForeignKey(orm['auth.user'], null=False)) + )) + db.create_unique(u'tag_suggested_by', ['tag_id', 'user_id']) + + def backwards(self, orm): + # Deleting field 'Tag.status' + db.delete_column(u'tag', 'status') + + # Removing M2M table for field suggested_by on 'Tag' + db.delete_table('tag_suggested_by') + + models = { + 'askbot.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'}), + 'object_id': ('django.db.models.fields.PositiveIntegerField', [], {}), + 'question': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['askbot.Post']", 'null': 'True'}), + 'receiving_users': ('django.db.models.fields.related.ManyToManyField', [], {'related_name': "'received_activity'", 'symmetrical': 'False', 'to': "orm['auth.User']"}), + 'recipients': ('django.db.models.fields.related.ManyToManyField', [], {'related_name': "'incoming_activity'", 'symmetrical': 'False', 'through': "orm['askbot.ActivityAuditStatus']", 'to': "orm['auth.User']"}), + 'summary': ('django.db.models.fields.TextField', [], {'default': "''"}), + 'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']"}) + }, + 'askbot.activityauditstatus': { + 'Meta': {'unique_together': "(('user', 'activity'),)", 'object_name': 'ActivityAuditStatus'}, + 'activity': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['askbot.Activity']"}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'status': ('django.db.models.fields.SmallIntegerField', [], {'default': '0'}), + 'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']"}) + }, + 'askbot.anonymousanswer': { + 'Meta': {'object_name': 'AnonymousAnswer'}, + 'added_at': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), + 'author': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']", 'null': 'True'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'ip_addr': ('django.db.models.fields.IPAddressField', [], {'max_length': '15'}), + 'question': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'anonymous_answers'", 'to': "orm['askbot.Post']"}), + 'session_key': ('django.db.models.fields.CharField', [], {'max_length': '40'}), + 'summary': ('django.db.models.fields.CharField', [], {'max_length': '180'}), + 'text': ('django.db.models.fields.TextField', [], {}), + 'wiki': ('django.db.models.fields.BooleanField', [], {'default': 'False'}) + }, + 'askbot.anonymousquestion': { + 'Meta': {'object_name': 'AnonymousQuestion'}, + 'added_at': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), + 'author': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']", 'null': 'True'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'ip_addr': ('django.db.models.fields.IPAddressField', [], {'max_length': '15'}), + 'is_anonymous': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'session_key': ('django.db.models.fields.CharField', [], {'max_length': '40'}), + 'summary': ('django.db.models.fields.CharField', [], {'max_length': '180'}), + 'tagnames': ('django.db.models.fields.CharField', [], {'max_length': '125'}), + 'text': ('django.db.models.fields.TextField', [], {}), + 'title': ('django.db.models.fields.CharField', [], {'max_length': '300'}), + 'wiki': ('django.db.models.fields.BooleanField', [], {'default': 'False'}) + }, + 'askbot.award': { + 'Meta': {'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['askbot.BadgeData']"}), + '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'}), + 'object_id': ('django.db.models.fields.PositiveIntegerField', [], {}), + 'user': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'award_user'", 'to': "orm['auth.User']"}) + }, + 'askbot.badgedata': { + 'Meta': {'ordering': "('slug',)", 'object_name': 'BadgeData'}, + 'awarded_count': ('django.db.models.fields.PositiveIntegerField', [], {'default': '0'}), + 'awarded_to': ('django.db.models.fields.related.ManyToManyField', [], {'related_name': "'badges'", 'symmetrical': 'False', 'through': "orm['askbot.Award']", 'to': "orm['auth.User']"}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'slug': ('django.db.models.fields.SlugField', [], {'unique': 'True', 'max_length': '50'}) + }, + 'askbot.emailfeedsetting': { + 'Meta': {'unique_together': "(('subscriber', 'feed_type'),)", 'object_name': 'EmailFeedSetting'}, + 'added_at': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}), + 'feed_type': ('django.db.models.fields.CharField', [], {'max_length': '16'}), + 'frequency': ('django.db.models.fields.CharField', [], {'default': "'n'", 'max_length': '8'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'reported_at': ('django.db.models.fields.DateTimeField', [], {'null': 'True'}), + 'subscriber': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'notification_subscriptions'", 'to': "orm['auth.User']"}) + }, + 'askbot.favoritequestion': { + 'Meta': {'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'}), + 'thread': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['askbot.Thread']"}), + 'user': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'user_favorite_questions'", 'to': "orm['auth.User']"}) + }, + 'askbot.groupmembership': { + 'Meta': {'unique_together': "(('group', 'user'),)", 'object_name': 'GroupMembership'}, + 'group': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'user_memberships'", 'to': "orm['askbot.Tag']"}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'user': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'group_memberships'", 'to': "orm['auth.User']"}) + }, + 'askbot.groupprofile': { + 'Meta': {'object_name': 'GroupProfile'}, + 'group_tag': ('django.db.models.fields.related.OneToOneField', [], {'related_name': "'group_profile'", 'unique': 'True', 'to': "orm['askbot.Tag']"}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'is_open': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'logo_url': ('django.db.models.fields.URLField', [], {'max_length': '200', 'null': 'True'}), + 'moderate_email': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), + 'preapproved_email_domains': ('django.db.models.fields.TextField', [], {'default': "''", 'null': 'True', 'blank': 'True'}), + 'preapproved_emails': ('django.db.models.fields.TextField', [], {'default': "''", 'null': 'True', 'blank': 'True'}) + }, + 'askbot.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['askbot.Tag']"}), + 'user': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'tag_selections'", 'to': "orm['auth.User']"}) + }, + 'askbot.post': { + 'Meta': {'object_name': 'Post'}, + 'added_at': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), + 'approved': ('django.db.models.fields.BooleanField', [], {'default': 'True', 'db_index': 'True'}), + 'author': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'posts'", 'to': "orm['auth.User']"}), + 'comment_count': ('django.db.models.fields.PositiveIntegerField', [], {'default': '0'}), + 'deleted': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'db_index': '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_posts'", 'null': 'True', 'to': "orm['auth.User']"}), + 'groups': ('django.db.models.fields.related.ManyToManyField', [], {'related_name': "'group_posts'", 'symmetrical': 'False', 'to': "orm['askbot.Tag']"}), + 'html': ('django.db.models.fields.TextField', [], {'null': 'True'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'is_anonymous': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + '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_posts'", 'null': 'True', 'to': "orm['auth.User']"}), + 'locked': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'locked_at': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}), + 'locked_by': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'locked_posts'", 'null': 'True', 'to': "orm['auth.User']"}), + 'offensive_flag_count': ('django.db.models.fields.SmallIntegerField', [], {'default': '0'}), + 'old_answer_id': ('django.db.models.fields.PositiveIntegerField', [], {'default': 'None', 'unique': 'True', 'null': 'True', 'blank': 'True'}), + 'old_comment_id': ('django.db.models.fields.PositiveIntegerField', [], {'default': 'None', 'unique': 'True', 'null': 'True', 'blank': 'True'}), + 'old_question_id': ('django.db.models.fields.PositiveIntegerField', [], {'default': 'None', 'unique': 'True', 'null': 'True', 'blank': 'True'}), + 'parent': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'comments'", 'null': 'True', 'to': "orm['askbot.Post']"}), + 'post_type': ('django.db.models.fields.CharField', [], {'max_length': '255', 'db_index': 'True'}), + 'score': ('django.db.models.fields.IntegerField', [], {'default': '0'}), + 'summary': ('django.db.models.fields.CharField', [], {'max_length': '180'}), + 'text': ('django.db.models.fields.TextField', [], {'null': 'True'}), + 'thread': ('django.db.models.fields.related.ForeignKey', [], {'default': 'None', 'related_name': "'posts'", 'null': 'True', 'blank': 'True', 'to': "orm['askbot.Thread']"}), + 'vote_down_count': ('django.db.models.fields.IntegerField', [], {'default': '0'}), + 'vote_up_count': ('django.db.models.fields.IntegerField', [], {'default': '0'}), + 'wiki': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'wikified_at': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}) + }, + 'askbot.postflagreason': { + 'Meta': {'object_name': 'PostFlagReason'}, + 'added_at': ('django.db.models.fields.DateTimeField', [], {}), + 'author': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']"}), + 'details': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'post_reject_reasons'", 'to': "orm['askbot.Post']"}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'title': ('django.db.models.fields.CharField', [], {'max_length': '128'}) + }, + 'askbot.postrevision': { + 'Meta': {'ordering': "('-revision',)", 'unique_together': "(('post', 'revision'),)", 'object_name': 'PostRevision'}, + 'approved': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'db_index': 'True'}), + 'approved_at': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}), + 'approved_by': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']", 'null': 'True', 'blank': 'True'}), + 'author': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'postrevisions'", 'to': "orm['auth.User']"}), + 'by_email': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'email_address': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'null': 'True', 'blank': 'True'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'is_anonymous': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'post': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'revisions'", 'null': 'True', 'to': "orm['askbot.Post']"}), + 'revised_at': ('django.db.models.fields.DateTimeField', [], {}), + 'revision': ('django.db.models.fields.PositiveIntegerField', [], {}), + 'summary': ('django.db.models.fields.CharField', [], {'max_length': '300', 'blank': 'True'}), + 'tagnames': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '125', 'blank': 'True'}), + 'text': ('django.db.models.fields.TextField', [], {}), + 'title': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '300', 'blank': 'True'}) + }, + 'askbot.questionview': { + 'Meta': {'object_name': 'QuestionView'}, + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'question': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'viewed'", 'to': "orm['askbot.Post']"}), + 'when': ('django.db.models.fields.DateTimeField', [], {}), + 'who': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'question_views'", 'to': "orm['auth.User']"}) + }, + 'askbot.replyaddress': { + 'Meta': {'object_name': 'ReplyAddress'}, + 'address': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '25'}), + 'allowed_from_email': ('django.db.models.fields.EmailField', [], {'max_length': '150'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'post': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'reply_addresses'", 'null': 'True', 'to': "orm['askbot.Post']"}), + 'reply_action': ('django.db.models.fields.CharField', [], {'default': "'auto_answer_or_comment'", 'max_length': '32'}), + 'response_post': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'edit_addresses'", 'null': 'True', 'to': "orm['askbot.Post']"}), + 'used_at': ('django.db.models.fields.DateTimeField', [], {'default': 'None', 'null': 'True'}), + 'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']"}) + }, + 'askbot.repute': { + 'Meta': {'object_name': 'Repute', 'db_table': "u'repute'"}, + 'comment': ('django.db.models.fields.CharField', [], {'max_length': '128', 'null': 'True'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'negative': ('django.db.models.fields.SmallIntegerField', [], {'default': '0'}), + 'positive': ('django.db.models.fields.SmallIntegerField', [], {'default': '0'}), + 'question': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['askbot.Post']", 'null': 'True', 'blank': 'True'}), + 'reputation': ('django.db.models.fields.IntegerField', [], {'default': '1'}), + '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', [], {'to': "orm['auth.User']"}) + }, + 'askbot.tag': { + 'Meta': {'ordering': "('-used_count', 'name')", 'object_name': 'Tag', 'db_table': "u'tag'"}, + 'created_by': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'created_tags'", 'to': "orm['auth.User']"}), + 'deleted': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + '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['auth.User']"}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '255'}), + 'status': ('django.db.models.fields.SmallIntegerField', [], {'default': '1'}), + 'suggested_by': ('django.db.models.fields.related.ManyToManyField', [], {'related_name': "'suggested_tags'", 'symmetrical': 'False', 'to': "orm['auth.User']"}), + 'tag_wiki': ('django.db.models.fields.related.OneToOneField', [], {'related_name': "'described_tag'", 'unique': 'True', 'null': 'True', 'to': "orm['askbot.Post']"}), + 'used_count': ('django.db.models.fields.PositiveIntegerField', [], {'default': '0'}) + }, + 'askbot.thread': { + 'Meta': {'object_name': 'Thread'}, + 'accepted_answer': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'+'", 'null': 'True', 'to': "orm['askbot.Post']"}), + 'added_at': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), + 'answer_accepted_at': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}), + 'answer_count': ('django.db.models.fields.PositiveIntegerField', [], {'default': '0'}), + 'approved': ('django.db.models.fields.BooleanField', [], {'default': 'True', 'db_index': 'True'}), + 'close_reason': ('django.db.models.fields.SmallIntegerField', [], {'null': 'True', 'blank': 'True'}), + 'closed': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'closed_at': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}), + 'closed_by': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']", 'null': 'True', 'blank': 'True'}), + 'favorited_by': ('django.db.models.fields.related.ManyToManyField', [], {'related_name': "'unused_favorite_threads'", 'symmetrical': 'False', 'through': "orm['askbot.FavoriteQuestion']", 'to': "orm['auth.User']"}), + 'favourite_count': ('django.db.models.fields.PositiveIntegerField', [], {'default': '0'}), + 'followed_by': ('django.db.models.fields.related.ManyToManyField', [], {'related_name': "'followed_threads'", 'symmetrical': 'False', 'to': "orm['auth.User']"}), + 'groups': ('django.db.models.fields.related.ManyToManyField', [], {'related_name': "'group_threads'", 'symmetrical': 'False', 'to': "orm['askbot.Tag']"}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'last_activity_at': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), + 'last_activity_by': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'unused_last_active_in_threads'", 'to': "orm['auth.User']"}), + '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': "'threads'", 'symmetrical': 'False', 'to': "orm['askbot.Tag']"}), + 'title': ('django.db.models.fields.CharField', [], {'max_length': '300'}), + 'view_count': ('django.db.models.fields.PositiveIntegerField', [], {'default': '0'}) + }, + 'askbot.vote': { + 'Meta': {'unique_together': "(('user', 'voted_post'),)", 'object_name': 'Vote', 'db_table': "u'vote'"}, + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'user': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'votes'", 'to': "orm['auth.User']"}), + 'vote': ('django.db.models.fields.SmallIntegerField', [], {}), + 'voted_at': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), + 'voted_post': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'votes'", 'to': "orm['askbot.Post']"}) + }, + '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_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': '30'}), + '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'}) + } + } + + complete_apps = ['askbot'] diff --git a/askbot/migrations/0130_auto__add_suggestedtag.py b/askbot/migrations/0130_auto__add_suggestedtag.py deleted file mode 100644 index d769c76d..00000000 --- a/askbot/migrations/0130_auto__add_suggestedtag.py +++ /dev/null @@ -1,357 +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 'SuggestedTag' - db.create_table('askbot_suggestedtag', ( - ('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)), - ('name', self.gf('django.db.models.fields.CharField')(unique=True, max_length=255)), - ('used_count', self.gf('django.db.models.fields.PositiveIntegerField')(default=1)), - ('thread_ids', self.gf('django.db.models.fields.TextField')()), - )) - db.send_create_signal('askbot', ['SuggestedTag']) - - # Adding M2M table for field threads on 'SuggestedTag' - db.create_table('askbot_suggestedtag_threads', ( - ('id', models.AutoField(verbose_name='ID', primary_key=True, auto_created=True)), - ('suggestedtag', models.ForeignKey(orm['askbot.suggestedtag'], null=False)), - ('thread', models.ForeignKey(orm['askbot.thread'], null=False)) - )) - db.create_unique('askbot_suggestedtag_threads', ['suggestedtag_id', 'thread_id']) - - # Adding M2M table for field users on 'SuggestedTag' - db.create_table('askbot_suggestedtag_users', ( - ('id', models.AutoField(verbose_name='ID', primary_key=True, auto_created=True)), - ('suggestedtag', models.ForeignKey(orm['askbot.suggestedtag'], null=False)), - ('user', models.ForeignKey(orm['auth.user'], null=False)) - )) - db.create_unique('askbot_suggestedtag_users', ['suggestedtag_id', 'user_id']) - - def backwards(self, orm): - # Deleting model 'SuggestedTag' - db.delete_table('askbot_suggestedtag') - - # Removing M2M table for field threads on 'SuggestedTag' - db.delete_table('askbot_suggestedtag_threads') - - # Removing M2M table for field users on 'SuggestedTag' - db.delete_table('askbot_suggestedtag_users') - - models = { - 'askbot.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'}), - 'object_id': ('django.db.models.fields.PositiveIntegerField', [], {}), - 'question': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['askbot.Post']", 'null': 'True'}), - 'receiving_users': ('django.db.models.fields.related.ManyToManyField', [], {'related_name': "'received_activity'", 'symmetrical': 'False', 'to': "orm['auth.User']"}), - 'recipients': ('django.db.models.fields.related.ManyToManyField', [], {'related_name': "'incoming_activity'", 'symmetrical': 'False', 'through': "orm['askbot.ActivityAuditStatus']", 'to': "orm['auth.User']"}), - 'summary': ('django.db.models.fields.TextField', [], {'default': "''"}), - 'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']"}) - }, - 'askbot.activityauditstatus': { - 'Meta': {'unique_together': "(('user', 'activity'),)", 'object_name': 'ActivityAuditStatus'}, - 'activity': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['askbot.Activity']"}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'status': ('django.db.models.fields.SmallIntegerField', [], {'default': '0'}), - 'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']"}) - }, - 'askbot.anonymousanswer': { - 'Meta': {'object_name': 'AnonymousAnswer'}, - 'added_at': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), - 'author': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']", 'null': 'True'}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'ip_addr': ('django.db.models.fields.IPAddressField', [], {'max_length': '15'}), - 'question': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'anonymous_answers'", 'to': "orm['askbot.Post']"}), - 'session_key': ('django.db.models.fields.CharField', [], {'max_length': '40'}), - 'summary': ('django.db.models.fields.CharField', [], {'max_length': '180'}), - 'text': ('django.db.models.fields.TextField', [], {}), - 'wiki': ('django.db.models.fields.BooleanField', [], {'default': 'False'}) - }, - 'askbot.anonymousquestion': { - 'Meta': {'object_name': 'AnonymousQuestion'}, - 'added_at': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), - 'author': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']", 'null': 'True'}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'ip_addr': ('django.db.models.fields.IPAddressField', [], {'max_length': '15'}), - 'is_anonymous': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), - 'session_key': ('django.db.models.fields.CharField', [], {'max_length': '40'}), - 'summary': ('django.db.models.fields.CharField', [], {'max_length': '180'}), - 'tagnames': ('django.db.models.fields.CharField', [], {'max_length': '125'}), - 'text': ('django.db.models.fields.TextField', [], {}), - 'title': ('django.db.models.fields.CharField', [], {'max_length': '300'}), - 'wiki': ('django.db.models.fields.BooleanField', [], {'default': 'False'}) - }, - 'askbot.award': { - 'Meta': {'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['askbot.BadgeData']"}), - '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'}), - 'object_id': ('django.db.models.fields.PositiveIntegerField', [], {}), - 'user': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'award_user'", 'to': "orm['auth.User']"}) - }, - 'askbot.badgedata': { - 'Meta': {'ordering': "('slug',)", 'object_name': 'BadgeData'}, - 'awarded_count': ('django.db.models.fields.PositiveIntegerField', [], {'default': '0'}), - 'awarded_to': ('django.db.models.fields.related.ManyToManyField', [], {'related_name': "'badges'", 'symmetrical': 'False', 'through': "orm['askbot.Award']", 'to': "orm['auth.User']"}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'slug': ('django.db.models.fields.SlugField', [], {'unique': 'True', 'max_length': '50'}) - }, - 'askbot.emailfeedsetting': { - 'Meta': {'unique_together': "(('subscriber', 'feed_type'),)", 'object_name': 'EmailFeedSetting'}, - 'added_at': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}), - 'feed_type': ('django.db.models.fields.CharField', [], {'max_length': '16'}), - 'frequency': ('django.db.models.fields.CharField', [], {'default': "'n'", 'max_length': '8'}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'reported_at': ('django.db.models.fields.DateTimeField', [], {'null': 'True'}), - 'subscriber': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'notification_subscriptions'", 'to': "orm['auth.User']"}) - }, - 'askbot.favoritequestion': { - 'Meta': {'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'}), - 'thread': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['askbot.Thread']"}), - 'user': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'user_favorite_questions'", 'to': "orm['auth.User']"}) - }, - 'askbot.groupmembership': { - 'Meta': {'unique_together': "(('group', 'user'),)", 'object_name': 'GroupMembership'}, - 'group': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'user_memberships'", 'to': "orm['askbot.Tag']"}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'user': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'group_memberships'", 'to': "orm['auth.User']"}) - }, - 'askbot.groupprofile': { - 'Meta': {'object_name': 'GroupProfile'}, - 'group_tag': ('django.db.models.fields.related.OneToOneField', [], {'related_name': "'group_profile'", 'unique': 'True', 'to': "orm['askbot.Tag']"}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'is_open': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), - 'logo_url': ('django.db.models.fields.URLField', [], {'max_length': '200', 'null': 'True'}), - 'moderate_email': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), - 'preapproved_email_domains': ('django.db.models.fields.TextField', [], {'default': "''", 'null': 'True', 'blank': 'True'}), - 'preapproved_emails': ('django.db.models.fields.TextField', [], {'default': "''", 'null': 'True', 'blank': 'True'}) - }, - 'askbot.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['askbot.Tag']"}), - 'user': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'tag_selections'", 'to': "orm['auth.User']"}) - }, - 'askbot.post': { - 'Meta': {'object_name': 'Post'}, - 'added_at': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), - 'approved': ('django.db.models.fields.BooleanField', [], {'default': 'True', 'db_index': 'True'}), - 'author': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'posts'", 'to': "orm['auth.User']"}), - 'comment_count': ('django.db.models.fields.PositiveIntegerField', [], {'default': '0'}), - 'deleted': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'db_index': '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_posts'", 'null': 'True', 'to': "orm['auth.User']"}), - 'groups': ('django.db.models.fields.related.ManyToManyField', [], {'related_name': "'group_posts'", 'symmetrical': 'False', 'to': "orm['askbot.Tag']"}), - 'html': ('django.db.models.fields.TextField', [], {'null': 'True'}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'is_anonymous': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), - '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_posts'", 'null': 'True', 'to': "orm['auth.User']"}), - 'locked': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), - 'locked_at': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}), - 'locked_by': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'locked_posts'", 'null': 'True', 'to': "orm['auth.User']"}), - 'offensive_flag_count': ('django.db.models.fields.SmallIntegerField', [], {'default': '0'}), - 'old_answer_id': ('django.db.models.fields.PositiveIntegerField', [], {'default': 'None', 'unique': 'True', 'null': 'True', 'blank': 'True'}), - 'old_comment_id': ('django.db.models.fields.PositiveIntegerField', [], {'default': 'None', 'unique': 'True', 'null': 'True', 'blank': 'True'}), - 'old_question_id': ('django.db.models.fields.PositiveIntegerField', [], {'default': 'None', 'unique': 'True', 'null': 'True', 'blank': 'True'}), - 'parent': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'comments'", 'null': 'True', 'to': "orm['askbot.Post']"}), - 'post_type': ('django.db.models.fields.CharField', [], {'max_length': '255', 'db_index': 'True'}), - 'score': ('django.db.models.fields.IntegerField', [], {'default': '0'}), - 'summary': ('django.db.models.fields.CharField', [], {'max_length': '180'}), - 'text': ('django.db.models.fields.TextField', [], {'null': 'True'}), - 'thread': ('django.db.models.fields.related.ForeignKey', [], {'default': 'None', 'related_name': "'posts'", 'null': 'True', 'blank': 'True', 'to': "orm['askbot.Thread']"}), - 'vote_down_count': ('django.db.models.fields.IntegerField', [], {'default': '0'}), - 'vote_up_count': ('django.db.models.fields.IntegerField', [], {'default': '0'}), - 'wiki': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), - 'wikified_at': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}) - }, - 'askbot.postflagreason': { - 'Meta': {'object_name': 'PostFlagReason'}, - 'added_at': ('django.db.models.fields.DateTimeField', [], {}), - 'author': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']"}), - 'details': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'post_reject_reasons'", 'to': "orm['askbot.Post']"}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'title': ('django.db.models.fields.CharField', [], {'max_length': '128'}) - }, - 'askbot.postrevision': { - 'Meta': {'ordering': "('-revision',)", 'unique_together': "(('post', 'revision'),)", 'object_name': 'PostRevision'}, - 'approved': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'db_index': 'True'}), - 'approved_at': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}), - 'approved_by': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']", 'null': 'True', 'blank': 'True'}), - 'author': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'postrevisions'", 'to': "orm['auth.User']"}), - 'by_email': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), - 'email_address': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'null': 'True', 'blank': 'True'}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'is_anonymous': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), - 'post': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'revisions'", 'null': 'True', 'to': "orm['askbot.Post']"}), - 'revised_at': ('django.db.models.fields.DateTimeField', [], {}), - 'revision': ('django.db.models.fields.PositiveIntegerField', [], {}), - 'summary': ('django.db.models.fields.CharField', [], {'max_length': '300', 'blank': 'True'}), - 'tagnames': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '125', 'blank': 'True'}), - 'text': ('django.db.models.fields.TextField', [], {}), - 'title': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '300', 'blank': 'True'}) - }, - 'askbot.questionview': { - 'Meta': {'object_name': 'QuestionView'}, - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'question': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'viewed'", 'to': "orm['askbot.Post']"}), - 'when': ('django.db.models.fields.DateTimeField', [], {}), - 'who': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'question_views'", 'to': "orm['auth.User']"}) - }, - 'askbot.replyaddress': { - 'Meta': {'object_name': 'ReplyAddress'}, - 'address': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '25'}), - 'allowed_from_email': ('django.db.models.fields.EmailField', [], {'max_length': '150'}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'post': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'reply_addresses'", 'null': 'True', 'to': "orm['askbot.Post']"}), - 'reply_action': ('django.db.models.fields.CharField', [], {'default': "'auto_answer_or_comment'", 'max_length': '32'}), - 'response_post': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'edit_addresses'", 'null': 'True', 'to': "orm['askbot.Post']"}), - 'used_at': ('django.db.models.fields.DateTimeField', [], {'default': 'None', 'null': 'True'}), - 'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']"}) - }, - 'askbot.repute': { - 'Meta': {'object_name': 'Repute', 'db_table': "u'repute'"}, - 'comment': ('django.db.models.fields.CharField', [], {'max_length': '128', 'null': 'True'}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'negative': ('django.db.models.fields.SmallIntegerField', [], {'default': '0'}), - 'positive': ('django.db.models.fields.SmallIntegerField', [], {'default': '0'}), - 'question': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['askbot.Post']", 'null': 'True', 'blank': 'True'}), - 'reputation': ('django.db.models.fields.IntegerField', [], {'default': '1'}), - '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', [], {'to': "orm['auth.User']"}) - }, - 'askbot.suggestedtag': { - 'Meta': {'ordering': "['-used_count', 'name']", 'object_name': 'SuggestedTag'}, - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '255'}), - 'thread_ids': ('django.db.models.fields.TextField', [], {}), - 'threads': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['askbot.Thread']", 'symmetrical': 'False'}), - 'used_count': ('django.db.models.fields.PositiveIntegerField', [], {'default': '1'}), - 'users': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.User']", 'symmetrical': 'False'}) - }, - 'askbot.tag': { - 'Meta': {'ordering': "('-used_count', 'name')", 'object_name': 'Tag', 'db_table': "u'tag'"}, - 'created_by': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'created_tags'", 'to': "orm['auth.User']"}), - 'deleted': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), - '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['auth.User']"}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '255'}), - 'tag_wiki': ('django.db.models.fields.related.OneToOneField', [], {'related_name': "'described_tag'", 'unique': 'True', 'null': 'True', 'to': "orm['askbot.Post']"}), - 'used_count': ('django.db.models.fields.PositiveIntegerField', [], {'default': '0'}) - }, - 'askbot.thread': { - 'Meta': {'object_name': 'Thread'}, - 'accepted_answer': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'+'", 'null': 'True', 'to': "orm['askbot.Post']"}), - 'added_at': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), - 'answer_accepted_at': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}), - 'answer_count': ('django.db.models.fields.PositiveIntegerField', [], {'default': '0'}), - 'approved': ('django.db.models.fields.BooleanField', [], {'default': 'True', 'db_index': 'True'}), - 'close_reason': ('django.db.models.fields.SmallIntegerField', [], {'null': 'True', 'blank': 'True'}), - 'closed': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), - 'closed_at': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}), - 'closed_by': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']", 'null': 'True', 'blank': 'True'}), - 'favorited_by': ('django.db.models.fields.related.ManyToManyField', [], {'related_name': "'unused_favorite_threads'", 'symmetrical': 'False', 'through': "orm['askbot.FavoriteQuestion']", 'to': "orm['auth.User']"}), - 'favourite_count': ('django.db.models.fields.PositiveIntegerField', [], {'default': '0'}), - 'followed_by': ('django.db.models.fields.related.ManyToManyField', [], {'related_name': "'followed_threads'", 'symmetrical': 'False', 'to': "orm['auth.User']"}), - 'groups': ('django.db.models.fields.related.ManyToManyField', [], {'related_name': "'group_threads'", 'symmetrical': 'False', 'to': "orm['askbot.Tag']"}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'last_activity_at': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), - 'last_activity_by': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'unused_last_active_in_threads'", 'to': "orm['auth.User']"}), - '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': "'threads'", 'symmetrical': 'False', 'to': "orm['askbot.Tag']"}), - 'title': ('django.db.models.fields.CharField', [], {'max_length': '300'}), - 'view_count': ('django.db.models.fields.PositiveIntegerField', [], {'default': '0'}) - }, - 'askbot.vote': { - 'Meta': {'unique_together': "(('user', 'voted_post'),)", 'object_name': 'Vote', 'db_table': "u'vote'"}, - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'user': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'votes'", 'to': "orm['auth.User']"}), - 'vote': ('django.db.models.fields.SmallIntegerField', [], {}), - 'voted_at': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), - 'voted_post': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'votes'", 'to': "orm['askbot.Post']"}) - }, - '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_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': '30'}), - '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'}) - } - } - - complete_apps = ['askbot'] \ No newline at end of file diff --git a/askbot/models/__init__.py b/askbot/models/__init__.py index 046f19a1..166bf0c8 100644 --- a/askbot/models/__init__.py +++ b/askbot/models/__init__.py @@ -29,7 +29,7 @@ from askbot.skins import utils as skin_utils from askbot.mail import messages from askbot.models.question import QuestionView, AnonymousQuestion from askbot.models.question import FavoriteQuestion -from askbot.models.tag import Tag, MarkedTag, SuggestedTag +from askbot.models.tag import Tag, MarkedTag from askbot.models.tag import get_group_names, get_groups from askbot.models.user import EmailFeedSetting, ActivityAuditStatus, Activity from askbot.models.user import GroupMembership, GroupProfile @@ -39,7 +39,6 @@ from askbot.models import signals from askbot.models.badges import award_badges_signal, get_badge, BadgeData from askbot.models.repute import Award, Repute, Vote from askbot import auth -from askbot.utils import category_tree from askbot.utils.decorators import auto_now_timestamp from askbot.utils.slug import slugify from askbot.utils.html import sanitize_html @@ -344,58 +343,6 @@ def user_can_create_tags(self): else: return True -def user_try_creating_tags(self, tag_names = None, thread = None): - created_tags = list() - if self.can_create_tags(): - suggested_tags = SuggestedTag.objects.filter(name__in = tag_names) - suggested_tags_dict = dict([(tag.name, tag) for tag in suggested_tags]) - for name in tag_names: - #todo: keep better track of who creates the tag - suggested_tag = suggested_tags_dict.get(name, None) - if suggested_tag: - creator = suggested_tag.users.all()[0] - else: - creator = self - - new_tag = Tag.objects.create( - name = name, - created_by = creator, - used_count = 1#wrong, but we are recounting downstream - ) - created_tags.append(new_tag) - #remove added tags from the suggested tag list - suggested_tags.delete() - elif tag_names:#notify admins by email about new tags - #maybe remove tags to report based on categories - #todo: maybe move this to tags_updated signal handler - if askbot_settings.TAG_SOURCE == 'category-tree': - category_names = category_tree.get_leaf_names() - #remove category tree tags from creation list - tag_names = tag_names - category_names - - #here we put tags on the moderation queue - if len(tag_names) > 0: - suggested_tags = SuggestedTag.objects.filter(name__in = tag_names) - - previously_suggested_tag_names = set() - for tag in suggested_tags: - tag.used_count += 1 - tag.threads.add(thread) - tag.users.add(self) - tag.save() - previously_suggested_tag_names.add(tag.name) - - tag_names = set(tag_names) - previously_suggested_tag_names - - SuggestedTag.objects.create( - tag_names = tag_names, - user = self, - thread = thread - ) - - return created_tags - - def user_can_have_strong_url(self): """True if user's homepage url can be followed by the search engine crawlers""" @@ -2664,7 +2611,6 @@ User.add_to_class('set_admin_status', user_set_admin_status) User.add_to_class('edit_group_membership', user_edit_group_membership) User.add_to_class('is_group_member', user_is_group_member) User.add_to_class('remove_admin_status', user_remove_admin_status) -User.add_to_class('try_creating_tags', user_try_creating_tags) User.add_to_class('is_moderator', user_is_moderator) User.add_to_class('is_approved', user_is_approved) User.add_to_class('is_watched', user_is_watched) @@ -3424,7 +3370,6 @@ __all__ = [ 'Vote', 'PostFlagReason', 'MarkedTag', - 'SuggestedTag', 'BadgeData', 'Award', diff --git a/askbot/models/question.py b/askbot/models/question.py index 2a5c557d..e4fb7e56 100644 --- a/askbot/models/question.py +++ b/askbot/models/question.py @@ -16,6 +16,7 @@ from askbot.conf import settings as askbot_settings from askbot import mail from askbot.mail import messages from askbot.models.tag import Tag, get_groups, get_tags_by_names +from askbot.models.tag import filter_accepted_tags, filter_suggested_tags from askbot.models.tag import delete_tags, separate_unused_tags from askbot.models.base import AnonymousContent, BaseQuerySetManager from askbot.models.tag import Tag, get_groups @@ -811,7 +812,7 @@ class Thread(models.Model): *IMPORTANT*: self._question_post() has to exist when update_tags() is called! """ - previous_tags = list(self.tags.all()) + previous_tags = list(self.tags.filter(status = Tag.STATUS_ACCEPTED)) ordered_updated_tagnames = [t for t in tagnames.strip().split(' ')] @@ -822,7 +823,9 @@ class Thread(models.Model): #remove tags from the question's tags many2many relation #used_count values are decremented on all tags removed_tags = self.remove_tags_by_names(removed_tagnames) + #modified tags go on to recounting their use + #todo - this can actually be done asynchronously - not so important modified_tags, unused_tags = separate_unused_tags(removed_tags) delete_tags(unused_tags)#tags with used_count == 0 are deleted @@ -831,7 +834,6 @@ class Thread(models.Model): #add new tags to the relation added_tagnames = updated_tagnames - previous_tagnames - #todo: the part below is too long and needs to be refactored if added_tagnames: #find reused tags reused_tags, new_tagnames = get_tags_by_names(added_tagnames) @@ -839,17 +841,20 @@ class Thread(models.Model): added_tags = list(reused_tags) #tag moderation is in the call below - created_tags = user.try_creating_tags(new_tagnames, thread = self) + created_tags = Tag.objects.create_in_bulk( + tag_names = new_tagnames, user = user + ) + added_tags.extend(created_tags) #todo: not nice that assignment of added_tags is way above self.tags.add(*added_tags) modified_tags.extend(added_tags) - else: added_tags = Tag.objects.none() #Save denormalized tag names on thread. Preserve order from user input. - added_tagnames = set([tag.name for tag in added_tags]) + accepted_added_tags = filter_accepted_tags(added_tags) + added_tagnames = set([tag.name for tag in accepted_added_tags]) final_tagnames = (previous_tagnames - removed_tagnames) | added_tagnames ordered_final_tagnames = list() for tagname in ordered_updated_tagnames: @@ -859,6 +864,21 @@ class Thread(models.Model): self.tagnames = ' '.join(ordered_final_tagnames) self.save()#need to save here? + #todo: factor out - tell author about suggested tags + suggested_tags = filter_suggested_tags(added_tags) + if len(suggested_tags) > 0: + if len(suggested_tags) == 1: + msg = _( + 'Tag %s is new and will be submitted for the ' + 'moderators approval' + ) % suggested_tags[0].name + else: + msg = _( + 'Tags %s are new and will be submitted for the ' + 'moderators approval' + ) % ', '.join([tag.name for tag in suggested_tags]) + user.message_set.create(message = msg) + #################################################################### self.update_summary_html() # regenerate question/thread summary html #################################################################### diff --git a/askbot/models/tag.py b/askbot/models/tag.py index 54c632e7..50edb801 100644 --- a/askbot/models/tag.py +++ b/askbot/models/tag.py @@ -5,6 +5,7 @@ from django.utils.translation import ugettext as _ from askbot.models.base import BaseQuerySetManager from askbot import const from askbot.conf import settings as askbot_settings +from askbot.utils import category_tree def delete_tags(tags): """deletes tags in the list""" @@ -26,6 +27,26 @@ def get_tags_by_names(tag_names): return tags, new_tag_names +def filter_tags_by_status(tags, status = None): + """returns a list or a query set of tags which are accepted""" + if isinstance(tags, models.query.QuerySet): + return tags.filter(status = status) + else: + return [tag for tag in tags if tag.status == status] + +def filter_accepted_tags(tags): + return filter_tags_by_status(tags, status = Tag.STATUS_ACCEPTED) + +def filter_suggested_tags(tags): + return filter_tags_by_status(tags, status = Tag.STATUS_SUGGESTED) + +def is_preapproved_tag_name(tag_name): + """true if tag name is in the category tree + or any other container of preapproved tags""" + #get list of preapproved tags, to make exceptions for + if askbot_settings.TAG_SOURCE == 'category-tree': + return tag_name in category_tree.get_leaf_names() + return False def separate_unused_tags(tags): """returns two lists:: @@ -144,6 +165,94 @@ class TagManager(BaseQuerySetManager): def get_query_set(self): return TagQuerySet(self.model) + def create(self, name = None, created_by = None, **kwargs): + """Creates a new tag""" + if created_by.can_create_tags() or is_preapproved_tag_name(name): + status = Tag.STATUS_ACCEPTED + else: + status = Tag.STATUS_SUGGESTED + + kwargs['created_by'] = created_by + kwargs['name'] = name + kwargs['status'] = status + + return super(TagManager, self).create(**kwargs) + + def create_suggested_tag(self, tag_names = None, user = None): + """This function is not used, and will probably need + to be retired. In the previous version we were sending + email to admins when the new tags were created, + now we have a separate page where new tags are listed. + """ + #todo: stuff below will probably go after + #tag moderation actions are implemented + from askbot import mail + from askbot.mail import messages + body_text = messages.notify_admins_about_new_tags( + tags = tag_names, + user = user, + thread = self + ) + site_name = askbot_settings.APP_SHORT_NAME + subject_line = _('New tags added to %s') % site_name + mail.mail_moderators( + subject_line, + body_text, + headers = {'Reply-To': user.email} + ) + + msg = _( + 'Tags %s are new and will be submitted for the ' + 'moderators approval' + ) % ', '.join(tag_names) + user.message_set.create(message = msg) + + def create_in_bulk(self, tag_names = None, user = None): + """creates tags by names. If user can create tags, + then they are set status ``STATUS_ACCEPTED``, + otherwise the status will be set to ``STATUS_SUGGESTED``. + + One exception: if suggested tag is in the category tree + and source of tags is category tree - then status of newly + created tag is ``STATUS_ACCEPTED`` + """ + + #load suggested tags + pre_suggested_tags = self.filter( + name__in = tag_names, status = Tag.STATUS_SUGGESTED + ) + + #deal with suggested tags + if user.can_create_tags(): + #turn previously suggested tags into accepted + pre_suggested_tags.update(status = Tag.STATUS_ACCEPTED) + else: + #increment use count and add user to "suggested_by" + for tag in pre_suggested_tags: + tag.times_used += 1 + tag.suggested_by.add(user) + tag.save() + + created_tags = list() + pre_suggested_tag_names = list() + for tag in pre_suggested_tags: + pre_suggested_tag_names.append(tag.name) + created_tags.append(tag) + + for tag_name in set(tag_names) - set(pre_suggested_tag_names): + + #status for the new tags is automatically set within the create() + new_tag = Tag.objects.create(name = tag_name, created_by = user) + created_tags.append(new_tag) + + if new_tag.status == Tag.STATUS_SUGGESTED: + new_tag.suggested_by.add(user) + + #todo: here we have a chance to send a signal and notify + #whoever wants about the new tag creation + + return created_tags + class GroupTagQuerySet(TagQuerySet): """Custom query set for the group""" @@ -192,8 +301,20 @@ class GroupTagManager(BaseQuerySetManager): return tag class Tag(models.Model): - name = models.CharField(max_length=255, unique=True) - created_by = models.ForeignKey(User, related_name='created_tags') + #a couple of status constants + STATUS_SUGGESTED = 0 + STATUS_ACCEPTED = 1 + + name = models.CharField(max_length=255, unique=True) + created_by = models.ForeignKey(User, related_name='created_tags') + + suggested_by = models.ManyToManyField( + User, related_name='suggested_tags', + help_text = 'Works only for suggested tags for tag moderation' + ) + + status = models.SmallIntegerField(default = STATUS_ACCEPTED) + # Denormalised data used_count = models.PositiveIntegerField(default=0) @@ -237,67 +358,3 @@ def get_groups(): def get_group_names(): #todo: cache me return get_groups().values_list('name', flat = True) - -class SuggestedTagManager(models.Manager): - def create(self, tag_names = None, user = None, thread = None): - """creates ``SuggestedTag`` records and saves them - in the database""" - suggested_tags = list() - for tag_name in tag_names: - #create new record - suggested_tag = SuggestedTag(name = tag_name) - suggested_tag.save() - #add user and thread - suggested_tag.users.add(user) - suggested_tag.threads.add(thread) - #add to the list that is to be returned - suggested_tags.append(suggested_tag) - - #todo: stuff below will probably go after - #tag moderation actions are implemented - from askbot import mail - from askbot.mail import messages - body_text = messages.notify_admins_about_new_tags( - tags = tag_names, - user = user, - thread = thread - ) - site_name = askbot_settings.APP_SHORT_NAME - subject_line = _('New tags added to %s') % site_name - mail.mail_moderators( - subject_line, - body_text, - headers = {'Reply-To': user.email} - ) - - msg = _( - 'Tags %s are new and will be submitted for the ' - 'moderators approval' - ) % ', '.join(tag_names) - user.message_set.create(message = msg) - - return suggested_tags - -class SuggestedTag(models.Model): - """Suggested tag knows about who suggested it - and in what thread""" - name = models.CharField( - max_length=255, unique=True, help_text = 'Name for the proposed tag' - ) - used_count = models.PositiveIntegerField(default = 1) - #todo: instead these can be associated with revisions - #but the problem is that there would be too many joins - #to pull out threads - #if we used revisions, then we would not need to have - #a separate "user" field - threads = models.ManyToManyField('Thread') - users = models.ManyToManyField(User) - thread_ids = models.TextField( - help_text = 'comma-separated list of thread ids' - ) - - objects = SuggestedTagManager() - - class Meta: - app_label = 'askbot' - ordering = ['-used_count', 'name'] diff --git a/askbot/skins/default/templates/moderate_tags.html b/askbot/skins/default/templates/moderate_tags.html index fbf43d5e..5cd95a87 100644 --- a/askbot/skins/default/templates/moderate_tags.html +++ b/askbot/skins/default/templates/moderate_tags.html @@ -22,7 +22,7 @@ ×{{ tag.used_count }} - {% for user in tag.users.all() %} + {% for user in tag.suggested_by.all() %}

{{ user.get_profile_link() }}

{% endfor %} diff --git a/askbot/views/commands.py b/askbot/views/commands.py index 0f59c122..19684179 100644 --- a/askbot/views/commands.py +++ b/askbot/views/commands.py @@ -493,7 +493,8 @@ def get_tag_list(request): function """ tag_names = models.Tag.objects.filter( - deleted = False + deleted = False, + status = models.Tag.STATUS_ACCEPTED ).values_list( 'name', flat = True ) diff --git a/askbot/views/meta.py b/askbot/views/meta.py index fd7cb3e2..418c9cd2 100644 --- a/askbot/views/meta.py +++ b/askbot/views/meta.py @@ -17,7 +17,7 @@ from askbot import skins from askbot.conf import settings as askbot_settings from askbot.forms import FeedbackForm from askbot.mail import mail_moderators -from askbot.models import BadgeData, Award, User, SuggestedTag +from askbot.models import BadgeData, Award, User, Tag from askbot.models import badges as badge_data from askbot.skins.loaders import get_template, render_into_skin, render_text_into_skin from askbot.utils.decorators import admins_only @@ -164,9 +164,10 @@ def moderate_tags(request): or cancel the moderation reuest.""" if askbot_settings.ENABLE_TAG_MODERATION == False: raise Http404 - tags = SuggestedTag.objects.all() + tags = Tag.objects.filter(status = Tag.STATUS_SUGGESTED) + tags = tags.order_by('-used_count', 'name') #paginate moderated tags - paginator = Paginator(SuggestedTag.objects.all(), 20) + paginator = Paginator(tags, 20) page_no = request.GET.get('page', '1') -- cgit v1.2.3-1-g7c22