Esempio n. 1
0
def wodbconnect(self, cmd, data):

    try:
        #            cmdname, args, kwargs = json.loads(data)

        logger.log_infomsg(str(data))

    except Exception:
        log_trace("Websocket malformed OOB request: %s" % data)
        raise
#        self.sessionhandler.data_in(self,"oob", oob=(cmd , args))

    aaa = "filename:" + sys._getframe(
    ).f_code.co_filename + " func: " + sys._getframe(
    ).f_code.co_name + " line:" + str(sys._getframe().f_lineno)

    self.log_zk(aaa + " ;mark:{" + cmd + "}")
    logger.log_file(aaa)

    cursor = connection.cursor()  #获得一个游标(cursor)对象

    cursor.execute("select username from  players_playerdb;")

    #    names = [row[0] for row in cursor.fetchall()]
    raw = cursor.fetchall()
    jsonresult = json.dumps(raw)

    aaa = "filename:" + sys._getframe(
    ).f_code.co_filename + " func: " + sys._getframe(
    ).f_code.co_name + " line:" + str(sys._getframe().f_lineno)

    log_zk(aaa + " ;raw:{" + str(jsonresult) + "}")
    self.sendLine(str(raw))
Esempio n. 2
0
    def load(self):
        """
        Add all forms from the form path.
        """
        # load classes
        for cls in classes_in_path(settings.PATH_REQUEST_PROCESSERS_BASE,
                                   BaseRequestProcesser):
            path = cls.path
            name = cls.name

            if not path and not name:
                logger.log_errmsg("Missing request's path and name.")
                continue

            if path[0] != "/":
                path = "/" + path

            if name is None:
                name = ""

            if self.dict.has_key((
                    path,
                    name,
            )):
                logger.log_infomsg("Request %s-%s is replaced by %s." %
                                   (path, name, cls))

            self.dict[(
                path,
                name,
            )] = cls()
Esempio n. 3
0
    def startedConnecting(self, connector):
        """
        Tracks reconnections for debugging.

        Args:
            connector (Connector): Represents the connection.

        """
        logger.log_infomsg("(re)connecting to %s" % self.channel)
Esempio n. 4
0
    def startedConnecting(self, connector):
        """
        Tracks reconnections for debugging.

        Args:
            connector (Connector): Represents the connection.

        """
        logger.log_infomsg("(re)connecting to %s" % self.channel)
Esempio n. 5
0
 def _die_on_bad_request(self):
     """
     If it becomes apparent that our configuration is generating improperly
     formed messages to EGI, we don't want to keep sending bad messages.
     Stop the service so we're not wasting resources.
     """
     logger.log_infomsg(
         "Shutting down Evennia Game Index client service due to "
         "invalid configuration.")
     self.stopService()
Esempio n. 6
0
 def _die_on_bad_request(self):
     """
     If it becomes apparent that our configuration is generating improperly
     formed messages to EGI, we don't want to keep sending bad messages.
     Stop the service so we're not wasting resources.
     """
     logger.log_infomsg(
         "Shutting down Evennia Game Index client service due to "
         "invalid configuration.")
     self.stopService()
Esempio n. 7
0
 def load(self):
     """
     Add all event actions from the path.
     """
     # load classes
     for cls in classes_in_path(settings.PATH_EVENT_ACTION_BASE, BaseEventAction):
         key = cls.key
         if key:
             if key in self.dict:
                 logger.log_infomsg("Event action %s is replaced by %s." % (key, cls))
             self.dict[key] = cls()
Esempio n. 8
0
    def load(self):
        """
        Add all event actions from the path.
        """
        # load classes
        for cls in classes_in_path(settings.PATH_EVENT_ACTION_BASE, BaseEventAction):
            key = cls.key

            if self.dict.has_key(key):
                logger.log_infomsg("Event action %s is replaced by %s." % (key, cls))

            self.dict[key] = cls()
Esempio n. 9
0
 def log(self, message, channel=True):
     """
     Emits session info to the appropriate outputs and info channels.
     """
     if channel:
         try:
             cchan = settings.CHANNEL_CONNECTINFO
             cchan = ChannelDB.objects.get_channel(cchan[0])
             cchan.msg("[%s]: %s" % (cchan.key, message))
         except Exception:
             pass
     logger.log_infomsg(message)
