Beispiel #1
0
 def process(self):
     # calculate nochoke pp and result
     if self.user_stats.gamemode == Gamemode.STANDARD:
         # determine score result
         self.__process_score_result()
         # only need to pass beatmap_id, 100s, 50s, and mods since all other options default to best possible
         with oppaipy.Calculator(get_beatmap_path(self.beatmap_id)) as calc:
             calc.set_accuracy(count_100=self.count_100, count_50=self.count_50)
             calc.set_mods(self.mods)
             calc.calculate()
             self.nochoke_pp = calc.pp if math.isfinite(calc.pp) else 0
             self.star_rating = calc.stars if math.isfinite(calc.stars) else 0
Beispiel #2
0
def getBeatmapFile(request, beatmap_id):
    with open(get_beatmap_path(beatmap_id), encoding="utf8") as fp:
        response = HttpResponse(fp.read())
        response["Content-Type"] = "text/plain"
        return response
Beispiel #3
0
    def add_scores_from_data(self, score_data_list):
        """
        Adds a list of scores and their beatmaps from the passed score_data_list.
        (requires all dicts to have beatmap_id set along with usual score data)
        """
        # Fetch beatmaps from database in bulk
        beatmap_ids = [int(s["beatmap_id"]) for s in score_data_list]
        beatmaps = list(Beatmap.objects.filter(id__in=beatmap_ids))

        beatmaps_to_create = []
        scores_from_data = []
        for score_data in score_data_list:
            score = Score()

            # Update Score fields
            score.score = int(score_data["score"])
            score.count_300 = int(score_data["count300"])
            score.count_100 = int(score_data["count100"])
            score.count_50 = int(score_data["count50"])
            score.count_miss = int(score_data["countmiss"])
            score.count_geki = int(score_data["countgeki"])
            score.count_katu = int(score_data["countkatu"])
            score.best_combo = int(score_data["maxcombo"])
            score.perfect = bool(int(score_data["perfect"]))
            score.mods = int(score_data["enabled_mods"])
            score.rank = score_data["rank"]
            score.date = datetime.strptime(
                score_data["date"],
                "%Y-%m-%d %H:%M:%S").replace(tzinfo=pytz.UTC)

            # Update foreign keys
            # Search for beatmap in fetched, else create it
            beatmap_id = int(score_data["beatmap_id"])
            beatmap = next(
                (beatmap for beatmap in beatmaps if beatmap.id == beatmap_id),
                None)
            if beatmap is None:
                beatmap = Beatmap.from_data(
                    apiv1.get_beatmaps(beatmap_id=beatmap_id)[0])
                if beatmap.status not in [
                        BeatmapStatus.APPROVED, BeatmapStatus.RANKED,
                        BeatmapStatus.LOVED
                ]:
                    continue
                beatmaps.append(
                    beatmap
                )  # add to beatmaps incase another score is on this map
                beatmaps_to_create.append(beatmap)
            score.beatmap = beatmap
            score.user_stats = self

            # Update pp
            if "pp" in score_data and score_data["pp"] is not None:
                score.pp = float(score_data["pp"])
            else:
                # Check for gamemode
                if self.gamemode != Gamemode.STANDARD:
                    # We cant calculate pp for this mode yet so we need to disregard this score
                    continue
                # Use oppai to calculate pp
                with oppaipy.Calculator(get_beatmap_path(beatmap_id)) as calc:
                    calc.set_accuracy(count_100=score.count_100,
                                      count_50=score.count_50)
                    calc.set_misses(score.count_miss)
                    calc.set_combo(score.best_combo)
                    calc.set_mods(score.mods)
                    calc.calculate()
                    score.pp = calc.pp if math.isfinite(calc.pp) else 0

            # Update convenience fields
            score.gamemode = self.gamemode
            score.accuracy = utils.get_accuracy(score.count_300,
                                                score.count_100,
                                                score.count_50,
                                                score.count_miss,
                                                score.count_katu,
                                                score.count_geki,
                                                gamemode=self.gamemode)
            score.bpm = utils.get_bpm(beatmap.bpm, score.mods)
            score.length = utils.get_length(beatmap.drain_time, score.mods)
            score.circle_size = utils.get_cs(beatmap.circle_size, score.mods)
            score.approach_rate = utils.get_ar(beatmap.approach_rate,
                                               score.mods)
            score.overall_difficulty = utils.get_od(beatmap.overall_difficulty,
                                                    score.mods)

            # Process score
            score.process()

            scores_from_data.append(score)

        # Remove potential duplicates from a top 100 play also being in the recent 50
        scores_from_data = [
            score for score in scores_from_data if score == next(
                s for s in scores_from_data if s.date == score.date)
        ]

        # Process scores for user stats values
        all_scores, scores_to_create = self.__process_scores(*scores_from_data)
        self.save()

        # Update new scores with newly saved UserStats id
        for score in scores_to_create:
            score.user_stats_id = self.id

        # Bulk add and update beatmaps and scores
        Beatmap.objects.bulk_create(beatmaps_to_create, ignore_conflicts=True)
        Score.objects.bulk_create(scores_to_create)

        # Update leaderboard memberships with all scores
        self.__update_memberships(*all_scores)

        # Return new scores
        return scores_to_create