summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rwxr-xr-xforum/management/commands/once_award_badges.py2
-rwxr-xr-xforum/models/__init__.py8
-rwxr-xr-xforum/models/base.py16
-rwxr-xr-xforum/views/writers.py9
-rw-r--r--stackexchange/management/commands/load_stackexchange.py96
5 files changed, 114 insertions, 17 deletions
diff --git a/forum/management/commands/once_award_badges.py b/forum/management/commands/once_award_badges.py
index 8c913348..372eb3aa 100755
--- a/forum/management/commands/once_award_badges.py
+++ b/forum/management/commands/once_award_badges.py
@@ -337,7 +337,7 @@ class Command(BaseCommand):
if user_id not in awarded_users:
user = get_object_or_404(User, id=user_id)
- award = Award(user=user, badge=badge)
+ award = Award(user=user, badge=badge)#todo: will this work with content_object null?
award.save()
awarded_users.append(user_id)
finally:
diff --git a/forum/models/__init__.py b/forum/models/__init__.py
index db66a227..c9a351bb 100755
--- a/forum/models/__init__.py
+++ b/forum/models/__init__.py
@@ -118,9 +118,7 @@ def record_answer_event(instance, created, **kwargs):
if created:
q_author = instance.question.author
found_match = False
- print 'going through %d messages' % q_author.message_set.all().count()
for m in q_author.message_set.all():
- print m.message
match = record_answer_event_re.search(m.message)
if match:
found_match = True
@@ -130,15 +128,11 @@ def record_answer_event(instance, created, **kwargs):
cnt = 1
m.message = u"You have received %d <a href=\"%s?sort=responses\">new responses</a>."\
% (cnt+1, q_author.get_profile_url())
- print 'updated message'
- print m.message
m.save()
break
if not found_match:
msg = u"You have received a <a href=\"%s?sort=responses\">new response</a>."\
% q_author.get_profile_url()
- print 'new message'
- print msg
q_author.message_set.create(message=msg)
activity = Activity(user=instance.author, \
@@ -201,7 +195,7 @@ def notify_award_message(instance, created, **kwargs):
+ u"Check out <a href=\"%s\">your profile</a>.") \
% (instance.badge.name, user.get_profile_url())
- user.message_set.create(message=message)
+ user.message_set.create(message=msg)
def record_answer_accepted(instance, created, **kwargs):
"""
diff --git a/forum/models/base.py b/forum/models/base.py
index 44fa6e66..56cb95be 100755
--- a/forum/models/base.py
+++ b/forum/models/base.py
@@ -120,10 +120,22 @@ class Content(models.Model):
except Exception:
logging.debug('problem pinging google did you register you sitemap with google?')
- def get_object_comments(self):
+ def get_comments(self):
comments = self.comments.all().order_by('id')
return comments
+ def add_comment(self, comment=None, user=None, added_at=None):
+ if added_at is None:
+ added_at = datetime.datetime.now()
+ if None in (comment ,user):
+ raise Exception('arguments comment and user are required')
+
+ Comment = models.get_model('forum','Comment')#todo: forum hardcoded
+ comment = Comment(content_object=self, comment=comment, user=user, added_at=added_at)
+ comment.save()
+ self.comment_count = self.comment_count + 1
+ self.save()
+
def post_get_last_update_info(self):
when = self.added_at
who = self.author
@@ -136,4 +148,4 @@ class Content(models.Model):
if c.added_at > when:
when = c.added_at
who = c.user
- return when, who \ No newline at end of file
+ return when, who
diff --git a/forum/views/writers.py b/forum/views/writers.py
index 52d910b5..a9406fdc 100755
--- a/forum/views/writers.py
+++ b/forum/views/writers.py
@@ -337,11 +337,10 @@ def __comments(request, obj, type):#non-view generic ajax handler to load commen
response = __generate_comments_json(obj, type, user)
elif request.method == "POST":
if auth.can_add_comments(user,obj):
- comment_data = request.POST.get('comment')
- comment = Comment(content_object=obj, comment=comment_data, user=request.user)
- comment.save()
- obj.comment_count = obj.comment_count + 1
- obj.save()
+ obj.add_comment(
+ comment = request.POST.get('comment'),
+ user = request.user,
+ )
response = __generate_comments_json(obj, type, user)
else:
response = HttpResponseForbidden(mimetype="application/json")
diff --git a/stackexchange/management/commands/load_stackexchange.py b/stackexchange/management/commands/load_stackexchange.py
index 7d47870e..d2262b8d 100644
--- a/stackexchange/management/commands/load_stackexchange.py
+++ b/stackexchange/management/commands/load_stackexchange.py
@@ -1,4 +1,6 @@
from django.core.management.base import BaseCommand
+from django.template.defaultfilters import slugify #todo: adopt unicode-aware slugify
+#todo: http://stackoverflow.com/questions/837828/how-to-use-a-slug-in-django
import os
import re
import sys
@@ -52,6 +54,14 @@ class X(object):#
'migrate','close','reopen','merge',
)
+ #badges whose names don't match exactly, but
+ #present in both SE and OSQA
+ badge_exceptions = {# SE --> OSQA
+ 'Citizen Patrol':'Citizen patrol',#single #todo: why sentence case?
+ 'Strunk &amp; White':'Strunk & White',#single
+ 'Civic Duty':'Civic duty',
+ }
+
revision_type_map = {
'Initial Title':'initial',
'Initial Body':'initial',
@@ -178,6 +188,10 @@ class X(object):#
badge_type = cls.badge_type_map[m.groupdict()['type']]
locals()[badge_type] = int(m.groupdict()['count'])
return (gold,silver,bronze)
+
+ @classmethod
+ def get_badge_name(cls, name):
+ return cls.badge_exceptions.get(name, name)
class Command(BaseCommand):
help = 'Loads StackExchange data from unzipped directory of XML files into the OSQA database'
@@ -202,6 +216,7 @@ class Command(BaseCommand):
self.transfer_badges()
self.transfer_votes()
self.transfer_favorites()
+ self.transfer_tag_preferences()
self.transfer_update_subscriptions()
self.transfer_flags()
self.transfer_meta_pages()
@@ -298,7 +313,11 @@ class Command(BaseCommand):
)
def _process_post_action_revision_group(self, rev_group):
- pass
+ #this is odd - there were no edit actions like these
+ #closed, reopened, etc in homeschoolers sample
+ print 'Warning: these content revisions were not processed'
+ print 'please give us your sample and we will write code to import it'
+ print ';'.join([rev.post_history_type.name for rev in rev_group])
def _process_post_revision_group(self, rev_group):
#determine revision type
@@ -312,6 +331,9 @@ class Command(BaseCommand):
else:
self._process_post_action_revision_group(rev_group)
+ def transfer_tag_preferences(self):
+ pass
+
def transfer_question_and_answer_activity(self):
"""transfers all question and answer
edits and related status changes
@@ -336,9 +358,79 @@ class Command(BaseCommand):
c_guid = se_rev.revision_guid
def transfer_comments(self):
- pass
+ for se_c in se.PostComment.objects.all():
+ if se_c.deletion_date:
+ print 'Warning deleted comment %d dropped' % se_c.id
+ continue
+ se_post = se_c.post
+ if se_post.post_type.name == 'Question':
+ osqa_post = QUESTION[se_post.id]
+ elif se_post.post_type.name == 'Answer':
+ osqa_post = ANSWER[se_post.id]
+
+ osqa_post.add_comment(
+ comment = se_c.text,
+ added_at = se_c.creation_date,
+ user = USER[se_c.user.id]
+ )
+
+ def _install_missing_badges(self):
+ self._missing_badges = {}
+ for se_b in se.Badge.objects.all():
+ name = X.get_badge_name(se_b.name)
+ try:
+ osqa.Badge.objects.get(name=name)
+ except:
+ self._missing_badges[name] = 0
+ if len(se_b.description) > 300:
+ print 'Warning truncated description for badge %d' % se_b.id
+ osqa.Badge.objects.create(
+ name = name,
+ slug = slugify(name),
+ description = se_b.description,
+ multiple = (not se_b.single),
+ type = se_b.class_type
+ )
+
+ def _award_badges(self):
+ #note: SE does not keep information on
+ #content-related badges like osqa does
+ for se_a in se.User2Badge.objects.all():
+ if se_a.user.id == -1:
+ continue #skip community user
+ u = USER[se_a.user.id]
+ badge_name = X.get_badge_name(se_a.badge.name)
+ b = osqa.Badge.objects.get(name=badge_name)
+ if b.multiple == False:
+ if b.award_badge.count() > 0:
+ continue
+ #todo: fake content object here b/c SE does not support this
+ #todo: but osqa requires related content object
+ osqa.Award.objects.create(
+ user=u,
+ badge=b,
+ awarded_at=se_a.date,
+ content_object=u,
+ )
+ if b.name in self._missing_badges:
+ self._missing_badges[b.name] += 1
+
+ def _cleanup_badges(self):
+ d = self._missing_badges
+ unused = [name for name in d.keys() if d[name] == 0]
+ osqa.Badge.objects.filter(name__in=unused).delete()
+ installed = [name for name in d.keys() if d[name] > 0]
+ print 'Warning - following unsupported badges were installed:'
+ print ', '.join(installed)
def transfer_badges(self):
+ #note: badge level is neglected
+ #1) install missing badges
+ self._install_missing_badges()
+ #2) award badges
+ self._award_badges()
+ #3) delete unused newly installed badges
+ self._cleanup_badges()
pass
def transfer_votes(self):