예제 #1
0
    def _get_loguserdata(self, cursor):
        #         try:
        #             cursor.execute("select uid, ctime, data from cabaret_userloggacha where '2015-09-29'<ctime and ctime<'2015-10-02 14:00:00';")
        #             row = cursor.fetchall()
        #         except:
        #             pass
        filters = dict(
            ctime__gt=DateTimeUtil.strToDateTime('2015-09-29', '%Y-%m-%d'),
            ctime__lt=DateTimeUtil.strToDateTime('2015-10-02 14:00:00',
                                                 '%Y-%m-%d %H:%M:%S'))
        loguserdata = {}
        #         for uid, ctime, log in row:
        for model in UserLogGacha.fetchValues(filters=filters):
            uid, ctime, logdata = model.uid, model.ctime, model.data
            #             obj = ObjectField()
            #             logdata = obj.to_python(log)
            mid = logdata.get('mid')
            prizeid = logdata.get('seat_prizeid')
            if prizeid == 600301 and mid == 1086:
                if loguserdata.get(uid):
                    loguserdata[uid].append(ctime.replace(tzinfo=None))
                else:
                    loguserdata[uid] = [ctime.replace(tzinfo=None)]

        for v in loguserdata.values():
            v.sort()
        return loguserdata
예제 #2
0
 def handle(self, *args, **options):
     
     print '================================'
     print 'aggregate_paymententry'
     print '================================'
     
     # 対象の日付(月).
     str_date = args[0]
     if str_date == 'auto':
         first = DateTimeUtil.strToDateTime(OSAUtil.get_now().strftime("%Y%m"), "%Y%m")
         str_date = (first - datetime.timedelta(days=1)).strftime("%Y%m")
     target_date = DateTimeUtil.strToDateTime(str_date, "%Y%m")
     print target_date
     
     # 出力先.
     output_dir = args[1]
     path = os.path.join(output_dir, target_date.strftime("paymententry_%Y%m.csv"))
     
     # 書き込むデータをここに溜め込む.
     writer = Command.Writer(path)
     writer.add(','.join([u'ペイメントID', u'単価', u'購入個数', u'合計ポイント']))
     
     self.aggregate(writer, GachaPaymentEntry, target_date)
     self.aggregate(writer, ShopPaymentEntry, target_date)
     
     writer.output(overwrite=False)
     
     print '================================'
     print 'all done..'
예제 #3
0
    def _get_loguserdata(self):
        model_mgr = ModelRequestMgr()

        gachamasteridlist = [557, 558, 559] # ステップガチャ 5,6,7
        gachamasters = model_mgr.get_models(GachaMaster, gachamasteridlist, using=settings.DB_READONLY)
        continuitydict = {master.id:master.continuity for master in gachamasters}
        loguserdata = {}

        # the error occured between 2017-02-09 16:00:00 and 2017-02-10 14:00:00
        # therefore we filter the User Log using this parameters
        filters = dict(ctime__gte=DateTimeUtil.strToDateTime('2017-02-09 16:00:00', '%Y-%m-%d %H:%M:%S'),
                       ctime__lte=DateTimeUtil.strToDateTime('2017-02-10 14:00:00', '%Y-%m-%d %H:%M:%S'))

        tmpdict = {continuity:defaultdict(int) for continuity in continuitydict.values()}

        for model in UserLogGacha.fetchValues(filters=filters):
            uid, ctime, logdata = model.uid, model.ctime, model.data
            continuity = logdata.get('continuity')
            if continuity in continuitydict.values():
                tmpdict[continuity][uid] += 1

        """
            ID's form PrizeMaster
            611045 => 5STEP目は「琥珀のかんざし」
            611044 => 6STEP目は「花魁のかんざし」
            400401 => 7STEP目は「ティアラ」
        """
        loguserdata[611045] = tmpdict.pop(8)
        loguserdata[611044] = tmpdict.pop(11)
        loguserdata[400401] = tmpdict.pop(19)

        return loguserdata
예제 #4
0
    def get_data(self):
        # 前月の最終日.
        e_date = DateTimeUtil.strToDateTime(
            self.date.strftime("%Y%m01"),
            "%Y%m%d") - datetime.timedelta(days=1)
        # 前月の1日.
        s_date = DateTimeUtil.strToDateTime(e_date.strftime("%Y%m01"),
                                            "%Y%m%d")

        return self.get_data_by_range(s_date, e_date)
예제 #5
0
 def process(self):
     
     model_mgr = self.getModelMgr()
     appconfig = BackendApi.get_appconfig(model_mgr, using=settings.DB_READONLY)
     if appconfig.is_maintenance():
         # メンテ中は実行しない.
         self.send(200, 'maintenance')
         return
     
     args = self.getUrlArgs('/aggregate_paymententry/')
     str_target_date = args.get(0)
     if str_target_date:
         target_date = DateTimeUtil.strToDateTime(str_target_date, "%Y%m")
     else:
         # 未指定の場合は前月分.
         last_date = DateTimeUtil.strToDateTime(OSAUtil.get_now().strftime("%Y%m"), "%Y%m") - datetime.timedelta(days=1)
         target_date = DateTimeUtil.strToDateTime(last_date.strftime("%Y%m"), "%Y%m")
     
     def makeWriter(name):
         # 出力先.
         path = os.path.join(settings_sub.KPI_ROOT, target_date.strftime("paymententry/paymententry_"+name+"_%Y%m.csv"))
         
         # 書き込むデータをここに溜め込む.
         writer = Handler.Writer(path)
         writer.add(','.join([u'ペイメントID', u'単価', u'購入個数', u'合計ポイント', u'executedTime']))
         
         return writer
     
     writer_sp = makeWriter("sp")
     writer_pc = makeWriter("pc")
     
     model_cls_list = (
         GachaPaymentEntry,
         ShopPaymentEntry,
     )
     self.__logs = []
     for model_cls in model_cls_list:
         self.work(model_cls, target_date, writer_sp, writer_pc)
         if self.response.isEnd:
             return
     print 'all end'
     writer_sp.output()
     writer_pc.output()
     print 'all output'
     
     self.__logs.insert(0, 'OK')
     print 'log insert'
     
     self.send(200, '\n'.join(self.__logs))
     print 'complete'
예제 #6
0
    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
예제 #7
0
 def __init__(self,
              uid,
              damage=0,
              cnt=0,
              number=0,
              feverendtime=None,
              champagne=False,
              champagne_post=0,
              champagne_add=0,
              material=0,
              tanzaku=0,
              tanzaku_post=0):
     self.__uid = uid
     self.__damage = damage
     self.__damage_cnt = cnt
     self.__number = number
     if not feverendtime:
         feverendtime = OSAUtil.get_datetime_min()
     elif not isinstance(feverendtime, datetime.datetime):
         feverendtime = DateTimeUtil.strToDateTime(feverendtime)
     self.__feverendtime = feverendtime
     self.__champagne = bool(champagne)
     self.__champagne_post = champagne_post
     self.__champagne_add = champagne_add
     self.__material_num = material
     self.__tanzaku = tanzaku
     self.__tanzaku_post = tanzaku_post
    def handle(self, *args, **options):

        print '================================'
        print 'aggregate_paymentusermap'
        print '================================'

        # 対象の日付(月).
        str_date = args[0]
        target_date = DateTimeUtil.strToDateTime(str_date, "%Y%m")
        print target_date

        # 出力先.
        output_dir = args[1]
        path = os.path.join(output_dir,
                            target_date.strftime("paymentusermap_%Y%m.csv"))

        # 書き込むデータをここに溜め込む.
        writer = Command.Writer(path)
        writer.add(','.join([u'ユーザID', u'消費ポイント']))

        dest_map = {}
        self.aggregate(GachaPaymentEntry, target_date, dest_map)
        self.aggregate(ShopPaymentEntry, target_date, dest_map)

        for data in dest_map.items():
            writer.add(u'%s,%s' % data)

        writer.output(overwrite=False)

        print '================================'
        print 'all done..'
