class Command(BaseCommand): """バトルイベント終了処理. """ def handle(self, *args, **options): print '================================' print 'close_battleevent' print '================================' now = OSAUtil.get_now() model_mgr = ModelRequestMgr() redisdb = RedisModel.getDB() config = BackendApi.get_current_battleeventconfig(model_mgr) eventmaster = BackendApi.get_battleevent_master(model_mgr, config.mid) if eventmaster is None: print u'イベントが設定されていません' return print 'check eventmaster...OK' # イベント設定. if now < config.endtime: print u'イベントがまだ終了していません' return print 'check event endtime...OK' # メンテナンス確認. appconfig = BackendApi.get_appconfig(model_mgr) if not appconfig.is_maintenance(): print u'メンテナンスモードにしてください' return print 'check maintenance...OK' rankmaster_dict = dict([ (master.id, master) for master in BattleEventRankMaster.fetchValues( filters={'eventid': config.mid}, fetch_deleted=True, using=settings.DB_READONLY) ]) print '================================' print 'send groupranking prizes.' # 未受け取りのグループ内ランキング報酬を配布. BackendApi.battleevent_send_groupranking_prizes(eventmaster) print '================================' print 'reset daily ranking.' logintime_today = DateTimeUtil.toLoginTime(now) keylist = [ BattleEventDailyRanking.makeKey( BattleEventDailyRanking.makeRankingId(logintime_today, config.mid, rankmaster.rank)) for rankmaster in rankmaster_dict.values() ] if keylist: redisdb.delete(*keylist) offset = 0 LIMIT = 500 while True: grouplist = BattleEventGroupLog.fetchValues(filters={ 'eventid': config.mid, 'cdate': datetime.date(logintime_today.year, logintime_today.month, logintime_today.day) }, order_by='id', offset=offset, limit=LIMIT) if not grouplist: break offset += LIMIT for group in grouplist: rankmaster = rankmaster_dict.get(group.rankid) rankingid = BattleEventDailyRanking.makeRankingId( logintime_today, config.mid, rankmaster.rank) pipe = redisdb.pipeline() for userdata in group.userdata: if 0 < userdata.point: BattleEventDailyRanking.create( rankingid, userdata.uid, userdata.point).save(pipe) pipe.execute() print '================================' print 'close group.' while True: grouplist = BattleEventGroup.fetchValues( filters={'eventid': config.mid}, order_by='cdate', limit=500) if not grouplist: break for group in grouplist: eventrankmaster = rankmaster_dict[group.rankid] model_mgr = db_util.run_in_transaction(Command.tr_close, eventmaster, eventrankmaster, group.id, now) model_mgr.write_end() print 'close %s' % group.id print '================================' print 'send daily ranking prizes.' date_today = datetime.date(logintime_today.year, logintime_today.month, logintime_today.day) rankmasterlist = rankmaster_dict.values() rankmasterlist.sort(key=lambda x: x.rank) for rankmaster in rankmasterlist: # 報酬を渡す. rankingid = BattleEventDailyRanking.makeRankingId( logintime_today, config.mid, rankmaster.rank) rankingprizes = rankmaster.rankingprizes textid = rankmaster.rankingprize_text for idx, data in enumerate(rankingprizes): prize_flag = (rankmaster.rank << 16) + idx pre_prize_flag = config.getDailyPrizeFlag(date_today) if prize_flag < pre_prize_flag: print 'skip...%d' % idx continue prizeidlist = data['prize'] rank_min = data['rank_min'] rank_max = data['rank_max'] prizelist = BackendApi.get_prizelist(model_mgr, prizeidlist) uidlist = [] for rank in xrange(rank_min, rank_max + 1): data = BattleEventDailyRanking.fetchByRank(rankingid, rank, zero=False) dic = dict(data) uidlist.extend(dic.keys()) if len(set(uidlist)) != len(uidlist): raise CabaretError(u'ランキング取得がなにかおかしい..%d' % rank) def tr(): model_mgr = ModelRequestMgr() config = CurrentBattleEventConfig.getByKeyForUpdate( CurrentBattleEventConfig.SINGLE_ID) if config.getDailyPrizeFlag(date_today) != pre_prize_flag: raise CabaretError(u'整合が取れていないので終了します') for uid in uidlist: BackendApi.tr_add_prize(model_mgr, uid, prizelist, textid) config.daily_prize_flag = prize_flag + 1 config.daily_prize_date = date_today model_mgr.set_save(config) model_mgr.write_all() return model_mgr, config try: tmp_model_mgr, wrote_config = db_util.run_in_transaction( tr) except CabaretError, err: print 'error...%s' % err.value return print 'save end...%d' % idx tmp_model_mgr.write_end() print 'cache end...%d' % idx config = wrote_config print '================================' print 'save rank uid set.' for rankmaster in rankmaster_dict.values(): BackendApi.save_battleevent_rankuidset(rankmaster.eventid, rankmaster.rank) print '================================' print 'update ranking:start' # ランキングを更新. offset = 0 limit = 1000 while True: recordlist = BattleEventScore.fetchValues( ['uid', 'point_total'], filters={'mid': config.mid}, limit=limit, offset=offset) pipe = BattleEventRanking.getDB().pipeline() for record in recordlist: BattleEventRanking.create(config.mid, record.uid, record.point_total).save(pipe) if BackendApi.check_battleevent_beginer( ModelRequestMgr(), record.uid, eventmaster, config, now, using=settings.DB_READONLY): BattleEventRankingBeginer.create( config.mid, record.uid, record.point_total).save(pipe) pipe.execute() if len(recordlist) < limit: break offset += limit print 'update ranking:end' # 報酬を渡す. def sendRankingPrize(ranking_cls, rankingprizes, textid, att_prize_flag): for idx, data in enumerate(rankingprizes): if idx < getattr(config, att_prize_flag): print 'skip...%d' % idx continue prizeidlist = data['prize'] rank_min = data['rank_min'] rank_max = data['rank_max'] prizelist = BackendApi.get_prizelist(model_mgr, prizeidlist) uidlist = [] for rank in xrange(rank_min, rank_max + 1): data = ranking_cls.fetchByRank(eventmaster.id, rank, zero=False) dic = dict(data) uidlist.extend(dic.keys()) if len(set(uidlist)) != len(uidlist): raise CabaretError(u'ランキング取得がなにかおかしい..%d' % rank) def tr(): model_mgr = ModelRequestMgr() config = CurrentBattleEventConfig.getByKeyForUpdate( CurrentBattleEventConfig.SINGLE_ID) if getattr(config, att_prize_flag) != idx: raise CabaretError(u'整合が取れていないので終了します') for uid in uidlist: BackendApi.tr_add_prize(model_mgr, uid, prizelist, textid) setattr(config, att_prize_flag, idx + 1) model_mgr.set_save(config) model_mgr.write_all() return model_mgr, config try: tmp_model_mgr, wrote_config = db_util.run_in_transaction( tr) except CabaretError, err: print 'error...%s' % err.value return print 'save end...%d' % idx tmp_model_mgr.write_end() print 'cache end...%d' % idx setattr(config, att_prize_flag, getattr(wrote_config, att_prize_flag))
def process(self): args = self.getUrlArgs('/battleeventranking/') eventid = args.getInt(0) view_myrank = args.getInt(1) == 1 model_mgr = self.getModelMgr() eventmaster = None if eventid: eventmaster = BackendApi.get_battleevent_master( model_mgr, eventid, using=settings.DB_READONLY) if eventmaster is None: if settings_sub.IS_LOCAL: raise CabaretError(u'引数がおかしい') self.redirectToTop() return # 開催中判定. cur_eventmaster = self.getCurrentBattleEvent(quiet=True) if cur_eventmaster and cur_eventmaster.id == eventid: is_opened = True if not self.checkBattleEventUser(do_check_battle_open=False, do_check_regist=False, do_check_emergency=False): return else: is_opened = False self.html_param['is_opened'] = is_opened # イベント情報. self.html_param['battleevent'] = Objects.battleevent(self, eventmaster) self.putEventTopic(eventid, 'ranking') v_player = self.getViewerPlayer() uid = v_player.id url_battleevent_ranking = UrlMaker.battleevent_ranking(eventid, False) url_battleevent_myrank = UrlMaker.battleevent_ranking(eventid, True) # 初心者判定. is_beginer = BackendApi.check_battleevent_beginer( model_mgr, uid, eventmaster, using=settings.DB_READONLY) self.html_param['is_beginer'] = is_beginer # ランキング. view_beginer = self.request.get(Defines.URLQUERY_BEGINER) == "1" if view_beginer and not is_beginer: view_myrank = False self.putRanking(uid, eventid, view_myrank, url_battleevent_ranking, url_battleevent_myrank, view_beginer=view_beginer) if eventmaster.is_goukon: self.writeAppHtml('gcevent/ranking') else: self.writeAppHtml('btevent/ranking')
def process(self): self.__execute_end_worklist = [] model_mgr = self.getModelMgr() config = BackendApi.get_current_battleeventconfig( model_mgr, using=settings.DB_READONLY) args = self.getUrlArgs('/battleeventtop/') eventid = str(args.get(0)) eventmaster = None if eventid and eventid.isdigit(): eventid = int(eventid) elif config: eventid = config.mid if eventid: eventmaster = BackendApi.get_battleevent_master( model_mgr, eventid, using=settings.DB_READONLY) if eventmaster is None: raise CabaretError(u'Event Closed.', CabaretError.Code.EVENT_CLOSED) return self.__eventmaster = eventmaster eventid = eventmaster.id cur_eventmaster = self.getCurrentBattleEvent(quiet=True) v_player = self.getViewerPlayer() uid = v_player.id is_open = cur_eventmaster and eventid == cur_eventmaster.id self.setFromPage(Defines.FromPages.BATTLEEVENT, eventid) if is_open: # 開催中. if self.isBattleOpen(): # バトルが開いている時. self.procOpened() else: # バトルが閉じている時. self.procBattleClosed() # イベント参加KPI保存. BackendApi.save_kpi_battleevent_join(uid, self.is_pc) else: self.procClosed() if self.response.isEnd: return self.html_param['player'] = Objects.player(self, v_player) # イベント情報. battleevent = Objects.battleevent(self, eventmaster) self.html_param['battleevent'] = battleevent # バトルチケットの使用期限 if is_open: self.html_param[ 'battle_ticket_expiry_date'] = self.get_battle_ticket_expiry_date( config.ticket_endtime) BackendApi.check_battleevent_piececollection_userdata_and_create( model_mgr, uid, eventid) self.html_param['allrarity_piece'] = self.create_piece_image_paths( uid, eventid) # トピック. self.putEventTopic(eventid) # バトル履歴. if not eventmaster.is_goukon: loglist = BackendApi.get_battleevent_battlelog_list( model_mgr, uid, limit=1, using=settings.DB_READONLY) if loglist: func_battleloginfo = BackendApi.make_battleevent_battleloginfo( self, loglist, do_execute=False) if func_battleloginfo: def put_battleloginfo(): self.html_param['battleloglist'] = func_battleloginfo() self.addExecuteApiWork(put_battleloginfo) # バトル履歴のリンク. self.html_param['url_battleevent_battlelog'] = self.makeAppLinkUrl( UrlMaker.battleevent_loglist()) tradeshop_urlparam = OSAUtil.addQuery( UrlMaker.trade(), Defines.URLQUERY_CTYPE, Defines.GachaConsumeType.GachaTopTopic.TICKET) self.html_param['url_battleticket_trade'] = self.makeAppLinkUrl( tradeshop_urlparam) battleticket = BackendApi.get_additional_gachaticket_nums( model_mgr, v_player.id, [Defines.GachaConsumeType.GachaTicketType.BATTLE_TICKET], using=settings.DB_READONLY) if battleticket: battle_ticket_num = battleticket[ Defines.GachaConsumeType.GachaTicketType.BATTLE_TICKET].num else: battle_ticket_num = 0 self.html_param['battleticket'] = { 'name': Defines.GachaConsumeType.NAMES[ Defines.GachaConsumeType.BATTLE_TICKET], 'num': battle_ticket_num, 'unit': Defines.ItemType.UNIT[Defines.ItemType.ADDITIONAL_GACHATICKET], } # グループ履歴のリンク. self.html_param['url_battleevent_grouplog'] = self.makeAppLinkUrl( UrlMaker.battleevent_grouploglist(eventid)) if not self.html_param.has_key('battleevent_rank'): # ランク情報がないのでデフォルトのを設定. if config.isFirstDay(): rankmaster = BackendApi.get_battleevent_rankmaster( model_mgr, eventid, eventmaster.rankstart, using=settings.DB_READONLY) else: rankmaster = BackendApi.get_battleevent_rankmaster( model_mgr, eventid, eventmaster.rankbeginer, using=settings.DB_READONLY) self.html_param['battleevent_rank'] = Objects.battleevent_rank( self, None, rankmaster, None) self.executeApiWithWork() # 初心者フラグ. is_beginer = BackendApi.check_battleevent_beginer( model_mgr, uid, eventmaster, config, using=settings.DB_READONLY) self.html_param['is_beginer'] = is_beginer # ユーザーデータのチェック, カウントの取得 user_cvictory_count = self.check_user_continue_victory_data( uid, eventid) self.put_user_continue_victory_data(user_cvictory_count) # ランキング. view_myrank = False view_beginer = self.request.get(Defines.URLQUERY_BEGINER) == "1" if not view_beginer or is_beginer: view_myrank = self.request.get(Defines.URLQUERY_FLAG) == "1" url_ranking = OSAUtil.addQuery(UrlMaker.battleevent_top(eventid), Defines.URLQUERY_FLAG, "0") url_myrank = OSAUtil.addQuery(UrlMaker.battleevent_top(eventid), Defines.URLQUERY_FLAG, "1") self.putRanking(uid, eventid, view_myrank, url_ranking, url_myrank, view_beginer=view_beginer) if eventmaster.is_goukon: self.writeAppHtml('gcevent/top') else: self.writeAppHtml('btevent/top')