def __init__(self): self.notify = Notify('Sterner.log') #database api self.db_api = DBApi() #start network server self.network = SternerNetwork(self, self.notify, self.db_api) self.network.startServer() #dict to save logged in players # K: player_id , V: panda connection self.logged_in_players = {} self.notify.info("Sterner started.") #so we dont have different versions of games all at once self.db_api.finishAllGamesExceptVersion(COMMUNICATION_PROTOCOL_VERSION) #dequeue for sending msgs to network... format:(player_id, (msg)) self.to_network = collections.deque() #dequeue for sending messages for engines and EngineHandlerThread, if msg[0] == STERNER_ID, than it is for handler self.msgs4engines = collections.deque() #dequeue in which EngineHandlerThread puts messages for Sterner self.fromHandler = collections.deque() self.engine_handler = EngineHandlerThread(self.fromHandler, self.msgs4engines, self.to_network, self.notify, self.db_api) self.engine_handler.start()
def __init__(self, db, notification_io, notification_config): """ Constructs the taks API. Args: db (DB): Client class to communicate with DB. notification_io (AbstractNotificationIO): A service to notify persons. notification_config (dict): The configuration for mail messages. """ DBApi.__init__(self, db=db, table_name=u"task") self._notification_io = notification_io self._notification_config = notification_config self._task_status_change_notification = db.task_status_change_notification
def create(self, document, lookup=None, auto_lookup=None): """ Delete item(s). Args: filters (dict): Filter to know what to delete. update (dict): Fields to update. lookup (list of dict): Lookup option (joins). auto_lookup (int): Let the database construct the lookups (value is the deep). Returns: (dict): The result of the deletion (with number of items deleted). """ result = DBApi.create(self, document, lookup, auto_lookup) if self._notification_config.get(u"ACTIVE", False): user_email = document['user']['email'] task_id = document[u"task"][u"id"] task = list( self._task_notification.find( {u"TASK_ID": document[u"task"][u"id"]}))[0] task[u"TASK_LINK"] = u"{}/{}".format( self._notification_config[u"APP_URL"], task[u"TASK_LINK"]) self._notification_io.notify( recipient=user_email, subject=( self._notification_config[u"USER_AFFECTED"][u"SUBJECT"] % task), message=( self._notification_config[u"USER_AFFECTED"][u"MESSAGE"] % task)) return result
def update_id(self, document_id, update, lookup=None, auto_lookup=None): """ Delete item(s). Args: id (int): The ID of the document to update. update (dict): Fields to update. lookup (list of dict): Lookup option (joins). auto_lookup (int): Let the database construct the lookups (value is the deep). Returns: (dict): The result of the deletion (with number of items deleted). """ old_task = self.get(document_id, lookup, auto_lookup) new_task = DBApi.update_id(self, document_id, update, lookup, auto_lookup) if self._notification_config.get( u"ACTIVE", False) and old_task[u"completed"] != new_task[u"completed"]: notifications = list( self._task_status_change_notification.find( query={u"TASK_ID": document_id})) common_task_notification = notifications[0] recipients = [ item[u"USER_EMAIL"] for item in notifications if item[u"USER_EMAIL"] is not None ] if common_task_notification[u"AUTHOR_EMAIL"] not in recipients: recipients.append(common_task_notification[u"AUTHOR_EMAIL"]) common_task_notification[u"TASK_LINK"] = u"{}/{}".format( self._notification_config[u"APP_URL"], common_task_notification[u"TASK_LINK"]) OPERATION = u"TASK_REOPENED" if not new_task[ u"completed"] else u"TASK_CLOSED" self._notification_io.notify( recipient=recipients, subject=(self._notification_config[OPERATION][u"SUBJECT"] % common_task_notification), message=(self._notification_config[OPERATION][u"MESSAGE"] % common_task_notification))
def create(self, document, lookup=None, auto_lookup=None): """ Delete item(s). Args: filters (dict): Filter to know what to delete. update (dict): Fields to update. lookup (list of dict): Lookup option (joins). auto_lookup (int): Let the database construct the lookups (value is the deep). Returns: (dict): The result of the deletion (with number of items deleted). """ result = DBApi.create(self, document, lookup, auto_lookup) if self._notification_config.get(u"ACTIVE", False): notifications = list( self._comment_notification.find( query={u"TASK_ID": document[u"task"].get(u"id")})) if len(notifications) > 0: common_notification = notifications[0] common_notification[u"TASK_LINK"] = u"{}/{}".format( self._notification_config[u"APP_URL"], common_notification[u"TASK_LINK"]) common_notification[u"AUTHOR_MAIL"] = document[u"author"][ u'email'] common_notification[u"AUTHOR_NAME"] = document[u"author"][ u'name'] recipient_emails = [ notif[u"USER_EMAIL"] for notif in notifications ] + [common_notification[u"TASK_AUTHOR_EMAIL"]] # If comment writer is in recipients, remove it. recipient_emails = [ email for email in recipient_emails if email != common_notification[u"AUTHOR_MAIL"] ] self._notification_io.notify( recipient=list(set(recipient_emails)), subject=self._notification_config[u"COMMENT_ADDED"] [u"SUBJECT"] % common_notification, message=self._notification_config[u"COMMENT_ADDED"] [u"MESSAGE"] % common_notification) return result
from dbapi import DBApi from dbapi import Song import os dbapi = DBApi() img_path = "/home/garrison/Cloud/work/chords/public/img/chords/guitar" img_chords = list(map(lambda x: x.replace(".gif", ""), os.listdir(img_path))) badchords = set() songs = dbapi.session.query(Song).all() for song in songs: chords = song.guitar_chords.split(";") for ch in chords: if ch not in img_chords: badchords.add(ch) print(sorted(badchords)) print(len(badchords)) """ rename IMGS: rename 's/_0//' * rename 's/w/#/' * SQL QUERIES: update songs set guitar_chords = REPLACE(guitar_chords, "/", "|") update songs
}}) # Init & register User API # Create user api object USER_API = user_api.create_user_api( db_url=USER_API_CONFIG.get(u"db_url"), jwt_secret=USER_API_CONFIG.get(u"jwt_secret"), jwt_lifetime=USER_API_CONFIG.get(u"jwt_lifetime"), user_created_callback=on_user_created, user_updated_callback=on_user_updated) FLASK_USER_API = USER_API.get_flask_user_api() DB_API_CONFIG = { u"projects": DBApi(DB, u"project"), u"clients": DBApi(DB, u"client"), u"hours": DBApi(DB, u"hour"), u"project_assignements": DBApi(DB, u"project_assignement"), u"_users": DBApi(DB, u"_user"), u"task-lists": DBApi(DB, u"task_list"), u"tasks": TaskDBApi(DB, MAIL_IO, NOTIFICATION_CONFIG), u"comments": CommentDBApi(DB, MAIL_IO, NOTIFICATION_CONFIG), u"tags": DBApi(DB, u"tag"), u"task-tags": DBApi(DB, u"task_has_tag"), u"clients_affected_to_users": DBApi(DB, u"clients_affected_to_users"), u"project_consumption": DBApi(DB, u"project_consumption"), u"project_consumption_per_user": DBApi(DB, u"project_consumption_per_user"), u"project-loads": DBApi(DB, u"project_load"), u"cras": DBApi(DB, u"cra"),
def main(): # pylint:disable=missing-docstring,too-many-locals log = logging.getLogger('gamebot_main') log.setLevel(MAIN_LOG_LEVEL) log_formatter = coloredlogs.ColoredFormatter(LOG_FMT) log_handler = logging.StreamHandler() log_handler.setFormatter(log_formatter) log.addHandler(log_handler) log.addHandler( logstash.TCPLogstashHandler(LOGSTASH_IP, LOGSTASH_PORT, version=1)) log.info("Starting GameBot") db_api = DBApi() # Check DB connection. while True: if db_api.check_connection(): log.info("Connection to DB Verified.") break else: log.fatal("Looks like DB is Down. Unable to verify db connection.") time.sleep(5) scripts_interface = ScriptsFacade(db_api) log.info("Initialization Complete") log.info("Check to see if there's a game running") while True: current_game_id = db_api.get_game_state() if current_game_id is None: log.info("Game is paused or hasn't started yet, retrying...") time.sleep(10) continue current_tick, seconds_left = db_api.get_current_tick_info() if current_tick != 0: log.info("We must be picking up from the last run. " "Sleep for {} seconds until the next tick.".format( seconds_left)) time.sleep(seconds_left) log.warning("Starting Main Loop") tick_id = current_tick while True: log.info("Starting Iteration") current_game_id = db_api.get_game_state() if current_game_id is None: log.info("Game is paused, breaking out of main loop") break # Create a new tick and decide what scripts to run against each team sleep_time, num_benign, num_exploit, num_get_flags = _get_ticks_configuration( db_api) # Update script to be run, we should update these first as scriptbot # waits for tick to pick up the scripts. # First, update scripts and then update tick so that # when the tick is updated, # scriptbot can get all the scripts in a single shot. if scripts_interface.update_scripts_to_run(tick_id + 1, num_benign, num_exploit, num_get_flags): log.info("Successfully updated scripts to run for:" + str(tick_id + 1)) else: log.error("Failed to update scripts to run for:" + str(tick_id + 1)) # Change the tick current = datetime.now() time_to_change = current + timedelta(seconds=sleep_time) tick_id = db_api.update_tick_info(time_to_change.isoformat(), current.isoformat()) log.info("Current Tick {}".format(tick_id)) log.info("Tick Configuration, Sleep Time:" + str(sleep_time) + ", num_benign:" + str(num_benign) + ", num_exploit:" + str(num_exploit) + ", num_get_flags:" + str(num_get_flags)) # compute scores for the previous tick (the last completed tick) if tick_id > 1: # update the state of services for previous tick old_time = datetime.now() log.info("Updating state of services across all teams.") scripts_interface.update_state_of_services(tick_id - 1) log.info("Updated state of services across all teams in:" + str(datetime.now() - old_time)) else: log.info("Ignoring Scoring, as this is first tick.") # Sleep for the amount of time until the next tick time_diff_to_sleep = time_to_change - datetime.now() if time_diff_to_sleep.total_seconds() < 0: log.warning( "Not sleeping at all. I was {} seconds too slow".format( time_diff_to_sleep)) else: seconds_to_sleep = (time_diff_to_sleep.seconds + (time_diff_to_sleep.microseconds / 1E6)) log.info("Sleeping for:" + str(seconds_to_sleep)) time.sleep(seconds_to_sleep) log.info("Awake")
import pandas import warnings import re from dbapi import DBApi BASE = os.getcwd() # OLD_LINKS = "/home/garrison/Cloud/work/chords/util/export-post-2019-01-12_19-48-44.csv" OLD_ARTIST = os.path.join(BASE, "util/check-chords-art+song.csv") OLD_CONTENT = os.path.join(BASE, "util/URL-content.csv") IN_DIR = os.path.join(BASE, "util/data_to_load") OUT_DIR = os.path.join(BASE, "util/data_in_db") # db = DBApi() db = DBApi() def read_old(): r = re.compile("<iframe.*>.*</iframe?>") r_div = re.compile("<div.*?>") df_content = pandas.read_csv(OLD_CONTENT) df_artist = pandas.read_csv(OLD_ARTIST) songs = {} for index, row in df_artist[df_artist["Песня"].notnull()].iterrows(): url = row["Old URL"] songs[url] = {"song_name": row["Песня"], "artist_name": row["Группа"]} if not pandas.isnull(row["Title"]): songs[url]["seo_title"] = row["Title"] if not pandas.isnull(row["Description"]): songs[url]["seo_description"] = row["Description"]
from dbapi import DBApi oracledb = DBApi("<USER>", "<PASS>") oracledb.disconnect()
class Sterner: def __init__(self): self.notify = Notify('Sterner.log') #database api self.db_api = DBApi() #start network server self.network = SternerNetwork(self, self.notify, self.db_api) self.network.startServer() #dict to save logged in players # K: player_id , V: panda connection self.logged_in_players = {} self.notify.info("Sterner started.") #so we dont have different versions of games all at once self.db_api.finishAllGamesExceptVersion(COMMUNICATION_PROTOCOL_VERSION) #dequeue for sending msgs to network... format:(player_id, (msg)) self.to_network = collections.deque() #dequeue for sending messages for engines and EngineHandlerThread, if msg[0] == STERNER_ID, than it is for handler self.msgs4engines = collections.deque() #dequeue in which EngineHandlerThread puts messages for Sterner self.fromHandler = collections.deque() self.engine_handler = EngineHandlerThread(self.fromHandler, self.msgs4engines, self.to_network, self.notify, self.db_api) self.engine_handler.start() def start(self): #for time limit - debug option if we want to stop sterner automatically after some time t = time.time() #-----------================------main loop---------=====================--------- #-----------================------main loop---------=====================--------- #-----------================------main loop---------=====================--------- while True: #get msg from network tmp_msg = self.network.readMsg() if tmp_msg: #print "sterner dobio:",tmp_msg try: msg, source = tmp_msg #check if this message is for sterner or not if msg[0] == STERNER_ID: self.handleSternerMsg(msg[1:], source) else: self.msgs4engines.append(msg) except: self.notify.error("Error with message:%s\ninfo:%s", str(tmp_msg), traceback.format_exc()) #check to_network for messages, and if there are any send them to players try: while True: player_id, game_id, msg = self.to_network.popleft() conn, in_game_id = self.logged_in_players[player_id] if conn and game_id == in_game_id: self.network.sendMsg(msg, conn) #IndexError if there is nothing to pop #KeyError if engine is sending messages to disconnected/unknown players, we just ignore this except (IndexError, KeyError): pass #check for messages from Handler try: while True: msg = self.fromHandler.popleft() self.handleHandlerMessage(msg) except IndexError: pass #behave nicely with cpu time.sleep(0.1) #if we set the option for sterner auto shutdown, check the time period if STERNER_TIME_LIMIT and time.time() - t > STERNER_TIME_LIMIT: break #---------================--------main loop--------==================---------- #---------================--------main loop--------==================---------- #---------================--------main loop--------==================---------- #shutdown everything we can self.engine_handler.stop = True self.network.stopServer() time.sleep(3) def handleHandlerMessage(self, msg): if msg[0] == NEW_GAME_STARTED: player_id = msg[1] game_id = msg[2] #try to find logged in player, if we cannot, just return source = self.getConnectionFromId(player_id) if not source: print "NIST PRIST" return #we don't know if it was a public game or private game so refresh both lists self.network.sendMsg( (MY_WAITING_GAMES, self.db_api.getMyWaitingGames(player_id)), source) self.network.sendMsg( (EMPTY_PUBLIC_GAMES, self.db_api.getAllEmptyPublicGames()), source) #K-player_id - V:(connection, game_id) def getConnectionFromId(self, player_id): try: return self.logged_in_players[player_id][0] except: return None def getIdFromConnection(self, connection): for player_id in self.logged_in_players.keys(): if self.logged_in_players[player_id][0] == connection: return player_id return None def handleSternerMsg(self, message, connection): if message[0] == START_NEW_GAME: level = message[1] budget = message[2] player_ids = message[3] public_game = message[4] game_name = message[5] player_id = self.getIdFromConnection(connection) #DEBUG: this is for setting up local test game if public_game == -1: self.msgs4engines.append( (STERNER_ID, START_NEW_GAME, -1, player_id)) return #check if there are at least 2 players if len(player_ids) < 2: self.network.sendMsg((ERROR, "Not enough players"), connection) return #check if level is ok all_levels = self.db_api.getAllLevels() if level not in all_levels: self.network.sendMsg((ERROR, "Wrong level"), connection) return #TODO: krav: check if budget is ok #if this is a private game check if player_ids are ok if not public_game: all_player_ids = [ int(x) for x, y in self.db_api.getAllPlayers() ] for p_id in player_ids: if p_id not in all_player_ids: self.network.sendMsg( (ERROR, "Wrong player id:%d" % p_id), connection) return #if public game, game creator's id must be one of the players, all others must be 0 else: if player_id not in player_ids: self.network.sendMsg((ERROR, "You have to be in the game"), connection) return tmp_player_ids = player_ids[:] tmp_player_ids.remove(player_id) for p in tmp_player_ids: if p != 0: self.network.sendMsg(( ERROR, "You cannot assign players other than yourself in public games" ), connection) return #check game name if not game_name: if not public_game: game_name = 'Private game on ' + level else: game_name = 'Public game on ' + level #create the game and all players in the database, set game creator accept status to 1 game_id = self.db_api.createGame(level, budget, player_id, datetime.datetime.now(), COMMUNICATION_PROTOCOL_VERSION, public_game, game_name) for i in xrange(0, len(player_ids)): if player_ids[i] == player_id: self.db_api.addPlayerToGame(game_id, player_ids[i], i, i, 1) else: self.db_api.addPlayerToGame(game_id, player_ids[i], i, i, 0) self.msgs4engines.append( (STERNER_ID, START_NEW_GAME, game_id, player_id)) return elif message[0] == ALL_FINISHED_GAMES: self.network.sendMsg( (ALL_FINISHED_GAMES, self.db_api.getAllFinishedGames()), connection) return elif message[0] == ENTER_GAME: game_id = message[1] player_id = self.getIdFromConnection(connection) self.logged_in_players[player_id] = (connection, game_id) self.msgs4engines.append((game_id, player_id, ENTER_GAME, game_id)) return elif message[0] == REFRESH_MY_GAME_LISTS: self.sendSternerData(connection) return elif message[0] == DECLINE_GAME: game_id = message[1] player_id = self.getIdFromConnection(connection) game = self.db_api.getGame(game_id, filter=True) #if there is no such game if not game: self.network.sendMsg((ERROR, "No such game."), connection) return #if this is a public game, you cant decline that if game[9]: self.network.sendMsg( (ERROR, "You cannot decline public games, just don't join :)"), connection) return #if this game already started if game[5] != 0: self.network.sendMsg(( ERROR, "This game already started, if you want to concede do it from inside the game" ), connection) return #if you are not a player in this game game_player = self.db_api.getGamePlayer(game_id, player_id) if not game_player: self.network.sendMsg(( ERROR, "You cannot decline, you are not even part of this game!"), connection) return #ok so delete the game self.db_api.deleteGame(game_id) #refresh his unaccepted games list self.network.sendMsg((MY_UNACCEPTED_GAMES, self.db_api.getMyUnacceptedGames(player_id)), connection) elif message[0] == ACCEPT_GAME: game_id = message[1] player_id = self.getIdFromConnection(connection) game = self.db_api.getGame(game_id) #if there is no such game if not game: self.network.sendMsg((ERROR, "No such game."), connection) return #check if this game already started or is finished if game[5] == 1: self.network.sendMsg((ERROR, "Game already started"), connection) return elif game[5] == 2: self.network.sendMsg((ERROR, "Game finished"), connection) return #if this is a public game if game[9]: #if we are already in this game, return error game_player = self.db_api.getGamePlayer(game_id, player_id) if game_player: self.network.sendMsg( (ERROR, "You are already in this game"), connection) return #find first empty slot, set this players id in its stead game_player = self.db_api.getGamePlayer(game_id, 0) game_player[2] = player_id #we update game_player later #if this is a private game else: #check if this player really did not accept this game yet game_player = self.db_api.getGamePlayer(game_id, player_id) if game_player[5] == 1: self.network.sendMsg((ERROR, "Already accepted this game"), connection) return #update this player's acceptance, for both cases (public/private game) game_player[5] = 1 self.db_api.updateGamePlayer(game_player) #we accepted this game self.network.sendMsg((ACCEPT_GAME, game_id), connection) #refresh unaccepted games list self.network.sendMsg((MY_UNACCEPTED_GAMES, self.db_api.getMyUnacceptedGames(player_id)), connection) #try to see if this is the last player accepting and if so start the game #if at least 1 player did not accept, return for player in self.db_api.getGameAllPlayers(game_id): if player[5] == 0: #refresh waiting games list self.network.sendMsg( (MY_WAITING_GAMES, self.db_api.getMyWaitingGames(player_id)), connection) return #ok all players accepted, start this game game[5] = 1 self.db_api.updateGame(game) #refresh active games self.network.sendMsg( (MY_ACTIVE_GAMES, self.db_api.getMyActiveGames(player_id)), connection) return elif message[1] == PING: print "ping:", message self.network.sendMsg((PONG, message[2]), connection) return else: self.notify.error("Undefined message:%s", str(message)) pass def sendSternerData(self, source): player_id = self.getIdFromConnection(source) self.network.sendMsg((ALL_PLAYERS, self.db_api.getAllPlayers()), source) self.network.sendMsg((ALL_LEVELS, self.db_api.getAllLevels()), source) #DEBUG: add local test game active_games = self.db_api.getMyActiveGames(player_id) active_games.insert(0, (-1, "assassins2", 1000, 1, 22, 0, 0, 0, '0.1', 0, "--------local test game-------", 0, 0)) self.network.sendMsg((MY_ACTIVE_GAMES, active_games, source)) self.network.sendMsg( (MY_UNACCEPTED_GAMES, self.db_api.getMyUnacceptedGames(player_id)), source) self.network.sendMsg( (MY_WAITING_GAMES, self.db_api.getMyWaitingGames(player_id)), source) self.network.sendMsg( (EMPTY_PUBLIC_GAMES, self.db_api.getAllEmptyPublicGames()), source) self.network.sendMsg((NEWS_FEED, self.db_api.getLast3News()), source) def playerConnected(self, player_id, source): #if this player already has a connection, disconnect him if player_id in self.logged_in_players: conn = self.getConnectionFromId(player_id) if conn: self.network.disconnect(conn) #remember this player-connection self.logged_in_players[player_id] = (source, 0) #send this new player everything he needs self.sendSternerData(source) def playerDisconnected(self, source): #go through all logged in players for pid in self.logged_in_players.keys(): #if we find the one with this connection if self.logged_in_players[pid] == source: #remove him from the dict del self.logged_in_players[pid] return