예제 #9
0
 def work(self, model_cls, target_date, writer_sp, writer_pc):
     
     s_executed_date = target_date
     e_executed_date = DateTimeUtil.strToDateTime((s_executed_date + datetime.timedelta(days=31)).strftime("%Y%m"), "%Y%m")
     
     # 前後1日を余分に.
     s_date = s_executed_date - datetime.timedelta(days=1)
     e_date = e_executed_date + datetime.timedelta(days=1)
     
     filters = {
         'state' : PaymentData.Status.COMPLETED,
         'ctime__gte' : s_date,
         'ctime__lt' : e_date,
     }
     LIMIT = 500
     offset = 0
     
     while True:
         model_mgr = ModelRequestMgr()
         
         modellist = model_cls.fetchValues(filters=filters, limit=LIMIT, offset=offset, order_by='ctime', using=backup_db)
         for model in modellist:
             
             player = BackendApi.get_player(self, model.uid, [], using=settings.DB_READONLY, model_mgr=model_mgr)
             
             try:
                 record = BackendApi.get_restful_paymentrecord(self, model.id, player.dmmid)
             except:
                 if not settings_sub.IS_DEV:
                     raise
                 else:
                     # クロスプロモで共有した環境のレコード.
                     continue
             
             if record.executeTime is None or not (s_executed_date <= record.executeTime < e_executed_date):
                 # 集計対象の日付ではない.
                 continue
             
             persons = BackendApi.get_dmmplayers(self, [player], using=settings.DB_READONLY, do_execute=False)
             person = persons[player.dmmid]
             if person and getattr(person, 'userType', None) == "staff":
                 # 優待アカウント.
                 self.__logs.append("%s=>staff" % model.id)
                 continue
             
             if str(record.paymentItems[0].itemId).isdigit():
                 writer = writer_sp
             else:
                 writer = writer_pc
             writer.add(','.join([model.id, str(model.price), str(model.inum), str(model.price*model.inum), record.executeTime.strftime("%Y-%m-%d %H:%M:%S")]))
             
             self.__logs.append(model.id)
         
         offset += LIMIT
         
         if len(modellist) < LIMIT:
             break
예제 #10
0
 def datetime_to_sql_week(self, dt):
     """週間データのカラムのパーティション用のSQLに変換.
     """
     if isinstance(dt, datetime.datetime):
         dt = DateTimeUtil.strToDateTime(dt.strftime("%Y-%m-01 00:00:00"), "%Y-%m-%d %H:%M:%S")
         endtime = BackendApi.to_cabaretclub_section_endtime(dt)
         v = endtime.strftime("%Y%W")
     else:
         v = dt
     return v
예제 #11
0
    def process(self):

        model_mgr = self.getModelMgr()
        appconfig = BackendApi.get_appconfig(model_mgr,
                                             using=settings.DB_READONLY)
        if appconfig.is_maintenance():
            # メンテ中は送信しない.
            self.send(200, 'maintenance')
            return

        args = self.getUrlArgs('/paymentlog_post/')
        str_target_date = args.get(0)
        if str_target_date:
            target_date = DateTimeUtil.strToDateTime(
                str_target_date, Handler.TARGET_DATE_FORMAT)
        else:
            # 未指定の場合は前日分.
            target_date = DateTimeUtil.toBaseTime(
                OSAUtil.get_now() - datetime.timedelta(days=1), 0)

        model_cls_list = (
            GachaPaymentEntry,
            ShopPaymentEntry,
        )
        post_nums = {
            str_target_date: {
                'sp': 0,
                'pc': 0,
            }
        }
        self.__logs = []
        for model_cls in model_cls_list:
            overwrite_sp = post_nums[str_target_date].get('sp', 0) < 1
            overwrite_pc = post_nums[str_target_date].get('pc', 0) < 1

            tmp_post_nums = self.work(model_cls, target_date, overwrite_sp,
                                      overwrite_pc) or {}
            for str_date, nums in tmp_post_nums.items():
                dic = post_nums[str_date] = post_nums.get(str_date) or {}
                for k, v in nums.items():
                    dic[k] = dic.get(k, 0) + v

            if self.response.isEnd:
                return

        # 送信した件数.
        self.__logs.append(u'nums:')
        for str_date, nums in post_nums.items():
            self.__logs.append(
                u'%s:sp=%s,pc=%s' %
                (str_date, nums.get('sp', 0), nums.get('pc', 0)))

        self.__logs.insert(0, 'OK')
        self.send(200, '\n'.join(self.__logs))
예제 #12
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
예제 #13
0
    def handle(self, *args, **options):

        print '================================'
        print 'select_userlog'
        print '================================'

        target = args[0]
        model_cls = self.getModelClass(target)

        str_ctime_min = args[1]
        ctime_min = DateTimeUtil.strToDateTime(str_ctime_min,
                                               "%Y-%m-%d %H:%M:%S")

        getter = eval(args[2])

        LIMIT = 3000
        uid_max = Player.max_value('id', using=backup_db)

        for uid in xrange(1, uid_max + 1):
            filters = {'uid': uid, 'ctime__gte': ctime_min}
            offset = 0
            num = 0
            while True:
                modellist = model_cls.fetchValues(filters=filters,
                                                  order_by='ctime',
                                                  limit=LIMIT,
                                                  offset=offset,
                                                  using=backup_db)
                if not modellist:
                    break
                offset += len(modellist)

                for model in modellist:
                    num += getter(model)
            if num:
                print '%d,%d' % (uid, num)

        print '================================'
        print 'all done..'
