1 # -*- coding: utf-8 -*-
3 from datetime import datetime
8 from django.utils.translation import ugettext as _
10 from django.utils.encoding import force_unicode
13 from cPickle import loads, dumps
15 from pickle import loads, dumps
17 from copy import deepcopy
18 from base64 import b64encode, b64decode
19 from zlib import compress, decompress
21 from xml.sax import make_parser
22 from xml.sax.handler import ContentHandler
25 from django.conf import settings
26 from south.orm import FakeORM
28 get_migration_number_re = re.compile(r'^((\d+)_.*)\.py$')
30 migrations_folder = os.path.join(settings.SITE_SRC_ROOT, 'forum/migrations')
35 for f in os.listdir(migrations_folder):
36 if os.path.isfile(os.path.join(migrations_folder, f)):
37 m = get_migration_number_re.match(f)
40 found = int(m.group(2))
42 if found > highest_number:
43 highest_number = found
44 highest_file = m.group(1)
46 mod = __import__('forum.migrations.%s' % highest_file, globals(), locals(), ['forum.migrations'])
47 return FakeORM(getattr(mod, 'Migration'), "forum")
51 class SXTableHandler(ContentHandler):
52 def __init__(self, fname, callback):
57 self.fname = fname.lower()
58 self.callback = callback
60 def startElement(self, name, attrs):
61 if name.lower() == self.fname:
63 elif name.lower() == "row":
66 def characters(self, ch):
69 def endElement(self, name):
70 if name.lower() == self.fname:
72 elif name.lower() == "row":
73 self.callback(self.el_data)
79 self.el_data[name.lower()] = self.ch_data.strip()
84 def readTable(path, name, callback):
85 parser = make_parser()
86 handler = SXTableHandler(name, callback)
87 parser.setContentHandler(handler)
89 f = os.path.join(path, "%s.xml" % name)
93 def dbsafe_encode(value):
94 return force_unicode(b64encode(compress(dumps(deepcopy(value)))))
98 for node in el.childNodes:
99 if node.nodeType == node.TEXT_NODE:
103 msstrip = re.compile(r'^(.*)\.\d+')
105 noms = msstrip.match(ts)
109 return datetime(*time.strptime(ts, '%Y-%m-%dT%H:%M:%S')[0:6])
112 # return dict([(n.tagName.lower(), getText(n)) for n in el.childNodes if n.nodeType == el.ELEMENT_NODE])
114 #def readTable(dump, name):
115 # for e in minidom.parseString(dump.read("%s.xml" % name)).getElementsByTagName('row'):
117 #return [readEl(e) for e in minidom.parseString(dump.read("%s.xml" % name)).getElementsByTagName('row')]
119 google_accounts_lookup = re.compile(r'^https?://www.google.com/accounts/')
120 yahoo_accounts_lookup = re.compile(r'^https?://me.yahoo.com/a/')
123 re.compile(r'^https?://www.google.com/profiles/(?P<uname>\w+(\.\w+)*)/?$'),
124 re.compile(r'^https?://me.yahoo.com/(?P<uname>\w+(\.\w+)*)/?$'),
125 re.compile(r'^https?://openid.aol.com/(?P<uname>\w+(\.\w+)*)/?$'),
126 re.compile(r'^https?://(?P<uname>\w+(\.\w+)*).myopenid.com/?$'),
127 re.compile(r'^https?://flickr.com/(\w+/)*(?P<uname>\w+(\.\w+)*)/?$'),
128 re.compile(r'^https?://technorati.com/people/technorati/(?P<uname>\w+(\.\w+)*)/?$'),
129 re.compile(r'^https?://(?P<uname>\w+(\.\w+)*).wordpress.com/?$'),
130 re.compile(r'^https?://(?P<uname>\w+(\.\w+)*).blogspot.com/?$'),
131 re.compile(r'^https?://(?P<uname>\w+(\.\w+)*).livejournal.com/?$'),
132 re.compile(r'^https?://claimid.com/(?P<uname>\w+(\.\w+)*)/?$'),
133 re.compile(r'^https?://(?P<uname>\w+(\.\w+)*).pip.verisignlabs.com/?$'),
134 re.compile(r'^https?://getopenid.com/(?P<uname>\w+(\.\w+)*)/?$'),
135 re.compile(r'^https?://[\w\.]+/(\w+/)*(?P<uname>\w+(\.\w+)*)/?$'),
136 re.compile(r'^https?://(?P<uname>[\w\.]+)/?$'),
139 def final_username_attempt(sxu):
140 openid = sxu.get('openid', None)
143 if google_accounts_lookup.search(openid):
144 return UnknownGoogleUser(sxu.get('id'))
145 if yahoo_accounts_lookup.search(openid):
146 return UnknownYahooUser(sxu.get('id'))
148 for lookup in openid_lookups:
149 if lookup.search(openid):
150 return lookup.search(openid).group('uname')
152 return UnknownUser(sxu.get('id'))
154 class UnknownUser(object):
155 def __init__(self, id):
159 return _("user-%(id)s") % {'id': self._id}
161 def __unicode__(self):
162 return self.__str__()
164 def encode(self, *args):
165 return self.__str__()
167 class UnknownGoogleUser(UnknownUser):
169 return _("user-%(id)s (google)") % {'id': self._id}
171 class UnknownYahooUser(UnknownUser):
173 return _("user-%(id)s (yahoo)") % {'id': self._id}
176 class IdMapper(dict):
177 def __getitem__(self, key):
179 return super(IdMapper, self).get(key, 1)
181 def __setitem__(self, key, value):
182 super(IdMapper, self).__setitem__(int(key), int(value))
184 class IdIncrementer():
185 def __init__(self, initial):
191 openidre = re.compile('^https?\:\/\/')
192 def userimport(path, options):
196 uidmapper = IdMapper()
198 authenticated_user = options.get('authenticated_user', None)
199 owneruid = options.get('owneruid', None)
200 #check for empty values
207 if sxu.get('id') == '-1':
209 #print "\n".join(["%s : %s" % i for i in sxu.items()])
211 if int(sxu.get('id')) == int(owneruid):
212 if authenticated_user:
213 osqau = orm.User.objects.get(id=authenticated_user.id)
215 for assoc in orm.AuthKeyUserAssociation.objects.filter(user=osqau):
216 openids.add(assoc.key)
218 uidmapper[owneruid] = osqau.id
219 uidmapper[-1] = osqau.id
222 uidmapper[owneruid] = int(owneruid)
223 uidmapper[-1] = int(owneruid)
226 sxbadges = sxu.get('badgesummary', None)
227 badges = {'1':'0', '2':'0', '3':'0'}
230 badges.update(dict([b.split('=') for b in sxbadges.split()]))
233 username = unicode(sxu.get('displayname',
234 sxu.get('displaynamecleaned', sxu.get('realname', final_username_attempt(sxu)))))[:30]
236 if username in usernames:
237 #if options.get('mergesimilar', False) and sxu.get('email', 'INVALID') == user_by_name[username].email:
238 # osqau = user_by_name[username]
240 # uidmapper[sxu.get('id')] = osqau.id
246 totest = "%s %d" % (username[:29 - len(str(inc))], inc)
248 if not totest in usernames:
256 email = sxu.get('email', ''),
257 is_superuser = sxu.get('usertypeid') == '5',
258 is_staff = sxu.get('usertypeid') == '4',
260 date_joined = readTime(sxu.get('creationdate')),
261 last_seen = readTime(sxu.get('lastaccessdate')),
262 about = sxu.get('aboutme', ''),
263 date_of_birth = sxu.get('birthday', None) and readTime(sxu['birthday']) or None,
264 email_isvalid = int(sxu.get('usertypeid')) > 2,
265 website = sxu.get('websiteurl', ''),
266 reputation = int(sxu.get('reputation')),
267 gold = int(badges['1']),
268 silver = int(badges['2']),
269 bronze = int(badges['3']),
270 real_name = sxu.get('realname', '')[:30],
271 location = sxu.get('location', ''),
276 user_joins = orm.Action(
277 action_type = "userjoins",
278 action_date = osqau.date_joined,
283 rep = orm.ActionRepute(
286 date = osqau.date_joined,
292 orm.SubscriptionSettings.objects.get(user=osqau)
294 s = orm.SubscriptionSettings(user=osqau)
297 uidmapper[osqau.id] = osqau.id
299 new_about = sxu.get('aboutme', None)
300 if new_about and osqau.about != new_about:
302 osqau.about = "%s\n|\n%s" % (osqau.about, new_about)
304 osqau.about = new_about
306 osqau.username = sxu.get('displayname',
307 sxu.get('displaynamecleaned', sxu.get('realname', final_username_attempt(sxu))))
308 osqau.email = sxu.get('email', '')
309 osqau.reputation += int(sxu.get('reputation'))
310 osqau.gold += int(badges['1'])
311 osqau.silver += int(badges['2'])
312 osqau.bronze += int(badges['3'])
314 osqau.date_joined = readTime(sxu.get('creationdate'))
315 osqau.website = sxu.get('websiteurl', '')
316 osqau.date_of_birth = sxu.get('birthday', None) and readTime(sxu['birthday']) or None
317 osqau.location = sxu.get('location', '')
318 osqau.real_name = sxu.get('realname', '')
320 #merged_users.append(osqau.id)
323 usernames.append(osqau.username)
325 openid = sxu.get('openid', None)
326 if openid and openidre.match(openid) and (not openid in openids):
327 assoc = orm.AuthKeyUserAssociation(user=osqau, key=openid, provider="openidurl")
331 openidalt = sxu.get('openidalt', None)
332 if openidalt and openidre.match(openidalt) and (not openidalt in openids):
333 assoc = orm.AuthKeyUserAssociation(user=osqau, key=openidalt, provider="openidurl")
335 openids.add(openidalt)
337 readTable(path, "Users", callback)
339 if uidmapper[-1] == -1:
344 def tagsimport(dump, uidmap):
350 id = int(sxtag['id']),
351 name = sxtag['name'],
352 used_count = int(sxtag['count']),
353 created_by_id = uidmap[sxtag.get('userid', 1)],
357 tagmap[otag.name] = otag
359 readTable(dump, "Tags", callback)
363 def add_post_state(name, post, action):
364 if not "(%s)" % name in post.state_string:
365 post.state_string = "%s(%s)" % (post.state_string, name)
369 state = orm.NodeState.objects.get(node=post, state_type=name)
370 state.action = action
373 state = orm.NodeState(node=post, state_type=name, action=action)
376 def remove_post_state(name, post):
377 if "(%s)" % name in post.state_string:
379 state = orm.NodeState.objects.get(state_type=name, post=post)
383 post.state_string = "".join("(%s)" % s for s in re.findall('\w+', post.state_string) if s != name)
385 def postimport(dump, uidmap, tagmap):
388 def callback(sxpost):
389 nodetype = (sxpost.get('posttypeid') == '1') and "nodetype" or "answer"
392 node_type = nodetype,
394 added_at = readTime(sxpost['creationdate']),
395 body = sxpost['body'],
396 score = sxpost.get('score', 0),
397 author_id = sxpost.get('deletiondate', None) and 1 or uidmap[sxpost.get('owneruserid', 1)]
402 create_action = orm.Action(
403 action_type = (nodetype == "nodetype") and "ask" or "answer",
404 user_id = post.author_id,
406 action_date = post.added_at
411 if sxpost.get('lasteditoruserid', None):
412 revise_action = orm.Action(
413 action_type = "revise",
414 user_id = uidmap[sxpost.get('lasteditoruserid')],
416 action_date = readTime(sxpost['lasteditdate']),
420 post.last_edited = revise_action
422 if sxpost.get('communityowneddate', None):
423 wikify_action = orm.Action(
424 action_type = "wikify",
427 action_date = readTime(sxpost['communityowneddate'])
431 add_post_state("wiki", post, wikify_action)
433 if sxpost.get('lastactivityuserid', None):
434 post.last_activity_by_id = uidmap[sxpost['lastactivityuserid']]
435 post.last_activity_at = readTime(sxpost['lastactivitydate'])
437 if sxpost.get('posttypeid') == '1': #question
438 post.node_type = "question"
439 post.title = sxpost['title']
441 tagnames = sxpost['tags'].replace(u'ö', '-').replace(u'é', '').replace(u'à ', '')
442 post.tagnames = tagnames
444 post.extra_count = sxpost.get('viewcount', 0)
446 add_tags_to_post(post, tagmap)
449 post.parent_id = sxpost['parentid']
453 all.append(int(post.id))
454 create_and_activate_revision(post)
458 readTable(dump, "Posts", callback)
462 def comment_import(dump, uidmap, posts):
463 currid = IdIncrementer(max(posts))
470 node_type = "comment",
471 added_at = readTime(sxc['creationdate']),
472 author_id = uidmap[sxc.get('userid', 1)],
474 parent_id = sxc.get('postid'),
477 if sxc.get('deletiondate', None):
478 delete_action = orm.Action(
479 action_type = "delete",
480 user_id = uidmap[sxc['deletionuserid']],
481 action_date = readTime(sxc['deletiondate'])
484 oc.author_id = uidmap[sxc['deletionuserid']]
487 delete_action.node = oc
490 add_post_state("deleted", oc, delete_action)
492 oc.author_id = uidmap[sxc.get('userid', 1)]
495 create_action = orm.Action(
496 action_type = "comment",
497 user_id = oc.author_id,
499 action_date = oc.added_at
502 create_and_activate_revision(oc)
507 posts.append(int(oc.id))
508 mapping[int(sxc['id'])] = int(oc.id)
510 readTable(dump, "PostComments", callback)
511 return posts, mapping
514 def add_tags_to_post(post, tagmap):
515 tags = [tag for tag in [tagmap.get(name.strip()) for name in post.tagnames.split(u' ') if name] if tag]
516 post.tagnames = " ".join([t.name for t in tags]).strip()
520 def create_and_activate_revision(post):
521 rev = orm.NodeRevision(
522 author_id = post.author_id,
525 revised_at = post.added_at,
527 summary = 'Initial revision',
528 tagnames = post.tagnames,
533 post.active_revision_id = rev.id
536 def post_vote_import(dump, uidmap, posts):
539 def close_callback(r):
540 close_reasons[r['id']] = r['name']
542 readTable(dump, "CloseReasons", close_callback)
548 user_id=uidmap[sxv['userid']],
549 action_date = readTime(sxv['creationdate']),
552 if not int(sxv['postid']) in posts: return
553 node = orm.Node.objects.get(id=sxv['postid'])
556 if sxv['votetypeid'] == '1':
558 question = orm.Node.objects.get(id=answer.parent_id)
560 action.action_type = "acceptanswer"
565 question.extra_ref_id = answer.id
570 elif sxv['votetypeid'] in ('2', '3'):
571 if not (action.node.id, action.user_id) in user2vote:
572 user2vote.append((action.node.id, action.user_id))
574 action.action_type = (sxv['votetypeid'] == '2') and "voteup" or "votedown"
578 node_id = action.node.id,
579 user_id = action.user_id,
580 voted_at = action.action_date,
581 value = sxv['votetypeid'] == '2' and 1 or -1,
586 action.action_type = "unknown"
589 elif sxv['votetypeid'] in ('4', '12', '13'):
590 action.action_type = "flag"
595 user_id = action.user_id,
596 flagged_at = action.action_date,
603 elif sxv['votetypeid'] == '5':
604 action.action_type = "favorite"
607 elif sxv['votetypeid'] == '6':
608 action.action_type = "close"
609 action.extra = dbsafe_encode(close_reasons[sxv['comment']])
615 elif sxv['votetypeid'] == '7':
616 action.action_type = "unknown"
622 remove_post_state("closed", node)
624 elif sxv['votetypeid'] == '10':
625 action.action_type = "delete"
628 elif sxv['votetypeid'] == '11':
629 action.action_type = "unknown"
632 remove_post_state("deleted", node)
635 action.action_type = "unknown"
638 if sxv.get('targetrepchange', None):
639 rep = orm.ActionRepute(
641 date = action.action_date,
642 user_id = uidmap[sxv['targetuserid']],
643 value = int(sxv['targetrepchange'])
648 if sxv.get('voterrepchange', None):
649 rep = orm.ActionRepute(
651 date = action.action_date,
652 user_id = uidmap[sxv['userid']],
653 value = int(sxv['voterrepchange'])
658 if action.action_type in ("acceptanswer", "delete", "close"):
659 state = {"acceptanswer": "accepted", "delete": "deleted", "close": "closed"}[action.action_type]
660 add_post_state(state, node, action)
662 readTable(dump, "Posts2Votes", callback)
665 def comment_vote_import(dump, uidmap, comments):
670 if sxv['votetypeid'] == "2":
671 comment_id = comments[int(sxv['postcommentid'])]
672 user_id = uidmap[sxv['userid']]
674 if not (comment_id, user_id) in user2vote:
675 user2vote.append((comment_id, user_id))
678 action_type = "voteupcomment",
680 action_date = readTime(sxv['creationdate']),
686 node_id = comment_id,
688 voted_at = action.action_date,
695 if not comment_id in comments2score:
696 comments2score[comment_id] = 1
698 comments2score[comment_id] += 1
700 readTable(dump, "Comments2Votes", callback)
702 for cid, score in comments2score.items():
703 orm.Node.objects.filter(id=cid).update(score=score)
706 def badges_import(dump, uidmap, post_list):
711 sxbadges[int(b['id'])] = b
713 readTable(dump, "Badges", sxcallback)
715 obadges = dict([(b.cls, b) for b in orm.Badge.objects.all()])
716 user_badge_count = {}
720 for id, sxb in sxbadges.items():
721 cls = "".join(sxb['name'].replace('&', 'And').split(' '))
724 sx_to_osqa[id] = obadges[cls]
732 sx_to_osqa[id] = osqab
737 badge = sx_to_osqa[int(sxa['badgeid'])]
739 user_id = uidmap[sxa['userid']]
740 if not user_badge_count.get(user_id, None):
741 user_badge_count[user_id] = 0
744 action_type = "award",
746 action_date = readTime(sxa['date'])
752 user_id = uidmap[sxa['userid']],
754 node_id = post_list[user_badge_count[user_id]],
755 awarded_at = action.action_date,
760 badge.awarded_count += 1
761 user_badge_count[user_id] += 1
763 readTable(dump, "Users2Badges", callback)
765 for badge in obadges.values():
768 def save_setting(k, v):
770 kv = orm.KeyValue.objects.get(key=k)
773 kv = orm.KeyValue(key = k, value = v)
778 def pages_import(dump, currid):
779 currid = IdIncrementer(currid)
788 body = b64decode(sxp['value']),
789 extra = dbsafe_encode({
790 'path': sxp['url'][1:],
791 'mimetype': sxp['contenttype'],
792 'template': (sxp['usemaster'] == "true") and "default" or "none",
795 'sidebar_wrap': True,
796 'sidebar_render': "html",
802 create_and_activate_revision(page)
805 registry[sxp['url'][1:]] = page.id
807 create_action = orm.Action(
808 action_type = "newpage",
809 user_id = page.author_id,
815 if sxp['active'] == "true" and sxp['contenttype'] == "text/html":
816 pub_action = orm.Action(
817 action_type = "publish",
818 user_id = page.author_id,
823 add_post_state("published", page, pub_action)
825 readTable(dump, "FlatPages", callback)
827 save_setting('STATIC_PAGE_REGISTRY', dbsafe_encode(registry))
830 u'theme.html.name': 'APP_TITLE',
831 u'theme.html.footer': 'CUSTOM_FOOTER',
832 u'theme.html.sidebar': 'SIDEBAR_UPPER_TEXT',
833 u'theme.html.sidebar-low': 'SIDEBAR_LOWER_TEXT',
834 u'theme.html.welcome': 'APP_INTRO',
835 u'theme.html.head': 'CUSTOM_HEAD',
836 u'theme.html.header': 'CUSTOM_HEADER',
837 u'theme.css': 'CUSTOM_CSS',
848 def html_decode(html):
849 html = force_unicode(html)
851 for args in html_codes:
852 html = html.replace(*args)
857 def static_import(dump):
861 if unicode(set['name']) in sx2osqa_set_map:
862 save_setting(sx2osqa_set_map[set['name']], dbsafe_encode(html_decode(set['value'])))
864 sx_unknown[set['name']] = html_decode(set['value'])
866 readTable(dump, "ThemeTextResources", callback)
868 save_setting('SXIMPORT_UNKNOWN_SETS', dbsafe_encode(sx_unknown))
870 def disable_triggers():
871 from south.db import db
872 if db.backend_name == "postgres":
873 db.execute_many(PG_DISABLE_TRIGGERS)
874 db.commit_transaction()
875 db.start_transaction()
877 def enable_triggers():
878 from south.db import db
879 if db.backend_name == "postgres":
880 db.start_transaction()
881 db.execute_many(PG_ENABLE_TRIGGERS)
882 db.commit_transaction()
884 def reset_sequences():
885 from south.db import db
886 if db.backend_name == "postgres":
887 db.start_transaction()
888 db.execute_many(PG_SEQUENCE_RESETS)
889 db.commit_transaction()
892 from south.db import db
893 if db.backend_name == "postgres":
894 db.start_transaction()
895 db.execute_many("UPDATE forum_noderevision set id = id WHERE TRUE;")
896 db.commit_transaction()
899 def sximport(dump, options):
902 triggers_disabled = True
904 triggers_disabled = False
906 uidmap = userimport(dump, options)
907 tagmap = tagsimport(dump, uidmap)
910 posts = postimport(dump, uidmap, tagmap)
913 posts, comments = comment_import(dump, uidmap, posts)
916 post_vote_import(dump, uidmap, posts)
919 comment_vote_import(dump, uidmap, comments)
922 badges_import(dump, uidmap, posts)
924 pages_import(dump, max(posts))
928 from south.db import db
929 db.commit_transaction()
933 if triggers_disabled:
938 PG_DISABLE_TRIGGERS = """
939 ALTER table auth_user DISABLE TRIGGER ALL;
940 ALTER table auth_user_groups DISABLE TRIGGER ALL;
941 ALTER table auth_user_user_permissions DISABLE TRIGGER ALL;
942 ALTER table forum_keyvalue DISABLE TRIGGER ALL;
943 ALTER table forum_action DISABLE TRIGGER ALL;
944 ALTER table forum_actionrepute DISABLE TRIGGER ALL;
945 ALTER table forum_subscriptionsettings DISABLE TRIGGER ALL;
946 ALTER table forum_validationhash DISABLE TRIGGER ALL;
947 ALTER table forum_authkeyuserassociation DISABLE TRIGGER ALL;
948 ALTER table forum_tag DISABLE TRIGGER ALL;
949 ALTER table forum_markedtag DISABLE TRIGGER ALL;
950 ALTER table forum_node DISABLE TRIGGER ALL;
951 ALTER table forum_nodestate DISABLE TRIGGER ALL;
952 ALTER table forum_node_tags DISABLE TRIGGER ALL;
953 ALTER table forum_noderevision DISABLE TRIGGER ALL;
954 ALTER table forum_node_tags DISABLE TRIGGER ALL;
955 ALTER table forum_questionsubscription DISABLE TRIGGER ALL;
956 ALTER table forum_vote DISABLE TRIGGER ALL;
957 ALTER table forum_flag DISABLE TRIGGER ALL;
958 ALTER table forum_badge DISABLE TRIGGER ALL;
959 ALTER table forum_award DISABLE TRIGGER ALL;
960 ALTER table forum_openidnonce DISABLE TRIGGER ALL;
961 ALTER table forum_openidassociation DISABLE TRIGGER ALL;
964 PG_ENABLE_TRIGGERS = """
965 ALTER table auth_user ENABLE TRIGGER ALL;
966 ALTER table auth_user_groups ENABLE TRIGGER ALL;
967 ALTER table auth_user_user_permissions ENABLE TRIGGER ALL;
968 ALTER table forum_keyvalue ENABLE TRIGGER ALL;
969 ALTER table forum_action ENABLE TRIGGER ALL;
970 ALTER table forum_actionrepute ENABLE TRIGGER ALL;
971 ALTER table forum_subscriptionsettings ENABLE TRIGGER ALL;
972 ALTER table forum_validationhash ENABLE TRIGGER ALL;
973 ALTER table forum_authkeyuserassociation ENABLE TRIGGER ALL;
974 ALTER table forum_tag ENABLE TRIGGER ALL;
975 ALTER table forum_markedtag ENABLE TRIGGER ALL;
976 ALTER table forum_node ENABLE TRIGGER ALL;
977 ALTER table forum_nodestate ENABLE TRIGGER ALL;
978 ALTER table forum_node_tags ENABLE TRIGGER ALL;
979 ALTER table forum_noderevision ENABLE TRIGGER ALL;
980 ALTER table forum_node_tags ENABLE TRIGGER ALL;
981 ALTER table forum_questionsubscription ENABLE TRIGGER ALL;
982 ALTER table forum_vote ENABLE TRIGGER ALL;
983 ALTER table forum_flag ENABLE TRIGGER ALL;
984 ALTER table forum_badge ENABLE TRIGGER ALL;
985 ALTER table forum_award ENABLE TRIGGER ALL;
986 ALTER table forum_openidnonce ENABLE TRIGGER ALL;
987 ALTER table forum_openidassociation ENABLE TRIGGER ALL;
990 PG_SEQUENCE_RESETS = """
991 SELECT setval('"auth_user_id_seq"', coalesce(max("id"), 1) + 2, max("id") IS NOT null) FROM "auth_user";
992 SELECT setval('"auth_user_groups_id_seq"', coalesce(max("id"), 1) + 2, max("id") IS NOT null) FROM "auth_user_groups";
993 SELECT setval('"auth_user_user_permissions_id_seq"', coalesce(max("id"), 1) + 2, max("id") IS NOT null) FROM "auth_user_user_permissions";
994 SELECT setval('"forum_keyvalue_id_seq"', coalesce(max("id"), 1) + 2, max("id") IS NOT null) FROM "forum_keyvalue";
995 SELECT setval('"forum_action_id_seq"', coalesce(max("id"), 1) + 2, max("id") IS NOT null) FROM "forum_action";
996 SELECT setval('"forum_actionrepute_id_seq"', coalesce(max("id"), 1) + 2, max("id") IS NOT null) FROM "forum_actionrepute";
997 SELECT setval('"forum_subscriptionsettings_id_seq"', coalesce(max("id"), 1) + 2, max("id") IS NOT null) FROM "forum_subscriptionsettings";
998 SELECT setval('"forum_validationhash_id_seq"', coalesce(max("id"), 1) + 2, max("id") IS NOT null) FROM "forum_validationhash";
999 SELECT setval('"forum_authkeyuserassociation_id_seq"', coalesce(max("id"), 1) + 2, max("id") IS NOT null) FROM "forum_authkeyuserassociation";
1000 SELECT setval('"forum_tag_id_seq"', coalesce(max("id"), 1) + 2, max("id") IS NOT null) FROM "forum_tag";
1001 SELECT setval('"forum_markedtag_id_seq"', coalesce(max("id"), 1) + 2, max("id") IS NOT null) FROM "forum_markedtag";
1002 SELECT setval('"forum_node_id_seq"', coalesce(max("id"), 1) + 2, max("id") IS NOT null) FROM "forum_node";
1003 SELECT setval('"forum_nodestate_id_seq"', coalesce(max("id"), 1) + 2, max("id") IS NOT null) FROM "forum_nodestate";
1004 SELECT setval('"forum_node_tags_id_seq"', coalesce(max("id"), 1) + 2, max("id") IS NOT null) FROM "forum_node_tags";
1005 SELECT setval('"forum_noderevision_id_seq"', coalesce(max("id"), 1) + 2, max("id") IS NOT null) FROM "forum_noderevision";
1006 SELECT setval('"forum_node_tags_id_seq"', coalesce(max("id"), 1) + 2, max("id") IS NOT null) FROM "forum_node_tags";
1007 SELECT setval('"forum_questionsubscription_id_seq"', coalesce(max("id"), 1) + 2, max("id") IS NOT null) FROM "forum_questionsubscription";
1008 SELECT setval('"forum_vote_id_seq"', coalesce(max("id"), 1) + 2, max("id") IS NOT null) FROM "forum_vote";
1009 SELECT setval('"forum_flag_id_seq"', coalesce(max("id"), 1) + 2, max("id") IS NOT null) FROM "forum_flag";
1010 SELECT setval('"forum_badge_id_seq"', coalesce(max("id"), 1) + 2, max("id") IS NOT null) FROM "forum_badge";
1011 SELECT setval('"forum_award_id_seq"', coalesce(max("id"), 1) + 2, max("id") IS NOT null) FROM "forum_award";
1012 SELECT setval('"forum_openidnonce_id_seq"', coalesce(max("id"), 1) + 2, max("id") IS NOT null) FROM "forum_openidnonce";
1013 SELECT setval('"forum_openidassociation_id_seq"', coalesce(max("id"), 1) + 2, max("id") IS NOT null) FROM "forum_openidassociation";