-
Notifications
You must be signed in to change notification settings - Fork 1
/
vitals.py
107 lines (96 loc) · 4.11 KB
/
vitals.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
import pprint
import sys
import zipfile
from typing import BinaryIO
import toml
from orchard.parse import parse
from orchard.vitals.facets.artist_list_facet import artist_list_facet
from orchard.vitals.facets.rdlevel_sha1_facet import rdlevel_sha1_facet
from orchard.vitals.facets.sha1_facet import sha1_facet
from orchard.vitals.facets.author_facet import author_facet
from orchard.vitals.facets.event_type_facet import event_type_facet
from orchard.vitals.facets.bpm_facet import bpm_facet
from orchard.vitals.facets.difficulty_facet import difficulty_facet
from orchard.vitals.facets.icon_facet import icon_facet
from orchard.vitals.facets.id_facet import id_facet
from orchard.vitals.facets.key_facet import make_key_facet, make_color_enabled_key_facet
from orchard.vitals.facets.player_facet import player_facet
from orchard.vitals.facets.tags_facet import tags_facet
from orchard.vitals.facets.thumbnail_facet import thumbnail_facet
from orchard.vitals.facets.updated_facet import updated_facet
class VitalsException(Exception):
pass
def main(f: BinaryIO):
facets = {
"id": id_facet,
("artist",): make_color_enabled_key_facet(["settings", "artist"]),
"artist_tokens": artist_list_facet,
("song", "song_ct"): make_color_enabled_key_facet(["settings", "song"]),
"seizure_warning": make_key_facet(["settings", "seizureWarning"], True),
("description", "description_ct"): make_color_enabled_key_facet(
["settings", "description"]
),
"hue": make_key_facet(["settings", "songNameHue"], 0.0),
"authors": author_facet,
("max_bpm", "min_bpm"): bpm_facet,
"difficulty": difficulty_facet,
("single_player", "two_player"): player_facet,
"last_updated": updated_facet,
"tags": tags_facet,
("image", "thumb"): thumbnail_facet,
"icon": icon_facet,
(
"has_classics",
"has_oneshots",
"has_squareshots",
"has_freezeshots",
"has_freetimes",
"has_holds",
"has_skipshots",
"has_window_dance",
): event_type_facet,
"sha1": sha1_facet,
"rdlevel_sha1": rdlevel_sha1_facet,
}
try:
with zipfile.ZipFile(f) as z:
with z.open("main.rdlevel", "r") as rdlevel:
text = rdlevel.read().decode("utf-8-sig")
parsed = parse(text)
# get the TOML comment if there is one.
# there can be only one
comments = [evt for evt in parsed["events"] if evt["type"] == "Comment"]
toml_comment = None
for comment in comments:
try:
content = comment["text"]
if "#orchard" not in content:
continue
toml_comment = toml.loads(content)
break # only consider the first valid comment we find.
except:
# it's fine if there isn't a comment.
continue
final = {}
for key, func in facets.items():
try:
result = func(
{"obj": parsed, "zip": z, "file": f, "toml": toml_comment}
)
if isinstance(key, tuple):
# multiple keys with (expected) multiple values that map to the keys.
for k, v in zip(key, result):
final[k] = v
else:
final[key] = result
except Exception as e:
raise VitalsException(
f"vitals: An unhandled error occured in a facet: {e}"
)
return final
except zipfile.BadZipFile:
raise VitalsException(
"vitals: this is not a zip file, or we couldn't decode it for some reason."
)
except KeyError:
raise VitalsException("vitals: there is no main.rdlevel in the zip.")