Skip to content

Commit 643b76a

Browse files
committed
add proper logging system to checker
1 parent cfe1a14 commit 643b76a

File tree

1 file changed

+90
-28
lines changed

1 file changed

+90
-28
lines changed

checker.py

Lines changed: 90 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -4,20 +4,19 @@
44
from pprint import pprint
55

66
from fet_api_to_gcal import db
7-
from fet_api_to_gcal.common.utils import getDate, perror, psuccess, path_leaf
7+
from fet_api_to_gcal.common.utils import (error_str, getDate, info_str,
8+
path_leaf, perror, psuccess,
9+
success_str, timestamped_filename)
810
from fet_api_to_gcal.models import Calendar, Resource, Std_mail, Teacher
911

10-
1112
# TODO: add proper logging to the script. (file + stdout).
1213
# TODO: add an arguemt parser to script.
1314

14-
15-
1615
dates = {
1716
"2CPI": "2020/02/23", # ! needs to be changed accordingly!
18-
"1CS": "2020/02/23", # ! needs to be changed accordingly!
19-
"2CS": "2020/02/23", # ! needs to be changed accordingly!
20-
"3CS": "2020/02/23", # ! needs to be changed accordingly!
17+
"1CS": "2020/02/23", # ! needs to be changed accordingly!
18+
"2CS": "2020/02/23", # ! needs to be changed accordingly!
19+
"3CS": "2020/02/23", # ! needs to be changed accordingly!
2120
"1CPI": "2020/02/23", # ! needs to be changed accordingly!
2221
}
2322

