Beispiel #1
0
 def get(cls):
     redisdb = RedisModel.getDB()
     userdict = redisdb.get(cls.KEY)
     if userdict:
         return cPickle.loads(userdict)
     else:
         return {}
Beispiel #2
0
 def write_end():
     redisdb = RedisModel.getDB()
     pipe = redisdb.pipeline()
     for weekly_model in weekly_data:
         CabaClubRanking.create('lastweek', weekly_model.uid,
                                weekly_model.proceeds).save(pipe)
     pipe.execute()
    def handle(self, *args, **options):
        redisdb = RedisModel.getDB()

        uid_max = Player.max_value('id')
        for i in xrange(0, uid_max):
            uid = uid_max - i

            changed = False
            for state in Defines.FriendState.NAMES.keys():
                friendlist = Friend.fetchValues(filters={
                    'uid': uid,
                    'state': state
                })
                cur_num = BackendApi._get_friend_num(uid, state)
                if cur_num == len(friendlist):
                    continue

                pipe = redisdb.pipeline()
                pipe.delete(FriendListSet.makeKey(uid, state))
                for friend in friendlist:
                    FriendListSet.create(uid, friend.fid, state,
                                         friend.ctime).save(pipe)
                pipe.execute()
                changed = True
            if changed:
                print '%s' % uid

        print '================================'
        print 'all done'
Beispiel #4
0
    def handle(self, *args, **options):

        starttime = OSAUtil.get_now()

        print '================================'
        print 'check_present_timeout'
        print '================================'

        now = OSAUtil.get_now() - datetime.timedelta(seconds=60)  # 1分間猶予をもたせる.
        presentlist = list(
            Present.all(using=backup_db).filter(limittime__lt=now).values(
                'id', 'toid', 'itype').fetch(100000))

        print 'delete target num:%d' % len(presentlist)
        if len(presentlist) == 0:
            # 削除対象がない.
            print '---------------'
            print 'end...'
            return

        print 'delete...start'
        # redisから削除.
        redisdb = RedisModel.getDB()
        pipe = redisdb.pipeline()

        LIMIT = 500
        presentidlist = []
        for data in presentlist:
            BackendApi.remove_present(data['toid'], data['id'], data['itype'],
                                      pipe)
            presentidlist.append(data['id'])
            if LIMIT <= len(presentidlist):
                print 'delete...redis'
                pipe.execute()
                pipe = redisdb.pipeline()
                print 'delete...mysql'
                Present.all().filter(id__in=presentidlist).delete()
                presentidlist = []
                print 'delete...restart'

        if presentidlist:
            print 'delete...redis'
            pipe.execute()
            print 'delete...mysql'
            Present.all().filter(id__in=presentidlist).delete()

        print 'delete...end'

        print '---------------'
        print 'all done.'

        diff = OSAUtil.get_now() - starttime
        sec = diff.days * 86400 + diff.seconds
        print 'time %d.%06d' % (sec, diff.microseconds)
Beispiel #5
0
 def update(self):
     redisdb = RedisModel.getDB()
     userdict = self.get()
     data = {
         self.uid: {
             'deckcost': self.deckcost,
             'ltime': self.ltime
         }
     }
     userdict.update(data)
     redisdb.set(self.KEY, cPickle.dumps(userdict))
     redisdb.expire(self.KEY, 21600)
Beispiel #6
0
    def handle(self, *args, **options):

        uid_max = Player.max_value('id')

        now = OSAUtil.get_now()
        bordertime = now - datetime.timedelta(days=30)

        redisdb = RedisModel.getDB()
        for i in xrange(0, uid_max):
            uid = uid_max - i
            player_login = PlayerLogin.getByKey(uid,
                                                using=settings.DB_READONLY)
            if player_login is None or bordertime <= player_login.ltime:
                continue

            pipe = redisdb.pipeline()

            pipe.delete(UserCardIdListSet.makeKey(uid))
            pipe.delete(CardKindListSet.makeKey(uid))
            pipe.delete(EvolutionAlbumHkLevelListSet.makeKey(uid))

            FriendAcceptNum.create(uid).delete(pipe)

            FreeGachaLastTime.create(uid).delete(pipe)

            RaidHelpFriendData.create(uid).delete(pipe)
            RaidCallFriendTime.create(uid).delete(pipe)

            for topic in Defines.PresentTopic.RANGE:
                pipe.delete(PresentIdListSet.makeKey(uid, topic))

            for treasuretype in Defines.TreasureType.NAMES.keys():
                pipe.delete(TreasureListSet.makeKey(uid, treasuretype))

            pipe.delete(PlayerLogListSet.makeKey(uid))

            LastViewArea.create(uid).delete(pipe)

            pipe.delete(RaidHelpSet.makeKey(uid))

            pipe.delete(RaidLogNotificationSet.makeKey(uid))

            PlayerConfigData.create(uid).delete(pipe)

            pipe.execute()

            print '%s..DELETE' % uid

        print '================================'
        print 'all done'