Esempio n. 10
0
    def load(self):
        """
        Add all quest status from the path.
        """
        # load classes
        for cls in classes_in_path(settings.PATH_QUEST_STATUS_BASE, BaseQuestStatus):
            key = cls.key

            if key in self.dict:
                logger.log_infomsg("Quest status %s is replaced by %s." % (key, cls))

            self.dict[key] = cls()
Esempio n. 11
0
 def log(self, message, channel=True):
     """
     Emits session info to the appropriate outputs and info channels.
     """
     if channel:
         try:
             cchan = settings.CHANNEL_CONNECTINFO
             cchan = ChannelDB.objects.get_channel(cchan[0])
             cchan.msg("[%s]: %s" % (cchan.key, message))
         except Exception:
             pass
     logger.log_infomsg(message)
Esempio n. 12
0
 def all_to_category(self, default_category):
     """
     Shifts all help entries in database to default_category.
     This action cannot be reverted. It is used primarily by
     the engine when importing a default help database, making
     sure this ends up in one easily separated category.
     """
     topics = self.all()
     for topic in topics:
         topic.help_category = default_category
         topic.save()
     string = "Help database moved to category %s" % default_category
     logger.log_infomsg(string)
Esempio n. 13
0
    def load(self):
        """
        Add all forms from the form path.
        """
        # load classes
        for cls in classes_in_path(settings.PATH_DATA_FORMS_BASE, forms.ModelForm):
            if hasattr(cls, "Meta") and hasattr(cls.Meta, "model"):
                model = cls.Meta.model
                model_name = model.__name__

                if self.dict.has_key(model_name):
                    logger.log_infomsg("Form %s is replaced by %s." % (model_name, cls))

                self.dict[model_name] = cls
Esempio n. 14
0
 def func(self):
     "Define function"
     try:
         # Only allow shutdown if caller has session
         self.caller.sessions[0]
     except Exception:
         return
     self.msg('Shutting down server ...')
     announcement = "\nServer is being SHUT DOWN!\n"
     if self.args:
         announcement += "%s\n" % self.args
     logger.log_infomsg('Server shutdown by %s.' % self.caller.name)
     SESSIONS.announce_all(announcement)
     SESSIONS.server.shutdown(mode='shutdown')
     SESSIONS.portal_shutdown()
Esempio n. 15
0
 def _send_to_connect_channel(self, message):
     "Helper method for loading the default comm channel"
     global _CONNECT_CHANNEL
     if not _CONNECT_CHANNEL:
         try:
             _CONNECT_CHANNEL = ChannelDB.objects.filter(db_key=settings.DEFAULT_CHANNELS[1]["key"])[0]
         except Exception:
             logger.log_trace()
     now = timezone.now()
     now = "%02i-%02i-%02i(%02i:%02i)" % (now.year, now.month,
                                          now.day, now.hour, now.minute)
     if _CONNECT_CHANNEL:
         _CONNECT_CHANNEL.tempmsg("[%s, %s]: %s" % (_CONNECT_CHANNEL.key, now, message))
     else:
         logger.log_infomsg("[%s]: %s" % (now, message))
Esempio n. 16
0
 def func(self):
     "Define function"
     try:
         # Only allow shutdown if caller has session
         self.caller.sessions[0]
     except Exception:
         return
     self.msg('Shutting down server ...')
     announcement = "\nServer is being SHUT DOWN!\n"
     if self.args:
         announcement += "%s\n" % self.args
     logger.log_infomsg('Server shutdown by %s.' % self.caller.name)
     SESSIONS.announce_all(announcement)
     SESSIONS.server.shutdown(mode='shutdown')
     SESSIONS.portal_shutdown()
Esempio n. 17
0
    def load(self):
        """
        Add all forms from the form path.
        """
        # load classes
        for cls in classes_in_path(settings.PATH_DATA_FORMS_BASE,
                                   forms.ModelForm):
            if hasattr(cls, "Meta") and hasattr(cls.Meta, "model"):
                model = cls.Meta.model
                model_name = model.__name__

                if model_name in self.dict:
                    logger.log_infomsg("Form %s is replaced by %s." %
                                       (model_name, cls))

                self.dict[model_name] = cls
