def update_topic_stats(self):
        self.stdout.write("\n *** set topic stats...\n")

        topics = Topic.objects.all()
        total = topics.count()
        process_info = ProcessInfo(total, use_last_rates=4)
        start_time = time.time()
        next_status = time.time() + 0.25
        for count, topic in enumerate(topics):
            if time.time() > next_status:
                next_status = time.time() + 1
                rest, eta, rate = process_info.update(count)
                msg = (
                    "\r\t%i/%i topics... rest: %i - eta: %s (rate: %.1f/sec)         "
                ) % (count, total, rest, eta, rate)
                self.stdout.write(msg)
                self.stdout.flush()

            queryset = Post.objects.only("created", "updated").filter(topic=topic)
            topic.post_count = queryset.count()
            try:
                last_post = queryset.latest("updated")
            except Post.DoesNotExist:
                # there is no post in this forum
                pass
            else:
                topic.last_post = last_post
                if last_post.updated:
                    topic.updated = last_post.updated
                else:
                    topic.updated = last_post.created
            topic.save()

        duration = time.time() - start_time
        rate = float(count) / duration
        self.stdout.write(
            "\r *** %i topic stats set in %s (rate: %.1f/sec)\n" % (
                count, human_duration(duration), rate
            )
        )
Exemple #2
0
    def update_topic_stats(self):
        self.out(u"\n *** set topic stats...\n")

        topics = Topic.objects.all()
        total = topics.count()
        process_info = ProcessInfo(total, use_last_rates=4)
        start_time = time.time()
        next_status = time.time() + 0.25
        for count, topic in enumerate(topics, 1):
            if time.time() > next_status:
                next_status = time.time() + 1
                rest, eta, rate = process_info.update(count)
                self.out_update(
                    "\t%i/%i topics... rest: %i - eta: %s (rate: %.1f/sec)" %
                    (count, total, rest, eta, rate))

            queryset = Post.objects.only("created",
                                         "updated").filter(topic=topic)
            topic.post_count = queryset.count()
            try:
                last_post = queryset.latest("updated")
            except Post.DoesNotExist:
                # there is no post in this forum
                pass
            else:
                topic.last_post = last_post
                if last_post.updated:
                    topic.updated = last_post.updated
                else:
                    topic.updated = last_post.created
            topic.save()

        duration = time.time() - start_time
        rate = float(count) / duration
        self.out_overwrite(" *** %i topic stats set in %s (rate: %.1f/sec)" %
                           (count, human_duration(duration), rate))
Exemple #3
0
    def migrate_posts(self, user_dict):
        self.out(u"\n *** Migrate phpBB posts entries...\n")

        anonymous_user = self._get_anonymous_user(
        )  # Pseudo account from phpBB

        posts = phpbb_Post.objects.all().order_by("time")
        total = posts.count()
        process_info = ProcessInfo(total, use_last_rates=4)
        start_time = time.time()
        next_status = start_time + 0.25
        for count, phpbb_post in enumerate(posts, 1):
            if self.max_entries and count >= self.max_entries:
                self.warn("Skip rest of posts because max_entries used!")
                break

            if time.time() > next_status:
                next_status = time.time() + 1
                rest, eta, rate = process_info.update(count)
                self.out_update(
                    "\t%i/%i posts migrated... rest: %i - eta: %s (rate: %.1f/sec)"
                    % (count, total, rest, eta, rate))

            topic_id = phpbb_post.topic_id
            try:
                topic = Topic.objects.get(id=topic_id)
            except Topic.DoesNotExist:
                self.out_overwrite(
                    self.style.NOTICE(
                        "topic for post %i doesn't exist! Skip post." %
                        phpbb_post.id))
                continue

            phpbb_user_id = phpbb_post.poster_id
            try:
                user = user_dict[phpbb_user_id]
            except KeyError:
                self.out_overwrite(
                    self.style.NOTICE(
                        "phpBB User with ID %i doesn't exist for post %i. Use Anonymous."
                        % (phpbb_user_id, phpbb_post.id)))
                user = anonymous_user

            if phpbb_post.edit_user > 0 and phpbb_post.edit_time > 0:
                updated = phpbb_post.update_datetime()
                try:
                    updated_by = user_dict[phpbb_post.edit_user]
                except KeyError:
                    updated_by = anonymous_user
            else:
                updated = None
                updated_by = None

            try:
                post = Post.objects.create(
                    id=phpbb_post.id,
                    topic=topic,
                    user=user,
                    created=phpbb_post.create_datetime(),
                    updated=updated,
                    updated_by=updated_by,
                    markup="bbcode",
                    body=phpbb_post.get_cleaned_bbcode(),
                    #body_html=html, # would be generated in save()
                    user_ip=phpbb_post.poster_ip,
                )
            except Exception, err:
                raise
                msg = (
                    "\n +++ ERROR: creating Post entry for phpBB3 post (ID: %s):\n"
                    "%s\n") % (phpbb_post.id, err)
                self.out_overwrite(self.style.NOTICE(msg))
                continue

            if phpbb_post.has_attachment():
                # copy attachment files
                phpbb_attachments = phpbb_Attachment.objects.filter(
                    post_msg=phpbb_post)
                for phpbb_attachment in phpbb_attachments:
                    src_path = os.path.join(settings.PHPBB_ATTACHMENT_PATH,
                                            phpbb_attachment.physical_filename)
                    if not os.path.isfile(src_path):
                        self.warn(
                            "\r\n +++ ERROR: Attachment not found: '%s'\n" %
                            src_path)
                    else:
                        attachment = Attachment(
                            size=phpbb_attachment.filesize,
                            content_type=phpbb_attachment.mimetype,
                            name=phpbb_attachment.real_filename,
                            post=post)
                        filename = "%d.0" % post.id
                        dst_path = os.path.join(
                            settings.MEDIA_ROOT,
                            forum_settings.ATTACHMENT_UPLOAD_TO, filename)
                        shutil.copy(src_path, dst_path)
                        attachment.path = filename
                        attachment.save()
                        self.out_overwrite(
                            "\t *** Attachment %s copied in: %s" %
                            (attachment.name, dst_path))