예제 #14
0
class RaidBoss():
    """レイドボス.
    """
    # 協力者報酬が適用開始される時間.
    DEMIWORLD_OPEN_TIME = DateTimeUtil.strToDateTime("201402031600",
                                                     "%Y%m%d%H%M")
    # HPが仕様変更される時間.
    if settings_sub.IS_DEV:
        HP_UPDATE_TIME = DateTimeUtil.strToDateTime("201402061430",
                                                    "%Y%m%d%H%M")
    else:
        HP_UPDATE_TIME = DateTimeUtil.strToDateTime("201402071430",
                                                    "%Y%m%d%H%M")

    # ダメージ履歴のバージョン.
    DAMAGE_RECORDVERSION = 1

    # レイドイベント報酬で通常のも受け取れるようになった時間.
    if settings_sub.IS_DEV:
        RAIDEVENT_PRIZE_UPDATETIME = DateTimeUtil.strToDateTime(
            "201402261300", "%Y%m%d%H%M")
    else:
        RAIDEVENT_PRIZE_UPDATETIME = DateTimeUtil.strToDateTime(
            "201402281500", "%Y%m%d%H%M")

    def __init__(self, raid, master, eventraidmaster=None):
        self.__raid = raid
        self.__master = master
        self.__eventraidmaster = None
        self.__records = {}
        self.__combo_cnt = 0
        self.__combo_etime = OSAUtil.get_datetime_min()
        self.setEventRaidMaster(eventraidmaster)

        combodata = self.__getDBComboData()
        if combodata:
            self.__combo_cnt = combodata['cnt']
            self.__combo_etime = combodata['etime']

    @property
    def id(self):
        return self.raid.id

    @property
    def raid(self):
        return self.__raid

    @property
    def master(self):
        return self.__master

    @property
    def raideventraidmaster(self):
        return self.__eventraidmaster if isinstance(
            self.__eventraidmaster, RaidEventRaidMaster) else None

    @property
    def scouteventraidmaster(self):
        return self.__eventraidmaster if isinstance(
            self.__eventraidmaster, ScoutEventRaidMaster) else None

    @property
    def produceeventraidmaster(self):
        return self.__eventraidmaster if isinstance(
            self.__eventraidmaster, ProduceEventRaidMaster) else None

    @property
    def hp(self):
        return self.raid.hp

    @property
    def defense(self):
        return self.get_defense()

    @property
    def ctype(self):
        return self.master.ctype

    @property
    def weakbonus(self):
        return self.master.weakbonus

    @property
    def timebonusflag(self):
        """タイムボーナスフラグ.
        """
        return self.raid.timebonusflag

    @property
    def fastflag(self):
        """秘宝ボーナスフラグ.
        """
        return self.raid.fastflag

    @property
    def combo_cnt(self):
        return self.__combo_cnt

    @property
    def combo_etime(self):
        return self.__combo_etime

    def __getDBDamageRecordData(self):
        """Raid.damage_recordの中身のバージョンを見て取得.
        """
        damage_record = self.raid.getDamageRecord()
        version = damage_record.get('VERSION', None)
        if version == 1:
            # コンボボーナス時間追加バージョン.
            records = damage_record['records'] = damage_record.get(
                'records', {})
            return records
        else:
            # リリース時のバージョン.
            return damage_record

    def __getDBComboData(self):
        """コンボ情報を取得.
        """
        damage_record = self.raid.getDamageRecord()
        version = damage_record.get('VERSION', None)
        if version == 1:
            # コンボボーナス時間追加バージョン.
            return damage_record.get('combo')
        else:
            # リリース時のバージョン.
            return None

    def __saveDBDamageRecordData(self, records):
        """Raid.damage_recordの中身のバージョンをつけて保存.
        """
        self.raid.setDamageRecord({
            'VERSION': RaidBoss.DAMAGE_RECORDVERSION,
            'records': records,
            'combo': {
                'cnt': self.__combo_cnt,
                'etime': self.__combo_etime or OSAUtil.get_now(),
            },
        })

    def setEventRaidMaster(self, eventraidmaster):
        if eventraidmaster and eventraidmaster.mid != self.master.id:
            raise CabaretError(u'不正な設定を行っている')
        self.__eventraidmaster = eventraidmaster

    def get_maxhp(self):
        """最大HP.
        """
        if (self.raid.ctime or OSAUtil.get_now()) < RaidBoss.HP_UPDATE_TIME:
            # 旧仕様.
            return max(
                1,
                (self.master.hpbase + self.raid.level * self.master.hpgrowth) *
                self.raid.hprate / 100)
        elif self.raideventraidmaster:
            lvband = max(0, int(self.raid.level / 10 - 1))
            cnt = lvband * (lvband + 1) / 2
            pre = cnt * 10 - lvband
            return max(1,
                       (self.master.hpbase + pre * 10 * self.master.hpgrowth +
                        self.master.hpgrowth * 10 * (self.raid.level - 1)) *
                       self.raid.hprate / 100)
        else:
            return max(
                1,
                (self.master.hpbase + self.raid.level * self.master.hpgrowth) *
                self.raid.hprate / 100)

    def get_defense(self):
        """防御力.
        """
        return self.master.defensebase + self.raid.level * self.master.defensegrowth

    def get_member_num(self):
        """参加人数.
        """
        cnt = 0
        for uid in self.getDamageRecordUserIdList():
            if 0 < self.getDamageRecord(uid).damage_cnt:
                cnt += 1
        return cnt

    def get_cabaretking(self):
        """キャバ王の秘宝.
        """
        return self.master.cabaretkingbase + self.raid.level * self.master.cabaretkinggrowth

    def get_demiworld(self):
        """キャバ王の秘宝(救援).
        """
        if self.raid.ctime < RaidBoss.DEMIWORLD_OPEN_TIME:
            # 公開前に発生したレイドについては0
            return 0
        else:
            return self.master.demiworldbase + self.raid.level * self.master.demiworldgrowth

    def get_owner_eventpoint(self):
        """発見者のイベントポイント.
        """
        point = 0
        if self.raideventraidmaster:
            if self.timebonusflag:
                point = self.raideventraidmaster.ownerpoint_timebonus + self.raid.level * self.raideventraidmaster.ownerpoint_timebonus_growth
            else:
                point = self.raideventraidmaster.ownerpoint + self.raid.level * self.raideventraidmaster.ownerpoint_growth
        return int(point * self.raid.evpointrate / 100)

    def get_mvp_eventpoint(self):
        """MVPのイベントポイント.
        """
        point = 0
        if self.raideventraidmaster:
            if self.timebonusflag:
                point = self.raideventraidmaster.mvppoint_timebonus + self.raid.level * self.raideventraidmaster.mvppoint_timebonus_growth
            else:
                point = self.raideventraidmaster.mvppoint + self.raid.level * self.raideventraidmaster.mvppoint_growth
        return int(point * self.raid.evpointrate / 100)

    def is_big(self):
        """大ボスフラグ.
        """
        return self.raideventraidmaster and self.raideventraidmaster.big

    def is_produceevent_bigboss(self):
        """プロデュースイベント大ボスフラグ
        """
        return self.produceeventraidmaster and self.produceeventraidmaster.big

    def getDamageRecordUserIdList(self):
        """ダメージ履歴にあるユーザーIDを取得.
        """
        damage_record = self.__getDBDamageRecordData()
        uidlist = list(
            set(list(self.__records.keys()) + list(damage_record.keys())))
        return uidlist

    def is_help_sent(self):
        """救援依頼を送ったか.
        """
        return 1 < len(self.getDamageRecordUserIdList())

    def getLastDamageRecord(self):
        """最後のダメージ履歴.
        """
        uidlist = self.getDamageRecordUserIdList()
        recordlist = [self.getDamageRecord(uid) for uid in uidlist]
        if recordlist:
            recordlist.sort(key=operator.attrgetter('number'), reverse=True)
            record = recordlist[0]
            if 0 < record.damage_cnt:
                return record
        return None

    def getDamageRecordList(self):
        """ダメージ履歴を全て取得.
        """
        uidlist = self.getDamageRecordUserIdList()
        recordlist = [self.getDamageRecord(uid) for uid in uidlist]
        recordlist.sort(key=operator.attrgetter('damage'), reverse=True)
        return recordlist

    def getDamageRecord(self, uid):
        """ダメージ履歴を取得.
        """
        if self.__records.has_key(uid):
            return self.__records[uid]
        damage_record = self.__getDBDamageRecordData()
        data = damage_record.get(uid, None)
        if data is None:
            record = RaidDamageRecord(uid)
        else:
            record = RaidDamageRecord(uid, **data)
        self.__records[uid] = record
        return record

    def addUser(self, uid):
        """ダメージ履歴に追記.
        """
        return self.getDamageRecord(uid)

    def addDamageRecord(self, uid, damage, feverendtime=None):
        """ダメージ履歴に追記.
        """
        lastrecord = self.getLastDamageRecord()
        if lastrecord:
            number = lastrecord.number + 1
        else:
            number = 1
        record = self.getDamageRecord(uid)
        record.addDamage(damage)
        record.setNumber(number)
        if feverendtime:
            record.updateFeverTime(feverendtime)

    def refrectDamageRecord(self):
        """ダメージ履歴の更新分を反映.
        """
        damage_record = self.__getDBDamageRecordData()
        for record in self.__records.values():
            damage_record[record.uid] = record.to_dict()
        self.__saveDBDamageRecordData(damage_record)

    def getMVPList(self):
        """MVPユーザIDを取得.
        """
        recordlist = self.getDamageRecordList()
        recordlist.sort(key=lambda x: x.damage, reverse=True)
        uidlist = []
        damage = 0
        for record in recordlist:
            if record.damage == 0 or record.damage < damage:
                break
            uidlist.append(record.uid)
            damage = record.damage
        return uidlist

    def getBorderDamageForPrizeGet(self):
        """報酬獲得に必要なダメージ.
        """
        if not self.raideventraidmaster:
            return 0
        maxhp = self.get_maxhp()
        border = int(maxhp * 3 / 100)
        return border

    def getHelpEventPoints(self, uid=None):
        """協力者のイベントポイント.
        ユーザIDがキー, ポイントが値.
        """
        data = {}
        if not self.raideventraidmaster:
            return data

        maxhp = self.get_maxhp()
        border = self.getBorderDamageForPrizeGet()

        if uid is None:
            recordlist = self.getDamageRecordList()
        else:
            recordlist = []
            record = self.getDamageRecord(uid)
            if record:
                recordlist.append(record)

        maxpoint = self.get_mvp_eventpoint()

        oid = self.raid.oid
        for record in recordlist:
            damage = record.damage
            if damage < border:
                continue
            elif record.uid == oid:
                continue
            # MVP報酬×貢献度(ボスに与えたダメージ割合)×5.
            data[record.uid] = int(
                min(maxpoint * damage * 5 / maxhp, maxpoint / 2))
        return data

    def getCurrentComboCount(self, now=None):
        """現在のコンボ数.
        """
        now = now or OSAUtil.get_now()
        if now < self.combo_etime:
            return self.combo_cnt
        else:
            return 0

    def setComboData(self, cnt, etime):
        """コンボ数を設定.
        """
        self.__combo_cnt = cnt
        self.__combo_etime = etime

    def addComboCount(self, uid, seconds, now=None, cnt=1):
        """コンボ数を加算.
        """
        now = now or OSAUtil.get_now()
        cur_cnt = self.getCurrentComboCount(now)
        if 0 < cur_cnt:
            lastrecord = self.getLastDamageRecord()
            if lastrecord and lastrecord.uid == uid:
                # 直前に同じ人が接客しているので加算しない.
                return
        self.setComboData(cur_cnt + cnt,
                          now + datetime.timedelta(seconds=seconds))

    def get_tanzaku_number(self, uid):
        if self.scouteventraidmaster is None:
            return None
        elif uid == self.raid.oid:
            return self.scouteventraidmaster.tanzaku_number if self.scouteventraidmaster.tanzaku_rate else None
        else:
            return self.scouteventraidmaster.tanzaku_help_number if self.scouteventraidmaster.tanzaku_help_rate else None