Beispiel #7
0
 def checkAggregateEnd(self, targettime):
     redisdb = RedisModel.getDB()
     ALREADY_KEY = "battleevent_aggregate:end"
     
     # 対象の日付(月).
     logintime = DateTimeUtil.toLoginTime(targettime)
     cdate = datetime.date(logintime.year, logintime.month, logintime.day)
     
     str_cdate_pre = redisdb.get(ALREADY_KEY)
     if str_cdate_pre:
         dt = DateTimeUtil.strToDateTime(str_cdate_pre, "%Y%m%d")
         cdate_pre = datetime.date(dt.year, dt.month, dt.day)
         if cdate_pre == cdate:
             # 集計が正常に終わっている.
             return True
     return False
Beispiel #8
0
    def old_delete_record(self, treasure_type):

        now = OSAUtil.get_now() - datetime.timedelta(seconds=60)  # 1分間猶予をもたせる.

        model_cls = TreasureUtil.get_model_cls(treasure_type)
        treasurelist = list(
            model_cls.all(using=backup_db).filter(etime__lt=now).values(
                'id', 'uid').fetch(30000))
        print 'delete target num:%d' % len(treasurelist)

        if len(treasurelist) == 0:
            # 削除対象がない.
            print '---------------'
            print 'end...'
            return

        print 'delete...start'
        # redisから削除.
        redisdb = RedisModel.getDB()
        pipe = redisdb.pipeline()

        LIMIT = 500
        treasureidlist = []
        for data in treasurelist:
            BackendApi.remove_treasure(data['uid'], treasure_type, data['id'],
                                       pipe)
            treasureidlist.append(data['id'])

            if LIMIT <= len(treasureidlist):
                print 'delete from redis'
                pipe.execute()
                pipe = redisdb.pipeline()

                print 'delete from mysql'
                model_cls.all().filter(id__in=treasureidlist).delete()
                treasureidlist = []

        if treasureidlist:
            print 'delete from redis'
            pipe.execute()
            print 'delete from mysql'
            model_cls.all().filter(id__in=treasureidlist).delete()

        print 'delete...end'

        print '---------------'
        print 'all done.'
Beispiel #9
0
 def fetch_by_cost(cls, cost, lower=0, upper=0, limit=100, ignorelist=None):
     ignorelist = ignorelist or []
     redisdb = RedisModel.getDB()
     datalist = list(redisdb.zrangebyscore(cls.KEY, cost, cost, withscores=True))
     not_enough = limit - len(datalist)
     if 0 < not_enough:
         if 1 < cost and 0 < lower:
             datalist.extend(redisdb.zrevrangebyscore(cls.KEY, cost-1, max(1, cost-lower), start=0, num=not_enough, withscores=True))
         if 0 < upper:
             datalist.extend(redisdb.zrangebyscore(cls.KEY, cost+1, cost+lower, start=0, num=not_enough, withscores=True))
         datalist.sort(key=lambda x:math.fabs(cost - x[1]))
     dest = []
     for str_uid, _ in datalist:
         uid = cls.value_to_int(str_uid)
         if (not uid) or (uid in ignorelist):
             continue
         dest.append(uid)
         if limit <= len(dest):
             break
     return dest
    def handle(self, *args, **options):

        print '======================================='
        print 'Generate cabaret club user ranking data'
        print '======================================='

        players = Player.fetchValues(using=settings.DB_READONLY)
        rand = AppRandom()
        redisdb = RedisModel.getDB()
        pipe = redisdb.pipeline()
        for player in players:
            sales = rand.getIntN(10000)
            CabaClubRanking.create("currentweek", player.id, sales).save(pipe)
            CabaClubRanking.create("lastweek", player.id,
                                   max(100, sales - 1500)).save(pipe)

        pipe.execute()

        print '================================'
        print 'all done...'
Beispiel #11
0
    def handle(self, *args, **options):

        print '================================'
        print 'reload_presentidlist'
        print '================================'

        uid_max = Player.max_value('id')
        redisdb = RedisModel.getDB()
        pipe = redisdb.pipeline()
        model_mgr = ModelRequestMgr()

        for uid in xrange(1, uid_max + 1):
            BackendApi._save_presentidlist(uid,
                                           model_mgr,
                                           using=settings.DB_READONLY,
                                           pipe=pipe)
            print '%s..end' % uid

        pipe.execute()
        print '================================'
        print 'all done'