Exemple #4
0
    def migrate_topic(self, user_dict, forum_dict):
        self.out(u"\n *** Migrate phpBB topic entries...\n")

        self.out(u"\tget topic watch information...")
        self.stdout.flush()
        topic_watch = get_topic_watch()
        self.out(u"OK\n")
        self.stdout.flush()

        anonymous_user = self._get_anonymous_user(
        )  # Pseudo account from phpBB

        topics = phpbb_Topic.objects.all().order_by("time")
        total = topics.count()
        process_info = ProcessInfo(total, use_last_rates=4)
        start_time = time.time()
        next_status = start_time + 0.25
        for count, topic in enumerate(topics, 1):
            if self.max_entries and count >= self.max_entries:
                self.warn("Skip rest of topics because max_entries used!")
                break

            if time.time() > next_status:
                next_status = time.time() + 1
                rest, eta, rate = process_info.update(count)
                self.out_update(
                    "\t%i/%i topics migrated... rest: %i - eta: %s (rate: %.1f/sec)"
                    % (count, total, rest, eta, rate))

            if topic.moved():
                # skip moved topics -> DjangoBB doesn't support them
                continue

            phpbb_user_id = topic.poster_id  #topic.poster.id
            try:
                user = user_dict[phpbb_user_id]
            except KeyError:
                self.out_overwrite(
                    self.style.NOTICE(
                        "topic %i poster: phpBB User with ID %i doesn't exist. Use Anonymous."
                        % (topic.id, phpbb_user_id)))
                user = anonymous_user

            forum = forum_dict[topic.forum_id]

            if topic.type in (1, 2, 3):
                # convert sticky, announce and global post to sticky
                # 0 == NORMAL, 1 == STICKY, 2 == ANNOUNCE, 3 == GLOBAL
                sticky = True
            else:
                sticky = False

            obj = Topic.objects.create(
                id=topic.id,
                forum=forum,
                user=user,
                name=topic.clean_title(),
                created=topic.create_datetime(),
                views=topic.views,
                sticky=sticky,
                closed=topic.locked(),

                # These attributes would be set later in update_topic_stats():
                # updated, post_count, last_post
            )
            if topic.id in topic_watch:
                subscribers = []
                phpbb_user_ids = topic_watch[topic.id]
                for phpbb_user_id in phpbb_user_ids:
                    try:
                        user = user_dict[phpbb_user_id]
                    except KeyError:
                        continue  # Skip not existing users.
                    subscribers.append(user)

                obj.subscribers = subscribers
                obj.save()

        duration = time.time() - start_time
        rate = float(count) / duration
        self.out_overwrite(" *** %i topics migrated in %s (rate: %.1f/sec)" %
                           (count, human_duration(duration), rate))
