Beispiel #1
0
    def __init__(self):
        self.fileHandler: FileHandler = FileHandler()
        self.sManager: SettingsManager = SettingsManager()
        self.server: ServerManager = ServerManager()
        self.scheduler: DeviceOpScheduler = DeviceOpScheduler()
        self.logger: Logger = None

        self.botClosing = False
Beispiel #2
0
    def __init__(self):
        """
        Constructor
        """
        self.__dict__ = self.__shared_state  # borg pattern

        if not self.instance:
            self.instance = True

            # extend filenames with path to the configurationfolder
            self.log_file = Globals.config_dir + FileManager.log_file
            self.fav_file = Globals.config_dir + FileManager.fav_file
            self.rec_file = Globals.config_dir + FileManager.rec_file
            self.conf_file = Globals.config_dir + FileManager.conf_file
            self.buddies_file = Globals.config_dir + FileManager.buddies_file
            self.filter_file = Globals.config_dir + FileManager.filter_file
            self.rcon_file = Globals.config_dir + FileManager.rcon_file
            self.window_size_file = Globals.config_dir+FileManager.\
                                                                window_size_file

            #initialise ServerManager
            self.srvman = ServerManager()
Beispiel #3
0
 def __init__(self):
     """
     Constructor
     """
     self.__dict__ = self.__shared_state # borg pattern
     
     if not self.instance:
         self.instance = True
         
         
         
         # extend filenames with path to the configurationfolder
         self.log_file = Globals.config_dir+FileManager.log_file
         self.fav_file = Globals.config_dir+FileManager.fav_file
         self.rec_file = Globals.config_dir+FileManager.rec_file
         self.conf_file = Globals.config_dir+FileManager.conf_file
         self.buddies_file = Globals.config_dir+FileManager.buddies_file
         self.filter_file = Globals.config_dir+FileManager.filter_file
         self.rcon_file = Globals.config_dir+FileManager.rcon_file
         self.window_size_file = Globals.config_dir+FileManager.\
                                                             window_size_file
         
         #initialise ServerManager
         self.srvman = ServerManager()