예제 #15
0
    def makeProceeds(self, master):
        """ガチャの課金情報を集計.
        """
        model_mgr = self.getModelMgr()
        appstime = DateTimeUtil.strToDateTime("20131224", "%Y%m%d")

        dest = {
            'id': master.id,
            'name': master.name,
        }
        schedulemaster = None
        if master.schedule:
            schedulemaster = BackendApi.get_schedule_master(
                model_mgr, master.schedule, using=settings.DB_READONLY)

        now = OSAUtil.get_now()
        if schedulemaster:
            stime = max(appstime, schedulemaster.stime)
            etime = min(now, schedulemaster.etime)
        else:
            stime = appstime
            etime = now

        table = {}
        filters = {
            'state': PaymentData.Status.COMPLETED,
            'iid': master.id,
        }
        cur_stime = stime

        useridset_total = set()
        count_total = 0

        while cur_stime < etime:

            filters['ctime__gte'] = cur_stime
            filters['ctime__lt'] = DateTimeUtil.toBaseTime(
                cur_stime + datetime.timedelta(days=1), 0)

            paymentlist = self.getPaymentFromCache(master.id, cur_stime, now)
            if paymentlist is None:
                paymentlist = GachaPaymentEntry.fetchValues(
                    ['uid', 'inum', 'price'],
                    filters=filters,
                    using=settings.DB_READONLY)
                self.setPaymentToCache(paymentlist, master.id, cur_stime, now)

            str_month = cur_stime.strftime("%Y%m")

            uidset = set([payment.uid for payment in paymentlist])
            cnt = len(paymentlist)

            monthdata = table[str_month] = table.get(str_month) or {
                'total': 0,
                'datalist': [],
                'name': cur_stime.strftime(u"%Y年%m月"),
                'count': 0,
                'uu': set()
            }
            monthdata['count'] += cnt
            monthdata['uu'] |= uidset
            useridset_total |= uidset
            count_total += cnt

            price = sum(
                [payment.inum * payment.price for payment in paymentlist])
            monthdata['datalist'].append({
                'day': cur_stime.day,
                'price': price,
                'uu': uidset,
                'count': cnt,
            })
            monthdata['total'] += price

            cur_stime = filters['ctime__lt']

        monthlist = table.keys()
        monthlist.sort()
        dest['table'] = [table[month] for month in monthlist]
        dest['total'] = sum([data['total'] for data in dest['table']])
        dest['uu'] = useridset_total
        dest['count'] = count_total

        return dest
예제 #16
0
    def handle(self, *args, **options):
        
        print '================================'
        print 'recov_takeover'
        print '================================'
        
        is_update = 0 < len(args) and args[0] == 'update'
        
        # 修正対象のcardidのリスト.
        if settings_sub.IS_DEV:
            tmp_cards = Card.fetchValues(filters={'mid__gte': 23203, 'mid__lte': 23205})
            TARGET_CARDID_LIST = [card.id for card in tmp_cards]
        else:
            tmp_cards = Card.fetchValues(filters={'mid__gte': 23203, 'mid__lte': 23205})
            TARGET_CARDID_LIST = [card.id for card in tmp_cards]

            # TARGET_CARDID_LIST = (
            #     243554710460995,
            #     259875586181903,
            #     264149078647399,
            #     267898585091933,
            #     289150083275628,
            #     303770151954557,
            #     326108276855142,
            #     2370821955526,
            #     59785944768327,
            #     97268124365984,
            #     164467182686565,
            #     191985038136826,
            #     207399675767609,
            #     207399675767612,
            #     226937481993457,
            #     253566279230399,
            #     298779399950377,
            #     326348795024926,
            #     407317518485754,
            #     425957676551555,
            # )
        # 対象のキャストが本番で公開された時間.
        CTIME_MIN = DateTimeUtil.strToDateTime('201603181400', "%Y%m%d%H%M")
        
        model_mgr = ModelRequestMgr()

        for cardid in TARGET_CARDID_LIST:
            # カードを取得.
            card = Card.getByKey(cardid)
            if card is None:
                print '%s...None' % cardid
                continue
            cardmaster = BackendApi.get_cardmasters([card.mid], model_mgr).get(card.mid)
            
            # このカードのハメ管理履歴を絞り込み.
            log_dict = {}
            for model in UserLogEvolution.fetchValues(filters={'uid':card.uid,'ctime__gte':CTIME_MIN}, order_by='ctime'):
                if cardid == model.data['material']['id']:
                    print '%s...material' % cardid
                    break
                elif cardid != model.data['base']['id']:
                    continue
                log_dict[model.data['base']['mid']] = model
            
            midlist = BackendApi.get_cardmasterid_by_albumhklevel(model_mgr, cardmaster.album)
            masters = dict([(model.hklevel, model) for model in BackendApi.get_cardmasters(midlist, model_mgr).values()])
            
            tmp_basecard = None
            for hklevel in xrange(1, cardmaster.hklevel):
                basemaster = masters[hklevel]
                logdata = log_dict[basemaster.id]
                
                tmp_basecard = CardSet(tmp_basecard.card if tmp_basecard else Card.makeInstance(cardid), basemaster)
                tmp_basecard.card.mid = basemaster.id
                tmp_basecard.card.level = logdata.data['base']['level']
                
                takeover = tmp_basecard.get_evolution_takeover()
                takeover *= 2
                tmp_basecard.card.takeover += takeover
            
            if card.takeover == tmp_basecard.card.takeover:
                print '%s...equal' % cardid
                continue
            
            if is_update:
                def tr(cardid, master, takeover):
                    card = Card.getByKeyForUpdate(cardid)
                    if master.id != card.mid:
                        # これは危険.
                        raise CabaretError()
                    
                    model_mgr = ModelRequestMgr()
                    card.takeover = takeover;
                    model_mgr.set_save(card)
                    
                    def writeEnd():
                        BackendApi.save_cardidset(CardSet(card, master))
                    model_mgr.add_write_end_method(writeEnd)
                    model_mgr.write_all()
                    
                    return model_mgr
                try:
                    db_util.run_in_transaction(tr, tmp_basecard.id, cardmaster, tmp_basecard.card.takeover).write_end()
                except CabaretError:
                    print '%s...danger' % cardid
                    continue
            print '%s...update %s=>%s' % (cardid, card.takeover, tmp_basecard.card.takeover)
        
        print '================================'
        print 'all done..'
예제 #17
0
 def str_to_pkey(cls, st):
     return DateTimeUtil.datetimeToDate(DateTimeUtil.strToDateTime(
         st, dtformat="%Y-%m-%d"),
                                        logintime=False)
