def asyncGet(self): output = "" try: # Get data by beatmap id or beatmapset id if "b" in self.request.arguments: id = self.get_argument("b") data = cheesegull.getBeatmap(id) elif "s" in self.request.arguments: id = self.get_argument("s") data = cheesegull.getBeatmapSet(id) else: raise exceptions.invalidArgumentsException(MODULE_NAME) log.info("Requested osu!direct np: {}/{}".format("b" if "b" in self.request.arguments else "s", id)) # Make sure cheesegull returned some valid data if data is None or len(data) == 0: raise exceptions.osuApiFailException(MODULE_NAME) # Write the response output = cheesegull.toDirectNp(data) + "\r\n" except (exceptions.invalidArgumentsException, exceptions.osuApiFailException, KeyError): output = "" finally: self.write(output)
def cacheMap(mapFile, _beatmap): # Check if we have to download the .osu file download = shouldDownloadMap(mapFile, _beatmap) # Download .osu file if needed if download: log.debug("maps ~> Downloading {} osu file".format(_beatmap.beatmapId)) # Get .osu file from osu servers fileContent = osuapiHelper.getOsuFileFromID(_beatmap.beatmapId) # Make sure osu servers returned something if fileContent is None or not isBeatmap(content=fileContent): raise exceptions.osuApiFailException("maps") # Delete old .osu file if it exists if os.path.isfile(mapFile): os.remove(mapFile) # Save .osu file with open(mapFile, "wb+") as f: f.write(fileContent) else: # Map file is already in folder log.debug("maps ~> Beatmap found in cache!")
def cacheMap(mapFile, _beatmap): # Check if we have to download the .osu file download = False if not os.path.isfile(mapFile): # .osu file doesn't exist. We must download it download = True else: # File exists, check md5 if generalUtils.fileMd5(mapFile) != _beatmap.fileMD5 or not isBeatmap( mapFile): # MD5 don't match, redownload .osu file download = True # Download .osu file if needed if download: log.debug("maps ~> Downloading {} osu file".format(_beatmap.beatmapID)) # Get .osu file from osu servers fileContent = osuapiHelper.getOsuFileFromID(_beatmap.beatmapID) # Make sure osu servers returned something if fileContent is None or not isBeatmap(content=fileContent): raise exceptions.osuApiFailException("maps") # Delete old .osu file if it exists if os.path.isfile(mapFile): os.remove(mapFile) # Save .osu file with open(mapFile, "wb+") as f: f.write(fileContent) else: # Map file is already in folder log.debug("maps ~> Beatmap found in cache!")
def asyncGet(self, fileName=None): try: # Check arguments if fileName is None: raise exceptions.invalidArgumentsException(MODULE_NAME) if fileName == "": raise exceptions.invalidArgumentsException(MODULE_NAME) fileNameShort = fileName[:32] + "..." if len( fileName) > 32 else fileName[:-4] log.info("Requested .osu file {}".format(fileNameShort)) # Get .osu file from osu! server fileContent = osuapiHelper.getOsuFileFromName(fileName) if fileContent is None: raise exceptions.osuApiFailException(MODULE_NAME) self.write(fileContent) except exceptions.invalidArgumentsException: self.set_status(500) except exceptions.osuApiFailException: self.set_status(500)
def asyncGet(self): output = "" try: # Get data by beatmap id or beatmapset id if "b" in self.request.arguments: _id = self.get_argument("b") data = cheesegull.getBeatmap(_id) elif "s" in self.request.arguments: _id = self.get_argument("s") data = cheesegull.getBeatmapSet(_id) elif "c" in self.request.arguments: md5 = self.get_argument("c") response = glob.db.fetch( "SELECT beatmap_id FROM beatmaps WHERE beatmap_md5 = %s LIMIT 1", [md5]) if not response: raise exceptions.invalidArgumentsException(MODULE_NAME) data = cheesegull.getBeatmap(response['beatmap_id']) _id = response['beatmap_id'] else: raise exceptions.invalidArgumentsException(MODULE_NAME) log.info("Requested osu!direct np: {}/{}".format( "b" if "b" in self.request.arguments else "s", _id)) # Make sure cheesegull returned some valid data if data is None or len(data) == 0: raise exceptions.osuApiFailException(MODULE_NAME) # Write the response output = cheesegull.toDirectNp(data) + "\r\n" except (exceptions.invalidArgumentsException, exceptions.osuApiFailException, KeyError): output = "" finally: self.write(output)
def asyncGet(self): output = "" try: username = self.get_argument("u") password = self.get_argument("h") user_id = userUtils.getID(username) if not verify_password(user_id, password): raise exceptions.loginFailedException(MODULE_NAME, username) # Get data by beatmap id or beatmapset id if "b" in self.request.arguments: _id = self.get_argument("b") data = cheesegull.getBeatmap(_id) elif "s" in self.request.arguments: _id = self.get_argument("s") data = cheesegull.getBeatmapSet(_id) else: raise exceptions.invalidArgumentsException(MODULE_NAME) log.info("Requested osu!direct np: {}/{}".format( "b" if "b" in self.request.arguments else "s", _id)) # Make sure cheesegull returned some valid data if data is None or len(data) == 0: raise exceptions.osuApiFailException(MODULE_NAME) # Write the response output = cheesegull.toDirectNp(data) + "\r\n" except (exceptions.invalidArgumentsException, exceptions.osuApiFailException, KeyError): output = "" except exceptions.loginFailedException: output = "error: pass" finally: self.write(output)
def getPP(self, tillerino=False, stars=False): """ Calculate total pp value with oppai and return it return -- total pp """ # Set variables self.pp = 0 try: # Build .osu map file path mapFile = "{path}/maps/{map}".format(path=self.OPPAI_FOLDER, map=self.map) try: # Check if we have to download the .osu file download = False if not os.path.isfile(mapFile): # .osu file doesn't exist. We must download it if glob.debug: consoleHelper.printColored( "[!] {} doesn't exist".format(mapFile), bcolors.YELLOW) download = True else: # File exists, check md5 if generalUtils.fileMd5(mapFile) != self.beatmap.fileMD5: # MD5 don't match, redownload .osu file if glob.debug: consoleHelper.printColored( "[!] Beatmaps md5 don't match", bcolors.YELLOW) download = True # Download .osu file if needed if download: if glob.debug: consoleHelper.printRippoppaiMessage( "Downloading {} from osu! servers...".format( self.beatmap.beatmapID)) # Get .osu file from osu servers fileContent = osuapiHelper.getOsuFileFromID( self.beatmap.beatmapID) # Make sure osu servers returned something if fileContent is None: raise exceptions.osuApiFailException(MODULE_NAME) # Delete old .osu file if it exists if os.path.isfile(mapFile): os.remove(mapFile) # Save .osu file with open(mapFile, "wb+") as f: f.write(fileContent.encode("latin-1")) else: # Map file is already in folder if glob.debug: consoleHelper.printRippoppaiMessage( "Found beatmap file {}".format(mapFile)) except exceptions.osuApiFailException: pass # Base command command = fixPath("{path}/oppai {mapFile}".format( path=self.OPPAI_FOLDER, mapFile=mapFile)) # Use only mods supported by oppai. modsFixed = self.mods & 5979 # Add params if needed if self.acc > 0: command += " {acc:.2f}%".format(acc=self.acc) if self.mods > 0: command += " +{mods}".format( mods=scoreUtils.readableMods(modsFixed)) if self.combo > 0: command += " {combo}x".format(combo=self.combo) if self.misses > 0: command += " {misses}xm".format(misses=self.misses) if tillerino: command += " tillerino" if stars: command += " stars" # Debug output if glob.debug: consoleHelper.printRippoppaiMessage( "Executing {}".format(command)) # oppai output process = subprocess.run(command, shell=True, stdout=subprocess.PIPE) output = process.stdout.decode("utf-8") # Get standard or tillerino output sep = "\n" if UNIX else "\r\n" if output == ['']: # This happens if mode not supported or something self.pp = 0 self.stars = None return self.pp output = output.split(sep) # get rid of pesky warnings!!! try: float(output[0]) except ValueError: del output[0] if tillerino: # Get tillerino output (multiple lines) if stars: self.pp = output[:-2] self.stars = float(output[-2]) else: self.pp = output.split( sep)[: -1] # -1 because there's an empty line at the end else: # Get standard output (:l to remove (/r)/n at the end) l = -1 if UNIX else -2 if stars: self.pp = float(output[len(output) - 2][:l - 1]) else: self.pp = float(output[len(output) - 2][:l]) # Debug output if glob.debug: consoleHelper.printRippoppaiMessage("Calculated pp: {}".format( self.pp)) finally: return self.pp
def calculatePP(self): """ Calculate total pp value with oppai and return it return -- total pp """ # Set variables self.pp = None try: # Build .osu map file path mapFile = "{path}/maps/{map}".format(path=self.OPPAI_FOLDER, map=self.map) log.debug("oppai ~> Map file: {}".format(mapFile)) try: # Check if we have to download the .osu file download = False if not os.path.isfile(mapFile): # .osu file doesn't exist. We must download it if glob.debug: consoleHelper.printColored("[!] {} doesn't exist".format(mapFile), bcolors.YELLOW) download = True else: # File exists, check md5 if generalUtils.fileMd5(mapFile) != self.beatmap.fileMD5: # MD5 don't match, redownload .osu file if glob.debug: consoleHelper.printColored("[!] Beatmaps md5 don't match", bcolors.YELLOW) download = True # Download .osu file if needed if download: log.debug("oppai ~> Downloading {} osu file".format(self.beatmap.beatmapID)) # Get .osu file from osu servers fileContent = osuapiHelper.getOsuFileFromID(self.beatmap.beatmapID) # Make sure osu servers returned something if fileContent is None: raise exceptions.osuApiFailException(MODULE_NAME) # Delete old .osu file if it exists if os.path.isfile(mapFile): os.remove(mapFile) # Save .osu file with open(mapFile, "wb+") as f: f.write(fileContent.encode("utf-8")) else: # Map file is already in folder log.debug("oppai ~> Beatmap found in cache!") except exceptions.osuApiFailException: log.error("oppai ~> osu!api error!") pass # Parse beatmap log.debug("oppai ~> About to parse beatmap") pyoppai.parse( mapFile, self._oppai_beatmap, self._oppai_buffer, self.BUFSIZE, False, self.OPPAI_FOLDER # /oppai_cache ) self.checkOppaiErrors() log.debug("oppai ~> Beatmap parsed with no errors") # Create diffcalc context and calculate difficulty log.debug("oppai ~> About to calculate difficulty") # Use only mods supported by oppai modsFixed = self.mods & 5979 if modsFixed > 0: pyoppai.apply_mods(self._oppai_beatmap, modsFixed) self._oppai_diffcalc_ctx = pyoppai.new_d_calc_ctx(self._oppai_ctx) diff_stars, diff_aim, diff_speed, _, _, _, _ = pyoppai.d_calc(self._oppai_diffcalc_ctx, self._oppai_beatmap) self.checkOppaiErrors() log.debug("oppai ~> Difficulty calculated with no errors. {}*, {} aim, {} speed".format(diff_stars, diff_aim, diff_speed)) # Calculate pp log.debug("oppai ~> About to calculate PP") if not self.tillerino: _, total_pp, aim_pp, speed_pp, acc_pp = pyoppai.pp_calc_acc(self._oppai_ctx, diff_aim, diff_speed, self._oppai_beatmap, self.acc if self.acc > 0 else 100, modsFixed, self.combo if self.combo > 0 else 0xFFFF, self.misses) self.checkOppaiErrors() log.debug("oppai ~> PP Calculated with no errors. {}pp, {} aim pp, {} speed pp, {} acc pp".format( total_pp, aim_pp, speed_pp, acc_pp )) self.pp = total_pp else: pp_list = [] for acc in [100, 99, 98, 95]: log.debug("oppai ~> Calculating PP with acc {}%".format(acc)) _, total_pp, aim_pp, speed_pp, acc_pp = pyoppai.pp_calc_acc(self._oppai_ctx, diff_aim, diff_speed, self._oppai_beatmap, acc, modsFixed) self.checkOppaiErrors() pp_list.append(total_pp) log.debug("oppai ~> PP Calculated with no errors. {}pp, {} aim pp, {} speed pp, {} acc pp".format( total_pp, aim_pp, speed_pp, acc_pp )) self.pp = pp_list self.stars = diff_stars log.debug("oppai ~> Calculated PP: {}".format(self.pp)) except OppaiError: log.error("oppai ~> pyoppai error!") self.pp = 0 except Exception as e: log.error("oppai ~> Unhandled exception: {}".format(str(e))) raise e finally: log.debug("oppai ~> Shutting down and returning {}pp".format(self.pp)) return self.pp