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
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
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