예제 #1
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
예제 #2
0
 def get_data(self):
     """ユーザごとのガチャデータ.
     """
     # 7日前.
     s_time = DateTimeUtil.toBaseTime(self.date - datetime.timedelta(days=7), 0)
     e_time = self.date
     
     # 過去1週間以内にログインしたユーザー.
     str_uidlist = WeeklyLoginSet.getUserIdListByRange(s_time, e_time)
     
     # 対象のガチャ.
     filters = {
         'consumetype__in' : Defines.GachaConsumeType.PAYMENT_TYPES,
     }
     gachamasterlist = GachaMaster.fetchValues(filters=filters, order_by='id', using=backup_db)
     
     model_mgr = ModelRequestMgr()
     
     def checkSchedule(gachamaster):
         if gachamaster.schedule:
             # 期間チェック.
             master = model_mgr.get_model(ScheduleMaster, gachamaster.schedule, using=backup_db)
             if master and ((master.stime <= master.etime <= s_time) or (e_time < master.stime <= master.etime)):
                 # 期間外.
                 return False
         return True
     
     midlist = [gachamaster.id for gachamaster in gachamasterlist if checkSchedule(gachamaster)]
     self.__midlist = midlist
     
     redisdb = GachaLastStepSortSet.getDB()
     result = []
     if midlist:
         for str_uid in str_uidlist:
             if not str_uid or not str(str_uid).isdigit():
                 continue
             uid = int(str_uid)
             
             tmp_model_mgr = ModelRequestMgr()
             idlist = [GachaPlayCount.makeID(uid, mid) for mid in midlist]
             # 回転数.
             countdict = BackendApi.get_model_dict(tmp_model_mgr, GachaPlayCount, idlist, using=backup_db, key=lambda x:x.mid)
             
             # 課金額.
             paydict = BackendApi.get_model_dict(tmp_model_mgr, GachaConsumePoint, idlist, using=backup_db, key=lambda x:x.mid)
             
             for mid in midlist:
                 if not countdict.get(mid):
                     continue
                 cnt = countdict[mid].cnttotal
                 pay = paydict[mid].point if paydict.get(mid) else 0
                 step = redisdb.zscore(GachaLastStepSortSet.makeKey(self.date, mid), uid) or 0
                 result.append((uid, mid, cnt, pay, step))
     return result
예제 #3
0
    def get_data(self):

        # 直近2週間で取ってきてみる.
        DAYS = 14
        date_from = self.date - datetime.timedelta(days=DAYS)
        date_to = OSAUtil.get_now()

        # ガチャのマスターデータ.
        gachamaster_dict = dict([(master.id, master)
                                 for master in GachaMaster.fetchValues(
                                     fetch_deleted=True, using=backup_db)])
        # カードのマスターデータ.
        cardmaster_dict = dict([(master.id, master)
                                for master in CardMaster.fetchValues(
                                    fetch_deleted=True, using=backup_db)])

        # 対象のユーザー.
        uidlist = PaymentGachaLastPlayTimeSortedSet.fetchByDate(
            date_from, date_to)

        result = [[
            'ユーザID', '生涯課金額', 'ガチャ1', 'ガチャを回した時のリーダー1', 'ガチャ2',
            'ガチャを回した時のリーダー2', 'ガチャ3', 'ガチャを回した時のリーダー3'
        ]]

        for uid in uidlist:
            row = [uid]

            # 生涯課金額.
            model = PlayerConsumePoint.getByKey(uid, using=backup_db)
            row.append(model.point_total if model else 0)

            redisdata = PaymentGachaPlayerLeaderHash.getByUserIDList(
                [uid]).get(uid) or {}
            items = list(redisdata.items())
            items.sort(key=lambda x: x[1]['date'], reverse=True)

            for gachaid, data in items:
                # 引いたガチャ.
                gachamaster = gachamaster_dict[gachaid]
                # その時のリーダー.
                cardmaster = cardmaster_dict[data['card']]

                row.extend([
                    u'%s(ID:%d)' % (gachamaster.name, gachamaster.id),
                    u'%s(ID:%d)' % (cardmaster.name, cardmaster.id)
                ])
            result.append(row)

        return result
