diff --git a/.gitignore b/.gitignore index 4591ab2..b400de5 100644 --- a/.gitignore +++ b/.gitignore @@ -2,4 +2,5 @@ *.env test*.* __pycache__/* -excel/* \ No newline at end of file +excel/* +venv/* \ No newline at end of file diff --git a/app.py b/app.py index 4104c90..e0f76ae 100644 --- a/app.py +++ b/app.py @@ -2,6 +2,7 @@ from functions import * from manage.manage import manage from upload import upload from login import login + load_dotenv() app = Flask(__name__) babel = Babel(app) @@ -10,14 +11,17 @@ app.register_blueprint(upload) app.register_blueprint(login) 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['BABEL_DEFAULT_LOCALE'] = 'zh_TW' app.jinja_env.add_extension('jinja2.ext.loopcontrols') sdb = SQLAlchemy(app) + class DefaultModelView(ModelView): restricted = True + def __init__(self, model, session, restricted=True, name=None, category=None, endpoint=None, url=None, **kwargs): self.restricted = restricted self.column_default_sort = ('id', True) @@ -25,24 +29,32 @@ class DefaultModelView(ModelView): setattr(self, k, v) setattr(self, 'can_export', True) super(DefaultModelView, self).__init__(model, session, name=name, category=category, endpoint=endpoint, url=url) + def is_accessible(self): - if self.restricted == True: - return ((not check_login_status()) and is_admin() and check_permission()) - 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()) + if self.restricted: + return (not check_login_status()) and is_admin() and check_permission() + 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): + return redirect('/') + + admin = Admin( - app, - name='Attendance 點名系統 後台管理', - template_mode='bootstrap3', - index_view=MyAdminIndexView(), - ) + app, + name='Attendance 點名系統 後台管理', + template_mode='bootstrap3', + index_view=MyAdminIndexView(), +) + + class Users(sdb.Model): id = sdb.Column(sdb.INT, primary_key=True) email = sdb.Column(sdb.Text) @@ -50,6 +62,8 @@ class Users(sdb.Model): oldUsername = sdb.Column(sdb.Text) role = sdb.Column(sdb.CHAR) password = sdb.Column(sdb.Text) + + class Students(sdb.Model): id = sdb.Column(sdb.INT, primary_key=True) email = sdb.Column(sdb.INT) @@ -60,6 +74,8 @@ class Students(sdb.Model): ename = sdb.Column(sdb.Text) classes = sdb.Column(sdb.Text) password = sdb.Column(sdb.Text) + + class Schedule(sdb.Model): id = sdb.Column(sdb.INT, primary_key=True) grade = sdb.Column(sdb.INT) @@ -68,6 +84,8 @@ class Schedule(sdb.Model): period = sdb.Column(sdb.CHAR) subject = sdb.Column(sdb.Text) teacher = sdb.Column(sdb.Text) + + class SpecSchedule(sdb.Model): __tablename__ = 'specschedule' id = sdb.Column(sdb.INT, primary_key=True) @@ -77,6 +95,8 @@ class SpecSchedule(sdb.Model): period = sdb.Column(sdb.CHAR) subject = sdb.Column(sdb.Text) teacher = sdb.Column(sdb.Text) + + class GPClasses(sdb.Model): __tablename__ = 'gpclasses' id = sdb.Column(sdb.INT, primary_key=True) @@ -84,11 +104,15 @@ class GPClasses(sdb.Model): subclass = sdb.Column(sdb.Text) about = sdb.Column(sdb.Text) accs = sdb.Column(sdb.Text) + + class Homerooms(sdb.Model): id = sdb.Column(sdb.INT, primary_key=True) grade = sdb.Column(sdb.INT) class_ = sdb.Column(sdb.INT) accs = sdb.Column(sdb.Text) + + class Submission(sdb.Model): id = sdb.Column(sdb.INT, primary_key=True) grade = sdb.Column(sdb.INT) @@ -104,6 +128,8 @@ class Submission(sdb.Model): ds6 = sdb.Column(sdb.INT) ds7 = sdb.Column(sdb.INT) notes = sdb.Column(sdb.Text) + + class DS(sdb.Model): id = sdb.Column(sdb.INT, primary_key=True) grade = sdb.Column(sdb.INT) @@ -113,10 +139,14 @@ class DS(sdb.Model): period = sdb.Column(sdb.CHAR) note = sdb.Column(sdb.Text) status = sdb.Column(sdb.CHAR, default='X') + + class Dates(sdb.Model): id = sdb.Column(sdb.INT, primary_key=True) date = sdb.Column(sdb.VARCHAR(11)) dow = sdb.Column(sdb.INT) + + class Absent(sdb.Model): id = sdb.Column(sdb.INT, primary_key=True) grade = sdb.Column(sdb.INT) @@ -126,22 +156,34 @@ class Absent(sdb.Model): period = sdb.Column(sdb.CHAR) status = sdb.Column(sdb.CHAR) note = sdb.Column(sdb.Text) + + class Forgot(sdb.Model): id = sdb.Column(sdb.INT, primary_key=True) resetID = sdb.Column(sdb.VARCHAR(11)) email = sdb.Column(sdb.Text) 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(SpecSchedule, sdb.session, restricted=False, column_searchable_list = ['grade', 'class_', 'date', 'period', 'subject', 'teacher'])) -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_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(SpecSchedule, sdb.session, restricted=False, + column_searchable_list=['grade', 'class_', 'date', 'period', 'subject', 'teacher'])) +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='Logout 登出', category='', url='/logout')) diff --git a/export.py b/export.py index facb606..df929e3 100644 --- a/export.py +++ b/export.py @@ -9,6 +9,7 @@ side = Side(border_style='thin') 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')) + def create_period_sheets(workbook, class_code): ws = workbook.create_sheet(class_code[0] + class_code[1]) 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).alignment = center ws.cell(row=2, column=i).border = border - + # loop over C:G for i in range(2, 8): ws.column_dimensions[str(chr(ord('A') + i))].width = 13 @@ -49,7 +50,8 @@ def create_period_sheets(workbook, class_code): # get data db = refresh_db() 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() data = {} 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: 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 = { 'm': ['7:30', '8:10'], '1': ['8:20', '9:05'], @@ -100,25 +102,27 @@ def create_period_sheets(workbook, class_code): if p == 'm' or p == 'n': ws.merge_cells('C' + str(curr) + ':G' + str(curr + 1)) 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)].alignment = center - 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)].font = std_font + 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 + 1)].border = border if p == 'm': ws['C' + str(curr)] = '早自習' else: ws['C' + str(curr)] = '午餐 / 午休' else: 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[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)].border = border - ws[chr(ord('C') + i-1) + str(curr + 1)].border = border + 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)].alignment = center + ws[chr(ord('C') + i - 1) + str(curr)].border = border + ws[chr(ord('C') + i - 1) + str(curr + 1)].border = border if i in data: if p in data[i]: - 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']) + 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']) curr += 2 ws.merge_cells('A26:G26') ws['A26'] = '科任老師一覽表' @@ -136,7 +140,7 @@ def create_period_sheets(workbook, class_code): pos = ['D', 'E'] else: 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[pos[0] + loc].font = std_font ws[pos[0] + loc].alignment = center @@ -148,6 +152,7 @@ def create_period_sheets(workbook, class_code): curr += 1 return workbook + def create_student_list(workbook, class_code): ws = workbook.create_sheet(class_code[0] + class_code[1]) 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 db = refresh_db() 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() last = data[-1][0] delcnt = 0 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)].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)].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)].alignment = center ws.row_dimensions[3 + i].height = 19 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 - if data[i - delcnt][0] != i+1: + 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: delcnt += 1 return workbook + def create_teacher_periods(workbook, teacher_name, orig_username=''): ws = workbook.create_sheet(teacher_name) 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).alignment = center ws.cell(row=2, column=i).border = border - + # loop over C:G for i in range(2, 8): 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() cursor = db.cursor() 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() 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() for j in tmp_sql: if j[0] not in data: @@ -263,7 +270,7 @@ def create_teacher_periods(workbook, teacher_name, orig_username=''): 'subject': i[0], '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() # loop over data for i in sql: @@ -274,7 +281,7 @@ def create_teacher_periods(workbook, teacher_name, orig_username=''): '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 = { 'm': ['7:30', '8:10'], '1': ['8:20', '9:05'], @@ -310,24 +317,27 @@ def create_teacher_periods(workbook, teacher_name, orig_username=''): if p == 'm' or p == 'n': ws.merge_cells('C' + str(curr) + ':G' + str(curr + 1)) 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)].alignment = center - 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)].font = std_font + 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 + 1)].border = border if p == 'm': ws['C' + str(curr)] = '早自習' else: ws['C' + str(curr)] = '午餐 / 午休' else: 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[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 + 1)].border = border - ws[chr(ord('C') + i-1) + str(curr)].alignment = center + Alignment(wrapText=True) + 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)].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) if i in data: 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' - and data[i][p]['subject'] != '--' else '' if data[i][p]['subject'] == '--' else data[i][p]['teacher']) + ws[chr(ord('C') + i - 1) + str(curr)] = ( + 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 - return workbook \ No newline at end of file + return workbook diff --git a/functions.py b/functions.py index 2c5ec06..9e021af 100644 --- a/functions.py +++ b/functions.py @@ -20,6 +20,7 @@ from flask_admin import Admin, AdminIndexView, expose from flask_admin.menu import MenuLink from flask_admin.contrib.sqla import ModelView from flask_babelex import Babel + load_dotenv() tz = pytz.timezone('Asia/Taipei') @@ -44,7 +45,7 @@ DSTEXT = [ ] DSOFFENSES = { 'A': "把玩物品、不專心聽講", - 'B': "書寫或傳遞紙條、物品", + 'B': "書寫或傳遞紙條、物品", 'C': "自言自語或與同學交談", 'D': "接話、大聲笑、起哄、發出怪聲", 'E': "亂動、逗弄同學、影響教學情境", @@ -54,17 +55,21 @@ DSOFFENSES = { 'Z': "上課睡覺" } + def refresh_db(): return mysql.connector.connect(user=os.environ.get('MYSQL_USER'), password=os.environ.get('MYSQL_PASSWORD'), host=os.environ.get('MYSQL_HOST'), database='attendance') + def genHash(password): return sha256_crypt.hash(password) + def verifyPassword(password, hash): return sha256_crypt.verify(password, hash) + def refresh_token(): session['is_logged_in'] = True session['loginTime'] = datetime.now(tz) @@ -79,6 +84,7 @@ def check_login_status(): session['is_logged_in'] == False or (datetime.now(tz) - session['loginTime']).total_seconds() > 43200) + def send_email(to, subject, text): return requests.post( "https://api.mailgun.net/v3/mg.aaronlee.tech/messages", @@ -88,6 +94,7 @@ def send_email(to, subject, text): "subject": subject, "html": text}) + def getName(grade, class_, number): db = refresh_db() cursor = db.cursor() @@ -98,6 +105,7 @@ def getName(grade, class_, number): db.close() return name[0] + # LOGIN @@ -113,18 +121,14 @@ def verify_recaptcha(response): print(r.json()) return r.json()['success'] + # UPLOAD def is_admin(): return 'subuser_type' in session and session['subuser_type'] == 'admin' + def check_permission(): if 'subuser_type' in session and session['subuser_type'] == 'admin': return session['showUpload'] else: - return False - -# MANAGE -def removeprefix(s, prefix): - if s.startswith(prefix): - return s[len(prefix):] - return s + return False \ No newline at end of file diff --git a/login.py b/login.py index aa55bd2..23bb5d9 100644 --- a/login.py +++ b/login.py @@ -1,5 +1,8 @@ from functions import * + login = Blueprint('login', __name__) + + @login.after_request def add_header(response): response.headers['SameSite'] = "Strict" @@ -13,10 +16,10 @@ def index(): return render_template('login.html') return redirect('/select') elif request.method == 'POST': - email = request.form['username'] + email = request.form['username'].strip() if check_login_status(): try: - if (verify_recaptcha("")): + if verify_recaptcha(""): if request.form['user_type'] == 'teacher': db = refresh_db() cursor = db.cursor(buffered=True) @@ -26,7 +29,7 @@ def index(): if user == None or not verifyPassword(request.form['password'], user[3]): raise Exception('Invalid Login') usrRole = user[1] - if (usrRole == 'R'): + if usrRole == 'R': print("RealPerson Login SUCC:", email, flush=True) session['is_logged_in'] = True session['email'] = email @@ -34,7 +37,7 @@ def index(): session['oldUsername'] = user[2] session['loginTime'] = datetime.now(tz) return redirect('/select') - if (usrRole == 'A' or usrRole == 'S'): + if usrRole == 'A' or usrRole == 'S': print("Admin Login SUCC:", email, flush=True) session['subuser_type'] = 'admin' session['is_logged_in'] = True @@ -47,7 +50,8 @@ def index(): elif request.form['user_type'] == 'student': db = refresh_db() 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() cursor.close() if user == None or not verifyPassword(request.form['password'], user[0]): @@ -83,12 +87,14 @@ def selSubUser(): flash("Timeout. 遇時,請重新登入") return redirect('/') 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') if request.method == 'GET': db = refresh_db() 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() cursor.close() hasGroup = False @@ -96,7 +102,7 @@ def selSubUser(): hasGroup = True db = refresh_db() 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() cursor.close() hrC = {} @@ -109,11 +115,11 @@ def selSubUser(): if data == []: return redirect('/select') try: - if (verify_recaptcha("")): - if (data[0] == 'homeroom'): + if verify_recaptcha(""): + if data[0] == 'homeroom': session['homeroom'] = data[1] + '^' + data[2] session['subuser_type'] = 'homeroom' - elif (data[0] == 'group'): + elif data[0] == 'group': session['subuser_type'] = 'group' return redirect('/manage') else: @@ -141,7 +147,7 @@ def chgPassword(): if not check_login_status(): refresh_token() try: - if (verify_recaptcha("")): + if verify_recaptcha(""): db = refresh_db() cursor = db.cursor(buffered=True) if ('user_type' in session and session['user_type'] == 'student'): @@ -167,21 +173,24 @@ def chgPassword(): raise Exception('帳號已被使用
Username already used') db = refresh_db() cursor = db.cursor(buffered=True) - 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)) - 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)) + 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)) + 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: cursor.execute("UPDATE users SET password = %s WHERE email = %s", ( genHash(request.form['new_password']), oldEmail)) - 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)) + 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)) db.commit() cursor.close() 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 信箱已更改", - """
+ """
Your email was changed at %s to %s.
If you did not change your email, please contact the student affair's office immediately.
@@ -190,7 +199,8 @@ def chgPassword():
This email was sent automatically. Please do not reply.
這個郵件是自動發送的,請不要回覆。
- """ % (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( '修改密碼成功,請重新登入
Password changed successfully. Please login again.') return redirect('/') @@ -211,12 +221,12 @@ def forgotPassword(): elif request.method == 'POST': email = request.form['username'] try: - if (verify_recaptcha("")): + if verify_recaptcha(""): db = refresh_db() 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,)) - elif (request.form['user_type'] == 'teacher'): + elif request.form['user_type'] == 'teacher': cursor.execute("SELECT email FROM users WHERE email = %s", (email,)) user = cursor.fetchone() cursor.close() @@ -235,11 +245,12 @@ def forgotPassword(): cursor.execute(""" INSERT INTO forgot (resetID, email, reqTime, userType) 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() cursor.close() send_email(email, "Password Reset 重置密碼", - """
+ """
Please go to the following link to reset your password:
https://abs.aaronlee.tech/resetPassword?resetCode=%s
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')) else: try: - if (verify_recaptcha("")): + if verify_recaptcha(""): db = refresh_db() cursor = db.cursor(buffered=True) cursor.execute(""" diff --git a/manage/admin.py b/manage/admin.py index 23296b2..bbb41f5 100644 --- a/manage/admin.py +++ b/manage/admin.py @@ -1,10 +1,12 @@ from functions import * from export import * + admin = Blueprint('admin', __name__) + @admin.route('/manage/admin/mark', methods=['GET', 'POST']) def mark_absent(): - if (check_login_status() or session['subuser_type'] != 'admin'): + if check_login_status() or session['subuser_type'] != 'admin': return redirect('/logout') refresh_token() if request.method == 'POST': @@ -14,13 +16,17 @@ def mark_absent(): db = refresh_db() cursor = db.cursor() for p in periods: - cursor.execute("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 '')) + cursor.execute( + "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() except Exception as e: flash(e) 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') db = refresh_db() cursor = db.cursor() @@ -35,18 +41,22 @@ def mark_absent(): 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") 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']) def admin_export(): - if (check_login_status() or session['subuser_type'] != 'admin'): + if check_login_status() or session['subuser_type'] != 'admin': return redirect('/logout') refresh_token() return render_template("admin_export.html", hideSel=True) + @admin.route('/manage/admin/export/homeroom_period', methods=['POST']) 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') refresh_token() workbook = Workbook() @@ -55,11 +65,14 @@ def admin_export_homeroom_period(): excel_stream = io.BytesIO() workbook.save(excel_stream) 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']) 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') refresh_token() db = refresh_db() @@ -78,7 +91,7 @@ def admin_export_homeroom_period_all(): @admin.route('/manage/admin/export/student_list', methods=['POST']) 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') refresh_token() workbook = Workbook() @@ -87,11 +100,14 @@ def admin_export_student_list(): excel_stream = io.BytesIO() workbook.save(excel_stream) 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']) 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') refresh_token() db = refresh_db() @@ -107,9 +123,10 @@ def admin_export_student_list_all(): excel_stream.seek(0) return send_file(excel_stream, attachment_filename='student_list_all.xlsx', as_attachment=True) + @admin.route('/manage/admin/export/teacher_period', methods=['POST']) 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') refresh_token() workbook = Workbook() @@ -118,11 +135,13 @@ def admin_export_teacher_period(): excel_stream = io.BytesIO() workbook.save(excel_stream) 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']) 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') refresh_token() db = refresh_db() @@ -136,4 +155,4 @@ def admin_export_teacher_period_all(): excel_stream = io.BytesIO() workbook.save(excel_stream) excel_stream.seek(0) - return send_file(excel_stream, attachment_filename='teacher_period_all.xlsx', as_attachment=True) \ No newline at end of file + return send_file(excel_stream, attachment_filename='teacher_period_all.xlsx', as_attachment=True) diff --git a/manage/group.py b/manage/group.py index 9f5a7b2..ab1f1d7 100644 --- a/manage/group.py +++ b/manage/group.py @@ -1,9 +1,11 @@ from functions import * + group = Blueprint('group', __name__) + @group.route('/manage/group_teach_publish', methods=['POST']) def group_teach_publish(): - if (check_login_status()): + if check_login_status(): return redirect('/logout') refresh_token() data = request.form.to_dict() @@ -13,10 +15,11 @@ def group_teach_publish(): } db = refresh_db() cursor = db.cursor() - cursor.execute("SELECT about FROM gpclasses WHERE category=%s AND subclass=%s", - (cclass['category'], cclass['class_id'])) + cursor.execute("SELECT about FROM gpclasses WHERE category=%s AND subclass=%s", + (cclass['category'], cclass['class_id'])) 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() homerooms = [] for x in students: @@ -37,7 +40,8 @@ def group_teach_publish(): if xs[0] == 'note': continue 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: h = h.split('^') cursor = db.cursor() @@ -99,4 +103,4 @@ def group_teach_publish(): VALUES (%s, %s, %s, %s, %s, %s) """, (d[0], d[1], d[2], date, period, d[3])) db.commit() - return redirect('/manage') \ No newline at end of file + return redirect('/manage') diff --git a/manage/homeroom.py b/manage/homeroom.py index 33cc03e..dc0af11 100644 --- a/manage/homeroom.py +++ b/manage/homeroom.py @@ -1,15 +1,18 @@ from functions import * + homeroom = Blueprint('homeroom', __name__) + @homeroom.route('/manage/abs', methods=['GET']) def showAllAbs(): - if (check_login_status()): + if check_login_status(): return redirect('/logout') refresh_token() currRoom = session['homeroom'].split('^') db = refresh_db() 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() students = {} for st in studentsSQL: @@ -18,9 +21,13 @@ def showAllAbs(): 'ename': st[2], } 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() - 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']) def showAllDS(): @@ -30,7 +37,8 @@ def showAllDS(): currRoom = session['homeroom'].split('^') db = refresh_db() 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() students = {} for st in studentsSQL: @@ -39,9 +47,13 @@ def showAllDS(): 'ename': st[2], } 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() - 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']) def homeroom_abs_publish(): @@ -58,7 +70,7 @@ def homeroom_abs_publish(): absentData = {} for x in data: xt = x.split('^') - if (xt[0] == 'note'): + if xt[0] == 'note': if xt[2] not in absentData: absentData[xt[2]] = {} absentData[xt[2]]['note'] = data[x] @@ -77,13 +89,15 @@ def homeroom_abs_publish(): INSERT INTO absent (grade, class_, date, period, num, status, note) 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() return redirect('/manage') + @homeroom.route('/manage/homeroom_ds', methods=['POST']) def homeroom_ds_publish(): - if (check_login_status()): + if check_login_status(): return redirect('/logout') refresh_token() 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)) for x in data: xt = x.split('^') - if (xt[0] == 'dsidv'): + if xt[0] == 'dsidv': dsidv[xt[1]] = data[x] for x in dsidv: cursor.execute(""" @@ -120,9 +134,10 @@ def homeroom_ds_publish(): db.commit() return redirect('/manage') + @homeroom.route('/manage/homeroom_confirm', methods=['POST']) def homeroom_confirm(): - if (check_login_status()): + if check_login_status(): return redirect('/logout') refresh_token() data = request.form.to_dict() diff --git a/manage/manage.py b/manage/manage.py index 9c5f886..00d36a4 100644 --- a/manage/manage.py +++ b/manage/manage.py @@ -3,20 +3,24 @@ from manage.homeroom import homeroom from manage.student import student from manage.admin import admin from manage.group import group + manage = Blueprint('manage', __name__) manage.register_blueprint(homeroom) manage.register_blueprint(student) manage.register_blueprint(admin) manage.register_blueprint(group) + @manage.route('/manage', methods=['GET']) def manageRoot(): return manageProcess("", "") + @homeroom.route('/manage/date/', methods=['GET']) def manage_date(date): return manageProcess("date", date) + @manage.route('/manage/admin///', methods=['GET']) def manage_admin(g, r, date): data = [ @@ -27,7 +31,7 @@ def manage_admin(g, r, date): def manageProcess(fCommand, fData): - if (check_login_status()): + if check_login_status(): return redirect('/logout') refresh_token() if 'user_type' in session and session['user_type'] == 'student': @@ -50,7 +54,8 @@ def manageProcess(fCommand, fData): else: currRoom = [homeroomsSQL[0][0], homeroomsSQL[0][1]] 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() studGP = {} for s in students: @@ -67,10 +72,11 @@ def manageProcess(fCommand, fData): if i[0] >= datetime.now(tz).strftime("%Y-%m-%d"): break 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] 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() schedule = {} for i in scheduleSQL: @@ -79,7 +85,8 @@ def manageProcess(fCommand, fData): "teacher": i[2], } 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() for i in specScheduleSQL: schedule[i[0]] = { @@ -88,17 +95,20 @@ def manageProcess(fCommand, fData): "special": True } 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() submission = {} 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() idvDS = {} for i in idvDSSQL: if i[0] not in idvDS: idvDS[i[0]] = {} - idvDS[i[0]][i[1]]= i[2] + idvDS[i[0]][i[1]] = i[2] for i in submissionSQL: if i[0] == 'c': submission[i[0]] = { @@ -126,7 +136,8 @@ def manageProcess(fCommand, fData): "ds7": i[9] } 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() absentData = {} 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], 'note': i[3], } - return render_template('admin.html', homerooms=homerooms, currRoom=currRoom, students=students, currDate=currDate, schedule=schedule, submission=submission, studGP=studGP, idvDS=idvDS, - 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']) + return render_template('admin.html', homerooms=homerooms, currRoom=currRoom, students=students, + currDate=currDate, schedule=schedule, submission=submission, studGP=studGP, idvDS=idvDS, + 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': db = refresh_db() 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() data = {} currDate = "" @@ -160,12 +175,12 @@ def manageProcess(fCommand, fData): if i[0] >= datetime.now(tz).strftime("%Y-%m-%d"): break 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] for c in gpclasses: - cursor.execute("SELECT about FROM gpclasses WHERE subclass=%s AND category=%s", - (c[1], c[0])) + cursor.execute("SELECT about FROM gpclasses WHERE subclass=%s AND category=%s", + (c[1], c[0])) cclass = { "name": cursor.fetchone()[0], "category": c[0], @@ -175,7 +190,8 @@ def manageProcess(fCommand, fData): "cdata": cclass, } # 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() # get student homerooms homerooms = [] @@ -185,13 +201,18 @@ def manageProcess(fCommand, fData): # get periods for h in homerooms: 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() - 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() for s in specNTPSQL: 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() specNTD = {} for i in specNTDSQL: @@ -205,7 +226,9 @@ def manageProcess(fCommand, fData): if (h not in data[cclass['category'] + ' ' + cclass['class_id']][p[0]]): data[cclass['category'] + ' ' + cclass['class_id']][p[0]][h] = {} 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() submitted = False try: @@ -217,13 +240,17 @@ def manageProcess(fCommand, fData): hrCfrm = False if not submitted: 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 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() 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]] status = "" if submitted: @@ -244,7 +271,8 @@ def manageProcess(fCommand, fData): "ename": x[4], "status": status, "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) elif pl == 'homeroom': @@ -266,13 +294,13 @@ def manageProcess(fCommand, fData): currPeriod = "" currTime = datetime.now(tz).strftime("%H:%M") for i in times: - if (times[i] <= currTime and - currTime <= times[next_item(times, i)]): + if times[i] <= currTime <= times[next_item(times, i)]: currPeriod = i break currRoom = session['homeroom'].split('^') 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() studGP = {} for s in students: @@ -289,10 +317,11 @@ def manageProcess(fCommand, fData): if i[0] >= datetime.now(tz).strftime("%Y-%m-%d"): break 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] 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() schedule = {} for i in scheduleSQL: @@ -301,7 +330,8 @@ def manageProcess(fCommand, fData): "teacher": i[2], } 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() for i in specScheduleSQL: schedule[i[0]] = { @@ -310,16 +340,19 @@ def manageProcess(fCommand, fData): "special": True } 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() 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() idvDS = {} for i in idvDSSQL: if i[0] not in idvDS: idvDS[i[0]] = {} - idvDS[i[0]][i[1]]= i[2] + idvDS[i[0]][i[1]] = i[2] submission = {} for i in submissionSQL: if i[0] == 'c': @@ -350,7 +383,8 @@ def manageProcess(fCommand, fData): if i[10] == 'yes': submission[i[0]]["dscfrm"] = True 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() absentData = {} 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], 'note': i[3], } - return render_template('homeroom.html', currRoom=currRoom, students=students, currDate=currDate, 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) + return render_template('homeroom.html', currRoom=currRoom, students=students, currDate=currDate, + 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: - return redirect('/logout') \ No newline at end of file + return redirect('/logout') diff --git a/manage/student.py b/manage/student.py index cf4f977..af16e68 100644 --- a/manage/student.py +++ b/manage/student.py @@ -1,30 +1,38 @@ from functions import * + student = Blueprint('student', __name__) + @student.route('/student', methods=['GET']) def showStudentAbs(): - if (check_login_status()): + if check_login_status(): return redirect('/logout') refresh_token() if not ('user_type' in session and session['user_type'] == 'student'): return redirect('/') db = refresh_db() 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() - 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']) def showStudentDS(): - if (check_login_status()): + if check_login_status(): return redirect('/logout') refresh_token() if not ('user_type' in session and session['user_type'] == 'student'): return redirect('/') db = refresh_db() 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() 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'])