Beispiel #12
0
    def setUp(self):
        # DMMID.
        self.__player = self.create_dummy(DummyType.PLAYER)

        model = self.__player.getModel(PlayerFriend)
        model.friendlimit = 8
        model.save()

        def addRequest(v_player, o_player):
            model_mgr = ModelRequestMgr()
            BackendApi.tr_add_friendrequest(model_mgr, v_player, o_player)
            model_mgr.write_all()
            model_mgr.write_end()

        def addFriend(v_player, o_player):
            model_mgr = ModelRequestMgr()
            BackendApi.tr_add_friend(model_mgr, v_player.id, o_player.id)
            model_mgr.write_all()
            model_mgr.write_end()

        redisdb = RedisModel.getDB()
        pipe = redisdb.pipeline()
        for _ in xrange(model.friendlimit):
            player = self.create_dummy(DummyType.PLAYER)

            uid = player.id

            boss = self.create_dummy(DummyType.BOSS_MASTER)
            areamaster = self.create_dummy(DummyType.AREA_MASTER, boss.id)
            logdata = BossWinLog.makeData(uid, areamaster.id)
            logdata.oid = self.__player.id
            logdata.save()

            addRequest(self.__player, player)
            addFriend(player, self.__player)

        pipe.execute()
Beispiel #13
0
 def get(cls, key):
   redisdb = RedisModel.getDB()
   strnum = redisdb.get(cls.REDIS_KEY.format(key))
   if strnum:
     return int(strnum)
   return None