Beispiel #4
0
class FileManager(object):
    """
    This class handles all file accesses of UrTSB.
    
    1. read/write of configuration
    2. access file for loading/storing favorites list
    3. access file for loading/storing recent servers
    
    """
    __shared_state = {} # borg pattern
    
    instance = None

    favorites = None
    recentservers = None
    configuration = None
    buddies = None
    filter = None
    rconpws = None
    window_sizing = None
    
    #filenames
    conf_file = 'urtsb.cfg'
    fav_file = 'favorites.srv'
    rec_file = 'recent.srv'
    buddies_file = 'buddies.cfg'
    log_file = 'urtsb.log'
    filter_file = 'filter.pkl'
    rcon_file = 'rcon_pws.cfg'
    window_size_file = 'window_size.pkl'
    
    
                  

    def __init__(self):
        """
        Constructor
        """
        self.__dict__ = self.__shared_state # borg pattern
        
        if not self.instance:
            self.instance = True
            
            
            
            # extend filenames with path to the configurationfolder
            self.log_file = Globals.config_dir+FileManager.log_file
            self.fav_file = Globals.config_dir+FileManager.fav_file
            self.rec_file = Globals.config_dir+FileManager.rec_file
            self.conf_file = Globals.config_dir+FileManager.conf_file
            self.buddies_file = Globals.config_dir+FileManager.buddies_file
            self.filter_file = Globals.config_dir+FileManager.filter_file
            self.rcon_file = Globals.config_dir+FileManager.rcon_file
            self.window_size_file = Globals.config_dir+FileManager.\
                                                                window_size_file
            
            #initialise ServerManager
            self.srvman = ServerManager()
    
    def get_window_sizing(self):
        """
        Loads the window size settings from the file or returnes a already 
        loaded instance if available
        """
        if self.window_sizing:
            return self.window_sizing
        
        
    
        pkl_file = None
        try:
            pkl_file = open(self.window_size_file, "rb") 
        except IOError:
            self.window_sizing = WindowSizing()
            return self.window_sizing
        
        self.window_sizing = pickle.load(pkl_file)
        
        pkl_file.close()
        return self.window_sizing
    
    def save_window_sizing(self):
        """
        Saves the window sizing instance in a file
        """
        pkl_file = open(self.window_size_file, "wb")
         
        pickle.dump(self.window_sizing, pkl_file, pickle.HIGHEST_PROTOCOL)
        
        pkl_file.close()
    
    def get_buddies(self):
        """
        Get the list of buddies (names or part of names). If already loaded 
        from file the instance from memory is returned, otherwise it is fresh 
        loaded from the file.
        
        @return list of server names
        """
        if self.buddies:
            return self.buddies
        
        self.buddies = []
        
        fobj = None
        try:
            fobj = open(self.buddies_file, "r") 
        except IOError:
            #the file does not exist! just return the empty list created earlier
            return self.buddies
        
        for line in fobj: 
            line = line.strip('\n')
            self.buddies.append(line)
        fobj.close()
        return self.buddies
        
    def save_buddies(self):
        """
        Writes the list of buddies to the buddies file.
        """
        fobj = open(self.buddies_file, "w") 
        for name in self.buddies:
            
            #format: one name on every line
            fobj.write(name + '\n')
        fobj.close()
        
    def save_rcon_passwords(self):
        """
        Saves the dict of rcon passwords
        """    
        fobj = open(self.rcon_file, "w") 
        for key in self.rconpws:
            pw = self.rconpws[key]
            #format: address,pw
            fobj.write(key + ',' + pw + '\n')
        fobj.close()
        
    def get_rcon_passwords(self):
        """
        Get a dict with server adress as key and rcon pws as values
        
        @return the dict of rcon pws
        """
        if self.rconpws:
            return self.rconpws
        
        self.rconpws = {}
        fobj = None
        try:
            fobj = open(self.rcon_file, "r") 
        except IOError:
            #the file does not exist! just return the empty dict created earlier
            return self.rconpws
        
        for line in fobj: 
            line = line.strip() 
            rconline = line.split(',') # file is a csv
            #format: adress,pw
            self.rconpws[rconline[0]] = rconline[1]
        fobj.close()
        
        return self.rconpws
    
    def getFavorites(self):
        """
        Get the Favorites. If already loaded from file, return the instance from
        memory, otherwise load from file. 
        
        @return dict of server objects (key = address)
        """
        if self.favorites:
            return self.favorites
        
        self.favorites = {}
        fobj = None
        try:
            fobj = open(self.fav_file, "r") 
        except IOError:
            #the file does not exist! just return the empty dict created earlier
            return self.favorites
        
        for line in fobj: 
            line = line.strip() 
            serverinfo = line.split(',') # file is a csv
            #format: ip,port,password,servername
            server = self.srvman.getServer(serverinfo[0], int(serverinfo[1]))
            server.setPassword(serverinfo[2])
            server.setName(serverinfo[3])
            server.setIsFavorite(True)
            #use the address (ip:port) as key to avoid duplicate entries
            self.favorites[server.getaddress()] = server
        fobj.close()
        
        return self.favorites
    
    def get_remembered_filter_parameters(self):
        """
        Load the 'remembered' filter paramters from file
        using the pickle python object serialization
        
        @return the filter dict
        """
        
        if self.filter: #already loaded!
            return self.filter
        
        pkl_file = None
        try:
            pkl_file = open(self.filter_file, "rb") 
        except IOError:
            #file not found - just return None
            filter = {}
            
            filter[filterkey.GT_ALL] = 'True'
            filter[filterkey.GT_BOMB] = 'True'
            filter[filterkey.GT_TS] = 'True'
            filter[filterkey.GT_CTF] = 'True'
            filter[filterkey.GT_TDM] = 'True'
            filter[filterkey.GT_CAH] = 'True'
            filter[filterkey.GT_FTL] = 'True'
            filter[filterkey.GT_FFA] = 'True'
            
            #other filters
            filter[filterkey.FLT_MIN_PLAYERS] = 0
            filter[filterkey.FLT_MAX_PLAYERS] = 99
            
            filter[filterkey.FLT_HIDE_NON_RESP] = 'True'
            filter[filterkey.FLT_HIDE_PASSWORDED] = 'True'
            
            #mapname and servername filter
            filter[filterkey.FLT_MAP_NAME] = ''
            filter[filterkey.FLT_SERVER_NAME] = ''       
            
            #query params
            filter[filterkey.QRY_SHOW_FULL] = 'False'
            filter[filterkey.QRY_SHOW_EMPTY] = 'False'
            
            filter[filterkey.FLT_GEAR] = cfgvalues.DISABLED
            
            filter[filterkey.FLT_VAR_LIST] = []
            self.filter = filter
            return filter       
            
        
        self.filter = pickle.load(pkl_file)
        
        Log.log.debug('[get_remembered_filter_parameters] loaded filter = '\
                      + str(self.filter))
        
        pkl_file.close()
          
        return self.filter
    
    def save_filter_to_remember(self):
        """
        Saves the current filter parameters to the filter file
        using the pickle python object serialization
        """
        pkl_file = open(self.filter_file, "wb")
         
        pickle.dump(self.filter, pkl_file, pickle.HIGHEST_PROTOCOL)
        Log.log.debug('[save_filter_to_remember]: saved filter = ' + str(self.filter))
        pkl_file.close()
    
    def addFavorite(self, server):
        """
        Adds a new favorite server to the list of favorites.
        Note: Immediately writes the current state of the list 
        into the favorites file. 
        
        @param server - the server object to add
        """
        favs = self.getFavorites() # this makes sure it is initialized 
        if server.getaddress() not in favs:
            self.favorites[server.getaddress()] = server
            #immdediately save to file in order to avoid a loss of data (crash etc.)
            self.saveFavorites()
            server.setIsFavorite(True)
    
    def removeFavorite(self, server):
        """
        Removes a existing favorite server from the favorites list.
        Note: Immediately updates the favorties file.
        
        @param server - the server object to be removed
        """
        favs = self.getFavorites() # this makes sure it is initialized  
        if server.getaddress() in favs:
            del self.favorites[server.getaddress()]
            self.saveFavorites()
            
    def remove_buddy(self, name):
        """
        Removes a name from the buddylist and immediately persists this change
        to the list into the buddylist file.
        
        @param name - the name to be removed
        """
        for i in range(len(self.buddies)):
            if name == self.buddies[i]:
                del self.buddies[i]
                break # already found the name to delete, so we can stop the loop
        self.save_buddies()
            
    def removeRecentServer(self, server):
        """
        Removes a existing recent server entry from the list.
        Note: Immediately updates the recent servers file.
        
        @param server - the server object to be removed
        """
        recents = self.getRecentServers() # this makes sure it is initialized  
        if server.getaddress() in recents.keys():
            del self.recentservers[server.getaddress()]
            self.saveRecentServers()
            
            
    def clearRecentServerList(self):
        """
        Clears the list of recent servers.
        """
        self.recentservers = {}
        self.saveRecentServers()
    
    def addRecent(self, server):
        """
        Adds a new server to the list of recent connected servers.
        Note: Immediately writes the current state of the list 
        into the recent servers file.
        Or if server exists, updates the existing entry 
        
        @param server - the server object to add
        """
        recent_servers = self.getRecentServers()
        if server.getaddress() not in self.recentservers:
            server.setConnections(1)
            self.recentservers[server.getaddress()] = server
        else:
            
            existing_entry = recent_servers[server.getaddress()] 
            conns = existing_entry.getConnections()
            conns += 1
            existing_entry.setConnections(conns)
            server = existing_entry
            
        server.setLastConnect(time.strftime("%Y.%m.%d - %H:%M"))
        #immdediately save to file in order to avoid a loss of data (crash etc.)
        self.saveRecentServers()
            
            
    def saveFavorites(self):
        """
        Performs the writing to the favorites file.
        """
        fobj = open(self.fav_file, "w") 
        for key in self.favorites:
            server = self.favorites[key]
            #format: ip,port,password,servername
            fobj.write(server.getHost() + ',' + str(server.getPort()) 
                       + ',' + server.getPassword() + ',' + server.getName() + '\n')
        fobj.close()
        
    def saveRecentServers(self):
        """
        Performs the writing to the recent servers file
        """
        fobj = open(self.rec_file, "w")
         
        for key in self.recentservers:
            server = self.recentservers[key]
            #format: ip,port,password, connectioncount,dateoflastconnection,name
            fobj.write(server.getHost() + ',' + str(server.getPort()) 
                     + ',' + server.getPassword() + ',' + str(server.getConnections()) + ','
                     + server.getLastConnect() + ',' + server.getName() + '\n')
        fobj.close()
    
    def getRecentServers(self):
        """
        Get the Recent Servers. If already loaded from file, return the instance from
        memory, otherwise load from file. 
        
        @return dict of server objects (key = address)
        """
        if self.recentservers:
            return self.recentservers
        
        self.recentservers = {}
        fobj = None
        try:
            fobj = open(self.rec_file, "r") 
        except IOError:
            #the file does not exist! just return the empty dict created earlier
            return self.recentservers
        
        for line in fobj: 
            line = line.strip() 
            serverinfo = line.split(',') # file is a csv
            #format: ip,port,password, connectioncount,dateoflastconnection,name
            server = self.srvman.getServer(serverinfo[0], int(serverinfo[1]))
            server.setPassword(serverinfo[2])
            server.setConnections(int(serverinfo[3]))
            server.setLastConnect(serverinfo[4])
            server.setName(serverinfo[5])
            self.recentservers[server.getaddress()] = server
        fobj.close()
        
        return self.recentservers        
    
    def getConfiguration(self):
        """
        Returns the configuration dict.
        If not already loaded from fail, else returned from memory.
        """
        if self.configuration:
            return self.configuration
        
        self.configuration = self.init_configuration()
        
        fobj = None
        try:
            fobj = open(self.conf_file, "r") 
        except IOError:
            #the file does not exist! just return the default dict created earlier
            return self.configuration
        
        for line in fobj: 
            #format of the configuration file is a key value pair on each 
            #line separated by a '='
            
            key, value = line.split('=', 1)
            self.configuration[key] = value.strip('\n') #strip linebreak
        return self.configuration
    
    def saveConfiguration(self):
        """
        Writes the current configuration dict into the configuration file.
        """
        fobj = open(self.conf_file, "w")
         
        for key in self.configuration:
            value = self.configuration[key]
            #format of each line:  key=value
            fobj.write(key+'='+str(value)+'\n')
        fobj.close()
        
    def init_configuration(self):
        """
        Performs initialisation of the configuration dict
        by setting all available options to default values
        """
        configuration = {}
        
        configuration[cfgkey.URT_EXE] = 'urbanterror'
        configuration[cfgkey.URT_EXE_PATH] = ''
        configuration[cfgkey.URT_EXE_PARAMS] = ''
        configuration[cfgkey.OPT_SAVE_PW] = 'True'
        configuration[cfgkey.OPT_DEFAULT_TAB] = 0
        configuration[cfgkey.OPT_UPDATE_SL_ROW] = 'False'
        configuration[cfgkey.OPT_FILTER] = cfgvalues.BASIC_FILTER
        configuration[cfgkey.OPT_BUDDYSEARCH] = 'False'

        return configuration
    
    def value_as_boolean(self, value):
        """
        Converts a passed config value (always strings) to a boolean
        and returns the resulting boolean value
        
        @param value - a str with "True" or "False" as value
        @return the boolean representation of the string : True or False
        """
        if 'True' == value:
            return True
        elif 'False' == value:
            return False
        else:
            Log.log.warn('[value_as_boolean] - value is neither "True" nor '
                         + '"False"! value = ' + value)
            return False #fallback
        
    def value_from_boolean(self, value):
        """
        Converts a passed boolean value to the string representation that will
        be stored in a file
        
        @param value - the boolean value
        @return "True" or "False"
        """
        if value:
            return "True"
        else:
            return "False"
Beispiel #5
0
def create_app():
    app = Flask(__name__)
    #app = QuitableFlask(__name__)
    #init ThriftServer
    app.config['extractor'] = ThriftExtractor(
        host=THRIFT_EXTRACTOR_CONFIG['host'],
        port=THRIFT_EXTRACTOR_CONFIG['port'])
    app.config['downloader'] = ThriftDownloader(
        host=THRIFT_DOWNLOADER_CONFIG['host'],
        port=THRIFT_DOWNLOADER_CONFIG['port'])
    app.config['scheduler'] = ThriftScheduler(
        host=THRIFT_SCHEDULER_CONFIG['host'],
        port=THRIFT_SCHEDULER_CONFIG['port'])
    app.config['entity_extractor'] = ThriftEntityExtractor(
        host=THRIFT_ENTITY_EXTRACTOR_CONFIG['host'],
        port=THRIFT_ENTITY_EXTRACTOR_CONFIG['port'])
    app.config['crawler_merge'] = ThriftCrawlerMerge(
        **THRIFT_CRAWLERMERGE_CONFIG)
    app.config['data_saver'] = ThriftDataSaver(**THRIFT_DATA_SAVER_CONFIG)
    # 统计器
    app.config['statistics'] = Statistics(logger=i_manage_log,
                                          mysql_conf=MYSQL)
    realtime_crawl = {}
    if hasattr(conf, "realtime_crawl"):
        realtime_crawl = conf.realtime_crawl
    app.config['schedule_debug'] = ScheduleDebug(logger=i_manage_log,
                                                 mysql_conf=MYSQL,
                                                 crawl_conf=realtime_crawl)
    # 服务监控器
    app.config['server_manager'] = ServerManager(logger=i_manage_log,
                                                 redis_conf=REDIS)
    # 消息队列服务
    app.config['put_beanstald_server'] = PutBeanstaldServer(
        beanstalk_conf=BEANSTALKD_CONFIG, log=i_manage_log)
    app.config['put_beanstald_server'].start()
    # 代理设置
    app.config['proxy'] = Proxies(log=i_manage_log, config=REDIS)
    #init MysqlEngine
    engine = create_engine(MYSQL)
    Dsession = sessionmaker(bind=engine)
    app.config['Dsession'] = Dsession
    # mongodb
    mongo_conn = pymongo.MongoClient(host=MONGODB['host'],
                                     port=MONGODB['port'])
    if MONGODB['username'] != '':
        app.config['mongodb'] = mongo_conn[MONGODB['database']]
        app.config['mongodb'].authenticate(MONGODB['username'],
                                           MONGODB['password'])
    else:
        app.config['mongodb'] = mongo_conn[MONGODB['database']]

    # redis
    app.config['redis'] = REDIS
    app.config['redis_conn'] = StrictRedis(host=REDIS['host'],
                                           port=REDIS['port'],
                                           password=REDIS['password'])
    # regiest log
    app.config['logger'] = i_manage_log
    #register blueprint
    from parser_api import parser_api
    app.register_blueprint(parser_api, url_prefix='/api/parser')
    from stat_api import stat_api
    app.register_blueprint(stat_api, url_prefix='/api/statistics')
    from site_api import site_api
    app.register_blueprint(site_api, url_prefix='/api/site')
    from seed_api import seed_api
    app.register_blueprint(seed_api, url_prefix='/api/seed')
    from topic_api import topic_api
    app.register_blueprint(topic_api, url_prefix='/api/topic')
    from schedule_api import schedule_api
    app.register_blueprint(schedule_api, url_prefix='/api/schedule')
    from download_api import download_api
    app.register_blueprint(download_api, url_prefix='/api/download')
    from datasave_api import datasave_api
    app.register_blueprint(datasave_api, url_prefix='/api/datasave')
    from entity_api import entity_api
    app.register_blueprint(entity_api, url_prefix='/api/entity')

    @app.route('/test_parser_config')
    def test_parser_config():
        return app.send_static_file('test_parser_config.html')

    return app
Beispiel #6
0
    def getServerList(self, host, port, empty, full):
        """
        Query a master server to retreive a list of registered game servers.
        
        @param host - host of the master server
        @param port - port of the master server
        @param empty - boolean parameter - false = empty servers will not be returned
                       by the master server - true = get also empty servers
        @param full - boolean parameter - false = full sercers will no be returned 
                      by the master server - true = get also full servers
                      
        @return list of server objects
        """
        Log.log.info('[Q3ServerQuery] - start master server query')

        #server manager
        srvman = ServerManager()
        self.serverlist = []

        #open socket to the master server
        s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
        s.connect((host, port))
        s.settimeout(2)
        # build command string based on the provided parameters empty and full
        # format 'OOBgetservers protocol [empty] [full] [demo]'
        cmd = self.packet_prefix + 'getservers  68 '
        if empty and full:
            cmd += 'empty full'
        else:
            if empty:
                cmd += 'empty'
            if full:
                cmd += 'full'
        cmd += ' demo'
        # send !
        s.send(cmd)

        # the master server can send multiple reponse packets based on the count
        # of servers - collect all of these response packtes in a list
        self.response = []
        while True:
            try:
                # a full responsepacket has 1394 bytes so use 1395 as
                # receive buffer
                response = s.recv(1395)

            except:
                break

            if not response:
                break
            else:
                self.response.append(response)

        Log.log.debug('[Q3ServerQuery] received ' \
                    + str(len(self.response)) + ' response packets ' \
                    + 'from master server')

        # parse the response
        # packet format: all packets starts with the OOB bytes and a
        # 'getserversResponse' string. after this start the server list starts
        # which are each 7 bytes. Start with the char / (first byte), the next
        # four bytes are the ip and the last two bytes is the port number
        # transmission of servers ends with '/EOF' at the end of the last packet
        for packet in self.response:
            index = 22  # OOB bytes + getserversResponse = 22 bytes
            # iterate over the 7 byte fields in the packet
            while True:
                # /EOF or malformed packet
                if index + 7 >= len(packet):
                    break
                # ip
                ip = inet_ntop(socket.AF_INET, packet[index + 1:index + 5])
                #port
                port = 256 * ord(packet[index + 5]) + ord(packet[index + 6])
                index += 7
                # create server object and add it to the serverlist that will
                # be returned
                server = srvman.getServer(ip, int(port))
                self.serverlist.append(server)

        s.close()

        Log.log.info('[Q3ServerQuery] - finished master server query. ' \
                     + 'returning list with ' + str(len(self.serverlist)) \
                     + ' servers')
        return self.serverlist