Esempio n. 18
0
    def connectionMade(self):
        """
        Triggered after connecting to the IMC2 network.
        """

        self.stopping = False
        self.factory.bot = self
        address = "%s@%s" % (self.mudname, self.network)
        self.init_session("ircbot", address, self.factory.sessionhandler)
        # link back and log in
        self.uid = int(self.factory.uid)
        self.logged_in = True
        self.factory.sessionhandler.connect(self)
        logger.log_infomsg("IMC2 bot connected to %s." % self.network)
        # Send authentication packet. The reply will be caught by lineReceived
        self._send_packet(pck.IMC2PacketAuthPlaintext())
Esempio n. 19
0
    def load_files(self, typeclass_path):
        """
        Get typeclasses' file path.
        """
        if not typeclass_path:
            return

        module = import_module(typeclass_path)
        base_path = module.__path__
        if not base_path:
            return

        base_path = base_path[0]
        for root, dirs, files in os.walk(base_path):
            for filename in files:
                name, ext = os.path.splitext(filename)
                if ext != ".py":
                    continue

                with open(os.path.join(root, filename), "r") as fp:
                    class_name = ""
                    for line in fp.readlines():
                        if not class_name:
                            match = self.match_class.match(line)
                            if match:
                                class_name = match.group(1)
                        else:
                            match = self.match_key.match(line)
                            if match:
                                key_name = match.group(2)

                                module_path = typeclass_path
                                if base_path == root:
                                    module_path += "." + name + "." + class_name
                                else:
                                    relative_path = get_module_path(
                                        os.path.relpath(root, base_path))
                                    module_path += "." + relative_path + "." + name + "." + class_name

                                if key_name in self.module_dict:
                                    logger.log_infomsg(
                                        "Typeclass %s is replaced by %s." %
                                        (key_name, module_path))

                                self.module_dict[key_name] = module_path
                                class_name = ""
Esempio n. 20
0
    def get(self, key):
        """
        Get a typeclass recursively.
        """
        if key in self.class_dict:
            return self.class_dict[key]
        elif key in self.module_dict:
            cls = class_from_module(self.module_dict[key])
            if self.class_dict.has_key(key):
                if self.class_dict[key] != cls:
                    logger.log_infomsg("Typeclass %s is replaced by %s." % (key, cls))

            self.class_dict[key] = cls
            self.trigger_dict[key] = cls.get_event_trigger_types()
            return cls

        logger.log_errmsg("Can not find typeclass key: %s." % key)
Esempio n. 21
0
 def signedOn(self):
     """
     This is called when we successfully connect to
     the network. We make sure to now register with
     the game as a full session.
     """
     self.join(self.channel)
     self.stopping = False
     self.factory.bot = self
     address = "%s@%s" % (self.channel, self.network)
     self.init_session("ircbot", address, self.factory.sessionhandler)
     # we link back to our bot and log in
     self.uid = int(self.factory.uid)
     self.logged_in = True
     self.factory.sessionhandler.connect(self)
     logger.log_infomsg("IRC bot '%s' connected to %s at %s:%s." % (self.nickname, self.channel,
                                                                           self.network, self.port))
Esempio n. 22
0
    def get(self, key):
        """
        Get a typeclass recursively.
        """
        if key in self.class_dict:
            return self.class_dict[key]
        elif key in self.module_dict:
            cls = class_from_module(self.module_dict[key])
            if key in self.class_dict:
                if self.class_dict[key] != cls:
                    logger.log_infomsg("Typeclass %s is replaced by %s." % (key, cls))

            self.class_dict[key] = cls
            self.trigger_dict[key] = cls.get_event_trigger_types()
            return cls

        logger.log_errmsg("Can not find typeclass key: %s." % key)
Esempio n. 23
0
 def _send_to_connect_channel(self, message):
     "Helper method for loading the default comm channel"
     global _CONNECT_CHANNEL
     if not _CONNECT_CHANNEL:
         try:
             _CONNECT_CHANNEL = ChannelDB.objects.filter(
                 db_key=settings.DEFAULT_CHANNELS[1]["key"])[0]
         except Exception:
             logger.log_trace()
     now = datetime.datetime.now()
     now = "%02i-%02i-%02i(%02i:%02i)" % (now.year, now.month, now.day,
                                          now.hour, now.minute)
     if _CONNECT_CHANNEL:
         _CONNECT_CHANNEL.tempmsg("[%s, %s]: %s" %
                                  (_CONNECT_CHANNEL.key, now, message))
     else:
         logger.log_infomsg("[%s]: %s" % (now, message))
