def onLoadConfig(self): """ Load plugin configuration. """ try: if self.config.get('settings', 'output_file')[0:6] == 'ftp://': self._ftpstatus = True self._ftpinfo = functions.splitDSN(self.config.get('settings', 'output_file')) self.debug('using custom remote path for settings/output_file: %s/%s' % (self._ftpinfo['host'], self._ftpinfo['path'])) else: self._outputFile = self.config.getpath('settings', 'output_file') self.debug('using custom local path for settings/output_file: %s' % self._outputFile) except NoOptionError: self._outputFile = os.path.normpath(os.path.expanduser(self._outputFile)) self.warning('could not find settings/output_file in config file, using default: %s' % self._outputFile) self._tkPlugin = self.console.getPlugin('tk') try: self._interval = self.config.getint('settings', 'interval') self.debug('using custom value for settings/interval: %s' % self._interval) except NoOptionError: self.warning('could not find settings/interval in config file, using default: %s' % self._interval) except ValueError, e: self.error('could not load settings/interval config value: %s' % e) self.debug('using default value (%s) for settings/interval' % self._interval)
def onLoadConfig(self): if self.config.get('settings','output_file')[0:6] == 'ftp://': self._ftpinfo = functions.splitDSN(self.config.get('settings','output_file')) self._ftpstatus = True else: self._outputFile = os.path.expanduser(self.config.get('settings', 'output_file')) self._tkPlugin = self.console.getPlugin('tk') self._interval = self.config.getint('settings', 'interval') try: self._enableDBsvarSaving = self.config.getboolean('settings', 'enableDBsvarSaving') except: self._enableDBsvarSaving = False try: self._enableDBclientSaving = self.config.getboolean('settings', 'enableDBclientSaving') except: self._enableDBclientSaving = False if self._enableDBsvarSaving: sql = "CREATE TABLE IF NOT EXISTS `current_svars` (`id` int(11) NOT NULL auto_increment,`name` varchar(255) NOT NULL,`value` varchar(255) NOT NULL, PRIMARY KEY (`id`), UNIQUE KEY `name` (`name`)) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ;" self.console.storage.query(sql) if self._enableDBclientSaving: sql = "CREATE TABLE IF NOT EXISTS `current_clients` (`id` INT(3) NOT NULL AUTO_INCREMENT,`Updated` VARCHAR( 255 ) NOT NULL ,`Name` VARCHAR( 255 ) NOT NULL ,`Level` VARCHAR( 255 ) NOT NULL ,`DBID` VARCHAR( 255 ) NOT NULL ,`CID` VARCHAR( 255 ) NOT NULL ,`Joined` VARCHAR( 255 ) NOT NULL ,`Connections` VARCHAR( 255 ) NOT NULL ,`State` VARCHAR( 255 ) NOT NULL ,`Score` VARCHAR( 255 ) NOT NULL ,`IP` VARCHAR( 255 ) NOT NULL ,`GUID` VARCHAR( 255 ) NOT NULL ,`PBID` VARCHAR( 255 ) NOT NULL ,`Team` VARCHAR( 255 ) NOT NULL ,`ColorName` VARCHAR( 255 ) NOT NULL, PRIMARY KEY (`id`)) ENGINE = MYISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=1;" self.console.storage.query(sql) if self._cronTab: # remove existing crontab self.console.cron - self._cronTab self._cronTab = b3.cron.PluginCronTab(self, self.update, '*/%s' % self._interval) self.console.cron + self._cronTab
def __init__(self, dsn, console): self.console = console self._lock = thread.allocate_lock() self.db = None self.dsn = dsn self.dsnDict = functions.splitDSN(self.dsn) self.connect()
def __init__(self, config): """ Object constructor. :param config: The main configuration file """ b3.console = self self._timeStart = self.time() logging.basicConfig(level=b3.output.VERBOSE2, format='%(asctime)s\t%(levelname)s\t%(message)s') self.log = logging.getLogger('output') self.config = config if isinstance(config, (b3.config.XmlConfigParser, b3.config.CfgConfigParser)): self.config = b3.config.MainConfig(config) elif isinstance(config, b3.config.MainConfig): self.config = config else: self.config = b3.config.MainConfig(b3.config.load(config)) self.storage = SqliteStorage("sqlite://:memory:", splitDSN("sqlite://:memory:"), self) self.storage.connect() self.clients = b3.clients.Clients(self) self.game = b3.game.Game(self, "fakeGame") self.game.mapName = 'ut4_turnpike' self.cvars = {} self._handlers = defaultdict(list) self.input = StringIO()
def init_thread(self, ftpfiledsn): self.ftpconfig = functions.splitDSN(ftpfiledsn) # the '/' is not part of the uri-path according to RFC 1738 3.1. Common Internet Scheme Syntax self.url_path = self.ftpconfig['path'][1:] thread1 = threading.Thread(target=self.update) self.info("starting ftpytail thread") thread1.start()
def __init__(self, config): """ Object constructor. :param config: The main configuration file """ b3.console = self self._timeStart = self.time() logging.basicConfig(level=b3.output.VERBOSE2, format='%(asctime)s\t%(levelname)s\t%(message)s') self.log = logging.getLogger('output') self.config = config if isinstance(config, b3.config.XmlConfigParser) or isinstance(config, b3.config.CfgConfigParser): self.config = b3.config.MainConfig(config) elif isinstance(config, b3.config.MainConfig): self.config = config else: self.config = b3.config.MainConfig(b3.config.load(config)) self.storage = SqliteStorage("sqlite://:memory:", splitDSN("sqlite://:memory:"), self) self.storage.connect() self.clients = b3.clients.Clients(self) self.game = b3.game.Game(self, "fakeGame") self.game.mapName = 'ut4_turnpike' self.cvars = {} self._handlers = {} if not self.config.has_option('server', 'punkbuster') or self.config.getboolean('server', 'punkbuster'): self.PunkBuster = b3.parsers.punkbuster.PunkBuster(self) self.input = StringIO.StringIO() self.working = True
def initThread(self, httpfileDSN): self.httpconfig = functions.splitDSN(httpfileDSN) self.url = httpfileDSN self.stop_event.clear() self.thread1 = threading.Thread(target=self.update) self.info("Starting httpytail thread") self.thread1.start()
def update(self): self.debug('Sending heartbeat to B3 master...') socket.setdefaulttimeout(10) plugins = [] for pname in self.console._pluginOrder: plugins.append("%s/%s" % (pname, getattr(getModule(self.console.getPlugin(pname).__module__), '__version__', 'Unknown Version'))) try: database = functions.splitDSN(self.console.storage.dsn)['protocol'] except: database = "unknown" version = getattr(b3, '__version__', 'Unknown Version') if b3.functions.main_is_frozen(): version += " win32" info = { 'action' : 'update', 'ip' : self.console._publicIp, 'port' : self.console._port, 'rconPort' : self.console._rconPort, 'version' : version, 'parser' : self.console.gameName, 'parserversion' : getattr(getModule(self.console.__module__), '__version__', 'Unknown Version'), 'database' : database, 'plugins' : ','.join(plugins), 'os' : os.name, 'python_version': sys.version } #self.debug(info) self.sendInfo(info)
def update(self): self.debug('Sending heartbeat to B3 master...') def getModule(name): mod = __import__(name) components = name.split('.') for comp in components[1:]: mod = getattr(mod, comp) return mod plugins = [] for pname in self.console._pluginOrder: plugins.append("%s/%s" % (pname, getattr(getModule(self.console.getPlugin(pname).__module__), '__version__', 'Unknown Version'))) info = { 'ip' : self.console._publicIp, 'port' : self.console._port, 'version' : getattr(b3, '__version__', 'Unknown Version'), 'parser' : self.console.gameName, 'parserversion' : getattr(getModule(self.console.__module__), '__version__', 'Unknown Version'), 'database' : functions.splitDSN(self.console.storage.dsn)['protocol'], 'plugins' : ','.join(plugins), 'os' : os.name } #self.debug(info) f = urllib.urlopen('%s?%s' % (self._url, urllib.urlencode(info))) self.debug(f.read()) f.close()
def startup(self): self.debug("startup()") # create the 'Server' client self.clients.newClient('Server', guid='Server', name='Server', hide=True, pbid='Server', team=b3.TEAM_UNKNOWN) if self.config.has_option('server','inifile'): # open ini file ini_file = self.config.get('server','inifile') if ini_file[0:6] == 'ftp://': self.ftpconfig = functions.splitDSN(ini_file) self._ini_file = 'ftp' self.bot('ftp supported') elif ini_file[0:7] == 'sftp://': self.bot('sftp currently not supported') else: self.bot('Getting configs from %s', ini_file) f = self.config.getpath('server', 'inifile') if os.path.isfile(f): self.input = file(f, 'r') self._ini_file = f if not self._ini_file: self.debug('Incorrect ini file or no ini file specified, map commands other than nextmap not available') # start crontab to trigger playerlist events self._cronTab = b3.cron.CronTab(self.retrievePlayerList, second='*/%s' % self._playerlistInterval) self.cron + self._cronTab # add specific events self.Events.createEvent('EVT_CLIENT_SQUAD_SAY', 'Squad Say') self.Events.createEvent('EVT_SERVER_SAY', 'Server Chatter') self.Events.createEvent('EVT_CLIENT_CLAN_CHANGE', 'Client Clan Change')
def setUp(self): """this method is called before each test""" B3TestCase.setUp(self) self.storage = self.console.storage = SqliteStorage( 'sqlite://' + SQLITE_DB, splitDSN('sqlite://' + SQLITE_DB), self.console) self.storage.connect()
def onLoadConfig(self): """ Load plugin configuration. """ try: if self.config.get("settings", "output_file")[0:6] == "ftp://": self._ftpstatus = True self._ftpinfo = functions.splitDSN(self.config.get("settings", "output_file")) self.debug( "using custom remote path for settings/output_file: %s/%s" % (self._ftpinfo["host"], self._ftpinfo["path"]) ) else: self._outputFile = self.config.getpath("settings", "output_file") self.debug("using custom local path for settings/output_file: %s" % self._outputFile) except NoOptionError: self._outputFile = os.path.normpath(os.path.expanduser(self._outputFile)) self.warning("could not find settings/output_file in config file, using default: %s" % self._outputFile) self._tkPlugin = self.console.getPlugin("tk") try: self._interval = self.config.getint("settings", "interval") self.debug("using custom value for settings/interval: %s" % self._interval) except NoOptionError: self.warning("could not find settings/interval in config file, using default: %s" % self._interval) except ValueError, e: self.error("could not load settings/interval config value: %s" % e) self.debug("using default value (%s) for settings/interval" % self._interval)
def startup(self): """ Called after the parser is created before run(). """ self.debug("startup") # create the 'Admin' client self.clients.newClient('Admin', guid='Server', name='Admin', hide=True, pbid='Server', team=b3.TEAM_UNKNOWN) if self.config.has_option('server', 'ro2admin'): self.username = self.config.get('server', 'ro2admin') else: self.username = "******" if self.config.has_option('server', 'inifile'): # open ini file ini_file = self.config.get('server', 'inifile') if ini_file[0:6] == 'ftp://': self.ftpconfig = functions.splitDSN(ini_file) self._ini_file = 'ftp' self.bot('ftp supported') elif ini_file[0:7] == 'sftp://': self.bot('sftp currently not supported') else: self.bot('getting configs from %s', ini_file) f = self.config.getpath('server', 'inifile') if os.path.isfile(f): self.input = file(f, 'r') self._ini_file = f if not self._ini_file: self.debug( 'Incorrect ini file or no ini file specified: map commands other than nextmap not available' ) self.cron.add( b3.cron.CronTab(self.retrievePlayerList, second='*/%s' % self._playerlistInterval)) self.user_agent = 'Mozilla/4.0 (compatible; MSIE 5.5; Windows NT)' self.headers = { 'User-Agent': self.user_agent, "Accept": "ext/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8", "Accept-Language": "en-us,en;q =0.5", "Content-type": "application/x-www-form-urlencoded", "Accept-Charset": "ISO-8859-1,utf-8;q=0.7,*;q=0.7", "Referer": '' } self.site = self._publicIp + ':' + str(self._rconPort) self.login_page = "ServerAdmin" self.password = self._rconPassword self.password_hash = "$sha1$%s" % hashlib.sha1( "%s%s" % (self.password, self.username)).hexdigest() self.url = "http://%s/%s" % (self.site, self.login_page)
def onLoadConfig(self): if self.config.get('settings','output_file')[0:6] == 'ftp://': self._ftpinfo = functions.splitDSN(self.config.get('settings','output_file')) self._ftpstatus = True else: self._outputFile = os.path.expanduser(self.config.get('settings', 'output_file')) self._cvars = [var.strip() for var in self.config.get('settings', 'cvars').split(',')] self.dump = self.config.get('settings','time').split(':')
def update(self): """send an upate heartbeat to B3 master server""" self.debug('Sending heartbeat to B3 master...') socket.setdefaulttimeout(10) plugins = [] for pname in self.console._pluginOrder: plugins.append( "%s/%s" % (pname, getattr(getModule(self.console.getPlugin(pname).__module__), '__version__', 'Unknown Version'))) try: database = functions.splitDSN(self.console.storage.dsn)['protocol'] except: database = "unknown" version = getattr(b3, '__version__', 'Unknown Version') if b3.functions.main_is_frozen(): version += " win32" info = { 'action': 'update', 'ip': self.console._publicIp, 'port': self.console._port, 'rconPort': self.console._rconPort, 'version': version, 'parser': self.console.gameName, 'parserversion': getattr(getModule(self.console.__module__), '__version__', 'Unknown Version'), 'database': database, 'plugins': ','.join(plugins), 'os': os.name, 'python_version': sys.version } if self.console.gameName in ('bfbc2', 'moh'): try: cvarDescription = self.console.getCvar('serverDescription') if cvarDescription is not None: info.update({'serverDescription': cvarDescription.value}) cvarBannerUrl = self.console.getCvar('bannerUrl') if cvarBannerUrl is not None: info.update({'bannerUrl': cvarBannerUrl.value}) except Exception, err: self.debug(err)
def startup(self): self.debug("startup()") # create the 'Server' client self.clients.newClient('Server', guid='Server', name='Server', hide=True, pbid='Server', team=b3.TEAM_UNKNOWN) if self.config.has_option('server','inifile'): # open ini file ini_file = self.config.get('server','inifile') if ini_file[0:6] == 'ftp://': self.ftpconfig = functions.splitDSN(ini_file) self._ini_file = 'ftp' self.bot('ftp supported') elif ini_file[0:7] == 'sftp://': self.bot('sftp currently not supported') else: self.bot('Getting configs from %s', ini_file) f = self.config.getpath('server', 'inifile') if os.path.isfile(f): self.input = file(f, 'r') self._ini_file = f if not self._ini_file: self.debug('Incorrect ini file or no ini file specified, map commands other than nextmap not available') # start crontab to trigger playerlist events self.cron + b3.cron.CronTab(self.retrievePlayerList, second='*/%s' % self._playerlistInterval) # add specific events self.Events.createEvent('EVT_CLIENT_SQUAD_SAY', 'Squad Say') self.Events.createEvent('EVT_SERVER_SAY', 'Server Chatter') self.Events.createEvent('EVT_CLIENT_CLAN_CHANGE', 'Client Clan Change') self.Events.createEvent('EVT_CLIENT_VOTE_START', 'Client Vote Start') self.Events.createEvent('EVT_CLIENT_VOTE', 'Client Vote') self.Events.createEvent('EVT_SERVER_VOTE_END', 'Server Vote End') #self.Events.createEvent('EVT_CLIENT_SQUAD_CHANGE', 'Client Squad Change') ## read game server info and store as much of it in self.game wich ## is an instance of the b3.game.Game class sq = SourceQuery.SourceQuery(self._publicIp, self._port, timeout=10) try: serverinfo = sq.info() self.debug("server info : %r", serverinfo) if 'map' in serverinfo: self.game.mapName = serverinfo['map'].lower() if 'steamid' in serverinfo: self.game.steamid = serverinfo['steamid'] if 'hostname' in serverinfo: self.game.sv_hostname = serverinfo['hostname'] if 'maxplayers' in serverinfo: self.game.sv_maxclients = serverinfo['maxplayers'] except Exception, err: self.exception(err)
def onLoadConfig(self): if self.config.get('settings', 'output_file')[0:6] == 'ftp://': self._ftpinfo = functions.splitDSN( self.config.get('settings', 'output_file')) self._ftpstatus = True else: self._outputFile = self.config.getpath('settings', 'output_file') self._tkPlugin = self.console.getPlugin('tk') self._interval = self.config.getint('settings', 'interval') try: self._enableDBsvarSaving = self.config.getboolean( 'settings', 'enableDBsvarSaving') except: self._enableDBsvarSaving = False try: self._enableDBclientSaving = self.config.getboolean( 'settings', 'enableDBclientSaving') except: self._enableDBclientSaving = False try: self._svarTable = self.config.get('settings', 'svar_table') self.debug('Using custom table for saving server svars: %s' % self._svarTable) except: self.debug('Using default table for saving server svars: %s' % self._svarTable) try: self._clientTable = self.config.get('settings', 'client_table') self.debug('Using custom table for saving current clients: %s' % self._clientTable) except: self.debug('Using default table for saving current clients: %s' % self._clientTable) if self._enableDBsvarSaving: sql = "CREATE TABLE IF NOT EXISTS `%s` (`id` int(11) NOT NULL auto_increment,`name` varchar(255) NOT NULL,`value` varchar(255) NOT NULL, PRIMARY KEY (`id`), UNIQUE KEY `name` (`name`)) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ;" % ( self._svarTable) self.console.storage.query(sql) if self._enableDBclientSaving: sql = "CREATE TABLE IF NOT EXISTS `%s` (`id` INT(3) NOT NULL AUTO_INCREMENT,`Updated` VARCHAR( 255 ) NOT NULL ,`Name` VARCHAR( 255 ) NOT NULL ,`Level` VARCHAR( 255 ) NOT NULL ,`DBID` VARCHAR( 255 ) NOT NULL ,`CID` VARCHAR( 255 ) NOT NULL ,`Joined` VARCHAR( 255 ) NOT NULL ,`Connections` VARCHAR( 255 ) NOT NULL ,`State` VARCHAR( 255 ) NOT NULL ,`Score` VARCHAR( 255 ) NOT NULL ,`IP` VARCHAR( 255 ) NOT NULL ,`GUID` VARCHAR( 255 ) NOT NULL ,`PBID` VARCHAR( 255 ) NOT NULL ,`Team` VARCHAR( 255 ) NOT NULL ,`ColorName` VARCHAR( 255 ) NOT NULL, PRIMARY KEY (`id`)) ENGINE = MYISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=1;" % ( self._clientTable) self.console.storage.query(sql) if self._cronTab: # remove existing crontab self.console.cron - self._cronTab self._cronTab = b3.cron.PluginCronTab(self, self.update, '*/%s' % self._interval) self.console.cron + self._cronTab
def run(self): """ Run the DB update """ clearscreen() print(""" _\|/_ (o o) {:>32} +----oOO---OOo----------------------------------+ | | | UPDATING B3 DATABASE | | | +-----------------------------------------------+ """.format('B3 : %s' % b3.__version__)) input("press any key to start the update...") def _update_database(storage, update_version): """ Update a B3 database. :param storage: the initialized storage module :param update_version: the update version """ if B3version(b3.__version__) >= update_version: sql = b3.getAbsolutePath('@b3/sql/%s/b3-update-%s.sql' % (storage.protocol, update_version)) if os.path.isfile(sql): try: print('>>> updating database to version %s' % update_version) sleep(.5) storage.queryFromFile(sql) except Exception as err: print( 'WARNING: could not update database properly: %s' % err) sleep(3) dsn = self.config.get('b3', 'database') dsndict = splitDSN(dsn) database = getStorage(dsn, dsndict, StubParser()) _update_database(database, '1.3.0') _update_database(database, '1.6.0') _update_database(database, '1.7.0') _update_database(database, '1.8.1') _update_database(database, '1.9.0') _update_database(database, '1.10.0') console_exit('B3 database update completed!')
def test_getConnection_mysql(self): # mock the pymysql module so we can test in an environement which does not have this module installed dsn = "mysql://*****:*****@somehost:someport/somedbname" mock_pymysql = Mock() mock_pymysql.connect = Mock(return_value=sentinel) with patch.dict('sys.modules', {'pymysql': mock_pymysql}): # verify that a correct dsn does work as expected mock_pymysql.connect.reset_mock() storage = MysqlStorage(dsn, splitDSN(dsn), Mock()) when(storage).getTables().thenReturn(B3_DEFAULT_TABLES) storage.connect() assert mock_pymysql.connect.called, "expecting pymysql.connect to be called" self.assertEqual(sentinel, storage.db) # verify that B3 creates necessary tables when they are missing mock_pymysql.connect.reset_mock() storage = MysqlStorage(dsn, splitDSN(dsn), Mock()) when(storage).getTables().thenReturn([]) storage.queryFromFile = Mock() storage.connect() assert storage.queryFromFile.called, "expecting MysqlStorage.queryFromFile to be called" self.assertEqual(sentinel, storage.db) # verify that whenever B3 is not able to create necessary tables, it stops mock_pymysql.connect.reset_mock() console_mock = Mock() console_mock.critical = Mock() storage = MysqlStorage(dsn, splitDSN(dsn), console_mock) storage.shutdown = Mock() when(storage).getTables().thenReturn([]) when(storage).queryFromFile(ANY()).thenRaise(Exception()) storage.connect() assert storage.shutdown.called, "expecting MysqlStorage.shutdown to be called" assert console_mock.critical.called, "expecting console_mock.critical to be called" self.assertIn("Missing MySQL database tables", console_mock.critical.call_args[0][0])
def update(self): """send an upate heartbeat to B3 master server""" self.debug("Sending heartbeat to B3 master...") socket.setdefaulttimeout(10) plugins = [] for pname in self.console._pluginOrder: plugins.append( "%s/%s" % ( pname, getattr(getModule(self.console.getPlugin(pname).__module__), "__version__", "Unknown Version"), ) ) try: database = functions.splitDSN(self.console.storage.dsn)["protocol"] except: database = "unknown" version = getattr(b3, "__version__", "Unknown Version") if b3.functions.main_is_frozen(): version += " win32" info = { "action": "update", "ip": self.console._publicIp, "port": self.console._port, "rconPort": self.console._rconPort, "version": version, "parser": self.console.gameName, "parserversion": getattr(getModule(self.console.__module__), "__version__", "Unknown Version"), "database": database, "plugins": ",".join(plugins), "os": os.name, "python_version": sys.version, "default_encoding": sys.getdefaultencoding(), } if self.console.gameName in ("bfbc2", "moh"): try: cvarDescription = self.console.getCvar("serverDescription") if cvarDescription is not None: info.update({"serverDescription": cvarDescription.value}) cvarBannerUrl = self.console.getCvar("bannerUrl") if cvarBannerUrl is not None: info.update({"bannerUrl": cvarBannerUrl.value}) except Exception, err: self.debug(err)
def onLoadConfig(self): if self.config.get('settings','output_file')[0:6] == 'ftp://': self._ftpinfo = functions.splitDSN(self.config.get('settings','output_file')) self._ftpstatus = True else: self._outputFile = os.path.expanduser(self.config.get('settings', 'output_file')) self._tkPlugin = self.console.getPlugin('tk') self._interval = self.config.getint('settings', 'interval') if self._cronTab: # remove existing crontab self.console.cron - self._cronTab self._cronTab = b3.cron.PluginCronTab(self, self.update, '*/%s' % self._interval) self.console.cron + self._cronTab
def setUp(self): """this method is called before each test""" B3TestCase.setUp(self) try: dsn = "postgresql://%s:%s@%s/%s" % (POSTGRESQL_TEST_USER, POSTGRESQL_TEST_PASSWORD, POSTGRESQL_TEST_HOST, POSTGRESQL_TEST_DB) self.storage = self.console.storage = PostgresqlStorage(dsn, splitDSN(dsn), self.console) self.storage.connect() tables = self.storage.getTables() if tables: # dont remove the groups table since we would need it in next tests tables.remove('groups') self.storage.truncateTable(tables) except Exception, e: self.fail("Error: %s" % e)
def startup(self): """ Called after the parser is created before run(). """ self.debug("startup") # create the 'Admin' client self.clients.newClient('Admin', guid='Server', name='Admin', hide=True, pbid='Server', team=b3.TEAM_UNKNOWN) if self.config.has_option('server','ro2admin'): self.username = self.config.get('server', 'ro2admin') else: self.username = "******" if self.config.has_option('server','inifile'): # open ini file ini_file = self.config.get('server','inifile') if ini_file[0:6] == 'ftp://': self.ftpconfig = functions.splitDSN(ini_file) self._ini_file = 'ftp' self.bot('ftp supported') elif ini_file[0:7] == 'sftp://': self.bot('sftp currently not supported') else: self.bot('getting configs from %s', ini_file) f = self.config.getpath('server', 'inifile') if os.path.isfile(f): self.input = file(f, 'r') self._ini_file = f if not self._ini_file: self.debug('Incorrect ini file or no ini file specified: map commands other than nextmap not available') self.cron.add(b3.cron.CronTab(self.retrievePlayerList, second='*/%s' % self._playerlistInterval)) self.user_agent = 'Mozilla/4.0 (compatible; MSIE 5.5; Windows NT)' self.headers = {'User-Agent': self.user_agent, "Accept": "ext/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8", "Accept-Language": "en-us,en;q =0.5", "Content-type": "application/x-www-form-urlencoded", "Accept-Charset": "ISO-8859-1,utf-8;q=0.7,*;q=0.7", "Referer": ''} self.site = self._publicIp + ':' + str(self._rconPort) self.login_page = "ServerAdmin" self.password = self._rconPassword self.password_hash = "$sha1$%s" % hashlib.sha1("%s%s" % (self.password, self.username)).hexdigest() self.url = "http://%s/%s" % (self.site, self.login_page)
def startup(self): patchCod4Parser() self.readConfig() if self._logToDB: self._storage = b3.storage.getStorage(self._dsn, splitDSN(self._dsn), self.console) self.debug('succesfully connected to database: %s' % self._storage.status()) self.checkTablesExist() self.registerEvent(EVT_ROTU_STATS_GAME) self.registerEvent(EVT_ROTU_STATS_PLAYER) self.registerEvent(EVT_ROTU_STATS_DONE) self.debug('Started')
class Test_MySQL(B3TestCase, StorageAPITest): def setUp(self): """this method is called before each test""" B3TestCase.setUp(self) try: db = driver.connect(host=MYSQL_TEST_HOST, user=MYSQL_TEST_USER, password=MYSQL_TEST_PASSWORD) except driver.OperationalError, message: self.fail("Error %d:\n%s" % (message[0], message[1])) db.query("DROP DATABASE IF EXISTS `%s`" % MYSQL_TEST_DB) db.query("CREATE DATABASE `%s` CHARACTER SET utf8;" % MYSQL_TEST_DB) dsn = "mysql://%s:%s@%s/%s" % (MYSQL_TEST_USER, MYSQL_TEST_PASSWORD, MYSQL_TEST_HOST, MYSQL_TEST_DB) self.storage = self.console.storage = MysqlStorage(dsn, splitDSN(dsn), self.console) self.storage.connect()
def update(self): """send an upate heartbeat to B3 master server""" self.debug('Sending heartbeat to B3 master...') socket.setdefaulttimeout(10) plugins = [] for pname in self.console._pluginOrder: plugins.append("%s/%s" % (pname, getattr(getModule(self.console.getPlugin(pname).__module__), '__version__', 'Unknown Version'))) try: database = functions.splitDSN(self.console.storage.dsn)['protocol'] except: database = "unknown" version = getattr(b3, '__version__', 'Unknown Version') if b3.functions.main_is_frozen(): version += " win32" info = { 'action' : 'update', 'ip' : self.console._publicIp, 'port' : self.console._port, 'rconPort' : self.console._rconPort, 'version' : version, 'parser' : self.console.gameName, 'parserversion' : getattr(getModule(self.console.__module__), '__version__', 'Unknown Version'), 'database' : database, 'plugins' : ','.join(plugins), 'os' : os.name, 'python_version': sys.version, 'default_encoding': sys.getdefaultencoding() } if self.console.gameName in ('bfbc2', 'moh'): try: cvarDescription = self.console.getCvar('serverDescription') if cvarDescription is not None: info.update({'serverDescription': cvarDescription.value}) cvarBannerUrl = self.console.getCvar('bannerUrl') if cvarBannerUrl is not None: info.update({'bannerUrl': cvarBannerUrl.value}) except Exception, err: self.debug(err)
def onLoadConfig(self): if self.config.get('settings', 'output_file')[0:6] == 'ftp://': self._ftpinfo = functions.splitDSN( self.config.get('settings', 'output_file')) self._ftpstatus = True else: self._outputFile = self.config.getpath('settings', 'output_file') self._tkPlugin = self.console.getPlugin('tk') self._interval = self.config.getint('settings', 'interval') try: self._enableDBsvarSaving = self.config.getboolean( 'settings', 'enableDBsvarSaving') except: self._enableDBsvarSaving = False try: self._enableDBclientSaving = self.config.getboolean( 'settings', 'enableDBclientSaving') except: self._enableDBclientSaving = False try: self._matchinterval = self.config.getint('settings', 'match_interval') except: self._matchinterval = self._interval try: self._showpass = self.config.getboolean('settings', 'show_password') except: self._showpass = False if self._enableDBsvarSaving: sql = "CREATE TABLE IF NOT EXISTS `current_svars` (`id` int(11) NOT NULL auto_increment,`name` varchar(255) NOT NULL,`value` varchar(255) NOT NULL, PRIMARY KEY (`id`), UNIQUE KEY `name` (`name`)) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ;" self.console.storage.query(sql) if self._enableDBclientSaving: sql = "CREATE TABLE IF NOT EXISTS `current_clients` (`id` INT(3) NOT NULL AUTO_INCREMENT,`Updated` VARCHAR( 255 ) NOT NULL ,`Name` VARCHAR( 255 ) NOT NULL ,`Level` VARCHAR( 255 ) NOT NULL ,`DBID` VARCHAR( 255 ) NOT NULL ,`CID` VARCHAR( 255 ) NOT NULL ,`Joined` VARCHAR( 255 ) NOT NULL ,`Connections` VARCHAR( 255 ) NOT NULL ,`State` VARCHAR( 255 ) NOT NULL ,`Score` VARCHAR( 255 ) NOT NULL ,`IP` VARCHAR( 255 ) NOT NULL ,`GUID` VARCHAR( 255 ) NOT NULL ,`PBID` VARCHAR( 255 ) NOT NULL ,`Team` VARCHAR( 255 ) NOT NULL ,`ColorName` VARCHAR( 255 ) NOT NULL, PRIMARY KEY (`id`)) ENGINE = MYISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=1;" self.console.storage.query(sql) if self._cronTab: # remove existing crontab self.console.cron - self._cronTab self._createCrontab(self._interval)
def setUp(self): """this method is called before each test""" B3TestCase.setUp(self) try: dsn = "postgresql://%s:%s@%s/%s" % ( POSTGRESQL_TEST_USER, POSTGRESQL_TEST_PASSWORD, POSTGRESQL_TEST_HOST, POSTGRESQL_TEST_DB) self.storage = self.console.storage = PostgresqlStorage( dsn, splitDSN(dsn), self.console) self.storage.connect() tables = self.storage.getTables() if tables: # dont remove the groups table since we would need it in next tests tables.remove('groups') self.storage.truncateTable(tables) except Exception, e: self.fail("Error: %s" % e)
def update(self): self.debug("Sending heartbeat to B3 master...") socket.setdefaulttimeout(10) def getModule(name): mod = __import__(name) components = name.split(".") for comp in components[1:]: mod = getattr(mod, comp) return mod plugins = [] for pname in self.console._pluginOrder: plugins.append( "%s/%s" % ( pname, getattr(getModule(self.console.getPlugin(pname).__module__), "__version__", "Unknown Version"), ) ) try: database = functions.splitDSN(self.console.storage.dsn)["protocol"] except: database = "unknown" version = getattr(b3, "__version__", "Unknown Version") if b3.functions.main_is_frozen(): version += " win32" info = { "action": "update", "ip": self.console._publicIp, "port": self.console._port, "version": version, "parser": self.console.gameName, "parserversion": getattr(getModule(self.console.__module__), "__version__", "Unknown Version"), "database": database, "plugins": ",".join(plugins), "os": os.name, } # self.debug(info) self.sendInfo(info)
def startup(self): self.debug("startup()") # create the 'Server' client self.clients.newClient('Server', guid='Server', name='Server', hide=True, pbid='Server', team=b3.TEAM_UNKNOWN) if self.config.has_option('server', 'inifile'): # open ini file ini_file = self.config.get('server', 'inifile') if ini_file[0:6] == 'ftp://': self.ftpconfig = functions.splitDSN(ini_file) self._ini_file = 'ftp' self.bot('ftp supported') elif ini_file[0:7] == 'sftp://': self.bot('sftp currently not supported') else: self.bot('Getting configs from %s', ini_file) f = self.config.getpath('server', 'inifile') if os.path.isfile(f): self.input = file(f, 'r') self._ini_file = f if not self._ini_file: self.debug( 'Incorrect ini file or no ini file specified, map commands other than nextmap not available' ) # start crontab to trigger playerlist events self._cronTab = b3.cron.CronTab(self.retrievePlayerList, second='*/%s' % self._playerlistInterval) self.cron + self._cronTab # add specific events self.Events.createEvent('EVT_CLIENT_SQUAD_SAY', 'Squad Say') self.Events.createEvent('EVT_SERVER_SAY', 'Server Chatter') self.Events.createEvent('EVT_CLIENT_CLAN_CHANGE', 'Client Clan Change')
def _write(self, text): if text.strip() == '': self._console.warning('AUTODOC: nothing to write') dsn = splitDSN(self._outputUrl) if dsn['protocol'] == 'ftp': self._console.debug('AUTODOC: uploading to FTP server %s' % dsn['host']) ftp = FTP(dsn['host'], dsn['user'], passwd=dsn['password']) ftp.cwd(os.path.dirname(dsn['path'])) ftpfile = StringIO.StringIO() ftpfile.write(text) ftpfile.seek(0) ftp.storbinary('STOR ' + os.path.basename(dsn['path']), ftpfile) elif dsn['protocol'] == 'file': path = getWritableFilePath(dsn['path'], True) self._console.debug('AUTODOC: writing to %s', path) f = file(path, 'w') f.write(text) f.close() else: self._console.error('AUTODOC: protocol [%s] is not supported' % dsn['protocol'])
def onLoadConfig(self): if self.config.get('settings','bans_file')[0:6] == 'ftp://': self._bansFile = self.config.get('settings','bans_file') self._remoteBansFile = True self._ftpConfig = functions.splitDSN(self._bansFile) self.info('Accessing pbbans.dat file in remote mode') else: self._bansFile = self.console.getAbsolutePath(self.config.get('settings', 'bans_file')) self._rebuildBans = self.config.get('settings', 'rebuild_bans') if self._cronTab: # remove old crontab self.console.cron - self._cronTab if self._rebuildBans == '0' or self._rebuildBans == 0: self._rebuildBans = 0 else: minute, hour, day, month, dow = self._rebuildBans.split(' ') self._cronTab = b3.cron.PluginCronTab(self, self.rebuildBans, '0', minute, hour, day, month, dow) self.console.cron + self._cronTab
def __init__(self, config): """ Object constructor. :param config: The main configuration file """ b3.console = self self._timeStart = self.time() logging.basicConfig(level=b3.output.VERBOSE2, format='%(asctime)s\t%(levelname)s\t%(message)s') self.log = logging.getLogger('output') self.config = config if isinstance(config, b3.config.XmlConfigParser) or isinstance( config, b3.config.CfgConfigParser): self.config = b3.config.MainConfig(config) elif isinstance(config, b3.config.MainConfig): self.config = config else: self.config = b3.config.MainConfig(b3.config.load(config)) self.storage = SqliteStorage("sqlite://:memory:", splitDSN("sqlite://:memory:"), self) self.storage.connect() self.clients = b3.clients.Clients(self) self.game = b3.game.Game(self, "fakeGame") self.game.mapName = 'ut4_turnpike' self.cvars = {} self._handlers = {} if not self.config.has_option('server', 'punkbuster') or self.config.getboolean( 'server', 'punkbuster'): self.PunkBuster = b3.parsers.punkbuster.PunkBuster(self) self.input = io.StringIO() self.working = True
def assertDsnEqual(self, url, expected): tmp = functions.splitDSN(url) self.assertEqual(tmp, expected)
def test_construct(self): self.assertRaises(AttributeError, MysqlStorage, 'foo://bar', splitDSN('foo://bar'), Mock())
def initThread(self, ftpfileDSN): self.sftpconfig = functions.splitDSN(ftpfileDSN) thread1 = threading.Thread(target=self.update) self.info("Starting sftpytail thread") thread1.start()
def test_sqlite(self): storage = getStorage('sqlite://:memory:', splitDSN('sqlite://:memory:'), Mock()) self.assertIsInstance(storage, SqliteStorage)
def test_postgresql(self): storage = getStorage('postgresql://*****:*****@localhost/b3', splitDSN('postgresql://*****:*****@localhost/b3'), Mock()) self.assertIsInstance(storage, PostgresqlStorage)
def init_thread(self, ftpfiledsn): self.sftpconfig = functions.splitDSN(ftpfiledsn) thread1 = threading.Thread(target=self.update) self.info("starting sftpytail thread") thread1.start() return thread1
class PublistPlugin(b3.plugin.Plugin): _cronTab = None _url = 'http://www.bigbrotherbot.net/master/serverping.php' _secondUrl = None requiresConfigFile = False _heartbeat_sent = False _initial_heartbeat_delay_minutes = 5 def onLoadConfig(self): try: self._secondUrl = self.config.get('settings', 'url') self.debug('Using second url : %s' % self._secondUrl) except: pass try: self._initial_heartbeat_delay_minutes = self.config.getint( 'settings', 'delay') self.debug('delay : %s' % self._initial_heartbeat_delay_minutes) except: pass def onStartup(self): # get the plugin so we can register commands self._adminPlugin = self.console.getPlugin('admin') if not self._adminPlugin: # something is wrong, can't start without admin plugin self.error('Could not find admin plugin') return False # set cvar for advertising purposes try: cvarValue = 'B3 %s' % b3.versionId self.console.setCvar('_B3', cvarValue) except: pass if self.console._publicIp == '127.0.0.1': self.info( "publist will not send heartbeat to master server as publicIp is not public." ) return rmin = random.randint(0, 59) rhour = random.randint(0, 23) self.debug("publist will send heartbeat at %02d:%02d every day" % (rhour, rmin)) self._cronTab = b3.cron.PluginCronTab(self, self.update, 0, rmin, rhour, '*', '*', '*') self.console.cron + self._cronTab # planning initial heartbeat # v1.9.1: Changing the threaded timer to a one time crontab to enable quick shutdown of the bot. _im = int(time.strftime('%M')) + self._initial_heartbeat_delay_minutes if _im >= 60: _im -= 60 self.info( 'initial heartbeat will be sent to B3 master server at %s minutes' % (str(_im).zfill(2))) self._cronTab = b3.cron.OneTimeCronTab(self.update, 0, _im, '*', '*', '*', '*') self.console.cron + self._cronTab def onEvent(self, event): if event.type == b3.events.EVT_STOP and self._heartbeat_sent: self.shutdown() def removeCrontab(self): try: self.console.cron - self._cronTab except KeyError: pass def shutdown(self): """Send a shutdown heartbeat to B3 master server""" self.info('Sending shutdown info to B3 master') info = { 'action': 'shutdown', 'ip': self.console._publicIp, 'port': self.console._port, 'rconPort': self.console._rconPort } #self.debug(info) self.sendInfo(info) def update(self): """send an upate heartbeat to B3 master server""" self.debug('Sending heartbeat to B3 master...') socket.setdefaulttimeout(10) plugins = [] for pname in self.console._pluginOrder: try: p = self.console.getPlugin(pname) p_module = getModule(p.__module__) p_version = getattr(p_module, '__version__', 'Unknown Version') plugins.append("%s/%s" % (pname, p_version)) except Exception, e: self.warning("Could not get version for plugin named '%s'" % pname, exc_info=e) try: database = functions.splitDSN(self.console.storage.dsn)['protocol'] except: database = "unknown" version = getattr(b3, '__version__', 'Unknown Version') if b3.functions.main_is_frozen(): version += " win32" info = { 'action': 'update', 'ip': self.console._publicIp, 'port': self.console._port, 'rconPort': self.console._rconPort, 'version': version, 'parser': self.console.gameName, 'parserversion': getattr(getModule(self.console.__module__), '__version__', 'Unknown Version'), 'database': database, 'plugins': ','.join(plugins), 'os': os.name, 'python_version': sys.version, 'default_encoding': sys.getdefaultencoding() } if self.console.gameName in ('bfbc2', 'moh'): try: cvarDescription = self.console.getCvar('serverDescription') if cvarDescription is not None: info.update({'serverDescription': cvarDescription.value}) cvarBannerUrl = self.console.getCvar('bannerUrl') if cvarBannerUrl is not None: info.update({'bannerUrl': cvarBannerUrl.value}) except Exception, err: self.debug(err)
def setUp(self): """this method is called before each test""" B3TestCase.setUp(self) self.storage = self.console.storage = SqliteStorage('sqlite://' + SQLITE_DB, splitDSN('sqlite://' + SQLITE_DB), self.console) self.storage.connect()
class PunkbusterPlugin(b3.plugin.Plugin): _adminPlugin = None _cronTab = None _remoteBansFile = False _ftpConfig = None _bansFile = '~/cod/pb/pbbans.dat' _rebuildBans = '0 0 * * *' #################################################################################################################### # # # STARTUP # # # #################################################################################################################### def onStartup(self): """ Initialize the plugin. """ self._adminPlugin = self.console.getPlugin('admin') if self.console.PunkBuster is None: self.warning( 'could not register commands because Punkbuster is disabled in your b3 configuration file' ) return False # register our commands if 'commands' in self.config.sections(): for cmd in self.config.options('commands'): level = self.config.get('commands', cmd) sp = cmd.split('-') alias = None if len(sp) == 2: cmd, alias = sp func = getCmd(self, cmd) if func: self._adminPlugin.registerCommand(self, cmd, level, func, alias) def onLoadConfig(self): """ Load plugin configuration """ try: self._bansFile = self.config.get('settings', 'bans_file') self.debug('loaded settings/bans_file: %s' % self._bansFile) except NoOptionError, e: self.error('could not load settings/bans_file config value: %s' % e) self.debug('using default value (%s) for settings/bans_file' % self._bansFile) if self._bansFile[0:6] == 'ftp://': self._remoteBansFile = True self._ftpConfig = functions.splitDSN(self._bansFile) self.info('accessing pbbans.dat file in remote mode') else: self._bansFile = self.console.getAbsolutePath(self._bansFile) try: self._rebuildBans = self.config.get('settings', 'rebuild_bans') self.debug('loaded settings/rebuild_bans: %s' % self._rebuildBans) except NoOptionError, e: self.error( 'could not load settings/rebuild_bans config value: %s' % e) self.debug('using default value (%s) for settings/rebuild_bans' % self._rebuildBans)
def __init__(self, config): self._timeStart = self.time() if not self.loadConfig(config): print 'COULD NOT LOAD CONFIG' raise SystemExit(220) # set up logging logfile = self.config.getpath('b3', 'logfile') self.log = b3.output.getInstance(logfile, self.config.getint('b3', 'log_level')) # save screen output to self.screen self.screen = sys.stdout print 'Activating log : %s' % logfile sys.stdout = b3.output.stdoutLogger(self.log) sys.stderr = b3.output.stderrLogger(self.log) # setup ip addresses self._publicIp = self.config.get('server', 'public_ip') self._rconIp = self.config.get('server', 'rcon_ip') self._port = self.config.getint('server', 'port') if self._publicIp[0:1] == '~' or self._publicIp[0:1] == '/': # load ip from a file f = file(self.getAbsolutePath(self._publicIp)) self._publicIp = f.read().strip() f.close() if self._rconIp[0:1] == '~' or self._rconIp[0:1] == '/': # load ip from a file f = file(self.getAbsolutePath(self._rconIp)) self._rconIp = f.read().strip() f.close() self.bot('%s', b3.sversion) self.bot('Python: %s', sys.version) self.bot('Starting %s server for %s:%s', self.__class__.__name__, self._rconIp, self._port) # get events self.Events = b3.events.eventManager self.bot('--------------------------------------------') # setup bot bot_name = self.config.get('b3', 'bot_name') if bot_name: self.name = bot_name bot_prefix = self.config.get('b3', 'bot_prefix') if bot_prefix: self.prefix = bot_prefix self.msgPrefix = self.prefix # delay between log reads if self.config.has_option('server', 'delay'): delay = self.config.getfloat('server', 'delay') self.delay = delay # demo mode: use log time if self.config.has_option('server', 'replay'): self.replay = self.config.getboolean('server', 'replay') if self.replay: self._timeStart = 0 self.bot('Replay mode enabled') self.storage = b3.storage.getStorage('database', self.config.get('b3', 'database'), self) # open log file if self.config.get('server','game_log')[0:6] == 'ftp://' : self.remoteLog = True self.bot('Working in Remote-Log-Mode') self.bot('Game log %s', self.config.get('server', 'game_log')) f = os.path.normpath(os.path.expanduser('games_mp.log')) ftptempfile = open(f, "w") ftptempfile.close() from b3 import functions from ftplib import FTP def handleDownload(block): self.file.write(block) self.file.flush() gamelog = self.config.get('server', 'game_log') ftpconfig = functions.splitDSN(gamelog) ftp=FTP(ftpconfig['host'], ftpconfig['user'], ftpconfig['password']) ftp.cwd(os.path.dirname(ftpconfig['path'])) self.file = open('games_mp.log', 'ab') size=os.path.getsize('games_mp.log') self.debug('Logfile updating, please wait') ftp.retrbinary('RETR ' + os.path.basename(ftpconfig['path']), handleDownload, rest=size) else: self.bot('Game log %s', self.config.getpath('server', 'game_log')) f = self.config.getpath('server', 'game_log') self.bot('Starting bot reading file %s', f) self.screen.write('Using Gamelog : %s\n' % f) if os.path.isfile(f): self.output = None self.input = file(f, 'r') # seek to point in log file? if self.replay: pass elif self.config.has_option('server', 'seek'): seek = self.config.getboolean('server', 'seek') if seek: self.input.seek(0, 2) else: self.input.seek(0, 2) else: self.error('Error reading file %s', f) raise SystemExit('Error reading file %s\n' % f) # setup rcon self.output = self.OutputClass(self, (self._rconIp, self._port), self.config.get('server', 'rcon_password')) # testing rcon res = self.output.write('Initiating %s' % self.config.get('b3', 'bot_name')) self.output.flush() self.screen.write('Testing RCON : ') self.screen.flush() if res == 'Bad rconpassword.': self.screen.write('>>> ERROR: Bad RCON password! This will lead to errors and render B3 without any power to interact!\n') self.screen.flush() time.sleep(10) elif res == '': self.screen.write('>>> ERROR: There is something wrong with the rcon connection to the server!\n>>> ERROR: Check your server-ip and port!\n') self.screen.flush() time.sleep(10) else: self.screen.write('OK\n') self.loadEvents() self.screen.write('Loading Events : %s events loaded\n' % len(self._events)) self.clients = b3.clients.Clients(self) self.loadPlugins() self.loadArbPlugins() self.game = b3.game.Game(self, self.gameName) self.queue = Queue.Queue(15) # event queue atexit.register(self.shutdown) self.say('%s ^2[ONLINE]' % b3.version)
def onStartup(self): if self.console.config.get('server','game_log')[0:6] == 'ftp://' : gamelog = self.console.config.get('server', 'game_log') self.ftpconfig = functions.splitDSN(gamelog) thread1 = threading.Thread( target=self.update) thread1.start()
class DBUpdate(object): """ Console database update procedure. """ def __init__(self, config=None): """ Object constructor. :param config: The B3 configuration file path """ if config: # use the specified configuration file config = b3.getAbsolutePath(config, True) if not os.path.isfile(config): console_exit('ERROR: configuration file not found (%s).\n' 'Please visit %s to create one.' % (config, B3_CONFIG_GENERATOR)) else: # search a configuration file for p in ('b3.%s', 'conf/b3.%s', 'b3/conf/b3.%s', os.path.join(HOMEDIR, 'b3.%s'), os.path.join(HOMEDIR, 'conf', 'b3.%s'), os.path.join(HOMEDIR, 'b3', 'conf', 'b3.%s'), '@b3/conf/b3.%s'): for e in ('ini', 'cfg', 'xml'): path = b3.getAbsolutePath(p % e, True) if os.path.isfile(path): print "Using configuration file: %s" % path config = path sleep(3) break if not config: console_exit('ERROR: could not find any valid configuration file.\n' 'Please visit %s to create one.' % B3_CONFIG_GENERATOR) try: self.config = b3.config.MainConfig(b3.config.load(config)) if self.config.analyze(): raise b3.config.ConfigFileNotValid except b3.config.ConfigFileNotValid: console_exit('ERROR: configuration file not valid (%s).\n' 'Please visit %s to generate a new one.' % (config, B3_CONFIG_GENERATOR)) def run(self): """ Run the DB update """ clearscreen() print """ _\|/_ (o o) {:>32} +----oOO---OOo----------------------------------+ | | | UPDATING B3 DATABASE | | | +-----------------------------------------------+ """.format('B3 : %s' % b3.__version__) raw_input("press any key to start the update...") def _update_database(storage, update_version): """ Update a B3 database. :param storage: the initialized storage module :param update_version: the update version """ if B3version(b3.__version__) >= update_version: sql = b3.getAbsolutePath('@b3/sql/%s/b3-update-%s.sql' % (storage.protocol, update_version)) if os.path.isfile(sql): try: print '>>> updating database to version %s' % update_version sleep(.5) storage.queryFromFile(sql) except Exception, err: print 'WARNING: could not update database properly: %s' % err sleep(3) dsn = self.config.get('b3', 'database') dsndict = splitDSN(dsn) database = getStorage(dsn, dsndict, StubParser()) _update_database(database, '1.3.0') _update_database(database, '1.6.0') _update_database(database, '1.7.0') _update_database(database, '1.8.1') _update_database(database, '1.9.0') _update_database(database, '1.10.0') console_exit('B3 database update completed!')