Last active
June 13, 2017 08:38
-
-
Save Senarin/f3b51781df01f3b523f2 to your computer and use it in GitHub Desktop.
Python version of BMS Parser core class (non-complete)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/python | |
# -*- coding: utf-8 -*- | |
import os, sys, math, cmath, hashlib, codecs | |
def md5_file(fname): | |
md5ob = hashlib.md5() | |
with open(fname,"rb") as f: | |
for chunk in iter(lambda: f.read(8192), ""): | |
md5ob.update(chunk) | |
return md5ob.hexdigest() | |
def strstr(haystack, needle, b_needle = False): | |
pos = haystack.find(needle) | |
if pos < 0: | |
return None | |
else: | |
if b_needle == True: | |
return haystack[:pos] | |
else: | |
return haystack[pos:] | |
class BMS_Reader: | |
# Directives for basic information (metadatas) | |
B_PLAYTYPE = "PLAYER" # Play mode | |
B_MUSIC_GENRE="GENRE" # Genre of the music | |
B_SCORE_TITLE="TITLE" # Title of the music | |
B_MUSIC_ARTIST="ARTIST" # Artist name | |
B_MUSIC_BPM="BPM" # BPM (beats per minute / Tempo) | |
B_SCORE_LEVEL="PLAYLEVEL" # Playing Difficulty | |
B_BRIEF_RANK="RANK" # Judge Level | |
B_PARAM_TOTAL="TOTAL" # Gauge Totals | |
B_MIXLEVEL="DIFFICULTY" # Display difficulty name | |
B_DET_RANK="DEFEXRANK" # Judge Rank (detailed) | |
B_BGMFILE="MIDIFILE" # Name of Background Music file | |
B_VOLUME="VOLWAV" # Sound Volume | |
# Maximum channel numbers | |
SP5KEYS = 16 # Single Play (5 keys) / 11~15: Keys 1~5, 16: SC | |
SP7KEYS = 19 # Single Play (7 keys) / 11~15: Keys 1~5, 16: SC, 18~19: Keys 6~7 | |
DP9KEYS = 25 # Double Play (9 keys) / 11~15: Keys 1~5, 22~25: Keys 6~9 | |
DP10KEYS = 26 # Double Play (10 keys) / 11~15: 1P Keys 1~5, 16: 1P SC, 21~25: 2P Keys 1~5, 26: 2P SC | |
DP14KEYS = 29 # Double Play (14 keys) / 11~15: 1P Keys 1~5, 16: 1P SC, 18~19: 1P Keys 6~7, 21~25: 2P Keys 1~5, 26: 2P SC, 28~29: 2P Keys 6~7 | |
# for Long-notes | |
LN_SP5KEYS = 56 | |
LN_SP7KEYS = 59 | |
LN_DP9KEYS = 65 | |
LN_DP10KEYS = 66 | |
LN_DP14KEYS = 69 | |
# Channel number for scratch notes | |
SCR_LEFT = 16 | |
SCR_RIGHT = 26 | |
LN_SCR_LEFT = 56 | |
LN_SCR_RIGHT = 66 | |
mixlevels = {} | |
mixlevels[1] = "Beginner" | |
mixlevels[2] = "Normal" | |
mixlevels[3] = "Hyper" | |
mixlevels[4] = "Another" | |
mixlevels[5] = "Insane" | |
playtypes = {} | |
playtypes[1] = "Single" | |
playtypes[2] = "Two" | |
playtypes[3] = "Double or 9-key" | |
brief_ranks = ["Very Hard", "Hard", "Normal", "Easy"] | |
def __init__(self, path): | |
self.path = path | |
#self.charset = charset | |
self.handle = open(path,"r",encoding = "sjis") | |
def parseMetadata(self): | |
data = {} | |
flagsfound = 0 | |
playtyped = False | |
tpath = os.path.abspath(self.path) | |
data["filepath"] = tpath.replace(os.pathsep,"/") | |
data["path"] = os.path.dirname(data["filepath"]) | |
data["filename"] = os.path.basename(self.path) | |
data["filesize"] = os.path.getsize(tpath) | |
#data["filehash"] = md5_file(tpath) | |
#parameter = "" | |
self.handle.seek(0) | |
for eachlines in self.handle.readlines(): | |
if eachlines[0] == "#": | |
parameter = strstr(eachlines," ",True) | |
print("b--"+str(eachlines[0])) | |
parameter = parameter.replace("#","") | |
print("a--"+str(parameter)) | |
parameter = parameter.upper() | |
value = strstr(eachlines," ") | |
value = value.strip() | |
else: | |
continue | |
if parameter == self.B_PLAYTYPE: | |
data["playtype_id"] = int(value) | |
data["playtype_name"] = self.playtypes[int(value)] | |
playtyped = True | |
elif parameter == self.B_MUSIC_GENRE: | |
data["genre"] = value | |
elif parameter == self.B_SCORE_TITLE: | |
data["title"] = value | |
elif parameter == self.B_BGMFILE: | |
data["bgmfile"] = value | |
elif parameter == self.B_VOLUME: | |
if value.isdight() == False or (value is None): | |
data["volume"] = 100 | |
else: | |
data["volume"] = float(value) | |
elif parameter == self.B_MUSIC_BPM: | |
data["bpm"] = float(value) | |
if value.isdight() == False: | |
data["bpm"] = 130 | |
elif parameter == self.B_SCORE_LEVEL: | |
data["plevel"] = int(value) | |
elif parameter == self.B_BRIEF_RANK: | |
if (value is None) or value.isdight() == False: | |
data["rank_id"] = 0 | |
data["rank_name"] = "Unknown" | |
else: | |
data["rank_id"] = int(value) | |
data["rank_name"] = self.brief_ranks[int(value)] | |
elif parameter == self.B_PARAM_TOTAL: | |
data["total"] = int(value) | |
elif parameter == self.B_MIXLEVEL: | |
data["mixlevel"] = self.mixlevels[int(value)] | |
elif parameter == self.B_DET_RANK: | |
data["decrank"] = value | |
if playtyped == False: | |
del data | |
data = {"error_code": 0x0F, "error_desc": "This file is not a valid BMS file!"} | |
return data | |
return data | |
example = BMS_Reader(os.path.abspath("example.bme")) | |
print(example.parseMetadata()) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment