Reformatted Files

This commit is contained in:
Aaron Lee 2021-12-27 22:34:19 +08:00
parent fb305c53d2
commit dbffe9289c
10 changed files with 329 additions and 178 deletions

3
.gitignore vendored
View file

@ -2,4 +2,5 @@
*.env *.env
test*.* test*.*
__pycache__/* __pycache__/*
excel/* excel/*
venv/*

92
app.py
View file

@ -2,6 +2,7 @@ from functions import *
from manage.manage import manage from manage.manage import manage
from upload import upload from upload import upload
from login import login from login import login
load_dotenv() load_dotenv()
app = Flask(__name__) app = Flask(__name__)
babel = Babel(app) babel = Babel(app)
@ -10,14 +11,17 @@ app.register_blueprint(upload)
app.register_blueprint(login) app.register_blueprint(login)
app.config['SECRET_KEY'] = os.environ.get('SECRET_KEY') app.config['SECRET_KEY'] = os.environ.get('SECRET_KEY')
app.config['SQLALCHEMY_DATABASE_URI'] = 'mysql+pymysql://'+os.environ.get('MYSQL_USER')+':'+os.environ.get('MYSQL_PASSWORD')+'@'+os.environ.get('MYSQL_HOST')+'/attendance' app.config['SQLALCHEMY_DATABASE_URI'] = 'mysql+pymysql://' + os.environ.get('MYSQL_USER') + ':' + os.environ.get(
'MYSQL_PASSWORD') + '@' + os.environ.get('MYSQL_HOST') + '/attendance'
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
app.config['BABEL_DEFAULT_LOCALE'] = 'zh_TW' app.config['BABEL_DEFAULT_LOCALE'] = 'zh_TW'
app.jinja_env.add_extension('jinja2.ext.loopcontrols') app.jinja_env.add_extension('jinja2.ext.loopcontrols')
sdb = SQLAlchemy(app) sdb = SQLAlchemy(app)
class DefaultModelView(ModelView): class DefaultModelView(ModelView):
restricted = True restricted = True
def __init__(self, model, session, restricted=True, name=None, category=None, endpoint=None, url=None, **kwargs): def __init__(self, model, session, restricted=True, name=None, category=None, endpoint=None, url=None, **kwargs):
self.restricted = restricted self.restricted = restricted
self.column_default_sort = ('id', True) self.column_default_sort = ('id', True)
@ -25,24 +29,32 @@ class DefaultModelView(ModelView):
setattr(self, k, v) setattr(self, k, v)
setattr(self, 'can_export', True) setattr(self, 'can_export', True)
super(DefaultModelView, self).__init__(model, session, name=name, category=category, endpoint=endpoint, url=url) super(DefaultModelView, self).__init__(model, session, name=name, category=category, endpoint=endpoint, url=url)
def is_accessible(self): def is_accessible(self):
if self.restricted == True: if self.restricted:
return ((not check_login_status()) and is_admin() and check_permission()) return (not check_login_status()) and is_admin() and check_permission()
return ((not check_login_status()) and is_admin()) return (not check_login_status()) and is_admin()
def inaccessible_callback(self, name, **kwargs):
return redirect('/')
class MyAdminIndexView(AdminIndexView):
def is_accessible(self):
return ((not check_login_status()) and is_admin())
def inaccessible_callback(self, name, **kwargs): def inaccessible_callback(self, name, **kwargs):
return redirect('/') return redirect('/')
class MyAdminIndexView(AdminIndexView):
def is_accessible(self):
return (not check_login_status()) and is_admin()
def inaccessible_callback(self, name, **kwargs):
return redirect('/')
admin = Admin( admin = Admin(
app, app,
name='Attendance 點名系統 後台管理', name='Attendance 點名系統 後台管理',
template_mode='bootstrap3', template_mode='bootstrap3',
index_view=MyAdminIndexView(), index_view=MyAdminIndexView(),
) )
class Users(sdb.Model): class Users(sdb.Model):
id = sdb.Column(sdb.INT, primary_key=True) id = sdb.Column(sdb.INT, primary_key=True)
email = sdb.Column(sdb.Text) email = sdb.Column(sdb.Text)
@ -50,6 +62,8 @@ class Users(sdb.Model):
oldUsername = sdb.Column(sdb.Text) oldUsername = sdb.Column(sdb.Text)
role = sdb.Column(sdb.CHAR) role = sdb.Column(sdb.CHAR)
password = sdb.Column(sdb.Text) password = sdb.Column(sdb.Text)
class Students(sdb.Model): class Students(sdb.Model):
id = sdb.Column(sdb.INT, primary_key=True) id = sdb.Column(sdb.INT, primary_key=True)
email = sdb.Column(sdb.INT) email = sdb.Column(sdb.INT)
@ -60,6 +74,8 @@ class Students(sdb.Model):
ename = sdb.Column(sdb.Text) ename = sdb.Column(sdb.Text)
classes = sdb.Column(sdb.Text) classes = sdb.Column(sdb.Text)
password = sdb.Column(sdb.Text) password = sdb.Column(sdb.Text)
class Schedule(sdb.Model): class Schedule(sdb.Model):
id = sdb.Column(sdb.INT, primary_key=True) id = sdb.Column(sdb.INT, primary_key=True)
grade = sdb.Column(sdb.INT) grade = sdb.Column(sdb.INT)
@ -68,6 +84,8 @@ class Schedule(sdb.Model):
period = sdb.Column(sdb.CHAR) period = sdb.Column(sdb.CHAR)
subject = sdb.Column(sdb.Text) subject = sdb.Column(sdb.Text)
teacher = sdb.Column(sdb.Text) teacher = sdb.Column(sdb.Text)
class SpecSchedule(sdb.Model): class SpecSchedule(sdb.Model):
__tablename__ = 'specschedule' __tablename__ = 'specschedule'
id = sdb.Column(sdb.INT, primary_key=True) id = sdb.Column(sdb.INT, primary_key=True)
@ -77,6 +95,8 @@ class SpecSchedule(sdb.Model):
period = sdb.Column(sdb.CHAR) period = sdb.Column(sdb.CHAR)
subject = sdb.Column(sdb.Text) subject = sdb.Column(sdb.Text)
teacher = sdb.Column(sdb.Text) teacher = sdb.Column(sdb.Text)
class GPClasses(sdb.Model): class GPClasses(sdb.Model):
__tablename__ = 'gpclasses' __tablename__ = 'gpclasses'
id = sdb.Column(sdb.INT, primary_key=True) id = sdb.Column(sdb.INT, primary_key=True)
@ -84,11 +104,15 @@ class GPClasses(sdb.Model):
subclass = sdb.Column(sdb.Text) subclass = sdb.Column(sdb.Text)
about = sdb.Column(sdb.Text) about = sdb.Column(sdb.Text)
accs = sdb.Column(sdb.Text) accs = sdb.Column(sdb.Text)
class Homerooms(sdb.Model): class Homerooms(sdb.Model):
id = sdb.Column(sdb.INT, primary_key=True) id = sdb.Column(sdb.INT, primary_key=True)
grade = sdb.Column(sdb.INT) grade = sdb.Column(sdb.INT)
class_ = sdb.Column(sdb.INT) class_ = sdb.Column(sdb.INT)
accs = sdb.Column(sdb.Text) accs = sdb.Column(sdb.Text)
class Submission(sdb.Model): class Submission(sdb.Model):
id = sdb.Column(sdb.INT, primary_key=True) id = sdb.Column(sdb.INT, primary_key=True)
grade = sdb.Column(sdb.INT) grade = sdb.Column(sdb.INT)
@ -104,6 +128,8 @@ class Submission(sdb.Model):
ds6 = sdb.Column(sdb.INT) ds6 = sdb.Column(sdb.INT)
ds7 = sdb.Column(sdb.INT) ds7 = sdb.Column(sdb.INT)
notes = sdb.Column(sdb.Text) notes = sdb.Column(sdb.Text)
class DS(sdb.Model): class DS(sdb.Model):
id = sdb.Column(sdb.INT, primary_key=True) id = sdb.Column(sdb.INT, primary_key=True)
grade = sdb.Column(sdb.INT) grade = sdb.Column(sdb.INT)
@ -113,10 +139,14 @@ class DS(sdb.Model):
period = sdb.Column(sdb.CHAR) period = sdb.Column(sdb.CHAR)
note = sdb.Column(sdb.Text) note = sdb.Column(sdb.Text)
status = sdb.Column(sdb.CHAR, default='X') status = sdb.Column(sdb.CHAR, default='X')
class Dates(sdb.Model): class Dates(sdb.Model):
id = sdb.Column(sdb.INT, primary_key=True) id = sdb.Column(sdb.INT, primary_key=True)
date = sdb.Column(sdb.VARCHAR(11)) date = sdb.Column(sdb.VARCHAR(11))
dow = sdb.Column(sdb.INT) dow = sdb.Column(sdb.INT)
class Absent(sdb.Model): class Absent(sdb.Model):
id = sdb.Column(sdb.INT, primary_key=True) id = sdb.Column(sdb.INT, primary_key=True)
grade = sdb.Column(sdb.INT) grade = sdb.Column(sdb.INT)
@ -126,22 +156,34 @@ class Absent(sdb.Model):
period = sdb.Column(sdb.CHAR) period = sdb.Column(sdb.CHAR)
status = sdb.Column(sdb.CHAR) status = sdb.Column(sdb.CHAR)
note = sdb.Column(sdb.Text) note = sdb.Column(sdb.Text)
class Forgot(sdb.Model): class Forgot(sdb.Model):
id = sdb.Column(sdb.INT, primary_key=True) id = sdb.Column(sdb.INT, primary_key=True)
resetID = sdb.Column(sdb.VARCHAR(11)) resetID = sdb.Column(sdb.VARCHAR(11))
email = sdb.Column(sdb.Text) email = sdb.Column(sdb.Text)
reqTime = sdb.Column(sdb.VARCHAR(20)) reqTime = sdb.Column(sdb.VARCHAR(20))
admin.add_view(DefaultModelView(Users, sdb.session, restricted=False, column_exclude_list = ['password'], column_searchable_list = ['name', 'email', 'role']))
admin.add_view(DefaultModelView(Students, sdb.session, restricted=False, column_exclude_list = ['password'], column_searchable_list = ['grade', 'class_', 'num', 'email','name', 'ename', 'classes']))
admin.add_view(DefaultModelView(Schedule, sdb.session, column_searchable_list = ['grade', 'class_', 'dow', 'period', 'subject', 'teacher'])) admin.add_view(DefaultModelView(Users, sdb.session, restricted=False, column_exclude_list=['password'],
admin.add_view(DefaultModelView(SpecSchedule, sdb.session, restricted=False, column_searchable_list = ['grade', 'class_', 'date', 'period', 'subject', 'teacher'])) column_searchable_list=['name', 'email', 'role']))
admin.add_view(DefaultModelView(GPClasses, sdb.session, column_searchable_list = ['category', 'subclass', 'about', 'accs'])) admin.add_view(DefaultModelView(Students, sdb.session, restricted=False, column_exclude_list=['password'],
admin.add_view(DefaultModelView(Homerooms, sdb.session, column_searchable_list = ['grade', 'class_', 'accs'])) column_searchable_list=['grade', 'class_', 'num', 'email', 'name', 'ename', 'classes']))
admin.add_view(DefaultModelView(Submission, sdb.session, column_exclude_list=['signature'], column_searchable_list = ['grade', 'class_', 'date', 'period', 'notes'])) admin.add_view(DefaultModelView(Schedule, sdb.session,
admin.add_view(DefaultModelView(DS, sdb.session, restricted=False, column_searchable_list = ['grade', 'class_', 'date', 'period', 'num', 'note', 'status'])) column_searchable_list=['grade', 'class_', 'dow', 'period', 'subject', 'teacher']))
admin.add_view(DefaultModelView(Dates, sdb.session, column_searchable_list = ['date', 'dow'])) admin.add_view(DefaultModelView(SpecSchedule, sdb.session, restricted=False,
admin.add_view(DefaultModelView(Absent, sdb.session, restricted=False, column_searchable_list = ['grade', 'class_', 'date', 'period', 'num', 'status', 'note'])) column_searchable_list=['grade', 'class_', 'date', 'period', 'subject', 'teacher']))
admin.add_view(DefaultModelView(Forgot, sdb.session, column_searchable_list = ['resetID', 'email', 'reqTime'])) admin.add_view(
DefaultModelView(GPClasses, sdb.session, column_searchable_list=['category', 'subclass', 'about', 'accs']))
admin.add_view(DefaultModelView(Homerooms, sdb.session, column_searchable_list=['grade', 'class_', 'accs']))
admin.add_view(DefaultModelView(Submission, sdb.session, column_exclude_list=['signature'],
column_searchable_list=['grade', 'class_', 'date', 'period', 'notes']))
admin.add_view(DefaultModelView(DS, sdb.session, restricted=False,
column_searchable_list=['grade', 'class_', 'date', 'period', 'num', 'note', 'status']))
admin.add_view(DefaultModelView(Dates, sdb.session, column_searchable_list=['date', 'dow']))
admin.add_view(DefaultModelView(Absent, sdb.session, restricted=False,
column_searchable_list=['grade', 'class_', 'date', 'period', 'num', 'status', 'note']))
admin.add_view(DefaultModelView(Forgot, sdb.session, column_searchable_list=['resetID', 'email', 'reqTime']))
admin.add_link(MenuLink(name='Back to Home 返回一般管理', category='', url='/manage')) admin.add_link(MenuLink(name='Back to Home 返回一般管理', category='', url='/manage'))
admin.add_link(MenuLink(name='Logout 登出', category='', url='/logout')) admin.add_link(MenuLink(name='Logout 登出', category='', url='/logout'))

View file

@ -9,6 +9,7 @@ side = Side(border_style='thin')
border = Border(left=side, right=side, top=side, bottom=side) border = Border(left=side, right=side, top=side, bottom=side)
bold_bottom = Border(left=side, right=side, top=side, bottom=Side(border_style='medium', color='FF000000')) bold_bottom = Border(left=side, right=side, top=side, bottom=Side(border_style='medium', color='FF000000'))
def create_period_sheets(workbook, class_code): def create_period_sheets(workbook, class_code):
ws = workbook.create_sheet(class_code[0] + class_code[1]) ws = workbook.create_sheet(class_code[0] + class_code[1])
ws.merge_cells('A1:F1') ws.merge_cells('A1:F1')
@ -41,7 +42,7 @@ def create_period_sheets(workbook, class_code):
ws.cell(row=2, column=i).font = Font(size=14, bold=True) ws.cell(row=2, column=i).font = Font(size=14, bold=True)
ws.cell(row=2, column=i).alignment = center ws.cell(row=2, column=i).alignment = center
ws.cell(row=2, column=i).border = border ws.cell(row=2, column=i).border = border
# loop over C:G # loop over C:G
for i in range(2, 8): for i in range(2, 8):
ws.column_dimensions[str(chr(ord('A') + i))].width = 13 ws.column_dimensions[str(chr(ord('A') + i))].width = 13
@ -49,7 +50,8 @@ def create_period_sheets(workbook, class_code):
# get data # get data
db = refresh_db() db = refresh_db()
cursor = db.cursor() cursor = db.cursor()
cursor.execute("SELECT dow,period,subject,teacher FROM schedule WHERE grade=%s AND class_=%s", (class_code[0], class_code[1])) cursor.execute("SELECT dow,period,subject,teacher FROM schedule WHERE grade=%s AND class_=%s",
(class_code[0], class_code[1]))
sql = cursor.fetchall() sql = cursor.fetchall()
data = {} data = {}
subject_teacher = {} subject_teacher = {}
@ -64,7 +66,7 @@ def create_period_sheets(workbook, class_code):
if i[2] != 'GP' and i[2] != '--' and i[3] != '--' and i[2] not in subject_teacher: if i[2] != 'GP' and i[2] != '--' and i[3] != '--' and i[2] not in subject_teacher:
subject_teacher[i[2]] = i[3] subject_teacher[i[2]] = i[3]
periods=['m', '1', '2', '3', '4', 'n', '5', '6', '7', '8', '9'] periods = ['m', '1', '2', '3', '4', 'n', '5', '6', '7', '8', '9']
times = { times = {
'm': ['7:30', '8:10'], 'm': ['7:30', '8:10'],
'1': ['8:20', '9:05'], '1': ['8:20', '9:05'],
@ -100,25 +102,27 @@ def create_period_sheets(workbook, class_code):
if p == 'm' or p == 'n': if p == 'm' or p == 'n':
ws.merge_cells('C' + str(curr) + ':G' + str(curr + 1)) ws.merge_cells('C' + str(curr) + ':G' + str(curr + 1))
for i in range(1, 6): for i in range(1, 6):
ws[chr(ord('C') + i-1) + str(curr)].font = std_font ws[chr(ord('C') + i - 1) + str(curr)].font = std_font
ws[chr(ord('C') + i-1) + str(curr)].alignment = center ws[chr(ord('C') + i - 1) + str(curr)].alignment = center
ws[chr(ord('C') + i-1) + str(curr)].border = border ws[chr(ord('C') + i - 1) + str(curr)].border = border
ws[chr(ord('C') + i-1) + str(curr + 1)].border = border ws[chr(ord('C') + i - 1) + str(curr + 1)].border = border
if p == 'm': if p == 'm':
ws['C' + str(curr)] = '早自習' ws['C' + str(curr)] = '早自習'
else: else:
ws['C' + str(curr)] = '午餐 / 午休' ws['C' + str(curr)] = '午餐 / 午休'
else: else:
for i in range(1, 6): for i in range(1, 6):
ws.merge_cells(chr(ord('C') + i-1) + str(curr) + ':' + chr(ord('C') + i-1) + str(curr + 1)) ws.merge_cells(chr(ord('C') + i - 1) + str(curr) + ':' + chr(ord('C') + i - 1) + str(curr + 1))
ws[chr(ord('C') + i-1) + str(curr)].font = std_font ws[chr(ord('C') + i - 1) + str(curr)].font = std_font
ws[chr(ord('C') + i-1) + str(curr)].alignment = center ws[chr(ord('C') + i - 1) + str(curr)].alignment = center
ws[chr(ord('C') + i-1) + str(curr)].border = border ws[chr(ord('C') + i - 1) + str(curr)].border = border
ws[chr(ord('C') + i-1) + str(curr + 1)].border = border ws[chr(ord('C') + i - 1) + str(curr + 1)].border = border
if i in data: if i in data:
if p in data[i]: if p in data[i]:
ws[chr(ord('C') + i-1) + str(curr)] = (data[i][p]['subject'] if data[i][p]['subject'] != 'GP' ws[chr(ord('C') + i - 1) + str(curr)] = (data[i][p]['subject'] if data[i][p]['subject'] != 'GP'
and data[i][p]['subject'] != '--' else '' if data[i][p]['subject'] == '--' else data[i][p]['teacher']) and data[i][p][
'subject'] != '--' else '' if
data[i][p]['subject'] == '--' else data[i][p]['teacher'])
curr += 2 curr += 2
ws.merge_cells('A26:G26') ws.merge_cells('A26:G26')
ws['A26'] = '科任老師一覽表' ws['A26'] = '科任老師一覽表'
@ -136,7 +140,7 @@ def create_period_sheets(workbook, class_code):
pos = ['D', 'E'] pos = ['D', 'E']
else: else:
pos = ['F', 'G'] pos = ['F', 'G']
loc = str(27+ int(curr/3)) loc = str(27 + int(curr / 3))
ws.merge_cells(pos[0] + loc + ':' + pos[1] + loc) ws.merge_cells(pos[0] + loc + ':' + pos[1] + loc)
ws[pos[0] + loc].font = std_font ws[pos[0] + loc].font = std_font
ws[pos[0] + loc].alignment = center ws[pos[0] + loc].alignment = center
@ -148,6 +152,7 @@ def create_period_sheets(workbook, class_code):
curr += 1 curr += 1
return workbook return workbook
def create_student_list(workbook, class_code): def create_student_list(workbook, class_code):
ws = workbook.create_sheet(class_code[0] + class_code[1]) ws = workbook.create_sheet(class_code[0] + class_code[1])
ws.merge_cells('A1:J1') ws.merge_cells('A1:J1')
@ -186,27 +191,29 @@ def create_student_list(workbook, class_code):
ws.column_dimensions[str(chr(ord('A') + i))].width = 5.8 ws.column_dimensions[str(chr(ord('A') + i))].width = 5.8
db = refresh_db() db = refresh_db()
cursor = db.cursor() cursor = db.cursor()
cursor.execute('SELECT num,name,ename FROM students WHERE grade=%s AND class_=%s ORDER BY num ASC', (class_code[0], class_code[1])) cursor.execute('SELECT num,name,ename FROM students WHERE grade=%s AND class_=%s ORDER BY num ASC',
(class_code[0], class_code[1]))
data = cursor.fetchall() data = cursor.fetchall()
last = data[-1][0] last = data[-1][0]
delcnt = 0 delcnt = 0
for i in range(0, last): for i in range(0, last):
ws['A' + str(3 + i)] = i+1 ws['A' + str(3 + i)] = i + 1
ws['A' + str(3 + i)].font = std_font ws['A' + str(3 + i)].font = std_font
ws['A' + str(3 + i)].alignment = center ws['A' + str(3 + i)].alignment = center
ws['B' + str(3 + i)] = data[i - delcnt][1] if data[i - delcnt][0] == i+1 else '' ws['B' + str(3 + i)] = data[i - delcnt][1] if data[i - delcnt][0] == i + 1 else ''
ws['B' + str(3 + i)].font = Font(name="DFKai-SB", size=14) ws['B' + str(3 + i)].font = Font(name="DFKai-SB", size=14)
ws['B' + str(3 + i)].alignment = center ws['B' + str(3 + i)].alignment = center
ws['C' + str(3 + i)] = data[i - delcnt][2] if data[i - delcnt][0] == i+1 else '' ws['C' + str(3 + i)] = data[i - delcnt][2] if data[i - delcnt][0] == i + 1 else ''
ws['C' + str(3 + i)].font = std_font ws['C' + str(3 + i)].font = std_font
ws['C' + str(3 + i)].alignment = center ws['C' + str(3 + i)].alignment = center
ws.row_dimensions[3 + i].height = 19 ws.row_dimensions[3 + i].height = 19
for j in range(0, 12): for j in range(0, 12):
ws[str(chr(ord('A') + j)) + str(3 + i)].border = bold_bottom if (i+1)%5==0 else border ws[str(chr(ord('A') + j)) + str(3 + i)].border = bold_bottom if (i + 1) % 5 == 0 else border
if data[i - delcnt][0] != i+1: if data[i - delcnt][0] != i + 1:
delcnt += 1 delcnt += 1
return workbook return workbook
def create_teacher_periods(workbook, teacher_name, orig_username=''): def create_teacher_periods(workbook, teacher_name, orig_username=''):
ws = workbook.create_sheet(teacher_name) ws = workbook.create_sheet(teacher_name)
ws.merge_cells('A1:E1') ws.merge_cells('A1:E1')
@ -241,7 +248,7 @@ def create_teacher_periods(workbook, teacher_name, orig_username=''):
ws.cell(row=2, column=i).font = Font(size=14, bold=True) ws.cell(row=2, column=i).font = Font(size=14, bold=True)
ws.cell(row=2, column=i).alignment = center ws.cell(row=2, column=i).alignment = center
ws.cell(row=2, column=i).border = border ws.cell(row=2, column=i).border = border
# loop over C:G # loop over C:G
for i in range(2, 8): for i in range(2, 8):
ws.column_dimensions[str(chr(ord('A') + i))].width = 13 ws.column_dimensions[str(chr(ord('A') + i))].width = 13
@ -251,10 +258,10 @@ def create_teacher_periods(workbook, teacher_name, orig_username=''):
db = refresh_db() db = refresh_db()
cursor = db.cursor() cursor = db.cursor()
if orig_username is not '': if orig_username is not '':
cursor.execute('SELECT category,subclass FROM gpclasses WHERE accs LIKE %s', ('%'+orig_username+'%',)) cursor.execute('SELECT category,subclass FROM gpclasses WHERE accs LIKE %s', ('%' + orig_username + '%',))
gp_sql = cursor.fetchall() gp_sql = cursor.fetchall()
for i in gp_sql: for i in gp_sql:
cursor.execute('SELECT dow,period FROM schedule WHERE teacher=%s', (i[0], )) cursor.execute('SELECT dow,period FROM schedule WHERE teacher=%s', (i[0],))
tmp_sql = cursor.fetchall() tmp_sql = cursor.fetchall()
for j in tmp_sql: for j in tmp_sql:
if j[0] not in data: if j[0] not in data:
@ -263,7 +270,7 @@ def create_teacher_periods(workbook, teacher_name, orig_username=''):
'subject': i[0], 'subject': i[0],
'class': i[1] 'class': i[1]
} }
cursor.execute("SELECT dow,period,subject,grade,class_ FROM schedule WHERE teacher=%s", (teacher_name, )) cursor.execute("SELECT dow,period,subject,grade,class_ FROM schedule WHERE teacher=%s", (teacher_name,))
sql = cursor.fetchall() sql = cursor.fetchall()
# loop over data # loop over data
for i in sql: for i in sql:
@ -274,7 +281,7 @@ def create_teacher_periods(workbook, teacher_name, orig_username=''):
'class': str(i[3]) + str(i[4]) 'class': str(i[3]) + str(i[4])
} }
periods=['m', '1', '2', '3', '4', 'n', '5', '6', '7', '8', '9'] periods = ['m', '1', '2', '3', '4', 'n', '5', '6', '7', '8', '9']
times = { times = {
'm': ['7:30', '8:10'], 'm': ['7:30', '8:10'],
'1': ['8:20', '9:05'], '1': ['8:20', '9:05'],
@ -310,24 +317,27 @@ def create_teacher_periods(workbook, teacher_name, orig_username=''):
if p == 'm' or p == 'n': if p == 'm' or p == 'n':
ws.merge_cells('C' + str(curr) + ':G' + str(curr + 1)) ws.merge_cells('C' + str(curr) + ':G' + str(curr + 1))
for i in range(1, 6): for i in range(1, 6):
ws[chr(ord('C') + i-1) + str(curr)].font = std_font ws[chr(ord('C') + i - 1) + str(curr)].font = std_font
ws[chr(ord('C') + i-1) + str(curr)].alignment = center ws[chr(ord('C') + i - 1) + str(curr)].alignment = center
ws[chr(ord('C') + i-1) + str(curr)].border = border ws[chr(ord('C') + i - 1) + str(curr)].border = border
ws[chr(ord('C') + i-1) + str(curr + 1)].border = border ws[chr(ord('C') + i - 1) + str(curr + 1)].border = border
if p == 'm': if p == 'm':
ws['C' + str(curr)] = '早自習' ws['C' + str(curr)] = '早自習'
else: else:
ws['C' + str(curr)] = '午餐 / 午休' ws['C' + str(curr)] = '午餐 / 午休'
else: else:
for i in range(1, 6): for i in range(1, 6):
ws.merge_cells(chr(ord('C') + i-1) + str(curr) + ':' + chr(ord('C') + i-1) + str(curr + 1)) ws.merge_cells(chr(ord('C') + i - 1) + str(curr) + ':' + chr(ord('C') + i - 1) + str(curr + 1))
ws[chr(ord('C') + i-1) + str(curr)].font = std_font ws[chr(ord('C') + i - 1) + str(curr)].font = std_font
ws[chr(ord('C') + i-1) + str(curr)].border = border ws[chr(ord('C') + i - 1) + str(curr)].border = border
ws[chr(ord('C') + i-1) + str(curr + 1)].border = border ws[chr(ord('C') + i - 1) + str(curr + 1)].border = border
ws[chr(ord('C') + i-1) + str(curr)].alignment = center + Alignment(wrapText=True) ws[chr(ord('C') + i - 1) + str(curr)].alignment = center + Alignment(wrapText=True)
if i in data: if i in data:
if p in data[i]: if p in data[i]:
ws[chr(ord('C') + i-1) + str(curr)] = (data[i][p]['subject'] + '\n' + data[i][p]['class'] if data[i][p]['subject'] != 'GP' ws[chr(ord('C') + i - 1) + str(curr)] = (
and data[i][p]['subject'] != '--' else '' if data[i][p]['subject'] == '--' else data[i][p]['teacher']) data[i][p]['subject'] + '\n' + data[i][p]['class'] if data[i][p]['subject'] != 'GP'
and data[i][p][
'subject'] != '--' else '' if
data[i][p]['subject'] == '--' else data[i][p]['teacher'])
curr += 2 curr += 2
return workbook return workbook

View file

@ -20,6 +20,7 @@ from flask_admin import Admin, AdminIndexView, expose
from flask_admin.menu import MenuLink from flask_admin.menu import MenuLink
from flask_admin.contrib.sqla import ModelView from flask_admin.contrib.sqla import ModelView
from flask_babelex import Babel from flask_babelex import Babel
load_dotenv() load_dotenv()
tz = pytz.timezone('Asia/Taipei') tz = pytz.timezone('Asia/Taipei')
@ -44,7 +45,7 @@ DSTEXT = [
] ]
DSOFFENSES = { DSOFFENSES = {
'A': "把玩物品、不專心聽講", 'A': "把玩物品、不專心聽講",
'B': "書寫或傳遞紙條、物品", 'B': "書寫或傳遞紙條、物品",
'C': "自言自語或與同學交談", 'C': "自言自語或與同學交談",
'D': "接話、大聲笑、起哄、發出怪聲", 'D': "接話、大聲笑、起哄、發出怪聲",
'E': "亂動、逗弄同學、影響教學情境", 'E': "亂動、逗弄同學、影響教學情境",
@ -54,17 +55,21 @@ DSOFFENSES = {
'Z': "上課睡覺" 'Z': "上課睡覺"
} }
def refresh_db(): def refresh_db():
return mysql.connector.connect(user=os.environ.get('MYSQL_USER'), password=os.environ.get('MYSQL_PASSWORD'), return mysql.connector.connect(user=os.environ.get('MYSQL_USER'), password=os.environ.get('MYSQL_PASSWORD'),
host=os.environ.get('MYSQL_HOST'), host=os.environ.get('MYSQL_HOST'),
database='attendance') database='attendance')
def genHash(password): def genHash(password):
return sha256_crypt.hash(password) return sha256_crypt.hash(password)
def verifyPassword(password, hash): def verifyPassword(password, hash):
return sha256_crypt.verify(password, hash) return sha256_crypt.verify(password, hash)
def refresh_token(): def refresh_token():
session['is_logged_in'] = True session['is_logged_in'] = True
session['loginTime'] = datetime.now(tz) session['loginTime'] = datetime.now(tz)
@ -79,6 +84,7 @@ def check_login_status():
session['is_logged_in'] == False or session['is_logged_in'] == False or
(datetime.now(tz) - session['loginTime']).total_seconds() > 43200) (datetime.now(tz) - session['loginTime']).total_seconds() > 43200)
def send_email(to, subject, text): def send_email(to, subject, text):
return requests.post( return requests.post(
"https://api.mailgun.net/v3/mg.aaronlee.tech/messages", "https://api.mailgun.net/v3/mg.aaronlee.tech/messages",
@ -88,6 +94,7 @@ def send_email(to, subject, text):
"subject": subject, "subject": subject,
"html": text}) "html": text})
def getName(grade, class_, number): def getName(grade, class_, number):
db = refresh_db() db = refresh_db()
cursor = db.cursor() cursor = db.cursor()
@ -98,6 +105,7 @@ def getName(grade, class_, number):
db.close() db.close()
return name[0] return name[0]
# LOGIN # LOGIN
@ -113,18 +121,14 @@ def verify_recaptcha(response):
print(r.json()) print(r.json())
return r.json()['success'] return r.json()['success']
# UPLOAD # UPLOAD
def is_admin(): def is_admin():
return 'subuser_type' in session and session['subuser_type'] == 'admin' return 'subuser_type' in session and session['subuser_type'] == 'admin'
def check_permission(): def check_permission():
if 'subuser_type' in session and session['subuser_type'] == 'admin': if 'subuser_type' in session and session['subuser_type'] == 'admin':
return session['showUpload'] return session['showUpload']
else: else:
return False return False
# MANAGE
def removeprefix(s, prefix):
if s.startswith(prefix):
return s[len(prefix):]
return s

View file

@ -1,5 +1,8 @@
from functions import * from functions import *
login = Blueprint('login', __name__) login = Blueprint('login', __name__)
@login.after_request @login.after_request
def add_header(response): def add_header(response):
response.headers['SameSite'] = "Strict" response.headers['SameSite'] = "Strict"
@ -13,10 +16,10 @@ def index():
return render_template('login.html') return render_template('login.html')
return redirect('/select') return redirect('/select')
elif request.method == 'POST': elif request.method == 'POST':
email = request.form['username'] email = request.form['username'].strip()
if check_login_status(): if check_login_status():
try: try:
if (verify_recaptcha("")): if verify_recaptcha(""):
if request.form['user_type'] == 'teacher': if request.form['user_type'] == 'teacher':
db = refresh_db() db = refresh_db()
cursor = db.cursor(buffered=True) cursor = db.cursor(buffered=True)
@ -26,7 +29,7 @@ def index():
if user == None or not verifyPassword(request.form['password'], user[3]): if user == None or not verifyPassword(request.form['password'], user[3]):
raise Exception('Invalid Login') raise Exception('Invalid Login')
usrRole = user[1] usrRole = user[1]
if (usrRole == 'R'): if usrRole == 'R':
print("RealPerson Login SUCC:", email, flush=True) print("RealPerson Login SUCC:", email, flush=True)
session['is_logged_in'] = True session['is_logged_in'] = True
session['email'] = email session['email'] = email
@ -34,7 +37,7 @@ def index():
session['oldUsername'] = user[2] session['oldUsername'] = user[2]
session['loginTime'] = datetime.now(tz) session['loginTime'] = datetime.now(tz)
return redirect('/select') return redirect('/select')
if (usrRole == 'A' or usrRole == 'S'): if usrRole == 'A' or usrRole == 'S':
print("Admin Login SUCC:", email, flush=True) print("Admin Login SUCC:", email, flush=True)
session['subuser_type'] = 'admin' session['subuser_type'] = 'admin'
session['is_logged_in'] = True session['is_logged_in'] = True
@ -47,7 +50,8 @@ def index():
elif request.form['user_type'] == 'student': elif request.form['user_type'] == 'student':
db = refresh_db() db = refresh_db()
cursor = db.cursor(buffered=True) cursor = db.cursor(buffered=True)
cursor.execute("SELECT password, grade, class_, num, name FROM students WHERE email = %s", (email,)) cursor.execute("SELECT password, grade, class_, num, name FROM students WHERE email = %s",
(email,))
user = cursor.fetchone() user = cursor.fetchone()
cursor.close() cursor.close()
if user == None or not verifyPassword(request.form['password'], user[0]): if user == None or not verifyPassword(request.form['password'], user[0]):
@ -83,12 +87,14 @@ def selSubUser():
flash("Timeout. 遇時,請重新登入") flash("Timeout. 遇時,請重新登入")
return redirect('/') return redirect('/')
refresh_token() refresh_token()
if 'subuser_type' in session and session['subuser_type'] == 'admin' or 'user_type' in session and session['user_type'] == 'student': if 'subuser_type' in session and session['subuser_type'] == 'admin' or 'user_type' in session and session[
'user_type'] == 'student':
return redirect('/manage') return redirect('/manage')
if request.method == 'GET': if request.method == 'GET':
db = refresh_db() db = refresh_db()
cursor = db.cursor(buffered=True) cursor = db.cursor(buffered=True)
cursor.execute("SELECT category, subclass FROM gpclasses WHERE accs LIKE %s LIMIT 1", ('%'+session['oldUsername']+'%',)) cursor.execute("SELECT category, subclass FROM gpclasses WHERE accs LIKE %s LIMIT 1",
('%' + session['oldUsername'] + '%',))
classes = cursor.fetchone() classes = cursor.fetchone()
cursor.close() cursor.close()
hasGroup = False hasGroup = False
@ -96,7 +102,7 @@ def selSubUser():
hasGroup = True hasGroup = True
db = refresh_db() db = refresh_db()
cursor = db.cursor(buffered=True) cursor = db.cursor(buffered=True)
cursor.execute("SELECT grade, class_ FROM homerooms WHERE accs LIKE %s", ('%'+session['oldUsername']+'%',)) cursor.execute("SELECT grade, class_ FROM homerooms WHERE accs LIKE %s", ('%' + session['oldUsername'] + '%',))
homerooms = cursor.fetchall() homerooms = cursor.fetchall()
cursor.close() cursor.close()
hrC = {} hrC = {}
@ -109,11 +115,11 @@ def selSubUser():
if data == []: if data == []:
return redirect('/select') return redirect('/select')
try: try:
if (verify_recaptcha("")): if verify_recaptcha(""):
if (data[0] == 'homeroom'): if data[0] == 'homeroom':
session['homeroom'] = data[1] + '^' + data[2] session['homeroom'] = data[1] + '^' + data[2]
session['subuser_type'] = 'homeroom' session['subuser_type'] = 'homeroom'
elif (data[0] == 'group'): elif data[0] == 'group':
session['subuser_type'] = 'group' session['subuser_type'] = 'group'
return redirect('/manage') return redirect('/manage')
else: else:
@ -141,7 +147,7 @@ def chgPassword():
if not check_login_status(): if not check_login_status():
refresh_token() refresh_token()
try: try:
if (verify_recaptcha("")): if verify_recaptcha(""):
db = refresh_db() db = refresh_db()
cursor = db.cursor(buffered=True) cursor = db.cursor(buffered=True)
if ('user_type' in session and session['user_type'] == 'student'): if ('user_type' in session and session['user_type'] == 'student'):
@ -167,21 +173,24 @@ def chgPassword():
raise Exception('帳號已被使用<br>Username already used') raise Exception('帳號已被使用<br>Username already used')
db = refresh_db() db = refresh_db()
cursor = db.cursor(buffered=True) cursor = db.cursor(buffered=True)
if ('user_type' in session and session['user_type'] == 'student'): if 'user_type' in session and session['user_type'] == 'student':
cursor.execute("UPDATE students SET password = %s WHERE email = %s", (genHash(request.form['new_password']), oldEmail)) cursor.execute("UPDATE students SET password = %s WHERE email = %s",
if (request.form['new_username'] != oldEmail and request.form['new_username'] != ''): (genHash(request.form['new_password']), oldEmail))
cursor.execute("UPDATE students SET email = %s WHERE email = %s", (request.form['new_username'], oldEmail)) if request.form['new_username'] != oldEmail and request.form['new_username'] != '':
cursor.execute("UPDATE students SET email = %s WHERE email = %s",
(request.form['new_username'], oldEmail))
else: else:
cursor.execute("UPDATE users SET password = %s WHERE email = %s", ( cursor.execute("UPDATE users SET password = %s WHERE email = %s", (
genHash(request.form['new_password']), oldEmail)) genHash(request.form['new_password']), oldEmail))
if (request.form['new_username'] != oldEmail and request.form['new_username'] != ''): if request.form['new_username'] != oldEmail and request.form['new_username'] != '':
cursor.execute("UPDATE users SET email = %s WHERE email = %s", (request.form['new_username'], oldEmail)) cursor.execute("UPDATE users SET email = %s WHERE email = %s",
(request.form['new_username'], oldEmail))
db.commit() db.commit()
cursor.close() cursor.close()
session.clear() session.clear()
if (request.form['new_username'] != oldEmail and request.form['new_username'] != ''): if request.form['new_username'] != oldEmail and request.form['new_username'] != '':
send_email(oldEmail, "Email Changed 信箱已更改", send_email(oldEmail, "Email Changed 信箱已更改",
"""<hr> """<hr>
Your email was changed at %s to %s.<br> Your email was changed at %s to %s.<br>
If you did not change your email, please contact the student affair's office immediately. If you did not change your email, please contact the student affair's office immediately.
<hr> <hr>
@ -190,7 +199,8 @@ def chgPassword():
<hr> <hr>
<small>This email was sent automatically. Please do not reply.<br> <small>This email was sent automatically. Please do not reply.<br>
這個郵件是自動發送的請不要回覆</small> 這個郵件是自動發送的請不要回覆</small>
""" % (datetime.now(tz).strftime("%Y-%m-%d %H:%M:%S"), request.form['new_username'], datetime.now(tz).strftime("%Y-%m-%d %H:%M:%S"), request.form['new_username'])) """ % (datetime.now(tz).strftime("%Y-%m-%d %H:%M:%S"), request.form['new_username'],
datetime.now(tz).strftime("%Y-%m-%d %H:%M:%S"), request.form['new_username']))
flash( flash(
'修改密碼成功,請重新登入<br>Password changed successfully. Please login again.') '修改密碼成功,請重新登入<br>Password changed successfully. Please login again.')
return redirect('/') return redirect('/')
@ -211,12 +221,12 @@ def forgotPassword():
elif request.method == 'POST': elif request.method == 'POST':
email = request.form['username'] email = request.form['username']
try: try:
if (verify_recaptcha("")): if verify_recaptcha(""):
db = refresh_db() db = refresh_db()
cursor = db.cursor(buffered=True) cursor = db.cursor(buffered=True)
if (request.form['user_type'] == 'student'): if request.form['user_type'] == 'student':
cursor.execute("SELECT * FROM students WHERE email = %s", (email,)) cursor.execute("SELECT * FROM students WHERE email = %s", (email,))
elif (request.form['user_type'] == 'teacher'): elif request.form['user_type'] == 'teacher':
cursor.execute("SELECT email FROM users WHERE email = %s", (email,)) cursor.execute("SELECT email FROM users WHERE email = %s", (email,))
user = cursor.fetchone() user = cursor.fetchone()
cursor.close() cursor.close()
@ -235,11 +245,12 @@ def forgotPassword():
cursor.execute(""" cursor.execute("""
INSERT INTO forgot (resetID, email, reqTime, userType) INSERT INTO forgot (resetID, email, reqTime, userType)
VALUES (%s, %s, %s, %s) VALUES (%s, %s, %s, %s)
""", (resetID, email, datetime.strftime(datetime.now(tz), '%Y-%m-%d %H:%M:%S'), 'T' if request.form['user_type'] == 'teacher' else 'S')) """, (resetID, email, datetime.strftime(datetime.now(tz), '%Y-%m-%d %H:%M:%S'),
'T' if request.form['user_type'] == 'teacher' else 'S'))
db.commit() db.commit()
cursor.close() cursor.close()
send_email(email, "Password Reset 重置密碼", send_email(email, "Password Reset 重置密碼",
"""<hr> """<hr>
Please go to the following link to reset your password:<br> Please go to the following link to reset your password:<br>
https://abs.aaronlee.tech/resetPassword?resetCode=%s<br> https://abs.aaronlee.tech/resetPassword?resetCode=%s<br>
If you did not request a password reset, please ignore this email. If you did not request a password reset, please ignore this email.
@ -274,7 +285,7 @@ def resetPassword():
return render_template('verifiedChgPassword.html', resetCode=request.args.get('resetCode')) return render_template('verifiedChgPassword.html', resetCode=request.args.get('resetCode'))
else: else:
try: try:
if (verify_recaptcha("")): if verify_recaptcha(""):
db = refresh_db() db = refresh_db()
cursor = db.cursor(buffered=True) cursor = db.cursor(buffered=True)
cursor.execute(""" cursor.execute("""

View file

@ -1,10 +1,12 @@
from functions import * from functions import *
from export import * from export import *
admin = Blueprint('admin', __name__) admin = Blueprint('admin', __name__)
@admin.route('/manage/admin/mark', methods=['GET', 'POST']) @admin.route('/manage/admin/mark', methods=['GET', 'POST'])
def mark_absent(): def mark_absent():
if (check_login_status() or session['subuser_type'] != 'admin'): if check_login_status() or session['subuser_type'] != 'admin':
return redirect('/logout') return redirect('/logout')
refresh_token() refresh_token()
if request.method == 'POST': if request.method == 'POST':
@ -14,13 +16,17 @@ def mark_absent():
db = refresh_db() db = refresh_db()
cursor = db.cursor() cursor = db.cursor()
for p in periods: for p in periods:
cursor.execute("INSERT INTO absent (grade, class_, date, period, num, status, note) VALUES (%s, %s, %s, %s, %s, %s, %s)", cursor.execute(
(data['grade'], data['class'], data['date'], p, data['num'], data['type'], data['notes'] if 'notes' in data else '')) "INSERT INTO absent (grade, class_, date, period, num, status, note) VALUES (%s, %s, %s, %s, %s, %s, %s)",
(data['grade'], data['class'], data['date'], p, data['num'], data['type'],
data['notes'] if 'notes' in data else ''))
db.commit() db.commit()
except Exception as e: except Exception as e:
flash(e) flash(e)
else: else:
flash("`成功! (" + data['grade'] + data['class'] + "" + data['num'] + "號, 日期: " + data['date'] + ", 總計 " + str(len(periods)) + "堂課)") flash(
"`成功! (" + data['grade'] + data['class'] + "" + data['num'] + "號, 日期: " + data['date'] + ", 總計 " + str(
len(periods)) + "堂課)")
return redirect('/manage/admin/mark') return redirect('/manage/admin/mark')
db = refresh_db() db = refresh_db()
cursor = db.cursor() cursor = db.cursor()
@ -35,18 +41,22 @@ def mark_absent():
students[i[0]][i[1]][i[2]] = i[3] students[i[0]][i[1]][i[2]] = i[3]
cursor.execute("SELECT date,period,grade,class_,num,status,note FROM absent ORDER BY id DESC LIMIT 10") cursor.execute("SELECT date,period,grade,class_,num,status,note FROM absent ORDER BY id DESC LIMIT 10")
records = cursor.fetchall() records = cursor.fetchall()
return render_template("admin_mark.html", students=students, periods=['m', '1', '2', '3', '4', 'n', '5', '6', '7', '8', '9'], records=records, hideSel=True) return render_template("admin_mark.html", students=students,
periods=['m', '1', '2', '3', '4', 'n', '5', '6', '7', '8', '9'], records=records,
hideSel=True)
@admin.route('/manage/admin/export', methods=['GET']) @admin.route('/manage/admin/export', methods=['GET'])
def admin_export(): def admin_export():
if (check_login_status() or session['subuser_type'] != 'admin'): if check_login_status() or session['subuser_type'] != 'admin':
return redirect('/logout') return redirect('/logout')
refresh_token() refresh_token()
return render_template("admin_export.html", hideSel=True) return render_template("admin_export.html", hideSel=True)
@admin.route('/manage/admin/export/homeroom_period', methods=['POST']) @admin.route('/manage/admin/export/homeroom_period', methods=['POST'])
def admin_export_homeroom_period(): def admin_export_homeroom_period():
if (check_login_status() or session['subuser_type'] != 'admin'): if check_login_status() or session['subuser_type'] != 'admin':
return redirect('/logout') return redirect('/logout')
refresh_token() refresh_token()
workbook = Workbook() workbook = Workbook()
@ -55,11 +65,14 @@ def admin_export_homeroom_period():
excel_stream = io.BytesIO() excel_stream = io.BytesIO()
workbook.save(excel_stream) workbook.save(excel_stream)
excel_stream.seek(0) excel_stream.seek(0)
return send_file(excel_stream, attachment_filename='homeroom_period_' + request.form['grade'] + request.form['class'] +'.xlsx', as_attachment=True) return send_file(excel_stream,
attachment_filename='homeroom_period_' + request.form['grade'] + request.form['class'] + '.xlsx',
as_attachment=True)
@admin.route('/manage/admin/export/homeroom_period/all', methods=['GET']) @admin.route('/manage/admin/export/homeroom_period/all', methods=['GET'])
def admin_export_homeroom_period_all(): def admin_export_homeroom_period_all():
if (check_login_status() or session['subuser_type'] != 'admin'): if check_login_status() or session['subuser_type'] != 'admin':
return redirect('/logout') return redirect('/logout')
refresh_token() refresh_token()
db = refresh_db() db = refresh_db()
@ -78,7 +91,7 @@ def admin_export_homeroom_period_all():
@admin.route('/manage/admin/export/student_list', methods=['POST']) @admin.route('/manage/admin/export/student_list', methods=['POST'])
def admin_export_student_list(): def admin_export_student_list():
if (check_login_status() or session['subuser_type'] != 'admin'): if check_login_status() or session['subuser_type'] != 'admin':
return redirect('/logout') return redirect('/logout')
refresh_token() refresh_token()
workbook = Workbook() workbook = Workbook()
@ -87,11 +100,14 @@ def admin_export_student_list():
excel_stream = io.BytesIO() excel_stream = io.BytesIO()
workbook.save(excel_stream) workbook.save(excel_stream)
excel_stream.seek(0) excel_stream.seek(0)
return send_file(excel_stream, attachment_filename='student_list_' + request.form['grade'] + request.form['class'] +'.xlsx', as_attachment=True) return send_file(excel_stream,
attachment_filename='student_list_' + request.form['grade'] + request.form['class'] + '.xlsx',
as_attachment=True)
@admin.route("/manage/admin/export/student_list/all", methods=['GET']) @admin.route("/manage/admin/export/student_list/all", methods=['GET'])
def admin_export_student_list_all(): def admin_export_student_list_all():
if (check_login_status() or session['subuser_type'] != 'admin'): if check_login_status() or session['subuser_type'] != 'admin':
return redirect('/logout') return redirect('/logout')
refresh_token() refresh_token()
db = refresh_db() db = refresh_db()
@ -107,9 +123,10 @@ def admin_export_student_list_all():
excel_stream.seek(0) excel_stream.seek(0)
return send_file(excel_stream, attachment_filename='student_list_all.xlsx', as_attachment=True) return send_file(excel_stream, attachment_filename='student_list_all.xlsx', as_attachment=True)
@admin.route('/manage/admin/export/teacher_period', methods=['POST']) @admin.route('/manage/admin/export/teacher_period', methods=['POST'])
def admin_export_teacher_period(): def admin_export_teacher_period():
if (check_login_status() or session['subuser_type'] != 'admin'): if check_login_status() or session['subuser_type'] != 'admin':
return redirect('/logout') return redirect('/logout')
refresh_token() refresh_token()
workbook = Workbook() workbook = Workbook()
@ -118,11 +135,13 @@ def admin_export_teacher_period():
excel_stream = io.BytesIO() excel_stream = io.BytesIO()
workbook.save(excel_stream) workbook.save(excel_stream)
excel_stream.seek(0) excel_stream.seek(0)
return send_file(excel_stream, attachment_filename='teacher_period_' + request.form['name'] + '_' + ('' if 'orig_username' not in request.form else request.form['orig_username']) +'.xlsx', as_attachment=True) return send_file(excel_stream, attachment_filename='teacher_period_' + request.form['name'] + '_' + (
'' if 'orig_username' not in request.form else request.form['orig_username']) + '.xlsx', as_attachment=True)
@admin.route('/manage/admin/export/teacher_period/all', methods=['GET']) @admin.route('/manage/admin/export/teacher_period/all', methods=['GET'])
def admin_export_teacher_period_all(): def admin_export_teacher_period_all():
if (check_login_status() or session['subuser_type'] != 'admin'): if check_login_status() or session['subuser_type'] != 'admin':
return redirect('/logout') return redirect('/logout')
refresh_token() refresh_token()
db = refresh_db() db = refresh_db()
@ -136,4 +155,4 @@ def admin_export_teacher_period_all():
excel_stream = io.BytesIO() excel_stream = io.BytesIO()
workbook.save(excel_stream) workbook.save(excel_stream)
excel_stream.seek(0) excel_stream.seek(0)
return send_file(excel_stream, attachment_filename='teacher_period_all.xlsx', as_attachment=True) return send_file(excel_stream, attachment_filename='teacher_period_all.xlsx', as_attachment=True)

View file

@ -1,9 +1,11 @@
from functions import * from functions import *
group = Blueprint('group', __name__) group = Blueprint('group', __name__)
@group.route('/manage/group_teach_publish', methods=['POST']) @group.route('/manage/group_teach_publish', methods=['POST'])
def group_teach_publish(): def group_teach_publish():
if (check_login_status()): if check_login_status():
return redirect('/logout') return redirect('/logout')
refresh_token() refresh_token()
data = request.form.to_dict() data = request.form.to_dict()
@ -13,10 +15,11 @@ def group_teach_publish():
} }
db = refresh_db() db = refresh_db()
cursor = db.cursor() cursor = db.cursor()
cursor.execute("SELECT about FROM gpclasses WHERE category=%s AND subclass=%s", cursor.execute("SELECT about FROM gpclasses WHERE category=%s AND subclass=%s",
(cclass['category'], cclass['class_id'])) (cclass['category'], cclass['class_id']))
cclass["name"] = cursor.fetchone()[0] cclass["name"] = cursor.fetchone()[0]
cursor.execute("SELECT grade,class_,num,name,ename FROM students WHERE classes LIKE " + '\'%\"'+ cclass['category'] + '\": \"' + cclass['class_id'] +'\"%\'' + " ORDER BY grade ASC,class_ ASC,num ASC") cursor.execute("SELECT grade,class_,num,name,ename FROM students WHERE classes LIKE " + '\'%\"' + cclass[
'category'] + '\": \"' + cclass['class_id'] + '\"%\'' + " ORDER BY grade ASC,class_ ASC,num ASC")
students = cursor.fetchall() students = cursor.fetchall()
homerooms = [] homerooms = []
for x in students: for x in students:
@ -37,7 +40,8 @@ def group_teach_publish():
if xs[0] == 'note': if xs[0] == 'note':
continue continue
else: else:
absentData.append([xs[1], xs[2], xs[3], 'K' if xs[0] == '1' else 'L', data['note^'+xs[1]+'^'+xs[2]+'^'+xs[3]]]) absentData.append([xs[1], xs[2], xs[3], 'K' if xs[0] == '1' else 'L',
data['note^' + xs[1] + '^' + xs[2] + '^' + xs[3]]])
for h in homerooms: for h in homerooms:
h = h.split('^') h = h.split('^')
cursor = db.cursor() cursor = db.cursor()
@ -99,4 +103,4 @@ def group_teach_publish():
VALUES (%s, %s, %s, %s, %s, %s) VALUES (%s, %s, %s, %s, %s, %s)
""", (d[0], d[1], d[2], date, period, d[3])) """, (d[0], d[1], d[2], date, period, d[3]))
db.commit() db.commit()
return redirect('/manage') return redirect('/manage')

View file

@ -1,15 +1,18 @@
from functions import * from functions import *
homeroom = Blueprint('homeroom', __name__) homeroom = Blueprint('homeroom', __name__)
@homeroom.route('/manage/abs', methods=['GET']) @homeroom.route('/manage/abs', methods=['GET'])
def showAllAbs(): def showAllAbs():
if (check_login_status()): if check_login_status():
return redirect('/logout') return redirect('/logout')
refresh_token() refresh_token()
currRoom = session['homeroom'].split('^') currRoom = session['homeroom'].split('^')
db = refresh_db() db = refresh_db()
cursor = db.cursor() cursor = db.cursor()
cursor.execute("SELECT num,name,ename FROM students WHERE grade=%s AND class_=%s ORDER BY num ASC", (currRoom[0], currRoom[1])) cursor.execute("SELECT num,name,ename FROM students WHERE grade=%s AND class_=%s ORDER BY num ASC",
(currRoom[0], currRoom[1]))
studentsSQL = cursor.fetchall() studentsSQL = cursor.fetchall()
students = {} students = {}
for st in studentsSQL: for st in studentsSQL:
@ -18,9 +21,13 @@ def showAllAbs():
'ename': st[2], 'ename': st[2],
} }
cursor = db.cursor() cursor = db.cursor()
cursor.execute("SELECT date, period, num, status, note FROM absent WHERE grade=%s AND class_=%s ORDER BY date DESC, FIND_IN_SET(period, 'm,1,2,3,4,n,5,6,7,8,9') DESC, num ASC", (currRoom[0], currRoom[1])) cursor.execute(
"SELECT date, period, num, status, note FROM absent WHERE grade=%s AND class_=%s ORDER BY date DESC, FIND_IN_SET(period, 'm,1,2,3,4,n,5,6,7,8,9') DESC, num ASC",
(currRoom[0], currRoom[1]))
absentDataSQL = cursor.fetchall() absentDataSQL = cursor.fetchall()
return render_template("list.html", title="Absent List | 缺勤紀錄", mode='ABS', students=students, data=absentDataSQL, currRoom=currRoom) return render_template("list.html", title="Absent List | 缺勤紀錄", mode='ABS', students=students, data=absentDataSQL,
currRoom=currRoom)
@homeroom.route('/manage/ds', methods=['GET']) @homeroom.route('/manage/ds', methods=['GET'])
def showAllDS(): def showAllDS():
@ -30,7 +37,8 @@ def showAllDS():
currRoom = session['homeroom'].split('^') currRoom = session['homeroom'].split('^')
db = refresh_db() db = refresh_db()
cursor = db.cursor() cursor = db.cursor()
cursor.execute("SELECT num,name,ename FROM students WHERE grade=%s AND class_=%s ORDER BY num ASC", (currRoom[0], currRoom[1])) cursor.execute("SELECT num,name,ename FROM students WHERE grade=%s AND class_=%s ORDER BY num ASC",
(currRoom[0], currRoom[1]))
studentsSQL = cursor.fetchall() studentsSQL = cursor.fetchall()
students = {} students = {}
for st in studentsSQL: for st in studentsSQL:
@ -39,9 +47,13 @@ def showAllDS():
'ename': st[2], 'ename': st[2],
} }
cursor = db.cursor() cursor = db.cursor()
cursor.execute("SELECT date, period, num, note FROM ds WHERE grade=%s AND class_=%s ORDER BY date DESC, FIND_IN_SET(period, 'm,1,2,3,4,n,5,6,7,8,9') DESC, num ASC", (currRoom[0], currRoom[1])) cursor.execute(
"SELECT date, period, num, note FROM ds WHERE grade=%s AND class_=%s ORDER BY date DESC, FIND_IN_SET(period, 'm,1,2,3,4,n,5,6,7,8,9') DESC, num ASC",
(currRoom[0], currRoom[1]))
dsDataSQL = cursor.fetchall() dsDataSQL = cursor.fetchall()
return render_template("list.html", title="DS List | 定心紀錄", mode='DS', students=students, data=dsDataSQL, currRoom=currRoom) return render_template("list.html", title="DS List | 定心紀錄", mode='DS', students=students, data=dsDataSQL,
currRoom=currRoom)
@homeroom.route('/manage/homeroom_abs', methods=['POST']) @homeroom.route('/manage/homeroom_abs', methods=['POST'])
def homeroom_abs_publish(): def homeroom_abs_publish():
@ -58,7 +70,7 @@ def homeroom_abs_publish():
absentData = {} absentData = {}
for x in data: for x in data:
xt = x.split('^') xt = x.split('^')
if (xt[0] == 'note'): if xt[0] == 'note':
if xt[2] not in absentData: if xt[2] not in absentData:
absentData[xt[2]] = {} absentData[xt[2]] = {}
absentData[xt[2]]['note'] = data[x] absentData[xt[2]]['note'] = data[x]
@ -77,13 +89,15 @@ def homeroom_abs_publish():
INSERT INTO absent INSERT INTO absent
(grade, class_, date, period, num, status, note) (grade, class_, date, period, num, status, note)
VALUES (%s, %s, %s, %s, %s, %s, %s) VALUES (%s, %s, %s, %s, %s, %s, %s)
""", (homeroom[0], homeroom[1], date, period, x, absentData[x]['status'], absentData[x]['note'] if 'note' in absentData[x] else '')) """, (homeroom[0], homeroom[1], date, period, x, absentData[x]['status'],
absentData[x]['note'] if 'note' in absentData[x] else ''))
db.commit() db.commit()
return redirect('/manage') return redirect('/manage')
@homeroom.route('/manage/homeroom_ds', methods=['POST']) @homeroom.route('/manage/homeroom_ds', methods=['POST'])
def homeroom_ds_publish(): def homeroom_ds_publish():
if (check_login_status()): if check_login_status():
return redirect('/logout') return redirect('/logout')
refresh_token() refresh_token()
db = refresh_db() db = refresh_db()
@ -109,7 +123,7 @@ def homeroom_ds_publish():
""", (ds1, ds2, ds3, ds4, ds5, ds6, ds7, notes, homeroom[0], homeroom[1], date, period)) """, (ds1, ds2, ds3, ds4, ds5, ds6, ds7, notes, homeroom[0], homeroom[1], date, period))
for x in data: for x in data:
xt = x.split('^') xt = x.split('^')
if (xt[0] == 'dsidv'): if xt[0] == 'dsidv':
dsidv[xt[1]] = data[x] dsidv[xt[1]] = data[x]
for x in dsidv: for x in dsidv:
cursor.execute(""" cursor.execute("""
@ -120,9 +134,10 @@ def homeroom_ds_publish():
db.commit() db.commit()
return redirect('/manage') return redirect('/manage')
@homeroom.route('/manage/homeroom_confirm', methods=['POST']) @homeroom.route('/manage/homeroom_confirm', methods=['POST'])
def homeroom_confirm(): def homeroom_confirm():
if (check_login_status()): if check_login_status():
return redirect('/logout') return redirect('/logout')
refresh_token() refresh_token()
data = request.form.to_dict() data = request.form.to_dict()

View file

@ -3,20 +3,24 @@ from manage.homeroom import homeroom
from manage.student import student from manage.student import student
from manage.admin import admin from manage.admin import admin
from manage.group import group from manage.group import group
manage = Blueprint('manage', __name__) manage = Blueprint('manage', __name__)
manage.register_blueprint(homeroom) manage.register_blueprint(homeroom)
manage.register_blueprint(student) manage.register_blueprint(student)
manage.register_blueprint(admin) manage.register_blueprint(admin)
manage.register_blueprint(group) manage.register_blueprint(group)
@manage.route('/manage', methods=['GET']) @manage.route('/manage', methods=['GET'])
def manageRoot(): def manageRoot():
return manageProcess("", "") return manageProcess("", "")
@homeroom.route('/manage/date/<date>', methods=['GET']) @homeroom.route('/manage/date/<date>', methods=['GET'])
def manage_date(date): def manage_date(date):
return manageProcess("date", date) return manageProcess("date", date)
@manage.route('/manage/admin/<g>/<r>/<date>', methods=['GET']) @manage.route('/manage/admin/<g>/<r>/<date>', methods=['GET'])
def manage_admin(g, r, date): def manage_admin(g, r, date):
data = [ data = [
@ -27,7 +31,7 @@ def manage_admin(g, r, date):
def manageProcess(fCommand, fData): def manageProcess(fCommand, fData):
if (check_login_status()): if check_login_status():
return redirect('/logout') return redirect('/logout')
refresh_token() refresh_token()
if 'user_type' in session and session['user_type'] == 'student': if 'user_type' in session and session['user_type'] == 'student':
@ -50,7 +54,8 @@ def manageProcess(fCommand, fData):
else: else:
currRoom = [homeroomsSQL[0][0], homeroomsSQL[0][1]] currRoom = [homeroomsSQL[0][0], homeroomsSQL[0][1]]
cursor = db.cursor() cursor = db.cursor()
cursor.execute("SELECT num,name,ename,classes FROM students WHERE grade=%s AND class_=%s ORDER BY num ASC", (currRoom[0], currRoom[1])) cursor.execute("SELECT num,name,ename,classes FROM students WHERE grade=%s AND class_=%s ORDER BY num ASC",
(currRoom[0], currRoom[1]))
students = cursor.fetchall() students = cursor.fetchall()
studGP = {} studGP = {}
for s in students: for s in students:
@ -67,10 +72,11 @@ def manageProcess(fCommand, fData):
if i[0] >= datetime.now(tz).strftime("%Y-%m-%d"): if i[0] >= datetime.now(tz).strftime("%Y-%m-%d"):
break break
cursor = db.cursor() cursor = db.cursor()
cursor.execute("SELECT dow FROM dates WHERE date=%s", (currDate, )) cursor.execute("SELECT dow FROM dates WHERE date=%s", (currDate,))
dow = cursor.fetchone()[0] dow = cursor.fetchone()[0]
cursor = db.cursor() cursor = db.cursor()
cursor.execute("SELECT period, subject, teacher FROM schedule WHERE grade=%s AND class_=%s AND dow=%s", (currRoom[0], currRoom[1], dow)) cursor.execute("SELECT period, subject, teacher FROM schedule WHERE grade=%s AND class_=%s AND dow=%s",
(currRoom[0], currRoom[1], dow))
scheduleSQL = cursor.fetchall() scheduleSQL = cursor.fetchall()
schedule = {} schedule = {}
for i in scheduleSQL: for i in scheduleSQL:
@ -79,7 +85,8 @@ def manageProcess(fCommand, fData):
"teacher": i[2], "teacher": i[2],
} }
cursor = db.cursor() cursor = db.cursor()
cursor.execute("SELECT period, subject, teacher FROM specschedule WHERE grade=%s AND class_=%s AND date=%s", (currRoom[0], currRoom[1], currDate)) cursor.execute("SELECT period, subject, teacher FROM specschedule WHERE grade=%s AND class_=%s AND date=%s",
(currRoom[0], currRoom[1], currDate))
specScheduleSQL = cursor.fetchall() specScheduleSQL = cursor.fetchall()
for i in specScheduleSQL: for i in specScheduleSQL:
schedule[i[0]] = { schedule[i[0]] = {
@ -88,17 +95,20 @@ def manageProcess(fCommand, fData):
"special": True "special": True
} }
cursor = db.cursor() cursor = db.cursor()
cursor.execute("SELECT period, signature, notes, ds1,ds2,ds3,ds4,ds5,ds6,ds7 FROM submission WHERE grade=%s AND class_=%s AND date=%s", (currRoom[0], currRoom[1], currDate)) cursor.execute(
"SELECT period, signature, notes, ds1,ds2,ds3,ds4,ds5,ds6,ds7 FROM submission WHERE grade=%s AND class_=%s AND date=%s",
(currRoom[0], currRoom[1], currDate))
submissionSQL = cursor.fetchall() submissionSQL = cursor.fetchall()
submission = {} submission = {}
cursor = db.cursor() cursor = db.cursor()
cursor.execute("SELECT period, num, note FROM ds WHERE grade=%s AND class_=%s AND date=%s", (currRoom[0], currRoom[1], currDate)) cursor.execute("SELECT period, num, note FROM ds WHERE grade=%s AND class_=%s AND date=%s",
(currRoom[0], currRoom[1], currDate))
idvDSSQL = cursor.fetchall() idvDSSQL = cursor.fetchall()
idvDS = {} idvDS = {}
for i in idvDSSQL: for i in idvDSSQL:
if i[0] not in idvDS: if i[0] not in idvDS:
idvDS[i[0]] = {} idvDS[i[0]] = {}
idvDS[i[0]][i[1]]= i[2] idvDS[i[0]][i[1]] = i[2]
for i in submissionSQL: for i in submissionSQL:
if i[0] == 'c': if i[0] == 'c':
submission[i[0]] = { submission[i[0]] = {
@ -126,7 +136,8 @@ def manageProcess(fCommand, fData):
"ds7": i[9] "ds7": i[9]
} }
cursor = db.cursor() cursor = db.cursor()
cursor.execute("SELECT period, num, status, note FROM absent WHERE grade=%s AND class_=%s AND date=%s", (currRoom[0], currRoom[1], currDate)) cursor.execute("SELECT period, num, status, note FROM absent WHERE grade=%s AND class_=%s AND date=%s",
(currRoom[0], currRoom[1], currDate))
absentDataSQL = cursor.fetchall() absentDataSQL = cursor.fetchall()
absentData = {} absentData = {}
for p in ['m', '1', '2', '3', '4', 'n', '5', '6', '7', '8', '9']: for p in ['m', '1', '2', '3', '4', 'n', '5', '6', '7', '8', '9']:
@ -138,13 +149,17 @@ def manageProcess(fCommand, fData):
'status': i[2], 'status': i[2],
'note': i[3], 'note': i[3],
} }
return render_template('admin.html', homerooms=homerooms, currRoom=currRoom, students=students, currDate=currDate, schedule=schedule, submission=submission, studGP=studGP, idvDS=idvDS, return render_template('admin.html', homerooms=homerooms, currRoom=currRoom, students=students,
dates=dates, absentData=absentData, periods=['m', '1', '2', '3', '4', 'n', '5', '6', '7', '8', '9'], showUpload=session['showUpload'], dsboard=DSBOARD, dstext=DSTEXT, dsoffenses=DSOFFENSES) currDate=currDate, schedule=schedule, submission=submission, studGP=studGP, idvDS=idvDS,
# 'n', '5', '6', '7', '8', '9'], showUpload=session['showUpload']) dates=dates, absentData=absentData,
periods=['m', '1', '2', '3', '4', 'n', '5', '6', '7', '8', '9'],
showUpload=session['showUpload'], dsboard=DSBOARD, dstext=DSTEXT, dsoffenses=DSOFFENSES)
# 'n', '5', '6', '7', '8', '9'], showUpload=session['showUpload'])
elif pl == 'group': elif pl == 'group':
db = refresh_db() db = refresh_db()
cursor = db.cursor() cursor = db.cursor()
cursor.execute("SELECT category, subclass FROM gpclasses WHERE accs LIKE %s", ('%'+session['oldUsername']+'%',)) cursor.execute("SELECT category, subclass FROM gpclasses WHERE accs LIKE %s",
('%' + session['oldUsername'] + '%',))
gpclasses = cursor.fetchall() gpclasses = cursor.fetchall()
data = {} data = {}
currDate = "" currDate = ""
@ -160,12 +175,12 @@ def manageProcess(fCommand, fData):
if i[0] >= datetime.now(tz).strftime("%Y-%m-%d"): if i[0] >= datetime.now(tz).strftime("%Y-%m-%d"):
break break
cursor = db.cursor() cursor = db.cursor()
cursor.execute("SELECT dow FROM dates WHERE date=%s", (currDate, )) cursor.execute("SELECT dow FROM dates WHERE date=%s", (currDate,))
dow = cursor.fetchone()[0] dow = cursor.fetchone()[0]
for c in gpclasses: for c in gpclasses:
cursor.execute("SELECT about FROM gpclasses WHERE subclass=%s AND category=%s", cursor.execute("SELECT about FROM gpclasses WHERE subclass=%s AND category=%s",
(c[1], c[0])) (c[1], c[0]))
cclass = { cclass = {
"name": cursor.fetchone()[0], "name": cursor.fetchone()[0],
"category": c[0], "category": c[0],
@ -175,7 +190,8 @@ def manageProcess(fCommand, fData):
"cdata": cclass, "cdata": cclass,
} }
# get student list # get student list
cursor.execute("SELECT grade,class_,num,name,ename FROM students WHERE classes LIKE " + '\'%\"'+ cclass['category'] + '\": \"' + cclass['class_id'] +'\"%\'' + " ORDER BY grade ASC,class_ ASC,num ASC") cursor.execute("SELECT grade,class_,num,name,ename FROM students WHERE classes LIKE " + '\'%\"' + cclass[
'category'] + '\": \"' + cclass['class_id'] + '\"%\'' + " ORDER BY grade ASC,class_ ASC,num ASC")
students = cursor.fetchall() students = cursor.fetchall()
# get student homerooms # get student homerooms
homerooms = [] homerooms = []
@ -185,13 +201,18 @@ def manageProcess(fCommand, fData):
# get periods # get periods
for h in homerooms: for h in homerooms:
hs = h.split('^') hs = h.split('^')
cursor.execute("SELECT period FROM schedule WHERE grade=%s AND class_=%s AND dow=%s AND teacher=%s", (hs[0], hs[1], dow, cclass['category'])) cursor.execute("SELECT period FROM schedule WHERE grade=%s AND class_=%s AND dow=%s AND teacher=%s",
(hs[0], hs[1], dow, cclass['category']))
scheduleSQL = cursor.fetchall() scheduleSQL = cursor.fetchall()
cursor.execute("SELECT period FROM specschedule WHERE grade=%s AND class_=%s AND date=%s AND teacher=%s", (hs[0], hs[1], currDate, cclass['category'])) cursor.execute(
"SELECT period FROM specschedule WHERE grade=%s AND class_=%s AND date=%s AND teacher=%s",
(hs[0], hs[1], currDate, cclass['category']))
specNTPSQL = cursor.fetchall() specNTPSQL = cursor.fetchall()
for s in specNTPSQL: for s in specNTPSQL:
scheduleSQL.append(s) scheduleSQL.append(s)
cursor.execute("SELECT period FROM specschedule WHERE grade=%s AND class_=%s AND date=%s AND teacher!=%s", (hs[0], hs[1], currDate, cclass['category'])) cursor.execute(
"SELECT period FROM specschedule WHERE grade=%s AND class_=%s AND date=%s AND teacher!=%s",
(hs[0], hs[1], currDate, cclass['category']))
specNTDSQL = cursor.fetchall() specNTDSQL = cursor.fetchall()
specNTD = {} specNTD = {}
for i in specNTDSQL: for i in specNTDSQL:
@ -205,7 +226,9 @@ def manageProcess(fCommand, fData):
if (h not in data[cclass['category'] + ' ' + cclass['class_id']][p[0]]): if (h not in data[cclass['category'] + ' ' + cclass['class_id']][p[0]]):
data[cclass['category'] + ' ' + cclass['class_id']][p[0]][h] = {} data[cclass['category'] + ' ' + cclass['class_id']][p[0]][h] = {}
cursor = db.cursor() cursor = db.cursor()
cursor.execute("SELECT signature, dscfrm FROM submission WHERE grade=%s AND class_=%s AND date=%s AND period=%s", (hs[0], hs[1], currDate, p[0])) cursor.execute(
"SELECT signature, dscfrm FROM submission WHERE grade=%s AND class_=%s AND date=%s AND period=%s",
(hs[0], hs[1], currDate, p[0]))
submissionSQL = cursor.fetchone() submissionSQL = cursor.fetchone()
submitted = False submitted = False
try: try:
@ -217,13 +240,17 @@ def manageProcess(fCommand, fData):
hrCfrm = False hrCfrm = False
if not submitted: if not submitted:
cursor = db.cursor() cursor = db.cursor()
cursor.execute("SELECT signature FROM submission WHERE grade=%s AND class_=%s AND date=%s AND period='c'", (hs[0], hs[1], currDate)) cursor.execute(
"SELECT signature FROM submission WHERE grade=%s AND class_=%s AND date=%s AND period='c'",
(hs[0], hs[1], currDate))
hrCfrm = True if cursor.fetchone() != None else submitted hrCfrm = True if cursor.fetchone() != None else submitted
cursor = db.cursor() cursor = db.cursor()
cursor.execute("SELECT num, status, note FROM absent WHERE grade=%s AND class_=%s AND date=%s AND period=%s", (hs[0], hs[1], currDate, p[0])) cursor.execute(
"SELECT num, status, note FROM absent WHERE grade=%s AND class_=%s AND date=%s AND period=%s",
(hs[0], hs[1], currDate, p[0]))
absentDataSQL = cursor.fetchall() absentDataSQL = cursor.fetchall()
for x in students: for x in students:
if (str(x[0])==hs[0] and str(x[1])==hs[1]): if (str(x[0]) == hs[0] and str(x[1]) == hs[1]):
studStatus = [item for item in absentDataSQL if item[0] == x[2]] studStatus = [item for item in absentDataSQL if item[0] == x[2]]
status = "" status = ""
if submitted: if submitted:
@ -244,7 +271,8 @@ def manageProcess(fCommand, fData):
"ename": x[4], "ename": x[4],
"status": status, "status": status,
"note": '' if studStatus == [] else studStatus[0][2], "note": '' if studStatus == [] else studStatus[0][2],
"needDS": False if hrCfrm != True and submissionSQL[1] != None and cclass['class_id'] in json.loads(submissionSQL[1]) else True "needDS": False if hrCfrm != True and submissionSQL[1] != None and cclass[
'class_id'] in json.loads(submissionSQL[1]) else True
} }
return render_template('group_teach.html', dates=dates, currDate=currDate, data=data, dsoffenses=DSOFFENSES) return render_template('group_teach.html', dates=dates, currDate=currDate, data=data, dsoffenses=DSOFFENSES)
elif pl == 'homeroom': elif pl == 'homeroom':
@ -266,13 +294,13 @@ def manageProcess(fCommand, fData):
currPeriod = "" currPeriod = ""
currTime = datetime.now(tz).strftime("%H:%M") currTime = datetime.now(tz).strftime("%H:%M")
for i in times: for i in times:
if (times[i] <= currTime and if times[i] <= currTime <= times[next_item(times, i)]:
currTime <= times[next_item(times, i)]):
currPeriod = i currPeriod = i
break break
currRoom = session['homeroom'].split('^') currRoom = session['homeroom'].split('^')
cursor = db.cursor() cursor = db.cursor()
cursor.execute("SELECT num,name,ename,classes FROM students WHERE grade=%s AND class_=%s ORDER BY num ASC", (currRoom[0], currRoom[1])) cursor.execute("SELECT num,name,ename,classes FROM students WHERE grade=%s AND class_=%s ORDER BY num ASC",
(currRoom[0], currRoom[1]))
students = cursor.fetchall() students = cursor.fetchall()
studGP = {} studGP = {}
for s in students: for s in students:
@ -289,10 +317,11 @@ def manageProcess(fCommand, fData):
if i[0] >= datetime.now(tz).strftime("%Y-%m-%d"): if i[0] >= datetime.now(tz).strftime("%Y-%m-%d"):
break break
cursor = db.cursor() cursor = db.cursor()
cursor.execute("SELECT dow FROM dates WHERE date=%s", (currDate, )) cursor.execute("SELECT dow FROM dates WHERE date=%s", (currDate,))
dow = cursor.fetchone()[0] dow = cursor.fetchone()[0]
cursor = db.cursor() cursor = db.cursor()
cursor.execute("SELECT period, subject, teacher FROM schedule WHERE grade=%s AND class_=%s AND dow=%s", (currRoom[0], currRoom[1], dow)) cursor.execute("SELECT period, subject, teacher FROM schedule WHERE grade=%s AND class_=%s AND dow=%s",
(currRoom[0], currRoom[1], dow))
scheduleSQL = cursor.fetchall() scheduleSQL = cursor.fetchall()
schedule = {} schedule = {}
for i in scheduleSQL: for i in scheduleSQL:
@ -301,7 +330,8 @@ def manageProcess(fCommand, fData):
"teacher": i[2], "teacher": i[2],
} }
cursor = db.cursor() cursor = db.cursor()
cursor.execute("SELECT period, subject, teacher FROM specschedule WHERE grade=%s AND class_=%s AND date=%s", (currRoom[0], currRoom[1], currDate)) cursor.execute("SELECT period, subject, teacher FROM specschedule WHERE grade=%s AND class_=%s AND date=%s",
(currRoom[0], currRoom[1], currDate))
specScheduleSQL = cursor.fetchall() specScheduleSQL = cursor.fetchall()
for i in specScheduleSQL: for i in specScheduleSQL:
schedule[i[0]] = { schedule[i[0]] = {
@ -310,16 +340,19 @@ def manageProcess(fCommand, fData):
"special": True "special": True
} }
cursor = db.cursor() cursor = db.cursor()
cursor.execute("SELECT period, signature, notes, ds1,ds2,ds3,ds4,ds5,ds6,ds7, dscfrm FROM submission WHERE grade=%s AND class_=%s AND date=%s", (currRoom[0], currRoom[1], currDate)) cursor.execute(
"SELECT period, signature, notes, ds1,ds2,ds3,ds4,ds5,ds6,ds7, dscfrm FROM submission WHERE grade=%s AND class_=%s AND date=%s",
(currRoom[0], currRoom[1], currDate))
submissionSQL = cursor.fetchall() submissionSQL = cursor.fetchall()
cursor = db.cursor() cursor = db.cursor()
cursor.execute("SELECT period, num, note FROM ds WHERE grade=%s AND class_=%s AND date=%s", (currRoom[0], currRoom[1], currDate)) cursor.execute("SELECT period, num, note FROM ds WHERE grade=%s AND class_=%s AND date=%s",
(currRoom[0], currRoom[1], currDate))
idvDSSQL = cursor.fetchall() idvDSSQL = cursor.fetchall()
idvDS = {} idvDS = {}
for i in idvDSSQL: for i in idvDSSQL:
if i[0] not in idvDS: if i[0] not in idvDS:
idvDS[i[0]] = {} idvDS[i[0]] = {}
idvDS[i[0]][i[1]]= i[2] idvDS[i[0]][i[1]] = i[2]
submission = {} submission = {}
for i in submissionSQL: for i in submissionSQL:
if i[0] == 'c': if i[0] == 'c':
@ -350,7 +383,8 @@ def manageProcess(fCommand, fData):
if i[10] == 'yes': if i[10] == 'yes':
submission[i[0]]["dscfrm"] = True submission[i[0]]["dscfrm"] = True
cursor = db.cursor() cursor = db.cursor()
cursor.execute("SELECT period, num, status, note FROM absent WHERE grade=%s AND class_=%s AND date=%s", (currRoom[0], currRoom[1], currDate)) cursor.execute("SELECT period, num, status, note FROM absent WHERE grade=%s AND class_=%s AND date=%s",
(currRoom[0], currRoom[1], currDate))
absentDataSQL = cursor.fetchall() absentDataSQL = cursor.fetchall()
absentData = {} absentData = {}
for p in ['m', '1', '2', '3', '4', 'n', '5', '6', '7', '8', '9']: for p in ['m', '1', '2', '3', '4', 'n', '5', '6', '7', '8', '9']:
@ -360,7 +394,10 @@ def manageProcess(fCommand, fData):
'status': i[2], 'status': i[2],
'note': i[3], 'note': i[3],
} }
return render_template('homeroom.html', currRoom=currRoom, students=students, currDate=currDate, schedule=schedule, submission=submission, currPeriod=currPeriod, studGP=studGP, return render_template('homeroom.html', currRoom=currRoom, students=students, currDate=currDate,
dates=dates, absentData=absentData, periods=['m', '1', '2', '3', '4', 'n', '5', '6', '7', '8', '9'], dsboard=DSBOARD, dstext=DSTEXT, dsoffenses=DSOFFENSES, idvDS=idvDS) schedule=schedule, submission=submission, currPeriod=currPeriod, studGP=studGP,
dates=dates, absentData=absentData,
periods=['m', '1', '2', '3', '4', 'n', '5', '6', '7', '8', '9'], dsboard=DSBOARD,
dstext=DSTEXT, dsoffenses=DSOFFENSES, idvDS=idvDS)
else: else:
return redirect('/logout') return redirect('/logout')

View file

@ -1,30 +1,38 @@
from functions import * from functions import *
student = Blueprint('student', __name__) student = Blueprint('student', __name__)
@student.route('/student', methods=['GET']) @student.route('/student', methods=['GET'])
def showStudentAbs(): def showStudentAbs():
if (check_login_status()): if check_login_status():
return redirect('/logout') return redirect('/logout')
refresh_token() refresh_token()
if not ('user_type' in session and session['user_type'] == 'student'): if not ('user_type' in session and session['user_type'] == 'student'):
return redirect('/') return redirect('/')
db = refresh_db() db = refresh_db()
cursor = db.cursor() cursor = db.cursor()
cursor.execute("SELECT date, period, num, status, note FROM absent WHERE grade=%s AND class_=%s AND num=%s ORDER BY date DESC, FIND_IN_SET(period, 'm,1,2,3,4,n,5,6,7,8,9') DESC, num ASC", (session['grade'], session['class'], session['num'])) cursor.execute(
"SELECT date, period, num, status, note FROM absent WHERE grade=%s AND class_=%s AND num=%s ORDER BY date DESC, FIND_IN_SET(period, 'm,1,2,3,4,n,5,6,7,8,9') DESC, num ASC",
(session['grade'], session['class'], session['num']))
absentDataSQL = cursor.fetchall() absentDataSQL = cursor.fetchall()
return render_template("list.html", title="Student Absent List | 學生缺勤紀錄", mode='STUDABS', data=absentDataSQL, currRoom=[session['grade'],session['class']], name=session['name'], num=session['num']) return render_template("list.html", title="Student Absent List | 學生缺勤紀錄", mode='STUDABS', data=absentDataSQL,
currRoom=[session['grade'], session['class']], name=session['name'], num=session['num'])
@student.route('/student/ds', methods=['GET']) @student.route('/student/ds', methods=['GET'])
def showStudentDS(): def showStudentDS():
if (check_login_status()): if check_login_status():
return redirect('/logout') return redirect('/logout')
refresh_token() refresh_token()
if not ('user_type' in session and session['user_type'] == 'student'): if not ('user_type' in session and session['user_type'] == 'student'):
return redirect('/') return redirect('/')
db = refresh_db() db = refresh_db()
cursor = db.cursor() cursor = db.cursor()
cursor.execute("SELECT date, period, num, note FROM ds WHERE grade=%s AND class_=%s AND num=%s ORDER BY date DESC, FIND_IN_SET(period, 'm,1,2,3,4,n,5,6,7,8,9') DESC, num ASC", (session['grade'], session['class'], session['num'])) cursor.execute(
"SELECT date, period, num, note FROM ds WHERE grade=%s AND class_=%s AND num=%s ORDER BY date DESC, FIND_IN_SET(period, 'm,1,2,3,4,n,5,6,7,8,9') DESC, num ASC",
(session['grade'], session['class'], session['num']))
dsDataSQL = cursor.fetchall() dsDataSQL = cursor.fetchall()
print(dsDataSQL) print(dsDataSQL)
return render_template("list.html", title="Student DS List | 學生定心紀錄", mode='STUDDS', data=dsDataSQL, currRoom=[session['grade'],session['class']], name=session['name'], num=session['num']) return render_template("list.html", title="Student DS List | 學生定心紀錄", mode='STUDDS', data=dsDataSQL,
currRoom=[session['grade'], session['class']], name=session['name'], num=session['num'])