class Command(BaseCommand):
    """ハプニングを全て削除する.
    """
    def handle(self, *args, **options):
        
        model_mgr = ModelRequestMgr()
        starttime = OSAUtil.get_now()
        
        print '================================'
        print 'delete_happening_all'
        print '================================'
        
        # クリア済みで受け取っていないハプニング.
        print '================================'
        print 'check raid:start'
        # クリア済みのレイドを全て終了させる.
        filters = {'state__in':[Defines.HappeningState.BOSS, Defines.HappeningState.CLEAR]}
        num = Happening.count(filters)
        print 'happenings %d' % num
        
        # メンテナンス確認.
        appconfig = BackendApi.get_appconfig(model_mgr)
        if not appconfig.is_maintenance():
            print u'メンテナンスモードにしてください'
            return
        print 'check maintenance...OK'
        
        offset = 0
        LIMIT = 200
        
        def tr_clear(happeningid):
            model_mgr = ModelRequestMgr()
            happening = Happening.getByKeyForUpdate(happeningid)
            raidboss = BackendApi.get_raid(model_mgr, happeningid)
            BackendApi.tr_happening_end(model_mgr, happening, raidboss)
            model_mgr.write_all()
            return model_mgr
        
        def tr_miss(happeningid):
            model_mgr = ModelRequestMgr()
            BackendApi.tr_happening_missed(model_mgr, happeningid, force=True)
            model_mgr.write_all()
            return model_mgr
        
        while True:
            happeninglist = Happening.fetchValues(['id','state'], filters, limit=LIMIT, offset=offset)
            offset += LIMIT
            
            for happening in happeninglist:
                try:
                    if happening.state == Defines.HappeningState.CLEAR:
                        model_mgr = db_util.run_in_transaction(tr_clear, happening.id)
                    else:
                        model_mgr = db_util.run_in_transaction(tr_miss, happening.id)
                    model_mgr.write_end()
                except CabaretError, err:
                    if err.code == CabaretError.Code.ALREADY_RECEIVED:
                        pass
                    else:
                        raise
                print 'update %d end' % happening.id
            
            if len(happeninglist) < LIMIT:
                break
        
        print 'check raid:end'
        
        print '================================'
        print 'delete mysql'
        # MySQLから削除.
        delete_target_model_cls_list = (
            RaidLog,
            RaidHelp,
            Raid,
            Happening,
        )
        def tr():
            Query.execute_update('set foreign_key_checks = 0;', [], False)
            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
            Query.execute_update('set foreign_key_checks = 1;', [], False)
        db_util.run_in_transaction(tr)
        
        print '================================'
        print 'delete redis'
        # Redisから削除.
        redisdb = RedisModel.getDB()
        uid_max = Player.max_value('id')
        for uid in xrange(1, uid_max+1):
            redisdb.delete(RaidLogListSet.makeKey(uid), RaidHelpSet.makeKey(uid))
            print 'delete redis...%s' % uid
        
        print '================================'
        print 'all end..'
        
        diff = OSAUtil.get_now() - starttime
        sec = diff.days * 86400 + diff.seconds
        print 'time %d.%06d' % (sec, diff.microseconds)
    def __proc_normal(self, model_mgr, redisdb, config, eventmaster,
                      rankmaster_dict, now, logintime, cdate):
        """通常のバトルイベント.
        """
        eventrankmaster = rankmaster_dict.get(eventmaster.rankstart)

        print 'start for normal'

        print '================================'
        print 'save level.'
        rediskey = "battleevent_preparation"
        redisdb.delete(rediskey)

        uid = PlayerExp.max_value('id')
        LIMIT = 500
        while 0 < uid:
            pipe = redisdb.pipeline()

            uidlist = range(max(0, uid - LIMIT) + 1, uid + 1)
            playerexplist = PlayerExp.getByKey(uidlist,
                                               using=settings.DB_READONLY)
            tutorialend_uid_list = [
                model.id for model in PlayerTutorial.getByKey(
                    uidlist, using=settings.DB_READONLY)
                if model.tutorialstate == Defines.TutorialStatus.COMPLETED
            ]
            for playerexp in playerexplist:
                if not playerexp.id in tutorialend_uid_list:
                    continue
                pipe.zadd(rediskey, playerexp.id, playerexp.level)

            pipe.execute()
            uid -= LIMIT

        print '================================'
        print 'allocate start.'
        data = redisdb.zrevrange(rediskey,
                                 0,
                                 1,
                                 withscores=True,
                                 score_cast_func=RedisModel.value_to_int)
        if data:
            level = data[0][1]
            groupid = 0
            while 0 < level:
                uidlist = [
                    RedisModel.value_to_int(uid)
                    for uid in redisdb.zrangebyscore(rediskey, level, level)
                    if RedisModel.value_to_int(uid)
                ]
                if uidlist:
                    random.shuffle(uidlist)
                    model_mgr, group = db_util.run_in_transaction(
                        Command.tr_write, groupid, eventmaster,
                        eventrankmaster, uidlist, now)
                    model_mgr.write_end()
                    if group and not group.fixed:
                        groupid = group.id
                    else:
                        groupid = 0
                level -= 1

        print '================================'
        print 'save rankuidset.'
        for rankmaster in rankmaster_dict.values():
            print "eventid=%s, rank=%s" % (rankmaster.eventid, rankmaster.rank)
            BackendApi.save_battleevent_rankuidset(rankmaster.eventid,
                                                   rankmaster.rank)

        # 後片付け.
        redisdb.delete(rediskey)

        print '================================'
        print 'all done.'
    def handle(self, *args, **options):

        print '================================'
        print 'battleevent_preparation'
        print '================================'

        now = OSAUtil.get_now()

        model_mgr = ModelRequestMgr()
        # メンテナンス確認.
        appconfig = BackendApi.get_appconfig(model_mgr)
        if not appconfig.is_maintenance():
            print u'メンテナンスモードにしてください'
            return
        print 'check maintenance...OK'

        config = BackendApi.get_current_battleeventconfig(model_mgr)
        if config.mid == 0:
            print 'Event is not set.'
            return
        elif config.starttime <= now:
            print 'Event has already beguns.'
            return
        eventmaster = BackendApi.get_battleevent_master(
            model_mgr, config.mid, using=settings.DB_READONLY)
        if eventmaster is None:
            print 'Event is not found.'
            return
        print 'check eventmaster...OK'

        rankmaster_dict = dict([
            (master.rank, master)
            for master in BattleEventRankMaster.fetchValues(
                filters={'eventid': config.mid},
                fetch_deleted=True,
                using=settings.DB_READONLY)
        ])
        eventrankmaster = rankmaster_dict.get(eventmaster.rankstart)
        if eventrankmaster is None:
            print 'BattleEventMaster.rankstart is not set.'
            return
        print 'check eventrankmaster...OK'

        # 対象の日付(月).
        logintime = DateTimeUtil.toLoginTime(now)
        cdate = datetime.date(logintime.year, logintime.month, logintime.day)
        print cdate.strftime("Create %Y/%m/%d")

        if not eventmaster.is_goukon:
            print '================================'
            print 'delete battleeventdata.'
            # Redisのバトルイベント関係を削除.
            RedisBattleEvent.getDB().flushdb()
            print 'delete...redis'

            BattleEventRanking.getDB().delete(
                BattleEventRanking.makeKey(eventmaster.id))
            BattleEventRankingBeginer.getDB().delete(
                BattleEventRankingBeginer.makeKey(eventmaster.id))
            print 'delete...ranking'

            tmp_time = config.starttime
            while tmp_time < config.endtime:
                keys = [
                    BattleEventDailyRanking.makeKey(
                        BattleEventDailyRanking.makeRankingId(
                            tmp_time, eventmaster.id, rankmaster.rank))
                    for rankmaster in rankmaster_dict.values()
                ]
                BattleEventDailyRanking.getDB().delete(*keys)
                tmp_time += datetime.timedelta(days=1)
            print 'delete...daily_ranking'

            delete_target_model_cls_list = (
                BattleEventFlags,
                BattleEventRank,
                BattleEventScore,
                BattleEventGroup,
                BattleEventGroupLog,
                BattleEventRevenge,
                BattleEventBattleLog,
                BattleEventGroupRankingPrize,
                BattleEventPresentData,
                BattleEventPresentCounts,
                UserLogBattleEventPresent,
            )

            def tr():
                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

            db_util.run_in_transaction(tr)
            OSAUtil.get_cache_client().flush()

        redisdb = RedisModel.getDB()

        if eventmaster.is_goukon:
            self.__proc_goukon(model_mgr, redisdb, config, eventmaster,
                               rankmaster_dict, now, logintime, cdate)
        else:
            self.__proc_normal(model_mgr, redisdb, config, eventmaster,
                               rankmaster_dict, now, logintime, cdate)