예제 #4
0
    def __valid_master(self, master):
        if not master.is_public:
            return

        if GachaMaster.getByKey(master.id) is None:
            raise ModelEditValidError(u'ガチャが存在しません.master=%d' % master.id)

        model_mgr = self.getModelMgr()
        if not isinstance(master.castlist, list):
            raise ModelEditValidError(u'castlistのJSONが壊れています.master=%d' %
                                      master.id)

        if self.valid_error_num < 10:
            for record in self.allmasters:
                if master.id == record.id:
                    self.valid_error_num += 1
                    raise ModelEditValidError(u'IDが重複しています.id={}'.format(
                        master.id))

        # 旧式のデータを新方式に置き換える.
        castlist = []
        for v in master.castlist:
            if isinstance(v, (int, long)):
                castlist.append([v, ''])
                continue
            elif not isinstance(
                    v, (list, tuple)) or len(v) != 2 or not isinstance(
                        v[0],
                        (int, long)) or not isinstance(v[1],
                                                       (str, unicode, list)):
                raise ModelEditValidError(
                    u'castlistは[[マスターID,画像]...]で設定してください.master=%d' %
                    master.id)
            castlist.append(v)

        master.castlist = castlist
        castdict = dict(castlist)
        if len(
                BackendApi.get_cardmasters(
                    castdict.keys(), arg_model_mgr=model_mgr).values()) != len(
                        master.castlist):
            raise ModelEditValidError(
                u'castlistに重複または存在しないものが含まれています.master=%d' % master.id)
예제 #5
0
    def getGachaMasterList(self, mid):
        """集計対象のガチャのリストを取得.
        """
        if not mid:
            return []

        model_mgr = self.getModelMgr()
        master = BackendApi.get_gachamaster(model_mgr,
                                            mid,
                                            using=settings.DB_READONLY)
        if master is None:
            return []

        if not master.stepid:
            return [master]

        masterlist = GachaMaster.fetchValues(filters={'stepid': master.stepid},
                                             using=settings.DB_READONLY)
        masterlist.sort(key=lambda x: x.step)
        return masterlist
예제 #6
0
    def get_special_gachamaster(self, model_mgr, special_gacha_consumetypes,
                                search_start_time, search_end_time):
        #特定のコンシュームタイプで、ガチャのスケージュールが特定の期間ならそれは特効ガチャのはず。
        gachamaster_list = GachaMaster.fetchValues(filters=({
            'consumetype__in':
            special_gacha_consumetypes
        }),
                                                   using=backup_db)

        special_gachamasters = []
        for gachamaster in gachamaster_list:
            schedule_master = model_mgr.get_model(ScheduleMaster,
                                                  gachamaster.schedule)
            if search_start_time.date() <= schedule_master.stime.date(
            ) and schedule_master.etime.date() <= search_end_time.date():
                special_gachamasters.append(gachamaster)

        if special_gachamasters:
            return special_gachamasters
        else:
            self.putAlertToHtmlParam(u'特効ガチャが見つけられませんでした', AlertCode.INFO)
            return None
예제 #7
0
    def handle(self, *args, **options):

        print '================================'
        print 'copy_img'
        print '================================'

        out = args[0]

        # ガチャのマスターを取得.
        gachalist = GachaMaster.fetchValues(filters={
            'consumetype__in':
            Defines.GachaConsumeType.PAYMENT_TYPES,
            'schedule__gt':
            0
        },
                                            using=backup_db)

        # ガチャのボックスデータを作成.
        read_boxids = []

        card_dict = {}
        for gacha in gachalist:
            if gacha.boxid in read_boxids:
                continue

            schedule = ScheduleMaster.getByKey(gacha.schedule, using=backup_db)
            name = u'%s(%s-%s)' % (gacha.name,
                                   schedule.stime.strftime('%m/%d'),
                                   schedule.stime.strftime('%m/%d'))

            boxmaster = GachaBoxMaster.getByKey(gacha.boxid, using=backup_db)
            gachamasterset = GachaMasterSet(gacha, boxmaster, schedule)

            gachabox = GachaBox(gachamasterset,
                                GachaPlayData.makeInstance(
                                    GachaPlayData.makeID(0, gacha.boxid)),
                                blank=True)
            grouplist = GachaGroupMaster.getByKey(gachabox.get_group_id_list(),
                                                  using=backup_db)

            # カードIDとガチャのIDをひもづける.
            for group in grouplist:
                if 1 < len(group.table):
                    continue
                cardid = group.table[0]['id']
                arr = card_dict[cardid] = card_dict.get(cardid) or []
                arr.append(name)

        # カードマスターを取得.
        cardmasterlist = CardMaster.getByKey(card_dict.keys(),
                                             order_by='id',
                                             using=backup_db)

        # CSVを作成.
        rows = []

        def makeRow(row):
            arr = []
            for v in row:
                s = u'%s' % v
                s = s.replace('"', '""')
                arr.append(u'"%s"' % s)
            return u','.join(arr)

        for cardmaster in cardmasterlist:
            cardsortmaster = CardSortMaster.getByKey(cardmaster.id,
                                                     using=backup_db)

            row = [
                cardmaster.id, cardmaster.name,
                Defines.Rarity.NAMES[cardsortmaster.rare],
                Defines.CharacterType.NAMES[cardsortmaster.ctype]
            ]
            row.extend(card_dict[cardmaster.id])
            str_row = makeRow(row)
            print str_row
            rows.append(str_row)
        csv_data = StrUtil.to_s(u'\n'.join(rows), dest_enc='shift-jis')

        f = None
        try:
            f = open(out, "w")
            f.write(csv_data)
            f.close()
        except:
            if f:
                f.close()
                f = None
            raise

        print '================================'
        print 'output:%s' % out
        print 'all done..'
