summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEvgeny Fadeev <evgeny.fadeev@gmail.com>2012-05-01 23:47:04 -0300
committerEvgeny Fadeev <evgeny.fadeev@gmail.com>2012-05-01 23:47:04 -0300
commita4692d9cb97154ee172185efbeedc374def6dcd0 (patch)
tree0142dea946db55072188bb3c051ffbf66bd89f87
parentdcae29a053866613612cfc5a74c8b3c5f3f88e8e (diff)
downloadaskbot-a4692d9cb97154ee172185efbeedc374def6dcd0.tar.gz
askbot-a4692d9cb97154ee172185efbeedc374def6dcd0.tar.bz2
askbot-a4692d9cb97154ee172185efbeedc374def6dcd0.zip
allowed admins to decide whether to moderate email posted to groups
-rw-r--r--askbot/conf/group_settings.py12
-rw-r--r--askbot/lamson_handlers.py7
-rw-r--r--askbot/migrations/0120_auto__add_field_groupprofile_moderate_email__add_field_postrevision_em.py322
-rw-r--r--askbot/models/__init__.py6
-rw-r--r--askbot/models/post.py22
-rw-r--r--askbot/models/question.py6
-rw-r--r--askbot/models/user.py1
-rw-r--r--askbot/skins/common/media/js/post.js29
-rw-r--r--askbot/skins/default/templates/users.html12
-rw-r--r--askbot/urls.py5
-rw-r--r--askbot/utils/mail.py3
-rw-r--r--askbot/views/commands.py18
-rw-r--r--askbot/views/users.py9
13 files changed, 438 insertions, 14 deletions
diff --git a/askbot/conf/group_settings.py b/askbot/conf/group_settings.py
index a48fb55d..b3c0069c 100644
--- a/askbot/conf/group_settings.py
+++ b/askbot/conf/group_settings.py
@@ -18,3 +18,15 @@ settings.register(
description = _('Enable user groups'),
)
)
+
+settings.register(
+ livesettings.BooleanValue(
+ GROUP_SETTINGS,
+ 'GROUP_EMAIL_ADDRESSES_ENABLED',
+ default = False,
+ description = _('Enable group email adddresses'),
+ help_text = _(
+ 'If selected, users can post to groups by email "group-name@domain.com"'
+ )
+ )
+)
diff --git a/askbot/lamson_handlers.py b/askbot/lamson_handlers.py
index 5c86bc98..1d4bb1bc 100644
--- a/askbot/lamson_handlers.py
+++ b/askbot/lamson_handlers.py
@@ -3,9 +3,10 @@ from lamson.routing import route, stateless
from lamson.server import Relay
from django.utils.translation import ugettext as _
from django.core.files.uploadedfile import SimpleUploadedFile
-from django.conf import settings
+from django.conf import settings as django_settings
from askbot.models import ReplyAddress, Tag
from askbot.utils import mail
+from askbot.conf import settings as askbot_settings
#we might end up needing to use something like this
@@ -122,6 +123,8 @@ def ASK(message, host = None, addr = None):
if addr == 'ask':
mail.process_emailed_question(from_address, subject, parts)
else:
+ if askbot_settings.GROUP_EMAIL_ADDRESSES_ENABLED == False:
+ return
try:
group_tag = Tag.group_tags.get(
deleted = False,
@@ -143,7 +146,7 @@ def PROCESS(message, address = None, host = None):
and make a post to askbot based on the contents of
the email, including the text body and the file attachments"""
try:
- for rule in settings.LAMSON_FORWARD:
+ for rule in django_settings.LAMSON_FORWARD:
if re.match(rule['pattern'], message.base['to']):
relay = Relay(host=rule['host'],
port=rule['port'], debug=1)
diff --git a/askbot/migrations/0120_auto__add_field_groupprofile_moderate_email__add_field_postrevision_em.py b/askbot/migrations/0120_auto__add_field_groupprofile_moderate_email__add_field_postrevision_em.py
new file mode 100644
index 00000000..4b9efe58
--- /dev/null
+++ b/askbot/migrations/0120_auto__add_field_groupprofile_moderate_email__add_field_postrevision_em.py
@@ -0,0 +1,322 @@
+# -*- 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 'GroupProfile.moderate_email'
+ db.add_column('askbot_groupprofile', 'moderate_email',
+ self.gf('django.db.models.fields.BooleanField')(default=True),
+ keep_default=False)
+
+ # Adding field 'PostRevision.email_address'
+ db.add_column('askbot_postrevision', 'email_address',
+ self.gf('django.db.models.fields.EmailField')(max_length=75, null=True, blank=True),
+ keep_default=False)
+
+ def backwards(self, orm):
+ # Deleting field 'GroupProfile.moderate_email'
+ db.delete_column('askbot_groupprofile', 'moderate_email')
+
+ # Deleting field 'PostRevision.email_address'
+ db.delete_column('askbot_postrevision', 'email_address')
+
+ 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': {'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'}),
+ 'logo_url': ('django.db.models.fields.URLField', [], {'max_length': '200', 'null': 'True'}),
+ 'moderate_email': ('django.db.models.fields.BooleanField', [], {'default': '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']"}),
+ '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', [], {}),
+ 'revision_type': ('django.db.models.fields.SmallIntegerField', [], {}),
+ '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'", 'to': "orm['askbot.Post']"}),
+ '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'}),
+ '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']"}),
+ '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_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'}),
+ 'silver': ('django.db.models.fields.SmallIntegerField', [], {'default': '0'}),
+ 'status': ('django.db.models.fields.CharField', [], {'default': "'w'", 'max_length': '2'}),
+ '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 e50baf0f..9167974e 100644
--- a/askbot/models/__init__.py
+++ b/askbot/models/__init__.py
@@ -1342,7 +1342,8 @@ def user_post_question(
wiki = False,
is_anonymous = False,
timestamp = None,
- by_email = False
+ by_email = False,
+ email_address = None
):
"""makes an assertion whether user can post the question
then posts it and returns the question object"""
@@ -1369,7 +1370,8 @@ def user_post_question(
added_at = timestamp,
wiki = wiki,
is_anonymous = is_anonymous,
- by_email = by_email
+ by_email = by_email,
+ email_address = email_address
)
question = thread._question_post()
if question.author != self:
diff --git a/askbot/models/post.py b/askbot/models/post.py
index 89763c1f..c1fc33d6 100644
--- a/askbot/models/post.py
+++ b/askbot/models/post.py
@@ -24,7 +24,7 @@ import askbot
from askbot.utils.slug import slugify
from askbot import const
from askbot.models.user import EmailFeedSetting
-from askbot.models.tag import MarkedTag, tags_match_some_wildcard
+from askbot.models.tag import Tag, MarkedTag, tags_match_some_wildcard
from askbot.conf import settings as askbot_settings
from askbot import exceptions
from askbot.utils import markup
@@ -1487,7 +1487,8 @@ class Post(models.Model):
text = None,
comment = None,
revised_at = None,
- by_email = False
+ by_email = False,
+ email_address = None
):
if None in (author, text):
raise Exception('author, text and comment are required arguments')
@@ -1509,7 +1510,8 @@ class Post(models.Model):
tagnames = self.thread.tagnames,
summary = comment,
text = text,
- by_email = by_email
+ by_email = by_email,
+ email_address = email_address
)
def add_revision(self, *kargs, **kwargs):
@@ -1709,9 +1711,10 @@ class PostRevision(models.Model):
approved = models.BooleanField(default=False, db_index=True)
approved_by = models.ForeignKey(User, null = True, blank = True)
- approved_at = models.DateTimeField(null= True, blank = True)
+ approved_at = models.DateTimeField(null = True, blank = True)
- by_email = models.BooleanField(default=False)#true, if edited by email
+ by_email = models.BooleanField(default = False)#true, if edited by email
+ email_address = models.EmailField(null = True, blank = True)
# Question-specific fields
title = models.CharField(max_length=300, blank=True, default='')
@@ -1736,6 +1739,15 @@ class PostRevision(models.Model):
return False
if self.approved:
return False
+
+ #if sent by email to group and group does not want moderation
+ if self.by_email and self.email:
+ group_name = self.email.split('@')[0]
+ try:
+ group = Tag.objects.get(name = group_name, deleted = False)
+ return group.group.profile.moderate_email
+ except Tag.DoesNotExist:
+ pass
return True
return False
diff --git a/askbot/models/question.py b/askbot/models/question.py
index de50c0c4..9481d3ac 100644
--- a/askbot/models/question.py
+++ b/askbot/models/question.py
@@ -71,7 +71,8 @@ class ThreadManager(models.Manager):
text,
tagnames = None,
is_anonymous = False,
- by_email = False
+ by_email = False,
+ email_address = None
):
# TODO: Some of this code will go to Post.objects.create_new
@@ -114,7 +115,8 @@ class ThreadManager(models.Manager):
text = text,
comment = const.POST_STATUS['default_version'],
revised_at = added_at,
- by_email = by_email
+ by_email = by_email,
+ email_address = email_address
)
# INFO: Question has to be saved before update_tags() is called
diff --git a/askbot/models/user.py b/askbot/models/user.py
index 3c1e0ded..f4c51cdc 100644
--- a/askbot/models/user.py
+++ b/askbot/models/user.py
@@ -354,6 +354,7 @@ class GroupProfile(models.Model):
related_name = 'group_profile'
)
logo_url = models.URLField(null = True)
+ moderate_email = models.BooleanField(default = True)
class Meta:
app_label = 'askbot'
diff --git a/askbot/skins/common/media/js/post.js b/askbot/skins/common/media/js/post.js
index f221536a..e858413d 100644
--- a/askbot/skins/common/media/js/post.js
+++ b/askbot/skins/common/media/js/post.js
@@ -2248,11 +2248,40 @@ var UserGroupProfileEditor = function(){
};
inherits(UserGroupProfileEditor, TagWikiEditor);
+UserGroupProfileEditor.prototype.toggleEmailModeration = function(){
+ var btn = this._moderate_email_btn;
+ var group_id = this.getTagId();
+ $.ajax({
+ type: 'POST',
+ dataType: 'json',
+ cache: false,
+ data: {group_id: group_id},
+ url: askbot['urls']['toggle_group_email_moderation'],
+ success: function(data){
+ if (data['success']){
+ btn.html(data['new_button_text']);
+ } else {
+ showMessage(btn, data['message']);
+ }
+ }
+ });
+};
+
UserGroupProfileEditor.prototype.decorate = function(element){
UserGroupProfileEditor.superClass_.decorate.call(this, element);
var change_logo_btn = element.find('.change-logo');
this._change_logo_btn = change_logo_btn;
+ var moderate_email_btn = element.find('.moderate-email');
+ this._moderate_email_btn = moderate_email_btn;
+ var me = this;
+ setupButtonEventHandlers(
+ moderate_email_btn,
+ function(){
+ me.toggleEmailModeration();
+ }
+ )
+
var logo_changer = new ImageChanger();
logo_changer.setImageElement(element.find('.group-logo'));
logo_changer.setAjaxData({
diff --git a/askbot/skins/default/templates/users.html b/askbot/skins/default/templates/users.html
index 9b7a282e..351a6df9 100644
--- a/askbot/skins/default/templates/users.html
+++ b/askbot/skins/default/templates/users.html
@@ -81,7 +81,16 @@
<a class="change-logo"
>{% trans %}add logo{% endtrans %}</a>
{% endif %}
-
+ {% if group_email_moderation_enabled %}
+ <span>|</span>
+ {% if group.group_profile.moderate_email %}
+ <a class="moderate-email"
+ >{% trans %}disable moderation of emailed questions{% endtrans %}</a>
+ {% else %}
+ <a class="moderate-email"
+ >{% trans %}moderate emailed questions{% endtrans %}</a>
+ {% endif %}
+ {% endif %}
</div>
{% endif %}
</div>
@@ -104,6 +113,7 @@
askbot['urls']['save_tag_wiki_text'] = '{% url save_tag_wiki_text %}';
askbot['urls']['save_group_logo_url'] = '{% url save_group_logo_url %}';
askbot['urls']['delete_group_logo_url'] = '{% url delete_group_logo %}';
+ askbot['urls']['toggle_group_email_moderation'] = '{% url toggle_group_email_moderation %}';
</script>
<script type='text/javascript' src='{{"/js/editor.js"|media}}'></script>
<script type='text/javascript' src='{{"/js/wmd/showdown.js"|media}}'></script>
diff --git a/askbot/urls.py b/askbot/urls.py
index e869d3b1..a3f694d9 100644
--- a/askbot/urls.py
+++ b/askbot/urls.py
@@ -212,6 +212,11 @@ urlpatterns = patterns('',
views.commands.delete_group_logo,
name = 'delete_group_logo'
),
+ url(#ajax only
+ r'^toggle-group-email-moderation/',
+ views.commands.toggle_group_email_moderation,
+ name = 'toggle_group_email_moderation'
+ ),
url(
r'^get-groups-list/',
views.commands.get_groups_list,
diff --git a/askbot/utils/mail.py b/askbot/utils/mail.py
index 2d4d80b0..37245b5a 100644
--- a/askbot/utils/mail.py
+++ b/askbot/utils/mail.py
@@ -283,7 +283,8 @@ def process_emailed_question(from_address, subject, parts, tags = None):
title = title,
tags = tagnames,
body_text = body_text,
- by_email = True
+ by_email = True,
+ email_address = from_address
)
else:
raise ValidationError()
diff --git a/askbot/views/commands.py b/askbot/views/commands.py
index efb50974..7eeccabe 100644
--- a/askbot/views/commands.py
+++ b/askbot/views/commands.py
@@ -809,6 +809,24 @@ def delete_post_reject_reason(request):
@decorators.ajax_only
@decorators.post_only
@decorators.admins_only
+def toggle_group_email_moderation(request):
+ from django.forms import IntegerField
+ group_id = IntegerField().clean(int(request.POST['group_id']))
+ group = models.Tag.group_tags.get(id = group_id)
+ group.group_profile.moderate_email = not group.group_profile.moderate_email
+ group.group_profile.save()
+ if group.group_profile.moderate_email:
+ new_button_text = _('moderate emailed questions')
+ else:
+ new_button_text = _('disable moderation of emailed questions')
+ return {'new_button_text': new_button_text}
+
+
+
+@csrf.csrf_exempt
+@decorators.ajax_only
+@decorators.post_only
+@decorators.admins_only
def save_post_reject_reason(request):
"""saves post reject reason and returns the reason id
if reason_id is not given in the input - a new reason is created,
diff --git a/askbot/views/users.py b/askbot/views/users.py
index b6e7d5f7..4c83a351 100644
--- a/askbot/views/users.py
+++ b/askbot/views/users.py
@@ -59,6 +59,7 @@ def users(request, by_group = False, group_id = None, group_slug = None):
"""Users view, including listing of users by group"""
users = models.User.objects.all()
group = None
+ group_email_moderation_enabled = False
if by_group == True:
if askbot_settings.GROUPS_ENABLED == False:
raise Http404
@@ -68,6 +69,11 @@ def users(request, by_group = False, group_id = None, group_slug = None):
else:
try:
group = models.Tag.group_tags.get(id = group_id)
+ group_email_moderation_enabled = \
+ (
+ askbot_settings.GROUP_EMAIL_ADDRESSES_ENABLED \
+ and askbot_settings.ENABLE_CONTENT_MODERATION
+ )
except models.Tag.DoesNotExist:
raise Http404
if group_slug == slugify(group.name):
@@ -149,7 +155,8 @@ def users(request, by_group = False, group_id = None, group_slug = None):
'suser' : suser,
'keywords' : suser,
'tab_id' : sortby,
- 'paginator_context' : paginator_context
+ 'paginator_context' : paginator_context,
+ 'group_email_moderation_enabled': group_email_moderation_enabled
}
return render_into_skin('users.html', data, request)