Esempio n. 24
0
    def log(self, message, channel=True):
        """
        Emits session info to the appropriate outputs and info channels.

        Args:
            message (str): The message to log.
            channel (bool, optional): Log to the CHANNEL_CONNECTINFO channel
                in addition to the server log.

        """
        if channel:
            try:
                cchan = settings.CHANNEL_CONNECTINFO
                cchan = ChannelDB.objects.get_channel(cchan[0])
                cchan.msg("[%s]: %s" % (cchan.key, message))
            except Exception:
                pass
        logger.log_infomsg(message)
Esempio n. 25
0
    def log(self, message, channel=True):
        """
        Emits session info to the appropriate outputs and info channels.

        Args:
            message (str): The message to log.
            channel (bool, optional): Log to the CHANNEL_CONNECTINFO channel
                in addition to the server log.

        """
        if channel:
            try:
                cchan = settings.CHANNEL_CONNECTINFO
                cchan = ChannelDB.objects.get_channel(cchan[0])
                cchan.msg("[%s]: %s" % (cchan.key, message))
            except Exception:
                pass
        logger.log_infomsg(message)
Esempio n. 26
0
 def signedOn(self):
     """
     This is called when we successfully connect to
     the network. We make sure to now register with
     the game as a full session.
     """
     self.join(self.channel)
     self.stopping = False
     self.factory.bot = self
     address = "%s@%s" % (self.channel, self.network)
     self.init_session("ircbot", address, self.factory.sessionhandler)
     # we link back to our bot and log in
     self.uid = int(self.factory.uid)
     self.logged_in = True
     self.factory.sessionhandler.connect(self)
     logger.log_infomsg(
         "IRC bot '%s' connected to %s at %s:%s." %
         (self.nickname, self.channel, self.network, self.port))
Esempio n. 27
0
    def load_files(self, typeclass_path):
        """
        Get typeclasses' file path.
        """
        if not typeclass_path:
            return

        module = import_module(typeclass_path)
        base_path = module.__path__
        if base_path:
            base_path = base_path[0]
            for root, dirs, files in os.walk(base_path):
                for filename in files:
                    name, ext = os.path.splitext(filename)
                    if ext != ".py":
                        continue

                    with open(os.path.join(root, filename), "r") as fp:
                        class_name = ""
                        key_name = ""
                        for line in fp.readlines():
                            if not class_name:
                                match = self.match_class.match(line)
                                if match:
                                    class_name = match.group(1)
                            else:
                                match = self.match_key.match(line)
                                if match:
                                    key_name = match.group(2)

                                    module_path = typeclass_path
                                    if base_path == root:
                                        module_path += "." + name + "." + class_name
                                    else:
                                        relative_path = get_module_path(os.path.relpath(root, base_path))
                                        module_path += "." + relative_path + "." + name + "." + class_name

                                    if key_name in self.module_dict:
                                        logger.log_infomsg("Typeclass %s is replaced by %s." % (key_name, module_path))

                                    self.module_dict[key_name] = module_path
                                    class_name = ""
                                    key_name = ""
Esempio n. 28
0
def cmdparser(raw_string, cmdset, caller, match_index=None):
    """
    This function is called by the cmdhandler once it has
    gathered and merged all valid cmdsets valid for this particular parsing.

    raw_string - the unparsed text entered by the caller.
    cmdset - the merged, currently valid cmdset
    caller - the caller triggering this parsing
    match_index - an optional integer index to pick a given match in a
                  list of same-named command matches.

    Returns:
     list of tuples: [(cmdname, args, cmdobj, cmdlen, mratio), ...]
            where cmdname is the matching command name and args is
            everything not included in the cmdname. Cmdobj is the actual
            command instance taken from the cmdset, cmdlen is the length
            of the command name and the mratio is some quality value to
            (possibly) separate multiple matches.

    """
    # Parse JSON formated command.
    logger.log_infomsg("Receive command, %s: %s" % (caller, raw_string))

    try:
        data = json.loads(raw_string)
    except Exception:
        # Command is not in JSON, call evennia's cmdparser.
        return evennia_cmdparser.cmdparser(raw_string, cmdset, caller,
                                           match_index)

    cmd = data["cmd"]
    args = data["args"]

    # Find the matching command in cmdset.
    for cmdobj in cmdset:
        if cmdobj.key == cmd:
            return [(cmd, args, cmdobj, len(cmd), 1, raw_string)]

    # can not find
    return []