예제 #8
0
    def handle(self, *args, **options):

        print '================================'
        print 'close_rankinggacha'
        print '================================'

        model_mgr = ModelRequestMgr()

        now = OSAUtil.get_now()

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

        print '================================'
        print 'check master'
        group = int(args[0])
        master_list = BackendApi.get_rankinggacha_master_by_group(
            model_mgr, group, using=settings.DB_READONLY)
        if not master_list:
            print u'ランキングガチャではありません'
            return
        boxidlist = [master.id for master in master_list]
        master_dict = dict([(master.id, master) for master in master_list])
        gachamaster_list = GachaMaster.fetchValues(
            filters={'boxid__in': boxidlist}, using=settings.DB_READONLY)
        gachamaster_list = [
            gachamaster.id for gachamaster in gachamaster_list
            if BackendApi.check_schedule(model_mgr,
                                         gachamaster.schedule,
                                         using=settings.DB_READONLY,
                                         now=now)
        ]
        if gachamaster_list:
            print u'ガチャが開いています.id=%s' % gachamaster_list
            return
        print 'check master...OK'

        print '================================'
        print 'update ranking:start'
        # ランキングを更新.
        for master in master_list:
            offset = 0
            limit = 1000
            flag_support_totalranking = master.is_support_totalranking

            while True:
                recordlist = RankingGachaScore.fetchValues(
                    filters={'mid': master.id}, limit=limit, offset=offset)

                pipe = RankingGachaSingleRanking.getDB().pipeline()
                for record in recordlist:
                    RankingGachaSingleRanking.create(master.id, record.uid,
                                                     record.single).save(pipe)
                    if flag_support_totalranking:
                        RankingGachaTotalRanking.create(
                            master.id, record.uid, record.total).save(pipe)
                pipe.execute()

                if len(recordlist) < limit:
                    break
                offset += limit
        print 'update ranking:end'

        print '================================'
        print 'send ranking prizes:start'
        for master in master_list:
            boxid = master.id

            close_model = RankingGachaClose.getByKey(boxid)
            if close_model is None:
                close_model = RankingGachaClose.makeInstance(boxid)
                close_model.insert()

            print 'start...single'
            close_model = self.__send_prize(model_mgr, master.singleprizes,
                                            master.singleprize_text,
                                            close_model, 'prize_flag_single',
                                            RankingGachaSingleRanking)

            if flag_support_totalranking:
                print 'start...total'
                close_model = self.__send_prize(model_mgr, master.totalprizes,
                                                master.totalprize_text,
                                                close_model,
                                                'prize_flag_total',
                                                RankingGachaTotalRanking)

        print '================================'
        print 'send whole prizes:start'
        # 勝利したBOX.
        wholedata_list = RankingGachaWholeData.getByKey(boxidlist)
        arr = [(wholedata.id, wholedata.point) for wholedata in wholedata_list]
        arr.sort(key=lambda x: x[1], reverse=True)
        winner = []
        point_max = None
        for boxid, point in arr:
            if point_max is not None and point < point_max:
                break
            elif point < 1:
                break
            winner.append(boxid)
            point_max = point
        print 'winner:%s' % winner

        queuelist = RankingGachaWholePrizeQueue.fetchValues(
            filters={'boxid__in': boxidlist})
        queuelist.sort(key=lambda x: x.id)

        boxidlist.sort()
        close_model_boxid = boxidlist[0]
        close_model = RankingGachaClose.getByKey(close_model_boxid)

        uid_max = Player.max_value('id')
        for uid in xrange(close_model.prize_flag_whole + 1, uid_max + 1):
            # 全員について検証.
            data = RankingGachaWholePrizeData.getByKey(uid)
            if data is None:
                # 未プレイ.
                continue

            # スコア情報.
            firstpoint_dict = dict([
                (scoredata.mid, scoredata.firstpoint)
                for scoredata in RankingGachaScore.getByKey([
                    RankingGachaScore.makeID(uid, boxid) for boxid in boxidlist
                ])
            ])

            # 未受け取り分.
            queuelist_not_received = [
                queue for queue in queuelist
                if data.queueid < queue.id and firstpoint_dict.get(queue.boxid)
                and firstpoint_dict[queue.boxid] <= queue.point
            ]

            # 勝利判定.
            win_boxidlist = list(set(firstpoint_dict.keys()) & set(winner))

            if not (queuelist_not_received or win_boxidlist):
                # 未受け取りの報酬が無い 且つ 敗北.
                continue

            try:
                model_mgr, close_model = db_util.run_in_transaction(
                    self.__tr_send_wholeprize, uid, queuelist_not_received,
                    master_dict, win_boxidlist, close_model_boxid)
                model_mgr.write_end()
                print '%d...receive' % uid
            except CabaretError, err:
                if err.code == CabaretError.Code.ALREADY_RECEIVED:
                    # 受取済みのキューを指定していた.
                    model_mgr, close_model = db_util.run_in_transaction(
                        self.__tr_send_wholeprize, uid, [], master_dict,
                        win_boxidlist, close_model_boxid)
                    model_mgr.write_end()
                    print '%d...already' % uid
                else:
                    raise
