-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathmodels.py
144 lines (118 loc) · 4.69 KB
/
models.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
import pickle
import re
from typing import List
from error_handler import io_error_handler
class Department:
def __init__(self, department_id, department_name):
self.id = department_id
self.name = department_name
def __repr__(self):
return self.name
class Course:
def __init__(self, id, group, credit, name, instructor, time, details, virtual_class, postgraduate, final=''):
self.id = id
self.group = group
self.credit = credit
self.name = name
self.instructor = instructor
self.time = time
self.details = details
self.virtual_class = virtual_class
self.final = final
self.postgraduate = postgraduate
try:
self.days, self.start, self.end = Course.get_day_and_hour(time)
except:
print(f"There is no time for Course {id}:{name}")
def __repr__(self):
return f'{self.name} {self.instructor} {self.group}'
def __hash__(self) -> int:
return hash(str([self.id, self.group, self.credit, self.name, self.instructor,
self.time, self.details, self.virtual_class, self.postgraduate]))
@staticmethod
def get_day_and_hour(s):
pattern = r'([^0-9]+)\s+(\d{1,2}:\d{2}|\d{1,2})\s+تا\s+(\d{1,2}:\d{2}|\d{1,2})'
match = re.search(pattern, s)
# result is [[first_day, second_day], [starting_hour, starting_minutes], [ending_hour, ending_minutes]]
result = []
if match:
days = match.group(1)
start = match.group(2)
end = match.group(3)
separated_days = days.split(' و ')
first_day = Course.get_day_from_str(separated_days[0])
second_day = None
if len(separated_days) > 1:
second_day = Course.get_day_from_str(separated_days[1])
result.append([first_day, second_day])
result.append(Course.get_hour_from_str(start))
result.append(Course.get_hour_from_str(end))
return result
return -1
@staticmethod
def get_day_from_str(day_in_str):
days_of_week = {
"شنبه": 0,
"یک": 1,
"دو": 2,
"سه": 3,
"چهار": 4,
"پنج": 5
}
for key, value in days_of_week.items():
if str(day_in_str).startswith(key):
return value
return -1
@staticmethod
def get_hour_from_str(hour_in_str):
if ':' in hour_in_str:
separated = hour_in_str.split(':')
return [int(separated[0]), int(separated[1])]
else:
return [int(hour_in_str), 0]
@staticmethod
def check_conflict(course1, course2):
if course1.end <= course2.start or course1.start >= course2.end:
return False
if course1.days[0] == course2.days[0]:
return True
if course1.days[1] != None and course1.days[1] == course2.days[0]:
return True
if course2.days[1] != None and course2.days[1] == course1.days[0]:
return True
if course1.days[1] != None and course2.days[1] != None and course2.days[1] == course1.days[1]:
return True
return False
def get_searchable_string(self):
return (f"{self.id} {self.name} {self.instructor} {self.details}").replace('ك', 'ک').replace('ي', 'ی')
class ApplicationData:
courses: List[Course] = []
added_courses: List[Course] = []
departments: List[Department] = []
def __init__(self, departments_list: Department, courses_list: Course):
self.departments = departments_list
self.courses = courses_list
# TODO: save users's username and password with device-specific encryption
@property
def data(self):
""" List of departments and courses """
return self.departments, self.courses
def __hash__(self) -> int:
return hash(''.join(str(hash(c)) for c in self.courses))
def is_data_uptodate(self, new_hash):
""" Checks if the current app data is recent by comparing it to the incoming hash """
return hash(self) == new_hash
@io_error_handler
def save(self):
""" Saves the list of courses and departments to 'appdata.cc' file """
with open('appdata.cc', 'wb') as f:
pickle.dump(self, f)
@staticmethod
@io_error_handler
def load() -> 'ApplicationData':
""" Loads application data from 'appdata.cc' file and returns an `ApplicationData` object"""
with open('appdata.cc', 'rb') as f:
return pickle.load(f)
def set_added_courses(self, course_List: List[Course]):
self.added_courses = course_List
self.save()