From fa803e983501c159302c30e87f7f82ef8c03746b Mon Sep 17 00:00:00 2001 From: hernani Date: Thu, 22 Apr 2010 12:09:13 +0000 Subject: [PATCH] beta version af the sx importer, don't use for importing production sites, only for testing git-svn-id: http://svn.osqa.net/svnroot/osqa/trunk@61 0cfe37f9-358a-4d5e-be75-b63607b5c754 --- forum/models/base.py | 2 +- forum/models/repute.py | 2 +- forum/models/user.py | 2 - forum/settings/__init__.py | 2 +- forum/skins/default/templates/footer.html | 6 +- forum/urls.py | 23 +- forum/views/commands.py | 2 +- forum/views/meta.py | 1 - forum/views/readers.py | 2 +- forum_modules/sximporter/__init__.py | 0 forum_modules/sximporter/importer.py | 458 +++++++++++++++++++ forum_modules/sximporter/orm.py | 299 ++++++++++++ forum_modules/sximporter/templates/page.html | 27 ++ forum_modules/sximporter/urls.py | 9 + forum_modules/sximporter/views.py | 17 + 15 files changed, 830 insertions(+), 22 deletions(-) create mode 100644 forum_modules/sximporter/__init__.py create mode 100644 forum_modules/sximporter/importer.py create mode 100644 forum_modules/sximporter/orm.py create mode 100644 forum_modules/sximporter/templates/page.html create mode 100644 forum_modules/sximporter/urls.py create mode 100644 forum_modules/sximporter/views.py diff --git a/forum/models/base.py b/forum/models/base.py index 41f4481..43668d9 100644 --- a/forum/models/base.py +++ b/forum/models/base.py @@ -61,7 +61,7 @@ class CachedManager(models.Manager): denorm_update = django.dispatch.Signal(providing_args=["instance", "field", "old", "new"]) -class DenormalizedField(models.PositiveIntegerField): +class DenormalizedField(models.IntegerField): __metaclass__ = models.SubfieldBase def contribute_to_class(self, cls, name): diff --git a/forum/models/repute.py b/forum/models/repute.py index 6457de2..0c54c1b 100644 --- a/forum/models/repute.py +++ b/forum/models/repute.py @@ -82,7 +82,7 @@ class Award(GenericContent, UserContent): self.user.save() class Meta: - unique_together = ('content_type', 'object_id', 'user', 'badge') + #unique_together = ('content_type', 'object_id', 'user', 'badge') app_label = 'forum' db_table = u'award' diff --git a/forum/models/user.py b/forum/models/user.py index eaa1516..abb3989 100644 --- a/forum/models/user.py +++ b/forum/models/user.py @@ -121,12 +121,10 @@ class User(BaseModel, DjangoUser): self.message_set.all().delete() def get_profile_url(self): - """Returns the URL for this User's profile.""" return "/%s%d/%s" % (_('users/'), self.id, slugify(self.username)) def get_profile_link(self): profile_link = u'%s' % (self.get_profile_url(),self.username) - logging.debug('in get profile link %s' % profile_link) return mark_safe(profile_link) def get_vote_count_today(self): diff --git a/forum/settings/__init__.py b/forum/settings/__init__.py index 5a8b308..c208978 100644 --- a/forum/settings/__init__.py +++ b/forum/settings/__init__.py @@ -5,7 +5,7 @@ from forms import ImageFormWidget from django.forms.widgets import Textarea from django.utils.translation import ugettext_lazy as _ -INTERNAL_VERSION = Setting('INTERNAL_VERSION', "58") +INTERNAL_VERSION = Setting('INTERNAL_VERSION', "59") SETTINGS_PACK = Setting('SETTINGS_PACK', "default") from basic import * diff --git a/forum/skins/default/templates/footer.html b/forum/skins/default/templates/footer.html index 66ea2bc..518318d 100644 --- a/forum/skins/default/templates/footer.html +++ b/forum/skins/default/templates/footer.html @@ -1,7 +1,6 @@ - {% load extra_tags %} {% load i18n %} - +
- {% if settings.GOOGLE_ANALYTICS_KEY %} {% endif %} - + diff --git a/forum/urls.py b/forum/urls.py index 2fea646..cb97329 100644 --- a/forum/urls.py +++ b/forum/urls.py @@ -18,7 +18,19 @@ sitemaps = { } APP_PATH = os.path.dirname(__file__) -urlpatterns = patterns('', + +from forum.modules import get_modules_script + +module_patterns = get_modules_script('urls') + +urlpatterns = patterns('') + +for pattern_file in module_patterns: + pattern = getattr(pattern_file, 'urlpatterns', None) + if pattern: + urlpatterns += pattern + +urlpatterns += patterns('', url(r'^$', app.readers.index, name='index'), url(r'^sitemap.xml$', 'django.contrib.sitemaps.views.sitemap', {'sitemaps': sitemaps}, name='sitemap'), #(r'^favicon\.ico$', 'django.views.generic.simple.redirect_to', {'url': '/media/images/favicon.ico'}), @@ -125,12 +137,3 @@ urlpatterns = patterns('', url(r'^feeds/rss/$', RssLastestQuestionsFeed, name="latest_questions_feed"), ) -from forum.modules import get_modules_script - -module_patterns = get_modules_script('urls') - -for pattern_file in module_patterns: - pattern = getattr(pattern_file, 'urlpatterns', None) - if pattern: - urlpatterns += pattern - diff --git a/forum/views/commands.py b/forum/views/commands.py index b129911..ee62af4 100644 --- a/forum/views/commands.py +++ b/forum/views/commands.py @@ -43,7 +43,7 @@ class AnonymousNotAllowedException(Exception): class NotEnoughLeftException(Exception): def __init__(self, action, limit): - super(NotEnoughRepPointsException, self).__init__( + super(NotEnoughLeftException, self).__init__( _(""" Sorry, but you don't have enough %(action)s left for today..
The limit is %(limit)s per day..
diff --git a/forum/views/meta.py b/forum/views/meta.py index c15f8f6..940bc4a 100644 --- a/forum/views/meta.py +++ b/forum/views/meta.py @@ -23,7 +23,6 @@ def about(request): def faq(request): data = { 'gravatar_faq_url': reverse('faq') + '#gravatar', - #'send_email_key_url': reverse('send_email_key'), 'ask_question_url': reverse('ask'), } return render_to_response('faq.html', data, context_instance=RequestContext(request)) diff --git a/forum/views/readers.py b/forum/views/readers.py index ac20dae..31efdce 100644 --- a/forum/views/readers.py +++ b/forum/views/readers.py @@ -200,7 +200,7 @@ def update_question_view_times(request, question): def match_question_slug(slug): slug_words = slug.split('-') - qs = Question.objects.filter(title__istartswith=slug_words[0]) + qs = Question.objects.filter(node_type="question", title__istartswith=slug_words[0]) for q in qs: if slug == urlquote(slugify(q.title)): diff --git a/forum_modules/sximporter/__init__.py b/forum_modules/sximporter/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/forum_modules/sximporter/importer.py b/forum_modules/sximporter/importer.py new file mode 100644 index 0000000..fb69930 --- /dev/null +++ b/forum_modules/sximporter/importer.py @@ -0,0 +1,458 @@ +# -*- coding: utf-8 -*- + +from xml.dom import minidom +from datetime import datetime +import time +import re +from django.utils.translation import ugettext as _ +from django.template.defaultfilters import slugify +from orm import orm + +def getText(el): + rc = "" + for node in el.childNodes: + if node.nodeType == node.TEXT_NODE: + rc = rc + node.data + return rc.strip() + +msstrip = re.compile(r'^(.*)\.\d+') +def readTime(ts): + noms = msstrip.match(ts) + if noms: + ts = noms.group(1) + + return datetime(*time.strptime(ts, '%Y-%m-%dT%H:%M:%S')[0:6]) + +def readEl(el): + return dict([(n.tagName.lower(), getText(n)) for n in el.childNodes if n.nodeType == el.ELEMENT_NODE]) + +def readTable(dump, name): + return [readEl(e) for e in minidom.parseString(dump.read("%s.xml" % name)).getElementsByTagName('row')] + +class UnknownUser(object): + counter = 0 + def __init__(self): + UnknownUser.counter += 1 + self.number = UnknownUser.counter + + def __str__(self): + return _("Unknown user %(number)d") % {'number': self.number} + + def __unicode__(self): + return self.__str__() + + def encode(self, *args): + return self.__str__() + +class IdMapper(dict): + def __getitem__(self, key): + key = int(key) + return super(IdMapper, self).get(key, key) + + def __setitem__(self, key, value): + super(IdMapper, self).__setitem__(int(key), int(value)) + +openidre = re.compile('^https?\:\/\/') +def userimport(dump, options): + users = readTable(dump, "Users") + + user_by_name = {} + uidmapper = IdMapper() + merged_users = [] + + owneruid = options.get('owneruid', None) + #check for empty values + if not owneruid: + owneruid = None + + for sxu in users: + create = True + + if sxu.get('id') == '-1': + continue + + if int(sxu.get('id')) == int(owneruid): + osqau = orm.User.objects.get(id=1) + uidmapper[owneruid] = 1 + uidmapper[-1] = 1 + create = False + else: + username = sxu.get('displayname', sxu.get('displaynamecleaned', sxu.get('realname', UnknownUser()))) + + if not isinstance(username, UnknownUser) and username in user_by_name: + if options.get('mergesimilar', False) and sxu.get('email', 'INVALID') == user_by_name[username].email: + osqau = user_by_name[username] + create = False + uidmapper[sxu.get('id')] = osqau.id + else: + inc = 1 + while ("%s %d" % (username, inc)) in user_by_name: + inc += 1 + + username = "%s %d" % (username, inc) + + sxbadges = sxu.get('badgesummary', None) + badges = {'1':'0','2':'0','3':'0'} + + if sxbadges: + badges.update(dict([b.split('=') for b in sxbadges.split()])) + + if create: + osqau = orm.User( + id = sxu.get('id'), + username = unicode(username), + password = '!', + email = sxu.get('email', ''), + is_superuser = sxu.get('usertypeid') == '5', + is_staff = sxu.get('usertypeid') == '4', + is_active = True, + date_joined = readTime(sxu.get('creationdate')), + about = sxu.get('aboutme', ''), + date_of_birth = sxu.get('birthday', None) and readTime(sxu['birthday']) or None, + email_isvalid = int(sxu.get('usertypeid')) > 2, + website = sxu.get('websiteurl', ''), + reputation = int(sxu.get('reputation')), + gold = int(badges['1']), + silver = int(badges['2']), + bronze = int(badges['3']), + real_name = sxu.get('realname', ''), + ) + + osqau.save() + + s = orm.SubscriptionSettings(user=osqau) + s.save() + + user_by_name[osqau.username] = osqau + else: + new_about = sxu.get('aboutme', None) + if new_about and osqau.about != new_about: + if osqau.about: + osqau.about = "%s\n|\n%s" % (osqau.about, new_about) + else: + osqau.about = new_about + + osqau.username = sxu.get('displayname', sxu.get('displaynamecleaned', sxu.get('realname', UnknownUser()))) + osqau.email = sxu.get('email', '') + osqau.reputation += int(sxu.get('reputation')) + osqau.gold += int(badges['1']) + osqau.silver += int(badges['2']) + osqau.bronze += int(badges['3']) + + merged_users.append(osqau.id) + osqau.save() + + + openid = sxu.get('openid', None) + if openid and openidre.match(openid): + assoc = orm.AuthKeyUserAssociation(user=osqau, key=openid, provider="openidurl") + assoc.save() + + if uidmapper[-1] == -1: + uidmapper[-1] = 1 + + return (uidmapper, merged_users) + +def tagsimport(dump, uidmap): + tags = readTable(dump, "Tags") + + tagmap = {} + + for sxtag in tags: + otag = orm.Tag( + id = int(sxtag['id']), + name = sxtag['name'], + used_count = int(sxtag['count']), + created_by_id = uidmap[sxtag['userid']], + ) + otag.save() + + tagmap[otag.name] = otag + + return tagmap + +def postimport(dump, uidmap, tagmap): + history = {} + all = {} + + for h in readTable(dump, "PostHistory"): + if not history.get(h.get('postid'), None): + history[h.get('postid')] = [] + + history[h.get('postid')].append(h) + + posts = readTable(dump, "Posts") + + for sxpost in posts: + accepted = {} + + postclass = sxpost.get('posttypeid') == '1' and orm.Question or orm.Answer + + post = postclass( + id = sxpost['id'], + added_at = readTime(sxpost['creationdate']), + body = sxpost['body'], + score = sxpost.get('score', 0), + vote_up_count = 0, + vote_down_count = 0 + ) + + if sxpost.get('deletiondate', None): + post.deleted = True + post.deleted_at = readTime(sxpost['deletiondate']) + post.author_id = 1 + else: + post.author_id = uidmap[sxpost['owneruserid']] + + if sxpost.get('lasteditoruserid', None): + post.last_edited_by_id = uidmap[sxpost.get('lasteditoruserid')] + post.last_edited_at = readTime(sxpost['lasteditdate']) + + if sxpost.get('communityowneddate', None): + post.wiki = True + post.wikified_at = readTime(sxpost['communityowneddate']) + + if sxpost.get('posttypeid') == '1': #question + post.node_type = "question" + post.title = sxpost['title'] + + tagnames = sxpost['tags'].replace(u'ö', '-').replace(u'é', '').replace(u'à', '') + post.tagnames = tagnames + + post.view_count = sxpost.get('viewcount', 0) + post.favourite_count = sxpost.get('favoritecount', 0) + post.answer_count = sxpost.get('answercount', 0) + + if sxpost.get('lastactivityuserid', None): + post.last_activity_by_id = uidmap[sxpost['lastactivityuserid']] + post.last_activity_at = readTime(sxpost['lastactivitydate']) + + if sxpost.get('closeddate', None): + post.closed = True + post.closed_by_id = 1 + post.closed_at = datetime.now() + + if sxpost.get('acceptedanswerid', None): + accepted[int(sxpost.get('acceptedanswerid'))] = post + + else: + post.node_type = "answer" + post.parent_id = sxpost['parentid'] + + if int(post.id) in accepted: + question = accepted[int(post.id)] + question.accepted_answer_id = post + question.save() + + post.accepted = True + post.accepted_at = datetime.now() + post.accepted_by_id = question.author_id + + all[int(post.id)] = post + + return all + +def comment_import(dump, uidmap, posts): + comments = readTable(dump, "PostComments") + currid = max(posts.keys()) + mapping = {} + + for sxc in comments: + currid += 1 + oc = orm.Node( + id = currid, + node_type = "comment", + added_at = readTime(sxc['creationdate']), + author_id = uidmap[sxc['userid']], + body = sxc['text'], + parent_id = sxc.get('postid'), + vote_up_count = 0, + vote_down_count = 0 + ) + + if sxc.get('deletiondate', None): + oc.deleted = True + oc.deleted_at = readTime(sxc['deletiondate']) + oc.deleted_by_id = uidmap[sxc['deletionuserid']] + oc.author_id = uidmap[sxc['deletionuserid']] + else: + oc.author_id = uidmap[sxc['userid']] + + + posts[oc.id] = oc + mapping[int(sxc['id'])] = int(oc.id) + + return posts, mapping + + +def save_posts(posts, tagmap): + for post in posts.values(): + post.save() + + if post.node_type == "question": + tags = filter(lambda t: t is not None, [tagmap.get(n, None) for n in post.tagnames.split()]) + post.tagnames = " ".join([t.name for t in tags]).strip() + post.tags = tags + + create_and_activate_revision(post) + + +def create_and_activate_revision(post): + rev = orm.NodeRevision( + author_id = post.author_id, + body = post.body, + node_id = post.id, + revised_at = post.added_at, + revision = 1, + summary = 'Initial revision', + tagnames = post.tagnames, + title = post.title, + ) + + rev.save() + post.active_revision_id = rev.id + post.save() + + +def post_vote_import(dump, uidmap, posts): + votes = readTable(dump, "Posts2Votes") + + for sxv in votes: + if sxv['votetypeid'] in ('2', '3'): + ov = orm.Vote( + node_id = sxv['postid'], + user_id = uidmap[sxv['userid']], + voted_at = readTime(sxv['creationdate']), + vote = sxv['votetypeid'] == '2' and 1 or -1, + ) + + if sxv['votetypeid'] == '2': + posts[int(sxv['postid'])].vote_up_count += 1 + else: + posts[int(sxv['postid'])].vote_down_count += 1 + + ov.save() + +def comment_vote_import(dump, uidmap, comments, posts): + votes = readTable(dump, "Comments2Votes") + + for sxv in votes: + if sxv['votetypeid'] in ('2', '3'): + ov = orm.Vote( + node_id = comments[int(sxv['postcommentid'])], + user_id = uidmap[sxv['userid']], + voted_at = readTime(sxv['creationdate']), + vote = sxv['votetypeid'] == '2' and 1 or -1, + ) + + if sxv['votetypeid'] == '2': + posts[comments[int(sxv['postcommentid'])]].vote_up_count += 1 + else: + posts[comments[int(sxv['postcommentid'])]].vote_down_count += 1 + + ov.save() + + + +def badges_import(dump, uidmap): + node_ctype = orm['contenttypes.contenttype'].objects.get(name='node') + obadges = dict([(b.slug, b) for b in orm.Badge.objects.all()]) + sxbadges = dict([(int(b['id']), b) for b in readTable(dump, "Badges")]) + + sx_to_osqa = {} + + for id, sxb in sxbadges.items(): + slug = slugify(sxb['name'].replace('&', 'and')) + if slug in obadges: + sx_to_osqa[id] = obadges[slug] + else: + osqab = orm.Badge( + name = sxb['name'], + slug = slugify(sxb['name']), + description = sxb['description'], + multiple = sxb.get('single', 'false') == 'false', + awarded_count = 0, + type = sxb['class'] + ) + osqab.save() + sx_to_osqa[id] = osqab + + sxawards = readTable(dump, "Users2Badges") + osqaawards = [] + + for sxa in sxawards: + badge = sx_to_osqa[int(sxa['badgeid'])] + osqaa = orm.Award( + user_id = uidmap[sxa['userid']], + badge = badge, + content_type = node_ctype, + object_id = 1 + ) + + osqaawards.append(osqaa) + badge.awarded_count += 1 + + for b in sx_to_osqa.values(): + b.save() + + for a in osqaawards: + a.save() + + +def reset_sequences(): + from south.db import db + if db.backend_name == "postgres": + db.start_transaction() + db.execute_many(PG_SEQUENCE_RESETS) + db.commit_transaction() + +def sximport(dump, options): + uidmap, merged_users = userimport(dump, options) + tagmap = tagsimport(dump, uidmap) + posts = postimport(dump, uidmap, tagmap) + posts, comments = comment_import(dump, uidmap, posts) + save_posts(posts, tagmap) + post_vote_import(dump, uidmap, posts) + comment_vote_import(dump, uidmap, comments, posts) + for post in posts.values(): + post.save() + badges_import(dump, uidmap) + + from south.db import db + db.commit_transaction() + + reset_sequences() + + + +PG_SEQUENCE_RESETS = """ +SELECT setval('"auth_user_groups_id_seq"', coalesce(max("id"), 1) + 2, max("id") IS NOT null) FROM "auth_user_groups"; +SELECT setval('"auth_user_user_permissions_id_seq"', coalesce(max("id"), 1) + 2, max("id") IS NOT null) FROM "auth_user_user_permissions"; +SELECT setval('"activity_id_seq"', coalesce(max("id"), 1) + 2, max("id") IS NOT null) FROM "activity"; +SELECT setval('"forum_subscriptionsettings_id_seq"', coalesce(max("id"), 1) + 2, max("id") IS NOT null) FROM "forum_subscriptionsettings"; +SELECT setval('"forum_validationhash_id_seq"', coalesce(max("id"), 1) + 2, max("id") IS NOT null) FROM "forum_validationhash"; +SELECT setval('"forum_authkeyuserassociation_id_seq"', coalesce(max("id"), 1) + 2, max("id") IS NOT null) FROM "forum_authkeyuserassociation"; +SELECT setval('"tag_id_seq"', coalesce(max("id"), 1) + 2, max("id") IS NOT null) FROM "tag"; +SELECT setval('"forum_markedtag_id_seq"', coalesce(max("id"), 1) + 2, max("id") IS NOT null) FROM "forum_markedtag"; +SELECT setval('"forum_node_id_seq"', coalesce(max("id"), 1) + 2, max("id") IS NOT null) FROM "forum_node"; +SELECT setval('"forum_node_tags_id_seq"', coalesce(max("id"), 1) + 2, max("id") IS NOT null) FROM "forum_node_tags"; +SELECT setval('"forum_noderevision_id_seq"', coalesce(max("id"), 1) + 2, max("id") IS NOT null) FROM "forum_noderevision"; +SELECT setval('"forum_node_tags_id_seq"', coalesce(max("id"), 1) + 2, max("id") IS NOT null) FROM "forum_node_tags"; +SELECT setval('"forum_node_tags_id_seq"', coalesce(max("id"), 1) + 2, max("id") IS NOT null) FROM "forum_node_tags"; +SELECT setval('"favorite_question_id_seq"', coalesce(max("id"), 1) + 2, max("id") IS NOT null) FROM "favorite_question"; +SELECT setval('"forum_questionsubscription_id_seq"', coalesce(max("id"), 1) + 2, max("id") IS NOT null) FROM "forum_questionsubscription"; +SELECT setval('"forum_node_tags_id_seq"', coalesce(max("id"), 1) + 2, max("id") IS NOT null) FROM "forum_node_tags"; +SELECT setval('"vote_id_seq"', coalesce(max("id"), 1) + 2, max("id") IS NOT null) FROM "vote"; +SELECT setval('"flagged_item_id_seq"', coalesce(max("id"), 1) + 2, max("id") IS NOT null) FROM "flagged_item"; +SELECT setval('"badge_id_seq"', coalesce(max("id"), 1) + 2, max("id") IS NOT null) FROM "badge"; +SELECT setval('"award_id_seq"', coalesce(max("id"), 1) + 2, max("id") IS NOT null) FROM "award"; +SELECT setval('"repute_id_seq"', coalesce(max("id"), 1) + 2, max("id") IS NOT null) FROM "repute"; +SELECT setval('"forum_node_tags_id_seq"', coalesce(max("id"), 1) + 2, max("id") IS NOT null) FROM "forum_node_tags"; +SELECT setval('"forum_keyvalue_id_seq"', coalesce(max("id"), 1) + 2, max("id") IS NOT null) FROM "forum_keyvalue"; +SELECT setval('"forum_openidnonce_id_seq"', coalesce(max("id"), 1) + 2, max("id") IS NOT null) FROM "forum_openidnonce"; +SELECT setval('"forum_openidassociation_id_seq"', coalesce(max("id"), 1) + 2, max("id") IS NOT null) FROM "forum_openidassociation"; +""" + + + + \ No newline at end of file diff --git a/forum_modules/sximporter/orm.py b/forum_modules/sximporter/orm.py new file mode 100644 index 0000000..c0898c3 --- /dev/null +++ b/forum_modules/sximporter/orm.py @@ -0,0 +1,299 @@ +from south.v2 import DataMigration +from south.orm import FakeORM + +class Migration(DataMigration): + + def forwards(self, orm): + + 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': {'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', 'blank': 'True'}), + 'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}), + 'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}), + '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': {'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.activity': { + 'Meta': {'object_name': 'Activity', 'db_table': "u'activity'"}, + 'active_at': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), + 'activity_type': ('django.db.models.fields.SmallIntegerField', [], {}), + 'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'is_auditted': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}), + 'object_id': ('django.db.models.fields.PositiveIntegerField', [], {}), + 'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['forum.User']"}) + }, + 'forum.anonymousnode': { + 'Meta': {'object_name': 'AnonymousNode', '_ormbases': ['forum.Node']}, + 'convertible_to': ('django.db.models.fields.CharField', [], {'default': "'node'", 'max_length': '16'}), + 'node_ptr': ('django.db.models.fields.related.OneToOneField', [], {'to': "orm['forum.Node']", 'unique': 'True', 'primary_key': 'True'}), + 'validation_hash': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'anonymous_content'", 'to': "orm['forum.Node']"}) + }, + 'forum.answer': { + 'Meta': {'object_name': 'Answer', '_ormbases': ['forum.Node'], 'db_table': "u'answer'"}, + 'accepted': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}), + 'accepted_at': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}), + 'accepted_by': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['forum.User']", 'null': 'True'}), + 'node_ptr': ('django.db.models.fields.related.OneToOneField', [], {'to': "orm['forum.Node']", 'unique': 'True', 'primary_key': 'True'}), + 'wiki': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}), + 'wikified_at': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}) + }, + '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': "(('content_type', 'object_id', 'user', 'badge'),)", 'object_name': 'Award', 'db_table': "u'award'"}, + 'awarded_at': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), + 'badge': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'award_badge'", 'to': "orm['forum.Badge']"}), + 'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'notified': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}), + 'object_id': ('django.db.models.fields.PositiveIntegerField', [], {}), + 'user': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'awards'", 'to': "orm['forum.User']"}) + }, + 'forum.badge': { + 'Meta': {'unique_together': "(('name', 'type'),)", 'object_name': 'Badge', 'db_table': "u'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']"}), + 'description': ('django.db.models.fields.CharField', [], {'max_length': '300'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'multiple': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '50'}), + 'slug': ('django.db.models.fields.SlugField', [], {'db_index': 'True', 'max_length': '50', 'blank': 'True'}), + 'type': ('django.db.models.fields.SmallIntegerField', [], {}) + }, + 'forum.favoritequestion': { + 'Meta': {'unique_together': "(('question', 'user'),)", 'object_name': 'FavoriteQuestion', 'db_table': "u'favorite_question'"}, + 'added_at': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'question': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['forum.Question']"}), + 'user': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'user_favorite_questions'", 'to': "orm['forum.User']"}) + }, + 'forum.flaggeditem': { + 'Meta': {'object_name': 'FlaggedItem', 'db_table': "u'flagged_item'"}, + 'canceled': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}), + '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': "'flaggeditems'", 'null': 'True', 'to': "orm['forum.Node']"}), + 'reason': ('django.db.models.fields.CharField', [], {'max_length': '300', 'null': 'True'}), + 'user': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'flaggeditems'", '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', [], {}) + }, + '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', [], {}), + 'comment_count': ('django.db.models.fields.PositiveIntegerField', [], {'default': '0'}), + 'deleted': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}), + 'deleted_at': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}), + 'deleted_by': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'deleted_nodes'", 'null': 'True', 'to': "orm['forum.User']"}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'last_edited_at': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}), + 'last_edited_by': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'last_edited_nodes'", 'null': 'True', 'to': "orm['forum.User']"}), + 'node_type': ('django.db.models.fields.CharField', [], {'default': "'node'", 'max_length': '16'}), + 'offensive_flag_count': ('django.db.models.fields.SmallIntegerField', [], {'default': '0'}), + 'parent': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'children'", 'null': 'True', 'to': "orm['forum.Node']"}), + 'score': ('django.db.models.fields.IntegerField', [], {'default': '0'}), + 'tagnames': ('django.db.models.fields.CharField', [], {'max_length': '125'}), + 'tags': ('django.db.models.fields.related.ManyToManyField', [], {'related_name': "'nodes'", 'to': "orm['forum.Tag']"}), + 'title': ('django.db.models.fields.CharField', [], {'max_length': '300'}), + 'vote_down_count': ('django.db.models.fields.IntegerField', [], {'default': '0'}), + 'vote_up_count': ('django.db.models.fields.IntegerField', [], {'default': '0'}) + }, + '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.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.question': { + 'Meta': {'object_name': 'Question', '_ormbases': ['forum.Node'], 'db_table': "u'question'"}, + 'accepted_answer': ('django.db.models.fields.related.OneToOneField', [], {'related_name': "'question_accepting'", 'unique': 'True', 'null': 'True', 'to': "orm['forum.Answer']"}), + 'answer_count': ('django.db.models.fields.PositiveIntegerField', [], {'default': '0'}), + 'close_reason': ('django.db.models.fields.SmallIntegerField', [], {'null': 'True', 'blank': 'True'}), + 'closed': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}), + 'closed_at': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}), + 'closed_by': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'closed_questions'", 'null': 'True', 'to': "orm['forum.User']"}), + 'favorited_by': ('django.db.models.fields.related.ManyToManyField', [], {'related_name': "'favorite_questions'", 'through': "'FavoriteQuestion'", 'to': "orm['forum.User']"}), + 'favourite_count': ('django.db.models.fields.IntegerField', [], {'default': '0'}), + 'last_activity_at': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), + 'last_activity_by': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'last_active_in_questions'", 'null': 'True', 'to': "orm['forum.User']"}), + 'node_ptr': ('django.db.models.fields.related.OneToOneField', [], {'to': "orm['forum.Node']", 'unique': 'True'}), + 'subscribers': ('django.db.models.fields.related.ManyToManyField', [], {'related_name': "'subscriptions'", 'through': "'QuestionSubscription'", 'to': "orm['forum.User']"}), + 'view_count': ('django.db.models.fields.IntegerField', [], {'default': '0'}), + 'wiki': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}), + 'wikified_at': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}) + }, + 'forum.questionsubscription': { + 'Meta': {'object_name': 'QuestionSubscription'}, + 'auto_subscription': ('django.db.models.fields.BooleanField', [], {'default': 'True', 'blank': 'True'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'last_view': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime(2010, 4, 17, 2, 50, 12, 337000)'}), + 'question': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['forum.Question']"}), + 'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['forum.User']"}) + }, + 'forum.repute': { + 'Meta': {'object_name': 'Repute', 'db_table': "u'repute'"}, + 'canceled': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'node': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'reputes'", 'null': 'True', 'to': "orm['forum.Node']"}), + 'question': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['forum.Question']"}), + 'reputation_type': ('django.db.models.fields.SmallIntegerField', [], {}), + 'reputed_at': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), + 'user': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'reputes'", 'to': "orm['forum.User']"}), + 'user_previous_rep': ('django.db.models.fields.IntegerField', [], {'default': '0'}), + 'value': ('django.db.models.fields.SmallIntegerField', [], {'default': '0'}) + }, + 'forum.subscriptionsettings': { + 'Meta': {'object_name': 'SubscriptionSettings'}, + 'all_questions': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}), + 'all_questions_watched_tags': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}), + 'enable_notifications': ('django.db.models.fields.BooleanField', [], {'default': 'True', 'blank': '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': "'d'", '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', 'blank': 'True'}), + 'notify_answers': ('django.db.models.fields.BooleanField', [], {'default': 'True', 'blank': 'True'}), + 'notify_comments': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}), + 'notify_comments_own_post': ('django.db.models.fields.BooleanField', [], {'default': 'True', 'blank': 'True'}), + 'notify_reply_to_comments': ('django.db.models.fields.BooleanField', [], {'default': 'True', 'blank': 'True'}), + 'questions_answered': ('django.db.models.fields.BooleanField', [], {'default': 'True', 'blank': 'True'}), + 'questions_asked': ('django.db.models.fields.BooleanField', [], {'default': 'True', 'blank': 'True'}), + 'questions_commented': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}), + 'questions_viewed': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': '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': {'object_name': 'Tag', 'db_table': "u'tag'"}, + 'created_by': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'created_tags'", 'to': "orm['forum.User']"}), + 'deleted': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}), + 'deleted_at': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}), + 'deleted_by': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'deleted_tags'", 'null': 'True', '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.SmallIntegerField', [], {'default': '0'}), + 'date_of_birth': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}), + 'email_isvalid': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}), + 'email_key': ('django.db.models.fields.CharField', [], {'max_length': '32', 'null': 'True'}), + 'gold': ('django.db.models.fields.SmallIntegerField', [], {'default': '0'}), + 'hide_ignored_questions': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}), + 'is_approved': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}), + 'last_seen': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), + 'location': ('django.db.models.fields.CharField', [], {'max_length': '100', 'blank': 'True'}), + 'questions_per_page': ('django.db.models.fields.SmallIntegerField', [], {'default': '10'}), + 'real_name': ('django.db.models.fields.CharField', [], {'max_length': '100', 'blank': 'True'}), + 'reputation': ('django.db.models.fields.PositiveIntegerField', [], {'default': '1'}), + 'silver': ('django.db.models.fields.SmallIntegerField', [], {'default': '0'}), + '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.validationhash': { + 'Meta': {'unique_together': "(('user', 'type'),)", 'object_name': 'ValidationHash'}, + 'expiration': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime(2010, 4, 18, 2, 50, 12, 421000)'}), + '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': {'object_name': 'Vote', 'db_table': "u'vote'"}, + 'canceled': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'node': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'votes'", 'null': 'True', 'to': "orm['forum.Node']"}), + 'user': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'votes'", 'to': "orm['forum.User']"}), + 'vote': ('django.db.models.fields.SmallIntegerField', [], {}), + 'voted_at': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}) + } + } + + complete_apps = ['forum'] + +orm = FakeORM(Migration, "forum") + diff --git a/forum_modules/sximporter/templates/page.html b/forum_modules/sximporter/templates/page.html new file mode 100644 index 0000000..0011d1d --- /dev/null +++ b/forum_modules/sximporter/templates/page.html @@ -0,0 +1,27 @@ +{% extends "osqaadmin/base.html" %} + +{% load i18n %} +{% load user_tags %} + +{% block subtitle %} + {% trans "SX Importer" %} +{% endblock %} +{% block description %} + {% trans "Welcome to Stack Exchange dump importer." %} +{% endblock %} + +{% block admincontent %} +
+
+ {% trans "Your user id in stack exchange" %} +
+ + + {% trans "Merge users with same user name and email" %}
+ + +
+ {% for n in names %} +

{{ n }}

+ {% endfor %} +{% endblock %} \ No newline at end of file diff --git a/forum_modules/sximporter/urls.py b/forum_modules/sximporter/urls.py new file mode 100644 index 0000000..85fa636 --- /dev/null +++ b/forum_modules/sximporter/urls.py @@ -0,0 +1,9 @@ +from django.conf.urls.defaults import * +from django.views.generic.simple import direct_to_template +from django.utils.translation import ugettext as _ + +from views import sximporter + +urlpatterns = patterns('', + url(r'^%s%s$' % (_('admin/'), _('sximporter/')), sximporter, name='sximporter'), +) \ No newline at end of file diff --git a/forum_modules/sximporter/views.py b/forum_modules/sximporter/views.py new file mode 100644 index 0000000..fb0bcd1 --- /dev/null +++ b/forum_modules/sximporter/views.py @@ -0,0 +1,17 @@ +from django.shortcuts import render_to_response +from django.template import RequestContext +from forum.views.admin import super_user_required +import importer +from zipfile import ZipFile + +@super_user_required +def sximporter(request): + list = [] + if request.method == "POST" and "dump" in request.FILES: + dump = ZipFile(request.FILES['dump']) + importer.sximport(dump, request.POST) + dump.close() + + return render_to_response('modules/sximporter/page.html', { + 'names': list + }, context_instance=RequestContext(request)) \ No newline at end of file -- 2.45.2