Coverage for rfpy/api/endpoints/reports/qtextxlsx.py: 100%
35 statements
« prev ^ index » next coverage.py v7.0.1, created at 2022-12-31 16:00 +0000
« prev ^ index » next coverage.py v7.0.1, created at 2022-12-31 16:00 +0000
1from io import BytesIO
3from sqlalchemy.orm import subqueryload
4from sqlalchemy.orm.session import Session
5import xlsxwriter
7from rfpy.auth import perms
8from rfpy.suxint import http
9from rfpy.model.project import Project
10from rfpy.model import QuestionInstance, Label
11from rfpy.api import fetch, validate
12from rfpy.web.mime import MimeTypes
14from .responses import attachment
17def _generate_xlsx(session: Session, project: Project) -> BytesIO:
19 q = session.query(QuestionInstance)\
20 .filter(QuestionInstance.project == project)\
21 .options(subqueryload(QuestionInstance.question_def))\
22 .order_by(QuestionInstance.number)
24 buff = BytesIO()
25 workbook = xlsxwriter.Workbook(buff, {'in_memory': True})
26 worksheet = workbook.add_worksheet()
28 for idx, qi in enumerate(q):
29 worksheet.write(idx, 0, qi.number.dotted)
30 worksheet.write(idx, 1, qi.question_def.title)
31 elements = qi.question_def.elements
32 col = 2
33 for element in elements:
34 if isinstance(element, Label):
35 worksheet.write(idx, col, element.label)
36 col = col + 1
37 workbook.close()
38 buff.seek(0)
39 return buff
42@http
43def get_project_report_qtext(session, user, project_id) -> MimeTypes.XLSX:
44 '''
45 Generate a spreadsheet with one row for each question and one column for title and then each
46 Label (question text) element in the question.
48 Useful for checking all the text in a questionnaire.
49 '''
50 project = fetch.project(session, project_id)
51 validate.check(user, perms.PROJECT_ACCESS, project=project, deny_restricted=True)
52 buff = _generate_xlsx(session, project)
53 buff.seek(0)
54 return attachment(buff.read(), MimeTypes.XLSX.value, f'{project.title[:25]}.xlsx')