예제 #18
0
 def handle(self, *args, **options):
     
     print '================================'
     print 'create_benchmark_csv'
     print '================================'
     
     
     USER_ID_START = OSAUtil.BENCH_USER_ID_START
     USER_NUM = 0
     if args:
         USER_NUM = int(args[0])
     USER_NUM = max(OSAUtil.BENCH_USER_ID_NUM, USER_NUM)
     
     print '================================'
     print 'USER_NUM=%d' % USER_NUM
     
     LEVEL = 1
     GOLD = 100000
     GACHA_PT = 3000
     CARD_NUM = 100
     CARD_LIMIT = CARD_NUM + 50
     FRIEND = 50
     FRIEND_REQUEST = 50
     FRIEND_EMPTY = 50
     FRIENDLIMIT = FRIEND + FRIEND_REQUEST * 2 + FRIEND_EMPTY
     RAID_ENDTIME = DateTimeUtil.strToDateTime("20150101", "%Y%m%d")
     RAIDLOG = 100
     GREETLOG = 100
     PRESENT = int(100 / len(Defines.ItemType.PRESENT_TYPES.keys()))
     PRESENT_LIMITTIME = DateTimeUtil.strToDateTime("20150101", "%Y%m%d")
     ITEM_RNUM = 50
     ITEM_VNUM = 50
     DECK_CAPACITY = 1000000
     CABARET_TREASURE = 100000
     
     TREASURE_NUM = 20
     
     OUTPUT_DIR = os.path.join(settings_sub.TMP_DOC_ROOT, 'dummy')
     csvmgr = ModelCSVManager(OUTPUT_DIR)
     
     model_mgr = ModelRequestMgr()
     
     # 各種マスターデータ.
     levelexpmaster = model_mgr.get_model(PlayerLevelExpMaster, LEVEL)
     item_all = model_mgr.get_mastermodel_all(ItemMaster)
     card_all = [master for master in model_mgr.get_mastermodel_all(CardMaster) if master.ckind == Defines.CardKind.NORMAL and master.hklevel == 1]
     happeningall = model_mgr.get_mastermodel_all(HappeningMaster)
     arealist = model_mgr.get_mastermodel_all(AreaMaster, order_by='id')[:2]
     scoutlist = ScoutMaster.fetchValues(filters={'area__in':[area.id for area in arealist]}, order_by='id')
     treasure_gold_all = model_mgr.get_mastermodel_all(TreasureGoldMaster)
     treasure_silver_all = model_mgr.get_mastermodel_all(TreasureSilverMaster)
     treasure_bronze_all = model_mgr.get_mastermodel_all(TreasureBronzeMaster)
     
     now = OSAUtil.get_now()
     
     print '================================'
     print 'players..'
     
     class ModelList:
         def __init__(self):
             self.modellist_all = []
         
         def add(self, modellist):
             csvmgr.setModelList(modellist)
     
     modellist_all = ModelList()
     
     for i in xrange(USER_NUM):
         modellist = []
         
         uid = i + USER_ID_START
         
         # プレイヤー作成.
         player = self.install(uid)
         
         # タイプ決定とか.
         self.regist(player, levelexpmaster, GOLD, GACHA_PT, FRIENDLIMIT, CARD_LIMIT, DECK_CAPACITY, CABARET_TREASURE)
         
         modellist.append(player.getModel(Player))
         for model_cls in ModelPlayer.Meta.MODELS:
             p = player.getModel(model_cls)
             if p:
                 modellist.append(p)
         
         # スカウト完了.
         for scout in scoutlist:
             playdata = ScoutPlayData.makeInstance(ScoutPlayData.makeID(uid, scout.id))
             playdata.progress = scout.execution
             modellist.append(playdata)
             
             # フレンドの近況.
             logdata = ScoutClearLog.makeData(player.id, scout.id)
             modellist.append(logdata)
         
         for area in arealist:
             model = AreaPlayData.makeInstance(AreaPlayData.makeID(uid, area.id))
             model.clevel = levelexpmaster.level
             modellist.append(model)
             
             # フレンドの近況.
             logdata = BossWinLog.makeData(player.id, area.id)
             modellist.append(logdata)
         
         # カード付与.
         playercard = player.getModel(PlayerCard)
         cardidlist = []
         for _ in xrange(CARD_NUM):
             playercard.card += 1
             cardid = Card.makeID(uid, playercard.card)
             
             cardmaster = random.choice(card_all)
             card = BackendApi.create_card_by_master(cardmaster)
             card.id = cardid
             card.uid = uid
             modellist.append(card)
             
             cardidlist.append(cardid)
         
         # デッキ設定.
         deck = Deck()
         deck.id = uid
         deck.set_from_array(cardidlist[:Defines.DECK_CARD_NUM_MAX])
         modellist.append(deck)
         
         # カード獲得フラグ.
         for cardmaster in card_all:
             cardacquisition = CardAcquisition.makeInstance(CardAcquisition.makeID(uid, cardmaster.id))
             cardacquisition.maxlevel = cardmaster.maxlevel
             modellist.append(cardacquisition)
             
             albumacquisition = AlbumAcquisition.makeInstance(AlbumAcquisition.makeID(uid, cardmaster.album))
             modellist.append(albumacquisition)
         
         # アイテム.
         for itemmaster in item_all:
             item = Item.makeInstance(Item.makeID(uid, itemmaster.id))
             item.rnum = ITEM_RNUM
             item.vnum = ITEM_VNUM
             modellist.append(item)
         
         # レイド履歴.
         states = (Defines.HappeningState.END, Defines.HappeningState.MISS, Defines.HappeningState.CANCEL)
         for lognumber in xrange(RAIDLOG):
             happeningmaster = random.choice(happeningall)
             raidmaster = BackendApi.get_raid_master(model_mgr, happeningmaster.boss)
             self.putRaidLog(modellist, player, happeningmaster, raidmaster, states[lognumber % len(states)])
         
         # レイド.
         happeningmaster = random.choice(happeningall)
         raidmaster = BackendApi.get_raid_master(model_mgr, happeningmaster.boss)
         self.putRaid(modellist, player, happeningmaster, raidmaster, RAID_ENDTIME)
         
         # プレゼント.
         def putPresent(itype, itemid, itemvalue):
             presentlist = BackendApi.create_present(model_mgr, 0, uid, itype, itemid, itemvalue, Defines.TextMasterID.ACCESS_BONUS, PRESENT_LIMITTIME, do_set_save=False)
             modellist.extend(presentlist)
             presentlist = BackendApi.create_present(model_mgr, 0, uid, itype, itemid, itemvalue, Defines.TextMasterID.ACCESS_BONUS, now, do_set_save=False)
             modellist.extend(presentlist)
         
         for _ in xrange(PRESENT):
             putPresent(Defines.ItemType.GOLD, 0, 1000)
             putPresent(Defines.ItemType.GACHA_PT, 0, 10)
             putPresent(Defines.ItemType.ITEM, random.choice(item_all).id, 1)
             putPresent(Defines.ItemType.CARD, random.choice(card_all).id, 1)
             putPresent(Defines.ItemType.RAREOVERTICKET, 0, 1)
             putPresent(Defines.ItemType.TRYLUCKTICKET, 0, 1)
             putPresent(Defines.ItemType.MEMORIESTICKET, 0, 1)
             putPresent(Defines.ItemType.GACHATICKET, 0, 1)
             putPresent(Defines.ItemType.GOLDKEY, 0, 1)
             putPresent(Defines.ItemType.SILVERKEY, 0, 1)
         
         # 宝箱.
         def makeTreasure(masterlist, model_cls, etime):
             master = random.choice(masterlist)
             model = model_cls()
             model.uid = uid
             model.mid = master.id
             model.etime = etime
             modellist.append(model)
         
         for _ in xrange(TREASURE_NUM):
             makeTreasure(treasure_gold_all, TreasureGold, now)
             makeTreasure(treasure_gold_all, TreasureGold, PRESENT_LIMITTIME)
             
             makeTreasure(treasure_silver_all, TreasureSilver, now)
             makeTreasure(treasure_silver_all, TreasureSilver, PRESENT_LIMITTIME)
             
             makeTreasure(treasure_bronze_all, TreasureBronze, now)
             makeTreasure(treasure_bronze_all, TreasureBronze, PRESENT_LIMITTIME)
         
         modellist_all.add(modellist)
         
         print 'complete uid=%d' % uid
     
     print '================================'
     print 'friends..'
     
     # ユーザーがそろっていないと作れないレコード.
     for i in xrange(USER_NUM):
         modellist = []
         
         uid = i + USER_ID_START
         
         # フレンド設定.
         self.putFriends(modellist, uid, USER_ID_START, USER_NUM, FRIEND, FRIEND_REQUEST)
         
         # あいさつ履歴.
         fid = uid
         for _ in xrange(GREETLOG):
             fid = ((fid - USER_ID_START + 1) % USER_NUM) + USER_ID_START
             while fid == uid:
                 fid = ((fid - USER_ID_START + 1) % USER_NUM) + USER_ID_START
             
             model = GreetLog()
             model.fromid = fid
             model.toid = uid
             modellist.append(model)
         
         modellist_all.add(modellist)
         
         print 'complete uid=%d' % uid
     
     csvmgr.output()
     
     print '================================'
     print 'all done..'
예제 #19
0
    def work(self,
             model_cls,
             target_date,
             overwrite_sp=True,
             overwrite_pc=True):
        self.__logs.append('overwrite_sp=%s,overwrite_pc=%s' %
                           (overwrite_sp, overwrite_pc))

        s_date = target_date - datetime.timedelta(seconds=7200)
        e_date = target_date + datetime.timedelta(days=1, seconds=2700)
        str_target_date = target_date.strftime(Handler.TARGET_DATE_FORMAT)

        filters = {
            'state': PaymentData.Status.COMPLETED,
            'ctime__gte': s_date,
            'ctime__lt': e_date,
        }
        LIMIT = PaymentLogRequestData.ENTRY_NUM_MAX
        offset = 0
        overwrite_flags = {
            'sp': overwrite_sp,
            'pc': overwrite_pc,
        }
        request_key_format = target_date.strftime(
            'PaymentLog:%Y%m%d:{device}:{offset}')

        post_nums = {
            str_target_date: {
                'sp': 0,
                'pc': 0,
            }
        }

        def addPostNum(executedtime, device, cnt=1):
            str_date = executedtime.strftime(Handler.TARGET_DATE_FORMAT)
            nums = post_nums[str_date] = post_nums.get(str_date) or {
                'sp': 0,
                'pc': 0,
            }
            nums[device] += cnt

        while True:

            modellist = model_cls.fetchValues(['id', 'uid', 'price', 'inum'],
                                              filters=filters,
                                              limit=LIMIT,
                                              offset=offset,
                                              order_by='ctime',
                                              using=settings.DB_READONLY)
            if len(modellist) < 1:
                break

            requestdata_table = {}

            def getRequestData(device, executedtime):
                str_date = executedtime.strftime(Handler.TARGET_DATE_FORMAT)
                if str_target_date != str_date:
                    # 当日のレコードのみにする.
                    return None

                requestdata = requestdata_table.get(device)
                if requestdata is None:
                    requestdata = PaymentLogRequestData(
                        executedtime, device, overwrite_flags[device])
                    requestdata_table[device] = requestdata

                return requestdata

            model_mgr = ModelRequestMgr()
            for model in modellist:
                # PC版をリリース前にPaymentEntryにdevice判定用のカラムを付けた方がいいかも.->と思ったけど結局executedTimeを取らなきゃいけなくなったのでこのままで.
                player = BackendApi.get_player(self,
                                               model.uid, [],
                                               using=settings.DB_READONLY,
                                               model_mgr=model_mgr)
                record = BackendApi.get_restful_paymentrecord(
                    self, model.id, player.dmmid)
                is_pc = False
                if not str(record.paymentItems[0].itemId).isdigit():
                    # 無理やりだけど..
                    is_pc = True

                executedtime = record.executeTime
                if not isinstance(executedtime, datetime.datetime):
                    executedtime = DateTimeUtil.strToDateTime(
                        executedtime, "%Y-%m-%d %H:%M:%S")

                device = 'pc' if is_pc else 'sp'
                requestdata = getRequestData(device, executedtime)
                if requestdata:
                    requestdata.addPaymentEntry(model.id, model.price,
                                                model.inum)
                    self.__logs.append(u'%s' % model.id)
                addPostNum(executedtime, device)

            for requestdata in requestdata_table.values():
                if len(requestdata.paymentList) < 1:
                    continue
                request = self.osa_util.makeApiRequest(ApiNames.PaymentLog,
                                                       requestdata)
                reqkey = request_key_format.format(device=requestdata.device,
                                                   offset=offset)
                self.addAppApiRequest(reqkey, request)

                overwrite_flags[requestdata.device] = False

            ret_data = self.execute_api()
            if ret_data:
                try:
                    for reqkey in ret_data.keys():
                        response_data = ret_data[reqkey].get()
                        if not response_data['is_success']:
                            raise AppError('PaymentLogApi Error:%s:data=%s' %
                                           (response_data['message'],
                                            response_data['data']))
                except urllib2.HTTPError, er:
                    if er.fp is None:
                        error_message = str(er)
                    else:
                        error_message = er.read()
                    error_message = 'HttpError:%s' % error_message
                    self.addlogerror('PaymentLog Failure:%s' % error_message)
                    self.send(200, error_message)
                    return
                except AppError, er:
                    error_message = 'AppError:%s' % er.value
                    self.addlogerror('PaymentLog Failure:%s' % error_message)
                    self.send(200, error_message)
                    return
                except Exception:
                    DbgLogger.write_error(self.osa_util.logger.to_string())
                    raise
