async def test_start_end_channel_incr(interface): await guild.system_channel.send(me_command) prev_stats = await utilities.get_user_stats(redis_client, bot_id, timepoint=timepoint) voice_channel = [channel for channel in guild.voice_channels if "screen/cam" in channel.name][1] voice_client = await voice_channel.connect() start_channel_time = utilities.get_time() utilities.sleep(time_to_stay) await voice_client.disconnect() end_channel_time = utilities.get_time() await guild.system_channel.send(me_command) utilities.sleep(discord_delay) cur_stats = await utilities.get_user_stats(redis_client, bot_id, timepoint=timepoint) # TODO test - use fields to check description? # reply = await guild.system_channel.history(limit=1).flatten()[0].embeds[0].description assert (utilities.check_stats_diff(prev_stats, cur_stats, time_to_stay, 1, redis_tolerance)) # Check SQL records = sqlalchemy_session.query(Action) \ .filter(Action.user_id == bot_id) \ .filter(Action.category.in_(["end channel", "start channel"])) \ .order_by(Action.creation_time.desc()).limit(2).all() records.reverse() assert (records[0].category == "start channel") assert (records[0].detail == records[1].detail == voice_channel.id) assert (records[0].creation_time - start_channel_time <= db_tolerance) assert (records[1].creation_time - end_channel_time <= db_tolerance)
def __init__(self, bot): self.bot = bot self.guild = None self.role_name_to_obj = None self.role_name_to_info = None self.supporter_role = None self.command_channels = utilities.config[ ("test_" if os.getenv("mode") == "test" else "") + "command_channels"] self.announcement_channel = utilities.config[ ("test_" if os.getenv("mode") == "test" else "") + "announcement_channel"] # TODO fix when files not existent self.data_change_logger = utilities.get_logger( "study_executor_data_change", "data_change.log") self.time_counter_logger = utilities.get_logger( "study_executor_time_counter", "discord.log") self.heartbeat_logger = utilities.get_logger( "study_executor_heartbeat", "heartbeat.log") self.redis_client = utilities.get_redis_client() engine = utilities.get_engine() Session = sessionmaker(bind=engine) self.sqlalchemy_session = Session() self.timezone_session = utilities.get_timezone_session() self.make_heartbeat.start() self.birthtime = utilities.get_time()
def sync_db(self, user_id, channel, category_type, category_offset): cur_time = utilities.get_time() categories = [i + " " + category_type for i in ["end", "start"]] cur_category = categories[category_offset] last_record = self.get_last_record(user_id, categories) # Heuristic data recovery if users have voice_state_update when the bot is down # See all possible scenarios in test_bot.py if last_record: # For case: # last: start id_1 # cur: end id_2 if last_record.detail != channel.id and categories.index( last_record.category): # Add end for last last_category_offset = categories.index(last_record.category) cur_time += timedelta(microseconds=1) record = Action(user_id=user_id, category=categories[1 - last_category_offset], detail=last_record.detail, creation_time=cur_time) self.sqlalchemy_session.add(record) if category_offset == 0: # Add start for cur # A bit inelegant when a user with video on switches to another channel cur_time += timedelta(microseconds=1) record = Action(user_id=user_id, category=categories[last_category_offset], detail=channel.id, creation_time=cur_time) self.sqlalchemy_session.add(record) # For case: # start(end) id_1 # start(end) id_1 # end id_1 # end id_2 elif last_record.category == cur_category: cur_time += timedelta(microseconds=1) record = Action(user_id=user_id, category=categories[1 - category_offset], detail=last_record.detail, creation_time=cur_time) self.sqlalchemy_session.add(record) cur_time += timedelta(microseconds=1) # Users might jump to non-monitored channels if check_categories(channel): record = Action(user_id=user_id, category=cur_category, detail=channel.id, creation_time=cur_time) self.sqlalchemy_session.add(record) utilities.commit_or_rollback(self.sqlalchemy_session) return last_record.creation_time if last_record else cur_time
def handle_in_session(self, user_id, reset): """ When a user issues commands, we want to show up-to-date info even if there is no "voice_state_update" """ # after data recovery we should have a sensible start channel record last_record = self.get_last_record(user_id, ["start channel"]) cur_time = utilities.get_time() last_record_time = last_record.creation_time if last_record else cur_time rank_categories = utilities.get_rank_categories(string=False) rank_categories_val = list(rank_categories.values()) string_rank_categories = list( utilities.get_rank_categories(string=True).values()) in_session_names = [ "in_session_" + str(in_session) for in_session in string_rank_categories[0] ] category_key_names = string_rank_categories[ 0] + string_rank_categories[1:] in_session_incrs = [] for in_session, in_session_name in zip(rank_categories_val[0], in_session_names): in_session_time = self.redis_client.hget(in_session_name, user_id) in_session_time = float(in_session_time) if in_session_time else 0 base_time = max(last_record_time, in_session) incr = utilities.timedelta_to_hours(cur_time - base_time) - in_session_time # Max necessary since an enter channel (or other voice status change) update/sync might be called earlier than the exit one incr = max(incr, 0) in_session_incrs.append(incr) new_val = 0 if reset else incr + in_session_time self.redis_client.hset(in_session_name, user_id, new_val) # standard incr is what gets used for monthly and weekly. In other words, official incr is one of the sets of stats in_session_std_time_name = f"in_session_std" in_session_std_time = self.redis_client.hget(in_session_std_time_name, user_id) in_session_std_time = float( in_session_std_time) if in_session_std_time else 0 std_incr = utilities.timedelta_to_hours( cur_time - last_record_time) - in_session_std_time neg_msg = f"std_incr Negative: {std_incr}\n" if std_incr < 0 else "" std_incr = max(std_incr, 0) in_session_std_time = 0 if reset else std_incr + in_session_std_time self.redis_client.hset(in_session_std_time_name, user_id, in_session_std_time) monthly_now, all_time_now = utilities.increment_studytime( category_key_names, self.redis_client, user_id, in_session_incrs=in_session_incrs, std_incr=std_incr) log_msg = f'{utilities.get_time()}\n{neg_msg}monthly_now: {monthly_now}\nall_time_now: {all_time_now}\nincr: {std_incr}\ncur_time: {cur_time}\nlast_record_time: {last_record_time}\npast_in_session_time: {in_session_std_time}\nuser_id: {user_id}' self.data_change_logger.info(log_msg)
def sync_db(self, user_id, channel, category_type, category_offset): cur_time = utilities.get_time() categories = [i + " " + category_type for i in ["end", "start"]] cur_category = categories[category_offset] last_record = self.get_last_record(user_id, categories) # data recovery if last_record: # For case: # last: start id_1 # cur: end id_2 if last_record.detail != channel.id and categories.index( last_record.category): # Add end for last last_category_offset = categories.index(last_record.category) cur_time += timedelta(microseconds=1) record = Action(user_id=user_id, category=categories[1 - last_category_offset], detail=last_record.detail, creation_time=cur_time) self.sqlalchemy_session.add(record) if category_offset == 0: # Add start for cur # A bit inelegant when a user with video on switches to another channel cur_time += timedelta(microseconds=1) record = Action(user_id=user_id, category=categories[last_category_offset], detail=channel.id, creation_time=cur_time) self.sqlalchemy_session.add(record) # For case: # start(end) id_1 # start(end) id_1 # end id_1 # end id_2 elif last_record.category == cur_category: cur_time += timedelta(microseconds=1) record = Action(user_id=user_id, category=categories[1 - category_offset], detail=last_record.detail, creation_time=cur_time) self.sqlalchemy_session.add(record) cur_time += timedelta(microseconds=1) record = Action(user_id=user_id, category=cur_category, detail=channel.id, creation_time=cur_time) self.sqlalchemy_session.add(record) utilities.commit_or_rollback(self.sqlalchemy_session) return last_record.creation_time if last_record else cur_time
def handle_in_session(self, user_id, reset): # after data recovery we should have a sensible start channel record last_record = self.get_last_record(user_id, ["start channel"]) cur_time = utilities.get_time() last_record_time = last_record.creation_time if last_record else cur_time rank_categories = utilities.get_rank_categories(string=False) rank_categories_val = list(rank_categories.values()) string_rank_categories = list( utilities.get_rank_categories(string=True).values()) in_session_names = [ "in_session_" + str(in_session) for in_session in string_rank_categories[0] ] category_key_names = string_rank_categories[ 0] + string_rank_categories[1:] in_session_incrs = [] std_incr = None # TODO optimize: most values here will be the same and this is the bottleneck for in_session, in_session_name in zip(rank_categories_val[0], in_session_names): past_in_session_time = self.redis_client.hget( in_session_name, user_id) past_in_session_time = float( past_in_session_time) if past_in_session_time else 0 base_time = max(last_record_time, in_session) incr = utilities.timedelta_to_hours( cur_time - base_time) - past_in_session_time if in_session_name[-8:] == str( utilities.config["business"]["update_time"]) + ":00:00": std_incr = incr prev_std_incr_name = "daily_" + str(in_session - timedelta(days=1)) prev_std_incr = self.redis_client.hget( "in_session_" + prev_std_incr_name, user_id) prev_std_incr = float(prev_std_incr) if prev_std_incr else 0 if prev_std_incr: std_incr += prev_std_incr self.redis_client.hset("in_session_" + prev_std_incr_name, user_id, 0) in_session_incrs.append(incr) new_val = 0 if reset else incr + past_in_session_time self.redis_client.hset(in_session_name, user_id, new_val) utilities.increment_studytime(category_key_names, self.redis_client, user_id, in_session_incrs=in_session_incrs, std_incr=std_incr)
def __init__(self, bot): self.bot = self.client = bot self.guild = None self.role_objs = None self.role_names = None self.supporter_role = None self.data_change_logger = utilities.get_logger( "study_executor_data_change", "data_change.log") self.time_counter_logger = utilities.get_logger( "study_executor_time_counter", "discord.log") self.redis_client = utilities.get_redis_client() engine = utilities.get_engine() Session = sessionmaker(bind=engine) self.sqlalchemy_session = Session() self.timezone_session = utilities.get_timezone_session() self.birthtime = utilities.get_time()
def __init__(self, bot): self.bot = bot self.guild = None self.role_objs = None self.role_name_to_obj = None self.supporter_role = None # TODO fix when files not existent self.time_counter_logger = utilities.get_logger( "study_executor_time_counter", "discord.log") self.heartbeat_logger = utilities.get_logger( "study_executor_heartbeat", "heartbeat.log") self.redis_client = utilities.get_redis_client() engine = utilities.get_engine() Session = sessionmaker(bind=engine) self.sqlalchemy_session = Session() self.timezone_session = utilities.get_timezone_session() self.make_heartbeat.start() self.birthtime = utilities.get_time()
async def on_command_error(self, ctx, exception): print(utilities.get_time(), exception) await ctx.send(f"{exception}\nTry ~help?")
return [float(row[1]), float(row[2])] path = os.path.join(os.path.dirname(__file__), '..', '../routes/ASC2018.csv') total_time = 0 #in minutes with open(path, 'r') as asc2018: next(asc2018) total_time = 0 p2 = None p1 = getCoordinates(asc2018) #[long, lat] f = open('predictions.csv', 'a') for i in range(16): while total_time < 30: p2 = getCoordinates(asc2018) d = find_distance(p1[0], p1[1], p2[0], p2[1]) total_time += get_time(d) * 60 #get time in mins p1 = p2 #PRINTING COORDINATES USED print(p1) print(p2) #get prediction forecast (API CALL) raw_forecast = get_radiation_data(p2[0], p2[1], api_key) future_forecast = [i, raw_forecast['forecasts'][1]['ghi']] #current time t = time.localtime() current_time = time.strftime("%H:%M:%S", t) print(current_time) #wait 30 minutes
logger = utilities.get_logger("main", "heartbeat.log") proc = None line = utilities.get_last_line() # TODO: fix - Dangerous - need to make sure it's our process utilities.kill_last_process(line) while True: try: line = utilities.get_last_line() last_time = utilities.get_last_time(line) max_diff_var_name = ("test_" if os.getenv("mode") == "test" else "") + "heart_attack_interval_sec" max_diff_sec = int(os.getenv(max_diff_var_name)) max_diff = timedelta(seconds=max_diff_sec) if (not last_time) or utilities.get_time() - last_time > max_diff: # Process has died. Restart it proc = subprocess.Popen(['python3', './time_counter.py']) logger.info(f"{utilities.get_time()} birth with pid {proc.pid}") sleep(60 if os.getenv("mode") != "test" else max_diff_sec) except Exception as e: print(e) # This does not catch exceptions from child processes!! if proc: proc.kill() logger.info(f"{utilities.get_time()} graceful death") break
def main(): print(utilities.get_time())