def init_order_queues(self): for group_account_entity in self.group_account_project_array: try: my_logger.info('初始化%s的订单队列', group_account_entity.group_account_id) my_logger.debug(self.order_queues) if group_account_entity.group_account_id not in self.order_queues: self.order_queues[ group_account_entity.group_account_id] = set() my_logger.debug('队列为空,重新初始化队列') else: my_logger.debug('队列不为空,不重新初始化队列') continue my_logger.debug( '项目%s队列长度: %s', group_account_entity.group_account_id, len(self.order_queues[ group_account_entity.group_account_id])) orders = self.query_project_orders(group_account_entity) for order in orders: listid = int(order['listid']) self.order_queues[ group_account_entity.group_account_id].add(listid) except Exception as e: my_logger.error('初始化订单队列失败!') my_logger.exception(e)
def get_plus_10_times(pro_id): """ 获取给本方加10分操作的次数 :param pro_id: :return: """ # fxf: 集资101.7以上 # wjl: 集资71.3以上 不包含99.9 # 每5次捣乱 +10分 my_logger.info('获取给本方加10分的次数,pro_id: %s' % pro_id) if pro_id == FXF_PRO_ID: rst = mysql_util.select_one( """ SELECT count(*) FROM `order` WHERE `pro_id`=%s and `backer_money`>= %s and `backer_money`<>%s """, (FXF_PRO_ID, 101.7, MINUS_AMOUNT)) elif pro_id == WJL_PRO_ID: rst = mysql_util.select_one( """ SELECT count(*) FROM `order` WHERE `pro_id`=%s and `backer_money`>= %s AND `backer_money`<>%s """, (WJL_PRO_ID, 71.3, MINUS_AMOUNT)) else: return 0 # 本方捣乱次数 # rst2 = get_make_trouble_time(pro_id) return rst[0]
def query_project_orders(self, group_account_entity, page=1, limit=10): """ 批量获取订单 :param group_account_entity: :param page: :param limit: :return: """ my_logger.info('查询项目订单, id: %s', group_account_entity.group_account_id) url = 'https://groupaccount.tenpay.com/fcgi-bin/grp_qry_group_water.fcgi' data = { "group_account_id": group_account_entity.group_account_id, "start_time": '2017-01-01 00:00:00', "end_time": '2100-01-31 00:00:00', "qry_ver": 1, "lastbkid": '', "offset": page - 1, "limit": limit, "type": 2, "target_unionid": "" } r = self.session.post(url=url, data=data, headers=self.weixin_header()).json() if int(r['retcode']) != 0: raise RuntimeError('获取订单信息失败') orders = json.loads(unquote(r['water_array'])) my_logger.info('项目订单: page: %s, orders: %s', page, orders) return orders['water_array']
def init_order_queues(self): for modian_entity in self.modian_project_array: try: my_logger.info('初始化%s的订单队列', modian_entity.pro_id) my_logger.debug(self.order_queues) if modian_entity.pro_id not in self.order_queues: self.order_queues[modian_entity.pro_id] = set() my_logger.debug('队列为空,重新初始化队列') else: my_logger.debug('队列不为空,不重新初始化队列') continue my_logger.debug('项目%s队列长度: %s', modian_entity.pro_id, len(self.order_queues[modian_entity.pro_id])) # 先拉一把项目的基本资料 self.get_project_profiles(modian_entity) orders = self.query_project_orders(modian_entity) for order in orders: backer_money_icon = order.find(class_='icon-payment') if not backer_money_icon: # 纯评论,直接跳过 continue comment_id = order.get('data-reply-id') # oid使用项目id和评论id拼装 oid = str(modian_entity.pro_id) + str(comment_id) my_logger.debug('oid: %s', oid) self.order_queues[modian_entity.pro_id].add(oid) except Exception as e: my_logger.error('初始化订单队列失败!') my_logger.exception(e)
def sync_order(): global modian_handler my_logger.info('同步订单') for modian in global_config.MODIAN_ARRAY: pro_id = modian.group_account_id orders = modian_handler.get_all_orders(modian) for order in orders: user_id = order['user_id'] nickname = order['nickname'] pay_time = order['pay_time'] backer_money = order['backer_money'] oid = uuid.uuid3(uuid.NAMESPACE_OID, str(user_id) + pay_time) # print('oid: %s', oid) rst = mysql_util.select_one( """ select * from `order` where id='%s' """, (str(oid), )) if len(rst) == 0: my_logger.info('该订单不在数据库中') # 每次需要更新一下昵称 mysql_util.query(""" INSERT INTO `supporter` (`id`, `name`) VALUES (%s, '%s') ON DUPLICATE KEY UPDATE `name`='%s' """ % (user_id, nickname, nickname)) mysql_util.query(""" INSERT INTO `order` (`id`, `supporter_id`, `backer_money`, `pay_time`, `pro_id`) VALUES ('%s', %s, %s, '%s', %s); """ % (oid, user_id, backer_money, pay_time, pro_id)) msg = '【机器人补播报】感谢 %s 支持了%s元, %s\n' % ( nickname, backer_money, util.random_str(global_config.MODIAN_POSTSCRIPTS)) # QQHandler.send_to_groups(['483548995'], msg) modian_handler.order_queues[modian.group_account_id].add(oid)
def init_order_queues(self): for modian_entity in self.modian_project_array: try: my_logger.info('初始化%s的订单队列', modian_entity.pro_id) my_logger.debug(self.order_queues) if modian_entity.pro_id not in self.order_queues: self.order_queues[modian_entity.pro_id] = set() my_logger.debug('队列为空,重新初始化队列') else: my_logger.debug('队列不为空,不重新初始化队列') continue # self.order_queues[modian_entity.pro_id] = set() my_logger.debug('项目%s队列长度: %s', modian_entity.pro_id, len(self.order_queues[modian_entity.pro_id])) orders = self.query_project_orders(modian_entity) # retry_time = 0 # while retry_time < 5: # retry_time += 1 # if len(orders) == 0: # my_logger.debug('请求订单失败,第%s次重试', retry_time) # orders = self.query_project_orders(modian_entity) # else: # break for order in orders: user_id = order['user_id'] pay_time = order['pay_time'] oid = uuid.uuid3(uuid.NAMESPACE_OID, str(user_id) + pay_time) self.order_queues[modian_entity.pro_id].add(oid) except Exception as e: my_logger.error('初始化订单队列失败!') my_logger.exception(e)
def get_current_and_target(self, taoba_entity): """ 查询当前项目情况 :param taoba_entity: :return: """ my_logger.info('获取当前进度和总额: pro_id: %s', taoba_entity.taoba_id) api = 'https://www.tao-ba.club/idols/detail' data = { 'id': taoba_entity.taoba_id, 'requestTime': int(time.time() * 1000), 'pf': 'h5' } r = self.session.post(api, data=self.encrypt(data), headers=self.taoba_header()) r = self.decrypt(r.text) if int(r['code']) == 0: name = r['datas']['title'] current = r['datas']['donation'] # user_num = r['user_num'] if 'pkgroup' in r['datas'].keys() and r['datas']['pkgroup']: taoba_entity.pk_group = r['datas']['pkgroup'] user_num = 0 my_logger.info('支持人数: %s, 当前进度: %s', user_num, current) return name, current, user_num else: raise RuntimeError('获取项目筹款结果查询失败')
def draw_missed_cards(self, modian_id, score=10): """ 补抽卡 :param modian_id: :param score: 抽卡消耗的积分数量 :return: """ logger.info('积分抽卡,modian_id:{}, score:{}'.format(modian_id, score)) import time if score < 15: return '消耗的积分必须要大于等于15!' if score % 15 != 0: return '消耗的积分必须是15的倍数!' current_score = int(self.get_current_score(modian_id)) if current_score < score: return '桃叭ID:{}的当前积分: {},少于需要消耗的积分: {},不能补抽!'.format(modian_id, current_score, score) else: result = '桃叭ID:{},积分抽卡,当前积分-{}\n'.format(modian_id, score) mysql_util.query(""" INSERT INTO `t_card_score` (`modian_id`, `score`) VALUES (%s, %s) """, (modian_id, -1 * score)) money = int(score // 10) * 10.17 result += self.draw(modian_id, '补抽用户', money, util.convert_timestamp_to_timestr(int(time.time() * 1000))) return result
def get_modian_rankings(self, modian_entity, type0=1, page=1): """ 查询项目集资榜和打卡榜 :param type0: 排名类型,1代表集资榜,2代表打卡榜 :param modian_entity: :param page: 页号,每页默认返回20条 :return: """ if type0 == 1: my_logger.info('查询项目集资榜, page=%s', page) elif type0 == 2: my_logger.info('查询项目打卡榜, page=%s', page) else: my_logger.error('type0参数不合法') raise RuntimeError('type0参数不合法!') api = 'https://wds.modian.com/api/project/rankings' params = {'pro_id': modian_entity.pro_id, 'type': type0, 'page': page} r = requests.post(api, self.make_post_params(params), headers=self.modian_header()).json() if int(r['status']) == 0: # pro_name = r['data']['pro_name'] rankings = r['data'] # my_logger.info('查询项目排名: %s', rankings) return rankings elif int(r['status'] == 2): return [] else: raise RuntimeError('获取项目排名失败, type=%d', type0)
def donate(modian_id, pay_amount): MIN_AMOUNT = 10 rst = '' has_created, character = created(modian_id) if has_created: my_logger.info('已经创建了人物: %s' % modian_id) # 如果已经创建 my_logger.debug('%s触发了随机事件(施工中)' % character.name) if pay_amount < MIN_AMOUNT: return '' tmp = pay_amount amounts = [200, 100, 50, 20, 10] # amounts = [i / 10 for i in amounts] max_event = 3 # 最多触发3次事件 idx = 0 while max_event > 0 and idx < len(amounts): event_time = int(tmp / amounts[idx]) event_time = max_event if event_time > max_event else event_time for i in range(event_time): sub_event_str = handle_event(amounts[idx], character) rst += sub_event_str my_logger.debug(sub_event_str) # rst += '----------------------------\n' max_event -= event_time tmp = tmp % amounts[idx] idx += 1 rst += '【{}】当前属性:\n攻:{}, 防: {}, 气: {}, 运:{}, 魅力: {}\n'.format( character.name, character.prop1, character.prop2, character.prop3, character.prop4, character.prop5) else: my_logger.info('未创建人物, modian_id: %s' % modian_id) if pay_amount >= MIN_AMOUNT: rst = create_character(modian_id) return rst
def notify_modian_pk(): """ 播报摩点集资PK情况 :return: """ global modian_handler msg = modian_handler.pk_taoba_activity() my_logger.info(msg)
def generate_card_pic(self, current_cards, user_id): """ 将当前获取的卡片拼接成一张大图,方便查看 :param current_cards: :param user_id: :return: """ from PIL import Image ##################################################### # parameter setting # ##################################################### bol_auto_place = False # auto place the image as a squared image, if 'True', ignore var 'row' and 'col' below row = 10 # row number which means col number images per row col = 10 # col number which means row number images per col nw = 138 # sub image size, nw x nh nh = 183 wgap = 20 dest_im = Image.new('RGB', (col * (nw + wgap), row * nh), (255, 255, 255)) # the image size of splicing image, background color is white for x in range(1, col + 1): # loop place the sub image for y in range(1, row + 1): try: card_id = x + (y - 1) * col if card_id not in self.cards_single.keys(): continue card = self.cards_single[card_id] if self.has_card(card, current_cards): pic_path = os.path.join(BASE_DIR, 'data', 'card_draw', 'imgs3', '{}.png'.format(card_id)) src_im = Image.open(pic_path) # open files in order else: pic_path = os.path.join(BASE_DIR, 'data', 'card_draw', 'imgs3', 'unknown.jpg') src_im = Image.open(pic_path) src_im = src_im.resize((nw, nh), Image.ANTIALIAS) # resize again # # 创建Font对象: # font = ImageFont.truetype('STSong.ttc', 36) # # 创建Draw对象: # draw = ImageDraw.Draw(src_im) # text = '{}-{}'.format(card.level.value, card.name) # # 输出文字: # # position = (40, 100) # draw.text(position, text, font=font, fill="#000000", spacing=0, align='left') resize_im = src_im.resize((nw, nh), Image.ANTIALIAS) # resize again dest_im.paste(resize_im, ((x - 1) * (nw + wgap), (y - 1) * nh)) # paste to dest_im except IOError: pass try: dest_im.save('/home/coolq/data/image/result.jpg') logger.info('图片已保存') except Exception as e: logger.exception(e) dest_im.save('result.jpg', quality=50)
def get_current_supporter_num(pro_id): """ 获取当前集资人数 :param pro_id: :return: """ rst = mysql_util.select_one(""" SELECT COUNT(DISTINCT(`supporter_id`)) FROM `order` WHERE `pro_id`= %s """, (pro_id,)) my_logger.info('[水灰PK]%s当前集资人数: %s' % (pro_id, rst[0] if rst[0] else 0)) return rst[0] if rst[0] else 0
def random_move(self): """ 随机移动 :return: """ ds = [Direction.UP, Direction.DOWN, Direction.LEFT, Direction.RIGHT] random_direction = util.choice(ds)[0] random_dist = random.randint(1, GAME_MAP.row) my_logger.info('随机移动') result = '移动方向: {}, 移动距离: {}, '.format(random_direction, random_dist) self.move(random_direction, random_dist) result += '当前位置: {}\n'.format(self.current_point) return result
def pk_modian_activity(self): """ 播报摩点PK战况 :return: """ if global_config.MODIAN_NEED_DISPLAY_PK is False: return '当前没有开启PK!' my_logger.info('摩点集资PK播报') pk_list = [] pk_list2 = [] for modian_id in global_config.MODIAN_PK_ARRAY: modian_entity = ModianEntity('link', 'title', modian_id) target, current, pro_name, backer_count = self.get_current_and_target( modian_entity) modian_entity.target = target modian_entity.current = current modian_entity.title = pro_name modian_entity.support_num = backer_count pk_list.append(modian_entity) # modian_entity2 = ModianEntity('link', 'title', modian_id) # modian_entity2.target = target # modian_entity2.title = pro_name # modian_entity2.support_num = backer_count # modian_entity2.current = current # modian_entity.current_percent = "%.2f%%" % (float(modian_entity.current) / current_sum * 100) # my_logger.debug('【总选PK】{}'.format(modian_entity.current_percent)) # if modian_id == 74791: # 冯晓菲 # modian_entity.target_percent = '25%' # modian_entity.title = '冯晓菲' # elif modian_id == 74780: # 汪佳翎 # modian_entity.target_percent = '20%' # modian_entity.title = '汪佳翎' # elif modian_id == 74779: # 宋昕冉 # modian_entity.target_percent = '35%' # modian_entity.title = '宋昕冉' # elif modian_id == 74782: # 祁静 # modian_entity.target_percent = '15%' # modian_entity.title = '祁静' # elif modian_id == 74807: # 杨冰怡 # modian_entity.target_percent = '25%' # modian_entity.title = '杨冰怡' # pk_list2.append(modian_entity2) msg1 = self.pk_list_sort(pk_list, '总排名') # msg2 = self.pk_list_sort(pk_list2, '增幅排名情况(7月20日20点-24点') msg = '{}\n'.format(msg1) my_logger.info(msg) return msg
def compute_fxf_yby_single_points(pro_id): """ 计算fxf,yby单日积分 :param pro_id: :return: """ my_logger.info('[水灰PK]计算应援会总分, pro_id=%s' % pro_id) # 总分 rst = mysql_util.select_one(""" SELECT SUM(`point`) from `point_detail` WHERE `pro_id`=%s """, (pro_id,)) point = rst[0] if rst[0] else 0 my_logger.info('[水灰PK]应援会总分: %s' % point) return point
def compute_shuihui_total_points(): """ 计算水灰应援会的总分=日常积分+人头数*25 :return: """ my_logger.info('[水灰PK]计算水灰应援会总分') # 人头数 supporter_num = get_current_supporter_num(SHUIHUI_PRO_ID) # 总分 rst = mysql_util.select_one(""" SELECT SUM(`point`) from `point_detail` WHERE `pro_id`=%s """, (SHUIHUI_PRO_ID, )) point = supporter_num * 25 + rst[0] if rst[0] else 0 my_logger.info('[水灰PK]水灰应援会总分: %s' % point) return point
def get_all_character(): """ 获取所有人物 :return: """ my_logger.info('获取所有人物') rst = mysql_util.select_all(""" SELECT * from `t_character`; """) character_list = [] if rst: for a in rst: character = Character(a[0], str(a[1], encoding='utf-8'), int(a[2]), int(a[3]), int(a[4]), int(a[5]), int(a[6])) character_list.append(character) return character_list
def download_pic(self, url, id): """ 下载图片 :param url: :param id: 卡id :return: """ import requests logger.info('url: {}; id: {}'.format(url, id)) # 这是一个图片的url try: response = requests.get(url) img = response.content with open('../data/card_draw/imgs3/{}.png'.format(id), 'wb') as f: f.write(img) except Exception as e: logger.exception(e)
def encrypt(self, request): """ 对request进行加密 :param request: :return: """ my_logger.info('对request进行加密') my_logger.info('1. 对字符串进行zlib压缩') res_str = json.dumps(request).strip() res = zlib.compress(bytes(res_str, encoding='utf-8')) my_logger.info('2. 对字符串进行处理') res = self.process(res) my_logger.info('3. base64编码') res = base64.b64encode(res) my_logger.info('4. 组装字符串') res = str(len(res_str)) + '$' + str(res, encoding='utf-8') return res
def get_current_points(pro_id): if pro_id not in [SWEET_PRO_ID, TREAT_PRO_ID]: return 0 time0 = time.time() points = 0 rst = mysql_util.select_all( """ SELECT `point` from `point_detail` WHERE `pro_id` = %s """, (pro_id, )) if not rst: return points for a in rst: points += a[0] my_logger.info('当前累计分数: %s' % points) my_logger.debug('该函数共消耗时间: %s' % (time.time() - time0)) return points
def use_good(self, good): """ 使用物品或学习技能 :param good: :return: """ my_logger.info('人物使用物品: %s' % good) self.prop1 += good.prop1 self.prop2 += good.prop2 self.prop3 += good.prop3 self.prop4 += good.prop4 self.prop5 += good.prop5 self.prop1 = 0 if self.prop1 < 0 else self.prop1 self.prop2 = 0 if self.prop2 < 0 else self.prop2 self.prop3 = 0 if self.prop3 < 0 else self.prop3 self.prop4 = 0 if self.prop4 < 0 else self.prop4 self.prop5 = 0 if self.prop5 < 0 else self.prop5
def find_user_jizi_rank(self, user_id, pro_id): """ 在集资榜中找到用户的排名 :param user_id: :param pro_id: :return: """ my_logger.info('找到id为%s的集资排名', user_id) ranking_list = mysql_util.select_all(""" select supporter_id, sum(backer_money) as c from `order` where pro_id=%s group by supporter_id order by c desc; """, (pro_id,)) cur_rank = 0 for temp_id, total in ranking_list: cur_rank += 1 if temp_id == user_id: return cur_rank, total return -1, -1
def decrypt(self, response): """ 对加密的response进行解密 :return: """ my_logger.info('对加密的response进行解密') my_logger.info('1. 分离出base64字符串') response_arr = response.split('$', 2) if len(response_arr) < 2: raise RuntimeError('response格式错误') base64_res = response_arr[1] my_logger.info('2. base64解码') base64_res = base64.b64decode(base64_res) my_logger.info('3. 对字符串进行进一步处理') res = self.process(base64_res) my_logger.info('4. 对处理结果进行zlib解压缩') res = zlib.decompress(res) return json.loads(str(res, encoding='utf-8'))
def find_user_daka_rank(self, user_id, pro_id): """ 在打卡榜中找到用户的排名 :param user_id: :param pro_id: :return: """ my_logger.info('找到用户id为%s的打卡排名', user_id) ranking_list = mysql_util.select_all(""" select supporter_id, count(distinct(date(pay_time))) as c from `order` where pro_id=%s group by supporter_id order by c desc; """, (pro_id,)) cur_rank = 0 for temp_id, days in ranking_list: cur_rank += 1 if temp_id == user_id: return cur_rank, days return -1, -1
def created(modian_id): """ 是否创建人物,以摩点id判断 :param modian_id: 摩点id :return: """ my_logger.info('查询人物是否创建,modian_id: %s' % modian_id) rst = mysql_util.select_one( """ SELECT * FROM `t_character` WHERE modian_id=%s """, (modian_id, )) my_logger.debug(type(rst)) my_logger.debug(rst) # my_logger.debug('rst: %s' % rst) if rst and len(rst) > 0: return True, Character(modian_id, str(rst[1], encoding='utf-8'), rst[2], rst[3], rst[4], rst[5], rst[6]) else: return False, None
def query_project_orders(self, modian_entity, page=1, page_size=20): """ 查询项目订单(bs4版本) :param page_size: :param page: :param modian_entity: :return: """ my_logger.info('查询项目订单, pro_id: %s', modian_entity.pro_id) api = 'https://zhongchou.modian.com/comment/ajax_comments?jsonpcallback=jQuery1_1&post_id={}&pro_class={}&page={}&page_size={}&_=2'.format( modian_entity.post_id, modian_entity.pro_class, page, page_size) r = self.session.get(api, headers=self.modian_header()).text r = r[40: -2] order_html = json.loads(r, encoding='utf-8')['html'] soup = BeautifulSoup(order_html, 'lxml') # print(soup.prettify()) # 对评论列表进行处理 comment_list = soup.find_all(name='li') return comment_list
def get_current_and_target(self, group_account_entity): """ 查询当前项目情况 :param group_account_entity: :return: """ my_logger.info('获取当前进度和总额: pro_id: %s', group_account_entity.group_account_id) api = 'https://groupaccount.tenpay.com/fcgi-bin/grp_qry_group_info.fcgi' data = {"group_account_id": group_account_entity.group_account_id} r = self.session.post(api, data=data, headers=self.weixin_header()).json() if int(r['retcode']) == 0: name = r['name'] current = float(r['balance']) / 100 user_num = r['user_num'] my_logger.info('支持人数: %s, 当前进度: %s', user_num, current) return name, current, user_num else: raise RuntimeError('获取项目筹款结果查询失败')
def get_project_profiles(self, modian_entity): """ 获取集资项目基本资料 :param modian_entity: :return: """ my_logger.info('获取集资项目基本资料, 摩点id: {}'.format(modian_entity.pro_id)) url = 'https://zhongchou.modian.com/realtime/get_simple_product?jsonpcallback=jQuery1_1&ids={}&if_all=1&_=2'.format( modian_entity.pro_id) rsp = self.session.get(url, headers=self.modian_header()).text # 中间结果是个json字符串,需要把头尾过滤掉 rsp = rsp[41: -3] my_logger.info('返回结果: {}'.format(rsp)) project_profile_json = json.loads(rsp, encoding='utf-8') modian_entity.pro_class = project_profile_json['pro_class'] modian_entity.target = project_profile_json['goal'] modian_entity.current = project_profile_json['backer_money'] modian_entity.support_num = project_profile_json['backer_count'] modian_entity.post_id = project_profile_json['moxi_post_id'] modian_entity.title = project_profile_json['name'] return modian_entity.target, modian_entity.current, modian_entity.title, modian_entity.support_num
def evolution(self, raw_list, user_id, pay_time): """ 进化(吞噬) :param raw_list: 原材料,只能为同等级的材料 :return: """ if (not raw_list) or len(raw_list) == 0: logger.exception('原材料为空!') raise RuntimeError('原材料列表为空') raw_material_level = raw_list[0].level if raw_material_level + 1 not in self.cards.keys(): logger.info('已经是最高级的卡牌,不能合成') return None logger.info('删除原材料') # 删除原材料 for raw_material in raw_list: mysql_util.query(""" UPDATE `draw_record` SET is_valid=0 WHERE id=%s """, (raw_material.id,)) # 从高1级的卡中获得一张 new_card = util.choice(self.cards[raw_material_level + 1]) logger.debug('合成的新卡: %s' % new_card) mysql_util.query(""" INSERT INTO `draw_record` (`supporter_id`, `card_id`, `draw_time`, `is_valid`) VALUES (%s, %s, %s, %s) """, (user_id, new_card.id, pay_time, 1)) logger.info('合卡完成')