예제 #20
0
 def _proc_view_record(self):
     """シリアルコードのレコード情報を表示.
     """
     CONTENT_NUM_PER_PAGE = 100
     # ページング.
     page = int(self.request.get('_page') or 0)
     
     # 検索条件を取得.
     serchtype = self.request.get('_serchtype')
     
     # 検索する日付.
     str_target_date = self.request.get('_date')
     
     # 検索用の値を取得.
     value = self.request.get('_value') or ''
     mid = self.request.get('_mid') or ''
     shareserial = self.request.get('_share') == '1'
     
     int_value = None
     if value.isdigit():
         int_value = int(value)
     self.html_param['_serchtype'] = serchtype
     self.html_param['_date'] = str_target_date
     self.html_param['_value'] = value
     self.html_param['_mid'] = mid
     self.html_param['shareserial'] = shareserial
     
     # シリアルコードの検索条件.
     filters = None
     if serchtype == 'uid':
         if int_value:
             filters = {
                 'uid' : int_value,
             }
     elif serchtype == 'dmmid':
         if value:
             uid = BackendApi.dmmid_to_appuid(self, [value], using=backup_db).get(value)
             if uid:
                 filters = {
                     'uid' : uid,
                 }
     elif serchtype == 'serial':
         if value:
             arr = list(set(value.split(',')))
             filters = {
                 'serial__in' : arr,
             }
     elif serchtype == 'mid':
         target_date = None
         if str_target_date:
             try:
                 target_date = DateTimeUtil.strToDateTime(str_target_date, "%Y-%m-%d")
             except:
                 pass
         if target_date is None:
             self.putAlertToHtmlParam(u'日付はyyyy-mm-ddで入力してください', AlertCode.ERROR)
             return
         
         if mid and mid.isdigit():
             mid = int(mid)
             master = BackendApi.get_serialcampaign_master(self.getModelMgr(), mid, using=backup_db)
             if master and master.share_serial == shareserial:
                 filters = {
                     'mid' : mid,
                     'itime__gte' : target_date,
                     'itime__lt' : target_date + datetime.timedelta(days=1),
                 }
     
     # シリアルコードを取得.
     serialcode_list = None
     has_next = False
     if filters:
         offset = page * CONTENT_NUM_PER_PAGE
         limit = CONTENT_NUM_PER_PAGE + 1
         model_cls = ShareSerialLog if shareserial else SerialCode
         serialcode_list = model_cls.fetchValues(filters=filters, order_by='-itime', limit=limit, offset=offset, using=backup_db)
         has_next = CONTENT_NUM_PER_PAGE < len(serialcode_list)
         serialcode_list = serialcode_list[:CONTENT_NUM_PER_PAGE]
     
     # 見つからなかった.
     if not serialcode_list:
         self.putAlertToHtmlParam(u'シリアルコードが見つかりませんでした', AlertCode.WARNING)
         return
     
     # テーブルのタイトル.
     self.__init_table(u'シリアルコード情報')
     self.__add_table_title('mid', u'キャンペーンID')
     self.__add_table_title('user', u'ユーザ')
     self.__add_table_title('serial', u'シリアルコード')
     self.__add_table_title('itime', u'入力した時間')
     self.__add_table_title('point', u'生涯課金額')
     self.__add_table_title('paymentlog', u'入力後2ヶ月間の購入履歴')
     
     # テーブルの作成.
     uidlist = list(set([serialcode.uid for serialcode in serialcode_list if 0 < serialcode.uid]))
     playerpoint_dict = dict([(model.id, model.point_total) for model in PlayerConsumePoint.getByKey(uidlist, using=backup_db)])
     url_paymentlog = OSAUtil.addQuery(UrlMaker.view_paymentlog(), '_logtype', 'gacha')
     url_paymentlog = OSAUtil.addQuery(url_paymentlog, '_is_complete', '1')
     url_paymentlog = OSAUtil.addQuery(url_paymentlog, '_serchtype', 'uid')
     
     for serialcode in serialcode_list:
         if serialcode.uid:
             url = UrlMaker.view_player(serialcode.uid)
             celldata_user = self.__make_table_celldata(serialcode.uid, self.makeAppLinkUrl(url))
             
             stime = serialcode.itime
             etime = serialcode.itime + datetime.timedelta(days=60)
             url = OSAUtil.addQuery(url_paymentlog, '_value', serialcode.uid)
             url = OSAUtil.addQuery(url, '_stime', urllib.quote(stime.strftime('%Y/%m/%d %H:%M:%S'), ''))
             url = OSAUtil.addQuery(url, '_etime', urllib.quote(etime.strftime('%Y/%m/%d %H:%M:%S'), ''))
             celldata_paymentlog = self.__make_table_celldata(u'購入履歴≫', self.makeAppLinkUrl(url))
         else:
             celldata_user = self.__make_table_celldata(u'未入力')
             celldata_paymentlog = self.__make_table_celldata(u'----')
         
         row = {
             'mid' : self.__make_table_celldata(serialcode.mid),
             'user' : celldata_user,
             'serial' : self.__make_table_celldata(serialcode.serial),
             'itime' : self.__make_table_celldata(serialcode.itime.strftime("%Y/%m/%d %H:%M:%S")),
             'point' : self.__make_table_celldata(playerpoint_dict.get(serialcode.uid, 0)),
             'paymentlog' : celldata_paymentlog,
         }
         self.__add_table_data(row)
     
     # ページング.
     url_prev = None
     url_next = None
     page_query_params = {
         '_proc' : 'view_record',
         '_serchtype' : serchtype,
         '_value' : value,
     }
     if 0 < page:
         url_prev = self.__make_url_self(_page=page-1, **page_query_params)
     if has_next:
         url_next = self.__make_url_self(_page=page+1, **page_query_params)
     self.html_param['url_prev'] = url_prev
     self.html_param['url_next'] = url_next