@@ -41,8 +40,31 @@ def check_timetable_validity(timetable_path,
4140
list: list of google styled events, each google event is a python dictionary.
4241
"""
4342

43+
# SETUP LOGGING
44+
45+
log_filename = timestamped_filename(filename=path_leaf(timetable_path))
46+
47+
logging.basicConfig(
48+
level=logging.DEBUG,
49+
format='%(asctime)s %(name)-12s %(levelname)-8s %(message)s',
50+
datefmt='%m-%d %H:%M:%S',
51+
filename="./logs/{}_checker_script.log".format(log_filename),
52+
filemode='w')
53+
54+
console = logging.StreamHandler()
55+
console.setLevel(logging.WARNING)
56+
formatter = logging.Formatter('%(name)-12s: %(levelname)-8s %(message)s')
57+
console.setFormatter(formatter)
58+
logging.getLogger('').addHandler(console)
59+
logging.info(info_str("Started logging in file {}".format(log_filename)))
60+
4461
timezone = "Africa/Algiers"
45-
f = open(timetable_path, "r")
62+
try:
63+
f = open(timetable_path, "r")
64+
except Exception as e:
65+
logging.exception(
66+
error_str("Exception while opening file {}".format(
67+
path_leaf(timetable_path))))
4668
lines = f.readlines()[1::]
4769
all_events = [] # to hold all json gevents later!
4870
temp_dict_holder = {}
@@ -80,14 +102,17 @@ def check_timetable_validity(timetable_path,
80102

81103
# ? 2nd phase
82104

83-
84105
# ? indexes are used to allow non-ordered events to be generated successfully.
106+
logging.info(info_str("Started converting event to google events"))
85107
indexes = list(map(int, list(temp_dict_holder.keys())))
86108
for event_inx in indexes:
87109
try:
88110
event___old = temp_dict_holder[str(event_inx)]
89111
except KeyError as e:
90-
print(e)
112+
logging.exception(
113+
error_str(
114+
"Exception in event at index {} thus will not be added".
115+
format(event_inx)))
91116
__gevent__ = {"summary": event___old["summary"]}
92117

93118
# ? get attendees emails
@@ -99,20 +124,29 @@ def check_timetable_validity(timetable_path,
99124
__gevent__["attendees"].append(
100125
{"email": teacher.teacher_email})
101126
else:
102-
perror("Teacher {} not found (event index: {})".format(
103-
teacher_name, event_inx))
127+
logging.warning(
128+
error_str("Teacher {} not found (event index: {})".format(
129+
teacher_name, event_inx)))
104130

105-
# students
131+
# students (important part)
106132
if event___old["std_set"] == "":
107-
perror("Std_set empty in event index : {}".format(event_inx))
108-
#pprint(event___old)
133+
logging.error(
134+
error_str(
135+
"Std_set empty in event index : {}, thus event is ignored".
136+
format(event_inx)))
109137
continue
138+
110139
for std_set__ in event___old["std_set"].split("+"):
111140

112141
std_mails_obj = Std_mail.query.filter_by(std_set=std_set__).first()
113142
if std_mails_obj is not None:
114143
__gevent__["attendees"].append(
115144
{"email": std_mails_obj.std_email})
145+
else:
146+
logging.error(
147+
error_str(
148+
"No Mapped email found for {}, thus calendar for it will be ignored"
149+
.format(std_set__)))
116150

117151
# add room if existing
118152

@@ -124,15 +158,18 @@ def check_timetable_validity(timetable_path,
124158
"email": res.resource_email,
125159
"resource": True
126160
})
161+
else:
162+
logging.warning(
163+
error_str("Room {} not found in database".format(
164+
event___old["room"])))
127165
else:
128-
perror("Room empty in event index : {}".format(event_inx))
129-
#continue
130-
# recurrence rule
166+
logging.warning(
167+
error_str("Room at event index {} is empty".format(event_inx)))
168+
169+
# ? recurrence rule
131170
__gevent__["recurrence"] = [
132171
"RRULE:FREQ=WEEKLY;COUNT=" + str(events_freq)
133172
]
134-
# set start and time
135-
# print(event___old["std_set"].split(" ")[0])
136173
dateTime_start = getDate(dates, event___old["std_set"].split(" ")[0],
137174
event___old["Day"],
138175
event___old["start"].split("h")[0],
@@ -152,18 +189,47 @@ def check_timetable_validity(timetable_path,
152189
all_events.append(__gevent__)
153190

154191
if len(all_events) == max_events:
192+
logging.info(
193+
success_str(
194+
"Converted {} events successfully (check log for warnings, if any)"
195+
.format(max_events)))
155196
return all_events
197+
logging.info(
198+
success_str(
199+
"Converted {} events successfully (check log for warnings, if any)"
200+
.format(len(all_events))))
156201
return all_events
157202

158203

159204
def check_google_event(gevent):
160-
205+
"""Checks if a google calendar object can be sent to the API without any errors/.\
206+
So, any errors would be either from the API itself or the network status.
207+
208+
Args:
209+
gevent (dict): A google calendar event
210+
211+
Raises:
212+
NotImplementedError: Obviously, this is not yet implemented, daah!
213+
"""
161214
raise NotImplementedError
162215

163216

164217
if __name__ == "__main__":
165-
tt_path = sys.argv[1]
166-
all_events = check_timetable_validity(timetable_path=tt_path)
218+
# ? create an arguemnt parser
219+
parser = argparse.ArgumentParser(
220+
description="Script to check FET timetable file for any errors/warnings before running the import" \
221+
" operation from the web app")
222+
parser.add_argument("-f",
223+
"--file",
224+
type=str,
225+
metavar='Path',
226+
dest='file',
227+
help="Path to the FET generated timetable CSV file.")
228+
229+
# ? Parse arguments
230+
args = parser.parse_args()
231+
tt_path = args.file
232+
all_events = check_timetable_validity(timetable_path=tt_path, dates=dates)
167233
for event in all_events:
168234
resource = None
169235
teachers = []
@@ -188,10 +254,6 @@ def check_google_event(gevent):
188254
std_email=std_mail["email"]).first()
189255
if cal_rec:
190256
calendar_id = cal_rec.calendar_id_google
191-
"""
192-
#import pdb; pdb.set_trace()
193-
"""
194257
else:
195-
print("Calendar does not exist")
196-
print("_________")
258+
perror("Calendar does not exist, check please")
197259
continue

0 commit comments

Comments
 (0)