from django.utils.translation import ugettext as _\r
from forum.models.action import ActionProxy\r
from forum.models import Comment, Question, Answer, NodeRevision\r
+import logging\r
\r
class NodeEditAction(ActionProxy):\r
def create_revision_data(self, initial=False, **data):\r
def process_data(self, title):\r
self.node.node_type = "question"\r
self.node.title = title\r
+ self.node.active_revision.title = title\r
+ self.node.active_revision.save()\r
self.node.last_edited = self\r
self.node.update_last_activity(self.user, save=True)\r
\r
'app_name': APP_SHORT_NAME,
}
+class EmailValidationAction(ActionProxy):
+ verb = _("validated e-mail")
+
+ def repute_users(self):
+ self.repute(self.user, int(settings.REP_GAIN_BY_EMAIL_VALIDATION))
+
+ def process_action(self):
+ self.user.email_isvalid = True
+ self.user.save()
+
+ def describe(self, viewer=None):
+ return _("%(user)s %(have_has)s validated the e-mail %(email)s") % {
+ 'user': self.hyperlink(self.user.get_profile_url(), self.friendly_username(viewer, self.user)),
+ 'have_has': self.viewer_or_user_verb(viewer, self.user, _('have'), _('has')),
+ 'email' : self.user.email
+ }
+
class EditProfileAction(ActionProxy):
verb = _("edited profile")
def __init__(self, *args, **kwargs):
super(TitleField, self).__init__(*args, **kwargs)
self.required = True
- self.widget = forms.TextInput(attrs={'size' : 70, 'autocomplete' : 'off'})
self.max_length = 255
+ self.widget = forms.TextInput(attrs={'size' : 70, 'autocomplete' : 'off', 'maxlength' : self.max_length})
self.label = _('title')
self.help_text = _('please enter a descriptive title for your question')
self.initial = ''
--- /dev/null
+from django.core.management.base import BaseCommand, CommandError
+from forum.models import Node, NodeRevision
+
+import logging
+
+# Used to activate the latest revision connected to some node
+def activate_latest_revision(node):
+ # We're adding a new try-except block just in case that function has been called incorrectly.
+ try:
+ # The latest revision is the one that was added the last.
+ rev = node.revisions.all().order_by('-pk')[0]
+ node.active_revision_id = rev.id
+ node.save()
+
+ return rev
+ except:
+ logging.error("Incorrect attempt to activate the latest revision of a node \
+ that has no revisions at all has been made.")
+ return None
+
+# Used to create a new NodeRevision object according to the node content
+def create_revision(node):
+ rev = NodeRevision(
+ author_id = node.author_id,
+ body = node.body,
+ node_id = node.id,
+ revised_at = node.added_at,
+ revision = 1,
+ summary = 'Initial revision',
+ tagnames = node.tagnames,
+ title = node.title,
+ )
+
+ node.save()
+
+ return node
+
+class Command(BaseCommand):
+
+ def handle(self,*args, **options):
+ print 'Running MaintainDb'
+
+ nodes = Node.objects.all()
+
+ for node in nodes:
+ if node.active_revision is None:
+ print "Node #%(node_id)d: NodeRevision doesn't exist" % dict(node_id=node.id)
+
+ # We currently don't have any active revision for this Node. Let's check if there are any revisions
+ # at all for it. If there are any we activate the last.
+ if node.revisions.all().count() > 0:
+ print " We have revisions for Node #%(node_id)d." % dict(node_id=node.id)
+
+ # If there are already some revisions connected to the current node, we activate the latest
+ activate_latest_revision(node)
+ else:
+ print " We don't have revisions for Node #%(node_id)d. We're "\
+ "going to create a new one from the current node content."% dict(node_id=node.id)
+
+ # First of all we're going to create a new revision according to the current node data...
+ create_revision(node)
+
+ # ...and after that we're going to activate it
+ activate_latest_revision(node)
+
+ #print rev.node
--- /dev/null
+from forum.user_messages import create_message
+from django.utils.translation import ugettext as _
+from django.core.urlresolvers import reverse
+from django.core.exceptions import ObjectDoesNotExist
+
+from forum.settings import EMAIL_HOST, EMAIL_HOST_USER, EMAIL_HOST_PASSWORD, \
+ APP_URL
+
+class AdminMessagesMiddleware(object):
+ def process_request(self, request):
+ # Check if the email settings are configured
+ self.check_email_settings(request)
+
+ # Check if the APP_URL setting is configured
+ self.check_app_url(request)
+
+ def check_email_settings(self, request):
+ # We want to warn only the administrators that the email settings are not configured.
+ # So, first of all we check if we're dealing with the administrators and after that if
+ # the SMTP settings are configured at all. We suppose that the SMTP settings are not configured
+ # if the EMAIL_HOST, the EMAIL_HOST_USER and the EMAIL_HOST_PASSWORD are not set at all.
+ if request.user.is_authenticated and request.user.is_staff and request.user.is_superuser and \
+ EMAIL_HOST == '' and EMAIL_HOST_USER == '' and EMAIL_HOST_PASSWORD == '':
+
+ msg = _("""
+ The e-mail settings of this community are not configured yet. We strongly recommend you to
+ do that from the <a href="%(email_settings_url)s">e-mail settings page</a> as soon as possible.
+ """ % dict(email_settings_url=reverse('admin_set', kwargs={'set_name':'email'})))
+
+ # We do not want to repeat ourselves. If the message already exists in the message list, we're not going to
+ # add it. That's why first of all we're going the check if it is there.
+ try:
+ # If the message doesn't exist in the RelatedManager ObjectsDoesNotExist is going to be raised.
+ request.user.message_set.all().get(message=msg)
+ except ObjectDoesNotExist:
+ # Let's create the message.
+ request.user.message_set.create(message=msg)
+ except:
+ pass
+
+ def check_app_url(self, request):
+ # We consider the APP_URL setting not configured if it contains only the protocol
+ # name or if it's shorter than 7 characters.
+ if request.user.is_authenticated and request.user.is_staff and request.user.is_superuser and \
+ APP_URL == 'http://' or APP_URL == 'https://' or len(APP_URL) < 7:
+
+ msg = _("""
+ Please, configure your APP_URL setting from the local settings file.
+ """)
+
+ # We do not want to repeat ourselves. If the message already exists in the message list, we're not going to
+ # add it. That's why first of all we're going the check if it is there.
+ try:
+ # If the message doesn't exist in the RelatedManager ObjectsDoesNotExist is going to be raised.
+ request.user.message_set.all().get(message=msg)
+ except ObjectDoesNotExist:
+ # Let's create the message.
+ request.user.message_set.create(message=msg)
+ except:
+ pass
--- /dev/null
+# encoding: utf-8
+import datetime
+from south.db import db
+from south.v2 import SchemaMigration
+from django.db import models
+
+class Migration(SchemaMigration):
+
+ def forwards(self, orm):
+ # Adding field 'Tag.created_at'
+ db.add_column('forum_tag', 'created_at', self.gf('django.db.models.fields.DateTimeField')(default=datetime.datetime.now, null=True, blank=True), keep_default=False)
+
+
+ def backwards(self, orm):
+ # Deleting field 'Tag.created_at'
+ db.delete_column('forum_tag', 'created_at')
+
+
+ models = {
+ 'auth.group': {
+ 'Meta': {'object_name': 'Group'},
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '80'}),
+ 'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'blank': 'True'})
+ },
+ 'auth.permission': {
+ 'Meta': {'ordering': "('content_type__app_label', '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']", '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']", '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': '16'}),
+ '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': '16'}),
+ 'extra': ('forum.models.utils.PickledObjectField', [], {'null': 'True'}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'ip': ('django.db.models.fields.CharField', [], {'max_length': '16'}),
+ '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'", 'through': "'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.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'", '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, 3, 3, 18, 19, 21, 244056)'}),
+ '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_answered': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
+ 'questions_asked': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
+ 'questions_commented': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
+ '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'", 'through': "'MarkedTag'", 'to': "orm['forum.User']"}),
+ 'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '255'}),
+ 'used_count': ('django.db.models.fields.PositiveIntegerField', [], {'default': '0'})
+ },
+ 'forum.user': {
+ 'Meta': {'object_name': 'User', '_ormbases': ['auth.User']},
+ 'about': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
+ 'bronze': ('django.db.models.fields.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.PositiveIntegerField', [], {'default': '0'}),
+ 'silver': ('django.db.models.fields.PositiveIntegerField', [], {'default': '0'}),
+ 'subscriptions': ('django.db.models.fields.related.ManyToManyField', [], {'related_name': "'subscribers'", 'through': "'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, 3, 4, 18, 19, 21, 460663)'}),
+ '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']
--- /dev/null
+# encoding: utf-8
+import datetime
+from south.db import db
+from south.v2 import DataMigration
+from django.db import models
+from forum.models import Tag, Question
+from urllib import unquote
+
+class Migration(DataMigration):
+
+ def forwards(self, orm):
+ for tag in Tag.objects.all():
+ try:
+ question = Question.objects.filter(tags__name=unquote(tag.name)).order_by('pk')[0]
+ date = question.added_at
+ tag.created_at = date
+ tag.save()
+ print str(date)
+ except:
+ pass
+
+
+ def backwards(self, orm):
+ "Write your backwards methods here."
+
+
+ models = {
+ 'auth.group': {
+ 'Meta': {'object_name': 'Group'},
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '80'}),
+ 'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'blank': 'True'})
+ },
+ 'auth.permission': {
+ 'Meta': {'ordering': "('content_type__app_label', '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']", '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']", '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': '16'}),
+ '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': '16'}),
+ 'extra': ('forum.models.utils.PickledObjectField', [], {'null': 'True'}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'ip': ('django.db.models.fields.CharField', [], {'max_length': '16'}),
+ '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'", 'through': "'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.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'", '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, 3, 3, 19, 8, 39, 301998)'}),
+ '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_answered': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
+ 'questions_asked': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
+ 'questions_commented': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
+ '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'", 'through': "'MarkedTag'", 'to': "orm['forum.User']"}),
+ 'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '255'}),
+ 'used_count': ('django.db.models.fields.PositiveIntegerField', [], {'default': '0'})
+ },
+ 'forum.user': {
+ 'Meta': {'object_name': 'User', '_ormbases': ['auth.User']},
+ 'about': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
+ 'bronze': ('django.db.models.fields.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.PositiveIntegerField', [], {'default': '0'}),
+ 'silver': ('django.db.models.fields.PositiveIntegerField', [], {'default': '0'}),
+ 'subscriptions': ('django.db.models.fields.related.ManyToManyField', [], {'related_name': "'subscribers'", 'through': "'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, 3, 4, 19, 8, 39, 353678)'}),
+ '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']
+
from django.utils.safestring import mark_safe
from django.utils.html import strip_tags
from forum.utils.html import sanitize_html
+from forum.settings import SUMMARY_LENGTH
from utils import PickledObjectField
class NodeContent(models.Model):
@property
def summary(self):
- return strip_tags(self.html)[:300]
+ return strip_tags(self.html)[:SUMMARY_LENGTH]
@models.permalink
def get_revisions_url(self):
+import datetime
from base import *
from django.utils.translation import ugettext as _
class Tag(BaseModel):
name = models.CharField(max_length=255, unique=True)
created_by = models.ForeignKey(User, related_name='created_tags')
+ created_at = models.DateTimeField(default=datetime.datetime.now, blank=True, null=True)
marked_by = models.ManyToManyField(User, related_name="marked_tags", through="MarkedTag")
# Denormalised data
used_count = models.PositiveIntegerField(default=0)
app_label = 'forum'
def __unicode__(self):
- return self.name
+ return u'%s' % self.name
def add_to_usage_count(self, value):
if self.used_count + value < 0:
from django.utils.translation import ugettext_lazy as _\r
from django.forms.widgets import PasswordInput\r
from django.forms.widgets import RadioSelect\r
+from forms import TestEmailSettingsWidget\r
\r
EMAIL_SET = SettingSet('email', _('Email settings'), _("Email server and other email related settings."), 50)\r
\r
help_text = _("Choose what should be the default email subscription status while registering."),\r
required=False))\r
\r
+TEST_EMAIL_SETTINGS = Setting('TEST_EMAIL_SETTINGS', '', EMAIL_SET, dict(\r
+label = _("E-Mail settings test"),\r
+help_text = _("Test the current E-Mail configuration."),\r
+required=False,\r
+widget=TestEmailSettingsWidget))\r
+\r
EMAIL_HOST = Setting('EMAIL_HOST', '', EMAIL_SET, dict(\r
label = _("Email Server"),\r
help_text = _("The SMTP server through which your application will be sending emails."),\r
from forum.settings.base import Setting
from django.utils.translation import ugettext as _
from django.core.files.storage import FileSystemStorage
+from django.core.urlresolvers import reverse
class DummySetting:
pass
else:
return ', '.join(data[name])
+class TestEmailSettingsWidget(forms.TextInput):
+ def render(self, name, value, attrs=None):
+ if not value:
+ value = ''
-
-
-
+ return """
+ <div id="test_email_settings">
+ <a href="%s" onclick="return false;" class="button test_button" href="/">Test</a>
+
+ <div style="margin-top: 7px">
+ <div style="display: none" class="ajax_indicator">
+ Testing your current e-mail settings. Please, wait.
+ </div>
+ <div class="test_status"></div>
+ </div>
+ </div>
+ """ % reverse("test_email_settings")
\ No newline at end of file
label = "Max rep by up votes / day",\r
help_text = _("Maximum reputation a user can gain in one day for being upvoted.")))\r
\r
+REP_GAIN_BY_EMAIL_VALIDATION = Setting('REP_GAIN_BY_EMAIL_VALIDATION', 10, REP_GAIN_SET, dict(\r
+label = _("Rep gain by e-mail validation"),\r
+help_text = _("Reputation a user gains for validating his e-mail.")))\r
+\r
REP_GAIN_BY_UPVOTED = Setting('REP_GAIN_BY_UPVOTED', 10, REP_GAIN_SET, dict(\r
label = _("Rep gain by upvoted"),\r
help_text = _("Reputation a user gains for having one of his posts up voted.")))\r
""" view settings """
VIEW_SET = SettingSet('view', _('View settings'), _("Set up how certain parts of the site are displayed."), 20)
+SUMMARY_LENGTH = Setting('SUMMARY_LENGTH', 300, VIEW_SET, dict(
+label = _("Summary Length"),
+help_text = _("The number of characters that are going to be displayed in order to get the content summary.")))
+
RECENT_TAGS_SIZE = Setting('RECENT_TAGS_SIZE', 25, VIEW_SET, dict(
label = _("Recent tags block size"),
help_text = _("The number of tags to display in the recent tags block in the front page.")))
$input.keyup(rewrite_anchor);\r
rewrite_anchor(); \r
});\r
+\r
+ $('#test_email_settings a.test_button').click(function() {\r
+ $('div.test_status').hide('slow')\r
+ $('div.ajax_indicator').show('fast')\r
+ $.post($(this).attr('href'), function(data) {\r
+ $('div.ajax_indicator').hide('fast')\r
+ $('div.test_status').html(data)\r
+ $('div.test_status').show('slow')\r
+ })\r
+ })\r
});\r
\r
/*\r
* Autocomplete - jQuery plugin 1.0.3\r
*\r
- * Copyright (c) 2007 Dylan Verheul, Dan G. Switzer, Anjesh Tuladhar, Jörn Zaefferer\r
+ * Copyright (c) 2007 Dylan Verheul, Dan G. Switzer, Anjesh Tuladhar, J�rn Zaefferer\r
*\r
* Dual licensed under the MIT and GPL licenses:\r
* http://www.opensource.org/licenses/mit-license.php\r
background-color: #ffffe0;
border: 3px double #b8860b;
padding: 4px;
+}
+
+.ajax_indicator {
+ background: transparent url('../images/indicator.gif') top left no-repeat;
+ padding: 7px 25px;
+ min-height: 24px;
}
\ No newline at end of file
<p style="line-height:12px;">\r
<strong>{% diff_date revision.revised_at %}</strong>\r
</p>\r
- {% gravatar revision.author 32 %}\r
- <p><a href="{{ revised_at.author.get_profile_url }}">{{ revision.author.username }}</a><br/>\r
+ <a href="{{ revision.author.get_profile_url }}">{% gravatar revision.author 32 %}</a>\r
+ <p><a href="{{ revision.author.get_profile_url }}">{{ revision.author.username }}</a><br/>\r
{% get_score_badge revision.author %}</p>\r
</div>
\ No newline at end of file
--- /dev/null
+{% load i18n extra_tags email_tags %}
+
+{% declare %}
+ prefix = settings.EMAIL_SUBJECT_PREFIX
+ app_name = settings.APP_SHORT_NAME
+
+ exclude_finetune = True
+{% enddeclare %}
+
+{% email %}
+ {% subject %}{% blocktrans %}{{ prefix }} Your email settings are correct: {{ app_name }}{% endblocktrans %}{% endsubject %}
+
+ {% htmlcontent notifications/base.html %}
+ {% trans "If you see this content your E-Mail settings are correct." %}
+ {% endhtmlcontent %}
+
+{% textcontent notifications/base_text.html %}
+ {% trans "If you see this content your E-Mail settings are correct." %}
+{% endtextcontent %}
+
+{% endemail %}
+
--- /dev/null
+{% load i18n %}
+
+<p>
+ {% blocktrans %}
+ An attempt has been made to send email to
+ {% endblocktrans %} {{ user.email }}.
+</p>
+
+<p>
+ {% blocktrans %}
+ Please, check your inbox and if you see the new test message your email STMP settings are correct.
+ {% endblocktrans %}
+</p>
+
+<p>
+ {% blocktrans %}
+ If you do not see the new test message check your spam folder, and if you don't find it check your SMTP settings
+ again. It might be useful to take a look at the log file.
+ {% endblocktrans %}
+</p>
\ No newline at end of file
url(r'^%s%s(?P<set_name>\w+)/$' % (_('admin/'), _('settings/')), app.admin.settings_set,
name="admin_set"),
+ url(r'%s%s' % (_('admin/'), _('test_email_settings/')), app.admin.test_email_settings,
+ name="test_email_settings"),
+
url(r'^feeds/rss[/]?$', app.readers.feed, name="latest_questions_feed"),
url(r'^(?P<path>.+)$', app.meta.page, name="static_page"),
from forum.forms import MaintenanceModeForm, PageForm, CreateUserForm
from forum.settings.forms import SettingsSetForm
from forum.utils import pagination, html
+from forum.utils.mail import send_template_email
from forum.models import Question, Answer, User, Node, Action, Page, NodeState, Tag
from forum.models.node import NodeMetaClass
'hide_menu': True
}))
+@super_user_required
+def test_email_settings(request):
+ user = request.user
+ send_template_email([user,], 'osqaadmin/mail_test.html', { 'user' : user })
-
-
+ return render_to_response(
+ 'osqaadmin/test_email_settings.html',
+ { 'user': user, },
+ RequestContext(request)
+ )
\ No newline at end of file
from forum.authentication import AUTH_PROVIDERS
from forum.models import AuthKeyUserAssociation, ValidationHash, Question, Answer
-from forum.actions import UserJoinsAction
+from forum.actions import UserJoinsAction, EmailValidationAction
+from forum.models.action import ActionRepute
+
+from forum.settings import REP_GAIN_BY_EMAIL_VALIDATION
def signin_page(request):
referer = request.META.get('HTTP_REFERER', '/')
user = get_object_or_404(User, id=user)
if (ValidationHash.objects.validate(code, user, 'email', [user.email])):
- user.email_isvalid = True
- user.save()
- return login_and_forward(request, user, reverse('index'), _("Thank you, your email is now validated."))
+ EmailValidationAction(user=user, ip=request.META['REMOTE_ADDR']).save()
+ if REP_GAIN_BY_EMAIL_VALIDATION > 0:
+ message = _("Thank you, your email is now validated and you've got %d points." % int(REP_GAIN_BY_EMAIL_VALIDATION))
+
+ else:
+ message = _("Thank you, your email is now validated.")
+
+ return login_and_forward(request, user, reverse('index'), message)
else:
return render_to_response('auth/mail_already_validated.html', { 'user' : user }, RequestContext(request))
from django.shortcuts import render_to_response, get_object_or_404
from django.http import HttpResponseRedirect, HttpResponse, Http404, HttpResponsePermanentRedirect
from django.core.paginator import Paginator, EmptyPage, InvalidPage
+from django.core.exceptions import ObjectDoesNotExist
from django.template import RequestContext
from django import template
from django.utils.html import *
@decorators.render('questions.html')
def tag(request, tag):
+ questions = Question.objects.filter(tags__name=unquote(tag))
+
+ if not questions:
+ raise Http404
+
return question_list(request,
- Question.objects.filter(tags__name=unquote(tag)),
+ questions,
mark_safe(_('questions tagged <span class="tag">%(tag)s</span>') % {'tag': tag}),
None,
mark_safe(_('Questions Tagged With %(tag)s') % {'tag': tag}),
post.save()
all.append(int(post.id))
+ create_and_activate_revision(post)
del post
action_date = oc.added_at
)
+ create_and_activate_revision(oc)
+
create_action.save()
oc.save()
tags = [tag for tag in [tagmap.get(name.strip()) for name in post.tagnames.split(u' ') if name] if tag]
post.tagnames = " ".join([t.name for t in tags]).strip()
post.tags = tags
- create_and_activate_revision(post)
def create_and_activate_revision(post):
author_id = 1
)
+ create_and_activate_revision(page)
+
page.save()
registry[sxp['url'][1:]] = page.id
'forum.middleware.anon_user.ConnectToSessionMessagesMiddleware',
'forum.middleware.request_utils.RequestUtils',
'forum.middleware.cancel.CancelActionMiddleware',
+ 'forum.middleware.admin_messages.AdminMessagesMiddleware',
#'recaptcha_django.middleware.ReCaptchaMiddleware',
'django.middleware.transaction.TransactionMiddleware',
]