mirror of
https://github.com/aaronleetw/Attendance.git
synced 2024-11-14 19:11:39 -08:00
Add database authentication
This commit is contained in:
parent
18f62768e0
commit
16250857df
8 changed files with 77 additions and 101 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -4,3 +4,4 @@ test.py
|
||||||
demoData/*
|
demoData/*
|
||||||
dummyData/*
|
dummyData/*
|
||||||
users.txt
|
users.txt
|
||||||
|
__pycache__/*
|
95
app.py
95
app.py
|
@ -42,8 +42,8 @@ def check_login_status():
|
||||||
|
|
||||||
|
|
||||||
def check_permission():
|
def check_permission():
|
||||||
return (db.child('Users').child(session['uid']).child('permission').get().val() == 'admin' and
|
return (db.child('Users').child(session['uid']).child('permission').get(session['token']).val() == 'admin' and
|
||||||
db.child("Users").child(session['uid']).child("showUpload").get().val() == '1')
|
db.child("Users").child(session['uid']).child("showUpload").get(session['token']).val() == '1')
|
||||||
|
|
||||||
|
|
||||||
def verify_recaptcha(response):
|
def verify_recaptcha(response):
|
||||||
|
@ -62,12 +62,12 @@ def manageProcess(fCommand, fData):
|
||||||
return redirect('/logout')
|
return redirect('/logout')
|
||||||
# this is to fix a bug where pyrebase doesnt load the first request
|
# this is to fix a bug where pyrebase doesnt load the first request
|
||||||
db.child("Users").child(
|
db.child("Users").child(
|
||||||
session['uid']).child("permission").get().val()
|
session['uid']).child("permission").get(session['token']).val()
|
||||||
# end bug fix
|
# end bug fix
|
||||||
pl = db.child("Users").child(
|
pl = db.child("Users").child(
|
||||||
session['uid']).child("permission").get().val()
|
session['uid']).child("permission").get(session['token']).val()
|
||||||
if pl == 'admin':
|
if pl == 'admin':
|
||||||
homerooms = db.child("Homerooms").get().val()
|
homerooms = db.child("Homerooms").get(session['token']).val()
|
||||||
currRoom = []
|
currRoom = []
|
||||||
if fCommand == "admin":
|
if fCommand == "admin":
|
||||||
currRoom = fData[0].split("^")
|
currRoom = fData[0].split("^")
|
||||||
|
@ -94,15 +94,15 @@ def manageProcess(fCommand, fData):
|
||||||
return render_template('admin.html', homerooms=homerooms, absData=absData,
|
return render_template('admin.html', homerooms=homerooms, absData=absData,
|
||||||
homeroomCode=currRoom, homeroomData=homeroomData, currDate=currDate, periods=['m', '1', '2', '3', '4',
|
homeroomCode=currRoom, homeroomData=homeroomData, currDate=currDate, periods=['m', '1', '2', '3', '4',
|
||||||
'n', '5', '6', '7', '8', '9'], showUpload=db.child("Users").child(
|
'n', '5', '6', '7', '8', '9'], showUpload=db.child("Users").child(
|
||||||
session['uid']).child("showUpload").get().val())
|
session['uid']).child("showUpload").get(session['token']).val())
|
||||||
elif pl == 'group':
|
elif pl == 'group':
|
||||||
classes = db.child("Users").child(
|
classes = db.child("Users").child(
|
||||||
session['uid']).child("class").get().val()
|
session['uid']).child("class").get(session['token']).val()
|
||||||
cclass = {}
|
cclass = {}
|
||||||
cateData = {}
|
cateData = {}
|
||||||
for i in classes:
|
for i in classes:
|
||||||
cateData = db.child("Classes").child(
|
cateData = db.child("Classes").child(
|
||||||
"GP_Class").child(i).get().val()
|
"GP_Class").child(i).get(session['token']).val()
|
||||||
cclass = {
|
cclass = {
|
||||||
"name": cateData['Class'][classes[i]]['name'],
|
"name": cateData['Class'][classes[i]]['name'],
|
||||||
"category": i,
|
"category": i,
|
||||||
|
@ -114,7 +114,8 @@ def manageProcess(fCommand, fData):
|
||||||
absData = {}
|
absData = {}
|
||||||
for h in homerooms:
|
for h in homerooms:
|
||||||
h = h.split('^')
|
h = h.split('^')
|
||||||
hrData = db.child("Homerooms").child(h[0]).child(h[1]).get().val()
|
hrData = db.child("Homerooms").child(
|
||||||
|
h[0]).child(h[1]).get(session['token']).val()
|
||||||
tmpAbsData = hrData['Absent']
|
tmpAbsData = hrData['Absent']
|
||||||
hrData.pop('Absent')
|
hrData.pop('Absent')
|
||||||
if 'placeholder' in hrData:
|
if 'placeholder' in hrData:
|
||||||
|
@ -188,9 +189,9 @@ def manageProcess(fCommand, fData):
|
||||||
return render_template('group_teach.html', cclass=cclass, absData=absData, dow=dow, currDate=currDate, tmpAbsData=tmpAbsData, confirmed=confirmed)
|
return render_template('group_teach.html', cclass=cclass, absData=absData, dow=dow, currDate=currDate, tmpAbsData=tmpAbsData, confirmed=confirmed)
|
||||||
elif pl == 'homeroom':
|
elif pl == 'homeroom':
|
||||||
homeroom = db.child("Users").child(
|
homeroom = db.child("Users").child(
|
||||||
session['uid']).child("homeroom").get().val().split('^')
|
session['uid']).child("homeroom").get(session['token']).val().split('^')
|
||||||
homeroomData = db.child("Homerooms").child(homeroom[0]).child(
|
homeroomData = db.child("Homerooms").child(homeroom[0]).child(
|
||||||
homeroom[1]).get().val()
|
homeroom[1]).get(session['token']).val()
|
||||||
times = OrderedDict({
|
times = OrderedDict({
|
||||||
'm': '00:00',
|
'm': '00:00',
|
||||||
'1': '08:15',
|
'1': '08:15',
|
||||||
|
@ -230,11 +231,11 @@ def manageProcess(fCommand, fData):
|
||||||
return redirect('/logout')
|
return redirect('/logout')
|
||||||
|
|
||||||
|
|
||||||
@ app.route('/', methods=['GET'])
|
@ app.route('/', methods=['GET', 'POST'])
|
||||||
def index():
|
def index():
|
||||||
if request.method == 'GET':
|
if request.method == 'GET':
|
||||||
if check_login_status():
|
if check_login_status():
|
||||||
return render_template('login.html', error=False)
|
return render_template('login.html')
|
||||||
return redirect('/manage')
|
return redirect('/manage')
|
||||||
elif request.method == 'POST':
|
elif request.method == 'POST':
|
||||||
if check_login_status():
|
if check_login_status():
|
||||||
|
@ -250,9 +251,13 @@ def index():
|
||||||
session['loginTime'] = datetime.now(tz)
|
session['loginTime'] = datetime.now(tz)
|
||||||
return redirect('/manage')
|
return redirect('/manage')
|
||||||
else:
|
else:
|
||||||
return render_template('login.html', error=True)
|
flash(
|
||||||
|
'reCAPTCHA 錯誤,請稍後再試一次<br>reCAPTCHA Failed. Please try again later.')
|
||||||
|
return redirect('/')
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
return render_template('login.html', error=True)
|
flash(
|
||||||
|
'帳號或密碼錯誤,請重新輸入<br>Incorrect username or password')
|
||||||
|
return redirect('/')
|
||||||
else:
|
else:
|
||||||
return redirect('/manage')
|
return redirect('/manage')
|
||||||
|
|
||||||
|
@ -281,16 +286,16 @@ def group_teach_publish():
|
||||||
if (check_login_status()):
|
if (check_login_status()):
|
||||||
return redirect('/logout')
|
return redirect('/logout')
|
||||||
classes = db.child("Users").child(
|
classes = db.child("Users").child(
|
||||||
session['uid']).child("class").get().val()
|
session['uid']).child("class").get(session['token']).val()
|
||||||
cclass = {}
|
cclass = {}
|
||||||
for i in classes:
|
for i in classes:
|
||||||
cclass = {
|
cclass = {
|
||||||
"name": db.child("Classes").child("GP_Class").child(i).child(
|
"name": db.child("Classes").child("GP_Class").child(i).child(
|
||||||
"Class").child(classes[i]).child("name").get().val(),
|
"Class").child(classes[i]).child("name").get(session['token']).val(),
|
||||||
"category": i,
|
"category": i,
|
||||||
"class_id": classes[i],
|
"class_id": classes[i],
|
||||||
"homerooms": db.child("Classes").child(
|
"homerooms": db.child("Classes").child(
|
||||||
"GP_Class").child(i).child("Homerooms").get().val()
|
"GP_Class").child(i).child("Homerooms").get(session['token']).val()
|
||||||
}
|
}
|
||||||
date = request.form['date']
|
date = request.form['date']
|
||||||
period = request.form['period']
|
period = request.form['period']
|
||||||
|
@ -307,28 +312,28 @@ def group_teach_publish():
|
||||||
with open(os.path.join('temp', rand), "wb") as fh:
|
with open(os.path.join('temp', rand), "wb") as fh:
|
||||||
fh.write(base64.decodebytes(signature))
|
fh.write(base64.decodebytes(signature))
|
||||||
storage.child(os.path.join('signatures', rand)
|
storage.child(os.path.join('signatures', rand)
|
||||||
).put(os.path.join('temp', rand))
|
).put(os.path.join('temp', rand), session['token'])
|
||||||
formData.pop('signatureData')
|
formData.pop('signatureData')
|
||||||
formData.pop('date')
|
formData.pop('date')
|
||||||
formData.pop('period')
|
formData.pop('period')
|
||||||
for i in formData:
|
for i in formData:
|
||||||
i = i.split('^')
|
i = i.split('^')
|
||||||
db.child("Homerooms").child(i[1]).child(i[2]).child(
|
db.child("Homerooms").child(i[1]).child(i[2]).child(
|
||||||
"Absent").child(date).child(period).update({i[3]: int(i[0])})
|
"Absent").child(date).child(period).update({i[3]: int(i[0])}, session['token'])
|
||||||
for h in cclass['homerooms']:
|
for h in cclass['homerooms']:
|
||||||
h = h.split('^')
|
h = h.split('^')
|
||||||
db.child("Homerooms").child(h[0]).child(h[1]).child(
|
db.child("Homerooms").child(h[0]).child(h[1]).child(
|
||||||
"Absent").child(date).child(period).child("signature").update({cclass['class_id']: str(storage.child(os.path.join('signatures', rand)).get_url(None))})
|
"Absent").child(date).child(period).child("signature").update({cclass['class_id']: str(storage.child(os.path.join('signatures', rand)).get_url(None))}, session['token'])
|
||||||
db.child("Homerooms").child(h[0]).child(h[1]).child(
|
db.child("Homerooms").child(h[0]).child(h[1]).child(
|
||||||
"Absent").child(date).child(period).child("names").child(cclass['class_id']).set(cclass['name'])
|
"Absent").child(date).child(period).child("names").child(cclass['class_id']).set(cclass['name'], session['token'])
|
||||||
currPeriodData = db.child("Homerooms").child(h[0]).child(h[1]).child(
|
currPeriodData = db.child("Homerooms").child(h[0]).child(h[1]).child(
|
||||||
"Absent").child(date).child(period).get().val()
|
"Absent").child(date).child(period).get(session['token']).val()
|
||||||
if 'notes' in currPeriodData:
|
if 'notes' in currPeriodData:
|
||||||
db.child("Homerooms").child(h[0]).child(h[1]).child(
|
db.child("Homerooms").child(h[0]).child(h[1]).child(
|
||||||
"Absent").child(date).child(period).update({'notes': currPeriodData['notes']+'; '+notes})
|
"Absent").child(date).child(period).update({'notes': currPeriodData['notes']+'; '+notes}, session['token'])
|
||||||
else:
|
else:
|
||||||
db.child("Homerooms").child(h[0]).child(h[1]).child(
|
db.child("Homerooms").child(h[0]).child(h[1]).child(
|
||||||
"Absent").child(date).child(period).update({'notes': notes})
|
"Absent").child(date).child(period).update({'notes': notes}, session['token'])
|
||||||
|
|
||||||
# upload notes
|
# upload notes
|
||||||
os.remove(os.path.join('temp', rand))
|
os.remove(os.path.join('temp', rand))
|
||||||
|
@ -355,7 +360,7 @@ def homeroom_abs_publish():
|
||||||
with open(os.path.join('temp', rand), "wb") as fh:
|
with open(os.path.join('temp', rand), "wb") as fh:
|
||||||
fh.write(base64.decodebytes(signature))
|
fh.write(base64.decodebytes(signature))
|
||||||
storage.child(os.path.join('signatures', rand)
|
storage.child(os.path.join('signatures', rand)
|
||||||
).put(os.path.join('temp', rand))
|
).put(os.path.join('temp', rand), session['token'])
|
||||||
formData.pop('signatureData')
|
formData.pop('signatureData')
|
||||||
formData.pop('date')
|
formData.pop('date')
|
||||||
formData.pop('homeroom')
|
formData.pop('homeroom')
|
||||||
|
@ -363,11 +368,11 @@ def homeroom_abs_publish():
|
||||||
for i in formData:
|
for i in formData:
|
||||||
i = i.split('^')
|
i = i.split('^')
|
||||||
db.child("Homerooms").child(homeroom[0]).child(
|
db.child("Homerooms").child(homeroom[0]).child(
|
||||||
homeroom[1]).child("Absent").child(date).child(period).update({i[1]: int(i[0])})
|
homeroom[1]).child("Absent").child(date).child(period).update({i[1]: int(i[0])}, session['token'])
|
||||||
db.child("Homerooms").child(homeroom[0]).child(homeroom[1]).child(
|
db.child("Homerooms").child(homeroom[0]).child(homeroom[1]).child(
|
||||||
"Absent").child(date).child(period).update({'signature': str(storage.child(os.path.join('signatures', rand)).get_url(None))})
|
"Absent").child(date).child(period).update({'signature': str(storage.child(os.path.join('signatures', rand)).get_url(None))}, session['token'])
|
||||||
db.child("Homerooms").child(homeroom[0]).child(homeroom[1]).child(
|
db.child("Homerooms").child(homeroom[0]).child(homeroom[1]).child(
|
||||||
"Absent").child(date).child(period).update({'notes': notes})
|
"Absent").child(date).child(period).update({'notes': notes}, session['token'])
|
||||||
os.remove(os.path.join('temp', rand))
|
os.remove(os.path.join('temp', rand))
|
||||||
return redirect('/manage')
|
return redirect('/manage')
|
||||||
|
|
||||||
|
@ -386,9 +391,9 @@ def homeroom_confirm():
|
||||||
with open(os.path.join('temp', rand), "wb") as fh:
|
with open(os.path.join('temp', rand), "wb") as fh:
|
||||||
fh.write(base64.decodebytes(signature))
|
fh.write(base64.decodebytes(signature))
|
||||||
storage.child(os.path.join('signatures', rand)
|
storage.child(os.path.join('signatures', rand)
|
||||||
).put(os.path.join('temp', rand))
|
).put(os.path.join('temp', rand), session['token'])
|
||||||
db.child("Homerooms").child(homeroom[0]).child(homeroom[1]).child("Absent").child(date).update(
|
db.child("Homerooms").child(homeroom[0]).child(homeroom[1]).child("Absent").child(date).update(
|
||||||
{"confirm": str(storage.child(os.path.join('signatures', rand)).get_url(None))})
|
{"confirm": str(storage.child(os.path.join('signatures', rand)).get_url(None))}, session['token'])
|
||||||
os.remove(os.path.join('temp', rand))
|
os.remove(os.path.join('temp', rand))
|
||||||
return redirect('/manage')
|
return redirect('/manage')
|
||||||
|
|
||||||
|
@ -421,7 +426,7 @@ def upload_homeroom():
|
||||||
})
|
})
|
||||||
else:
|
else:
|
||||||
db.child("Homerooms").child(gradec).child(
|
db.child("Homerooms").child(gradec).child(
|
||||||
classc).child(row['number']).set(row)
|
classc).child(row['number']).set(row, session['token'])
|
||||||
# row['class'] row['number'] row['name'] row['eng_name']
|
# row['class'] row['number'] row['name'] row['eng_name']
|
||||||
os.remove(filepath)
|
os.remove(filepath)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
|
@ -451,7 +456,7 @@ def upload_gp_classes():
|
||||||
break
|
break
|
||||||
if j % 5 == 0:
|
if j % 5 == 0:
|
||||||
db.child("Classes").child("GP_Class").child(csv_dict.columns[i+1]).child("Class").child(
|
db.child("Classes").child("GP_Class").child(csv_dict.columns[i+1]).child("Class").child(
|
||||||
tmp_csv[j]).child("name").set(tmp_csv[j+1] + " : " + tmp_csv[j+2] + " (" + tmp_csv[j+3] + ")")
|
tmp_csv[j]).child("name").set(tmp_csv[j+1] + " : " + tmp_csv[j+2] + " (" + tmp_csv[j+3] + ")", session['token'])
|
||||||
auth.create_user_with_email_and_password(
|
auth.create_user_with_email_and_password(
|
||||||
tmp_csv[j] + "@group-attendance.fhjh.tp.edu.tw", tmp_csv[j+4])
|
tmp_csv[j] + "@group-attendance.fhjh.tp.edu.tw", tmp_csv[j+4])
|
||||||
user = auth.sign_in_with_email_and_password(
|
user = auth.sign_in_with_email_and_password(
|
||||||
|
@ -462,7 +467,7 @@ def upload_gp_classes():
|
||||||
"class": {
|
"class": {
|
||||||
csv_dict.columns[i+1]: tmp_csv[j],
|
csv_dict.columns[i+1]: tmp_csv[j],
|
||||||
}
|
}
|
||||||
})
|
}, session['token'])
|
||||||
os.remove(filepath)
|
os.remove(filepath)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
os.remove(filepath)
|
os.remove(filepath)
|
||||||
|
@ -490,11 +495,11 @@ def upload_stud_in_group():
|
||||||
headers = headers[1:]
|
headers = headers[1:]
|
||||||
for h in headers:
|
for h in headers:
|
||||||
db.child("Classes").child("GP_Class").child(
|
db.child("Classes").child("GP_Class").child(
|
||||||
h).child("Homerooms").update({gradec+'^'+classc: 0})
|
h).child("Homerooms").update({gradec+'^'+classc: 0}, session['token'])
|
||||||
for row in csv_dict:
|
for row in csv_dict:
|
||||||
for h in headers:
|
for h in headers:
|
||||||
db.child("Homerooms").child(gradec).child(classc).child(
|
db.child("Homerooms").child(gradec).child(classc).child(
|
||||||
row['number']).child("GP_Class").update({h: row[h]})
|
row['number']).child("GP_Class").update({h: row[h]}, session['token'])
|
||||||
os.remove(filepath)
|
os.remove(filepath)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
os.remove(filepath)
|
os.remove(filepath)
|
||||||
|
@ -525,14 +530,14 @@ def upload_period_list():
|
||||||
if not (periodCodes[j].endswith('-t')):
|
if not (periodCodes[j].endswith('-t')):
|
||||||
if type(tmp_csv[j]) == float:
|
if type(tmp_csv[j]) == float:
|
||||||
db.child("Classes").child("Homeroom").child(gradec).child(classc).child(
|
db.child("Classes").child("Homeroom").child(gradec).child(classc).child(
|
||||||
str(i+1)).child(periodCodes[j]).update({'name': '--'})
|
str(i+1)).child(periodCodes[j]).update({'name': '--'}, session['token'])
|
||||||
else:
|
else:
|
||||||
db.child("Classes").child("Homeroom").child(gradec).child(classc).child(
|
db.child("Classes").child("Homeroom").child(gradec).child(classc).child(
|
||||||
str(i+1)).child(periodCodes[j]).update({'name': tmp_csv[j]})
|
str(i+1)).child(periodCodes[j]).update({'name': tmp_csv[j]}, session['token'])
|
||||||
if not(periodCodes[j] == 'm' or periodCodes[j] == 'n'):
|
if not(periodCodes[j] == 'm' or periodCodes[j] == 'n'):
|
||||||
j += 1
|
j += 1
|
||||||
db.child("Classes").child("Homeroom").child(gradec).child(classc).child(
|
db.child("Classes").child("Homeroom").child(gradec).child(classc).child(
|
||||||
str(i+1)).child(periodCodes[j-1]).update({'teacher': tmp_csv[j]})
|
str(i+1)).child(periodCodes[j-1]).update({'teacher': tmp_csv[j]}, session['token'])
|
||||||
os.remove(filepath)
|
os.remove(filepath)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
os.remove(filepath)
|
os.remove(filepath)
|
||||||
|
@ -555,19 +560,17 @@ def upload_dates():
|
||||||
with open(filepath) as file:
|
with open(filepath) as file:
|
||||||
csv_dict = csv.DictReader(file)
|
csv_dict = csv.DictReader(file)
|
||||||
headers = csv_dict.fieldnames
|
headers = csv_dict.fieldnames
|
||||||
temp = db.child("Homerooms").get().val()
|
temp = db.child("Homerooms").get(session['token']).val()
|
||||||
for row in csv_dict:
|
for row in csv_dict:
|
||||||
for h in headers:
|
for h in headers:
|
||||||
for t in temp:
|
for t in temp:
|
||||||
for i in temp[t]:
|
for i in temp[t]:
|
||||||
periodData = db.child("Classes").child(
|
periodData = db.child("Classes").child(
|
||||||
"Homeroom").child(t).child(i).get().val()
|
"Homeroom").child(t).child(i).get(session['token']).val()
|
||||||
db.child("Homerooms").child(t).child(i).child(
|
db.child("Homerooms").child(t).child(i).child(
|
||||||
"Absent").child(h).update({"dow": row[h]})
|
"Absent").child(h).update({"dow": row[h]}, session['token'])
|
||||||
db.child("Homerooms").child(t).child(i).child(
|
db.child("Homerooms").child(t).child(i).child(
|
||||||
"Absent").child(h).update(
|
"Absent").child(h).update(periodData[int(row[h])], session['token'])
|
||||||
periodData[int(row[h])]
|
|
||||||
)
|
|
||||||
os.remove(filepath)
|
os.remove(filepath)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
os.remove(filepath)
|
os.remove(filepath)
|
||||||
|
@ -598,7 +601,7 @@ def upload_admin_acc():
|
||||||
'permission': 'admin',
|
'permission': 'admin',
|
||||||
'username': row['username'],
|
'username': row['username'],
|
||||||
'showUpload': row['permission']
|
'showUpload': row['permission']
|
||||||
})
|
}, session['token'])
|
||||||
os.remove(filepath)
|
os.remove(filepath)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
os.remove(filepath)
|
os.remove(filepath)
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
<meta charset="utf-8">
|
<meta charset="utf-8">
|
||||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
<title>Admin 管理員</title>
|
<title>Admin 管理員 - Attendance 點名</title>
|
||||||
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.1/dist/css/bootstrap.min.css" rel="stylesheet"
|
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.1/dist/css/bootstrap.min.css" rel="stylesheet"
|
||||||
integrity="sha384-F3w7mX95PdgyTmZZMECAngseQB83DfGTowi0iMjiWaeVhAn4FJkqJByhZMI3AhiU" crossorigin="anonymous">
|
integrity="sha384-F3w7mX95PdgyTmZZMECAngseQB83DfGTowi0iMjiWaeVhAn4FJkqJByhZMI3AhiU" crossorigin="anonymous">
|
||||||
<link rel="stylesheet" href="/static/allpages.css">
|
<link rel="stylesheet" href="/static/allpages.css">
|
||||||
|
@ -199,15 +199,7 @@
|
||||||
<div id="loading" style="text-align:center; width:100%; display:none;"><img src="/static/loading.gif" alt=""
|
<div id="loading" style="text-align:center; width:100%; display:none;"><img src="/static/loading.gif" alt=""
|
||||||
style="height:100%;" />
|
style="height:100%;" />
|
||||||
</div>
|
</div>
|
||||||
<footer>
|
{% include 'footer.html' %}
|
||||||
<hr>
|
|
||||||
<p style="text-align: center;">© 2021 Attendance (β) | Made by <a target="_blank"
|
|
||||||
href="https://github.com/aaronleetw">Aaron Lee 李翊愷</a> for <a target="_blank"
|
|
||||||
href="https://www.fhjh.tp.edu.tw">Taipei Fuhsing Private School</a>
|
|
||||||
<br>
|
|
||||||
Consultants: Mr. Raymond Tsai 蔡瑋倫老師, Alvin Tsao 曹庭睿
|
|
||||||
</p>
|
|
||||||
</footer>
|
|
||||||
<script>
|
<script>
|
||||||
var homerooms = {};
|
var homerooms = {};
|
||||||
{% for i in homerooms %}
|
{% for i in homerooms %}
|
||||||
|
|
9
templates/footer.html
Normal file
9
templates/footer.html
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
<footer>
|
||||||
|
<hr>
|
||||||
|
<p style="text-align: center;">© 2021 Attendance (β) | Made by <a target="_blank"
|
||||||
|
href="https://github.com/aaronleetw">Aaron Lee 李翊愷</a> for <a target="_blank"
|
||||||
|
href="https://www.fhjh.tp.edu.tw">Taipei Fuhsing Private School</a>
|
||||||
|
<br>
|
||||||
|
Consultants: Mr. Raymond Tsai 蔡瑋倫老師, Alvin Tsao 曹庭睿
|
||||||
|
</p>
|
||||||
|
</footer>
|
|
@ -5,7 +5,7 @@
|
||||||
<meta charset="utf-8">
|
<meta charset="utf-8">
|
||||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
<title>Group 分組</title>
|
<title>Group 分組 - Attendance 點名</title>
|
||||||
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.1/dist/css/bootstrap.min.css" rel="stylesheet"
|
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.1/dist/css/bootstrap.min.css" rel="stylesheet"
|
||||||
integrity="sha384-F3w7mX95PdgyTmZZMECAngseQB83DfGTowi0iMjiWaeVhAn4FJkqJByhZMI3AhiU" crossorigin="anonymous">
|
integrity="sha384-F3w7mX95PdgyTmZZMECAngseQB83DfGTowi0iMjiWaeVhAn4FJkqJByhZMI3AhiU" crossorigin="anonymous">
|
||||||
<link rel="stylesheet" href="/static/allpages.css">
|
<link rel="stylesheet" href="/static/allpages.css">
|
||||||
|
@ -188,18 +188,10 @@
|
||||||
document.getElementById('late^' + string).checked = false;
|
document.getElementById('late^' + string).checked = false;
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
<div id="loading" style="text-align:center; width:100%; display:none;"><img src="/static/loading.gif" alt=""
|
<div id="loading" style="text-align:center; width:100%; max-height:100%; display:none;"><img
|
||||||
style="width:100%;" />
|
src="/static/loading.gif" alt="" style="width:100%;" />
|
||||||
</div>
|
</div>
|
||||||
<footer>
|
{% include 'footer.html' %}
|
||||||
<hr>
|
|
||||||
<p style="text-align: center;">© 2021 Attendance (β) | Made by <a target="_blank"
|
|
||||||
href="https://github.com/aaronleetw">Aaron Lee 李翊愷</a> for <a target="_blank"
|
|
||||||
href="https://www.fhjh.tp.edu.tw">Taipei Fuhsing Private School</a>
|
|
||||||
<br>
|
|
||||||
Consultants: Mr. Raymond Tsai 蔡瑋倫老師, Alvin Tsao 曹庭睿
|
|
||||||
</p>
|
|
||||||
</footer>
|
|
||||||
<script>
|
<script>
|
||||||
function loadingAnimation() {
|
function loadingAnimation() {
|
||||||
$("div.container").hide();
|
$("div.container").hide();
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
<meta charset="utf-8">
|
<meta charset="utf-8">
|
||||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
<title>Homeroom 班級 ({{homeroomCode[0]}}{{homeroomCode[1]}})</title>
|
<title>Homeroom 班級 ({{homeroomCode[0]}}{{homeroomCode[1]}}) - Attendance 點名</title>
|
||||||
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.1/dist/css/bootstrap.min.css" rel="stylesheet"
|
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.1/dist/css/bootstrap.min.css" rel="stylesheet"
|
||||||
integrity="sha384-F3w7mX95PdgyTmZZMECAngseQB83DfGTowi0iMjiWaeVhAn4FJkqJByhZMI3AhiU" crossorigin="anonymous">
|
integrity="sha384-F3w7mX95PdgyTmZZMECAngseQB83DfGTowi0iMjiWaeVhAn4FJkqJByhZMI3AhiU" crossorigin="anonymous">
|
||||||
<link rel="stylesheet" href="/static/allpages.css">
|
<link rel="stylesheet" href="/static/allpages.css">
|
||||||
|
@ -217,15 +217,7 @@
|
||||||
<div id="loading" style="text-align:center; width:100%; display:none;"><img src="/static/loading.gif" alt=""
|
<div id="loading" style="text-align:center; width:100%; display:none;"><img src="/static/loading.gif" alt=""
|
||||||
style="height:100%;" />
|
style="height:100%;" />
|
||||||
</div>
|
</div>
|
||||||
<footer>
|
{% include 'footer.html' %}
|
||||||
<hr>
|
|
||||||
<p style="text-align: center;">© 2021 Attendance (β) | Made by <a target="_blank"
|
|
||||||
href="https://github.com/aaronleetw">Aaron Lee 李翊愷</a> for <a target="_blank"
|
|
||||||
href="https://www.fhjh.tp.edu.tw">Taipei Fuhsing Private School</a>
|
|
||||||
<br>
|
|
||||||
Consultants: Mr. Raymond Tsai 蔡瑋倫老師, Alvin Tsao 曹庭睿
|
|
||||||
</p>
|
|
||||||
</footer>
|
|
||||||
<script>
|
<script>
|
||||||
var signaturePad, hrCfrm = false;
|
var signaturePad, hrCfrm = false;
|
||||||
var width = $(window).width();
|
var width = $(window).width();
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
<meta charset="utf-8">
|
<meta charset="utf-8">
|
||||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
<title>Login | 登入</title>
|
<title>Attendance 點名系統 (β)</title>
|
||||||
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.1/dist/css/bootstrap.min.css" rel="stylesheet"
|
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.1/dist/css/bootstrap.min.css" rel="stylesheet"
|
||||||
integrity="sha384-F3w7mX95PdgyTmZZMECAngseQB83DfGTowi0iMjiWaeVhAn4FJkqJByhZMI3AhiU" crossorigin="anonymous">
|
integrity="sha384-F3w7mX95PdgyTmZZMECAngseQB83DfGTowi0iMjiWaeVhAn4FJkqJByhZMI3AhiU" crossorigin="anonymous">
|
||||||
<link rel="stylesheet" href="/static/allpages.css">
|
<link rel="stylesheet" href="/static/allpages.css">
|
||||||
|
@ -51,12 +51,15 @@
|
||||||
<a target="_blank" href="https://policies.google.com/privacy">Privacy Policy</a> and
|
<a target="_blank" href="https://policies.google.com/privacy">Privacy Policy</a> and
|
||||||
<a target="_blank" href="https://policies.google.com/terms">Terms of Service</a> apply.
|
<a target="_blank" href="https://policies.google.com/terms">Terms of Service</a> apply.
|
||||||
</div>
|
</div>
|
||||||
{% if error %}
|
{% with messages = get_flashed_messages() %}
|
||||||
|
{% if messages %}
|
||||||
<div class="alert alert-danger" role="alert">
|
<div class="alert alert-danger" role="alert">
|
||||||
帳號或密碼錯誤,請重新輸入<br>
|
{% for message in messages %}
|
||||||
Incorrect username or password
|
{% autoescape false %}{{message}}{% endautoescape %}
|
||||||
|
{% endfor %}
|
||||||
</div>
|
</div>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
{% endwith %}
|
||||||
</div>
|
</div>
|
||||||
<div class="col"></div>
|
<div class="col"></div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -64,15 +67,7 @@
|
||||||
<div id="loading" style="text-align:center; width:100%; display:none;"><img src="/static/loading.gif" alt=""
|
<div id="loading" style="text-align:center; width:100%; display:none;"><img src="/static/loading.gif" alt=""
|
||||||
style="height:100%;" />
|
style="height:100%;" />
|
||||||
</div>
|
</div>
|
||||||
<footer>
|
{% include 'footer.html' %}
|
||||||
<hr>
|
|
||||||
<p style="text-align: center;">© 2021 Attendance (β) | Made by <a target="_blank"
|
|
||||||
href="https://github.com/aaronleetw">Aaron Lee 李翊愷</a> for <a target="_blank"
|
|
||||||
href="https://www.fhjh.tp.edu.tw">Taipei Fuhsing Private School</a>
|
|
||||||
<br>
|
|
||||||
Consultants: Mr. Raymond Tsai 蔡瑋倫老師, Alvin Tsao 曹庭睿
|
|
||||||
</p>
|
|
||||||
</footer>
|
|
||||||
<script type=" text/javascript" src="/static/jquery.min.js"></script>
|
<script type=" text/javascript" src="/static/jquery.min.js"></script>
|
||||||
<script>
|
<script>
|
||||||
function loadingAnimation() {
|
function loadingAnimation() {
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
<meta charset="utf-8">
|
<meta charset="utf-8">
|
||||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
<title>Login</title>
|
<title>Attendance 點名 - Upload</title>
|
||||||
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.1/dist/css/bootstrap.min.css" rel="stylesheet"
|
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.1/dist/css/bootstrap.min.css" rel="stylesheet"
|
||||||
integrity="sha384-F3w7mX95PdgyTmZZMECAngseQB83DfGTowi0iMjiWaeVhAn4FJkqJByhZMI3AhiU" crossorigin="anonymous">
|
integrity="sha384-F3w7mX95PdgyTmZZMECAngseQB83DfGTowi0iMjiWaeVhAn4FJkqJByhZMI3AhiU" crossorigin="anonymous">
|
||||||
<link rel="stylesheet" href="/static/allpages.css">
|
<link rel="stylesheet" href="/static/allpages.css">
|
||||||
|
@ -62,15 +62,7 @@
|
||||||
<div id="loading" style="text-align:center; width:100%; display:none;"><img src="/static/loading.gif" alt=""
|
<div id="loading" style="text-align:center; width:100%; display:none;"><img src="/static/loading.gif" alt=""
|
||||||
style="height:100%;" />
|
style="height:100%;" />
|
||||||
</div>
|
</div>
|
||||||
<footer>
|
{% include 'footer.html' %}
|
||||||
<hr>
|
|
||||||
<p style="text-align: center;">© 2021 Attendance (β) | Made by <a target="_blank"
|
|
||||||
href="https://github.com/aaronleetw">Aaron Lee 李翊愷</a> for <a target="_blank"
|
|
||||||
href="https://www.fhjh.tp.edu.tw">Taipei Fuhsing Private School</a>
|
|
||||||
<br>
|
|
||||||
Consultants: Mr. Raymond Tsai 蔡瑋倫老師, Alvin Tsao 曹庭睿
|
|
||||||
</p>
|
|
||||||
</footer>
|
|
||||||
<script type="text/javascript" src="/static/jquery.min.js"></script>
|
<script type="text/javascript" src="/static/jquery.min.js"></script>
|
||||||
<script>
|
<script>
|
||||||
function loadingAnimation() {
|
function loadingAnimation() {
|
||||||
|
|
Loading…
Reference in a new issue