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
async def on_member_join(self, member): if self.sqlalchemy_session: user_sql_obj = self.sqlalchemy_session.query(User).filter( User.id == member.id).all() if not user_sql_obj: to_insert = User(id=member.id) self.sqlalchemy_session.add(to_insert) utilities.commit_or_rollback(self.sqlalchemy_session)
async def add_streak(self, user_id, reset=False): user = self.sqlalchemy_session.query(User).filter( User.id == user_id).first() if reset: user.current_streak = 0 else: user.current_streak += 1 if user.longest_streak < user.current_streak: user.longest_streak = user.current_streak utilities.commit_or_rollback(self.sqlalchemy_session)
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
async def change(self, ctx, dataset_name, val: float, user: discord.Member = None): """ Changes users' hours (use '~help change' to see more) Only streak data and zset data types are supported ("longest_streak", "current_streak", "all_time" and "monthly_*") example: '-c current_streak 21 @target_user' changes the current_streak data to be 21 and update the longest_streak if sensible example: '-c longest_streak 210 @target_user' changes the longest_streak data to be 210 examples: '-c monthly_February 200.5 @target_user' changes the February monthly data to be 200 hours for user examples: '-c all_time 400.21 @target_user' changes the all_time data to be 400.21 hours Suggestion: ALWAYS test any change commands on @studydev first. """ user_id = user.id if dataset_name in ["longest_streak", "current_streak"]: val = round(val) user_sql_obj = self.sqlalchemy_session.query(User).filter( User.id == user_id).first() if dataset_name == "longest_streak": user_sql_obj.longest_streak = val elif dataset_name == "current_streak": user_sql_obj.current_streak = val user_sql_obj.longest_streak = max(val, user_sql_obj.longest_streak) utilities.commit_or_rollback(self.sqlalchemy_session) elif self.redis_client.type(dataset_name) == "zset": self.redis_client.zrem(dataset_name, user_id) self.redis_client.zadd(dataset_name, {user_id: val}) await ctx.send( f"user_id: {user_id}, dataset_name: {dataset_name}\nval: {val}")