Esempio n. 29
0
    def _send_to_connect_channel(self, message):
        """
        Helper method for loading and sending to the comm channel
        dedicated to connection messages.

        Args:
            message (str): A message to send to the connect channel.

        """
        global _CONNECT_CHANNEL
        if not _CONNECT_CHANNEL:
            try:
                _CONNECT_CHANNEL = ChannelDB.objects.filter(db_key=settings.DEFAULT_CHANNELS[1]["key"])[0]
            except Exception:
                logger.log_trace()
        now = timezone.now()
        now = "%02i-%02i-%02i(%02i:%02i)" % (now.year, now.month,
                                             now.day, now.hour, now.minute)
        if _CONNECT_CHANNEL:
            _CONNECT_CHANNEL.tempmsg("[%s, %s]: %s" % (_CONNECT_CHANNEL.key, now, message))
        else:
            logger.log_infomsg("[%s]: %s" % (now, message))
Esempio n. 30
0
 def send_game_details(self):
     """
     This is where the magic happens. Send details about the game to the
     Evennia Game Index.
     """
     status_code, response_body = yield self._form_and_send_request()
     if status_code == 200:
         if not self.logged_first_connect:
             logger.log_infomsg(
                 "Successfully sent game details to Evennia Game Index.")
             self.logged_first_connect = True
         return
     # At this point, either EGD is having issues or the payload we sent
     # is improperly formed (probably due to mis-configuration).
     logger.log_errmsg(
         'Failed to send game details to Evennia Game Index. HTTP '
         'status code was %s. Message was: %s' % (status_code, response_body)
     )
     if status_code == 400 and self._on_bad_request:
         # Improperly formed request. Defer to the callback as far as what
         # to do. Probably not a great idea to continue attempting to send
         # to EGD, though.
         self._on_bad_request()
Esempio n. 31
0
    def _imc_login(self, line):
        """
        Connect and identify to imc network as per the
        `self.auth_type` setting.

        Args:
            line (str): Incoming text.

        """

        if self.auth_type == "plaintext":
            # Only support Plain text passwords.
            # SERVER Sends: PW <servername> <serverpw> version=<version#> <networkname>

            logger.log_infomsg("IMC2: AUTH< %s" % line)

            line_split = line.split(' ')
            pw_present = line_split[0] == 'PW'
            autosetup_present = line_split[0] == 'autosetup'

            if "reject" in line_split:
                auth_message = _("IMC2 server rejected connection.")
                logger.log_infomsg(auth_message)
                return

            if pw_present:
                self.server_name = line_split[1]
                self.network_name = line_split[4]
            elif autosetup_present:
                logger.log_infomsg(_("IMC2: Autosetup response found."))
                self.server_name = line_split[1]
                self.network_name = line_split[3]
            self.is_authenticated = True
            self.sequence = int(time())

            # Log to stdout and notify over MUDInfo.
            logger.log_infomsg('IMC2: Authenticated to %s' %
                               self.factory.network)

            # Ask to see what other MUDs are connected.
            self._send_packet(pck.IMC2PacketKeepAliveRequest())
            # IMC2 protocol states that KeepAliveRequests should be followed
            # up by the requester sending an IsAlive packet.
            self._send_packet(pck.IMC2PacketIsAlive())
            # Get a listing of channels.
            self._send_packet(pck.IMC2PacketIceRefresh())
