def get_data(self): """FQ5課金ユーザ. """ # 1日のDate. s_time = DateTimeUtil.strToDateTime(self.date.strftime("%Y%m01"), "%Y%m%d") # 集計終了時間. e_time = DateTimeUtil.toBaseTime(self.date, 23, 59, 59) # 対象のガチャ. filters = { 'consumetype__in': Defines.GachaConsumeType.PAYMENT_TYPES, } gachamasterlist = GachaMaster.fetchValues(filters=filters, order_by='id', using=backup_db) model_mgr = ModelRequestMgr() result = [] for gachamaster in gachamasterlist: if gachamaster.schedule: # 期間チェック. master = model_mgr.get_model(ScheduleMaster, gachamaster.schedule, using=backup_db) if master and ((master.stime <= master.etime <= s_time) or (e_time < master.stime <= master.etime)): # 期間外. continue # FQ5UU. cnt = FQ5PaymentSet.countByRange(s_time, e_time, gachamaster.id) result.append((gachamaster.id, cnt)) return result
def get_data(self): """ユーザごとのガチャデータ. """ # 7日前. s_time = DateTimeUtil.toBaseTime(self.date - datetime.timedelta(days=7), 0) e_time = self.date # 過去1週間以内にログインしたユーザー. str_uidlist = WeeklyLoginSet.getUserIdListByRange(s_time, e_time) # 対象のガチャ. filters = { 'consumetype__in' : Defines.GachaConsumeType.PAYMENT_TYPES, } gachamasterlist = GachaMaster.fetchValues(filters=filters, order_by='id', using=backup_db) model_mgr = ModelRequestMgr() def checkSchedule(gachamaster): if gachamaster.schedule: # 期間チェック. master = model_mgr.get_model(ScheduleMaster, gachamaster.schedule, using=backup_db) if master and ((master.stime <= master.etime <= s_time) or (e_time < master.stime <= master.etime)): # 期間外. return False return True midlist = [gachamaster.id for gachamaster in gachamasterlist if checkSchedule(gachamaster)] self.__midlist = midlist redisdb = GachaLastStepSortSet.getDB() result = [] if midlist: for str_uid in str_uidlist: if not str_uid or not str(str_uid).isdigit(): continue uid = int(str_uid) tmp_model_mgr = ModelRequestMgr() idlist = [GachaPlayCount.makeID(uid, mid) for mid in midlist] # 回転数. countdict = BackendApi.get_model_dict(tmp_model_mgr, GachaPlayCount, idlist, using=backup_db, key=lambda x:x.mid) # 課金額. paydict = BackendApi.get_model_dict(tmp_model_mgr, GachaConsumePoint, idlist, using=backup_db, key=lambda x:x.mid) for mid in midlist: if not countdict.get(mid): continue cnt = countdict[mid].cnttotal pay = paydict[mid].point if paydict.get(mid) else 0 step = redisdb.zscore(GachaLastStepSortSet.makeKey(self.date, mid), uid) or 0 result.append((uid, mid, cnt, pay, step)) return result
def get_data(self): # 直近2週間で取ってきてみる. DAYS = 14 date_from = self.date - datetime.timedelta(days=DAYS) date_to = OSAUtil.get_now() # ガチャのマスターデータ. gachamaster_dict = dict([(master.id, master) for master in GachaMaster.fetchValues( fetch_deleted=True, using=backup_db)]) # カードのマスターデータ. cardmaster_dict = dict([(master.id, master) for master in CardMaster.fetchValues( fetch_deleted=True, using=backup_db)]) # 対象のユーザー. uidlist = PaymentGachaLastPlayTimeSortedSet.fetchByDate( date_from, date_to) result = [[ 'ユーザID', '生涯課金額', 'ガチャ1', 'ガチャを回した時のリーダー1', 'ガチャ2', 'ガチャを回した時のリーダー2', 'ガチャ3', 'ガチャを回した時のリーダー3' ]] for uid in uidlist: row = [uid] # 生涯課金額. model = PlayerConsumePoint.getByKey(uid, using=backup_db) row.append(model.point_total if model else 0) redisdata = PaymentGachaPlayerLeaderHash.getByUserIDList( [uid]).get(uid) or {} items = list(redisdata.items()) items.sort(key=lambda x: x[1]['date'], reverse=True) for gachaid, data in items: # 引いたガチャ. gachamaster = gachamaster_dict[gachaid] # その時のリーダー. cardmaster = cardmaster_dict[data['card']] row.extend([ u'%s(ID:%d)' % (gachamaster.name, gachamaster.id), u'%s(ID:%d)' % (cardmaster.name, cardmaster.id) ]) result.append(row) return result
def __valid_master(self, master): if not master.is_public: return if GachaMaster.getByKey(master.id) is None: raise ModelEditValidError(u'ガチャが存在しません.master=%d' % master.id) model_mgr = self.getModelMgr() if not isinstance(master.castlist, list): raise ModelEditValidError(u'castlistのJSONが壊れています.master=%d' % master.id) if self.valid_error_num < 10: for record in self.allmasters: if master.id == record.id: self.valid_error_num += 1 raise ModelEditValidError(u'IDが重複しています.id={}'.format( master.id)) # 旧式のデータを新方式に置き換える. castlist = [] for v in master.castlist: if isinstance(v, (int, long)): castlist.append([v, '']) continue elif not isinstance( v, (list, tuple)) or len(v) != 2 or not isinstance( v[0], (int, long)) or not isinstance(v[1], (str, unicode, list)): raise ModelEditValidError( u'castlistは[[マスターID,画像]...]で設定してください.master=%d' % master.id) castlist.append(v) master.castlist = castlist castdict = dict(castlist) if len( BackendApi.get_cardmasters( castdict.keys(), arg_model_mgr=model_mgr).values()) != len( master.castlist): raise ModelEditValidError( u'castlistに重複または存在しないものが含まれています.master=%d' % master.id)
def getGachaMasterList(self, mid): """集計対象のガチャのリストを取得. """ if not mid: return [] model_mgr = self.getModelMgr() master = BackendApi.get_gachamaster(model_mgr, mid, using=settings.DB_READONLY) if master is None: return [] if not master.stepid: return [master] masterlist = GachaMaster.fetchValues(filters={'stepid': master.stepid}, using=settings.DB_READONLY) masterlist.sort(key=lambda x: x.step) return masterlist
def get_special_gachamaster(self, model_mgr, special_gacha_consumetypes, search_start_time, search_end_time): #特定のコンシュームタイプで、ガチャのスケージュールが特定の期間ならそれは特効ガチャのはず。 gachamaster_list = GachaMaster.fetchValues(filters=({ 'consumetype__in': special_gacha_consumetypes }), using=backup_db) special_gachamasters = [] for gachamaster in gachamaster_list: schedule_master = model_mgr.get_model(ScheduleMaster, gachamaster.schedule) if search_start_time.date() <= schedule_master.stime.date( ) and schedule_master.etime.date() <= search_end_time.date(): special_gachamasters.append(gachamaster) if special_gachamasters: return special_gachamasters else: self.putAlertToHtmlParam(u'特効ガチャが見つけられませんでした', AlertCode.INFO) return None
def handle(self, *args, **options): print '================================' print 'copy_img' print '================================' out = args[0] # ガチャのマスターを取得. gachalist = GachaMaster.fetchValues(filters={ 'consumetype__in': Defines.GachaConsumeType.PAYMENT_TYPES, 'schedule__gt': 0 }, using=backup_db) # ガチャのボックスデータを作成. read_boxids = [] card_dict = {} for gacha in gachalist: if gacha.boxid in read_boxids: continue schedule = ScheduleMaster.getByKey(gacha.schedule, using=backup_db) name = u'%s(%s-%s)' % (gacha.name, schedule.stime.strftime('%m/%d'), schedule.stime.strftime('%m/%d')) boxmaster = GachaBoxMaster.getByKey(gacha.boxid, using=backup_db) gachamasterset = GachaMasterSet(gacha, boxmaster, schedule) gachabox = GachaBox(gachamasterset, GachaPlayData.makeInstance( GachaPlayData.makeID(0, gacha.boxid)), blank=True) grouplist = GachaGroupMaster.getByKey(gachabox.get_group_id_list(), using=backup_db) # カードIDとガチャのIDをひもづける. for group in grouplist: if 1 < len(group.table): continue cardid = group.table[0]['id'] arr = card_dict[cardid] = card_dict.get(cardid) or [] arr.append(name) # カードマスターを取得. cardmasterlist = CardMaster.getByKey(card_dict.keys(), order_by='id', using=backup_db) # CSVを作成. rows = [] def makeRow(row): arr = [] for v in row: s = u'%s' % v s = s.replace('"', '""') arr.append(u'"%s"' % s) return u','.join(arr) for cardmaster in cardmasterlist: cardsortmaster = CardSortMaster.getByKey(cardmaster.id, using=backup_db) row = [ cardmaster.id, cardmaster.name, Defines.Rarity.NAMES[cardsortmaster.rare], Defines.CharacterType.NAMES[cardsortmaster.ctype] ] row.extend(card_dict[cardmaster.id]) str_row = makeRow(row) print str_row rows.append(str_row) csv_data = StrUtil.to_s(u'\n'.join(rows), dest_enc='shift-jis') f = None try: f = open(out, "w") f.write(csv_data) f.close() except: if f: f.close() f = None raise print '================================' print 'output:%s' % out print 'all done..'
def handle(self, *args, **options): print '================================' print 'close_rankinggacha' print '================================' model_mgr = ModelRequestMgr() now = OSAUtil.get_now() # メンテナンス確認. appconfig = BackendApi.get_appconfig(model_mgr) if not appconfig.is_maintenance(): print u'メンテナンスモードにしてください' return print 'check maintenance...OK' print '================================' print 'check master' group = int(args[0]) master_list = BackendApi.get_rankinggacha_master_by_group( model_mgr, group, using=settings.DB_READONLY) if not master_list: print u'ランキングガチャではありません' return boxidlist = [master.id for master in master_list] master_dict = dict([(master.id, master) for master in master_list]) gachamaster_list = GachaMaster.fetchValues( filters={'boxid__in': boxidlist}, using=settings.DB_READONLY) gachamaster_list = [ gachamaster.id for gachamaster in gachamaster_list if BackendApi.check_schedule(model_mgr, gachamaster.schedule, using=settings.DB_READONLY, now=now) ] if gachamaster_list: print u'ガチャが開いています.id=%s' % gachamaster_list return print 'check master...OK' print '================================' print 'update ranking:start' # ランキングを更新. for master in master_list: offset = 0 limit = 1000 flag_support_totalranking = master.is_support_totalranking while True: recordlist = RankingGachaScore.fetchValues( filters={'mid': master.id}, limit=limit, offset=offset) pipe = RankingGachaSingleRanking.getDB().pipeline() for record in recordlist: RankingGachaSingleRanking.create(master.id, record.uid, record.single).save(pipe) if flag_support_totalranking: RankingGachaTotalRanking.create( master.id, record.uid, record.total).save(pipe) pipe.execute() if len(recordlist) < limit: break offset += limit print 'update ranking:end' print '================================' print 'send ranking prizes:start' for master in master_list: boxid = master.id close_model = RankingGachaClose.getByKey(boxid) if close_model is None: close_model = RankingGachaClose.makeInstance(boxid) close_model.insert() print 'start...single' close_model = self.__send_prize(model_mgr, master.singleprizes, master.singleprize_text, close_model, 'prize_flag_single', RankingGachaSingleRanking) if flag_support_totalranking: print 'start...total' close_model = self.__send_prize(model_mgr, master.totalprizes, master.totalprize_text, close_model, 'prize_flag_total', RankingGachaTotalRanking) print '================================' print 'send whole prizes:start' # 勝利したBOX. wholedata_list = RankingGachaWholeData.getByKey(boxidlist) arr = [(wholedata.id, wholedata.point) for wholedata in wholedata_list] arr.sort(key=lambda x: x[1], reverse=True) winner = [] point_max = None for boxid, point in arr: if point_max is not None and point < point_max: break elif point < 1: break winner.append(boxid) point_max = point print 'winner:%s' % winner queuelist = RankingGachaWholePrizeQueue.fetchValues( filters={'boxid__in': boxidlist}) queuelist.sort(key=lambda x: x.id) boxidlist.sort() close_model_boxid = boxidlist[0] close_model = RankingGachaClose.getByKey(close_model_boxid) uid_max = Player.max_value('id') for uid in xrange(close_model.prize_flag_whole + 1, uid_max + 1): # 全員について検証. data = RankingGachaWholePrizeData.getByKey(uid) if data is None: # 未プレイ. continue # スコア情報. firstpoint_dict = dict([ (scoredata.mid, scoredata.firstpoint) for scoredata in RankingGachaScore.getByKey([ RankingGachaScore.makeID(uid, boxid) for boxid in boxidlist ]) ]) # 未受け取り分. queuelist_not_received = [ queue for queue in queuelist if data.queueid < queue.id and firstpoint_dict.get(queue.boxid) and firstpoint_dict[queue.boxid] <= queue.point ] # 勝利判定. win_boxidlist = list(set(firstpoint_dict.keys()) & set(winner)) if not (queuelist_not_received or win_boxidlist): # 未受け取りの報酬が無い 且つ 敗北. continue try: model_mgr, close_model = db_util.run_in_transaction( self.__tr_send_wholeprize, uid, queuelist_not_received, master_dict, win_boxidlist, close_model_boxid) model_mgr.write_end() print '%d...receive' % uid except CabaretError, err: if err.code == CabaretError.Code.ALREADY_RECEIVED: # 受取済みのキューを指定していた. model_mgr, close_model = db_util.run_in_transaction( self.__tr_send_wholeprize, uid, [], master_dict, win_boxidlist, close_model_boxid) model_mgr.write_end() print '%d...already' % uid else: raise
def handle(self, *args, **options): print '================================' print 'init_rankinggacha' print '================================' model_mgr = ModelRequestMgr() now = OSAUtil.get_now() # メンテナンス確認. appconfig = BackendApi.get_appconfig(model_mgr) if not appconfig.is_maintenance(): print u'メンテナンスモードにしてください' return print 'check maintenance...OK' print '================================' print 'check master' group = int(args[0]) master_list = BackendApi.get_rankinggacha_master_by_group( model_mgr, group, using=settings.DB_READONLY) if not master_list: print u'ランキングガチャではありません' return boxidlist = [master.id for master in master_list] gachamaster_list = GachaMaster.fetchValues( filters={'boxid__in': boxidlist}, using=settings.DB_READONLY) gachamaster_list = [ gachamaster.id for gachamaster in gachamaster_list if BackendApi.check_schedule(model_mgr, gachamaster.schedule, using=settings.DB_READONLY, now=now) ] if gachamaster_list: print u'ガチャが開いています.id=%s' % gachamaster_list return print 'check master...OK' print '================================' print 'check flag' close_model_list = RankingGachaClose.getByKey(boxidlist) if len(close_model_list) != len(boxidlist): print u'未集計です.close_rankinggachaを実行してください' return print 'check flag...OK' print '================================' print 'delete redis' pipe = RankingGachaSingleRanking.getDB().pipeline() for boxid in boxidlist: pipe.delete(RankingGachaSingleRanking.makeKey(boxid), RankingGachaTotalRanking.makeKey(boxid)) pipe.execute() print '================================' print 'delete mysql' limit = 500 while True: recordlist = RankingGachaScore.fetchValues( filters={'mid__in': boxidlist}, limit=limit) def tr(): model_mgr = ModelRequestMgr() for record in recordlist: model_mgr.set_delete(record) model_mgr.write_all() return model_mgr db_util.run_in_transaction(tr).write_end() if len(recordlist) < limit: break delete_target_model_cls_list = ( UserLogRankingGachaWholePrize, RankingGachaPlayLog, ) def tr_delete_common(): for model_cls in delete_target_model_cls_list: tablename = model_cls.get_tablename() query_string = "truncate table `%s`;" % tablename Query.execute_update(query_string, [], False) print 'delete...%s' % tablename model_mgr = ModelRequestMgr() for close_model in close_model_list: model_mgr.set_delete(close_model) for wholedata in RankingGachaWholeData.getByKey(boxidlist): model_mgr.set_delete(wholedata) for queue in RankingGachaWholePrizeQueue.fetchValues( filters={'boxid__in': boxidlist}): model_mgr.set_delete(queue) model_mgr.write_all() return model_mgr db_util.run_in_transaction(tr_delete_common).write_end() RankingGachaWholePrizeQueueIdSet.flush() print '================================' print 'all done..'