예제 #21
0
    def handle(self, *args, **options):

        print '================================'
        print 'aggregate_cabaretclub_weekly'
        print '================================'

        last_week_starttime = BackendApi.to_cabaretclub_section_starttime(
            OSAUtil.get_now() - datetime.timedelta(days=7))

        str_year_and_week = args[0] if 0 < len(args) else None
        if str_year_and_week:
            week = int(str_year_and_week[4:])
            first_of_year = DateTimeUtil.strToDateTime(
                "%s%02d" % (str_year_and_week[:4],
                            Defines.CABARETCLUB_EVENT_DATE_CHANGE_TIME),
                "%Y%H")
            # 0週目.
            zero = BackendApi.to_cabaretclub_section_starttime(first_of_year)
            starttime = zero + datetime.timedelta(days=week * 7)
            if last_week_starttime < starttime:
                print u'未完了の週なので集計は行えません'
                return
        else:
            # 指定がない場合は前回の週.
            starttime = last_week_starttime
        print "target:%s" % starttime.strftime("%Y%W")
        endtime = BackendApi.to_cabaretclub_section_endtime(starttime)
        section_lasttime = endtime - datetime.timedelta(microseconds=1)

        model_mgr = ModelRequestMgr()
        self.update_eventconfig_previous_mid(model_mgr, starttime)

        # 店舗のマスターデータ.
        cabaclubstoremaster_dict = dict([
            (cabaclubstoremaster.id, cabaclubstoremaster)
            for cabaclubstoremaster in model_mgr.get_mastermodel_all(
                CabaClubStoreMaster, fetch_deleted=True, using=backup_db)
        ])
        # ユーザIDの最大値.
        uid_max = PlayerTreasure.max_value('id', using=backup_db)
        for uid in xrange(1, uid_max + 1):
            # 所持している店舗.ここはreadonlyで大丈夫.
            store_list = CabaClubStorePlayerData.fetchByOwner(
                uid, using=settings.DB_READONLY)
            if store_list:
                # この週に更新された店舗数.
                update_store_cnt = 0
                # Activeな店舗を週の終了時間まですすめる.
                for store in store_list:
                    cabaclubstoremaster = cabaclubstoremaster_dict[store.mid]
                    if not store.is_open:
                        # 閉じるときに集計しているので必要なし.
                        if starttime <= store.utime:
                            update_store_cnt += 1
                        continue
                    store_set = CabaclubStoreSet(cabaclubstoremaster, store)
                    lasttime = min(
                        section_lasttime,
                        store_set.get_limit_time() -
                        datetime.timedelta(microseconds=1))
                    if (lasttime - store.utime).total_seconds(
                    ) < cabaclubstoremaster.customer_interval:
                        # 獲得時間が経過していないので更新する必要が無い.
                        if starttime <= store.utime:
                            update_store_cnt += 1
                        continue

                    def tr_advance_the_time(uid, cabaclubstoremaster, now):
                        """店舗の時間をすすめる.
                        """
                        model_mgr = ModelRequestMgr()
                        BackendApi.tr_cabaclubstore_advance_the_time_with_checkalive(
                            model_mgr, uid, cabaclubstoremaster, now)
                        model_mgr.write_all()
                        model_mgr.write_end()

                    try:
                        db_util.run_in_transaction(tr_advance_the_time, uid,
                                                   cabaclubstoremaster,
                                                   lasttime)
                    except CabaretError, err:
                        if err.code == CabaretError.Code.ALREADY_RECEIVED:
                            # ユーザー自信が更新した可能性.
                            pass
                        else:
                            DbgLogger.write_error(err.value)
                            raise
                    update_store_cnt += 1
                if 0 < update_store_cnt:
                    # 売り上げに応じた名誉ポイントを配布.
                    def tr_send_point(uid, starttime):
                        """名誉ポイントの配布.
                        """
                        model_mgr = ModelRequestMgr()
                        scoredata_weekly = CabaClubScorePlayerDataWeekly.getByKeyForUpdate(
                            CabaClubScorePlayerDataWeekly.makeID(
                                uid, starttime))
                        if scoredata_weekly is None or scoredata_weekly.flag_aggregate:
                            return 0
                        # 配布する数を計算.
                        cabaclub_honor = int(
                            math.ceil(scoredata_weekly.proceeds / 1000.0))
                        if 0 < cabaclub_honor:
                            # 報酬付与.
                            prizedata = PrizeData.create(
                                cabaclub_honor=cabaclub_honor)
                            BackendApi.tr_add_prize(
                                model_mgr, uid, [prizedata],
                                Defines.TextMasterID.CABARETCLUB_WEEKLY_PRIZE)
                        # 重複防止.
                        scoredata_weekly.flag_aggregate = True
                        model_mgr.set_save(scoredata_weekly)
                        model_mgr.write_all()
                        model_mgr.write_end()
                        return cabaclub_honor

                    cabaclub_honor = db_util.run_in_transaction(
                        tr_send_point, uid, starttime)
                    print '%s...honor=%d' % (uid, cabaclub_honor)
                else:
                    print '%s...not updated' % uid
예제 #22
0
 def to_datetime(st):
     try:
         return DateTimeUtil.strToDateTime(st, '%Y/%m/%d %H:%M:%S')
     except:
         return None
예제 #23
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
예제 #24
0
    def handle(self, *args, **options):

        print '================================'
        print 'recov_present'
        print '================================'

        IS_TEST = args[0] != 'write'
        # 問題の発生時間.
        #        targetstime = DateTimeUtil.strToDateTime("2014-06-13 00:00:00", "%Y-%m-%d %H:%M:%S")
        print 'TEST_MODE=%s' % IS_TEST
        """間違えて配った新店舗ランキング報酬を削除.
        とりあえずredisだけ.MySQLは直接消す.
        """
        targetstime = DateTimeUtil.strToDateTime("2014-11-18 15:00:00",
                                                 "%Y-%m-%d %H:%M:%S")
        for present in Present.fetchValues(['id', 'toid', 'itype'], {
                'textid': 144,
                'ctime__gte': targetstime
        }):
            BackendApi.remove_present(present.toid, present.id, present.itype)
            print 'delete...(%s,%s,%s)' % (present.toid, present.id,
                                           present.itype)

#        worked = (660,1661,3581,3720,8126,9614,16668,17376,17509,21214,22047,24504,24561,28933,29917,30368,32027,32498,32769,33609,34236,34841,40884,41124,42399,43762,44215,48391,48677,49798,50201,51676,52670,53295,55290,55910,56477,56838,57510,58601,59730,60412,63282,67219,69693,73282,73500,75072,78939,82382,83309,85689,86435,88635,90980,94654,99140,99325,103059,105616,105626,105964,111016,112823,114409,120378,121419,134001,134259,135012,136129,139024,139036,139055,139057,139066,139088,139115,139116,139121,139151,139159,139162,139200,139323,139331,139332,139335,139364,139367,139386,139451,139453,139523,139540,139582,139583,139606,139610,139618,139625,139627,139675,139694,139703,139721,139722,139727,139733,139746,139815,139820,139850,139854,139857,139871,139892,139912,139932,139970,140006,140047,140054,140061,140070,140076,140113,140117,140160,140175,140189,140224,140233,140240,140266,140328,140329,140363,140366,140412,140418,140419,140453,140459,140475,140493,140503,140518,140557,140612,140618,140644,140646,140666,140671,140692,140695,140735,140739,140743,140775,140792,140809,140842,140871,140884,140888,140892,140893,140897,140939,140985,140986,140993,141006,141015,141030,141051,141064,141074,141109,141130,141139,141161,141175,141182,141197,141203,141211,141221,141225,141227,141229,141249,141284,141292,141332,141346,141351,141368,141400,141414,141444,141462,141533,141541,141542,141578,141583,141585,141604,141703,141708,141719,141736,141754,141762,141783,141792,141794,141795,141796,141810,141817,141818,141834,141844,141867,141891,141893,141901)
#
#        if settings_sub.IS_DEV:
#            LIMIT = 1
#        else:
#            LIMIT = 500
#        itemid = Defines.ItemEffect.CARD_BOX_EXPANSION
#
#        """
#        ・全プレID:10を受け取ったユーザーのアイテム所持数を1個減らす。減らせない場合はプレゼントを削除。
#        ・2014-06-13 00:00:00以降に全プレID:9を受け取ったユーザーのアイテム所持数を4個増やす。
#        """
#
#        # 全プレID:10を受け取ったユーザーのアイテム所持数を1個減らす。減らせない場合はプレゼントを削除.
#        offset = 0
#        filters = {
#            'mid' : 10,
#        }
#
#        unable_nums = {}
#
#        print 'start ID=10'
#        while True:
#            modellist = PresentEveryoneReceiveMypage.fetchValues(filters=filters, order_by='id', limit=LIMIT, offset=offset)
#            if not modellist:
#                break
#
#            delete_num = 0
#            for model in modellist:
#                uid = model.uid
#
#                # 所持数確認.
#                item = Item.getByKey(Item.makeID(uid, itemid))
#                if item and 0 < item.vnum:
#                    if not IS_TEST:
#                        def tr_item(modelid, uid, itemid):
#                            # 所持数を減らす.
#                            model_mgr = ModelRequestMgr()
#                            BackendApi.tr_add_item(model_mgr, uid, itemid, -1)
#
#                            # 受け取りフラグを消す.
#                            model = PresentEveryoneReceiveMypage.getByKeyForUpdate(modelid)
#                            model_mgr.set_delete(model)
#
#                            model_mgr.write_all()
#                            return model_mgr
#                        db_util.run_in_transaction(tr_item, model.id, uid, itemid).write_end()
#                        delete_num += 1
#                    print '%s=>item' % uid
#                else:
#                    # プレゼントを探す.
#                    present = Present.getValues(filters={'toid':uid,'itype':Defines.ItemType.ITEM,'ivalue':itemid,'inum':1})
#                    if present is None:
#                        # ここに来るのは受取済みで使用済み.
#                        unable_nums[uid] = 1
#                        print 'unable %s' % uid
#                    else:
#                        if not IS_TEST:
#                            def tr_present(modelid, uid, presentid):
#                                model_mgr = ModelRequestMgr()
#
#                                # プレゼントを消す.
#                                present = Present.getByKeyForUpdate(presentid)
#                                model_mgr.set_delete(present)
#
#                                # 受け取りフラグを消す.
#                                model = PresentEveryoneReceiveMypage.getByKeyForUpdate(modelid)
#                                model_mgr.set_delete(model)
#
#                                def writeEnd():
#                                    BackendApi.remove_present(uid, presentid)
#                                model_mgr.add_write_end_method(writeEnd)
#
#                                model_mgr.write_all()
#                                return model_mgr
#                            db_util.run_in_transaction(tr_present, model.id, uid, present.id).write_end()
#                            delete_num += 1
#                        print '%s=>present %d' % (uid, present.id)
#            offset += LIMIT - delete_num

