Commit 7c49db426cbe94a3c319e396c96873b736b243aa

Authored by Miguel Barao
1 parent f1ad38ab
Exists in master and in 1 other branch dev

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 # THE MIT License 3 # THE MIT License
4 # 4 #
@@ -32,10 +32,10 @@ proof of submission and for review. @@ -32,10 +32,10 @@ proof of submission and for review.
32 ''' 32 '''
33 33
34 APP_NAME = 'perguntations' 34 APP_NAME = 'perguntations'
35 -APP_VERSION = '2021.01.dev1' 35 +APP_VERSION = '2021.09.dev1'
36 APP_DESCRIPTION = __doc__ 36 APP_DESCRIPTION = __doc__
37 37
38 __author__ = 'Miguel Barão' 38 __author__ = 'Miguel Barão'
39 -__copyright__ = 'Copyright 2020, Miguel Barão' 39 +__copyright__ = 'Copyright 2021, Miguel Barão'
40 __license__ = 'MIT license' 40 __license__ = 'MIT license'
41 __version__ = APP_VERSION 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,10 +22,10 @@ from sqlalchemy.exc import NoResultFound
21 22
22 # this project 23 # this project
23 from perguntations.models import Student, Test, Question 24 from perguntations.models import Student, Test, Question
  25 +from perguntations.questions import question_from
24 from perguntations.tools import load_yaml 26 from perguntations.tools import load_yaml
25 from perguntations.testfactory import TestFactory, TestFactoryException 27 from perguntations.testfactory import TestFactory, TestFactoryException
26 import perguntations.test 28 import perguntations.test
27 -from perguntations.questions import question_from  
28 29
29 # setup logger for this module 30 # setup logger for this module
30 logger = logging.getLogger(__name__) 31 logger = logging.getLogger(__name__)
@@ -113,44 +114,44 @@ class App(): @@ -113,44 +114,44 @@ class App():
113 len(self.allowed)) 114 len(self.allowed))
114 self._pregenerate_tests(len(self.allowed)) 115 self._pregenerate_tests(len(self.allowed))
115 else: 116 else:
116 - logger.info('No tests were generated.') 117 + logger.info('No tests generated yet.')
117 118
118 if conf['correct']: 119 if conf['correct']:
119 self._correct_tests() 120 self._correct_tests()
120 121
  122 + # ------------------------------------------------------------------------
121 def _db_setup(self) -> None: 123 def _db_setup(self) -> None:
122 logger.info('Setup database') 124 logger.info('Setup database')
123 125
124 # connect to database and check registered students 126 # connect to database and check registered students
125 dbfile = path.expanduser(self.testfactory['database']) 127 dbfile = path.expanduser(self.testfactory['database'])
126 if not path.exists(dbfile): 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 self._engine = create_engine(f'sqlite:///{dbfile}', future=True) 130 self._engine = create_engine(f'sqlite:///{dbfile}', future=True)
129 131
130 try: 132 try:
131 - query = select(func.count(Student.id)).where(Student.id != '0')  
132 with Session(self._engine, future=True) as session: 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 except Exception as exc: 137 except Exception as exc:
135 raise AppException(f'Database unusable {dbfile}.') from exc 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 logger.info('Database "%s" has %s students.', dbfile, num) 140 logger.info('Database "%s" has %s students.', dbfile, num)
143 141
144 -  
145 -  
146 # ------------------------------------------------------------------------ 142 # ------------------------------------------------------------------------
147 def _correct_tests(self): 143 def _correct_tests(self):
148 - with self._db_session() as sess: 144 + with Session(self._engine, future=True) as session:
149 # Find which tests have to be corrected 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 logger.info('Correcting %d tests...', len(dbtests)) 156 logger.info('Correcting %d tests...', len(dbtests))
156 for dbtest in dbtests: 157 for dbtest in dbtests:
@@ -204,16 +205,26 @@ class App(): @@ -204,16 +205,26 @@ class App():
204 logger.warning('"%s" unauthorized.', uid) 205 logger.warning('"%s" unauthorized.', uid)
205 return 'unauthorized' 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 if hashed_pw == '': # update password on first login 218 if hashed_pw == '': # update password on first login
213 await self.update_student_password(uid, try_pw) 219 await self.update_student_password(uid, try_pw)
214 pw_ok = True 220 pw_ok = True
215 else: # check password 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 if not pw_ok: # wrong password 229 if not pw_ok: # wrong password
219 logger.info('"%s" wrong password.', uid) 230 logger.info('"%s" wrong password.', uid)