Esempio n. 32
0
    def _imc_login(self, line):
        """
        Connect and identify to imc network as per the
        `self.auth_type` setting.

        Args:
            line (str): Incoming text.

        """

        if self.auth_type == "plaintext":
            # Only support Plain text passwords.
            # SERVER Sends: PW <servername> <serverpw> version=<version#> <networkname>

            logger.log_infomsg("IMC2: AUTH< %s" % line)

            line_split = line.split(' ')
            pw_present = line_split[0] == 'PW'
            autosetup_present = line_split[0] == 'autosetup'

            if "reject" in line_split:
                auth_message = _("IMC2 server rejected connection.")
                logger.log_infomsg(auth_message)
                return

            if pw_present:
                self.server_name = line_split[1]
                self.network_name = line_split[4]
            elif autosetup_present:
                logger.log_infomsg(_("IMC2: Autosetup response found."))
                self.server_name = line_split[1]
                self.network_name = line_split[3]
            self.is_authenticated = True
            self.sequence = int(time())

            # Log to stdout and notify over MUDInfo.
            logger.log_infomsg('IMC2: Authenticated to %s' % self.factory.network)

            # Ask to see what other MUDs are connected.
            self._send_packet(pck.IMC2PacketKeepAliveRequest())
            # IMC2 protocol states that KeepAliveRequests should be followed
            # up by the requester sending an IsAlive packet.
            self._send_packet(pck.IMC2PacketIsAlive())
            # Get a listing of channels.
            self._send_packet(pck.IMC2PacketIceRefresh())
Esempio n. 33
0
 def startedConnecting(self, connector):
     "Tracks reconnections for debugging"
     logger.log_infomsg("(re)connecting to %s" % self.channel)
Esempio n. 34
0
            count += 1
        return "%s (model: %s, line: %s)" % (err_message, model_name, line)

    # separate name and ext name
    (filename, ext_name) = os.path.splitext(fullname)
    if not table_name:
        table_name = filename
    if not file_type:
        if ext_name:
            file_type = ext_name[1:].lower()

    # get model
    model_obj = apps.get_model(settings.WORLD_DATA_APP, table_name)

    if clear:
        clear_model_data(model_obj, **kwargs)

    reader_class = readers.get_reader(file_type)
    if not reader_class:
        # Does support this file type.
        raise (MudderyError(ERR.import_data_error, "Unknown file type."))

    reader = reader_class(fullname)
    if not reader:
        # Does support this file type.
        raise (MudderyError(ERR.import_data_error,
                            "Does not support this file type."))

    logger.log_infomsg("Importing %s" % table_name)
    import_data(model_obj, reader)
Esempio n. 35
0
 def startedConnecting(self, connector):
     "Tracks reconnections for debugging"
     logger.log_infomsg("(re)connecting to %s" % self.channel)
Esempio n. 36
0
        return "%s (model: %s, line: %s)" % (err_message, model_name, line)


    # separate name and ext name
    (filename, ext_name) = os.path.splitext(fullname)
    if not table_name:
        table_name = filename
    if not file_type:
        if ext_name:
            file_type = ext_name[1:].lower()

    # get model
    model_obj = apps.get_model(settings.WORLD_DATA_APP, table_name)

    if clear:
        clear_model_data(model_obj, **kwargs)

    reader_class = readers.get_reader(file_type)
    if not reader_class:
        # Does support this file type.
        raise(MudderyError(ERR.import_data_error, "Unknown file type."))

    reader = reader_class(fullname)
    if not reader:
        # Does support this file type.
        raise(MudderyError(ERR.import_data_error, "Does not support this file type."))

    logger.log_infomsg("Importing %s" % table_name)
    import_data(model_obj, reader)

