-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathshotboard_db.py
146 lines (98 loc) · 3.73 KB
/
shotboard_db.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
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
import bisect
import json
DEFAULT_JSON_FILENAME = "shots.json"
class ShotBoardDb:
def __init__(self):
self._frame_count = 0
self._shots = [] # contains the start frame number of each shot (integer)
self._is_dirty = False
def is_dirty(self):
return self._is_dirty
def clear_shots(self):
self._shots.clear()
self._is_dirty = True
def set_frame_count(self, frame_count):
self._frame_count = frame_count
self._is_dirty = True
def get_frame_count(self):
return self._frame_count
def get_start_frame_index(self, shot_index):
return self._shots[shot_index]
def set_shots(self, frame_indices):
self._shots = sorted(list(set(frame_indices)))
self._is_dirty = True
def add_shot(self, start_frame):
index = bisect.bisect_left(self._shots, start_frame)
self._shots.insert(index, start_frame)
self._is_dirty = True
return index
def del_shot(self, frame):
if frame in self._shots:
self._shots.remove(frame)
self._is_dirty = True
def get_shot(self, frame_index):
return self._shots.index(frame_index)
def get_shots(self):
return self._shots.copy()
def get_start_end_frame_indexes(self, frame_index):
assert frame_index >= 0
assert self._shots
if not self._shots:
return
# The last frame doesn't have a next frame
if frame_index >= self._shots[-1]:
return self._shots[-1], self._frame_count
shot_index = bisect.bisect_left(self._shots, frame_index)
if self._shots[shot_index] == frame_index:
start_index = shot_index
end_index = shot_index + 1
else:
start_index = shot_index - 1
end_index = shot_index
start_frame = self._shots[start_index]
end_frame = self._shots[end_index] if end_index < len(self._shots) else self._frame_count
return start_frame, end_frame
# Example usage: if start_frame in db:
def __contains__(self, start_frame):
return start_frame in self._shots
def __getitem__(self, shot_index):
return self._shots[shot_index]
# Example usage: del db[shot_index]
def __delitem__(self, shot_index):
del self._shots[shot_index]
self._is_dirty = True
# Example usage: len(db)
def __len__(self):
return len(self._shots)
# Example usage: for frame in db; for index, frame in enumerate(db)
def __iter__(self):
for start_frame in self._shots:
yield start_frame
# Example usage: print(db):
def __str__(self):
return f"ShotBoardDb(frames={self._shots})"
def save_to_json(self, filename=DEFAULT_JSON_FILENAME):
data = {
"frame_count": self._frame_count,
"shots": self._shots
}
with open(filename, 'w', encoding='utf-8') as json_file:
json.dump(data, json_file)
self._is_dirty = False
def load_from_json(self, filename=DEFAULT_JSON_FILENAME):
self.clear_shots()
try:
with open(filename, 'r', encoding='utf-8') as json_file:
data = json.load(json_file)
self.set_frame_count(data["frame_count"])
self.set_shots(data["shots"])
except FileNotFoundError:
print(f"File not found: {filename}")
except json.JSONDecodeError as e:
print(f"Error loading JSON: {e}")
except Exception as e:
print(f"An error occurred while loading data: {e}")
self._is_dirty = False
# TEST
if __name__ == "__main__":
print(f"\033[91mTHIS MODULE FILE IS NOT MEANT TO BE RUN!\033[0m")