changing how to handle message and tests

This commit is contained in:
GitBluub
2023-04-02 20:46:01 +09:00
parent b2e11b013c
commit 09fd62706b
12 changed files with 358 additions and 325 deletions
+338 -305
View File
@@ -7,7 +7,7 @@ import os
import select import select
import sys import sys
from dataclasses import dataclass from dataclasses import dataclass
from typing import Literal from typing import Literal, Tuple
import requests import requests
from chroma_case.Key import Key from chroma_case.Key import Key
@@ -29,341 +29,374 @@ PRACTICE = 1
@dataclass @dataclass
class InvalidMessage: class InvalidMessage:
message: str message: str
@dataclass @dataclass
class StartMessage(ValidatedDC): class StartMessage(ValidatedDC):
id: int id: int
bearer: str bearer: str
mode: Literal["normal", "practice"] mode: Literal["normal", "practice"]
type: Literal["start"] = "start" type: Literal["start"] = "start"
@dataclass @dataclass
class EndMessage(ValidatedDC): class EndMessage(ValidatedDC):
type: Literal["end"] = "end" type: Literal["end"] = "end"
@dataclass @dataclass
class NoteOnMessage(ValidatedDC): class NoteOnMessage(ValidatedDC):
time: int time: int
note: int note: int
id: int id: int
type: Literal["note_on"] = "note_on" type: Literal["note_on"] = "note_on"
@dataclass @dataclass
class NoteOffMessage(ValidatedDC): class NoteOffMessage(ValidatedDC):
time: int time: int
note: int note: int
id: int id: int
type: Literal["note_off"] = "note_off" type: Literal["note_off"] = "note_off"
@dataclass @dataclass
class PauseMessage(ValidatedDC): class PauseMessage(ValidatedDC):
paused: bool paused: bool
time: int time: int
type: Literal["pause"] = "pause" type: Literal["pause"] = "pause"
def send(o):
print(json.dumps(o), flush=True)
class Scorometer:
def __init__(self, mode, midiFile) -> None:
self.partition = self.getPartition(midiFile)
self.keys_down = []
self.score = 0
self.mode = mode
if mode == PRACTICE:
get_start = operator.attrgetter("start")
self.practice_partition = [
list(g)
for _, g in itertools.groupby(
sorted(self.partition.notes, key=get_start), get_start
)
]
else:
self.practice_partition: list[list[Key]] = []
def getPartition(self, midiFile):
notes = []
s = 3500
notes_on = {}
prev_note_on = {}
for msg in MidiFile(midiFile):
d = msg.dict()
s += d["time"] * 1000 * RATIO
if d["type"] == "note_on":
prev_note_on[d["note"]] = 0
if d["note"] in notes_on:
prev_note_on[d["note"]] = notes_on[d["note"]] # 500
notes_on[d["note"]] = s # 0
if d["type"] == "note_off":
duration = s - notes_on[d["note"]]
note_start = notes_on[d["note"]]
notes.append(Key(d["note"], note_start, duration - 10))
notes_on[d["note"]] = s # 500
return Partition(midiFile, notes)
def handleNote(self, obj):
_key = obj["note"]
status = obj["type"]
timestamp = obj["time"]
is_down = any(x[0] == _key for x in self.keys_down)
key = None
if status == "note_on" and not is_down:
self.keys_down.append((_key, timestamp))
debug({"note": _key})
elif status == "note_off" or is_down:
down_since = next(
since for (h_key, since) in self.keys_down if h_key == _key
)
self.keys_down.remove((_key, down_since))
key = Key(_key, down_since, (timestamp - down_since))
# debug({key: key})
if key is None:
return
to_play = next(
(
i
for i in self.partition.notes
if i.key == key.key and self.is_timing_close(key, i) and i.done is False
),
None,
)
if to_play is None:
self.score -= 50
debug("Invalid key.")
else:
timingScore, timingInformation = self.getTiming(key, to_play)
self.score += (
100
if timingScore == "perfect"
else 75
if timingScore == "great"
else 50
)
to_play.done = True
self.sendScore(obj["id"], timingScore, timingInformation)
def handleNotePractice(self, obj):
_key = obj["note"]
status = obj["type"]
timestamp = obj["time"]
is_down = any(x[0] == _key for x in self.keys_down)
key = None
if status == "note_on" and not is_down:
self.keys_down.append((_key, timestamp))
debug({"note": _key})
elif status == "note_off" or is_down:
down_since = next(
since for (h_key, since) in self.keys_down if h_key == _key
)
self.keys_down.remove((_key, down_since))
key = Key(_key, down_since, (timestamp - down_since))
# debug({key: key})
if key is None:
return
keys_to_play = next(
(i for i in self.practice_partition if any(x.done != True for x in i)), None
)
if keys_to_play is None:
warn("Key sent but there is no keys to play")
self.score -= 50
return
to_play = next(
(i for i in keys_to_play if i.key == key.key and i.done != True), None
)
if to_play == None:
self.score -= 50
debug(f"Invalid key.")
else:
timingScore, _ = self.getTiming(key, to_play)
self.score += (
100
if timingScore == "perfect"
else 75
if timingScore == "great"
else 50
)
to_play.done = True
self.sendScore(obj["id"], timingScore, "practice")
def getTiming(self, key: Key, to_play: Key):
return self.getTimingScore(key, to_play), self.getTimingInfo(key, to_play)
def getTimingScore(self, key: Key, to_play: Key):
tempo_percent = abs((key.duration / to_play.duration) - 1)
if tempo_percent < 0.3:
timingScore = "perfect"
elif tempo_percent < 0.5:
timingScore = f"great"
else:
timingScore = "good"
return timingScore
def getTimingInfo(self, key: Key, to_play: Key):
return (
"perfect"
if abs(key.start - to_play.start) < 200
else "fast"
if key.start < to_play.start
else "late"
)
# is it in the 500 ms range
def is_timing_close(self, key: Key, i: Key):
return abs(i.start - key.start) < 500
def handleMessage(self, message: str):
obj = json.loads(message)
if "type" not in obj.keys():
warn(f"Could not handle message {message}")
return
if obj["type"] == "note_on" or obj["type"] == "note_off":
if self.mode == NORMAL:
self.handleNote(obj)
elif self.mode == PRACTICE:
self.handleNotePractice(obj)
if obj["type"] == "pause":
pass
def sendScore(self, id, timingScore, timingInformation):
send(
{
"id": id,
"timingScore": timingScore,
"timingInformation": timingInformation,
}
)
def gameLoop(self):
while True:
if select.select(
[
sys.stdin,
],
[],
[],
0.0,
)[0]:
line = input()
if not line:
break
info(f"handling message {line}")
self.handleMessage(line.rstrip())
else:
pass
for i in self.partition.notes:
if i.done == False:
self.score -= 50
return self.score, {}
def handleStartMessage(start_message):
for key in ["type", "id", "mode", "bearer"]:
if key not in start_message.keys():
raise Exception(f"{key} is not specified in start message")
if start_message["type"] != "start":
raise Exception("start message is not of type start")
mode = PRACTICE if start_message["mode"] == "practice" else NORMAL
song_id = start_message["id"]
bearer = start_message["bearer"]
try:
r = requests.get(f"{BACK_URL}/auth/me")
r.raise_for_status()
user_id = r.json()["id"]
except Exception:
fatal("Could not get user id with given bearer")
send({"error": "Could not get user id with given bearer"})
exit()
try:
r = requests.get(f"{BACK_URL}/song/{song_id}")
r.raise_for_status()
song_path = r.json()["midiPath"]
song_path = song_path.replace("/musics/", MUSICS_FOLDER)
except Exception:
fatal("Invalid song id")
send({"error": "Invalid song id"})
exit()
return mode, song_path, song_id, user_id
def sendScore(score, difficulties, song_id, user_id):
send({"overallScore": score, "score": difficulties})
requests.post(
f"{BACK_URL}/history",
json={
"songID": song_id,
"userID": user_id,
"score": score,
"difficulties": difficulties,
},
)
message_map = { message_map = {
"start": StartMessage, "start": StartMessage,
"end": EndMessage, "end": EndMessage,
"note_on": NoteOnMessage, "note_on": NoteOnMessage,
"note_off": NoteOffMessage, "note_off": NoteOffMessage,
"pause": PauseMessage, "pause": PauseMessage,
} }
def getMessage() -> ( def getMessage() -> (
StartMessage Tuple[
| EndMessage StartMessage
| NoteOnMessage | EndMessage
| NoteOffMessage | NoteOnMessage
| PauseMessage | NoteOffMessage
| InvalidMessage | PauseMessage
| InvalidMessage,
str,
]
): ):
try: try:
msg = input() msg = input()
obj = json.loads(msg) obj = json.loads(msg)
res = message_map[obj["type"]](**obj) res = message_map[obj["type"]](**obj)
if is_valid(res): if is_valid(res):
return res return res, msg
else: else:
return InvalidMessage(get_errors(res)) return InvalidMessage(str(get_errors(res))), msg
except Exception as e: except Exception as e:
return InvalidMessage(str(e)) return InvalidMessage(str(e)), ""
def send(o):
print(json.dumps(o), flush=True)
class Scorometer:
def __init__(self, mode, midiFile, song_id, user_id) -> None:
self.partition = self.getPartition(midiFile)
self.keys_down = []
self.mode = mode
self.song_id = song_id
self.user_id = user_id
self.score = 0
self.missed = 0
self.perfect = 0
self.great = 0
self.good = 0
self.difficulties = {}
if mode == PRACTICE:
get_start = operator.attrgetter("start")
self.practice_partition = [
list(g)
for _, g in itertools.groupby(
sorted(self.partition.notes, key=get_start), get_start
)
]
else:
self.practice_partition: list[list[Key]] = []
def getPartition(self, midiFile):
notes = []
s = 3500
notes_on = {}
prev_note_on = {}
for msg in MidiFile(midiFile):
d = msg.dict()
s += d["time"] * 1000 * RATIO
if d["type"] == "note_on":
prev_note_on[d["note"]] = 0
if d["note"] in notes_on:
prev_note_on[d["note"]] = notes_on[d["note"]] # 500
notes_on[d["note"]] = s # 0
if d["type"] == "note_off":
duration = s - notes_on[d["note"]]
note_start = notes_on[d["note"]]
notes.append(Key(d["note"], note_start, duration - 10))
notes_on[d["note"]] = s # 500
return Partition(midiFile, notes)
def handleNoteOn(self, message: NoteOnMessage):
_key = message.note
timestamp = message.time
is_down = any(x[0] == _key for x in self.keys_down)
if not is_down:
self.keys_down.append((_key, timestamp))
logging.debug({"note": _key})
def handleNoteOff(self, message: NoteOffMessage):
_key = message.note
timestamp = message.time
down_since = next(since for (h_key, since) in self.keys_down if h_key == _key)
self.keys_down.remove((_key, down_since))
key = Key(_key, down_since, (timestamp - down_since))
# debug({key: key})
to_play = next(
(
i
for i in self.partition.notes
if i.key == key.key and self.is_timing_close(key, i) and i.done is False
),
None,
)
if to_play is None:
self.score -= 50
logging.debug("Invalid key.")
else:
timingScore, timingInformation = self.getTiming(key, to_play)
self.score += (
100
if timingScore == "perfect"
else 75
if timingScore == "great"
else 50
)
to_play.done = True
self.sendScore(message.id, timingScore, timingInformation)
def handleNoteOnPractice(self, message: NoteOnMessage):
_key = message.note
timestamp = message.time
is_down = any(x[0] == _key for x in self.keys_down)
if not is_down:
self.keys_down.append((_key, timestamp))
logging.debug({"note": _key})
def handleNoteOffPractice(self, message: NoteOffMessage):
_key = message.note
timestamp = message.time
# is_down = any(x[0] == _key for x in self.keys_down)
down_since = next(since for (h_key, since) in self.keys_down if h_key == _key)
self.keys_down.remove((_key, down_since))
key = Key(_key, down_since, (timestamp - down_since))
keys_to_play = next(
(i for i in self.practice_partition if any(x.done is not True for x in i)),
None,
)
if keys_to_play is None:
logging.warning("Key sent but there is no keys to play")
self.score -= 50
return
to_play = next(
(i for i in keys_to_play if i.key == key.key and i.done is not True), None
)
if to_play is None:
self.score -= 50
logging.debug("Invalid key.")
else:
timingScore, _ = self.getTiming(key, to_play)
self.score += (
100
if timingScore == "perfect"
else 75
if timingScore == "great"
else 50
)
to_play.done = True
self.sendScore(message.id, timingScore, "practice")
def getTiming(self, key: Key, to_play: Key):
return self.getTimingScore(key, to_play), self.getTimingInfo(key, to_play)
def getTimingScore(self, key: Key, to_play: Key):
tempo_percent = abs((key.duration / to_play.duration) - 1)
if tempo_percent < 0.3:
timingScore = "perfect"
elif tempo_percent < 0.5:
timingScore = "great"
else:
timingScore = "good"
return timingScore
def getTimingInfo(self, key: Key, to_play: Key):
return (
"perfect"
if abs(key.start - to_play.start) < 200
else "fast"
if key.start < to_play.start
else "late"
)
# is it in the 500 ms range
def is_timing_close(self, key: Key, i: Key):
return abs(i.start - key.start) < 500
def handleMessage(
self,
message: StartMessage
| EndMessage
| NoteOnMessage
| NoteOffMessage
| PauseMessage
| InvalidMessage,
line: str,
):
match message:
case InvalidMessage(error):
logging.warning(f"Invalid message {line} with error: {error}")
send({"error": "Invalid message sent"})
case NoteOnMessage():
if self.mode == NORMAL:
self.handleNoteOn(message)
elif self.mode == PRACTICE:
self.handleNoteOnPractice(message)
case NoteOffMessage():
if self.mode == NORMAL:
self.handleNoteOff(message)
elif self.mode == PRACTICE:
self.handleNoteOffPractice(message)
case PauseMessage():
pass
case EndMessage():
self.endGame()
case _:
logging.warning(
f"Expected note_on note_off or pause message but got {message.type} instead"
)
def sendScore(self, id, timingScore, timingInformation):
send(
{
"id": id,
"timingScore": timingScore,
"timingInformation": timingInformation,
}
)
def gameLoop(self):
while True:
if select.select(
[
sys.stdin,
],
[],
[],
0.0,
)[0]:
message, line = getMessage()
logging.info(f"handling message {line}")
self.handleMessage(message, line)
else:
pass
def endGame(self):
for i in self.partition.notes:
if i.done is False:
self.score -= 50
send(
{
"overallScore": self.score,
"score": {
"missed": self.missed,
"good": self.good,
"great": self.great,
"perfect": self.perfect,
"maxScore": len(self.partition.notes) * 100,
},
}
)
if self.user_id != -1:
requests.post(
f"{BACK_URL}/history",
json={
"songID": self.song_id,
"userID": self.user_id,
"score": self.score,
"difficulties": self.difficulties,
},
)
exit()
def handleStartMessage(start_message: StartMessage):
mode = PRACTICE if start_message.mode == "practice" else NORMAL
song_id = start_message.id
user_id = -1
try:
if start_message.bearer != "":
r = requests.get(
f"{BACK_URL}/auth/me",
headers={"Authorization": f"Bearer {start_message.bearer}"},
)
r.raise_for_status()
user_id = r.json()["id"]
except Exception as e:
logging.fatal("Could not get user id with given bearer", exc_info=e)
send({"error": "Could not get user id with given bearer"})
exit()
try:
r = requests.get(f"{BACK_URL}/song/{song_id}")
r.raise_for_status()
song_path = r.json()["midiPath"]
song_path = song_path.replace("/musics/", MUSICS_FOLDER)
except Exception as e:
logging.fatal("Invalid song id", exc_info=e)
send({"error": "Invalid song id, song does not exist"})
exit()
return mode, song_path, song_id, user_id
def startGame(start_message: StartMessage):
mode, song_path, song_id, user_id = handleStartMessage(start_message)
sc = Scorometer(mode, song_path, song_id, user_id)
sc.gameLoop()
def main(): def main():
try: try:
while True: msg, _ = getMessage()
msg = getMessage() match msg:
match msg: case StartMessage():
case StartMessage(mode, song_id, bearer): startGame(msg)
print("start", song_id, mode, bearer) case EndMessage():
case EndMessage(): logging.info("scorometer ended before a start message")
print("end") send({"error": "Did not receive a start message"})
case NoteOnMessage(id, note, time): exit()
print("note_on", id, note, time) case InvalidMessage(error):
case NoteOffMessage(): logging.warning(f"invalid message with error: {error}")
print("note_off") send({"error": "Invalid input, expected a start message"})
case PauseMessage(): case _:
print("pause") logging.warning(f"invalid message with type: {msg.type}")
case InvalidMessage(error): send({"error": "Invalid input, expected a start message"})
print(error) except Exception as e:
exit() logging.fatal("error", exc_info=e)
mode, song_path, song_id, user_id = handleStartMessage(start_message) send({"error": "a fatal error occured"})
sc = Scorometer(mode, song_path)
score, difficulties = sc.gameLoop()
sendScore(score, difficulties, song_id, user_id)
except Exception as e:
logging.fatal("error", exc_info=e)
send({"error": "a fatal error occured"})
if __name__ == "__main__": if __name__ == "__main__":
main() main()
+2 -2
View File
@@ -1,4 +1,4 @@
{"type":"start", "id": 1, "mode": "normal", "user_id": 1} {"type":"start", "id": 1, "mode": "normal", "bearer": ""}
{"type": "note_on", "id": 2, "time": 3750, "note": 67} {"type": "note_on", "id": 2, "time": 3750, "note": 67}
{"type": "note_off", "id": 2, "time": 3980, "note": 67} {"type": "note_off", "id": 2, "time": 3980, "note": 67}
{"type": "note_on", "id": 3, "time": 4000, "note": 62} {"type": "note_on", "id": 3, "time": 4000, "note": 62}
@@ -17,5 +17,5 @@
{"type": "note_off", "id": 9, "time": 6990, "note": 62} {"type": "note_off", "id": 9, "time": 6990, "note": 62}
{"type": "note_on", "id": 10, "time": 6750, "note": 60} {"type": "note_on", "id": 10, "time": 6750, "note": 60}
{"type": "note_off", "id": 10, "time": 7240, "note": 60} {"type": "note_off", "id": 10, "time": 7240, "note": 60}
{} {"type": "end"}
+2 -2
View File
@@ -1,4 +1,4 @@
{"type":"start", "id": 1, "mode": "normal", "user_id": 1} {"type":"start", "id": 1, "mode": "normal", "bearer": ""}
{"type": "note_on", "id": 1, "time": 3250, "note": 68} {"type": "note_on", "id": 1, "time": 3250, "note": 68}
{"type": "note_off", "id": 1, "time": 3490, "note": 68} {"type": "note_off", "id": 1, "time": 3490, "note": 68}
{"type": "note_on", "id": 2, "time": 3500, "note": 67} {"type": "note_on", "id": 2, "time": 3500, "note": 67}
@@ -19,5 +19,5 @@
{"type": "note_off", "id": 9, "time": 6740, "note": 62} {"type": "note_off", "id": 9, "time": 6740, "note": 62}
{"type": "note_on", "id": 10, "time": 6500, "note": 60} {"type": "note_on", "id": 10, "time": 6500, "note": 60}
{"type": "note_off", "id": 10, "time": 6990, "note": 60} {"type": "note_off", "id": 10, "time": 6990, "note": 60}
{} {"type": "end"}
+1 -1
View File
@@ -8,4 +8,4 @@
{"id": 8, "timingScore": "perfect", "timingInformation": "fast"} {"id": 8, "timingScore": "perfect", "timingInformation": "fast"}
{"id": 9, "timingScore": "perfect", "timingInformation": "fast"} {"id": 9, "timingScore": "perfect", "timingInformation": "fast"}
{"id": 10, "timingScore": "perfect", "timingInformation": "fast"} {"id": 10, "timingScore": "perfect", "timingInformation": "fast"}
{"overallScore": 1000, "score": {}} {"overallScore": 1000, "score": {"missed": 0, "good": 0, "great": 0, "perfect": 0, "maxScore": 1000}}
+2 -2
View File
@@ -1,4 +1,4 @@
{"type":"start", "id": 1, "mode": "normal", "user_id": 1} {"type":"start", "id": 1, "mode": "normal", "bearer": ""}
{"type": "note_on", "id": 1, "time": 3500, "note": 68} {"type": "note_on", "id": 1, "time": 3500, "note": 68}
{"type": "note_off", "id": 1, "time": 3740, "note": 68} {"type": "note_off", "id": 1, "time": 3740, "note": 68}
{"type": "note_on", "id": 2, "time": 3750, "note": 67} {"type": "note_on", "id": 2, "time": 3750, "note": 67}
@@ -15,5 +15,5 @@
{"type": "note_off", "id": 7, "time": 4980, "note": 63} {"type": "note_off", "id": 7, "time": 4980, "note": 63}
{"type": "note_on", "id": 8, "time": 5000, "note": 63} {"type": "note_on", "id": 8, "time": 5000, "note": 63}
{"type": "note_off", "id": 8, "time": 5990, "note": 63} {"type": "note_off", "id": 8, "time": 5990, "note": 63}
{} {"type": "end"}
+2 -2
View File
@@ -1,4 +1,4 @@
{"type":"start", "id": 1, "mode": "normal", "user_id": 1} {"type":"start", "id": 1, "mode": "normal", "bearer": ""}
{"type": "note_on", "id": 1, "time": 3500, "note": 68} {"type": "note_on", "id": 1, "time": 3500, "note": 68}
{"type": "note_off", "id": 1, "time": 3540, "note": 68} {"type": "note_off", "id": 1, "time": 3540, "note": 68}
{"type": "note_on", "id": 2, "time": 3750, "note": 67} {"type": "note_on", "id": 2, "time": 3750, "note": 67}
@@ -19,5 +19,5 @@
{"type": "note_off", "id": 9, "time": 6690, "note": 62} {"type": "note_off", "id": 9, "time": 6690, "note": 62}
{"type": "note_on", "id": 10, "time": 6750, "note": 60} {"type": "note_on", "id": 10, "time": 6750, "note": 60}
{"type": "note_off", "id": 10, "time": 6840, "note": 60} {"type": "note_off", "id": 10, "time": 6840, "note": 60}
{} {"type": "end"}
+2 -2
View File
@@ -1,4 +1,4 @@
{"type":"start", "id": 1, "mode": "normal", "user_id": 1} {"type":"start", "id": 1, "mode": "normal", "bearer": ""}
{"type": "note_on", "id": 1, "time": 3500, "note": 68} {"type": "note_on", "id": 1, "time": 3500, "note": 68}
{"type": "note_off", "id": 1, "time": 3990, "note": 68} {"type": "note_off", "id": 1, "time": 3990, "note": 68}
{"type": "note_on", "id": 2, "time": 3750, "note": 67} {"type": "note_on", "id": 2, "time": 3750, "note": 67}
@@ -19,5 +19,5 @@
{"type": "note_off", "id": 9, "time": 7240, "note": 62} {"type": "note_off", "id": 9, "time": 7240, "note": 62}
{"type": "note_on", "id": 10, "time": 6750, "note": 60} {"type": "note_on", "id": 10, "time": 6750, "note": 60}
{"type": "note_off", "id": 10, "time": 7490, "note": 60} {"type": "note_off", "id": 10, "time": 7490, "note": 60}
{} {"type": "end"}
+1 -1
View File
@@ -1,2 +1,2 @@
{"type":"start", "id": 0, "mode": "normal", "user_id": 1} {"type":"start", "id": 0, "mode": "normal", "bearer": ""}
+2 -2
View File
@@ -1,4 +1,4 @@
{"type":"start", "id": 1, "mode": "normal", "user_id": 1} {"type":"start", "id": 1, "mode": "normal", "bearer": ""}
{"type": "note_on", "id": 1, "time": 3750, "note": 68} {"type": "note_on", "id": 1, "time": 3750, "note": 68}
{"type": "note_off", "id": 1, "time": 3990, "note": 68} {"type": "note_off", "id": 1, "time": 3990, "note": 68}
{"type": "note_on", "id": 2, "time": 4000, "note": 67} {"type": "note_on", "id": 2, "time": 4000, "note": 67}
@@ -19,5 +19,5 @@
{"type": "note_off", "id": 9, "time": 7240, "note": 62} {"type": "note_off", "id": 9, "time": 7240, "note": 62}
{"type": "note_on", "id": 10, "time": 7000, "note": 60} {"type": "note_on", "id": 10, "time": 7000, "note": 60}
{"type": "note_off", "id": 10, "time": 7490, "note": 60} {"type": "note_off", "id": 10, "time": 7490, "note": 60}
{} {"type": "end"}
+2 -2
View File
@@ -1,4 +1,4 @@
{"type":"start", "id": 1, "mode": "normal", "user_id": 1} {"type":"start", "id": 1, "mode": "normal", "bearer": ""}
{"type": "note_on", "id": 1, "time": 3500, "note": 68} {"type": "note_on", "id": 1, "time": 3500, "note": 68}
{"type": "note_off", "id": 1, "time": 3740, "note": 68} {"type": "note_off", "id": 1, "time": 3740, "note": 68}
{"type": "note_on", "id": 2, "time": 3750, "note": 67} {"type": "note_on", "id": 2, "time": 3750, "note": 67}
@@ -19,5 +19,5 @@
{"type": "note_off", "id": 9, "time": 6990, "note": 62} {"type": "note_off", "id": 9, "time": 6990, "note": 62}
{"type": "note_on", "id": 10, "time": 6750, "note": 60} {"type": "note_on", "id": 10, "time": 6750, "note": 60}
{"type": "note_off", "id": 10, "time": 7240, "note": 60} {"type": "note_off", "id": 10, "time": 7240, "note": 60}
{} {"type": "end"}
+2 -2
View File
@@ -1,4 +1,4 @@
{"type":"start", "id": 1, "mode": "normal", "user_id": 1} {"type":"start", "id": 1, "mode": "normal", "bearer": ""}
{"type": "note_on", "id": 1, "time": 3500, "note": 68} {"type": "note_on", "id": 1, "time": 3500, "note": 68}
{"type": "note_off", "id": 1, "time": 3740, "note": 68} {"type": "note_off", "id": 1, "time": 3740, "note": 68}
{"type": "note_on", "id": 3, "time": 4000, "note": 62} {"type": "note_on", "id": 3, "time": 4000, "note": 62}
@@ -15,5 +15,5 @@
{"type": "note_off", "id": 9, "time": 6990, "note": 62} {"type": "note_off", "id": 9, "time": 6990, "note": 62}
{"type": "note_on", "id": 10, "time": 6750, "note": 60} {"type": "note_on", "id": 10, "time": 6750, "note": 60}
{"type": "note_off", "id": 10, "time": 7240, "note": 60} {"type": "note_off", "id": 10, "time": 7240, "note": 60}
{} {"type": "end"}
+2 -2
View File
@@ -10,7 +10,7 @@ TESTS_SUCCESS=0
TESTS_FAILED=0 TESTS_FAILED=0
function test { function test {
cat $1/input | BACK_URL="http://localhost:3000" MUSICS_FOLDER="../../musics/" python3 ../main.py 1> /tmp/scorometer_res 2> /dev/null cat $1/input | BACK_URL="http://localhost:3000" MUSICS_FOLDER="../../musics/" python3 ../main.py 1> /tmp/scorometer_res 2> /tmp/scorometer_log
TESTS_DONE=$((TESTS_DONE + 1)) TESTS_DONE=$((TESTS_DONE + 1))
if ! diff $1/output /tmp/scorometer_res &>/dev/null; then if ! diff $1/output /tmp/scorometer_res &>/dev/null; then
echo "$t failed, do runner.sh $t for more info" echo "$t failed, do runner.sh $t for more info"
@@ -27,7 +27,7 @@ then
done done
exit $TESTS_FAILED exit $TESTS_FAILED
else else
cat $1/input | BACK_URL="http://localhost:3000" MUSICS_FOLDER="../../musics/" python3 ../main.py 1> /tmp/scorometer_res 2> /dev/null cat $1/input | BACK_URL="http://localhost:3000" MUSICS_FOLDER="../../musics/" python3 ../main.py 1> /tmp/scorometer_res 2> /tmp/scorometer_log
echo "=========== CURRENT OUTPUT ===========" echo "=========== CURRENT OUTPUT ==========="
cat /tmp/scorometer_res cat /tmp/scorometer_res
echo "======================================" echo "======================================"