routes = [ (r"/", front.IndexHandler), (r"/content", front.ContentHandler), # (r'/i/(?P<code>.*)', front.Project), (r'/project/(?P<url>.*)', front.Project), (r"/project/info", front.ProjectInfo), (r"/hote/login", hote.LoginHandler), (r"/hote/register", hote.RegisterHandler), (r"/hote/logout", hote.LogoutHandler), (r"/hote", hote.IndexHandler), (r"/hote/list_project", hote.ListProject), (r"/hote/add_project", hote.AddProject), (r"/hote/add_project", hote.AddProject), (r'/hote/project/(?P<url>.*)', hote.ProjectInfo), (r"/hote/list_card", hote.ListCard), (r"/hote/add_card", hote.AddCard), (r"/templates/(.*?)", StaticFileHandler, dict(path=os.path.join(PACKAGE_FOLDER, 'templates'))), ] application = web.Application( routes, template_loader=Jinja2TemplateLoader(ABS_TEMPLATE_FOLDER_PATH), static_path=os.path.join(PACKAGE_FOLDER, 'static'), cookie_secret=COOKIE_SECRET, debug=DEBUG, ) application.sentry_client = AsyncSentryClient(SENTRY_DSN)
listeners=[MySQLPingListener()]) session_factory = scoped_session( sessionmaker(bind=engine, autoflush=True, autocommit=False)) self.db = session_factory() self.rcache = RedisManaher().cache_con() #redis cache conn self.mcache = MemcacheManager().get_conn() #memcache conn tornado.web.Application.__init__(self, handlers, **settings) if __name__ == "__main__": reload(sys) sys.setdefaultencoding('utf-8') parse_config_file(os.path.join(os.path.dirname(__file__), 'web_conf.conf')) tornado.options.parse_command_line() try: port = int(sys.argv[1]) except: port = 8008 #if port in [8103,8009,8102]: app = Application(handlers, options.ENGINE, **settings_mobile) app.sentry_client = AsyncSentryClient( 'http://*****:*****@logs.gongzhuhao.com/2' ) #else: # app = Application(handlers,engine, **settings_mobile) app.listen(port) print "Starting development server:", port http_server = tornado.httpserver.HTTPServer(app, xheaders=True) tornado.ioloop.IOLoop.instance().start()
def __init__(self, **args): settings = dict( debug=seplis.config['debug'], autoescape=None, xsrf_cookies=False, ) static_path = os.path.join(os.path.dirname(__file__), 'static') urls = [ URLSpec(r'/(favicon.ico)', tornado.web.StaticFileHandler, {'path': os.path.join(static_path, 'favicon.ico')}), URLSpec(r'/static/(.*)', tornado.web.StaticFileHandler, {'path': static_path}), URLSpec(r'/1/shows', seplis.api.handlers.show.Handler), URLSpec(r'/1/shows/externals/([a-z_-]+)/([a-z0-9]+)', seplis.api.handlers.show.External_handler), URLSpec(r'/1/shows/([0-9]+)', seplis.api.handlers.show.Handler), URLSpec(r'/1/shows/([0-9,]+)', seplis.api.handlers.show.Multi_handler), URLSpec(r'/1/shows/([0-9]+)/episodes', seplis.api.handlers.episode.Handler), URLSpec(r'/1/shows/([0-9]+)/episodes/([0-9]+)', seplis.api.handlers.episode.Handler), URLSpec(r'/1/shows/([0-9]+)/episodes/([0-9]+)/play-servers', seplis.api.handlers.episode.Play_servers_handler), URLSpec(r'/1/shows/([0-9]+)/images', seplis.api.handlers.image.Handler, {'relation_type': constants.IMAGE_RELATION_TYPE_SHOW}), URLSpec(r'/1/shows/([0-9]+)/images/([0-9]+)', seplis.api.handlers.image.Handler), URLSpec(r'/1/shows/([0-9]+)/images/([0-9]+)/data', seplis.api.handlers.image.Data_handler), URLSpec(r'/1/shows/([0-9]+)/update', seplis.api.handlers.show.Update_handler), URLSpec(r'/1/shows/([0-9]+)/fans', seplis.api.handlers.show.Fans_handler), URLSpec(r'/1/shows/([0-9]+)/fans/([0-9]+)', seplis.api.handlers.show.Fans_handler), URLSpec(r'/1/users', seplis.api.handlers.user.Handler), URLSpec(r'/1/users/current', seplis.api.handlers.user.Handler), URLSpec(r'/1/users/([0-9]+)', seplis.api.handlers.user.Handler), URLSpec(r'/1/users/([0-9]+)/fan-of', seplis.api.handlers.show.Fan_of_handler), URLSpec(r'/1/users/([0-9]+)/fan-of/([0-9]+)', seplis.api.handlers.show.Fan_of_handler), URLSpec(r'/1/users/([0-9]+)/stats', seplis.api.handlers.user.Stats_handler), URLSpec(r'/1/users/([0-9]+)/air-dates', seplis.api.handlers.episode.Air_dates_handler), URLSpec( r'/1/users/([0-9]+)/watched/shows/([0-9]+)/episodes/([0-9]+)', seplis.api.handlers.episode.Watched_handler), URLSpec( r'/1/users/([0-9]+)/watched/shows/([0-9]+)/episodes/([0-9]+)-([0-9]+)', seplis.api.handlers.episode.Watched_interval_handler), URLSpec(r'/1/users/([0-9]+)/tags', seplis.api.handlers.tag.User_types_handler), URLSpec(r'/1/users/([0-9]+)/tags/shows/([0-9]+)', seplis.api.handlers.tag.Relation_handler, {'type_': 'shows'}), URLSpec(r'/1/users/([0-9]+)/tags/([0-9]+)/shows/([0-9]+)', seplis.api.handlers.tag.Relation_handler, {'type_': 'shows'}), URLSpec(r'/1/users/([0-9]+)/tags/shows', seplis.api.handlers.tag.Relations_handler, {'type_': 'shows'}), URLSpec(r'/1/users/([0-9]+)/tags/([0-9]+)/shows', seplis.api.handlers.tag.Relations_handler, {'type_': 'shows'}), URLSpec(r'/1/users/([0-9]+)/play-servers/([0-9]+)', seplis.api.handlers.play.Server_handler), URLSpec(r'/1/users/([0-9]+)/play-servers', seplis.api.handlers.play.Server_handler), URLSpec(r'/1/users/([0-9]+)/play-servers/([0-9]+)/users', seplis.api.handlers.play.Access_handler), URLSpec(r'/1/users/([0-9]+)/play-servers/([0-9]+)/users/([0-9]+)', seplis.api.handlers.play.Access_handler), URLSpec(r'/1/apps', seplis.api.handlers.app.Handler), URLSpec(r'/1/apps/([0-9]+)', seplis.api.handlers.app.Handler), URLSpec(r'/1/token', seplis.api.handlers.user.Token_handler), URLSpec(r'.*', seplis.api.handlers.base.Handler), ] self.executor = ThreadPoolExecutor( max_workers=seplis.config['api']['max_workers']) self.sentry_client = AsyncSentryClient(seplis.config['sentry_dsn'], raise_send_errors=True) tornado.web.Application.__init__(self, urls, **settings)
def create_app(config=None, use_db_pool=True, ioloop=None): settings = setting_from_object(default_settings) if isinstance(config, dict): settings.update(config) handlers = [] + Route.routes() # Custom 404 ErrorHandler handlers.append((r"/(.*)", ErrorHandler)) settings['static_handler_class'] = StaticFileHandler app.initialize(tornado.web.Application(handlers, **settings)) if ioloop: from .libs.peewee_async import PooledMySQLDatabase from .libs.peewee_async import RetryMySQLDatabase else: from playhouse.pool import PooledMySQLDatabase from .ext.database import RetryMySQLDatabase # configure database if use_db_pool: db_conn = PooledMySQLDatabase( app.settings['db_name'], host=app.settings['db_host'], user=app.settings['db_user'], passwd=app.settings['db_passwd'], port=app.settings['db_port'], use_unicode=True, charset="utf8mb4", threadlocals=False, max_connections=app.settings['db_max_conns'], stale_timeout=1800) else: db_conn = RetryMySQLDatabase(app.settings['db_name'], host=app.settings['db_host'], user=app.settings['db_user'], passwd=app.settings['db_passwd'], port=app.settings['db_port'], use_unicode=True, charset="utf8mb4") db.initialize(db_conn) redis.init_app(app) app.db = db_conn app.redis = redis if ioloop: ioloop.run_until_complete(db_conn.connect_async()) celery.conf.update( BROKER_URL=app.settings['celery_broker_url'], CELERY_RESULT_BACKEND=app.settings['celery_result_url'], CELERY_TASK_SERIALIZER='json', CELERY_ACCEPT_CONTENT=['json'], # Ignore other content CELERY_RESULT_SERIALIZER='json', CELERY_TASK_RESULT_EXPIRES=18000, CELERY_TIMEZONE='Asia/Shanghai', CELERY_ENABLE_UTC=False, CELERYBEAT_SCHEDULE=app.settings["celerybeat_schedule"], ) celery.settings = app.settings celery.db = db celery.redis = redis logging.basicConfig( level=logging.DEBUG if app.settings['debug'] else logging.WARNING, format='%(asctime)s:%(msecs)03d %(levelname)-8s %(message)s', datefmt='%m-%d %H:%M') app.logger = logging.getLogger(str(app.__class__)) app.logger.setLevel( logging.DEBUG if app.settings['debug'] else logging.WARNING) if app.settings['sentry_dsn']: app.sentry_client = AsyncSentryClient(app.settings['sentry_dsn']) # app = Sentry(app, client=app.raven_client) else: app.sentry_client = None return app
try: if cli_args.port: consoleHelper.printColored("[!] Running on port {}, bypassing config.ini", bcolors.YELLOW) glob.serverPort = int(cli_args.port) else: glob.serverPort = glob.conf["HTTP_PORT"] except: consoleHelper.printColored("[!] Invalid server port! Please check your config.ini and run the server again", bcolors.RED) # Make app glob.application = make_app() # Set up sentry try: if glob.conf.sentry_enabled: glob.application.sentry_client = AsyncSentryClient(glob.conf["SENTRY_DSN"], release=glob.VERSION) else: consoleHelper.printColored("[!] Warning! Sentry logging is disabled!", bcolors.YELLOW) except: consoleHelper.printColored("[!] Error while starting Sentry client! Please check your config.ini and run the server again", bcolors.RED) # Set up Datadog try: if glob.conf.datadog_enabled: glob.dog = datadogClient.datadogClient( glob.conf["DATADOG_API_KEY"], glob.conf["DATADOG_APP_KEY"], constant_tags=["worker:{}".format(glob.serverPort)] ) else: consoleHelper.printColored("[!] Warning! Datadog stats tracking is disabled!", bcolors.YELLOW)
dict(path=path.join(options.static_root, 'static'))), (r'/(.*)', IndexHandler), ] settings = { 'host': options.host, 'port': options.port, 'debug': options.debug, 'session': { 'driver': 'file', 'driver_settings': { 'host': options.session_path }, 'cookie_config': { 'expires_days': 365 }, 'force_persistence': True, 'cache_driver': True } } mongo_connection.connect(host=options.mongo_uri) server = RobomanServer(bots=bots, mode=options.mode, handlers=handlers, settings=settings) server.sentry_client = AsyncSentryClient( 'https://*****:*****@sentry.team.ktsstudio.ru/6' ) server.start()
def make_external_app(router): app = Application(handlers=[(r'/(?P<path>.*)', handlers.ExecHandler)], debug=options.debug) app.router = router app.sentry_client = AsyncSentryClient(options.sentry_dsn) return app
def run(): app = Application() app.sentry_client = AsyncSentryClient(app.settings['sentry_url']) http_server = HTTPServer(app, xheaders=True) http_server.listen(options.port) print('Running on port %d' % options.port)
def main() -> int: # AGPL license agreement try: agpl.check_license("ripple", "LETS") except agpl.LicenseError as e: print(str(e)) return 1 try: consoleHelper.printServerStartHeader(True) # Read config consoleHelper.printNoNl("> Reading config file... ") glob.conf = config.config("config.ini") if glob.conf.default: # We have generated a default config.ini, quit server consoleHelper.printWarning() consoleHelper.printColored( "[!] config.ini not found. A default one has been generated.", bcolors.YELLOW) consoleHelper.printColored( "[!] Please edit your config.ini and run the server again.", bcolors.YELLOW) return 1 # If we haven't generated a default config.ini, check if it's valid if not glob.conf.checkConfig(): consoleHelper.printError() consoleHelper.printColored( "[!] Invalid config.ini. Please configure it properly", bcolors.RED) consoleHelper.printColored( "[!] Delete your config.ini to generate a default one", bcolors.RED) return 1 else: consoleHelper.printDone() # Read additional config file consoleHelper.printNoNl("> Loading additional config file... ") try: if not os.path.isfile(glob.conf.config["custom"]["config"]): consoleHelper.printWarning() consoleHelper.printColored( "[!] Missing config file at {}; A default one has been generated at this location." .format(glob.conf.config["custom"]["config"]), bcolors.YELLOW) shutil.copy("common/default_config.json", glob.conf.config["custom"]["config"]) with open(glob.conf.config["custom"]["config"], "r") as f: glob.conf.extra = json.load(f) consoleHelper.printDone() except: consoleHelper.printWarning() consoleHelper.printColored( "[!] Unable to load custom config at {}".format( glob.conf.config["custom"]["config"]), bcolors.RED) return 1 # Create data/oppai maps folder if needed consoleHelper.printNoNl("> Checking folders... ") paths = [ ".data", ".data/oppai", ".data/catch_the_pp", glob.conf.config["server"]["replayspath"], "{}_relax".format(glob.conf.config["server"]["replayspath"]), glob.conf.config["server"]["beatmapspath"], glob.conf.config["server"]["screenshotspath"] ] for i in paths: if not os.path.exists(i): os.makedirs(i, 0o770) consoleHelper.printDone() # Connect to db try: consoleHelper.printNoNl("> Connecting to MySQL database... ") glob.db = dbConnector.db(glob.conf.config["db"]["host"], glob.conf.config["db"]["username"], glob.conf.config["db"]["password"], glob.conf.config["db"]["database"], int(glob.conf.config["db"]["workers"])) consoleHelper.printNoNl(" ") consoleHelper.printDone() except: # Exception while connecting to db consoleHelper.printError() consoleHelper.printColored( "[!] Error while connection to database. Please check your config.ini and run the server again", bcolors.RED) raise # Connect to redis try: consoleHelper.printNoNl("> Connecting to redis... ") glob.redis = redis.Redis(glob.conf.config["redis"]["host"], glob.conf.config["redis"]["port"], glob.conf.config["redis"]["database"], glob.conf.config["redis"]["password"]) glob.redis.ping() consoleHelper.printNoNl(" ") consoleHelper.printDone() except: # Exception while connecting to db consoleHelper.printError() consoleHelper.printColored( "[!] Error while connection to redis. Please check your config.ini and run the server again", bcolors.RED) raise # Empty redis cache #TODO: do we need this? try: glob.redis.eval( "return redis.call('del', unpack(redis.call('keys', ARGV[1])))", 0, "lets:*") except redis.exceptions.ResponseError: # Script returns error if there are no keys starting with peppy:* pass # Save lets version in redis glob.redis.set("lets:version", glob.VERSION) # Create threads pool try: consoleHelper.printNoNl("> Creating threads pool... ") glob.pool = ThreadPool(int(glob.conf.config["server"]["threads"])) consoleHelper.printDone() except: consoleHelper.printError() consoleHelper.printColored( "[!] Error while creating threads pool. Please check your config.ini and run the server again", bcolors.RED) # Load achievements consoleHelper.printNoNl("> Loading achievements... ") try: achievements = glob.db.fetchAll("SELECT * FROM achievements") for achievement in achievements: condition = eval( f"lambda score, mode_vn, stats: {achievement.pop('cond')}") glob.achievements.append( Achievement(_id=achievement['id'], file=achievement['icon'], name=achievement['name'], desc=achievement['description'], cond=condition)) except Exception as e: consoleHelper.printError() consoleHelper.printColored( "[!] Error while loading achievements! ({})".format( traceback.format_exc()), bcolors.RED, ) return 1 consoleHelper.printDone() # Set achievements version glob.redis.set("lets:achievements_version", glob.ACHIEVEMENTS_VERSION) consoleHelper.printColored( "Achievements version is {}".format(glob.ACHIEVEMENTS_VERSION), bcolors.YELLOW) # Print disallowed mods into console (Used to also assign it into variable but has been moved elsewhere) unranked_mods = [ key for key, value in glob.conf.extra["common"] ["rankable-mods"].items() if not value ] consoleHelper.printColored( "Unranked mods: {}".format(", ".join(unranked_mods)), bcolors.YELLOW) # Print allowed beatmap rank statuses allowed_beatmap_rank = [ key for key, value in glob.conf.extra["lets"] ["allowed-beatmap-rankstatus"].items() if value ] consoleHelper.printColored( "Allowed beatmap rank statuses: {}".format( ", ".join(allowed_beatmap_rank)), bcolors.YELLOW) # Make array of bools to respective rank id's glob.conf.extra["_allowed_beatmap_rank"] = [ getattr(rankedStatuses, key) for key in allowed_beatmap_rank ] # Store the allowed beatmap rank id's into glob # Discord if generalUtils.stringToBool(glob.conf.config["discord"]["enable"]): glob.schiavo = schiavo.schiavo( glob.conf.config["discord"]["boturl"], "**lets**") else: consoleHelper.printColored( "[!] Warning! Discord logging is disabled!", bcolors.YELLOW) # Check debug mods glob.debug = generalUtils.stringToBool( glob.conf.config["server"]["debug"]) if glob.debug: consoleHelper.printColored( "[!] Warning! Server running in debug mode!", bcolors.YELLOW) # Server port try: serverPort = int(glob.conf.config["server"]["port"]) except: consoleHelper.printColored( "[!] Invalid server port! Please check your config.ini and run the server again", bcolors.RED) # Make app glob.application = make_app() # Set up sentry try: glob.sentry = generalUtils.stringToBool( glob.conf.config["sentry"]["enable"]) if glob.sentry: glob.application.sentry_client = AsyncSentryClient( glob.conf.config["sentry"]["dsn"], release=glob.VERSION) else: consoleHelper.printColored( "[!] Warning! Sentry logging is disabled!", bcolors.YELLOW) except: consoleHelper.printColored( "[!] Error while starting Sentry client! Please check your config.ini and run the server again", bcolors.RED) # Set up Datadog try: if generalUtils.stringToBool( glob.conf.config["datadog"]["enable"]): glob.dog = datadogClient.datadogClient( glob.conf.config["datadog"]["apikey"], glob.conf.config["datadog"]["appkey"]) else: consoleHelper.printColored( "[!] Warning! Datadog stats tracking is disabled!", bcolors.YELLOW) except: consoleHelper.printColored( "[!] Error while starting Datadog client! Please check your config.ini and run the server again", bcolors.RED) # Connect to pubsub channels pubSub.listener(glob.redis, { "lets:beatmap_updates": beatmapUpdateHandler.handler(), }).start() # Prometheus port statsPort = None try: if glob.conf.config["prometheus"]["port"]: statsPort = int(glob.conf.config["prometheus"]["port"]) except: consoleHelper.printColored( "Invalid stats port! Please check your config.ini and run the server again", bcolors.YELLOW) raise if statsPort: consoleHelper.printColored( "Stats exporter listening on localhost:{}".format(statsPort), bcolors.GREEN) prometheus_client.start_http_server(statsPort, addr="127.0.0.1") # Server start message and console output consoleHelper.printColored( "> L.E.T.S. is listening for clients on {}:{}...".format( glob.conf.config["server"]["host"], serverPort), bcolors.GREEN) # Start Tornado glob.application.listen(serverPort, address=glob.conf.config["server"]["host"]) tornado.ioloop.IOLoop.instance().start() finally: # Perform some clean up print("> Disposing server... ") glob.fileBuffers.flushAll() consoleHelper.printColored("Goodbye!", bcolors.GREEN) return 0
logging.warning('Tornado %s started to listen %s' % (APP_VERSION, APP_PORT)) # init application # logging.debug('App settings:\n%s' % yaml.safe_dump(settings, default_flow_style=False, allow_unicode=True)) tornado.web.Application.__init__(self, handlers, **settings) if __name__ == '__main__': tornado.options.parse_command_line() tornado.locale.load_translations( path.join(path.dirname(__file__), 'main', 'translation')) application = myApplication() application.sentry_client = AsyncSentryClient(dsn=APP_SENTRY, release=APP_VERSION) server = tornado.httpserver.HTTPServer(application, xheaders=True, max_body_size=1024 * 1024 * 1024 * 5) if APP_DEBUG: server.listen(APP_PORT) else: server.bind(APP_PORT) server.start(0) tornado.ioloop.IOLoop.current().start()
def __init__(self): settings = dict(debug=options.debug, autoreload=True) tornado.web.Application.__init__(self, handlers, **settings) self.db = session self.sentry_client = AsyncSentryClient(app_config['sentry'])
def load_app(): global app app = make_app() if settings.SENTRY_CLIENT: app.sentry_client = AsyncSentryClient(settings.SENTRY_CLIENT) app.listen(settings.PORT)
def get_tornado_application(): application = tornado.web.Application(handlers) application.sentry_client = AsyncSentryClient( SENTRY_DSN, ignored_exception_types=[tornado.web.HTTPError]) return application
def sentry(stamp, dsn): from raven.contrib.tornado import AsyncSentryClient message = 'lifeordeath alert: %s' % stamp.key sentry = AsyncSentryClient(dsn) sentry.captureMessage(message=message)
@classmethod def get_version(cls, settings, path): # temporarily muted return None urls = [ (r"/", FlipboardHandler), (r"/flipboard/getDashboardsPaths", GetDashboardsPaths), (r"/communication/websocket", DashboardSocketHandler), (r"/([a-zA-Z0-9_-]*)", DashboardRendererHandler), (r"/api/{}/{}/tileconfig/([a-zA-Z0-9_-]+)".format( api_version, settings.API_KEY), MetaProperty), (r"/api/{}/{}/tiledata/([a-zA-Z0-9_-]+)".format( api_version, settings.API_KEY), TileData), (r"/api/{}/{}/info".format(api_version, settings.API_KEY), ProjectInfo), (r"/api/{}/{}/push".format(api_version, settings.API_KEY), Push), ] flipboard = Flipboard() app = tornado.web.Application( urls, template_path=os.path.join(settings.TIPBOARD_PATH, 'templates'), static_path=os.path.join(settings.TIPBOARD_PATH, "static"), static_handler_class=MultiStaticFileHandler, debug=settings.DEBUG, tiles_paths=settings.TILES_PATHS, sentry_client=AsyncSentryClient(settings.SENTRY_DSN), )
def main(): parser = argparse.ArgumentParser( description=consoleHelper.ASCII + "\n\nLatest Essential Tatoe Server v{}\nBy The Ripple Team".format( glob.VERSION), formatter_class=argparse.RawTextHelpFormatter) parser.add_argument("-p", "--port", help="Run on a specific port (bypasses config.ini)", required=False) parser.add_argument( "-s", "--stats-port", help="Run prometheus on a specific port (bypasses config.ini)", required=False) parser.add_argument("-q", "--quiet", help="Log less stuff during startup", required=False, default=False, action="store_true") cli_args = parser.parse_args() # AGPL license agreement try: agpl.check_license("ripple", "LETS") except agpl.LicenseError as e: logging.error(str(e)) sys.exit(1) try: if not cli_args.quiet: consoleHelper.printServerStartHeader(True) def loudLog(s, f=logging.info): if not cli_args.quiet: f(s) # Read config loudLog("Reading config file... ") glob.conf = Config() # Create data/oppai maps folder if needed loudLog("Checking folders... ") paths = (".data", glob.conf["BEATMAPS_FOLDER"], glob.conf["SCREENSHOTS_FOLDER"], glob.conf["FAILED_REPLAYS_FOLDER"], glob.conf["REPLAYS_FOLDER"]) for i in paths: if not os.path.exists(i): os.makedirs(i, 0o770) # Connect to db try: loudLog("Connecting to MySQL database") glob.db = dbConnector.db(host=glob.conf["DB_HOST"], port=glob.conf["DB_PORT"], user=glob.conf["DB_USERNAME"], password=glob.conf["DB_PASSWORD"], database=glob.conf["DB_NAME"], autocommit=True, charset="utf8") glob.db.fetch("SELECT 1") except: # Exception while connecting to db logging.error( "Error while connection to database. Please check your config.ini and run the server again" ) raise # Connect to redis try: loudLog("Connecting to redis") glob.redis = redis.Redis(glob.conf["REDIS_HOST"], glob.conf["REDIS_PORT"], glob.conf["REDIS_DATABASE"], glob.conf["REDIS_PASSWORD"]) glob.redis.ping() except: # Exception while connecting to db logging.error( "Error while connection to redis. Please check your config.ini and run the server again" ) raise # Empty redis cache try: glob.redis.eval( "return redis.call('del', unpack(redis.call('keys', ARGV[1])))", 0, "lets:*") except redis.exceptions.ResponseError: # Script returns error if there are no keys starting with peppy:* pass # Save lets version in redis glob.redis.set("lets:version", glob.VERSION) # Create threads pool try: loudLog("Creating threads pool") glob.pool = ThreadPool(glob.conf["THREADS"]) except: logging.error( "Error while creating threads pool. Please check your config.ini and run the server again" ) raise # Check osuapi if not glob.conf["OSU_API_ENABLE"]: logging.warning( "osu!api features are disabled. If you don't have a " "valid beatmaps table, all beatmaps will show as unranked") if glob.conf["BEATMAP_CACHE_EXPIRE"] > 0: logging.warning( "IMPORTANT! Your beatmapcacheexpire in config.ini is > 0 and osu!api " "features are disabled.\nWe do not recommend this, because too old " "beatmaps will be shown as unranked.\nSet beatmapcacheexpire to 0 to " "disable beatmap latest update check and fix that issue.") # Load achievements #loudLog("Loading achievements") #try: # secret.achievements.utils.load_achievements() #except: # logging.error("Error while loading achievements") # raise glob.ACHIEVEMENTS_VERSION = "0.0.0" # Set achievements version glob.redis.set("lets:achievements_version", glob.ACHIEVEMENTS_VERSION) loudLog("Achievements version is {}".format(glob.ACHIEVEMENTS_VERSION)) # Check if s3 is enabled if not glob.conf.s3_enabled: loudLog("S3 is disabled!", logging.warning) else: c = glob.db.fetch( "SELECT COUNT(*) AS c FROM s3_replay_buckets WHERE max_score_id IS NULL" )["c"] if c != 1: logging.error( "There must be only one bucket flagged as WRITE bucket! You have {}." .format(c), ) sys.exit() # Discord if glob.conf.schiavo_enabled: glob.schiavo = schiavo.schiavo(glob.conf["SCHIAVO_URL"], "**lets**") else: logging.warning("Schiavo logging is disabled!") # Server port try: if cli_args.port: loudLog( "Running on port {}, bypassing config.ini".format( cli_args.port), logging.warning) glob.serverPort = int(cli_args.port) else: glob.serverPort = glob.conf["HTTP_PORT"] except: logging.error( "Invalid server port! Please check your config.ini and run the server again" ) raise # Prometheus port try: if cli_args.stats_port: loudLog( "Running stats exporter on port {}, bypassing config.ini". format(cli_args.stats_port), logging.warning) glob.statsPort = int(cli_args.stats_port) elif glob.conf["PROMETHEUS_PORT"]: glob.statsPort = int(glob.conf["PROMETHEUS_PORT"]) except: logging.error( "Invalid stats port! Please check your config.ini and run the server again" ) raise # Make app glob.application = make_app() # Set up sentry if glob.conf.sentry_enabled: glob.application.sentry_client = AsyncSentryClient( glob.conf["SENTRY_DSN"], release=glob.VERSION) else: loudLog("Sentry logging is disabled!", logging.warning) # Set up Datadog if glob.conf.datadog_enabled: glob.dog = datadogClient.datadogClient( glob.conf["DATADOG_API_KEY"], glob.conf["DATADOG_APP_KEY"], constant_tags=["worker:{}".format(glob.serverPort)]) else: glob.dog = datadogClient.datadogClient() loudLog("Datadog stats tracking is disabled!", logging.warning) # Connect to pubsub channels t = pubSub.listener( glob.redis, { "lets:beatmap_updates": beatmapUpdateHandler.handler(), "lets:reload_aql": lambda x: x == b"reload" and glob.aqlThresholds.reload(), }) t.setDaemon(True) t.start() # Check debug mods if glob.conf["DEBUG"]: logging.warning("Server running in debug mode.") # Close main thread db connection as we don't need it anymore glob.threadScope.dbClose() # Server start message and console output logging.info("L.E.T.S. is listening for clients on {}:{}...".format( glob.conf["HTTP_HOST"], glob.serverPort)) # log.discord("bunker", "Server started!") # Start Tornado def term(_, __): tornado.ioloop.IOLoop.instance().add_callback_from_signal( lambda: tornado.ioloop.IOLoop.instance().stop()) signal.signal(signal.SIGINT, term) signal.signal(signal.SIGTERM, term) if glob.statsPort is not None: logging.info("Stats exporter listening on 0.0.0.0:{}".format( glob.statsPort)) prometheus_client.start_http_server(glob.statsPort, addr="0.0.0.0") glob.application.listen(glob.serverPort, address=glob.conf["HTTP_HOST"]) tornado.ioloop.IOLoop.instance().start() logging.debug("IOLoop stopped") finally: # Perform some clean up logging.info("Disposing server") glob.fileBuffers.flushAll() if glob.redis.connection_pool is not None: glob.redis.connection_pool.disconnect() # TODO: properly dispose mysql connections if glob.pool is not None: # Close db conn in each thread glob.pool.imap(lambda *_: glob.threadScope.dbClose(), [None] * glob.conf["THREADS"], chunksize=1) # Wait for everything else to finish (should always terminate immediately) glob.pool.close() glob.pool.join() logging.info("Goodbye!")
try: serverPort = int(glob.conf.config["server"]["port"]) except: consoleHelper.printColored( "[!] Invalid server port! Please check your config.ini and run the server again", bcolors.RED) # Make app glob.application = make_app() # Set up sentry try: glob.sentry = generalUtils.stringToBool( glob.conf.config["sentry"]["enable"]) if glob.sentry: glob.application.sentry_client = AsyncSentryClient( glob.conf.config["sentry"]["dsn"], release=glob.VERSION) else: consoleHelper.printColored( "[!] Warning! Sentry logging is disabled!", bcolors.YELLOW) except: consoleHelper.printColored( "[!] Error while starting Sentry client! Please check your config.ini and run the server again", bcolors.RED) # Set up Datadog try: if generalUtils.stringToBool( glob.conf.config["datadog"]["enable"]): glob.dog = datadogClient.datadogClient( glob.conf.config["datadog"]["apikey"], glob.conf.config["datadog"]["appkey"])
def __init__(self): tornado.web.Application.__init__(self, url_patterns, **settings.application_settings) self.sentry_client = AsyncSentryClient(settings.DSN)