Commit 7c49db426cbe94a3c319e396c96873b736b243aa
1 parent
f1ad38ab
Exists in
master
and in
1 other branch
more changes towards sqlalchemy-1.4 compatibility
Showing
2 changed files
with
37 additions
and
26 deletions
Show diff stats
perguntations/__init__.py
| 1 | -# Copyright (C) 2020 Miguel Barão | |
| 1 | +# Copyright (C) 2021 Miguel Barão | |
| 2 | 2 | # |
| 3 | 3 | # THE MIT License |
| 4 | 4 | # |
| ... | ... | @@ -32,10 +32,10 @@ proof of submission and for review. |
| 32 | 32 | ''' |
| 33 | 33 | |
| 34 | 34 | APP_NAME = 'perguntations' |
| 35 | -APP_VERSION = '2021.01.dev1' | |
| 35 | +APP_VERSION = '2021.09.dev1' | |
| 36 | 36 | APP_DESCRIPTION = __doc__ |
| 37 | 37 | |
| 38 | 38 | __author__ = 'Miguel Barão' |
| 39 | -__copyright__ = 'Copyright 2020, Miguel Barão' | |
| 39 | +__copyright__ = 'Copyright 2021, Miguel Barão' | |
| 40 | 40 | __license__ = 'MIT license' |
| 41 | 41 | __version__ = APP_VERSION | ... | ... |
perguntations/app.py
| 1 | 1 | ''' |
| 2 | -Main application module | |
| 2 | +File: perguntations/app.py | |
| 3 | +Description: Main application logic. | |
| 3 | 4 | ''' |
| 4 | 5 | |
| 5 | 6 | |
| ... | ... | @@ -21,10 +22,10 @@ from sqlalchemy.exc import NoResultFound |
| 21 | 22 | |
| 22 | 23 | # this project |
| 23 | 24 | from perguntations.models import Student, Test, Question |
| 25 | +from perguntations.questions import question_from | |
| 24 | 26 | from perguntations.tools import load_yaml |
| 25 | 27 | from perguntations.testfactory import TestFactory, TestFactoryException |
| 26 | 28 | import perguntations.test |
| 27 | -from perguntations.questions import question_from | |
| 28 | 29 | |
| 29 | 30 | # setup logger for this module |
| 30 | 31 | logger = logging.getLogger(__name__) |
| ... | ... | @@ -113,44 +114,44 @@ class App(): |
| 113 | 114 | len(self.allowed)) |
| 114 | 115 | self._pregenerate_tests(len(self.allowed)) |
| 115 | 116 | else: |
| 116 | - logger.info('No tests were generated.') | |
| 117 | + logger.info('No tests generated yet.') | |
| 117 | 118 | |
| 118 | 119 | if conf['correct']: |
| 119 | 120 | self._correct_tests() |
| 120 | 121 | |
| 122 | + # ------------------------------------------------------------------------ | |
| 121 | 123 | def _db_setup(self) -> None: |
| 122 | 124 | logger.info('Setup database') |
| 123 | 125 | |
| 124 | 126 | # connect to database and check registered students |
| 125 | 127 | dbfile = path.expanduser(self.testfactory['database']) |
| 126 | 128 | if not path.exists(dbfile): |
| 127 | - raise AppException('Database does not exist.') | |
| 129 | + raise AppException('Database does not exist. Use "initdb" to create.') | |
| 128 | 130 | self._engine = create_engine(f'sqlite:///{dbfile}', future=True) |
| 129 | 131 | |
| 130 | 132 | try: |
| 131 | - query = select(func.count(Student.id)).where(Student.id != '0') | |
| 132 | 133 | with Session(self._engine, future=True) as session: |
| 133 | - num = session.execute(query).scalar() | |
| 134 | + num = session.execute( | |
| 135 | + select(func.count(Student.id)).where(Student.id != '0') | |
| 136 | + ).scalar() | |
| 134 | 137 | except Exception as exc: |
| 135 | 138 | raise AppException(f'Database unusable {dbfile}.') from exc |
| 136 | 139 | |
| 137 | - # try: | |
| 138 | - # with self._db_session() as sess: | |
| 139 | - # num = sess.query(Student).filter(Student.id != '0').count() | |
| 140 | - # except Exception as exc: | |
| 141 | - # raise AppException(f'Database unusable {dbfile}.') from exc | |
| 142 | 140 | logger.info('Database "%s" has %s students.', dbfile, num) |
| 143 | 141 | |
| 144 | - | |
| 145 | - | |
| 146 | 142 | # ------------------------------------------------------------------------ |
| 147 | 143 | def _correct_tests(self): |
| 148 | - with self._db_session() as sess: | |
| 144 | + with Session(self._engine, future=True) as session: | |
| 149 | 145 | # Find which tests have to be corrected |
| 150 | - dbtests = sess.query(Test)\ | |
| 151 | - .filter(Test.ref == self.testfactory['ref'])\ | |
| 152 | - .filter(Test.state == "SUBMITTED")\ | |
| 153 | - .all() | |
| 146 | + dbtests = session.execute( | |
| 147 | + select(Test). | |
| 148 | + where(Test.ref == self.testfactory['ref']). | |
| 149 | + where(Test.state == "SUBMITTED") | |
| 150 | + ).all() | |
| 151 | + # dbtests = session.query(Test)\ | |
| 152 | + # .filter(Test.ref == self.testfactory['ref'])\ | |
| 153 | + # .filter(Test.state == "SUBMITTED")\ | |
| 154 | + # .all() | |
| 154 | 155 | |
| 155 | 156 | logger.info('Correcting %d tests...', len(dbtests)) |
| 156 | 157 | for dbtest in dbtests: |
| ... | ... | @@ -204,16 +205,26 @@ class App(): |
| 204 | 205 | logger.warning('"%s" unauthorized.', uid) |
| 205 | 206 | return 'unauthorized' |
| 206 | 207 | |
| 207 | - with self._db_session() as sess: | |
| 208 | - name, hashed_pw = sess.query(Student.name, Student.password)\ | |
| 209 | - .filter_by(id=uid)\ | |
| 210 | - .one() | |
| 208 | + with Session(self._engine, future=True) as session: | |
| 209 | + # with self._db_session() as sess: | |
| 210 | + name, hashed_pw = session.execute( | |
| 211 | + select(Student.name, Student.password). | |
| 212 | + where(id == uid) | |
| 213 | + ).one() | |
| 214 | + # name, hashed_pw = sess.query(Student.name, Student.password)\ | |
| 215 | + # .filter_by(id=uid)\ | |
| 216 | + # .one() | |
| 211 | 217 | |
| 212 | 218 | if hashed_pw == '': # update password on first login |
| 213 | 219 | await self.update_student_password(uid, try_pw) |
| 214 | 220 | pw_ok = True |
| 215 | 221 | else: # check password |
| 216 | - pw_ok = await check_password(try_pw, hashed_pw) # async bcrypt | |
| 222 | + loop = asyncio.get_running_loop() | |
| 223 | + pw_ok = await loop.run_in_executor(None, | |
| 224 | + bcrypt.checkpw, | |
| 225 | + try_pw.encode('utf-8'), | |
| 226 | + hashed_pw.password) | |
| 227 | + # pw_ok = await check_password(try_pw, hashed_pw) # async bcrypt | |
| 217 | 228 | |
| 218 | 229 | if not pw_ok: # wrong password |
| 219 | 230 | logger.info('"%s" wrong password.', uid) | ... | ... |