mirror of
https://github.com/aaronleetw/Attendance.git
synced 2024-11-14 19:11:39 -08:00
Separate py files
This commit is contained in:
parent
54b5bfae63
commit
9edc8863c8
8 changed files with 621 additions and 558 deletions
549
app.py
549
app.py
|
@ -1,16 +1,16 @@
|
|||
from typing import OrderedDict
|
||||
from flask import *
|
||||
import pyrebase
|
||||
from datetime import datetime
|
||||
import pytz
|
||||
import csv
|
||||
import os
|
||||
import pandas as pd
|
||||
import base64
|
||||
from dotenv import load_dotenv
|
||||
import requests
|
||||
from manage import manage
|
||||
from upload import upload
|
||||
load_dotenv()
|
||||
app = Flask(__name__)
|
||||
app.register_blueprint(manage)
|
||||
app.register_blueprint(upload)
|
||||
|
||||
app.config['SECRET_KEY'] = os.environ.get('SECRET_KEY')
|
||||
config = {
|
||||
|
@ -24,27 +24,16 @@ config = {
|
|||
"measurementId": os.environ.get('measurementId'),
|
||||
}
|
||||
firebase = pyrebase.initialize_app(config)
|
||||
db = firebase.database()
|
||||
auth = firebase.auth()
|
||||
storage = firebase.storage()
|
||||
tz = pytz.timezone('Asia/Taipei')
|
||||
|
||||
|
||||
def next_item(odic, key):
|
||||
return list(odic)[list(odic.keys()).index(key) + 1]
|
||||
|
||||
|
||||
def check_login_status():
|
||||
return ('is_logged_in' not in session or
|
||||
session['is_logged_in'] == False or
|
||||
(datetime.now(tz) - session['loginTime']).total_seconds() > 3600)
|
||||
|
||||
|
||||
def check_permission():
|
||||
return (db.child('Users').child(session['uid']).child('permission').get(session['token']).val() == 'admin' and
|
||||
db.child("Users").child(session['uid']).child("showUpload").get(session['token']).val() == '1')
|
||||
|
||||
|
||||
def verify_recaptcha(response):
|
||||
data = {
|
||||
'secret': os.environ.get('RECAPTCHA_SECRET'),
|
||||
|
@ -56,186 +45,6 @@ def verify_recaptcha(response):
|
|||
return r.json()['success']
|
||||
|
||||
|
||||
def removeprefix(s, prefix):
|
||||
if s.startswith(prefix):
|
||||
return s[len(prefix):]
|
||||
return s
|
||||
|
||||
|
||||
def manageProcess(fCommand, fData):
|
||||
if (check_login_status()):
|
||||
return redirect('/logout')
|
||||
# this is to fix a bug where pyrebase doesnt load the first request
|
||||
db.child("Users").child(
|
||||
session['uid']).child("permission").get(session['token']).val()
|
||||
# end bug fix
|
||||
pl = db.child("Users").child(
|
||||
session['uid']).child("permission").get(session['token']).val()
|
||||
if pl == 'admin':
|
||||
homerooms = db.child("Homerooms").get(session['token']).val()
|
||||
currRoom = []
|
||||
if fCommand == "admin":
|
||||
currRoom = fData[0].split("^")
|
||||
else:
|
||||
for i in homerooms:
|
||||
currRoom.append(i)
|
||||
for j in homerooms[i]:
|
||||
currRoom.append(j)
|
||||
break
|
||||
break
|
||||
homeroomData = homerooms[currRoom[0]][currRoom[1]]
|
||||
absData = homeroomData["Absent"]
|
||||
homeroomData.pop('Absent')
|
||||
if 'placeholder' in homeroomData:
|
||||
homeroomData.pop('placeholder')
|
||||
currDate = ""
|
||||
if fCommand != "":
|
||||
currDate = fData[1]
|
||||
else:
|
||||
for i in absData:
|
||||
currDate = i
|
||||
if i >= datetime.now(tz).strftime("%Y-%m-%d"):
|
||||
break
|
||||
return render_template('admin.html', homerooms=homerooms, absData=absData,
|
||||
homeroomCode=currRoom, homeroomData=homeroomData, currDate=currDate, periods=['m', '1', '2', '3', '4',
|
||||
'n', '5', '6', '7', '8', '9'], showUpload=db.child("Users").child(
|
||||
session['uid']).child("showUpload").get(session['token']).val())
|
||||
elif pl == 'group':
|
||||
classes = db.child("Users").child(
|
||||
session['uid']).child("class").get(session['token']).val()
|
||||
cclass = {}
|
||||
cateData = {}
|
||||
for i in classes:
|
||||
cateData = db.child("Classes").child(
|
||||
"GP_Class").child(i).get(session['token']).val()
|
||||
cclass = {
|
||||
"name": cateData['Class'][classes[i]]['name'],
|
||||
"category": i,
|
||||
"class_id": classes[i]
|
||||
}
|
||||
homerooms = cateData['Homerooms']
|
||||
currDate = ""
|
||||
confirmed = []
|
||||
absData = {}
|
||||
for h in homerooms:
|
||||
h = h.split('^')
|
||||
hrData = db.child("Homerooms").child(
|
||||
h[0]).child(h[1]).get(session['token']).val()
|
||||
tmpAbsData = hrData['Absent']
|
||||
hrData.pop('Absent')
|
||||
if 'placeholder' in hrData:
|
||||
hrData.pop('placeholder')
|
||||
periods = []
|
||||
dow = ""
|
||||
if currDate == "":
|
||||
if fCommand == 'date':
|
||||
currDate = fData
|
||||
for j in tmpAbsData[currDate]:
|
||||
if j == "dow":
|
||||
dow = tmpAbsData[currDate][j]
|
||||
continue
|
||||
elif j == "confirm":
|
||||
confirmed.append([h[0], h[1]])
|
||||
continue
|
||||
if (tmpAbsData[currDate][j]['name'] == 'GP' and
|
||||
tmpAbsData[currDate][j]['teacher'] == cclass['category']):
|
||||
periods.append(j)
|
||||
|
||||
else:
|
||||
for i in tmpAbsData:
|
||||
currDate = i
|
||||
if i >= datetime.now(tz).strftime("%Y-%m-%d"):
|
||||
tmp = False
|
||||
for j in tmpAbsData[i]:
|
||||
if j == "dow":
|
||||
dow = tmpAbsData[i][j]
|
||||
continue
|
||||
elif j == "confirm":
|
||||
confirmed.append([h[0], h[1]])
|
||||
continue
|
||||
if (tmpAbsData[i][j]['name'] == 'GP' and
|
||||
tmpAbsData[i][j]['teacher'] == cclass['category']):
|
||||
periods.append(j)
|
||||
tmp = True
|
||||
if tmp == True:
|
||||
break
|
||||
else:
|
||||
for j in tmpAbsData[currDate]:
|
||||
if j == "dow":
|
||||
dow = tmpAbsData[currDate][j]
|
||||
continue
|
||||
elif j == "confirm":
|
||||
confirmed.append([h[0], h[1]])
|
||||
continue
|
||||
if (tmpAbsData[currDate][j]['name'] == 'GP' and
|
||||
tmpAbsData[currDate][j]['teacher'] == cclass['category']):
|
||||
periods.append(j)
|
||||
for p in periods:
|
||||
if not p in absData:
|
||||
absData[p] = {}
|
||||
for p in periods:
|
||||
if not h[0] in absData[p]:
|
||||
absData[p][h[0]] = {}
|
||||
absData[p][h[0]][h[1]] = {}
|
||||
if 'notes' in tmpAbsData[currDate][p]:
|
||||
absData[p][h[0]][h[1]
|
||||
]['notes'] = tmpAbsData[currDate][p]['notes']
|
||||
for num in hrData:
|
||||
if (cclass['category'] in hrData[num]['GP_Class'] and
|
||||
hrData[num]['GP_Class'][cclass['category']] == cclass['class_id']):
|
||||
for p in periods:
|
||||
absData[p][h[0]][h[1]][num] = {
|
||||
"name": hrData[num]['name'],
|
||||
"eng_name": hrData[num]['eng_name'],
|
||||
"alr_fill": ('signature' in tmpAbsData[currDate][p] and
|
||||
cclass['class_id'] in tmpAbsData[currDate][p]['signature']),
|
||||
"absent": False if not num in tmpAbsData[currDate][p] else tmpAbsData[currDate][p][num]
|
||||
}
|
||||
return render_template('group_teach.html', cclass=cclass, absData=absData, dow=dow, currDate=currDate, tmpAbsData=tmpAbsData, confirmed=confirmed)
|
||||
elif pl == 'homeroom':
|
||||
homeroom = db.child("Users").child(
|
||||
session['uid']).child("homeroom").get(session['token']).val().split('^')
|
||||
homeroomData = db.child("Homerooms").child(homeroom[0]).child(
|
||||
homeroom[1]).get(session['token']).val()
|
||||
times = OrderedDict({
|
||||
'm': '00:00',
|
||||
'1': '08:15',
|
||||
'2': '09:10',
|
||||
'3': '10:05',
|
||||
'4': '11:00',
|
||||
'n': '11:55',
|
||||
'5': '13:10',
|
||||
'6': '14:05',
|
||||
'7': '15:00',
|
||||
'8': '15:53',
|
||||
'9': '16:43',
|
||||
'ph': '23:59'
|
||||
})
|
||||
currPeriod = ""
|
||||
currTime = datetime.now(tz).strftime("%H:%M")
|
||||
for i in times:
|
||||
if (times[i] <= currTime and
|
||||
currTime <= times[next_item(times, i)]):
|
||||
currPeriod = i
|
||||
break
|
||||
absData = homeroomData["Absent"]
|
||||
homeroomData.pop('Absent')
|
||||
if 'placeholder' in homeroomData:
|
||||
homeroomData.pop('placeholder')
|
||||
currDate = ""
|
||||
if fCommand == 'date':
|
||||
currDate = fData
|
||||
else:
|
||||
for i in absData:
|
||||
currDate = i
|
||||
if i >= datetime.now(tz).strftime("%Y-%m-%d"):
|
||||
break
|
||||
return render_template('homeroom.html', absData=absData, homeroomCode=homeroom, homeroomData=homeroomData,
|
||||
currDate=currDate, periods=['m', '1', '2', '3', '4', 'n', '5', '6', '7', '8', '9'], currPeriod=currPeriod)
|
||||
else:
|
||||
return redirect('/logout')
|
||||
|
||||
|
||||
@ app.route('/', methods=['GET', 'POST'])
|
||||
def index():
|
||||
if request.method == 'GET':
|
||||
|
@ -267,356 +76,6 @@ def index():
|
|||
return redirect('/manage')
|
||||
|
||||
|
||||
@ app.route('/manage', methods=['GET'])
|
||||
def manage():
|
||||
return manageProcess("", "")
|
||||
|
||||
|
||||
@ app.route('/manage/date', methods=['POST'])
|
||||
def manage_date():
|
||||
return manageProcess("date", request.form['date'])
|
||||
|
||||
|
||||
@app.route('/manage/admin', methods=['POST'])
|
||||
def manage_admin():
|
||||
data = [
|
||||
request.form['grade'] + '^' + request.form['room'],
|
||||
request.form['date']
|
||||
]
|
||||
return manageProcess("admin", data)
|
||||
|
||||
|
||||
@ app.route('/manage/group_teach_publish', methods=['POST'])
|
||||
def group_teach_publish():
|
||||
if (check_login_status()):
|
||||
return redirect('/logout')
|
||||
classes = db.child("Users").child(
|
||||
session['uid']).child("class").get(session['token']).val()
|
||||
cclass = {}
|
||||
for i in classes:
|
||||
cclass = {
|
||||
"name": db.child("Classes").child("GP_Class").child(i).child(
|
||||
"Class").child(classes[i]).child("name").get(session['token']).val(),
|
||||
"category": i,
|
||||
"class_id": classes[i],
|
||||
"homerooms": db.child("Classes").child(
|
||||
"GP_Class").child(i).child("Homerooms").get(session['token']).val()
|
||||
}
|
||||
date = request.form['date']
|
||||
period = request.form['period']
|
||||
signature = request.form['signatureData']
|
||||
formData = request.form.to_dict()
|
||||
notes = ""
|
||||
if 'notes' in request.form:
|
||||
notes = request.form['notes']
|
||||
formData.pop('notes')
|
||||
signature = removeprefix(signature, 'data:image/png;base64,')
|
||||
signature = bytes(signature, 'utf-8')
|
||||
rand = str(date + '^' + cclass['category'] +
|
||||
'^' + cclass['class_id'] + '^' + period)
|
||||
rand += ".png"
|
||||
with open(os.path.join('temp', rand), "wb") as fh:
|
||||
fh.write(base64.decodebytes(signature))
|
||||
storage.child(os.path.join('signatures', rand)
|
||||
).put(os.path.join('temp', rand), session['token'])
|
||||
formData.pop('signatureData')
|
||||
formData.pop('date')
|
||||
formData.pop('period')
|
||||
for i in formData:
|
||||
i = i.split('^')
|
||||
db.child("Homerooms").child(i[1]).child(i[2]).child(
|
||||
"Absent").child(date).child(period).update({i[3]: int(i[0])}, session['token'])
|
||||
for h in cclass['homerooms']:
|
||||
h = h.split('^')
|
||||
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))}, session['token'])
|
||||
db.child("Homerooms").child(h[0]).child(h[1]).child(
|
||||
"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(
|
||||
"Absent").child(date).child(period).get(session['token']).val()
|
||||
if 'notes' in currPeriodData:
|
||||
db.child("Homerooms").child(h[0]).child(h[1]).child(
|
||||
"Absent").child(date).child(period).update({'notes': currPeriodData['notes']+'; '+notes}, session['token'])
|
||||
else:
|
||||
db.child("Homerooms").child(h[0]).child(h[1]).child(
|
||||
"Absent").child(date).child(period).update({'notes': notes}, session['token'])
|
||||
|
||||
# upload notes
|
||||
os.remove(os.path.join('temp', rand))
|
||||
return redirect('/manage')
|
||||
|
||||
|
||||
@ app.route('/manage/homeroom_abs', methods=['POST'])
|
||||
def homeroom_abs_publish():
|
||||
if (check_login_status()):
|
||||
return redirect('/logout')
|
||||
date = request.form['date']
|
||||
homeroom = request.form['homeroom'].split('^')
|
||||
period = request.form['period']
|
||||
signature = request.form['signatureData']
|
||||
formData = request.form.to_dict()
|
||||
notes = ""
|
||||
if 'notes' in request.form:
|
||||
notes = request.form['notes']
|
||||
formData.pop('notes')
|
||||
signature = removeprefix(signature, 'data:image/png;base64,')
|
||||
signature = bytes(signature, 'utf-8')
|
||||
rand = str(date + '^' + homeroom[0] + '^' + homeroom[1] + '^' + period)
|
||||
rand += ".png"
|
||||
with open(os.path.join('temp', rand), "wb") as fh:
|
||||
fh.write(base64.decodebytes(signature))
|
||||
storage.child(os.path.join('signatures', rand)
|
||||
).put(os.path.join('temp', rand), session['token'])
|
||||
formData.pop('signatureData')
|
||||
formData.pop('date')
|
||||
formData.pop('homeroom')
|
||||
formData.pop('period')
|
||||
for i in formData:
|
||||
i = i.split('^')
|
||||
db.child("Homerooms").child(homeroom[0]).child(
|
||||
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(
|
||||
"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(
|
||||
"Absent").child(date).child(period).update({'notes': notes}, session['token'])
|
||||
os.remove(os.path.join('temp', rand))
|
||||
return redirect('/manage')
|
||||
|
||||
|
||||
@app.route('/manage/homeroom_confirm', methods=['POST'])
|
||||
def homeroom_confirm():
|
||||
if (check_login_status()):
|
||||
return redirect('/logout')
|
||||
date = request.form['date']
|
||||
homeroom = request.form['homeroom'].split('^')
|
||||
signature = request.form['signatureData']
|
||||
signature = removeprefix(signature, 'data:image/png;base64,')
|
||||
signature = bytes(signature, 'utf-8')
|
||||
rand = str(date + '^' + homeroom[0] + '^' + homeroom[1] + '^' + 'hrCfrm')
|
||||
rand += ".png"
|
||||
with open(os.path.join('temp', rand), "wb") as fh:
|
||||
fh.write(base64.decodebytes(signature))
|
||||
storage.child(os.path.join('signatures', rand)
|
||||
).put(os.path.join('temp', rand), session['token'])
|
||||
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))}, session['token'])
|
||||
os.remove(os.path.join('temp', rand))
|
||||
return redirect('/manage')
|
||||
|
||||
|
||||
@ app.route('/upload/1', methods=['GET', 'POST'])
|
||||
def upload_homeroom():
|
||||
if ((not check_login_status()) and check_permission()):
|
||||
if request.method == 'GET':
|
||||
return render_template('uploadcsv.html', title="Homeroom List", url="/upload/1")
|
||||
elif request.method == 'POST':
|
||||
try:
|
||||
# get csv
|
||||
gradec = request.form['gradeCode']
|
||||
classc = request.form['classcode']
|
||||
csv_file = request.files['csv']
|
||||
filepath = os.path.join('./temp', csv_file.filename)
|
||||
csv_file.save(filepath)
|
||||
with open(filepath) as file:
|
||||
csv_dict = csv.DictReader(file)
|
||||
for row in csv_dict:
|
||||
if row['number'] == 'password':
|
||||
auth.create_user_with_email_and_password(
|
||||
gradec + classc + "@group-attendance.fhjh.tp.edu.tw", row['name'])
|
||||
user = auth.sign_in_with_email_and_password(
|
||||
gradec + classc + "@group-attendance.fhjh.tp.edu.tw", row['name'])
|
||||
db.child("Users").child(user['localId']).update({
|
||||
"permission": 'homeroom',
|
||||
"username": gradec + classc,
|
||||
"homeroom": gradec + classc
|
||||
})
|
||||
else:
|
||||
db.child("Homerooms").child(gradec).child(
|
||||
classc).child(row['number']).set(row, session['token'])
|
||||
# row['class'] row['number'] row['name'] row['eng_name']
|
||||
os.remove(filepath)
|
||||
except Exception as e:
|
||||
os.remove(filepath)
|
||||
return "Error. Please try again\n("+str(e)+")"
|
||||
return "Successfully uploaded " + gradec + "-" + classc
|
||||
else:
|
||||
return redirect('/logout')
|
||||
|
||||
|
||||
@ app.route('/upload/2', methods=['GET', 'POST'])
|
||||
def upload_gp_classes():
|
||||
if ((not check_login_status()) and check_permission()):
|
||||
if request.method == 'GET':
|
||||
return render_template('uploadcsv.html', title="Group Classes", url="/upload/2")
|
||||
elif request.method == 'POST':
|
||||
try:
|
||||
csv_file = request.files['csv']
|
||||
filepath = os.path.join('./temp', csv_file.filename)
|
||||
csv_file.save(filepath)
|
||||
csv_dict = pd.read_csv(filepath)
|
||||
category_cnt = csv_dict.shape[1] - 1
|
||||
for i in range(category_cnt):
|
||||
tmp_csv = csv_dict[csv_dict.columns[i+1]].tolist()
|
||||
for j in range(len(tmp_csv)):
|
||||
if type(tmp_csv[j]) == float:
|
||||
break
|
||||
if j % 5 == 0:
|
||||
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] + ")", session['token'])
|
||||
auth.create_user_with_email_and_password(
|
||||
tmp_csv[j] + "@group-attendance.fhjh.tp.edu.tw", tmp_csv[j+4])
|
||||
user = auth.sign_in_with_email_and_password(
|
||||
tmp_csv[j] + "@group-attendance.fhjh.tp.edu.tw", tmp_csv[j+4])
|
||||
db.child("Users").child(user['localId']).update({
|
||||
"permission": 'group',
|
||||
"username": tmp_csv[j],
|
||||
"class": {
|
||||
csv_dict.columns[i+1]: tmp_csv[j],
|
||||
}
|
||||
}, session['token'])
|
||||
os.remove(filepath)
|
||||
except Exception as e:
|
||||
os.remove(filepath)
|
||||
return "Error. Please try again\n("+str(e)+")"
|
||||
return "Successfully uploaded"
|
||||
else:
|
||||
return redirect('/logout')
|
||||
|
||||
|
||||
@ app.route('/upload/3', methods=['GET', 'POST'])
|
||||
def upload_stud_in_group():
|
||||
if ((not check_login_status()) and check_permission()):
|
||||
if request.method == 'GET':
|
||||
return render_template('uploadcsv.html', title="Student in Group List", url="/upload/3")
|
||||
elif request.method == 'POST':
|
||||
try:
|
||||
gradec = request.form['gradeCode']
|
||||
classc = request.form['classcode']
|
||||
csv_file = request.files['csv']
|
||||
filepath = os.path.join('./temp', csv_file.filename)
|
||||
csv_file.save(filepath)
|
||||
with open(filepath) as file:
|
||||
csv_dict = csv.DictReader(file)
|
||||
headers = csv_dict.fieldnames
|
||||
headers = headers[1:]
|
||||
for h in headers:
|
||||
db.child("Classes").child("GP_Class").child(
|
||||
h).child("Homerooms").update({gradec+'^'+classc: 0}, session['token'])
|
||||
for row in csv_dict:
|
||||
for h in headers:
|
||||
db.child("Homerooms").child(gradec).child(classc).child(
|
||||
row['number']).child("GP_Class").update({h: row[h]}, session['token'])
|
||||
os.remove(filepath)
|
||||
except Exception as e:
|
||||
os.remove(filepath)
|
||||
return "Error. Please try again\n("+str(e)+")"
|
||||
return "Successfully uploaded " + gradec + "-" + classc
|
||||
else:
|
||||
return redirect('/logout')
|
||||
|
||||
|
||||
@ app.route('/upload/4', methods=['GET', 'POST'])
|
||||
def upload_period_list():
|
||||
if ((not check_login_status()) and check_permission()):
|
||||
if request.method == 'GET':
|
||||
return render_template('uploadcsv.html', title="Period List", url="/upload/4")
|
||||
elif request.method == 'POST':
|
||||
try:
|
||||
# get csv
|
||||
gradec = request.form['gradeCode']
|
||||
classc = request.form['classcode']
|
||||
csv_file = request.files['csv']
|
||||
filepath = os.path.join('./temp', csv_file.filename)
|
||||
csv_file.save(filepath)
|
||||
csv_dict = pd.read_csv(filepath)
|
||||
periodCodes = csv_dict['Period Day'].tolist()
|
||||
for i in range(5):
|
||||
tmp_csv = csv_dict[str(i+1)].tolist()
|
||||
for j in range(len(tmp_csv)):
|
||||
if not (periodCodes[j].endswith('-t')):
|
||||
if type(tmp_csv[j]) == float:
|
||||
db.child("Classes").child("Homeroom").child(gradec).child(classc).child(
|
||||
str(i+1)).child(periodCodes[j]).update({'name': '--'}, session['token'])
|
||||
else:
|
||||
db.child("Classes").child("Homeroom").child(gradec).child(classc).child(
|
||||
str(i+1)).child(periodCodes[j]).update({'name': tmp_csv[j]}, session['token'])
|
||||
if not(periodCodes[j] == 'm' or periodCodes[j] == 'n'):
|
||||
j += 1
|
||||
db.child("Classes").child("Homeroom").child(gradec).child(classc).child(
|
||||
str(i+1)).child(periodCodes[j-1]).update({'teacher': tmp_csv[j]}, session['token'])
|
||||
os.remove(filepath)
|
||||
except Exception as e:
|
||||
os.remove(filepath)
|
||||
return "Error. Please try again\n("+str(e)+")"
|
||||
return "Successfully uploaded " + gradec + "-" + classc
|
||||
else:
|
||||
return redirect('/logout')
|
||||
|
||||
|
||||
@ app.route('/upload/dates', methods=['GET', 'POST'])
|
||||
def upload_dates():
|
||||
if ((not check_login_status()) and check_permission()):
|
||||
if request.method == 'GET':
|
||||
return render_template('uploadcsv.html', title="School Days", url="/upload/dates")
|
||||
elif request.method == 'POST':
|
||||
try:
|
||||
csv_file = request.files['csv']
|
||||
filepath = os.path.join('./temp', csv_file.filename)
|
||||
csv_file.save(filepath)
|
||||
with open(filepath) as file:
|
||||
csv_dict = csv.DictReader(file)
|
||||
headers = csv_dict.fieldnames
|
||||
temp = db.child("Homerooms").get(session['token']).val()
|
||||
for row in csv_dict:
|
||||
for h in headers:
|
||||
for t in temp:
|
||||
for i in temp[t]:
|
||||
periodData = db.child("Classes").child(
|
||||
"Homeroom").child(t).child(i).get(session['token']).val()
|
||||
db.child("Homerooms").child(t).child(i).child(
|
||||
"Absent").child(h).update({"dow": row[h]}, session['token'])
|
||||
db.child("Homerooms").child(t).child(i).child(
|
||||
"Absent").child(h).update(periodData[int(row[h])], session['token'])
|
||||
os.remove(filepath)
|
||||
except Exception as e:
|
||||
os.remove(filepath)
|
||||
return "Error. Please try again\n("+str(e)+")"
|
||||
return "Successfully uploaded dates"
|
||||
else:
|
||||
return redirect('/logout')
|
||||
|
||||
|
||||
@app.route('/upload/admin_acc', methods=['GET', 'POST'])
|
||||
def upload_admin_acc():
|
||||
if ((not check_login_status()) and check_permission()):
|
||||
if request.method == 'GET':
|
||||
return render_template('uploadcsv.html', title="Admin Accounts", url="/upload/admin_acc")
|
||||
elif request.method == 'POST':
|
||||
try:
|
||||
csv_file = request.files['csv']
|
||||
filepath = os.path.join('./temp', csv_file.filename)
|
||||
csv_file.save(filepath)
|
||||
with open(filepath) as file:
|
||||
csv_dict = csv.DictReader(file)
|
||||
for row in csv_dict:
|
||||
auth.create_user_with_email_and_password(
|
||||
row['username'] + '@group-attendance.fhjh.tp.edu.tw', row['password'])
|
||||
user = auth.sign_in_with_email_and_password(
|
||||
row['username'] + '@group-attendance.fhjh.tp.edu.tw', row['password'])
|
||||
db.child("Users").child(user['localId']).update({
|
||||
'permission': 'admin',
|
||||
'username': row['username'],
|
||||
'showUpload': row['permission']
|
||||
}, session['token'])
|
||||
os.remove(filepath)
|
||||
except Exception as e:
|
||||
os.remove(filepath)
|
||||
return "Error. Please try again\n("+str(e)+")"
|
||||
return "Successfully uploaded admin accounts"
|
||||
else:
|
||||
return redirect('/logout')
|
||||
|
||||
|
||||
@ app.route('/logout', methods=['GET'])
|
||||
def logout():
|
||||
session.clear()
|
||||
|
|
355
manage.py
Normal file
355
manage.py
Normal file
|
@ -0,0 +1,355 @@
|
|||
from flask import *
|
||||
from typing import OrderedDict
|
||||
from flask import *
|
||||
import pyrebase
|
||||
from datetime import datetime
|
||||
import pytz
|
||||
import os
|
||||
import base64
|
||||
from dotenv import load_dotenv
|
||||
load_dotenv()
|
||||
|
||||
|
||||
manage = Blueprint('manage', __name__)
|
||||
config = {
|
||||
"apiKey": os.environ.get('apiKey'),
|
||||
"authDomain": os.environ.get('authDomain'),
|
||||
"databaseURL": os.environ.get('databaseURL'),
|
||||
"storageBucket": os.environ.get('storageBucket'),
|
||||
"serviceAccount": os.environ.get('serviceAccount'),
|
||||
"messagingSenderId": os.environ.get('messagingSenderId'),
|
||||
"appId": os.environ.get('appId'),
|
||||
"measurementId": os.environ.get('measurementId'),
|
||||
}
|
||||
firebase = pyrebase.initialize_app(config)
|
||||
db = firebase.database()
|
||||
auth = firebase.auth()
|
||||
storage = firebase.storage()
|
||||
tz = pytz.timezone('Asia/Taipei')
|
||||
|
||||
|
||||
def next_item(odic, key):
|
||||
return list(odic)[list(odic.keys()).index(key) + 1]
|
||||
|
||||
|
||||
def check_login_status():
|
||||
return ('is_logged_in' not in session or
|
||||
session['is_logged_in'] == False or
|
||||
(datetime.now(tz) - session['loginTime']).total_seconds() > 3600)
|
||||
|
||||
|
||||
def removeprefix(s, prefix):
|
||||
if s.startswith(prefix):
|
||||
return s[len(prefix):]
|
||||
return s
|
||||
|
||||
|
||||
def manageProcess(fCommand, fData):
|
||||
if (check_login_status()):
|
||||
return redirect('/logout')
|
||||
# this is to fix a bug where pyrebase doesnt load the first request
|
||||
db.child("Users").child(
|
||||
session['uid']).child("permission").get(session['token']).val()
|
||||
# end bug fix
|
||||
pl = db.child("Users").child(
|
||||
session['uid']).child("permission").get(session['token']).val()
|
||||
if pl == 'admin':
|
||||
homerooms = db.child("Homerooms").get(session['token']).val()
|
||||
currRoom = []
|
||||
if fCommand == "admin":
|
||||
currRoom = fData[0].split("^")
|
||||
else:
|
||||
for i in homerooms:
|
||||
currRoom.append(i)
|
||||
for j in homerooms[i]:
|
||||
currRoom.append(j)
|
||||
break
|
||||
break
|
||||
homeroomData = homerooms[currRoom[0]][currRoom[1]]
|
||||
absData = homeroomData["Absent"]
|
||||
homeroomData.pop('Absent')
|
||||
if 'placeholder' in homeroomData:
|
||||
homeroomData.pop('placeholder')
|
||||
currDate = ""
|
||||
if fCommand != "":
|
||||
currDate = fData[1]
|
||||
else:
|
||||
for i in absData:
|
||||
currDate = i
|
||||
if i >= datetime.now(tz).strftime("%Y-%m-%d"):
|
||||
break
|
||||
return render_template('admin.html', homerooms=homerooms, absData=absData,
|
||||
homeroomCode=currRoom, homeroomData=homeroomData, currDate=currDate, periods=['m', '1', '2', '3', '4',
|
||||
'n', '5', '6', '7', '8', '9'], showUpload=db.child("Users").child(
|
||||
session['uid']).child("showUpload").get(session['token']).val())
|
||||
elif pl == 'group':
|
||||
classes = db.child("Users").child(
|
||||
session['uid']).child("class").get(session['token']).val()
|
||||
cclass = {}
|
||||
cateData = {}
|
||||
for i in classes:
|
||||
cateData = db.child("Classes").child(
|
||||
"GP_Class").child(i).get(session['token']).val()
|
||||
cclass = {
|
||||
"name": cateData['Class'][classes[i]]['name'],
|
||||
"category": i,
|
||||
"class_id": classes[i]
|
||||
}
|
||||
homerooms = cateData['Homerooms']
|
||||
currDate = ""
|
||||
confirmed = []
|
||||
absData = {}
|
||||
for h in homerooms:
|
||||
h = h.split('^')
|
||||
hrData = db.child("Homerooms").child(
|
||||
h[0]).child(h[1]).get(session['token']).val()
|
||||
tmpAbsData = hrData['Absent']
|
||||
hrData.pop('Absent')
|
||||
if 'placeholder' in hrData:
|
||||
hrData.pop('placeholder')
|
||||
periods = []
|
||||
dow = ""
|
||||
if currDate == "":
|
||||
if fCommand == 'date':
|
||||
currDate = fData
|
||||
for j in tmpAbsData[currDate]:
|
||||
if j == "dow":
|
||||
dow = tmpAbsData[currDate][j]
|
||||
continue
|
||||
elif j == "confirm":
|
||||
confirmed.append([h[0], h[1]])
|
||||
continue
|
||||
if (tmpAbsData[currDate][j]['name'] == 'GP' and
|
||||
tmpAbsData[currDate][j]['teacher'] == cclass['category']):
|
||||
periods.append(j)
|
||||
|
||||
else:
|
||||
for i in tmpAbsData:
|
||||
currDate = i
|
||||
if i >= datetime.now(tz).strftime("%Y-%m-%d"):
|
||||
tmp = False
|
||||
for j in tmpAbsData[i]:
|
||||
if j == "dow":
|
||||
dow = tmpAbsData[i][j]
|
||||
continue
|
||||
elif j == "confirm":
|
||||
confirmed.append([h[0], h[1]])
|
||||
continue
|
||||
if (tmpAbsData[i][j]['name'] == 'GP' and
|
||||
tmpAbsData[i][j]['teacher'] == cclass['category']):
|
||||
periods.append(j)
|
||||
tmp = True
|
||||
if tmp == True:
|
||||
break
|
||||
else:
|
||||
for j in tmpAbsData[currDate]:
|
||||
if j == "dow":
|
||||
dow = tmpAbsData[currDate][j]
|
||||
continue
|
||||
elif j == "confirm":
|
||||
confirmed.append([h[0], h[1]])
|
||||
continue
|
||||
if (tmpAbsData[currDate][j]['name'] == 'GP' and
|
||||
tmpAbsData[currDate][j]['teacher'] == cclass['category']):
|
||||
periods.append(j)
|
||||
for p in periods:
|
||||
if not p in absData:
|
||||
absData[p] = {}
|
||||
for p in periods:
|
||||
if not h[0] in absData[p]:
|
||||
absData[p][h[0]] = {}
|
||||
absData[p][h[0]][h[1]] = {}
|
||||
if 'notes' in tmpAbsData[currDate][p]:
|
||||
absData[p][h[0]][h[1]
|
||||
]['notes'] = tmpAbsData[currDate][p]['notes']
|
||||
for num in hrData:
|
||||
if (cclass['category'] in hrData[num]['GP_Class'] and
|
||||
hrData[num]['GP_Class'][cclass['category']] == cclass['class_id']):
|
||||
for p in periods:
|
||||
absData[p][h[0]][h[1]][num] = {
|
||||
"name": hrData[num]['name'],
|
||||
"eng_name": hrData[num]['eng_name'],
|
||||
"alr_fill": ('signature' in tmpAbsData[currDate][p] and
|
||||
cclass['class_id'] in tmpAbsData[currDate][p]['signature']),
|
||||
"absent": False if not num in tmpAbsData[currDate][p] else tmpAbsData[currDate][p][num]
|
||||
}
|
||||
return render_template('group_teach.html', cclass=cclass, absData=absData, dow=dow, currDate=currDate, tmpAbsData=tmpAbsData, confirmed=confirmed)
|
||||
elif pl == 'homeroom':
|
||||
homeroom = db.child("Users").child(
|
||||
session['uid']).child("homeroom").get(session['token']).val().split('^')
|
||||
homeroomData = db.child("Homerooms").child(homeroom[0]).child(
|
||||
homeroom[1]).get(session['token']).val()
|
||||
times = OrderedDict({
|
||||
'm': '00:00',
|
||||
'1': '08:15',
|
||||
'2': '09:10',
|
||||
'3': '10:05',
|
||||
'4': '11:00',
|
||||
'n': '11:55',
|
||||
'5': '13:10',
|
||||
'6': '14:05',
|
||||
'7': '15:00',
|
||||
'8': '15:53',
|
||||
'9': '16:43',
|
||||
'ph': '23:59'
|
||||
})
|
||||
currPeriod = ""
|
||||
currTime = datetime.now(tz).strftime("%H:%M")
|
||||
for i in times:
|
||||
if (times[i] <= currTime and
|
||||
currTime <= times[next_item(times, i)]):
|
||||
currPeriod = i
|
||||
break
|
||||
absData = homeroomData["Absent"]
|
||||
homeroomData.pop('Absent')
|
||||
if 'placeholder' in homeroomData:
|
||||
homeroomData.pop('placeholder')
|
||||
currDate = ""
|
||||
if fCommand == 'date':
|
||||
currDate = fData
|
||||
else:
|
||||
for i in absData:
|
||||
currDate = i
|
||||
if i >= datetime.now(tz).strftime("%Y-%m-%d"):
|
||||
break
|
||||
return render_template('homeroom.html', absData=absData, homeroomCode=homeroom, homeroomData=homeroomData,
|
||||
currDate=currDate, periods=['m', '1', '2', '3', '4', 'n', '5', '6', '7', '8', '9'], currPeriod=currPeriod)
|
||||
else:
|
||||
return redirect('/logout')
|
||||
|
||||
|
||||
@manage.route('/manage', methods=['GET'])
|
||||
def manageRoot():
|
||||
return manageProcess("", "")
|
||||
|
||||
|
||||
@manage.route('/manage/date', methods=['POST'])
|
||||
def manage_date():
|
||||
return manageProcess("date", request.form['date'])
|
||||
|
||||
|
||||
@manage.route('/manage/admin', methods=['POST'])
|
||||
def manage_admin():
|
||||
data = [
|
||||
request.form['grade'] + '^' + request.form['room'],
|
||||
request.form['date']
|
||||
]
|
||||
return manageProcess("admin", data)
|
||||
|
||||
|
||||
@manage.route('/manage/group_teach_publish', methods=['POST'])
|
||||
def group_teach_publish():
|
||||
if (check_login_status()):
|
||||
return redirect('/logout')
|
||||
classes = db.child("Users").child(
|
||||
session['uid']).child("class").get(session['token']).val()
|
||||
cclass = {}
|
||||
for i in classes:
|
||||
cclass = {
|
||||
"name": db.child("Classes").child("GP_Class").child(i).child(
|
||||
"Class").child(classes[i]).child("name").get(session['token']).val(),
|
||||
"category": i,
|
||||
"class_id": classes[i],
|
||||
"homerooms": db.child("Classes").child(
|
||||
"GP_Class").child(i).child("Homerooms").get(session['token']).val()
|
||||
}
|
||||
date = request.form['date']
|
||||
period = request.form['period']
|
||||
signature = request.form['signatureData']
|
||||
formData = request.form.to_dict()
|
||||
notes = ""
|
||||
if 'notes' in request.form:
|
||||
notes = request.form['notes']
|
||||
formData.pop('notes')
|
||||
signature = removeprefix(signature, 'data:image/png;base64,')
|
||||
signature = bytes(signature, 'utf-8')
|
||||
rand = str(date + '^' + cclass['category'] +
|
||||
'^' + cclass['class_id'] + '^' + period)
|
||||
rand += ".png"
|
||||
with open(os.path.join('temp', rand), "wb") as fh:
|
||||
fh.write(base64.decodebytes(signature))
|
||||
storage.child(os.path.join('signatures', rand)
|
||||
).put(os.path.join('temp', rand), session['token'])
|
||||
formData.pop('signatureData')
|
||||
formData.pop('date')
|
||||
formData.pop('period')
|
||||
for i in formData:
|
||||
i = i.split('^')
|
||||
db.child("Homerooms").child(i[1]).child(i[2]).child(
|
||||
"Absent").child(date).child(period).update({i[3]: int(i[0])}, session['token'])
|
||||
for h in cclass['homerooms']:
|
||||
h = h.split('^')
|
||||
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))}, session['token'])
|
||||
db.child("Homerooms").child(h[0]).child(h[1]).child(
|
||||
"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(
|
||||
"Absent").child(date).child(period).get(session['token']).val()
|
||||
if 'notes' in currPeriodData:
|
||||
db.child("Homerooms").child(h[0]).child(h[1]).child(
|
||||
"Absent").child(date).child(period).update({'notes': currPeriodData['notes']+'; '+notes}, session['token'])
|
||||
else:
|
||||
db.child("Homerooms").child(h[0]).child(h[1]).child(
|
||||
"Absent").child(date).child(period).update({'notes': notes}, session['token'])
|
||||
|
||||
# upload notes
|
||||
os.remove(os.path.join('temp', rand))
|
||||
return redirect('/manage')
|
||||
|
||||
|
||||
@manage.route('/manage/homeroom_abs', methods=['POST'])
|
||||
def homeroom_abs_publish():
|
||||
if (check_login_status()):
|
||||
return redirect('/logout')
|
||||
date = request.form['date']
|
||||
homeroom = request.form['homeroom'].split('^')
|
||||
period = request.form['period']
|
||||
signature = request.form['signatureData']
|
||||
formData = request.form.to_dict()
|
||||
notes = ""
|
||||
if 'notes' in request.form:
|
||||
notes = request.form['notes']
|
||||
formData.pop('notes')
|
||||
signature = removeprefix(signature, 'data:image/png;base64,')
|
||||
signature = bytes(signature, 'utf-8')
|
||||
rand = str(date + '^' + homeroom[0] + '^' + homeroom[1] + '^' + period)
|
||||
rand += ".png"
|
||||
with open(os.path.join('temp', rand), "wb") as fh:
|
||||
fh.write(base64.decodebytes(signature))
|
||||
storage.child(os.path.join('signatures', rand)
|
||||
).put(os.path.join('temp', rand), session['token'])
|
||||
formData.pop('signatureData')
|
||||
formData.pop('date')
|
||||
formData.pop('homeroom')
|
||||
formData.pop('period')
|
||||
for i in formData:
|
||||
i = i.split('^')
|
||||
db.child("Homerooms").child(homeroom[0]).child(
|
||||
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(
|
||||
"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(
|
||||
"Absent").child(date).child(period).update({'notes': notes}, session['token'])
|
||||
os.remove(os.path.join('temp', rand))
|
||||
return redirect('/manage')
|
||||
|
||||
|
||||
@manage.route('/manage/homeroom_confirm', methods=['POST'])
|
||||
def homeroom_confirm():
|
||||
if (check_login_status()):
|
||||
return redirect('/logout')
|
||||
date = request.form['date']
|
||||
homeroom = request.form['homeroom'].split('^')
|
||||
signature = request.form['signatureData']
|
||||
signature = removeprefix(signature, 'data:image/png;base64,')
|
||||
signature = bytes(signature, 'utf-8')
|
||||
rand = str(date + '^' + homeroom[0] + '^' + homeroom[1] + '^' + 'hrCfrm')
|
||||
rand += ".png"
|
||||
with open(os.path.join('temp', rand), "wb") as fh:
|
||||
fh.write(base64.decodebytes(signature))
|
||||
storage.child(os.path.join('signatures', rand)
|
||||
).put(os.path.join('temp', rand), session['token'])
|
||||
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))}, session['token'])
|
||||
os.remove(os.path.join('temp', rand))
|
||||
return redirect('/manage')
|
|
@ -23,11 +23,16 @@
|
|||
</head>
|
||||
|
||||
<body>
|
||||
<div class="showTime">Current Time: <span id="showTime"></span></div>
|
||||
<div class="showTime"><span id="showTime"></span></div>
|
||||
<div class="container">
|
||||
<h1 class="margin-top">Admin View | 管理頁面</h1>
|
||||
<h2 class="margin-top">{{homeroomCode[0]}} {{homeroomCode[1]}}</h2>
|
||||
<h2>[{{currDate}}]</h2>
|
||||
{% if 'confirm' in absData[currDate] %}
|
||||
<h2 style="color: rgb(61, 194, 0); text-align: center;">Homeroom Confirmed 班導已確認</h2>
|
||||
{% else %}
|
||||
<h2 style="color: red; text-align: center;">Homeroom NOT Confirmed 班導尚未確認</h2>
|
||||
{% endif %}
|
||||
<a href="/logout"><button class="btn btn-primary logout margin-top">Logout 登出</button></a>
|
||||
<div class="container margin-bottom">
|
||||
<form action="/manage/admin" id="adminSelForm" method="post">
|
||||
|
@ -135,18 +140,13 @@
|
|||
</div>
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
{% if 'confirm' in absData[currDate] %}
|
||||
<p style="color: blue; text-align: center;">Homeroom Teacher Confirmed 班導已確認</p>
|
||||
{% else %}
|
||||
<p style="color: red; text-align: center;">Homeroom Teacher NOT Confirmed 班導尚未確認</p>
|
||||
{% endif %}
|
||||
{% for c in range(periods|length + 1) %}
|
||||
{% if c % 4 == 0 %}
|
||||
<div class="row signatures">
|
||||
{% endif %}
|
||||
<div class="col half">
|
||||
{% if c == 0 %}
|
||||
<div class="row">Homeroom Teacher</div>
|
||||
<div class="row">Homeroom Teacher 導師</div>
|
||||
{% if 'confirm' in absData[currDate] %}
|
||||
<div class="row"><img src="{{absData[currDate]['confirm']}}" alt=""></div>
|
||||
{% else %}
|
||||
|
|
|
@ -23,7 +23,7 @@
|
|||
</head>
|
||||
|
||||
<body>
|
||||
<div class="showTime">Current Time: <span id="showTime"></span></div>
|
||||
<div class="showTime"><span id="showTime"></span></div>
|
||||
<div class="container">
|
||||
<h1 class="margin-top">Group Class View | 分組課頁面</h1>
|
||||
<h2 class="margin-top">{{cclass['category']}}: {{cclass['class_id']}}: {{cclass['name']}}</h2>
|
||||
|
@ -188,8 +188,8 @@
|
|||
document.getElementById('late^' + string).checked = false;
|
||||
}
|
||||
</script>
|
||||
<div id="loading" style="text-align:center; width:100%; max-height:100%; display:none;"><img
|
||||
src="/static/loading.gif" alt="" style="width:100%;" />
|
||||
<div id="loading" style="text-align:center; width:100%; display:none;"><img src="/static/loading.gif" alt=""
|
||||
style="height:100%;" />
|
||||
</div>
|
||||
{% include 'footer.html' %}
|
||||
<script>
|
||||
|
|
|
@ -24,7 +24,7 @@
|
|||
</head>
|
||||
|
||||
<body>
|
||||
<div class="showTime">Current Time: <span id="showTime"></span></div>
|
||||
<div class="showTime"><span id="showTime"></span></div>
|
||||
<div class="container">
|
||||
<h1 class="margin-top">Homeroom View | 班級主頁</h1>
|
||||
<h2 class="margin-top">{{homeroomCode[0]}}{{homeroomCode[1]}}</h2>
|
||||
|
|
|
@ -23,7 +23,7 @@
|
|||
</head>
|
||||
|
||||
<body>
|
||||
<div class="showTime">Current Time: <span id="showTime"></span></div>
|
||||
<div class="showTime"><span id="showTime"></span></div>
|
||||
<div class="container">
|
||||
<h1 class="margin-top margin-bottom">Attendance 點名系統 (β) | Login 登入</h1>
|
||||
<div class="row">
|
||||
|
|
|
@ -22,7 +22,7 @@
|
|||
</head>
|
||||
|
||||
<body>
|
||||
<div class="showTime">Current Time: <span id="showTime"></span></div>
|
||||
<div class="showTime"><span id="showTime"></span></div>
|
||||
<div class="container">
|
||||
<div class="row">
|
||||
<div class="col"></div>
|
||||
|
|
249
upload.py
Normal file
249
upload.py
Normal file
|
@ -0,0 +1,249 @@
|
|||
from flask import *
|
||||
import pyrebase
|
||||
from datetime import datetime
|
||||
import pytz
|
||||
import csv
|
||||
import os
|
||||
import pandas as pd
|
||||
from dotenv import load_dotenv
|
||||
load_dotenv()
|
||||
|
||||
upload = Blueprint('upload', __name__)
|
||||
config = {
|
||||
"apiKey": os.environ.get('apiKey'),
|
||||
"authDomain": os.environ.get('authDomain'),
|
||||
"databaseURL": os.environ.get('databaseURL'),
|
||||
"storageBucket": os.environ.get('storageBucket'),
|
||||
"serviceAccount": os.environ.get('serviceAccount'),
|
||||
"messagingSenderId": os.environ.get('messagingSenderId'),
|
||||
"appId": os.environ.get('appId'),
|
||||
"measurementId": os.environ.get('measurementId'),
|
||||
}
|
||||
firebase = pyrebase.initialize_app(config)
|
||||
db = firebase.database()
|
||||
auth = firebase.auth()
|
||||
tz = pytz.timezone('Asia/Taipei')
|
||||
|
||||
|
||||
def check_login_status():
|
||||
return ('is_logged_in' not in session or
|
||||
session['is_logged_in'] == False or
|
||||
(datetime.now(tz) - session['loginTime']).total_seconds() > 3600)
|
||||
|
||||
|
||||
def check_permission():
|
||||
return (db.child('Users').child(session['uid']).child('permission').get(session['token']).val() == 'admin' and
|
||||
db.child("Users").child(session['uid']).child("showUpload").get(session['token']).val() == '1')
|
||||
|
||||
|
||||
@upload.route('/upload/1', methods=['GET', 'POST'])
|
||||
def upload_homeroom():
|
||||
if ((not check_login_status()) and check_permission()):
|
||||
if request.method == 'GET':
|
||||
return render_template('uploadcsv.html', title="Homeroom List", url="/upload/1")
|
||||
elif request.method == 'POST':
|
||||
try:
|
||||
# get csv
|
||||
gradec = request.form['gradeCode']
|
||||
classc = request.form['classcode']
|
||||
csv_file = request.files['csv']
|
||||
filepath = os.path.join('./temp', csv_file.filename)
|
||||
csv_file.save(filepath)
|
||||
with open(filepath) as file:
|
||||
csv_dict = csv.DictReader(file)
|
||||
for row in csv_dict:
|
||||
if row['number'] == 'password':
|
||||
auth.create_user_with_email_and_password(
|
||||
gradec + classc + "@group-attendance.fhjh.tp.edu.tw", row['name'])
|
||||
user = auth.sign_in_with_email_and_password(
|
||||
gradec + classc + "@group-attendance.fhjh.tp.edu.tw", row['name'])
|
||||
db.child("Users").child(user['localId']).update({
|
||||
"permission": 'homeroom',
|
||||
"username": gradec + classc,
|
||||
"homeroom": gradec + classc
|
||||
})
|
||||
else:
|
||||
db.child("Homerooms").child(gradec).child(
|
||||
classc).child(row['number']).set(row, session['token'])
|
||||
# row['class'] row['number'] row['name'] row['eng_name']
|
||||
os.remove(filepath)
|
||||
except Exception as e:
|
||||
os.remove(filepath)
|
||||
return "Error. Please try again\n("+str(e)+")"
|
||||
return "Successfully uploaded " + gradec + "-" + classc
|
||||
else:
|
||||
return redirect('/logout')
|
||||
|
||||
|
||||
@upload.route('/upload/2', methods=['GET', 'POST'])
|
||||
def upload_gp_classes():
|
||||
if ((not check_login_status()) and check_permission()):
|
||||
if request.method == 'GET':
|
||||
return render_template('uploadcsv.html', title="Group Classes", url="/upload/2")
|
||||
elif request.method == 'POST':
|
||||
try:
|
||||
csv_file = request.files['csv']
|
||||
filepath = os.path.join('./temp', csv_file.filename)
|
||||
csv_file.save(filepath)
|
||||
csv_dict = pd.read_csv(filepath)
|
||||
category_cnt = csv_dict.shape[1] - 1
|
||||
for i in range(category_cnt):
|
||||
tmp_csv = csv_dict[csv_dict.columns[i+1]].tolist()
|
||||
for j in range(len(tmp_csv)):
|
||||
if type(tmp_csv[j]) == float:
|
||||
break
|
||||
if j % 5 == 0:
|
||||
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] + ")", session['token'])
|
||||
auth.create_user_with_email_and_password(
|
||||
tmp_csv[j] + "@group-attendance.fhjh.tp.edu.tw", tmp_csv[j+4])
|
||||
user = auth.sign_in_with_email_and_password(
|
||||
tmp_csv[j] + "@group-attendance.fhjh.tp.edu.tw", tmp_csv[j+4])
|
||||
db.child("Users").child(user['localId']).update({
|
||||
"permission": 'group',
|
||||
"username": tmp_csv[j],
|
||||
"class": {
|
||||
csv_dict.columns[i+1]: tmp_csv[j],
|
||||
}
|
||||
}, session['token'])
|
||||
os.remove(filepath)
|
||||
except Exception as e:
|
||||
os.remove(filepath)
|
||||
return "Error. Please try again\n("+str(e)+")"
|
||||
return "Successfully uploaded"
|
||||
else:
|
||||
return redirect('/logout')
|
||||
|
||||
|
||||
@upload.route('/upload/3', methods=['GET', 'POST'])
|
||||
def upload_stud_in_group():
|
||||
if ((not check_login_status()) and check_permission()):
|
||||
if request.method == 'GET':
|
||||
return render_template('uploadcsv.html', title="Student in Group List", url="/upload/3")
|
||||
elif request.method == 'POST':
|
||||
try:
|
||||
gradec = request.form['gradeCode']
|
||||
classc = request.form['classcode']
|
||||
csv_file = request.files['csv']
|
||||
filepath = os.path.join('./temp', csv_file.filename)
|
||||
csv_file.save(filepath)
|
||||
with open(filepath) as file:
|
||||
csv_dict = csv.DictReader(file)
|
||||
headers = csv_dict.fieldnames
|
||||
headers = headers[1:]
|
||||
for h in headers:
|
||||
db.child("Classes").child("GP_Class").child(
|
||||
h).child("Homerooms").update({gradec+'^'+classc: 0}, session['token'])
|
||||
for row in csv_dict:
|
||||
for h in headers:
|
||||
db.child("Homerooms").child(gradec).child(classc).child(
|
||||
row['number']).child("GP_Class").update({h: row[h]}, session['token'])
|
||||
os.remove(filepath)
|
||||
except Exception as e:
|
||||
os.remove(filepath)
|
||||
return "Error. Please try again\n("+str(e)+")"
|
||||
return "Successfully uploaded " + gradec + "-" + classc
|
||||
else:
|
||||
return redirect('/logout')
|
||||
|
||||
|
||||
@upload.route('/upload/4', methods=['GET', 'POST'])
|
||||
def upload_period_list():
|
||||
if ((not check_login_status()) and check_permission()):
|
||||
if request.method == 'GET':
|
||||
return render_template('uploadcsv.html', title="Period List", url="/upload/4")
|
||||
elif request.method == 'POST':
|
||||
try:
|
||||
# get csv
|
||||
gradec = request.form['gradeCode']
|
||||
classc = request.form['classcode']
|
||||
csv_file = request.files['csv']
|
||||
filepath = os.path.join('./temp', csv_file.filename)
|
||||
csv_file.save(filepath)
|
||||
csv_dict = pd.read_csv(filepath)
|
||||
periodCodes = csv_dict['Period Day'].tolist()
|
||||
for i in range(5):
|
||||
tmp_csv = csv_dict[str(i+1)].tolist()
|
||||
for j in range(len(tmp_csv)):
|
||||
if not (periodCodes[j].endswith('-t')):
|
||||
if type(tmp_csv[j]) == float:
|
||||
db.child("Classes").child("Homeroom").child(gradec).child(classc).child(
|
||||
str(i+1)).child(periodCodes[j]).update({'name': '--'}, session['token'])
|
||||
else:
|
||||
db.child("Classes").child("Homeroom").child(gradec).child(classc).child(
|
||||
str(i+1)).child(periodCodes[j]).update({'name': tmp_csv[j]}, session['token'])
|
||||
if not(periodCodes[j] == 'm' or periodCodes[j] == 'n'):
|
||||
j += 1
|
||||
db.child("Classes").child("Homeroom").child(gradec).child(classc).child(
|
||||
str(i+1)).child(periodCodes[j-1]).update({'teacher': tmp_csv[j]}, session['token'])
|
||||
os.remove(filepath)
|
||||
except Exception as e:
|
||||
os.remove(filepath)
|
||||
return "Error. Please try again\n("+str(e)+")"
|
||||
return "Successfully uploaded " + gradec + "-" + classc
|
||||
else:
|
||||
return redirect('/logout')
|
||||
|
||||
|
||||
@upload.route('/upload/dates', methods=['GET', 'POST'])
|
||||
def upload_dates():
|
||||
if ((not check_login_status()) and check_permission()):
|
||||
if request.method == 'GET':
|
||||
return render_template('uploadcsv.html', title="School Days", url="/upload/dates")
|
||||
elif request.method == 'POST':
|
||||
try:
|
||||
csv_file = request.files['csv']
|
||||
filepath = os.path.join('./temp', csv_file.filename)
|
||||
csv_file.save(filepath)
|
||||
with open(filepath) as file:
|
||||
csv_dict = csv.DictReader(file)
|
||||
headers = csv_dict.fieldnames
|
||||
temp = db.child("Homerooms").get(session['token']).val()
|
||||
for row in csv_dict:
|
||||
for h in headers:
|
||||
for t in temp:
|
||||
for i in temp[t]:
|
||||
periodData = db.child("Classes").child(
|
||||
"Homeroom").child(t).child(i).get(session['token']).val()
|
||||
db.child("Homerooms").child(t).child(i).child(
|
||||
"Absent").child(h).update({"dow": row[h]}, session['token'])
|
||||
db.child("Homerooms").child(t).child(i).child(
|
||||
"Absent").child(h).update(periodData[int(row[h])], session['token'])
|
||||
os.remove(filepath)
|
||||
except Exception as e:
|
||||
os.remove(filepath)
|
||||
return "Error. Please try again\n("+str(e)+")"
|
||||
return "Successfully uploaded dates"
|
||||
else:
|
||||
return redirect('/logout')
|
||||
|
||||
|
||||
@upload.route('/upload/admin_acc', methods=['GET', 'POST'])
|
||||
def upload_admin_acc():
|
||||
if ((not check_login_status()) and check_permission()):
|
||||
if request.method == 'GET':
|
||||
return render_template('uploadcsv.html', title="Admin Accounts", url="/upload/admin_acc")
|
||||
elif request.method == 'POST':
|
||||
try:
|
||||
csv_file = request.files['csv']
|
||||
filepath = os.path.join('./temp', csv_file.filename)
|
||||
csv_file.save(filepath)
|
||||
with open(filepath) as file:
|
||||
csv_dict = csv.DictReader(file)
|
||||
for row in csv_dict:
|
||||
auth.create_user_with_email_and_password(
|
||||
row['username'] + '@group-attendance.fhjh.tp.edu.tw', row['password'])
|
||||
user = auth.sign_in_with_email_and_password(
|
||||
row['username'] + '@group-attendance.fhjh.tp.edu.tw', row['password'])
|
||||
db.child("Users").child(user['localId']).update({
|
||||
'permission': 'admin',
|
||||
'username': row['username'],
|
||||
'showUpload': row['permission']
|
||||
}, session['token'])
|
||||
os.remove(filepath)
|
||||
except Exception as e:
|
||||
os.remove(filepath)
|
||||
return "Error. Please try again\n("+str(e)+")"
|
||||
return "Successfully uploaded admin accounts"
|
||||
else:
|
||||
return redirect('/logout')
|
Loading…
Reference in a new issue