Exemple #5
0
    def migrate_users(self, cleanup_users, moderator_groups):
        self.out(u"\n *** Migrate phpbb_forum users...\n")

        lang_codes = [i[0] for i in settings.LANGUAGES]
        default_lang = settings.LANGUAGE_CODE.split("-")[0]

        moderators = []
        user_dict = {}
        phpbb_users = phpbb_User.objects.all()

        total = phpbb_users.count()
        process_info = ProcessInfo(total, use_last_rates=4)
        skip_count = 0
        start_time = time.time()
        next_status = start_time + 0.25
        for count, phpbb_user in enumerate(phpbb_users, 1):
            if self.max_entries and count >= self.max_entries:
                self.warn("Skip rest of users because max_entries used!")
                break

            if time.time() > next_status:
                next_status = time.time() + 1
                rest, eta, rate = process_info.update(count)
                self.out_update(
                    "\t%i/%i users migrated %i skiped... rest: %i - eta: %s (rate: %.1f/sec)"
                    % (count, total, skip_count, rest, eta, rate))

            if not phpbb_user.posts:
                #assert phpbb_user.has_content() == False

                # Only users with has no posts can be skip.
                if cleanup_users >= 1:
                    if not phpbb_user.email:
                        skip_count += 1
                        if self.verbosity >= 2:
                            self.out_overwrite(
                                u"\t * Skip '%s' (no email)" %
                                smart_unicode(phpbb_user.username))
                        continue
                if cleanup_users >= 2:
                    if not phpbb_user.lastvisit:
                        skip_count += 1
                        if self.verbosity >= 2:
                            self.out_overwrite(
                                u"\t * Skip '%s' (no lastvisit)" %
                                smart_unicode(phpbb_user.username))
                        continue
                if cleanup_users >= 3:
                    if not phpbb_user.posts:
                        skip_count += 1
                        if self.verbosity >= 2:
                            self.out_overwrite(
                                u"\t * Skip '%s' (no posts)" %
                                smart_unicode(phpbb_user.username))
                        continue

            last_login = phpbb_user.lastvisit_datetime()
            if not last_login:
                # can't be None in User model:
                last_login = datetime.datetime(year=datetime.MINYEAR,
                                               month=1,
                                               day=1)

            is_moderator = phpbb_user.group in moderator_groups
            is_active = phpbb_user.inactive_time == 0

            # Prefix the password, e.g.: "$H$9dwN..." -> "phpBB3_md5$H$9dwN..."
            phpbb_password = PHPBB_PASSWORD % phpbb_user.password

            django_user, created = User.objects.get_or_create(
                username=phpbb_user.username,
                defaults={
                    "email": phpbb_user.email,
                    "password": phpbb_password,
                    "is_staff": is_moderator,
                    "is_active": is_active,
                    "is_superuser": False,
                    "last_login": last_login,
                    "date_joined": phpbb_user.registration_datetime(),
                })
            if created:
                if self.verbosity >= 2:
                    self.out_overwrite(u"\tUser '%s' created." %
                                       smart_unicode(django_user.username))
            else:
                if self.verbosity >= 2:
                    self.out_overwrite(u"\tUser '%s' exists." %
                                       smart_unicode(django_user.username))
                if django_user.password in (None, "", "!"):
                    # Update old migration
                    django_user.password = phpbb_password
                django_user.is_staff = is_moderator
                django_user.is_active = is_active
                django_user.save()

            if is_moderator:
                if self.verbosity >= 1:
                    self.out_overwrite(
                        u"\t *** Mark user '%s' as global forum moderator" %
                        phpbb_user)
                moderators.append(django_user)

            user_dict[phpbb_user.id] = django_user

            tz = TZ_CHOICES[int(phpbb_user.timezone)][0]
            #print tz

            # TODO: migrate avatar, too!
            # see:
            # https://github.com/jedie/django-phpBB3/issues/6

            if phpbb_user.lang in lang_codes:
                language = phpbb_user.lang
            else:
                language = default_lang

            cleaned_signature = phpbb_user.get_cleaned_signature()

            user_profile, created = Profile.objects.get_or_create(
                user=django_user,
                defaults={
                    "site": phpbb_user.website,
                    "signature": cleaned_signature,
                    #"signature_html": phpbb_user.sig,
                    "post_count": phpbb_user.posts,
                    "yahoo": phpbb_user.yim,
                    "time_zone": tz,
                    "language": language,
                    "jabber": phpbb_user.jabber,
                    "icq": phpbb_user.icq,
                    "msn": phpbb_user.msnm,
                    "aim": phpbb_user.aim,
                })
            if created:
                if self.verbosity >= 2:
                    self.out_overwrite(u"\t - User profile for '%s' created." %
                                       smart_unicode(django_user.username))
            else:
                if self.verbosity >= 2:
                    self.out_overwrite(u"\t - User profile for '%s' exists." %
                                       smart_unicode(django_user.username))

        duration = time.time() - start_time
        rate = float(count) / duration
        self.out_overwrite(
            u" *** %i users migrated %i skiped in %s (rate: %.1f/sec)" %
            (count, skip_count, human_duration(duration), rate))

        return user_dict, moderators
    def migrate_posts(self, user_dict, topic_dict):
        self.stdout.write("\n *** Migrate phpBB posts entries...\n")

        posts = phpbb_Post.objects.all().order_by("time")
        total = posts.count()
        process_info = ProcessInfo(total, use_last_rates=4)
        count = 0
        start_time = time.time()
        next_status = start_time + 0.25
        for phpbb_post in posts:
            count += 1
            if time.time() > next_status:
                next_status = time.time() + 1
                rest, eta, rate = process_info.update(count)
                msg = (
                    "\r\t%i/%i posts migrated... rest: %i - eta: %s (rate: %.1f/sec)         "
                ) % (count, total, rest, eta, rate)
                self.stdout.write(msg)
                self.stdout.flush()

            topic = topic_dict[phpbb_post.topic.id]
            user = user_dict[phpbb_post.poster.id]

            if phpbb_post.edit_user > 0 and phpbb_post.edit_time > 0:
                updated = phpbb_post.update_datetime()
                updated_by = user_dict[phpbb_post.edit_user]
            else:
                updated = None
                updated_by = None

            try:
                post = Post.objects.create(
                    id=phpbb_post.id,
                    topic=topic,
                    user=user,
                    created=phpbb_post.create_datetime(),
                    updated=updated,
                    updated_by=updated_by,
                    markup="bbcode",
                    body=phpbb_post.get_cleaned_bbcode(),
                    #body_html=html, # would be generated in save()
                    user_ip=phpbb_post.poster_ip,
                )
            except Exception, err:
                msg = (
                    "\n +++ ERROR: creating Post entry for phpBB3 post (ID: %s):\n"
                    "%s\n"
                ) % (phpbb_post.id, err)
                self._warn(msg)
                continue

            if phpbb_post.has_attachment():
                # copy attachment files
                phpbb_attachment = phpbb_Attachment.objects.get(post_msg=phpbb_post)
                src_path = os.path.join(settings.PHPBB_ATTACHMENT_PATH, phpbb_attachment.physical_filename)
                if not os.path.isfile(src_path):
                    self._warn("\n +++ ERROR: Attachment not found: '%s'\n" % src_path)
                else:
                    attachment = Attachment(
                        size=phpbb_attachment.filesize,
                        content_type=phpbb_attachment.mimetype,
                        name=phpbb_attachment.real_filename,
                        post=post
                    )
                    filename = "%d.0" % post.id
                    dst_path = os.path.join(
                        settings.MEDIA_ROOT, forum_settings.ATTACHMENT_UPLOAD_TO,
                        filename
                    )
                    shutil.copy(src_path, dst_path)
                    attachment.path = filename
                    attachment.save()
                    self.stdout.write(
                        "\n\t *** Attachment %s copied in: %s\n" % (
                            attachment, dst_path
                        )
                    )
                    self.stdout.flush()
    def migrate_topic(self, user_dict, forum_dict):
        self.stdout.write("\n *** Migrate phpBB topic entries...\n")

        self.stdout.write("\tget topic watch information...")
        self.stdout.flush()
        topic_watch = get_topic_watch()
        self.stdout.write("OK\n")
        self.stdout.flush()

        topic_dict = {}
        topics = phpbb_Topic.objects.all().order_by("time")
        total = topics.count()
        process_info = ProcessInfo(total, use_last_rates=4)
        count = 0
        start_time = time.time()
        next_status = start_time + 0.25
        for topic in topics:
            count += 1
            if time.time() > next_status:
                next_status = time.time() + 1
                rest, eta, rate = process_info.update(count)
                msg = (
                    "\r\t%i/%i topics migrated... rest: %i - eta: %s (rate: %.1f/sec)         "
                ) % (count, total, rest, eta, rate)
                self.stdout.write(msg)
                self.stdout.flush()

            if topic.moved():
                # skip moved topics -> DjangoBB doesn't support them
                continue

            user = user_dict[topic.poster.id]
            forum = forum_dict[topic.forum.id]

            if topic.type in (1, 2, 3):
                # convert sticky, announce and global post to sticky
                # 0 == NORMAL, 1 == STICKY, 2 == ANNOUNCE, 3 == GLOBAL
                sticky = True
            else:
                sticky = False

            obj = Topic.objects.create(
                id=topic.id,
                forum=forum,
                user=user,
                name=topic.clean_title(),
                created=topic.create_datetime(),
                views=topic.views,
                sticky=sticky,
                closed=topic.locked(),

                # These attributes would be set later in update_topic_stats():
                # updated, post_count, last_post
            )
            if topic.id in topic_watch:
                subscribers = [user_dict[user_id] for user_id in topic_watch[topic.id]]
                obj.subscribers = subscribers
                obj.save()

            topic_dict[topic.id] = obj

        duration = time.time() - start_time
        rate = float(count) / duration
        self.stdout.write(
            "\r *** %i topics migrated in %s (rate: %.1f/sec)\n" % (
                count, human_duration(duration), rate
            )
        )
        return topic_dict
    def migrate_posts(self, user_dict):
        self.out(u"\n *** Migrate phpBB posts entries...\n")

        anonymous_user = self._get_anonymous_user() # Pseudo account from phpBB

        posts = phpbb_Post.objects.all().order_by("time")
        total = posts.count()
        process_info = ProcessInfo(total, use_last_rates=4)
        start_time = time.time()
        next_status = start_time + 0.25
        for count, phpbb_post in enumerate(posts, 1):
            if self.max_entries and count >= self.max_entries:
                self.warn("Skip rest of posts because max_entries used!")
                break

            if time.time() > next_status:
                next_status = time.time() + 1
                rest, eta, rate = process_info.update(count)
                self.out_update(
                    "\t%i/%i posts migrated... rest: %i - eta: %s (rate: %.1f/sec)" % (
                        count, total, rest, eta, rate
                    )
                )

            topic_id = phpbb_post.topic_id
            try:
                topic = Topic.objects.get(id=topic_id)
            except Topic.DoesNotExist:
                self.out_overwrite(self.style.NOTICE(
                    "topic for post %i doesn't exist! Skip post." % phpbb_post.id
                ))
                continue

            phpbb_user_id = phpbb_post.poster_id
            try:
                user = user_dict[phpbb_user_id]
            except KeyError:
                self.out_overwrite(self.style.NOTICE(
                    "phpBB User with ID %i doesn't exist for post %i. Use Anonymous." % (
                        phpbb_user_id, phpbb_post.id
                    )
                ))
                user = anonymous_user


            if phpbb_post.edit_user > 0 and phpbb_post.edit_time > 0:
                updated = phpbb_post.update_datetime()
                try:
                    updated_by = user_dict[phpbb_post.edit_user]
                except KeyError:
                    updated_by = anonymous_user
            else:
                updated = None
                updated_by = None

            try:
                post = Post.objects.create(
                    id=phpbb_post.id,
                    topic=topic,
                    user=user,
                    created=phpbb_post.create_datetime(),
                    updated=updated,
                    updated_by=updated_by,
                    markup="bbcode",
                    body=phpbb_post.get_cleaned_bbcode(),
                    #body_html=html, # would be generated in save()
                    user_ip=phpbb_post.poster_ip,
                )
            except Exception, err:
                raise
                msg = (
                    "\n +++ ERROR: creating Post entry for phpBB3 post (ID: %s):\n"
                    "%s\n"
                ) % (phpbb_post.id, err)
                self.out_overwrite(self.style.NOTICE(msg))
                continue

            if phpbb_post.has_attachment():
                # copy attachment files
                phpbb_attachments = phpbb_Attachment.objects.filter(post_msg=phpbb_post)
                for phpbb_attachment in phpbb_attachments:
                    src_path = os.path.join(settings.PHPBB_ATTACHMENT_PATH, phpbb_attachment.physical_filename)
                    if not os.path.isfile(src_path):
                        self.warn("\r\n +++ ERROR: Attachment not found: '%s'\n" % src_path)
                    else:
                        attachment = Attachment(
                            size=phpbb_attachment.filesize,
                            content_type=phpbb_attachment.mimetype,
                            name=phpbb_attachment.real_filename,
                            post=post
                        )
                        filename = "%d.0" % post.id
                        dst_path = os.path.join(
                            settings.MEDIA_ROOT, forum_settings.ATTACHMENT_UPLOAD_TO,
                            filename
                        )
                        shutil.copy(src_path, dst_path)
                        attachment.path = filename
                        attachment.save()
                        self.out_overwrite(
                            "\t *** Attachment %s copied in: %s" % (
                                attachment.name, dst_path
                            )
                        )
    def migrate_topic(self, user_dict, forum_dict):
        self.out(u"\n *** Migrate phpBB topic entries...\n")

        self.out(u"\tget topic watch information...")
        self.stdout.flush()
        topic_watch = get_topic_watch()
        self.out(u"OK\n")
        self.stdout.flush()

        anonymous_user = self._get_anonymous_user() # Pseudo account from phpBB

        topics = phpbb_Topic.objects.all().order_by("time")
        total = topics.count()
        process_info = ProcessInfo(total, use_last_rates=4)
        start_time = time.time()
        next_status = start_time + 0.25
        for count, topic in enumerate(topics, 1):
            if self.max_entries and count >= self.max_entries:
                self.warn("Skip rest of topics because max_entries used!")
                break

            if time.time() > next_status:
                next_status = time.time() + 1
                rest, eta, rate = process_info.update(count)
                self.out_update(
                    "\t%i/%i topics migrated... rest: %i - eta: %s (rate: %.1f/sec)" % (
                        count, total, rest, eta, rate
                    )
                )

            if topic.moved():
                # skip moved topics -> DjangoBB doesn't support them
                continue

            phpbb_user_id = topic.poster_id #topic.poster.id
            try:
                user = user_dict[phpbb_user_id]
            except KeyError:
                self.out_overwrite(self.style.NOTICE(
                    "topic %i poster: phpBB User with ID %i doesn't exist. Use Anonymous." % (
                        topic.id, phpbb_user_id
                    )
                ))
                user = anonymous_user

            forum = forum_dict[topic.forum_id]

            if topic.type in (1, 2, 3):
                # convert sticky, announce and global post to sticky
                # 0 == NORMAL, 1 == STICKY, 2 == ANNOUNCE, 3 == GLOBAL
                sticky = True
            else:
                sticky = False

            obj = Topic.objects.create(
                id=topic.id,
                forum=forum,
                user=user,
                name=topic.clean_title(),
                created=topic.create_datetime(),
                views=topic.views,
                sticky=sticky,
                closed=topic.locked(),

                # These attributes would be set later in update_topic_stats():
                # updated, post_count, last_post
            )
            if topic.id in topic_watch:
                subscribers = []
                phpbb_user_ids = topic_watch[topic.id]
                for phpbb_user_id in phpbb_user_ids:
                    try:
                        user = user_dict[phpbb_user_id]
                    except KeyError:
                        continue # Skip not existing users.
                    subscribers.append(user)

                obj.subscribers = subscribers
                obj.save()

        duration = time.time() - start_time
        rate = float(count) / duration
        self.out_overwrite(
            " *** %i topics migrated in %s (rate: %.1f/sec)" % (
                count, human_duration(duration), rate
            )
        )
    def migrate_users(self, cleanup_users, moderator_groups):
        self.out(u"\n *** Migrate phpbb_forum users...\n")

        lang_codes = [i[0] for i in settings.LANGUAGES]
        default_lang = settings.LANGUAGE_CODE.split("-")[0]

        moderators = []
        user_dict = {}
        phpbb_users = phpbb_User.objects.all()

        total = phpbb_users.count()
        process_info = ProcessInfo(total, use_last_rates=4)
        skip_count = 0
        start_time = time.time()
        next_status = start_time + 0.25
        for count, phpbb_user in enumerate(phpbb_users, 1):
            if self.max_entries and count >= self.max_entries:
                self.warn("Skip rest of users because max_entries used!")
                break

            if time.time() > next_status:
                next_status = time.time() + 1
                rest, eta, rate = process_info.update(count)
                self.out_update(
                    "\t%i/%i users migrated %i skiped... rest: %i - eta: %s (rate: %.1f/sec)" % (
                        count, total, skip_count, rest, eta, rate
                    )
                )

            if not phpbb_user.posts:
                #assert phpbb_user.has_content() == False

                # Only users with has no posts can be skip.
                if cleanup_users >= 1:
                    if not phpbb_user.email:
                        skip_count += 1
                        if self.verbosity >= 2:
                            self.out_overwrite(
                                u"\t * Skip '%s' (no email)" % smart_unicode(phpbb_user.username)
                            )
                        continue
                if cleanup_users >= 2:
                    if not phpbb_user.lastvisit:
                        skip_count += 1
                        if self.verbosity >= 2:
                            self.out_overwrite(
                                u"\t * Skip '%s' (no lastvisit)" % smart_unicode(phpbb_user.username)
                            )
                        continue
                if cleanup_users >= 3:
                    if not phpbb_user.posts:
                        skip_count += 1
                        if self.verbosity >= 2:
                            self.out_overwrite(
                                u"\t * Skip '%s' (no posts)" % smart_unicode(phpbb_user.username)
                            )
                        continue

            last_login = phpbb_user.lastvisit_datetime()
            if not last_login:
                # can't be None in User model:
                last_login = datetime.datetime(year=datetime.MINYEAR, month=1, day=1)

            is_moderator = phpbb_user.group in moderator_groups
            is_active = phpbb_user.inactive_time == 0


            # Prefix the password, e.g.: "$H$9dwN..." -> "phpBB3_md5$H$9dwN..."
            phpbb_password = PHPBB_PASSWORD % phpbb_user.password

            django_user, created = User.objects.get_or_create(
                username=phpbb_user.username,
                defaults={
                    "email":phpbb_user.email,
                    "password": phpbb_password,
                    "is_staff": is_moderator,
                    "is_active": is_active,
                    "is_superuser": False,
                    "last_login": last_login,
                    "date_joined": phpbb_user.registration_datetime(),
                }
            )
            if created:
                if self.verbosity >= 2:
                    self.out_overwrite(
                        u"\tUser '%s' created." % smart_unicode(django_user.username)
                    )
            else:
                if self.verbosity >= 2:
                    self.out_overwrite(
                        u"\tUser '%s' exists." % smart_unicode(django_user.username)
                    )
                if django_user.password in (None, "", "!"):
                    # Update old migration
                    django_user.password = phpbb_password
                django_user.is_staff = is_moderator
                django_user.is_active = is_active
                django_user.save()

            if is_moderator:
                if self.verbosity >= 1:
                    self.out_overwrite(
                        u"\t *** Mark user '%s' as global forum moderator" % phpbb_user
                    )
                moderators.append(django_user)

            user_dict[phpbb_user.id] = django_user

            tz = TZ_CHOICES[int(phpbb_user.timezone)][0]
            #print tz

            # TODO: migrate avatar, too!
            # see:
            # https://github.com/jedie/django-phpBB3/issues/6

            if phpbb_user.lang in lang_codes:
                language = phpbb_user.lang
            else:
                language = default_lang

            cleaned_signature = phpbb_user.get_cleaned_signature()

            user_profile, created = Profile.objects.get_or_create(
                user=django_user,
                defaults={
                    "site": phpbb_user.website,
                    "signature": cleaned_signature,
                    #"signature_html": phpbb_user.sig,
                    "post_count": phpbb_user.posts,
                    "yahoo": phpbb_user.yim,

                    "time_zone": tz,
                    "language":language,

                    "jabber":phpbb_user.jabber,
                    "icq":phpbb_user.icq,
                    "msn":phpbb_user.msnm,
                    "aim":phpbb_user.aim,
                }
            )
            if created:
                if self.verbosity >= 2:
                    self.out_overwrite(
                        u"\t - User profile for '%s' created." % smart_unicode(django_user.username)
                    )
            else:
                if self.verbosity >= 2:
                    self.out_overwrite(
                        u"\t - User profile for '%s' exists." % smart_unicode(django_user.username)
                    )

        duration = time.time() - start_time
        rate = float(count) / duration
        self.out_overwrite(
            u" *** %i users migrated %i skiped in %s (rate: %.1f/sec)" % (
                count, skip_count, human_duration(duration), rate
            )
        )

        return user_dict, moderators