#        # 2014-06-13 00:00:00以降に全プレID:9を受け取ったユーザーのアイテム所持数を4個増やす.
#        offset = 0
#        filters = {
#            'mid' : 9,
#            'rtime__gte' : targetstime,
#        }
#        print 'start ID=9'
#        while True:
#            modellist = PresentEveryoneReceiveMypage.fetchValues(filters=filters, order_by='id', limit=LIMIT, offset=offset)
#            offset += LIMIT
#            if not modellist:
#                break
#
#            uidlist = list(set([model.uid for model in modellist]))
#            for uid in uidlist:
#                add_num = 4 - unable_nums.get(uid, 0)
#                if not IS_TEST:
#                    def tr(uid, itemid, add_num):
#                        model_mgr = ModelRequestMgr()
#                        BackendApi.tr_add_item(model_mgr, uid, itemid, add_num)
#                        model_mgr.write_all()
#                        return model_mgr
#                    db_util.run_in_transaction(tr, uid, itemid, add_num).write_end()
#                print 'add item:%s=>%d' % (uid, add_num)
#
#        # 2014-05-23 16:00:00以降に全プレID:7を受け取ったユーザーのアイテム所持数を1個減らす.減らせない場合はプレゼントを消す.
#        targetstime = DateTimeUtil.strToDateTime("2014-05-23 16:00:00", "%Y-%m-%d %H:%M:%S")
#
#        offset = 0
#        filters = {
#            'mid' : 7,
#            'rtime__gte' : targetstime,
#        }
#        print 'start ID=7'
#        while True:
#            modellist = PresentEveryoneReceiveMypage.fetchValues(filters=filters, order_by='id', limit=LIMIT, offset=offset)
#            if not modellist:
#                break
#
#            delete_num = 0
#            for model in modellist:
#                uid = model.uid
#                if uid in worked:
#                    # 処理済み.
#                    continue
#
#                # 所持数確認.
#                item = Item.getByKey(Item.makeID(uid, itemid))
#                if item and 0 < item.vnum:
#                    if not IS_TEST:
#                        def tr_item(modelid, uid, itemid):
#                            # 所持数を減らす.
#                            model_mgr = ModelRequestMgr()
#                            BackendApi.tr_add_item(model_mgr, uid, itemid, -1)
#
#                            # 受け取りフラグを消す.
#                            model = PresentEveryoneReceiveMypage.getByKeyForUpdate(modelid)
#                            model_mgr.set_delete(model)
#
#                            model_mgr.write_all()
#                            return model_mgr
#                        db_util.run_in_transaction(tr_item, model.id, uid, itemid).write_end()
#                        delete_num += 1
#                    print '%s=>item' % uid
#                else:
#                    # プレゼントを探す.
#                    present = Present.getValues(filters={'toid':uid,'itype':Defines.ItemType.ITEM,'ivalue':itemid,'inum':1})
#                    if present is None:
#                        # ボックス上限を減らす.
#                        if not IS_TEST:
#                            def tr_player(modelid, uid):
#                                model_mgr = ModelRequestMgr()
#
#                                player = PlayerDeck.getByKeyForUpdate(uid)
#                                player.cardlimititem = max(0, player.cardlimititem - 20)
#                                model_mgr.set_save(player)
#
#                                # 受け取りフラグを消す.
#                                model = PresentEveryoneReceiveMypage.getByKeyForUpdate(modelid)
#                                model_mgr.set_delete(model)
#
#                                model_mgr.write_all()
#                                return model_mgr
#                            db_util.run_in_transaction(tr_player, model.id, uid).write_end()
#                            delete_num += 1
#                        print 'box %s' % uid
#                    else:
#                        if not IS_TEST:
#                            def tr_present(modelid, uid, presentid):
#                                model_mgr = ModelRequestMgr()
#
#                                # プレゼントを消す.
#                                present = Present.getByKeyForUpdate(presentid)
#                                model_mgr.set_delete(present)
#
#                                # 受け取りフラグを消す.
#                                model = PresentEveryoneReceiveMypage.getByKeyForUpdate(modelid)
#                                model_mgr.set_delete(model)
#
#                                def writeEnd():
#                                    BackendApi.remove_present(uid, presentid)
#                                model_mgr.add_write_end_method(writeEnd)
#
#                                model_mgr.write_all()
#                                return model_mgr
#                            db_util.run_in_transaction(tr_present, model.id, uid, present.id).write_end()
#                            delete_num += 1
#                        print '%s=>present %d' % (uid, present.id)
#            offset += LIMIT - delete_num

        print '================================'
        print 'all done..'
예제 #25
0
    def handle(self, *args, **options):
        
        print '================================'
        print 'support'
        print '================================'
        
        # 出力先.
        path = OSAUtil.get_now().strftime(args[0])
        
        # 書き込むデータをここに溜め込む.
        writer = Command.Writer(path)
        
        # レイドマスター.
        model_mgr = ModelRequestMgr()
        raid_all = dict([(master.id, master) for master in model_mgr.get_mastermodel_all(RaidMaster, using=settings.DB_READONLY)])
        eventraid_all = dict([(master.mid, master) for master in model_mgr.get_mastermodel_all(RaidEventRaidMaster, using=settings.DB_READONLY)])
        
        # 対象のユーザ.
        UIDLIST = [16268, 29339]
        UIDSET = set(UIDLIST)
        
        UNKNOWNS = [
            56272661512882,
            56272661512893,
            87759066759449,
            99127845191766,
            128943508160593,
            136047384068178,
            137099651055617,
            137550622621716,
            143374598275073,
            149615185756161,
            157689724272723,
            165957536317441,
            172352742621192,
            183549722361857,
            193870528774147,
        ]
        
        # 対象の時間.
        filters = {
            'ctime__gte' : DateTimeUtil.strToDateTime("2014-01-07 15:00:00", "%Y-%m-%d %H:%M:%S"),
            'ctime__lt' : DateTimeUtil.strToDateTime("2014-01-13 19:00:00", "%Y-%m-%d %H:%M:%S"),
            'hp' : 0,
        }
        LIMIT = 1000
        
        offset = 0
        
        timebonus_time_min = DateTimeUtil.strToDateTime("2014-01-13 17:00:00", "%Y-%m-%d %H:%M:%S")
        timebonus_time_max = DateTimeUtil.strToDateTime("2014-01-13 19:00:00", "%Y-%m-%d %H:%M:%S")
        
        # 対象のハプニング.
        while True:
            raidlist = Raid.fetchValues(filters=filters, order_by='id', limit=LIMIT, offset=offset)
            
            for raid in raidlist:
                raidboss = RaidBoss(raid, raid_all[raid.mid], eventraid_all.get(raid.mid))
                if raid.id in UNKNOWNS:
                    print raid.id
                
                uidset = set(raidboss.getDamageRecordUserIdList())
                targetlist = list(UIDSET & uidset)
                if not targetlist:
                    continue
                
                helppoints = raidboss.getHelpEventPoints()
                for uid in targetlist:
                    owner = 0
                    mvp = 0
                    helppoint = 0
                    
                    if uid == raidboss.raid.oid:
                        # 発見者報酬.
                        owner = raidboss.get_owner_eventpoint()
                    else:
                        # 協力者報酬.
                        helppoint = helppoints.get(uid, 0)
                    
                    # MVP報酬.
                    mvpuidlist = raidboss.getMVPList()
                    for mvpuid in mvpuidlist:
                        if uid == mvpuid:
                            mvp += raidboss.get_mvp_eventpoint()
                    if not (owner or mvp or helppoint):
                        print raidboss.id
                    else:
                        text = '%s,%s,%s,%s,%s' % (uid, owner, mvp, helppoint, raid.ctime.strftime("%Y-%m-%d %H:%M"))
                        writer.add(text)
#                        print text
                
            if len(raidlist) < LIMIT:
                break
            offset += LIMIT
        
        writer.output(overwrite=False)
        
        print '================================'
        print 'all done..'