Beispiel #17
0
 def get(cls, uid):
   redisdb = RedisModel.getDB()
   return redisdb.get(cls.REDIS_KEY.format(uid))
Beispiel #18
0
    def handle(self, *args, **options):

        print '================================'
        print 'battleevent_aggregate'
        print '================================'

        now = OSAUtil.get_now()

        model_mgr = ModelRequestMgr()
        is_battle_open = BackendApi.is_battleevent_battle_open(
            model_mgr, settings.DB_READONLY, now, do_check_emergency=False)

        if is_battle_open:
            # こっちは緊急で修復する場合..
            tomorrow = now
            now = tomorrow - datetime.timedelta(days=1)
        else:
            tomorrow = now + datetime.timedelta(days=1)

        config = BackendApi.get_current_battleeventconfig(model_mgr)
        if config.mid == 0:
            print 'イベントが設定されていません.'
            return
        elif now < config.starttime:
            print 'イベントが始まっていません.'
            return
        elif config.endtime <= now:
            print 'イベントが終わっています.'
            return
        elif is_battle_open and not config.is_emergency:
            print 'バトル中です.'
            return

        eventmaster = BackendApi.get_battleevent_master(
            model_mgr, config.mid, using=settings.DB_READONLY)
        if eventmaster is None:
            print 'イベントが見つかりません.'
            return
        print 'check eventmaster...OK'

        redisdb = RedisModel.getDB()
        ALREADY_KEY = "battleevent_aggregate:end"

        # 対象の日付(月).
        logintime = DateTimeUtil.toLoginTime(tomorrow)
        cdate = datetime.date(logintime.year, logintime.month, logintime.day)
        print cdate.strftime("Create %Y/%m/%d")

        str_cdate_pre = redisdb.get(ALREADY_KEY)
        if str_cdate_pre:
            dt = DateTimeUtil.strToDateTime(str_cdate_pre, "%Y%m%d")
            cdate_pre = datetime.date(dt.year, dt.month, dt.day)
            if cdate_pre == cdate:
                print "already..."
                return

        rankmaster_dict = dict([
            (master.id, master)
            for master in BattleEventRankMaster.fetchValues(
                filters={'eventid': config.mid},
                fetch_deleted=True,
                using=settings.DB_READONLY)
        ])

        print '================================'
        print 'check rankmax'
        rank_max = config.getRankMax(logintime)
        print 'rankmax=%s' % rank_max
        if rank_max is None:
            rankmaster_list = rankmaster_dict.values()
        else:
            rankmaster_list = [
                rankmaster for rankmaster in rankmaster_dict.values()
                if rankmaster.rank <= rank_max
            ]
        if not rankmaster_list:
            print 'rank:all closed'
            return

        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 or cdate <= grouplist[0].cdate:
                break

            for group in grouplist:
                if cdate <= group.cdate:
                    break

                eventrankmaster = rankmaster_dict[group.rankid]
                model_mgr = db_util.run_in_transaction(Command.tr_close,
                                                       eventmaster,
                                                       eventrankmaster,
                                                       group.id, now, rank_max)
                model_mgr.write_end()

                print 'close %s' % group.id

        print '================================'
        print 'send rankingprizes.'
        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
Beispiel #19
0
    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