Esempio n. 37
0
def import_file(fullname, file_type=None, table_name=None, clear=True, **kwargs):
    """
    Import data from a data file to the db model

    Args:
        fullname: (string) file's full name
        table_name: (string) the type of the file. If it's None, the function will get
                   the file type from the extension name of the file.
    """

    def get_field_types(model_obj, field_names):
        """
        Get field types by field names.

        type = 0    means common field
        type = 1    means Boolean field
        type = 2    means Integer field
        type = 3    means Float field
        type = 4    means ForeignKey field, not support
        type = 5    means ManyToManyField field, not support
        type = -1   means field does not exist
        """
        field_types = []
        for field_name in field_names:
            field_type = -1

            try:
                # get field info
                field = model_obj._meta.get_field(field_name)

                if isinstance(field, models.BooleanField):
                    field_type = 1
                elif isinstance(field, models.IntegerField):
                    field_type = 2
                elif isinstance(field, models.FloatField):
                    field_type = 3
                elif isinstance(field, models.ForeignKey):
                    field_type = 4
                elif isinstance(field, models.ManyToManyField):
                    field_type = 5
                else:
                    field_type = 0
            except Exception as e:
                field_type = -1
                logger.log_errmsg("Field %s error: %s" % (field_name, e))

            field_types.append(field_type)

        return field_types

    def parse_record(field_names, field_types, values):
        """
        Parse text values to field values.
        """
        record = {}
        for item in zip(field_names, field_types, values):
            field_name = item[0]
            # skip "id" field
            if field_name == "id":
                continue

            field_type = item[1]
            value = item[2]

            try:
                # set field values
                if field_type == -1:
                    # not support this field
                    continue
                elif field_type == 0:
                    # default
                    record[field_name] = value
                elif field_type == 1:
                    # boolean value
                    if value:
                        if value == 'True':
                            record[field_name] = True
                        elif value == 'False':
                            record[field_name] = False
                        else:
                            record[field_name] = (int(value) != 0)
                elif field_type == 2:
                    # interger value
                    if value:
                        record[field_name] = int(value)
                elif field_type == 3:
                    # float value
                    if value:
                        record[field_name] = float(value)
            except Exception as e:
                raise ValidationError({field_name: "value error: '%s'" % value})

        return record

    def import_data(model_obj, data_iterator):
        """
        Import data to a table.

        Args:
            model_obj: (model) model object.
            data_iterator: (list) data list.

        Returns:
            None
        """
        line = 1
        try:
            # read title
            titles = next(data_iterator)
            field_types = get_field_types(model_obj, titles)            
            line += 1

            # import values
            for values in data_iterator:
                # skip blank lines
                blank_line = True
                for value in values:
                    if value:
                        blank_line = False
                        break
                if blank_line:
                    line += 1
                    continue

                record = parse_record(titles, field_types, values)
                data = model_obj(**record)
                data.full_clean()
                data.save()
                line += 1

        except StopIteration:
            # reach the end of file, pass this exception
            pass
        except ValidationError as e:
            traceback.print_exc()
            raise MudderyError(ERR.import_data_error, parse_error(e, model_obj.__name__, line))
        except Exception as e:
            traceback.print_exc()
            raise MudderyError(ERR.import_data_error, "%s (model: %s, line: %s)" % (e, model_obj.__name__, line))

    def clear_model_data(model_obj, **kwargs):
        """
        Remove all data from db.

        Args:
            model_obj: model object.

        Returns:
            None
        """
        # clear old data
        model_obj.objects.all().delete()

    def parse_error(error, model_name, line):
        """
        Parse validation error to string message.

        Args:
            error: (ValidationError) a ValidationError.
            line: (number) the line number where the error occurs.
        Returns:
            (string) output string.
        """
        err_message = ""

        if hasattr(error, "error_dict"):
            error_dict = error.error_dict
        else:
            error_dict = {"": error.error_list}

        count = 1
        for field, error_list in error_dict.items():
            err_message += str(count) + ". "
            if field:
                err_message += "[" + field + "] "
            for item in error_list:
                print("item.message: %s" % item.message)
                print("item.params: %s" % item.params)
                if item.params:
                    err_message += item.message % item.params + "  "
                else:
                    err_message += item.message + "  "
            count += 1
        return "%s (model: %s, line: %s)" % (err_message, model_name, line)


    # separate name and ext name
    (filename, ext_name) = os.path.splitext(fullname)
    if not table_name:
        table_name = filename
    if not file_type:
        if ext_name:
            file_type = ext_name[1:].lower()

    # get model
    model_obj = apps.get_model(settings.WORLD_DATA_APP, table_name)

    if clear:
        clear_model_data(model_obj, **kwargs)

    reader_class = readers.get_reader(file_type)
    if not reader_class:
        # Does support this file type.
        raise(MudderyError(ERR.import_data_error, "Unknown file type."))

    reader = reader_class(fullname)
    if not reader:
        # Does support this file type.
        raise(MudderyError(ERR.import_data_error, "Does not support this file type."))

    logger.log_infomsg("Importing %s" % table_name)
    import_data(model_obj, reader)