--- /dev/null
+# -*- coding: utf-8 -*-\r
+\r
+from xml.dom import minidom\r
+from datetime import datetime\r
+import time\r
+import re\r
+from django.utils.translation import ugettext as _\r
+from django.template.defaultfilters import slugify\r
+from orm import orm\r
+\r
+def getText(el):\r
+ rc = ""\r
+ for node in el.childNodes:\r
+ if node.nodeType == node.TEXT_NODE:\r
+ rc = rc + node.data\r
+ return rc.strip()\r
+\r
+msstrip = re.compile(r'^(.*)\.\d+')\r
+def readTime(ts):\r
+ noms = msstrip.match(ts)\r
+ if noms:\r
+ ts = noms.group(1)\r
+\r
+ return datetime(*time.strptime(ts, '%Y-%m-%dT%H:%M:%S')[0:6])\r
+\r
+def readEl(el):\r
+ return dict([(n.tagName.lower(), getText(n)) for n in el.childNodes if n.nodeType == el.ELEMENT_NODE])\r
+\r
+def readTable(dump, name):\r
+ return [readEl(e) for e in minidom.parseString(dump.read("%s.xml" % name)).getElementsByTagName('row')]\r
+\r
+class UnknownUser(object):\r
+ counter = 0\r
+ def __init__(self):\r
+ UnknownUser.counter += 1\r
+ self.number = UnknownUser.counter\r
+\r
+ def __str__(self):\r
+ return _("Unknown user %(number)d") % {'number': self.number}\r
+\r
+ def __unicode__(self):\r
+ return self.__str__()\r
+\r
+ def encode(self, *args):\r
+ return self.__str__()\r
+\r
+class IdMapper(dict):\r
+ def __getitem__(self, key):\r
+ key = int(key)\r
+ return super(IdMapper, self).get(key, key)\r
+\r
+ def __setitem__(self, key, value):\r
+ super(IdMapper, self).__setitem__(int(key), int(value))\r
+\r
+openidre = re.compile('^https?\:\/\/')\r
+def userimport(dump, options):\r
+ users = readTable(dump, "Users")\r
+\r
+ user_by_name = {}\r
+ uidmapper = IdMapper()\r
+ merged_users = []\r
+\r
+ owneruid = options.get('owneruid', None)\r
+ #check for empty values\r
+ if not owneruid:\r
+ owneruid = None\r
+\r
+ for sxu in users:\r
+ create = True\r
+\r
+ if sxu.get('id') == '-1':\r
+ continue\r
+\r
+ if int(sxu.get('id')) == int(owneruid):\r
+ osqau = orm.User.objects.get(id=1)\r
+ uidmapper[owneruid] = 1\r
+ uidmapper[-1] = 1\r
+ create = False\r
+ else:\r
+ username = sxu.get('displayname', sxu.get('displaynamecleaned', sxu.get('realname', UnknownUser())))\r
+\r
+ if not isinstance(username, UnknownUser) and username in user_by_name:\r
+ if options.get('mergesimilar', False) and sxu.get('email', 'INVALID') == user_by_name[username].email:\r
+ osqau = user_by_name[username]\r
+ create = False\r
+ uidmapper[sxu.get('id')] = osqau.id\r
+ else:\r
+ inc = 1\r
+ while ("%s %d" % (username, inc)) in user_by_name:\r
+ inc += 1\r
+\r
+ username = "%s %d" % (username, inc)\r
+\r
+ sxbadges = sxu.get('badgesummary', None)\r
+ badges = {'1':'0','2':'0','3':'0'}\r
+\r
+ if sxbadges:\r
+ badges.update(dict([b.split('=') for b in sxbadges.split()]))\r
+\r
+ if create:\r
+ osqau = orm.User(\r
+ id = sxu.get('id'),\r
+ username = unicode(username),\r
+ password = '!',\r
+ email = sxu.get('email', ''),\r
+ is_superuser = sxu.get('usertypeid') == '5',\r
+ is_staff = sxu.get('usertypeid') == '4',\r
+ is_active = True,\r
+ date_joined = readTime(sxu.get('creationdate')),\r
+ about = sxu.get('aboutme', ''),\r
+ date_of_birth = sxu.get('birthday', None) and readTime(sxu['birthday']) or None,\r
+ email_isvalid = int(sxu.get('usertypeid')) > 2,\r
+ website = sxu.get('websiteurl', ''),\r
+ reputation = int(sxu.get('reputation')),\r
+ gold = int(badges['1']),\r
+ silver = int(badges['2']),\r
+ bronze = int(badges['3']),\r
+ real_name = sxu.get('realname', ''),\r
+ )\r
+\r
+ osqau.save()\r
+\r
+ s = orm.SubscriptionSettings(user=osqau)\r
+ s.save()\r
+\r
+ user_by_name[osqau.username] = osqau\r
+ else:\r
+ new_about = sxu.get('aboutme', None)\r
+ if new_about and osqau.about != new_about:\r
+ if osqau.about:\r
+ osqau.about = "%s\n|\n%s" % (osqau.about, new_about)\r
+ else:\r
+ osqau.about = new_about\r
+\r
+ osqau.username = sxu.get('displayname', sxu.get('displaynamecleaned', sxu.get('realname', UnknownUser())))\r
+ osqau.email = sxu.get('email', '')\r
+ osqau.reputation += int(sxu.get('reputation'))\r
+ osqau.gold += int(badges['1'])\r
+ osqau.silver += int(badges['2'])\r
+ osqau.bronze += int(badges['3'])\r
+\r
+ merged_users.append(osqau.id)\r
+ osqau.save()\r
+\r
+\r
+ openid = sxu.get('openid', None)\r
+ if openid and openidre.match(openid):\r
+ assoc = orm.AuthKeyUserAssociation(user=osqau, key=openid, provider="openidurl")\r
+ assoc.save()\r
+\r
+ if uidmapper[-1] == -1:\r
+ uidmapper[-1] = 1\r
+\r
+ return (uidmapper, merged_users)\r
+\r
+def tagsimport(dump, uidmap):\r
+ tags = readTable(dump, "Tags")\r
+\r
+ tagmap = {}\r
+\r
+ for sxtag in tags:\r
+ otag = orm.Tag(\r
+ id = int(sxtag['id']),\r
+ name = sxtag['name'],\r
+ used_count = int(sxtag['count']),\r
+ created_by_id = uidmap[sxtag['userid']],\r
+ )\r
+ otag.save()\r
+\r
+ tagmap[otag.name] = otag\r
+\r
+ return tagmap\r
+\r
+def postimport(dump, uidmap, tagmap):\r
+ history = {}\r
+ all = {}\r
+\r
+ for h in readTable(dump, "PostHistory"):\r
+ if not history.get(h.get('postid'), None):\r
+ history[h.get('postid')] = []\r
+\r
+ history[h.get('postid')].append(h)\r
+\r
+ posts = readTable(dump, "Posts")\r
+\r
+ for sxpost in posts:\r
+ accepted = {}\r
+\r
+ postclass = sxpost.get('posttypeid') == '1' and orm.Question or orm.Answer\r
+\r
+ post = postclass(\r
+ id = sxpost['id'],\r
+ added_at = readTime(sxpost['creationdate']),\r
+ body = sxpost['body'],\r
+ score = sxpost.get('score', 0),\r
+ vote_up_count = 0,\r
+ vote_down_count = 0\r
+ )\r
+\r
+ if sxpost.get('deletiondate', None):\r
+ post.deleted = True\r
+ post.deleted_at = readTime(sxpost['deletiondate'])\r
+ post.author_id = 1\r
+ else:\r
+ post.author_id = uidmap[sxpost['owneruserid']]\r
+\r
+ if sxpost.get('lasteditoruserid', None):\r
+ post.last_edited_by_id = uidmap[sxpost.get('lasteditoruserid')]\r
+ post.last_edited_at = readTime(sxpost['lasteditdate'])\r
+\r
+ if sxpost.get('communityowneddate', None):\r
+ post.wiki = True\r
+ post.wikified_at = readTime(sxpost['communityowneddate'])\r
+\r
+ if sxpost.get('posttypeid') == '1': #question\r
+ post.node_type = "question"\r
+ post.title = sxpost['title']\r
+\r
+ tagnames = sxpost['tags'].replace(u'ö', '-').replace(u'é', '').replace(u'à', '')\r
+ post.tagnames = tagnames\r
+\r
+ post.view_count = sxpost.get('viewcount', 0)\r
+ post.favourite_count = sxpost.get('favoritecount', 0)\r
+ post.answer_count = sxpost.get('answercount', 0)\r
+\r
+ if sxpost.get('lastactivityuserid', None):\r
+ post.last_activity_by_id = uidmap[sxpost['lastactivityuserid']]\r
+ post.last_activity_at = readTime(sxpost['lastactivitydate'])\r
+\r
+ if sxpost.get('closeddate', None):\r
+ post.closed = True\r
+ post.closed_by_id = 1\r
+ post.closed_at = datetime.now()\r
+\r
+ if sxpost.get('acceptedanswerid', None):\r
+ accepted[int(sxpost.get('acceptedanswerid'))] = post\r
+\r
+ else:\r
+ post.node_type = "answer"\r
+ post.parent_id = sxpost['parentid']\r
+\r
+ if int(post.id) in accepted:\r
+ question = accepted[int(post.id)]\r
+ question.accepted_answer_id = post\r
+ question.save()\r
+\r
+ post.accepted = True\r
+ post.accepted_at = datetime.now()\r
+ post.accepted_by_id = question.author_id\r
+\r
+ all[int(post.id)] = post\r
+\r
+ return all\r
+\r
+def comment_import(dump, uidmap, posts):\r
+ comments = readTable(dump, "PostComments")\r
+ currid = max(posts.keys())\r
+ mapping = {}\r
+\r
+ for sxc in comments:\r
+ currid += 1\r
+ oc = orm.Node(\r
+ id = currid,\r
+ node_type = "comment",\r
+ added_at = readTime(sxc['creationdate']),\r
+ author_id = uidmap[sxc['userid']],\r
+ body = sxc['text'],\r
+ parent_id = sxc.get('postid'),\r
+ vote_up_count = 0,\r
+ vote_down_count = 0\r
+ )\r
+\r
+ if sxc.get('deletiondate', None):\r
+ oc.deleted = True\r
+ oc.deleted_at = readTime(sxc['deletiondate'])\r
+ oc.deleted_by_id = uidmap[sxc['deletionuserid']]\r
+ oc.author_id = uidmap[sxc['deletionuserid']]\r
+ else:\r
+ oc.author_id = uidmap[sxc['userid']]\r
+\r
+\r
+ posts[oc.id] = oc\r
+ mapping[int(sxc['id'])] = int(oc.id)\r
+\r
+ return posts, mapping\r
+\r
+\r
+def save_posts(posts, tagmap):\r
+ for post in posts.values():\r
+ post.save()\r
+\r
+ if post.node_type == "question":\r
+ tags = filter(lambda t: t is not None, [tagmap.get(n, None) for n in post.tagnames.split()])\r
+ post.tagnames = " ".join([t.name for t in tags]).strip()\r
+ post.tags = tags\r
+\r
+ create_and_activate_revision(post)\r
+\r
+\r
+def create_and_activate_revision(post):\r
+ rev = orm.NodeRevision(\r
+ author_id = post.author_id,\r
+ body = post.body,\r
+ node_id = post.id,\r
+ revised_at = post.added_at,\r
+ revision = 1,\r
+ summary = 'Initial revision',\r
+ tagnames = post.tagnames,\r
+ title = post.title,\r
+ )\r
+\r
+ rev.save()\r
+ post.active_revision_id = rev.id\r
+ post.save()\r
+\r
+\r
+def post_vote_import(dump, uidmap, posts):\r
+ votes = readTable(dump, "Posts2Votes")\r
+\r
+ for sxv in votes:\r
+ if sxv['votetypeid'] in ('2', '3'):\r
+ ov = orm.Vote(\r
+ node_id = sxv['postid'],\r
+ user_id = uidmap[sxv['userid']],\r
+ voted_at = readTime(sxv['creationdate']),\r
+ vote = sxv['votetypeid'] == '2' and 1 or -1,\r
+ )\r
+\r
+ if sxv['votetypeid'] == '2':\r
+ posts[int(sxv['postid'])].vote_up_count += 1\r
+ else:\r
+ posts[int(sxv['postid'])].vote_down_count += 1\r
+\r
+ ov.save()\r
+\r
+def comment_vote_import(dump, uidmap, comments, posts):\r
+ votes = readTable(dump, "Comments2Votes")\r
+\r
+ for sxv in votes:\r
+ if sxv['votetypeid'] in ('2', '3'):\r
+ ov = orm.Vote(\r
+ node_id = comments[int(sxv['postcommentid'])],\r
+ user_id = uidmap[sxv['userid']],\r
+ voted_at = readTime(sxv['creationdate']),\r
+ vote = sxv['votetypeid'] == '2' and 1 or -1,\r
+ )\r
+\r
+ if sxv['votetypeid'] == '2':\r
+ posts[comments[int(sxv['postcommentid'])]].vote_up_count += 1\r
+ else:\r
+ posts[comments[int(sxv['postcommentid'])]].vote_down_count += 1\r
+\r
+ ov.save()\r
+\r
+\r
+\r
+def badges_import(dump, uidmap):\r
+ node_ctype = orm['contenttypes.contenttype'].objects.get(name='node')\r
+ obadges = dict([(b.slug, b) for b in orm.Badge.objects.all()])\r
+ sxbadges = dict([(int(b['id']), b) for b in readTable(dump, "Badges")])\r
+\r
+ sx_to_osqa = {}\r
+\r
+ for id, sxb in sxbadges.items():\r
+ slug = slugify(sxb['name'].replace('&', 'and'))\r
+ if slug in obadges:\r
+ sx_to_osqa[id] = obadges[slug]\r
+ else:\r
+ osqab = orm.Badge(\r
+ name = sxb['name'],\r
+ slug = slugify(sxb['name']),\r
+ description = sxb['description'],\r
+ multiple = sxb.get('single', 'false') == 'false',\r
+ awarded_count = 0,\r
+ type = sxb['class'] \r
+ )\r
+ osqab.save()\r
+ sx_to_osqa[id] = osqab\r
+\r
+ sxawards = readTable(dump, "Users2Badges")\r
+ osqaawards = []\r
+\r
+ for sxa in sxawards:\r
+ badge = sx_to_osqa[int(sxa['badgeid'])]\r
+ osqaa = orm.Award(\r
+ user_id = uidmap[sxa['userid']],\r
+ badge = badge,\r
+ content_type = node_ctype,\r
+ object_id = 1\r
+ )\r
+\r
+ osqaawards.append(osqaa)\r
+ badge.awarded_count += 1\r
+\r
+ for b in sx_to_osqa.values():\r
+ b.save()\r
+\r
+ for a in osqaawards:\r
+ a.save()\r
+\r
+\r
+def reset_sequences():\r
+ from south.db import db\r
+ if db.backend_name == "postgres":\r
+ db.start_transaction()\r
+ db.execute_many(PG_SEQUENCE_RESETS)\r
+ db.commit_transaction()\r
+\r
+def sximport(dump, options):\r
+ uidmap, merged_users = userimport(dump, options)\r
+ tagmap = tagsimport(dump, uidmap)\r
+ posts = postimport(dump, uidmap, tagmap)\r
+ posts, comments = comment_import(dump, uidmap, posts)\r
+ save_posts(posts, tagmap)\r
+ post_vote_import(dump, uidmap, posts)\r
+ comment_vote_import(dump, uidmap, comments, posts)\r
+ for post in posts.values():\r
+ post.save()\r
+ badges_import(dump, uidmap)\r
+\r
+ from south.db import db\r
+ db.commit_transaction()\r
+\r
+ reset_sequences()\r
+\r
+ \r
+ \r
+PG_SEQUENCE_RESETS = """\r
+SELECT setval('"auth_user_groups_id_seq"', coalesce(max("id"), 1) + 2, max("id") IS NOT null) FROM "auth_user_groups";\r
+SELECT setval('"auth_user_user_permissions_id_seq"', coalesce(max("id"), 1) + 2, max("id") IS NOT null) FROM "auth_user_user_permissions";\r
+SELECT setval('"activity_id_seq"', coalesce(max("id"), 1) + 2, max("id") IS NOT null) FROM "activity";\r
+SELECT setval('"forum_subscriptionsettings_id_seq"', coalesce(max("id"), 1) + 2, max("id") IS NOT null) FROM "forum_subscriptionsettings";\r
+SELECT setval('"forum_validationhash_id_seq"', coalesce(max("id"), 1) + 2, max("id") IS NOT null) FROM "forum_validationhash";\r
+SELECT setval('"forum_authkeyuserassociation_id_seq"', coalesce(max("id"), 1) + 2, max("id") IS NOT null) FROM "forum_authkeyuserassociation";\r
+SELECT setval('"tag_id_seq"', coalesce(max("id"), 1) + 2, max("id") IS NOT null) FROM "tag";\r
+SELECT setval('"forum_markedtag_id_seq"', coalesce(max("id"), 1) + 2, max("id") IS NOT null) FROM "forum_markedtag";\r
+SELECT setval('"forum_node_id_seq"', coalesce(max("id"), 1) + 2, max("id") IS NOT null) FROM "forum_node";\r
+SELECT setval('"forum_node_tags_id_seq"', coalesce(max("id"), 1) + 2, max("id") IS NOT null) FROM "forum_node_tags";\r
+SELECT setval('"forum_noderevision_id_seq"', coalesce(max("id"), 1) + 2, max("id") IS NOT null) FROM "forum_noderevision";\r
+SELECT setval('"forum_node_tags_id_seq"', coalesce(max("id"), 1) + 2, max("id") IS NOT null) FROM "forum_node_tags";\r
+SELECT setval('"forum_node_tags_id_seq"', coalesce(max("id"), 1) + 2, max("id") IS NOT null) FROM "forum_node_tags";\r
+SELECT setval('"favorite_question_id_seq"', coalesce(max("id"), 1) + 2, max("id") IS NOT null) FROM "favorite_question";\r
+SELECT setval('"forum_questionsubscription_id_seq"', coalesce(max("id"), 1) + 2, max("id") IS NOT null) FROM "forum_questionsubscription";\r
+SELECT setval('"forum_node_tags_id_seq"', coalesce(max("id"), 1) + 2, max("id") IS NOT null) FROM "forum_node_tags";\r
+SELECT setval('"vote_id_seq"', coalesce(max("id"), 1) + 2, max("id") IS NOT null) FROM "vote";\r
+SELECT setval('"flagged_item_id_seq"', coalesce(max("id"), 1) + 2, max("id") IS NOT null) FROM "flagged_item";\r
+SELECT setval('"badge_id_seq"', coalesce(max("id"), 1) + 2, max("id") IS NOT null) FROM "badge";\r
+SELECT setval('"award_id_seq"', coalesce(max("id"), 1) + 2, max("id") IS NOT null) FROM "award";\r
+SELECT setval('"repute_id_seq"', coalesce(max("id"), 1) + 2, max("id") IS NOT null) FROM "repute";\r
+SELECT setval('"forum_node_tags_id_seq"', coalesce(max("id"), 1) + 2, max("id") IS NOT null) FROM "forum_node_tags";\r
+SELECT setval('"forum_keyvalue_id_seq"', coalesce(max("id"), 1) + 2, max("id") IS NOT null) FROM "forum_keyvalue";\r
+SELECT setval('"forum_openidnonce_id_seq"', coalesce(max("id"), 1) + 2, max("id") IS NOT null) FROM "forum_openidnonce";\r
+SELECT setval('"forum_openidassociation_id_seq"', coalesce(max("id"), 1) + 2, max("id") IS NOT null) FROM "forum_openidassociation";\r
+"""\r
+\r
+\r
+ \r
+
\ No newline at end of file
--- /dev/null
+from south.v2 import DataMigration\r
+from south.orm import FakeORM\r
+\r
+class Migration(DataMigration):\r
+\r
+ def forwards(self, orm):\r
+\r
+ pass\r
+\r
+\r
+ def backwards(self, orm):\r
+ "Write your backwards methods here."\r
+\r
+ models = {\r
+ 'auth.group': {\r
+ 'Meta': {'object_name': 'Group'},\r
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),\r
+ 'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '80'}),\r
+ 'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'blank': 'True'})\r
+ },\r
+ 'auth.permission': {\r
+ 'Meta': {'unique_together': "(('content_type', 'codename'),)", 'object_name': 'Permission'},\r
+ 'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}),\r
+ 'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}),\r
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),\r
+ 'name': ('django.db.models.fields.CharField', [], {'max_length': '50'})\r
+ },\r
+ 'auth.user': {\r
+ 'Meta': {'object_name': 'User'},\r
+ 'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),\r
+ 'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}),\r
+ 'first_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),\r
+ 'groups': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Group']", 'blank': 'True'}),\r
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),\r
+ 'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True', 'blank': 'True'}),\r
+ 'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}),\r
+ 'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}),\r
+ 'last_login': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),\r
+ 'last_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),\r
+ 'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}),\r
+ 'user_permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'blank': 'True'}),\r
+ 'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'})\r
+ },\r
+ 'contenttypes.contenttype': {\r
+ 'Meta': {'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"},\r
+ 'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}),\r
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),\r
+ 'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}),\r
+ 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'})\r
+ },\r
+ 'forum.activity': {\r
+ 'Meta': {'object_name': 'Activity', 'db_table': "u'activity'"},\r
+ 'active_at': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),\r
+ 'activity_type': ('django.db.models.fields.SmallIntegerField', [], {}),\r
+ 'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}),\r
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),\r
+ 'is_auditted': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}),\r
+ 'object_id': ('django.db.models.fields.PositiveIntegerField', [], {}),\r
+ 'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['forum.User']"})\r
+ },\r
+ 'forum.anonymousnode': {\r
+ 'Meta': {'object_name': 'AnonymousNode', '_ormbases': ['forum.Node']},\r
+ 'convertible_to': ('django.db.models.fields.CharField', [], {'default': "'node'", 'max_length': '16'}),\r
+ 'node_ptr': ('django.db.models.fields.related.OneToOneField', [], {'to': "orm['forum.Node']", 'unique': 'True', 'primary_key': 'True'}),\r
+ 'validation_hash': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'anonymous_content'", 'to': "orm['forum.Node']"})\r
+ },\r
+ 'forum.answer': {\r
+ 'Meta': {'object_name': 'Answer', '_ormbases': ['forum.Node'], 'db_table': "u'answer'"},\r
+ 'accepted': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}),\r
+ 'accepted_at': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}),\r
+ 'accepted_by': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['forum.User']", 'null': 'True'}),\r
+ 'node_ptr': ('django.db.models.fields.related.OneToOneField', [], {'to': "orm['forum.Node']", 'unique': 'True', 'primary_key': 'True'}),\r
+ 'wiki': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}),\r
+ 'wikified_at': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'})\r
+ },\r
+ 'forum.authkeyuserassociation': {\r
+ 'Meta': {'object_name': 'AuthKeyUserAssociation'},\r
+ 'added_at': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),\r
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),\r
+ 'key': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '255'}),\r
+ 'provider': ('django.db.models.fields.CharField', [], {'max_length': '64'}),\r
+ 'user': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'auth_keys'", 'to': "orm['forum.User']"})\r
+ },\r
+ 'forum.award': {\r
+ 'Meta': {'unique_together': "(('content_type', 'object_id', 'user', 'badge'),)", 'object_name': 'Award', 'db_table': "u'award'"},\r
+ 'awarded_at': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),\r
+ 'badge': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'award_badge'", 'to': "orm['forum.Badge']"}),\r
+ 'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}),\r
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),\r
+ 'notified': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}),\r
+ 'object_id': ('django.db.models.fields.PositiveIntegerField', [], {}),\r
+ 'user': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'awards'", 'to': "orm['forum.User']"})\r
+ },\r
+ 'forum.badge': {\r
+ 'Meta': {'unique_together': "(('name', 'type'),)", 'object_name': 'Badge', 'db_table': "u'badge'"},\r
+ 'awarded_count': ('django.db.models.fields.PositiveIntegerField', [], {'default': '0'}),\r
+ 'awarded_to': ('django.db.models.fields.related.ManyToManyField', [], {'related_name': "'badges'", 'through': "'Award'", 'to': "orm['forum.User']"}),\r
+ 'description': ('django.db.models.fields.CharField', [], {'max_length': '300'}),\r
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),\r
+ 'multiple': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}),\r
+ 'name': ('django.db.models.fields.CharField', [], {'max_length': '50'}),\r
+ 'slug': ('django.db.models.fields.SlugField', [], {'db_index': 'True', 'max_length': '50', 'blank': 'True'}),\r
+ 'type': ('django.db.models.fields.SmallIntegerField', [], {})\r
+ },\r
+ 'forum.favoritequestion': {\r
+ 'Meta': {'unique_together': "(('question', 'user'),)", 'object_name': 'FavoriteQuestion', 'db_table': "u'favorite_question'"},\r
+ 'added_at': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),\r
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),\r
+ 'question': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['forum.Question']"}),\r
+ 'user': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'user_favorite_questions'", 'to': "orm['forum.User']"})\r
+ },\r
+ 'forum.flaggeditem': {\r
+ 'Meta': {'object_name': 'FlaggedItem', 'db_table': "u'flagged_item'"},\r
+ 'canceled': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}),\r
+ 'flagged_at': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),\r
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),\r
+ 'node': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'flaggeditems'", 'null': 'True', 'to': "orm['forum.Node']"}),\r
+ 'reason': ('django.db.models.fields.CharField', [], {'max_length': '300', 'null': 'True'}),\r
+ 'user': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'flaggeditems'", 'to': "orm['forum.User']"})\r
+ },\r
+ 'forum.keyvalue': {\r
+ 'Meta': {'object_name': 'KeyValue'},\r
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),\r
+ 'key': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '255'}),\r
+ 'value': ('forum.models.utils.PickledObjectField', [], {})\r
+ },\r
+ 'forum.markedtag': {\r
+ 'Meta': {'object_name': 'MarkedTag'},\r
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),\r
+ 'reason': ('django.db.models.fields.CharField', [], {'max_length': '16'}),\r
+ 'tag': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'user_selections'", 'to': "orm['forum.Tag']"}),\r
+ 'user': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'tag_selections'", 'to': "orm['forum.User']"})\r
+ },\r
+ 'forum.node': {\r
+ 'Meta': {'object_name': 'Node'},\r
+ 'abs_parent': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'all_children'", 'null': 'True', 'to': "orm['forum.Node']"}),\r
+ 'active_revision': ('django.db.models.fields.related.OneToOneField', [], {'related_name': "'active'", 'unique': 'True', 'null': 'True', 'to': "orm['forum.NodeRevision']"}),\r
+ 'added_at': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),\r
+ 'author': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'nodes'", 'to': "orm['forum.User']"}),\r
+ 'body': ('django.db.models.fields.TextField', [], {}),\r
+ 'comment_count': ('django.db.models.fields.PositiveIntegerField', [], {'default': '0'}),\r
+ 'deleted': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}),\r
+ 'deleted_at': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}),\r
+ 'deleted_by': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'deleted_nodes'", 'null': 'True', 'to': "orm['forum.User']"}),\r
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),\r
+ 'last_edited_at': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}),\r
+ 'last_edited_by': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'last_edited_nodes'", 'null': 'True', 'to': "orm['forum.User']"}),\r
+ 'node_type': ('django.db.models.fields.CharField', [], {'default': "'node'", 'max_length': '16'}),\r
+ 'offensive_flag_count': ('django.db.models.fields.SmallIntegerField', [], {'default': '0'}),\r
+ 'parent': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'children'", 'null': 'True', 'to': "orm['forum.Node']"}),\r
+ 'score': ('django.db.models.fields.IntegerField', [], {'default': '0'}),\r
+ 'tagnames': ('django.db.models.fields.CharField', [], {'max_length': '125'}),\r
+ 'tags': ('django.db.models.fields.related.ManyToManyField', [], {'related_name': "'nodes'", 'to': "orm['forum.Tag']"}),\r
+ 'title': ('django.db.models.fields.CharField', [], {'max_length': '300'}),\r
+ 'vote_down_count': ('django.db.models.fields.IntegerField', [], {'default': '0'}),\r
+ 'vote_up_count': ('django.db.models.fields.IntegerField', [], {'default': '0'})\r
+ },\r
+ 'forum.noderevision': {\r
+ 'Meta': {'unique_together': "(('node', 'revision'),)", 'object_name': 'NodeRevision'},\r
+ 'author': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'noderevisions'", 'to': "orm['forum.User']"}),\r
+ 'body': ('django.db.models.fields.TextField', [], {}),\r
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),\r
+ 'node': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'revisions'", 'to': "orm['forum.Node']"}),\r
+ 'revised_at': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),\r
+ 'revision': ('django.db.models.fields.PositiveIntegerField', [], {}),\r
+ 'summary': ('django.db.models.fields.CharField', [], {'max_length': '300'}),\r
+ 'tagnames': ('django.db.models.fields.CharField', [], {'max_length': '125'}),\r
+ 'title': ('django.db.models.fields.CharField', [], {'max_length': '300'})\r
+ },\r
+ 'forum.openidassociation': {\r
+ 'Meta': {'object_name': 'OpenIdAssociation'},\r
+ 'assoc_type': ('django.db.models.fields.TextField', [], {'max_length': '64'}),\r
+ 'handle': ('django.db.models.fields.CharField', [], {'max_length': '255'}),\r
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),\r
+ 'issued': ('django.db.models.fields.IntegerField', [], {}),\r
+ 'lifetime': ('django.db.models.fields.IntegerField', [], {}),\r
+ 'secret': ('django.db.models.fields.TextField', [], {'max_length': '255'}),\r
+ 'server_url': ('django.db.models.fields.TextField', [], {'max_length': '2047'})\r
+ },\r
+ 'forum.openidnonce': {\r
+ 'Meta': {'object_name': 'OpenIdNonce'},\r
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),\r
+ 'salt': ('django.db.models.fields.CharField', [], {'max_length': '50'}),\r
+ 'server_url': ('django.db.models.fields.URLField', [], {'max_length': '200'}),\r
+ 'timestamp': ('django.db.models.fields.IntegerField', [], {})\r
+ },\r
+ 'forum.question': {\r
+ 'Meta': {'object_name': 'Question', '_ormbases': ['forum.Node'], 'db_table': "u'question'"},\r
+ 'accepted_answer': ('django.db.models.fields.related.OneToOneField', [], {'related_name': "'question_accepting'", 'unique': 'True', 'null': 'True', 'to': "orm['forum.Answer']"}),\r
+ 'answer_count': ('django.db.models.fields.PositiveIntegerField', [], {'default': '0'}),\r
+ 'close_reason': ('django.db.models.fields.SmallIntegerField', [], {'null': 'True', 'blank': 'True'}),\r
+ 'closed': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}),\r
+ 'closed_at': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}),\r
+ 'closed_by': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'closed_questions'", 'null': 'True', 'to': "orm['forum.User']"}),\r
+ 'favorited_by': ('django.db.models.fields.related.ManyToManyField', [], {'related_name': "'favorite_questions'", 'through': "'FavoriteQuestion'", 'to': "orm['forum.User']"}),\r
+ 'favourite_count': ('django.db.models.fields.IntegerField', [], {'default': '0'}),\r
+ 'last_activity_at': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),\r
+ 'last_activity_by': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'last_active_in_questions'", 'null': 'True', 'to': "orm['forum.User']"}),\r
+ 'node_ptr': ('django.db.models.fields.related.OneToOneField', [], {'to': "orm['forum.Node']", 'unique': 'True'}),\r
+ 'subscribers': ('django.db.models.fields.related.ManyToManyField', [], {'related_name': "'subscriptions'", 'through': "'QuestionSubscription'", 'to': "orm['forum.User']"}),\r
+ 'view_count': ('django.db.models.fields.IntegerField', [], {'default': '0'}),\r
+ 'wiki': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}),\r
+ 'wikified_at': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'})\r
+ },\r
+ 'forum.questionsubscription': {\r
+ 'Meta': {'object_name': 'QuestionSubscription'},\r
+ 'auto_subscription': ('django.db.models.fields.BooleanField', [], {'default': 'True', 'blank': 'True'}),\r
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),\r
+ 'last_view': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime(2010, 4, 17, 2, 50, 12, 337000)'}),\r
+ 'question': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['forum.Question']"}),\r
+ 'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['forum.User']"})\r
+ },\r
+ 'forum.repute': {\r
+ 'Meta': {'object_name': 'Repute', 'db_table': "u'repute'"},\r
+ 'canceled': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}),\r
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),\r
+ 'node': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'reputes'", 'null': 'True', 'to': "orm['forum.Node']"}),\r
+ 'question': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['forum.Question']"}),\r
+ 'reputation_type': ('django.db.models.fields.SmallIntegerField', [], {}),\r
+ 'reputed_at': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),\r
+ 'user': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'reputes'", 'to': "orm['forum.User']"}),\r
+ 'user_previous_rep': ('django.db.models.fields.IntegerField', [], {'default': '0'}),\r
+ 'value': ('django.db.models.fields.SmallIntegerField', [], {'default': '0'})\r
+ },\r
+ 'forum.subscriptionsettings': {\r
+ 'Meta': {'object_name': 'SubscriptionSettings'},\r
+ 'all_questions': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}),\r
+ 'all_questions_watched_tags': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}),\r
+ 'enable_notifications': ('django.db.models.fields.BooleanField', [], {'default': 'True', 'blank': 'True'}),\r
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),\r
+ 'member_joins': ('django.db.models.fields.CharField', [], {'default': "'n'", 'max_length': '1'}),\r
+ 'new_question': ('django.db.models.fields.CharField', [], {'default': "'d'", 'max_length': '1'}),\r
+ 'new_question_watched_tags': ('django.db.models.fields.CharField', [], {'default': "'i'", 'max_length': '1'}),\r
+ 'notify_accepted': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}),\r
+ 'notify_answers': ('django.db.models.fields.BooleanField', [], {'default': 'True', 'blank': 'True'}),\r
+ 'notify_comments': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}),\r
+ 'notify_comments_own_post': ('django.db.models.fields.BooleanField', [], {'default': 'True', 'blank': 'True'}),\r
+ 'notify_reply_to_comments': ('django.db.models.fields.BooleanField', [], {'default': 'True', 'blank': 'True'}),\r
+ 'questions_answered': ('django.db.models.fields.BooleanField', [], {'default': 'True', 'blank': 'True'}),\r
+ 'questions_asked': ('django.db.models.fields.BooleanField', [], {'default': 'True', 'blank': 'True'}),\r
+ 'questions_commented': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}),\r
+ 'questions_viewed': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}),\r
+ 'subscribed_questions': ('django.db.models.fields.CharField', [], {'default': "'i'", 'max_length': '1'}),\r
+ 'user': ('django.db.models.fields.related.OneToOneField', [], {'related_name': "'subscription_settings'", 'unique': 'True', 'to': "orm['forum.User']"})\r
+ },\r
+ 'forum.tag': {\r
+ 'Meta': {'object_name': 'Tag', 'db_table': "u'tag'"},\r
+ 'created_by': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'created_tags'", 'to': "orm['forum.User']"}),\r
+ 'deleted': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}),\r
+ 'deleted_at': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}),\r
+ 'deleted_by': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'deleted_tags'", 'null': 'True', 'to': "orm['forum.User']"}),\r
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),\r
+ 'marked_by': ('django.db.models.fields.related.ManyToManyField', [], {'related_name': "'marked_tags'", 'through': "'MarkedTag'", 'to': "orm['forum.User']"}),\r
+ 'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '255'}),\r
+ 'used_count': ('django.db.models.fields.PositiveIntegerField', [], {'default': '0'})\r
+ },\r
+ 'forum.user': {\r
+ 'Meta': {'object_name': 'User', '_ormbases': ['auth.User']},\r
+ 'about': ('django.db.models.fields.TextField', [], {'blank': 'True'}),\r
+ 'bronze': ('django.db.models.fields.SmallIntegerField', [], {'default': '0'}),\r
+ 'date_of_birth': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}),\r
+ 'email_isvalid': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}),\r
+ 'email_key': ('django.db.models.fields.CharField', [], {'max_length': '32', 'null': 'True'}),\r
+ 'gold': ('django.db.models.fields.SmallIntegerField', [], {'default': '0'}),\r
+ 'hide_ignored_questions': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}),\r
+ 'is_approved': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}),\r
+ 'last_seen': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),\r
+ 'location': ('django.db.models.fields.CharField', [], {'max_length': '100', 'blank': 'True'}),\r
+ 'questions_per_page': ('django.db.models.fields.SmallIntegerField', [], {'default': '10'}),\r
+ 'real_name': ('django.db.models.fields.CharField', [], {'max_length': '100', 'blank': 'True'}),\r
+ 'reputation': ('django.db.models.fields.PositiveIntegerField', [], {'default': '1'}),\r
+ 'silver': ('django.db.models.fields.SmallIntegerField', [], {'default': '0'}),\r
+ 'user_ptr': ('django.db.models.fields.related.OneToOneField', [], {'to': "orm['auth.User']", 'unique': 'True', 'primary_key': 'True'}),\r
+ 'website': ('django.db.models.fields.URLField', [], {'max_length': '200', 'blank': 'True'})\r
+ },\r
+ 'forum.validationhash': {\r
+ 'Meta': {'unique_together': "(('user', 'type'),)", 'object_name': 'ValidationHash'},\r
+ 'expiration': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime(2010, 4, 18, 2, 50, 12, 421000)'}),\r
+ 'hash_code': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '255'}),\r
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),\r
+ 'seed': ('django.db.models.fields.CharField', [], {'max_length': '12'}),\r
+ 'type': ('django.db.models.fields.CharField', [], {'max_length': '12'}),\r
+ 'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['forum.User']"})\r
+ },\r
+ 'forum.vote': {\r
+ 'Meta': {'object_name': 'Vote', 'db_table': "u'vote'"},\r
+ 'canceled': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}),\r
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),\r
+ 'node': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'votes'", 'null': 'True', 'to': "orm['forum.Node']"}),\r
+ 'user': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'votes'", 'to': "orm['forum.User']"}),\r
+ 'vote': ('django.db.models.fields.SmallIntegerField', [], {}),\r
+ 'voted_at': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'})\r
+ }\r
+ }\r
+\r
+ complete_apps = ['forum']\r
+\r
+orm = FakeORM(Migration, "forum")\r
+\r