예제 #9
0
    def handle(self, *args, **options):

        print '================================'
        print 'init_rankinggacha'
        print '================================'

        model_mgr = ModelRequestMgr()

        now = OSAUtil.get_now()

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

        print '================================'
        print 'check master'
        group = int(args[0])
        master_list = BackendApi.get_rankinggacha_master_by_group(
            model_mgr, group, using=settings.DB_READONLY)
        if not master_list:
            print u'ランキングガチャではありません'
            return
        boxidlist = [master.id for master in master_list]
        gachamaster_list = GachaMaster.fetchValues(
            filters={'boxid__in': boxidlist}, using=settings.DB_READONLY)
        gachamaster_list = [
            gachamaster.id for gachamaster in gachamaster_list
            if BackendApi.check_schedule(model_mgr,
                                         gachamaster.schedule,
                                         using=settings.DB_READONLY,
                                         now=now)
        ]
        if gachamaster_list:
            print u'ガチャが開いています.id=%s' % gachamaster_list
            return
        print 'check master...OK'

        print '================================'
        print 'check flag'
        close_model_list = RankingGachaClose.getByKey(boxidlist)
        if len(close_model_list) != len(boxidlist):
            print u'未集計です.close_rankinggachaを実行してください'
            return
        print 'check flag...OK'

        print '================================'
        print 'delete redis'
        pipe = RankingGachaSingleRanking.getDB().pipeline()
        for boxid in boxidlist:
            pipe.delete(RankingGachaSingleRanking.makeKey(boxid),
                        RankingGachaTotalRanking.makeKey(boxid))
        pipe.execute()

        print '================================'
        print 'delete mysql'
        limit = 500
        while True:
            recordlist = RankingGachaScore.fetchValues(
                filters={'mid__in': boxidlist}, limit=limit)

            def tr():
                model_mgr = ModelRequestMgr()
                for record in recordlist:
                    model_mgr.set_delete(record)
                model_mgr.write_all()
                return model_mgr

            db_util.run_in_transaction(tr).write_end()

            if len(recordlist) < limit:
                break

        delete_target_model_cls_list = (
            UserLogRankingGachaWholePrize,
            RankingGachaPlayLog,
        )

        def tr_delete_common():
            for model_cls in delete_target_model_cls_list:
                tablename = model_cls.get_tablename()
                query_string = "truncate table `%s`;" % tablename
                Query.execute_update(query_string, [], False)
                print 'delete...%s' % tablename

            model_mgr = ModelRequestMgr()
            for close_model in close_model_list:
                model_mgr.set_delete(close_model)

            for wholedata in RankingGachaWholeData.getByKey(boxidlist):
                model_mgr.set_delete(wholedata)

            for queue in RankingGachaWholePrizeQueue.fetchValues(
                    filters={'boxid__in': boxidlist}):
                model_mgr.set_delete(queue)
            model_mgr.write_all()

            return model_mgr

        db_util.run_in_transaction(tr_delete_common).write_end()

        RankingGachaWholePrizeQueueIdSet.flush()

        print '================================'
        print 'all done..'