Coverage for rfpy/api/endpoints/reports/qtextxlsx.py: 100%
36 statements
« prev ^ index » next coverage.py v7.8.0, created at 2025-04-24 10:52 +0000
« prev ^ index » next coverage.py v7.8.0, created at 2025-04-24 10:52 +0000
1from io import BytesIO
3from sqlalchemy.orm import subqueryload
4from sqlalchemy.orm.session import Session
5import xlsxwriter # type: ignore[import]
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
13from rfpy.web.response import XAccelResponse
15from .responses import attachment
18def _generate_xlsx(session: Session, project: Project) -> BytesIO:
19 q = (
20 session.query(QuestionInstance)
21 .filter(QuestionInstance.project == project)
22 .options(subqueryload(QuestionInstance.question_def))
23 .order_by(QuestionInstance.number)
24 )
26 buff = BytesIO()
27 workbook = xlsxwriter.Workbook(buff, {"in_memory": True})
28 worksheet = workbook.add_worksheet()
30 for idx, qi in enumerate(q):
31 worksheet.write(idx, 0, qi.number.dotted)
32 worksheet.write(idx, 1, qi.question_def.title)
33 elements = qi.question_def.elements
34 col = 2
35 for element in elements:
36 if isinstance(element, Label):
37 worksheet.write(idx, col, element.label)
38 col = col + 1
39 workbook.close()
40 buff.seek(0)
41 return buff
44@http
45def get_project_report_qtext(session, user, project_id) -> XAccelResponse:
46 """
47 Generate a spreadsheet with one row for each question and one column for title and then each
48 Label (question text) element in the question.
50 Useful for checking all the text in a questionnaire.
51 """
52 project = fetch.project(session, project_id)
53 validate.check(user, perms.PROJECT_ACCESS, project=project, deny_restricted=True)
54 buff = _generate_xlsx(session, project)
55 buff.seek(0)
56 return attachment(buff.read(), MimeTypes.XLSX.value, f"{project.title[:25]}.xlsx")