From aa9d250fc29ad29a9b7863a6253e906c772df914 Mon Sep 17 00:00:00 2001 From: jordan Date: Sat, 2 Jul 2011 14:04:43 +0000 Subject: [PATCH] Jira OSQA-598, a functionality that allows to convert comments to questions directly has been added. Also the length of the action_type field of the Action model has been increased to 32 characters. Database migration added. git-svn-id: http://svn.osqa.net/svnroot/osqa/trunk@1092 0cfe37f9-358a-4d5e-be75-b63607b5c754 --- forum/actions/node.py | 24 ++ ...0051_auto__chg_field_action_action_type.py | 277 ++++++++++++++++++ forum/models/action.py | 2 +- forum/models/user.py | 4 +- .../images/convert-to-question-hover.png | Bin 0 -> 780 bytes .../media/images/convert-to-question-off.png | Bin 0 -> 759 bytes forum/skins/default/media/style/style.css | 10 +- .../default/templates/node/comments.html | 2 + forum/views/writers.py | 17 +- 9 files changed, 327 insertions(+), 9 deletions(-) create mode 100644 forum/migrations/0051_auto__chg_field_action_action_type.py create mode 100644 forum/skins/default/media/images/convert-to-question-hover.png create mode 100644 forum/skins/default/media/images/convert-to-question-off.png diff --git a/forum/actions/node.py b/forum/actions/node.py index 79b7531..c26a53a 100644 --- a/forum/actions/node.py +++ b/forum/actions/node.py @@ -197,6 +197,30 @@ class CommentToAnswerAction(ActionProxy): 'user': self.hyperlink(self.user.get_profile_url(), self.friendly_username(viewer, self.user)), 'question': self.describe_node(viewer, self.node.abs_parent), } +class CommentToQuestionAction(NodeEditAction): + verb = _("converted") + + def process_data(self, **data): + revision_data = self.create_revision_data(**data) + revision = self.node.create_revision(self.user, **revision_data) + + self.extra = { + 'covert_revision': revision.revision, + } + + self.node.node_type = "question" + self.node.parent = None + self.node.abs_parent = None + + def process_action(self): + self.node.last_edited = self + self.node.save() + + def describe(self, viewer=None): + return _("%(user)s converted comment on %(question)s to a new question") % { + 'user': self.hyperlink(self.user.get_profile_url(), self.friendly_username(viewer, self.user)), + 'question': self.describe_node(viewer, self.node.abs_parent), + } class AnswerToQuestionAction(NodeEditAction): verb = _("converted to question") diff --git a/forum/migrations/0051_auto__chg_field_action_action_type.py b/forum/migrations/0051_auto__chg_field_action_action_type.py new file mode 100644 index 0000000..1c83b6a --- /dev/null +++ b/forum/migrations/0051_auto__chg_field_action_action_type.py @@ -0,0 +1,277 @@ +# 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): + + # Changing field 'Action.action_type' + db.alter_column('forum_action', 'action_type', self.gf('django.db.models.fields.CharField')(max_length=32)) + + + def backwards(self, orm): + + # Changing field 'Action.action_type' + db.alter_column('forum_action', 'action_type', self.gf('django.db.models.fields.CharField')(max_length=16)) + + + models = { + 'auth.group': { + 'Meta': {'object_name': 'Group'}, + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '80'}), + 'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}) + }, + 'auth.permission': { + 'Meta': {'ordering': "('content_type__app_label', 'content_type__model', 'codename')", 'unique_together': "(('content_type', 'codename'),)", 'object_name': 'Permission'}, + 'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}), + 'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '50'}) + }, + 'auth.user': { + 'Meta': {'object_name': 'User'}, + 'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), + 'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}), + 'first_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}), + 'groups': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Group']", 'symmetrical': 'False', 'blank': 'True'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), + 'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'last_login': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), + 'last_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}), + 'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}), + 'user_permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}), + 'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'}) + }, + 'contenttypes.contenttype': { + 'Meta': {'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"}, + 'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}) + }, + 'forum.action': { + 'Meta': {'object_name': 'Action'}, + 'action_date': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), + 'action_type': ('django.db.models.fields.CharField', [], {'max_length': '32'}), + 'canceled': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'canceled_at': ('django.db.models.fields.DateTimeField', [], {'null': 'True'}), + 'canceled_by': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'canceled_actions'", 'null': 'True', 'to': "orm['forum.User']"}), + 'canceled_ip': ('django.db.models.fields.CharField', [], {'max_length': '39'}), + 'extra': ('forum.models.utils.PickledObjectField', [], {'null': 'True'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'ip': ('django.db.models.fields.CharField', [], {'max_length': '39'}), + 'node': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'actions'", 'null': 'True', 'to': "orm['forum.Node']"}), + 'real_user': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'proxied_actions'", 'null': 'True', 'to': "orm['forum.User']"}), + 'user': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'actions'", 'to': "orm['forum.User']"}) + }, + 'forum.actionrepute': { + 'Meta': {'object_name': 'ActionRepute'}, + 'action': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'reputes'", 'to': "orm['forum.Action']"}), + 'by_canceled': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'date': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'user': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'reputes'", 'to': "orm['forum.User']"}), + 'value': ('django.db.models.fields.IntegerField', [], {'default': '0'}) + }, + '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': "(('user', 'badge', 'node'),)", 'object_name': 'Award'}, + 'action': ('django.db.models.fields.related.OneToOneField', [], {'related_name': "'award'", 'unique': 'True', 'to': "orm['forum.Action']"}), + 'awarded_at': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), + 'badge': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'awards'", 'to': "orm['forum.Badge']"}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'node': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['forum.Node']", 'null': 'True'}), + 'trigger': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'awards'", 'null': 'True', 'to': "orm['forum.Action']"}), + 'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['forum.User']"}) + }, + 'forum.badge': { + 'Meta': {'object_name': 'Badge'}, + 'awarded_count': ('django.db.models.fields.PositiveIntegerField', [], {'default': '0'}), + 'awarded_to': ('django.db.models.fields.related.ManyToManyField', [], {'related_name': "'badges'", 'symmetrical': 'False', 'through': "orm['forum.Award']", 'to': "orm['forum.User']"}), + 'cls': ('django.db.models.fields.CharField', [], {'max_length': '50', 'null': 'True'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'type': ('django.db.models.fields.SmallIntegerField', [], {}) + }, + 'forum.flag': { + 'Meta': {'unique_together': "(('user', 'node'),)", 'object_name': 'Flag'}, + 'action': ('django.db.models.fields.related.OneToOneField', [], {'related_name': "'flag'", 'unique': 'True', 'to': "orm['forum.Action']"}), + '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': "'flags'", 'to': "orm['forum.Node']"}), + 'reason': ('django.db.models.fields.CharField', [], {'max_length': '300'}), + 'user': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'flags'", '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', [], {'null': 'True'}) + }, + '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.mysqlftsindex': { + 'Meta': {'object_name': 'MysqlFtsIndex', 'managed': 'False'}, + 'body': ('django.db.models.fields.TextField', [], {}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'node': ('django.db.models.fields.related.OneToOneField', [], {'related_name': "'ftsindex'", 'unique': 'True', 'to': "orm['forum.Node']"}), + 'tagnames': ('django.db.models.fields.CharField', [], {'max_length': '255'}), + 'title': ('django.db.models.fields.CharField', [], {'max_length': '300'}) + }, + 'forum.node': { + 'Meta': {'object_name': 'Node'}, + 'abs_parent': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'all_children'", 'null': 'True', 'to': "orm['forum.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', [], {}), + 'extra': ('forum.models.utils.PickledObjectField', [], {'null': 'True'}), + 'extra_count': ('django.db.models.fields.IntegerField', [], {'default': '0'}), + 'extra_ref': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['forum.Node']", 'null': 'True'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'last_activity_at': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}), + 'last_activity_by': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['forum.User']", 'null': 'True'}), + 'last_edited': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'edited_node'", 'unique': 'True', 'null': 'True', 'to': "orm['forum.Action']"}), + 'marked': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'node_type': ('django.db.models.fields.CharField', [], {'default': "'node'", 'max_length': '16'}), + 'parent': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'children'", 'null': 'True', 'to': "orm['forum.Node']"}), + 'score': ('django.db.models.fields.IntegerField', [], {'default': '0'}), + 'state_string': ('django.db.models.fields.TextField', [], {'default': "''"}), + 'tagnames': ('django.db.models.fields.CharField', [], {'max_length': '125'}), + 'tags': ('django.db.models.fields.related.ManyToManyField', [], {'related_name': "'nodes'", 'symmetrical': 'False', 'to': "orm['forum.Tag']"}), + 'title': ('django.db.models.fields.CharField', [], {'max_length': '300'}) + }, + '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.nodestate': { + 'Meta': {'unique_together': "(('node', 'state_type'),)", 'object_name': 'NodeState'}, + 'action': ('django.db.models.fields.related.OneToOneField', [], {'related_name': "'node_state'", 'unique': 'True', 'to': "orm['forum.Action']"}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'node': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'states'", 'to': "orm['forum.Node']"}), + 'state_type': ('django.db.models.fields.CharField', [], {'max_length': '16'}) + }, + 'forum.openidassociation': { + 'Meta': {'object_name': 'OpenIdAssociation'}, + 'assoc_type': ('django.db.models.fields.TextField', [], {'max_length': '64'}), + 'handle': ('django.db.models.fields.CharField', [], {'max_length': '255'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'issued': ('django.db.models.fields.IntegerField', [], {}), + 'lifetime': ('django.db.models.fields.IntegerField', [], {}), + 'secret': ('django.db.models.fields.TextField', [], {'max_length': '255'}), + 'server_url': ('django.db.models.fields.TextField', [], {'max_length': '2047'}) + }, + 'forum.openidnonce': { + 'Meta': {'object_name': 'OpenIdNonce'}, + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'salt': ('django.db.models.fields.CharField', [], {'max_length': '50'}), + 'server_url': ('django.db.models.fields.URLField', [], {'max_length': '200'}), + 'timestamp': ('django.db.models.fields.IntegerField', [], {}) + }, + 'forum.questionsubscription': { + 'Meta': {'object_name': 'QuestionSubscription'}, + 'auto_subscription': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'last_view': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime(2011, 7, 2, 9, 57, 53, 818588)'}), + 'question': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['forum.Node']"}), + 'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['forum.User']"}) + }, + 'forum.subscriptionsettings': { + 'Meta': {'object_name': 'SubscriptionSettings'}, + 'all_questions': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'all_questions_watched_tags': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'enable_notifications': ('django.db.models.fields.BooleanField', [], {'default': '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': "'n'", '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'}), + 'notify_answers': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), + 'notify_comments': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'notify_comments_own_post': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), + 'notify_reply_to_comments': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), + 'questions_viewed': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'send_digest': ('django.db.models.fields.BooleanField', [], {'default': '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': {'ordering': "('-used_count', 'name')", 'object_name': 'Tag'}, + 'created_at': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now', 'null': 'True', 'blank': 'True'}), + 'created_by': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'created_tags'", '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'", 'symmetrical': 'False', 'through': "orm['forum.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.PositiveIntegerField', [], {'default': '0'}), + 'date_of_birth': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}), + 'email_isvalid': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'gold': ('django.db.models.fields.PositiveIntegerField', [], {'default': '0'}), + 'is_approved': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'last_seen': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), + 'location': ('django.db.models.fields.CharField', [], {'max_length': '100', 'blank': 'True'}), + 'real_name': ('django.db.models.fields.CharField', [], {'max_length': '100', 'blank': 'True'}), + 'reputation': ('django.db.models.fields.IntegerField', [], {'default': '0'}), + 'silver': ('django.db.models.fields.PositiveIntegerField', [], {'default': '0'}), + 'subscriptions': ('django.db.models.fields.related.ManyToManyField', [], {'related_name': "'subscribers'", 'symmetrical': 'False', 'through': "orm['forum.QuestionSubscription']", 'to': "orm['forum.Node']"}), + '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.userproperty': { + 'Meta': {'unique_together': "(('user', 'key'),)", 'object_name': 'UserProperty'}, + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'key': ('django.db.models.fields.CharField', [], {'max_length': '16'}), + 'user': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'properties'", 'to': "orm['forum.User']"}), + 'value': ('forum.models.utils.PickledObjectField', [], {'null': 'True'}) + }, + 'forum.validationhash': { + 'Meta': {'unique_together': "(('user', 'type'),)", 'object_name': 'ValidationHash'}, + 'expiration': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime(2011, 7, 3, 9, 57, 54, 45564)'}), + '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': {'unique_together': "(('user', 'node'),)", 'object_name': 'Vote'}, + 'action': ('django.db.models.fields.related.OneToOneField', [], {'related_name': "'vote'", 'unique': 'True', 'to': "orm['forum.Action']"}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'node': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'votes'", 'to': "orm['forum.Node']"}), + 'user': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'votes'", 'to': "orm['forum.User']"}), + 'value': ('django.db.models.fields.SmallIntegerField', [], {}), + 'voted_at': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}) + } + } + + complete_apps = ['forum'] diff --git a/forum/models/action.py b/forum/models/action.py index ca92c27..e8d0765 100644 --- a/forum/models/action.py +++ b/forum/models/action.py @@ -44,7 +44,7 @@ class Action(BaseModel): real_user = models.ForeignKey('User', related_name="proxied_actions", null=True) ip = models.CharField(max_length=39) node = models.ForeignKey('Node', null=True, related_name="actions") - action_type = models.CharField(max_length=16) + action_type = models.CharField(max_length=32) action_date = models.DateTimeField(default=datetime.datetime.now) extra = PickledObjectField() diff --git a/forum/models/user.py b/forum/models/user.py index f00f378..e73244d 100644 --- a/forum/models/user.py +++ b/forum/models/user.py @@ -317,8 +317,8 @@ class User(BaseModel, DjangoUser): return (not answer.marked) and (self.is_superuser or self.is_staff or answer.author == self or self.reputation >= int (settings.REP_TO_CONVERT_TO_COMMENT)) - def can_convert_to_question(self, answer): - return (not answer.marked) and (self.is_superuser or self.is_staff or answer.author == self or self.reputation >= int + def can_convert_to_question(self, node): + return (not node.marked) and (self.is_superuser or self.is_staff or node.author == self or self.reputation >= int (settings.REP_TO_CONVERT_TO_QUESTION)) @true_if_is_super_or_staff diff --git a/forum/skins/default/media/images/convert-to-question-hover.png b/forum/skins/default/media/images/convert-to-question-hover.png new file mode 100644 index 0000000000000000000000000000000000000000..52f6ee656a96bb9014ad13cd333aeed29e9be1f3 GIT binary patch literal 780 zcmV+n1M~ceP)Px#24YJ`L;(K){{a7>y{D4^000SaNLh0L01FcU01FcV0GgZ_00007bV*G`2ipe$ z7A+opKSg%{00N9jL_t(2&sB_DYgAVlK-ag=Iho02lEyJ()Le87N)rfy2=#)Oq6ne{ zQ6EH9P+I*5?Qdv*K@>4hiVrbVQH1tEpA>@%v2h5RC}fOdj?*MFlgZ3E`<%UfQt5hL zYl-js04SvZT0KXdO(wjfuB*0VA&SkLTA&|BvAG45jWGbo*HA=`x22l?&?NfjmW9O% zAVO!0CEITC2y&&$+V9rd``<%rkFWb7H9lQ*6BGYxRs#pmRRBa5+7dA*23-2nI#^n% zoJQon6bgm*bX&{wS4B5_^+}!PL<1twt zX)k;IX@#Wg;1Cn&7_l+?dLk|kX?AsKKyl;QDrN0uT_qP(Q_>r`J6)q(v+VB;IX@WC zpfrVY#OS1Dwit70i>A9ZWVvd%H(jSO>5VAQb@~>TLw0u=_G}8tG-{4*3$by;TrpyN zI!0?vZ%Pvz!|OtT=Q@3^F-H8dW`4=Cx!Ew(X?ZlKDAxpIp|S?`ASTp85GqP*f;FC~ zAk^<0T*HTzkjZ>Rq(cVM0S=l*M{{^fok)k|79*-bNNds%g!;X^QmH;TkZs;Sm9O$_ zUa>V5v$xyuV><}oIq=V0#q+#HiQ!i}BY%_t=vXt`def8g`^D z7MLjtFFz?_1DE!+acZC;?-&0YmYJCuMC4>wXUFZUPb=Qd$z_b?e<*=-KehAgu9RN* z^!bdnc0#76rm)t6wWoSEZ}>A`Z^@26{>ZE!0MOTw;L6XN=t-`=n_pP`4Usz{f@Ct8 zZ|6)V(|P%qOBYX`7&($^ZrTP=t<`5I{<`<~=(X!(zV9!7b-w`Mg+3&bf9T-=0000< KMNUMnLSTZ1d|dzl literal 0 HcmV?d00001 diff --git a/forum/skins/default/media/images/convert-to-question-off.png b/forum/skins/default/media/images/convert-to-question-off.png new file mode 100644 index 0000000000000000000000000000000000000000..846fa15b8a83c7e26cc613c721469268e0e3493d GIT binary patch literal 759 zcmVPx#24YJ`L;(K){{a7>y{D4^000SaNLh0L01FcU01FcV0GgZ_00007bV*G`2ipe$ z7A-PP=P8r`00MVOL_t(2&rOoMP9s+UK+nD7VPL@KVOC&^0fa1yScoENun+~^N~V$}&w?PJ*Xsc=F)_i^ z)D*^;zaAbQzB9(W`7hL3znGky{I%2RIA>>P42MIclmHlG7#SI%SS&I$bL<#HLN)QS+|wHzHCeOakg7z_q@o=34*1Rw|kj*pLN zx7#c)FOyEE>G%6oDis{Zc_~w=RH57LvbeZNKA*>RT?&N)T5EjY=k)Xxr4;FO8m%?A zx3{EHsX|I?ErK9mI2_`-F1cKe%gal8y&lFGY}+P|W0EA{@$nHUCB_&blO(BGmPM!2 zq0wldlp>qWVvNDEES8p*P)gBiwHOQrIF3V-B(+o&MQ;m*!dAUrr(Um<$zMBtby%p7J_1Wy~?4KtmC*J=4K2l0N&m)`70^s{TH#awEt=Zbz zVr^~hL%ZGnT-0hcgb=Uh=jVSpJUp}y4i5OZ)klO7Y;JB+DwR~L)%w~P^Sd}dKgSq@ zG3LvKg@vE`{r<|{-X6_n6M$SU$M*I%uIpB>udlxqLj3mc*Z(7>oZs2m`JvftzKf!$ p5k*ns?(S}HcX#)DDdpU!?%$J2Htg4*Ax!`P002ovPDHLkV1n*fQ%C>+ literal 0 HcmV?d00001 diff --git a/forum/skins/default/media/style/style.css b/forum/skins/default/media/style/style.css index 980f316..9927bf8 100644 --- a/forum/skins/default/media/style/style.css +++ b/forum/skins/default/media/style/style.css @@ -1525,7 +1525,7 @@ a.accept-answer.on, a.accept-answer:hover { margin-left: 4px; } -a.comment-like, a.comment-delete, a.comment-edit, a.comment-convert { +a.comment-like, a.comment-delete, a.comment-edit, a.comment-convert, a.comment-convert-to-question { margin-left: 2px; width: 18px; } @@ -1554,6 +1554,14 @@ a.comment-convert:hover { background: url("../images/convert-hover.png") no-repeat scroll center center transparent; } +a.comment-convert-to-question { + background: url("../images/convert-to-question-off.png") no-repeat scroll center center transparent; +} + +a.comment-convert-to-question:hover { + background: url("../images/convert-to-question-hover.png") no-repeat scroll center center transparent; +} + a.comment-edit { background: url("../images/comment-edit.png") no-repeat scroll center center transparent; } diff --git a/forum/skins/default/templates/node/comments.html b/forum/skins/default/templates/node/comments.html index d4f9b62..25f04b6 100644 --- a/forum/skins/default/templates/node/comments.html +++ b/forum/skins/default/templates/node/comments.html @@ -24,6 +24,8 @@ {% if comment.can_convert %} + {% endif %} diff --git a/forum/views/writers.py b/forum/views/writers.py index 5064757..8e9c544 100644 --- a/forum/views/writers.py +++ b/forum/views/writers.py @@ -12,7 +12,7 @@ from django.utils.translation import ugettext as _ from django.core.urlresolvers import reverse from django.core.exceptions import PermissionDenied -from forum.actions import AskAction, AnswerAction, ReviseAction, RollbackAction, RetagAction, AnswerToQuestionAction +from forum.actions import AskAction, AnswerAction, ReviseAction, RollbackAction, RetagAction, AnswerToQuestionAction, CommentToQuestionAction from forum.forms import * from forum.models import * from forum.forms import get_next_url @@ -114,13 +114,20 @@ def ask(request): def convert_to_question(request, id): user = request.user - answer = get_object_or_404(Answer, id=id) - if not user.can_convert_to_question(answer): + node_type = request.GET.get('node_type', 'answer') + if node_type == 'comment': + node = get_object_or_404(Comment, id=id) + action_class = CommentToQuestionAction + else: + node = get_object_or_404(Answer, id=id) + action_class = AnswerToQuestionAction + + if not user.can_convert_to_question(node): return HttpResponseUnauthorized(request) - return _edit_question(request, answer, template='node/convert_to_question.html', summary=_("Converted to question"), - action_class=AnswerToQuestionAction, allow_rollback=False, url_getter=lambda a: Question.objects.get(id=a.id).get_absolute_url()) + return _edit_question(request, node, template='node/convert_to_question.html', summary=_("Converted to question"), + action_class =action_class, allow_rollback=False, url_getter=lambda a: Question.objects.get(id=a.id).get_absolute_url()) def edit_question(request, id): question = get_object_or_404(Question, id=id) -- 2.45.1