def report_status(): if not base_data[r'server_uuid']: ip_resp = yield Utils.http_request(Config.IpEchoInterface, method=r'GET') if ip_resp and ip_resp.code >= 200 and ip_resp.code < 300: base_data[r'server_uuid'] = str(ip_resp.body, r'utf-8') if not base_data[r'server_uuid']: app_log.warning(r"get server ip failed, status report abort") return data = { r'server_type': r'account_service', } data.update(base_data) status = Utils.get_machine_status() data.update(status) mysql_conn = MySQLPool().get_conn_status() data[r'mysql_conn'] = json.dumps(mysql_conn) redis_conn = MCachePool().get_conn_status() data[r'redis_conn'] = json.dumps(redis_conn) resp = yield Utils.http_request(Config.MaintainServiceInterface + r'server_status', method=r'POST', body=data, style=r'JSON') if not resp or not (resp.code >= 200 and resp.code < 300): app_log.error(r"status report error")
def test_random_float(self): rand1 = Utils.random_float() rand2 = Utils.random_float() self.assertNotEqual(rand1, rand2) self.assertLess(rand1, 100) self.assertLess(rand2, 100) self.assertGreaterEqual(rand1, 0) self.assertGreaterEqual(rand2, 0)
def today_used_info(self, uid): result = [False, ErrorCode.NotFoundUser] with catch_error(): mssql_account_conn = self.get_mssql_conn(Config.MssqlRecordDbName) today_zero = Utils.today_zero() with mssql_account_conn.cursor() as cur: cur.execute(r"""select sum(CostValue) as today_used_count from RecordPrivateCost where UserID={0} and DATEDIFF(s, '1970-01-01 00:00:00', CostDate) > {1} and CostFrom in (1,2)""".format( uid, today_zero)) _infos = cur.fetchall() mssql_account_conn.close() if not _infos[0]['today_used_count']: return result if _infos[0]['today_used_count'] > 0: result[0] = True result[1] = _infos if _infos[0]['today_used_count'] < 0: result[0] = True result[1] = 0 return result
def all_today_prize_count(self, prize_id): num = None with catch_error(): db_client = self.get_db_client() today_zero = Utils.today_zero() sql_where = 'prize_id = %s and create_time > %d' % (prize_id, today_zero) res = yield db_client.select(r'prize_log', what='count(1) as all_today_prize_count', where=sql_where) if res: num = res[0]['all_today_prize_count'] return num
def write_log(self, uid, prize_id, plus_num): result = [False, ErrorCode.Unknown] param = { 'user_id': uid, 'create_time': Utils.timestamp(), 'prize_id': prize_id } with catch_error(): db_client = self.get_db_client() if plus_num: # 插入获奖日志,并且增加房卡 if plus_num > 0: # 需要增加房卡的 '''增加房卡''' update_score_statu = yield db_client.increase_update(r'game_score_info', where={'user_id': uid}, fields1={'insure_score': plus_num}) # print(2, update_score_statu) # 0 if not update_score_statu > 0: result[1] = ErrorCode.Database.set_extra('增加房卡失败!') self.Break() # mssql_score_conn = self.get_mssql_conn(Config.MssqlTreasureDbName) # with mssql_score_conn.cursor() as cur: # cur.execute(r"""update GameScoreInfo set InsureScore = # InsureScore + {} where UserID = {}""".format(plus_num, uid)) # rowcount = cur.rowcount # if not rowcount > 0: # result[1] = ErrorCode.Database.set_extra(r'添加房卡失败!') # self.Break() # mssql_score_conn.commit() # mssql_score_conn.close() '''更新获奖日志,需要加京东卡或红包的''' insert_statu = yield db_client.insert('prize_log', **param) # print(1, insert_statu) # 0 if insert_statu < 0: result[1] = ErrorCode.Database.set_extra('插入日志失败!') self.Break() '''更新领奖次数''' update_statu = yield db_client.increase_update('make_prize', where={'user_id': uid}, fields1={'left_chance': -1}, fields2={'used_chance': 1}) # print(3, update_statu) # 1 if not update_statu > 0: result[1] = ErrorCode.Database.set_extra('更新领取表失败!') self.Break() result[0] = True return result
def initial_draw_card_info(self, account_info): """ 插入本地创建的领取记录表,并且对房卡进行增加 :param account_info: :return: """ result = False with catch_error(): insert_map = {} insert_map['user_id'] = account_info['UserID'] insert_map['union_id'] = account_info['unionid'] insert_map['create_time'] = Utils.timestamp() db_client = self.get_db_client() res_insert_draw = yield db_client.insert('draw_card_info', **insert_map) if res_insert_draw < 0: self.Break() uid = account_info['UserID'] '''本地数据库试验''' # res_insert_score = yield db_client.increase_update(r'game_score_info', where={'user_id': uid}, # fields1={'insure_score': 5}) # if not res_insert_score > 0: # self.Break() '''mssql数据库正式操作''' # mssql_score_conn = self.get_mssql_conn(Config.MssqlTreasureDbName) # with mssql_score_conn.cursor() as cur: # cur.execute(r"update GameScoreInfo set InsureScore = InsureScore + {} where UserID = {}".format( # 5, # uid)) # rowcount = cur.rowcount # if not rowcount > 0: # self.Break() # mssql_score_conn.commit() # mssql_score_conn.close() result = True return result
async def tipfavorites_cmd(self, ctx: Context): if ctx.error: await Messages.add_x_reaction(ctx.message) return msg = ctx.message user = ctx.user send_amount = ctx.send_amount # Check anti-spam if not ctx.god and await RedisDB.instance().exists(f"tipfavoritesspam{msg.author.id}"): await Messages.add_timer_reaction(msg) await Messages.send_basic_dm(msg.author, "You can only tipfavorites once every 5 minutes") return # Get their favorites favorites = await Favorite.filter(user=user).prefetch_related('favorited_user').all() if len(favorites) < 1: await Messages.add_x_reaction(msg) await Messages.send_error_dm(msg.author, "You don't have any favorites, add some first.") return individual_send_amount = NumberUtil.truncate_digits(send_amount / len(favorites), max_digits=Env.precision_digits()) if individual_send_amount < Constants.TIP_MINIMUM: await Messages.add_x_reaction(msg) await Messages.send_error_dm(msg.author, f"Tip amount too small, each user needs to receive at least {Constants.TIP_MINIMUM}. With your tip they'd only be getting {individual_send_amount}") return # See how much they need to make this tip. amount_needed = individual_send_amount * len(favorites) available_balance = Env.raw_to_amount(await user.get_available_balance()) if amount_needed > available_balance: await Messages.add_x_reaction(msg) await Messages.send_error_dm(msg.author, f"Your balance isn't high enough to complete this tip. You have **{available_balance} {Env.currency_symbol()}**, but this tip would cost you **{amount_needed} {Env.currency_symbol()}**") return # Make the transactions in the database tx_list = [] task_list = [] for u in favorites: tx = await Transaction.create_transaction_internal_dbuser( sending_user=user, amount=individual_send_amount, receiving_user=u.favorited_user ) if tx is not None: tx_list.append(tx) if not await user.is_muted_by(u.favorited_user.id): task_list.append( Messages.send_basic_dm( member=self.bot.get_user(u.favorited_user.id), message=f"You were tipped **{individual_send_amount} {Env.currency_symbol()}** by {msg.author.name.replace('`', '')}.\nUse `{config.Config.instance().command_prefix}mute {msg.author.id}` to disable notifications for this user." ) ) if len(tx_list) < 1: await Messages.add_x_reaction(msg) await Messages.send_error_dm(msg.author, f"No users you mentioned are eligible to receive tips.") return # Send DMs asyncio.ensure_future(Utils.run_task_list(task_list)) # Add reactions await Messages.add_tip_reaction(msg, amount_needed) # Queue the actual sends for tx in tx_list: await TransactionQueue.instance().put(tx) # anti spam await RedisDB.instance().set(f"tipfavoritesspam{msg.author.id}", "as", expires=300) # Update stats stats: Stats = await user.get_stats(server_id=msg.guild.id) if msg.channel.id not in config.Config.instance().get_no_stats_channels(): await stats.update_tip_stats(amount_needed)
async def update_activity_stats(msg: discord.Message): """Update activity statistics for a user""" if ChannelUtil.is_private(msg.channel): return member = msg.author # Ignore if user doesnt have rain role has_rain_role = False rain_roles = config.Config.instance().get_rain_roles() if len(rain_roles) > 0: for role in member.roles: if role.id in rain_roles: has_rain_role = True break if not has_rain_role: return content_adjusted = Utils.emoji_strip(msg.content) if len(content_adjusted) == 0: return # Get user OBJ from redis if it exists, else create one user_key = f"activity:{msg.guild.id}:{msg.author.id}" active_stats = await RedisDB.instance().get(user_key) if active_stats is None: # Create stats and save active_stats = { 'user_id': msg.author.id, 'last_msg': datetime.datetime.utcnow().strftime('%m/%d/%Y %H:%M:%S'), 'msg_count': 1 } await RedisDB.instance().set(user_key, json.dumps(active_stats), expires=1800) return else: active_stats = json.loads(active_stats) # Ignore em if they've messaged too recently last_msg_dt = datetime.datetime.strptime(active_stats['last_msg'], '%m/%d/%Y %H:%M:%S') delta_s = (datetime.datetime.utcnow() - last_msg_dt).total_seconds() if 90 > delta_s: return elif delta_s > 1200: # Deduct a point if active_stats['msg_count'] > 1: active_stats['msg_count'] -= 1 active_stats['last_msg'] = datetime.datetime.utcnow().strftime( '%m/%d/%Y %H:%M:%S') await RedisDB.instance().set(user_key, json.dumps(active_stats), expires=1800) else: # add a point if active_stats['msg_count'] <= Constants.RAIN_MSG_REQUIREMENT * 2: active_stats['msg_count'] += 1 active_stats['last_msg'] = datetime.datetime.utcnow().strftime( '%m/%d/%Y %H:%M:%S') await RedisDB.instance().set(user_key, json.dumps(active_stats), expires=1800) else: # Reset key expiry active_stats['last_msg'] = datetime.datetime.utcnow().strftime( '%m/%d/%Y %H:%M:%S') await RedisDB.instance().set(user_key, json.dumps(active_stats), expires=1800)
async def rain_cmd(self, ctx: Context): if ctx.error: return msg = ctx.message user = ctx.user send_amount = ctx.send_amount anon = 'anon' in msg.content # Get active users active_users = await self.get_active(ctx, excluding=msg.author.id) if len(active_users) < Constants.RAIN_MIN_ACTIVE_COUNT: await Messages.add_x_reaction(msg) await Messages.send_error_dm( msg.author, f"Not enough users are active to rain - I need at least {Constants.RAIN_MIN_ACTIVE_COUNT} but there's only {len(active_users)} active bros" ) return individual_send_amount = Env.truncate_digits( send_amount / len(active_users), max_digits=Env.precision_digits()) individual_send_amount_str = f"{individual_send_amount:.2f}" if Env.banano( ) else f"{individual_send_amount:.6f}" if individual_send_amount < Constants.TIP_MINIMUM: await Messages.add_x_reaction(msg) await Messages.send_error_dm( msg.author, f"Amount is too small to divide across {len(active_users)} users" ) return # See how much they need to make this tip. amount_needed = Env.truncate_digits(individual_send_amount * len(active_users), max_digits=Env.precision_digits()) available_balance = Env.raw_to_amount(await user.get_available_balance()) if amount_needed > available_balance: await Messages.add_x_reaction(msg) await Messages.send_error_dm( msg.author, f"Your balance isn't high enough to complete this tip. You have **{available_balance} {Env.currency_symbol()}**, but this tip would cost you **{amount_needed} {Env.currency_symbol()}**" ) return # Make the transactions in the database tx_list = [] task_list = [] for u in active_users: tx = await Transaction.create_transaction_internal_dbuser( sending_user=user, amount=individual_send_amount, receiving_user=u) tx_list.append(tx) if not await user.is_muted_by(u.id): if not anon: task_list.append( Messages.send_basic_dm( member=msg.guild.get_member(u.id), message= f"You were tipped **{individual_send_amount_str} {Env.currency_symbol()}** by {msg.author.name.replace('`', '')}.\nUse `{config.Config.instance().command_prefix}mute {msg.author.id}` to disable notifications for this user.", skip_dnd=True)) else: task_list.append( Messages.send_basic_dm( member=msg.guild.get_member(u.id), message= f"You were tipped **{individual_send_amount_str} {Env.currency_symbol()}** anonymously!", skip_dnd=True)) # Send DMs in the background asyncio.ensure_future(Utils.run_task_list(task_list)) # Add reactions await Messages.add_tip_reaction(msg, amount_needed, rain=True) # Queue the actual sends for tx in tx_list: await TransactionQueue.instance().put(tx) # Add anti-spam await RedisDB.instance().set(f"rainspam{msg.author.id}", "as", expires=300) # Update stats stats: Stats = await user.get_stats(server_id=msg.guild.id) if msg.channel.id not in config.Config.instance( ).get_no_stats_channels(): await stats.update_tip_stats(amount_needed) # DM creator await Messages.send_success_dm( msg.author, f"You rained **{amount_needed} {Env.currency_symbol()}** to **{len(tx_list)} users**, they received **{individual_send_amount_str} {Env.currency_symbol()}** each.", header="Make it Rain") # Make the rainer auto-rain eligible await self.auto_rain_eligible(msg)
def initial_chance_info(self, uid): result = [False, ErrorCode.Unknown] with catch_error(): db_client = self.get_db_client() info = yield db_client.select(r'make_prize', what='first_time,left_chance,used_chance', where={'user_id': uid}) # 查找本地账户是否有该人 total_chance = Config.TotalChance # 如果有的话,拿到该人的最后一次领取时间 # print(1, info) # [{'first_time': 150993117, 'left_chance': 0, 'used_chance': 1}] if info: first_time = info[0]['first_time'] if not info: # 如果没有的话,初始化本地该人账户 '''先从sqlserver中查找该人信息''' m_account_info = AccountInfo() # 从账户中查找该人信息 user_info = yield m_account_info.get_mssql_user_info_by_user_id(uid) # print(2, user_info) # [True, [{'UserID': 120, 'NickName': '游客7486118'}]] if user_info[0]: # 如果有该用户的话,写入本地账户 insert_map = {} insert_map['create_time'] = Utils.timestamp() insert_map['user_id'] = user_info[1][0]['UserID'] insert_map['nick_name'] = user_info[1][0]['NickName'] insert_account_statu = yield db_client.insert('account_info', **insert_map) # print(3, insert_account_statu) # 120 if insert_account_statu < 0: # 如果没有插入成功的话 result[1] = ErrorCode.Database.set_extra(r'初始化时插入用户表中信息失败!') self.Break() else: #插入成功的话,再往make_prize中插 param = { 'user_id': uid, 'first_time': Utils.timestamp(), 'left_chance': 1, 'used_chance': 0, 'added_chance': 1, } insert_make_prize_statu = yield db_client.insert('make_prize', **param) # print(4, insert_make_prize_statu) # 0 if insert_make_prize_statu < 0: # 成功的话返回None result[1] = ErrorCode.Database.set_extra(r'插入本地奖品次数表失败!') self.Break() first_time = param['first_time'] else: # 没有该用户信息的话 result[1] = user_info[1] self.Break() if first_time < Utils.today_zero(): # 如果领取时间是昨天,就刷领取信息 param = { 'first_time': Utils.timestamp(), 'left_chance': 1, 'used_chance': 0, 'added_chance': 1, } flush_status = yield db_client.update('make_prize', **param, where={'user_id': uid}) # print(5, flush_status) # 1 if flush_status < 0: # 成功的话返回1, row_count result[1] = ErrorCode.Database.set_extra(r'刷新用户信息失败!') self.Break() info = yield db_client.select(r'make_prize', what='left_chance,used_chance,added_chance', where={'user_id': uid}) # print(6, info) # [{'left_chance': 1, 'used_chance': 0, 'added_chance': 1}] left_chance = info[0]['left_chance'] added_chance = info[0]['added_chance'] today_used_count = yield CardUsedInfoModel().today_used_info(uid) # print(7, today_used_count) # [False, -20017 ] if not today_used_count[0]: today_used = 0 if today_used_count[0]: today_used = today_used_count[1][0]['today_used_count'] if today_used <= 0: today_used = 0 all_time = divmod(today_used, Config.EveryChanceRequire)[0] all_times = all_time if all_time < total_chance else total_chance add_time = all_times - added_chance if add_time < 0: add_time = 0 add_time_status = yield db_client.increase_update(r'make_prize', where={'user_id': uid}, fields1={'left_chance': add_time}, fields2={'added_chance': add_time}) # print(8, add_time_status) # 0 if add_time_status < 0: # 受影响的行数 0 result[1] = ErrorCode.Database.set_extra("更新奖品次数失败!") self.Break() result[1] = left_chance + add_time result[0] = True return result
async def tiprandom_cmd(self, ctx: Context): if ctx.error: await Messages.add_x_reaction(ctx.message) return msg = ctx.message user = ctx.user send_amount = ctx.send_amount # Check anti-spam if not ctx.god and await RedisDB.instance().exists( f"tiprandomspam{msg.guild.id}{msg.author.id}"): await Messages.add_timer_reaction(msg) await Messages.send_basic_dm( msg.author, "You can only tiprandom once every minute") return active_users = await rain.RainCog.get_active(ctx, excluding=msg.author.id) if len(active_users) < Constants.RAIN_MIN_ACTIVE_COUNT: await Messages.send_error_dm( msg.author, f"There aren't enough active people to do a random tip. Only **{len(active_users)}** are active, but I'd like to see at least **{Constants.RAIN_MIN_ACTIVE_COUNT}**" ) return target_user = secrets.choice(active_users) # See how much they need to make this tip. available_balance = Env.raw_to_amount(await user.get_available_balance()) if send_amount > available_balance: await Messages.add_x_reaction(ctx.message) await Messages.send_error_dm( msg.author, f"Your balance isn't high enough to complete this tip. You have **{available_balance} {Env.currency_symbol()}**, but this tip would cost you **{send_amount} {Env.currency_symbol()}**" ) return # Make the transactions in the database tx = await Transaction.create_transaction_internal_dbuser( sending_user=user, amount=send_amount, receiving_user=target_user) task_list = [] if not await user.is_muted_by(target_user.id): task_list.append( Messages.send_basic_dm( member=msg.guild.get_member(target_user.id), message= f"You were randomly selected and received **{send_amount} {Env.currency_symbol()}** from {msg.author.name.replace('`', '')}.\nUse `{config.Config.instance().command_prefix}mute {msg.author.id}` to disable notifications for this user.", skip_dnd=True)) task_list.append( Messages.send_basic_dm( member=msg.author, message= f'"{target_user.name}" was the recipient of your random tip of {send_amount} {Env.currency_symbol()}' )) asyncio.ensure_future(Utils.run_task_list(task_list)) # Add reactions await Messages.add_tip_reaction(msg, send_amount) # Queue the actual send await TransactionQueue.instance().put(tx) # anti spam await RedisDB.instance().set( f"tiprandomspam{msg.guild.id}{msg.author.id}", "as", expires=60) # Update stats stats: Stats = await user.get_stats(server_id=msg.guild.id) if msg.channel.id not in config.Config.instance( ).get_no_stats_channels(): await stats.update_tip_stats(send_amount)
async def tipsplit_cmd(self, ctx: Context): if ctx.error: await Messages.add_x_reaction(ctx.message) return msg = ctx.message user = ctx.user send_amount = ctx.send_amount # Get all eligible users to tip in their message users_to_tip = [] for m in msg.mentions: if not m.bot and m.id != msg.author.id: users_to_tip.append(m) if len(users_to_tip) < 1: await Messages.add_x_reaction(msg) await Messages.send_error_dm( msg.author, f"No users you mentioned are eligible to receive tips.") return individual_send_amount = NumberUtil.truncate_digits( send_amount / len(users_to_tip), max_digits=Env.precision_digits()) if individual_send_amount < Constants.TIP_MINIMUM: await Messages.add_x_reaction(msg) await Messages.send_error_dm( msg.author, f"Tip amount too small, each user needs to receive at least {Constants.TIP_MINIMUM}. With your tip they'd only be getting {individual_send_amount}" ) return # See how much they need to make this tip. amount_needed = individual_send_amount * len(users_to_tip) available_balance = Env.raw_to_amount(await user.get_available_balance()) if amount_needed > available_balance: await Messages.add_x_reaction(msg) await Messages.send_error_dm( msg.author, f"Your balance isn't high enough to complete this tip. You have **{available_balance} {Env.currency_symbol()}**, but this tip would cost you **{amount_needed} {Env.currency_symbol()}**" ) return # Make the transactions in the database tx_list = [] task_list = [] for u in users_to_tip: tx = await Transaction.create_transaction_internal( sending_user=user, amount=individual_send_amount, receiving_user=u) if tx is not None: tx_list.append(tx) if not await user.is_muted_by(u.id): task_list.append( Messages.send_basic_dm( member=u, message= f"You were tipped **{individual_send_amount} {Env.currency_symbol()}** by {msg.author.name.replace('`', '')}.\nUse `{config.Config.instance().command_prefix}mute {msg.author.id}` to disable notifications for this user.", skip_dnd=True)) if len(tx_list) < 1: await Messages.add_x_reaction(msg) await Messages.send_error_dm( msg.author, f"No users you mentioned are eligible to receive tips.") return # Send DMs asyncio.ensure_future(Utils.run_task_list(task_list)) # Add reactions await Messages.add_tip_reaction(msg, amount_needed) # Queue the actual sends for tx in tx_list: await TransactionQueue.instance().put(tx) # Update stats stats: Stats = await user.get_stats(server_id=msg.guild.id) if msg.channel.id not in config.Config.instance( ).get_no_stats_channels(): await stats.update_tip_stats(amount_needed)
def test_emoji_strip(self): self.assertEqual(Utils.emoji_strip("å—æ¼¢å—Hello😊myfriend\u2709"), "å—æ¼¢å—Hellomyfriend")
# coding=utf-8 import json from tornado.gen import coroutine from tornado.log import app_log from util.util import Utils from model.base import MySQLPool, MCachePool from config import Config base_data = { r'server_uuid': None, r'up_time': Utils.timestamp() } @coroutine def report_status(): if not base_data[r'server_uuid']: ip_resp = yield Utils.http_request(Config.IpEchoInterface, method=r'GET') if ip_resp and ip_resp.code >= 200 and ip_resp.code < 300: base_data[r'server_uuid'] = str(ip_resp.body, r'utf-8') if not base_data[r'server_uuid']: app_log.warning(r"get server ip failed, status report abort") return data = { r'server_type': r'account_service', }