Beispiel #7
0
  def getServerList(self, host, port, empty, full):
      """
      Query a master server to retreive a list of registered game servers.
      
      @param host - host of the master server
      @param port - port of the master server
      @param empty - boolean parameter - false = empty servers will not be returned
                     by the master server - true = get also empty servers
      @param full - boolean parameter - false = full sercers will no be returned 
                    by the master server - true = get also full servers
                    
      @return list of server objects
      """
      Log.log.info('[Q3ServerQuery] - start master server query')
      
      #server manager
      srvman = ServerManager()
      self.serverlist = []
      
      #open socket to the master server
      s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
      s.connect((host, port))
      s.settimeout(2) 
      # build command string based on the provided parameters empty and full
      # format 'OOBgetservers protocol [empty] [full] [demo]'
      cmd = self.packet_prefix+'getservers  68 '
      if empty and full:
          cmd+='empty full'
      else:
          if empty:
              cmd+='empty'
          if full:
              cmd+='full'
      cmd+=' demo'
      # send !
      s.send(cmd)
      
      # the master server can send multiple reponse packets based on the count
      # of servers - collect all of these response packtes in a list
      self.response = []
      while True:
          try:
              # a full responsepacket has 1394 bytes so use 1395 as 
              # receive buffer
              response = s.recv(1395)
                 
          except:
              break
          
          if not response :
              break
          else:
              self.response.append(response)
     
      Log.log.debug('[Q3ServerQuery] received ' \
                  + str(len(self.response)) + ' response packets ' \
                  + 'from master server')
     
      # parse the response 
      # packet format: all packets starts with the OOB bytes and a
      # 'getserversResponse' string. after this start the server list starts
      # which are each 7 bytes. Start with the char / (first byte), the next
      # four bytes are the ip and the last two bytes is the port number
      # transmission of servers ends with '/EOF' at the end of the last packet
      for packet in self.response:
          index = 22 # OOB bytes + getserversResponse = 22 bytes
          # iterate over the 7 byte fields in the packet 
          while True:
              # /EOF or malformed packet
              if index+7>=len(packet):
                  break
              # ip              
              ip = inet_ntop(socket.AF_INET, packet[index+1:index+5])
              #port
              port = 256*ord(packet[index+5]) + ord(packet[index+6])
              index+=7
              # create server object and add it to the serverlist that will
              # be returned
              server = srvman.getServer(ip, int(port))
              self.serverlist.append(server)
       
      s.close()
      
      Log.log.info('[Q3ServerQuery] - finished master server query. ' \
                   + 'returning list with ' + str(len(self.serverlist)) \
                   + ' servers')
      return self.serverlist
      
 
      
