from askbot.models import BadgeData from askbot.models import FavoriteQuestion from askbot.models import Group from askbot.models import ImportedObjectInfo from askbot.models import Post from askbot.models import Tag from askbot.models import Thread from askbot.models import User from askbot.management.commands.base import BaseImportXMLCommand from django.conf import settings as django_settings from django.contrib.auth.models import Group as AuthGroup from django.contrib.contenttypes.models import ContentType from django.db import transaction from django.db.models import Q if 'avatar' in django_settings.INSTALLED_APPS: from avatar.models import Avatar def get_status_rank(status): """returns integer rank of user account status, the larger is the number the higher is the status""" if len(status) != 1: #default status - approved user status = 'a' try: return 'bswamd'.index(status) except ValueError: return 0 class Command(BaseImportXMLCommand): help = 'Adds XML askbot data produced by the "dumpdata" command' def handle_import(self): self.read_content_types() self.import_groups() self.import_users() #we don't import subscriptions if 'avatar' in django_settings.INSTALLED_APPS: self.import_avatars() #we need this to link old user ids to #new users' personal groups #self.record_personal_groups() self.import_user_logins() self.import_tags() self.import_marked_tags() self.import_threads() self.apply_groups_to_threads() #model="askbot.posttogroup"> self.import_posts('question', save_redirects=True) self.import_posts('answer') self.import_posts('comment') self.import_post_revisions() self.apply_groups_to_posts() self.apply_question_followers() self.import_votes() self.import_badges() self.import_badge_awards() self.delete_new_messages() #we'll try to ignore importing this #model="askbot.activity" def log_personal_group(self, group): info = ImportedObjectInfo() info.old_id = group.id info.new_id = int(group.name.split('_')[-1]) info.model = 'personal_group' info.run = self.run info.save() def get_group_by_old_id(self, old_id): normal_group = self.get_imported_object_by_old_id(AuthGroup, old_id) if normal_group: return Group.objects.get(group_ptr=normal_group) log = ImportedObjectInfo.objects.get( model='personal_group', old_id=old_id, run=self.run ) old_user_id = log.new_id new_user = self.get_imported_object_by_old_id(User, old_user_id) return new_user.get_personal_group() def read_content_types(self): """reads content types from the data dump and makes dictionary with keys of old content type ids and values - active content type objects""" ctypes_map = dict() for old_ctype in self.get_objects_for_model('contenttypes.contenttype'): try: new_ctype = ContentType.objects.get( app_label=old_ctype.app_label, model=old_ctype.model ) except ContentType.DoesNotExist: continue ctypes_map[old_ctype.id] = new_ctype self.content_types_map = ctypes_map """ activity askbot activity """ def get_content_type_by_old_id(self, old_ctype_id): return self.content_types_map[old_ctype_id] @transaction.commit_manually def import_groups(self): """imports askbot group profiles""" #redirects_file = self.open_unique_file('group_redirects') #1) we import auth groups for group in self.get_objects_for_model('auth.group'): #old_url = group.get_absolute_url() if group.name.startswith('_personal'): #we don't import these groups, but log #associations between old user ids and old personal #group ids, because we create the personal groups #anew and so need to have a connection #old personal group id --> old user id --> new user id # --> new pers. group id self.log_personal_group(group) continue old_group_id = group.id try: group = AuthGroup.objects.get(name=group.name) except AuthGroup.DoesNotExist: group.id = None group.save() transaction.commit() #new_url = group.get_absolute_url() #if old_url != new_url: # redirects_file.write('%s %s\n' % (old_url, new_url)) #we will later populate memberships only in these groups self.log_action_with_old_id(old_group_id, group) if transaction.is_dirty(): transaction.commit() #redirects_file.close() #2) we import askbot group profiles only for groups for profile in self.get_objects_for_model('askbot.group'): auth_group = self.get_imported_object_by_old_id(AuthGroup, profile.group_ptr_id) if auth_group is None or auth_group.name.startswith('_personal'): continue #if profile for this group does not exist, then create new profile and save try: existing_profile = Group.objects.get(group_ptr__id=auth_group.id) self.copy_string_parameter(profile, existing_profile, 'logo_url') self.merge_words_parameter(profile, existing_profile, 'preapproved_emails') self.merge_words_parameter(profile, existing_profile, 'preapproved_email_domains') existing_profile.save() except Group.DoesNotExist: new_profile = Group.objects.create( name=auth_group.name, logo_url=profile.logo_url, preapproved_emails=profile.preapproved_emails, preapproved_email_domains=profile.preapproved_email_domains ) new_profile.save() transaction.commit() if transaction.is_dirty(): transaction.commit() def import_users(self): redirects_file = self.open_unique_file('user_redirects') model_path = str(User._meta) dupes = 0 for from_user in self.get_objects_for_model('auth.user'): log_info = dict() log_info['notify_user'] = list() old_url = from_user.get_absolute_url() try: to_user = User.objects.get(email=from_user.email) dupes += 1 except User.DoesNotExist: username = self.get_safe_username(from_user.username) if username != from_user.username: template = 'Your user name was changed from %s to %s' log_info['notify_user'].append(template % (from_user.username, username)) to_user = User.objects.create_user(username, from_user.email) #copy the data if from_user.username != to_user.username: names = (from_user.username, to_user.username) log_info['notify_user'].append('Your user name has changed from %s to %s' % names) self.copy_string_parameter(from_user, to_user, 'first_name') self.copy_string_parameter(from_user, to_user, 'last_name') self.copy_string_parameter(from_user, to_user, 'real_name') self.copy_string_parameter(from_user, to_user, 'website') self.copy_string_parameter(from_user, to_user, 'location') to_user.country = from_user.country self.copy_string_parameter(from_user, to_user, 'about') self.copy_string_parameter(from_user, to_user, 'email_signature') self.copy_string_parameter(from_user, to_user, 'twitter_access_token') self.copy_string_parameter(from_user, to_user, 'twitter_handle') self.merge_words_parameter(from_user, to_user, 'interesting_tags') self.merge_words_parameter(from_user, to_user, 'ignored_tags') self.merge_words_parameter(from_user, to_user, 'subscribed_tags') self.merge_words_parameter(from_user, to_user, 'languages') if to_user.password == '!' and from_user.password != '!': to_user.password = from_user.password self.copy_bool_parameter(from_user, to_user, 'is_staff') self.copy_bool_parameter(from_user, to_user, 'is_active') self.copy_bool_parameter(from_user, to_user, 'is_superuser') self.copy_bool_parameter(from_user, to_user, 'is_fake', operator='and') self.copy_bool_parameter(from_user, to_user, 'email_isvalid', operator='and') self.copy_bool_parameter(from_user, to_user, 'show_country') self.copy_bool_parameter(from_user, to_user, 'show_marked_tags') self.copy_numeric_parameter(from_user, to_user, 'last_login') self.copy_numeric_parameter(from_user, to_user, 'last_seen') self.copy_numeric_parameter(from_user, to_user, 'date_joined', operator='min') self.copy_numeric_parameter(from_user, to_user, 'email_tag_filter_strategy') self.copy_numeric_parameter(from_user, to_user, 'display_tag_filter_strategy') self.copy_numeric_parameter( from_user, to_user, 'consecutive_days_visit_count', operator='sum' ) self.copy_numeric_parameter(from_user, to_user, 'social_sharing_mode') #position of character in this string == rank of status if get_status_rank(from_user.status) > get_status_rank(to_user.status): to_user.status = from_user.status to_user.save() new_url = to_user.get_absolute_url() self.write_redirect(old_url, new_url, redirects_file) group_ids = self.get_m2m_ids_for_field(from_user, 'groups') for group_id in group_ids: #get group by old id, #if group is private - skip, #otherwise join this group group = self.get_imported_object_by_old_id(Group, int(group_id)) if group is None or group.name.startswith('_personal'): continue #unfortunately, xml dump does not allow us to know of the membership status #as m2m user -> group does not contain id of the m2m bridge relation, but #only id of the group itself to_user.join_group(group, force=True) """ these were not imported: 1 0 0 0 0 0 """ self.log_action(from_user, to_user, extra_info=log_info) redirects_file.close() def import_avatars(self): """imports user avatar, chooses later uploaded primary avatar""" for avatar in self.get_objects_for_model('avatar.avatar'): user = self.get_imported_object_by_old_id(User, avatar.user_id) if avatar.primary: #get other primary avatar and make the later one as primary try: existing_avatar = Avatar.objects.get(user=user, primary=True) if existing_avatar.date_uploaded > avatar.date_uploaded: avatar.primary = False else: existing_avatar.primary = False existing_avatar.save() except Avatar.DoesNotExist: pass avatar.user = user avatar.id = None avatar.save() """ 33 True avatars/Valdir Barbosa/ValdirBarbosa.png 2013-08-22T16:45:01.517315 """ def import_marked_tags(self): #model="askbot.markedtag"> for mark in self.get_objects_for_model('askbot.markedtag'): tag = self.get_imported_object_by_old_id(Tag, mark.tag_id) user = self.get_imported_object_by_old_id(User, mark.user_id) user.mark_tags(tagnames=tag.name, reason=mark.reason, action='add') """ 13 205 good """ @transaction.commit_manually def import_user_logins(self): #logins_soup = self.soup.find_all('object', {'model': 'django_authopenid.userassociation'}) #for login_info in self.get_objects_for_model('django_authopenid.userassociation'): #for login_ for association in self.get_objects_for_model('django_authopenid.userassociation'): #where possible, we should copy the login, but respecting the #uniqueness constraints: ('user','provider_name'), ('openid_url', 'provider_name') #1) get new user by old id user = self.get_imported_object_by_old_id(User, association.user_id) try: association.id = None association.user = user association.save() transaction.commit() except: transaction.rollback() def import_tags(self): """imports tag objects""" for tag in self.get_objects_for_model('askbot.tag'): old_tag_id = tag.id try: #try to get existing tag with this name tag = Tag.objects.get(name__iexact=tag.name, language_code=tag.language_code) except Tag.DoesNotExist: tag.id = None tag.tag_wiki = None tag.created_by = self.get_imported_object_by_old_id(User, tag.created_by_id) tag.deleted_by = self.get_imported_object_by_old_id(User, tag.deleted_by_id) tag.save() self.log_action_with_old_id(old_tag_id, tag) def import_threads(self): """import thread objects""" count = 0 for thread in self.get_objects_for_model('askbot.thread'): count += 1 new_thread = Thread( title=thread.title, tagnames=thread.tagnames, view_count=thread.view_count, favourite_count=thread.favourite_count, answer_count=thread.answer_count, last_activity_at=thread.last_activity_at, last_activity_by=self.get_imported_object_by_old_id(User, thread.last_activity_by_id), language_code=thread.language_code, closed_by=self.get_imported_object_by_old_id(User, thread.closed_by_id), closed=thread.closed, closed_at=thread.closed_at, close_reason=thread.close_reason, deleted=thread.deleted, approved=thread.approved, answer_accepted_at=thread.answer_accepted_at, added_at=thread.added_at, ) #apply tags to threads tag_names = thread.get_tag_names() if tag_names: tag_filter = Q(name__iexact=tag_names[0]) for tag_name in tag_names[1:]: tag_filter |= Q(name__iexact=tag_name) tags = Tag.objects.filter(tag_filter & Q(language_code=thread.language_code)) new_thread.tagnames = ' '.join([tag.name for tag in tags]) new_thread.save() for tag in tags: new_thread.tags.add(tag) tag.used_count += 1 tag.save() else: new_thread.save() self.log_action(thread, new_thread) """ these are not handled here 0 """ def apply_question_followers(self): """mark followed questions""" for fave in self.get_objects_for_model('askbot.favoritequestion'): #askbot.favoritequestion user = self.get_imported_object_by_old_id(User, fave.user_id) thread = self.get_imported_object_by_old_id(Thread, fave.thread_id) user.toggle_favorite_question(thread._question_post(), timestamp=fave.added_at) """ 8 32 2012-12-28T17:34:17.289056 """ def apply_groups_to_threads(self): for link in self.get_objects_for_model('askbot.threadtogroup'): thread = self.get_imported_object_by_old_id(Thread, link.thread_id) group = self.get_group_by_old_id(link.group_id) thread.add_to_groups([group,], visibility=link.visibility) def import_posts(self, post_type, save_redirects=False): """imports posts of specific post_type""" if save_redirects: redirects_file = self.open_unique_file('question_redirects') for post in self.get_objects_for_model('askbot.post'): if post.post_type != post_type: continue #this line is a bit risky, but should work if we import things in correct order post.parent = self.get_imported_object_by_old_id(Post, post.parent_id) post.thread = self.get_imported_object_by_old_id(Thread, post.thread_id) if save_redirects: old_url = post.get_absolute_url(thread=post.thread) post.author = self.get_imported_object_by_old_id(User, post.author_id) post.deleted_by = self.get_imported_object_by_old_id(User, post.deleted_by_id) post.locked_by = self.get_imported_object_by_old_id(User, post.locked_by_id) post.last_edited_by = self.get_imported_object_by_old_id(User, post.last_edited_by_id) post.points = 0 post.vote_up_count = 0 post.vote_down_count = 0 post.offensive_flag_count = 0 old_post_id = post.id post.id = None post.save() if save_redirects: new_url = post.get_absolute_url() self.write_redirect(old_url, new_url, redirects_file) self.log_action_with_old_id(old_post_id, post) if save_redirects: redirects_file.close() """ these were not imported votes 0 0 """ def apply_groups_to_posts(self): for link in self.get_objects_for_model('askbot.posttogroup'): post = self.get_imported_object_by_old_id(Post, link.post_id) group = self.get_group_by_old_id(link.group_id) post.add_to_groups([group,]) def import_post_revisions(self): for revision in self.get_objects_for_model('askbot.postrevision'): revision.post = self.get_imported_object_by_old_id(Post, revision.post_id) revision.author = self.get_imported_object_by_old_id(User, revision.author_id) revision.approved_by = self.get_imported_object_by_old_id(User, revision.approved_by_id) revision.id = None revision.save() def import_badges(self): """imports badgedata objects""" for badge in self.get_objects_for_model('askbot.badgedata'): #here we need to make sure that we don't create duplicate badges old_badge_id = badge.id try: new_badge = BadgeData.objects.get(slug=badge.slug) except BadgeData.DoesNotExist: new_badge = badge new_badge.id = None new_badge.awarded_count = 0 #we will re-award this, restart count new_badge.save() self.log_action_with_old_id(old_badge_id, new_badge) """ taxonomist 9 """ def import_badge_awards(self): for award in self.get_objects_for_model('askbot.award'): award.user = self.get_imported_object_by_old_id(User, award.user_id) badge = self.get_imported_object_by_old_id(BadgeData, award.badge_id) #if multiple or user does not have this badge, then award if badge.is_multiple() or (not award.user.has_badge(badge)): award.badge = badge content_type = self.get_content_type_by_old_id(award.content_type_id) obj_class = content_type.model_class() award.object_id = self.get_imported_object_id_by_old_id(obj_class, award.object_id) award.content_type = content_type award.id = None award.save() """ 2 10 30 1 2012-10-22T18:09:13.527031 False """ def import_votes(self): for vote in self.get_objects_for_model('askbot.vote'): post = self.get_imported_object_by_old_id(Post, vote.voted_post_id) user = self.get_imported_object_by_old_id(User, vote.user_id) if vote.vote == 1: user.upvote(post, timestamp=vote.voted_at) else: user.downvote(post, timestamp=vote.voted_at) """ 8 20 1 2012-12-26T19:10:08.334818 """