Beispiel #8
0
class FileManager(object):
    """
    This class handles all file accesses of UrTSB.
    
    1. read/write of configuration
    2. access file for loading/storing favorites list
    3. access file for loading/storing recent servers
    
    """
    __shared_state = {}  # borg pattern

    instance = None

    favorites = None
    recentservers = None
    configuration = None
    buddies = None
    filter = None
    rconpws = None
    window_sizing = None

    #filenames
    conf_file = 'urtsb.cfg'
    fav_file = 'favorites.srv'
    rec_file = 'recent.srv'
    buddies_file = 'buddies.cfg'
    log_file = 'urtsb.log'
    filter_file = 'filter.pkl'
    rcon_file = 'rcon_pws.cfg'
    window_size_file = 'window_size.pkl'

    def __init__(self):
        """
        Constructor
        """
        self.__dict__ = self.__shared_state  # borg pattern

        if not self.instance:
            self.instance = True

            # extend filenames with path to the configurationfolder
            self.log_file = Globals.config_dir + FileManager.log_file
            self.fav_file = Globals.config_dir + FileManager.fav_file
            self.rec_file = Globals.config_dir + FileManager.rec_file
            self.conf_file = Globals.config_dir + FileManager.conf_file
            self.buddies_file = Globals.config_dir + FileManager.buddies_file
            self.filter_file = Globals.config_dir + FileManager.filter_file
            self.rcon_file = Globals.config_dir + FileManager.rcon_file
            self.window_size_file = Globals.config_dir+FileManager.\
                                                                window_size_file

            #initialise ServerManager
            self.srvman = ServerManager()

    def get_window_sizing(self):
        """
        Loads the window size settings from the file or returnes a already 
        loaded instance if available
        """
        if self.window_sizing:
            return self.window_sizing

        pkl_file = None
        try:
            pkl_file = open(self.window_size_file, "rb")
        except IOError:
            self.window_sizing = WindowSizing()
            return self.window_sizing

        self.window_sizing = pickle.load(pkl_file)

        pkl_file.close()
        return self.window_sizing

    def save_window_sizing(self):
        """
        Saves the window sizing instance in a file
        """
        pkl_file = open(self.window_size_file, "wb")

        pickle.dump(self.window_sizing, pkl_file, pickle.HIGHEST_PROTOCOL)

        pkl_file.close()

    def get_buddies(self):
        """
        Get the list of buddies (names or part of names). If already loaded 
        from file the instance from memory is returned, otherwise it is fresh 
        loaded from the file.
        
        @return list of server names
        """
        if self.buddies:
            return self.buddies

        self.buddies = []

        fobj = None
        try:
            fobj = open(self.buddies_file, "r")
        except IOError:
            #the file does not exist! just return the empty list created earlier
            return self.buddies

        for line in fobj:
            line = line.strip('\n')
            self.buddies.append(line)
        fobj.close()
        return self.buddies

    def save_buddies(self):
        """
        Writes the list of buddies to the buddies file.
        """
        fobj = open(self.buddies_file, "w")
        for name in self.buddies:

            #format: one name on every line
            fobj.write(name + '\n')
        fobj.close()

    def save_rcon_passwords(self):
        """
        Saves the dict of rcon passwords
        """
        fobj = open(self.rcon_file, "w")
        for key in self.rconpws:
            pw = self.rconpws[key]
            #format: address,pw
            fobj.write(key + ',' + pw + '\n')
        fobj.close()

    def get_rcon_passwords(self):
        """
        Get a dict with server adress as key and rcon pws as values
        
        @return the dict of rcon pws
        """
        if self.rconpws:
            return self.rconpws

        self.rconpws = {}
        fobj = None
        try:
            fobj = open(self.rcon_file, "r")
        except IOError:
            #the file does not exist! just return the empty dict created earlier
            return self.rconpws

        for line in fobj:
            line = line.strip()
            rconline = line.split(',')  # file is a csv
            #format: adress,pw
            self.rconpws[rconline[0]] = rconline[1]
        fobj.close()

        return self.rconpws

    def getFavorites(self):
        """
        Get the Favorites. If already loaded from file, return the instance from
        memory, otherwise load from file. 
        
        @return dict of server objects (key = address)
        """
        if self.favorites:
            return self.favorites

        self.favorites = {}
        fobj = None
        try:
            fobj = open(self.fav_file, "r")
        except IOError:
            #the file does not exist! just return the empty dict created earlier
            return self.favorites

        for line in fobj:
            line = line.strip()
            serverinfo = line.split(',')  # file is a csv
            #format: ip,port,password,servername
            server = self.srvman.getServer(serverinfo[0], int(serverinfo[1]))
            server.setPassword(serverinfo[2])
            server.setName(serverinfo[3])
            server.setIsFavorite(True)
            #use the address (ip:port) as key to avoid duplicate entries
            self.favorites[server.getaddress()] = server
        fobj.close()

        return self.favorites

    def get_remembered_filter_parameters(self):
        """
        Load the 'remembered' filter paramters from file
        using the pickle python object serialization
        
        @return the filter dict
        """

        if self.filter:  #already loaded!
            return self.filter

        pkl_file = None
        try:
            pkl_file = open(self.filter_file, "rb")
        except IOError:
            #file not found - just return None
            filter = {}

            filter[filterkey.GT_ALL] = 'True'
            filter[filterkey.GT_BOMB] = 'True'
            filter[filterkey.GT_TS] = 'True'
            filter[filterkey.GT_CTF] = 'True'
            filter[filterkey.GT_TDM] = 'True'
            filter[filterkey.GT_CAH] = 'True'
            filter[filterkey.GT_FTL] = 'True'
            filter[filterkey.GT_FFA] = 'True'

            #other filters
            filter[filterkey.FLT_MIN_PLAYERS] = 0
            filter[filterkey.FLT_MAX_PLAYERS] = 99

            filter[filterkey.FLT_HIDE_NON_RESP] = 'True'
            filter[filterkey.FLT_HIDE_PASSWORDED] = 'True'

            #mapname and servername filter
            filter[filterkey.FLT_MAP_NAME] = ''
            filter[filterkey.FLT_SERVER_NAME] = ''

            #query params
            filter[filterkey.QRY_SHOW_FULL] = 'False'
            filter[filterkey.QRY_SHOW_EMPTY] = 'False'

            filter[filterkey.FLT_GEAR] = cfgvalues.DISABLED

            filter[filterkey.FLT_VAR_LIST] = []
            self.filter = filter
            return filter

        self.filter = pickle.load(pkl_file)

        Log.log.debug('[get_remembered_filter_parameters] loaded filter = '\
                      + str(self.filter))

        pkl_file.close()

        return self.filter

    def save_filter_to_remember(self):
        """
        Saves the current filter parameters to the filter file
        using the pickle python object serialization
        """
        pkl_file = open(self.filter_file, "wb")

        pickle.dump(self.filter, pkl_file, pickle.HIGHEST_PROTOCOL)
        Log.log.debug('[save_filter_to_remember]: saved filter = ' +
                      str(self.filter))
        pkl_file.close()

    def addFavorite(self, server):
        """
        Adds a new favorite server to the list of favorites.
        Note: Immediately writes the current state of the list 
        into the favorites file. 
        
        @param server - the server object to add
        """
        favs = self.getFavorites()  # this makes sure it is initialized
        if server.getaddress() not in favs:
            self.favorites[server.getaddress()] = server
            #immdediately save to file in order to avoid a loss of data (crash etc.)
            self.saveFavorites()
            server.setIsFavorite(True)

    def removeFavorite(self, server):
        """
        Removes a existing favorite server from the favorites list.
        Note: Immediately updates the favorties file.
        
        @param server - the server object to be removed
        """
        favs = self.getFavorites()  # this makes sure it is initialized
        if server.getaddress() in favs:
            del self.favorites[server.getaddress()]
            self.saveFavorites()

    def remove_buddy(self, name):
        """
        Removes a name from the buddylist and immediately persists this change
        to the list into the buddylist file.
        
        @param name - the name to be removed
        """
        for i in range(len(self.buddies)):
            if name == self.buddies[i]:
                del self.buddies[i]
                break  # already found the name to delete, so we can stop the loop
        self.save_buddies()

    def removeRecentServer(self, server):
        """
        Removes a existing recent server entry from the list.
        Note: Immediately updates the recent servers file.
        
        @param server - the server object to be removed
        """
        recents = self.getRecentServers()  # this makes sure it is initialized
        if server.getaddress() in recents.keys():
            del self.recentservers[server.getaddress()]
            self.saveRecentServers()

    def clearRecentServerList(self):
        """
        Clears the list of recent servers.
        """
        self.recentservers = {}
        self.saveRecentServers()

    def addRecent(self, server):
        """
        Adds a new server to the list of recent connected servers.
        Note: Immediately writes the current state of the list 
        into the recent servers file.
        Or if server exists, updates the existing entry 
        
        @param server - the server object to add
        """
        recent_servers = self.getRecentServers()
        if server.getaddress() not in self.recentservers:
            server.setConnections(1)
            self.recentservers[server.getaddress()] = server
        else:

            existing_entry = recent_servers[server.getaddress()]
            conns = existing_entry.getConnections()
            conns += 1
            existing_entry.setConnections(conns)
            server = existing_entry

        server.setLastConnect(time.strftime("%Y.%m.%d - %H:%M"))
        #immdediately save to file in order to avoid a loss of data (crash etc.)
        self.saveRecentServers()

    def saveFavorites(self):
        """
        Performs the writing to the favorites file.
        """
        fobj = open(self.fav_file, "w")
        for key in self.favorites:
            server = self.favorites[key]
            #format: ip,port,password,servername
            fobj.write(server.getHost() + ',' + str(server.getPort()) + ',' +
                       server.getPassword() + ',' + server.getName() + '\n')
        fobj.close()

    def saveRecentServers(self):
        """
        Performs the writing to the recent servers file
        """
        fobj = open(self.rec_file, "w")

        for key in self.recentservers:
            server = self.recentservers[key]
            #format: ip,port,password, connectioncount,dateoflastconnection,name
            fobj.write(server.getHost() + ',' + str(server.getPort()) + ',' +
                       server.getPassword() + ',' +
                       str(server.getConnections()) + ',' +
                       server.getLastConnect() + ',' + server.getName() + '\n')
        fobj.close()

    def getRecentServers(self):
        """
        Get the Recent Servers. If already loaded from file, return the instance from
        memory, otherwise load from file. 
        
        @return dict of server objects (key = address)
        """
        if self.recentservers:
            return self.recentservers

        self.recentservers = {}
        fobj = None
        try:
            fobj = open(self.rec_file, "r")
        except IOError:
            #the file does not exist! just return the empty dict created earlier
            return self.recentservers

        for line in fobj:
            line = line.strip()
            serverinfo = line.split(',')  # file is a csv
            #format: ip,port,password, connectioncount,dateoflastconnection,name
            server = self.srvman.getServer(serverinfo[0], int(serverinfo[1]))
            server.setPassword(serverinfo[2])
            server.setConnections(int(serverinfo[3]))
            server.setLastConnect(serverinfo[4])
            server.setName(serverinfo[5])
            self.recentservers[server.getaddress()] = server
        fobj.close()

        return self.recentservers

    def getConfiguration(self):
        """
        Returns the configuration dict.
        If not already loaded from fail, else returned from memory.
        """
        if self.configuration:
            return self.configuration

        self.configuration = self.init_configuration()

        fobj = None
        try:
            fobj = open(self.conf_file, "r")
        except IOError:
            #the file does not exist! just return the default dict created earlier
            return self.configuration

        for line in fobj:
            #format of the configuration file is a key value pair on each
            #line separated by a '='

            key, value = line.split('=', 1)
            self.configuration[key] = value.strip('\n')  #strip linebreak
        return self.configuration

    def saveConfiguration(self):
        """
        Writes the current configuration dict into the configuration file.
        """
        fobj = open(self.conf_file, "w")

        for key in self.configuration:
            value = self.configuration[key]
            #format of each line:  key=value
            fobj.write(key + '=' + str(value) + '\n')
        fobj.close()

    def init_configuration(self):
        """
        Performs initialisation of the configuration dict
        by setting all available options to default values
        """
        configuration = {}

        configuration[cfgkey.URT_EXE] = 'urbanterror'
        configuration[cfgkey.URT_EXE_PATH] = ''
        configuration[cfgkey.URT_EXE_PARAMS] = ''
        configuration[cfgkey.OPT_SAVE_PW] = 'True'
        configuration[cfgkey.OPT_DEFAULT_TAB] = 0
        configuration[cfgkey.OPT_UPDATE_SL_ROW] = 'False'
        configuration[cfgkey.OPT_FILTER] = cfgvalues.BASIC_FILTER
        configuration[cfgkey.OPT_BUDDYSEARCH] = 'False'

        return configuration

    def value_as_boolean(self, value):
        """
        Converts a passed config value (always strings) to a boolean
        and returns the resulting boolean value
        
        @param value - a str with "True" or "False" as value
        @return the boolean representation of the string : True or False
        """
        if 'True' == value:
            return True
        elif 'False' == value:
            return False
        else:
            Log.log.warn('[value_as_boolean] - value is neither "True" nor ' +
                         '"False"! value = ' + value)
            return False  #fallback

    def value_from_boolean(self, value):
        """
        Converts a passed boolean value to the string representation that will
        be stored in a file
        
        @param value - the boolean value
        @return "True" or "False"
        """
        if value:
            return "True"
        else:
            return "False"