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

1from io import BytesIO 

2 

3from sqlalchemy.orm import subqueryload 

4from sqlalchemy.orm.session import Session 

5import xlsxwriter # type: ignore[import] 

6 

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 

14 

15from .responses import attachment 

16 

17 

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 ) 

25 

26 buff = BytesIO() 

27 workbook = xlsxwriter.Workbook(buff, {"in_memory": True}) 

28 worksheet = workbook.add_worksheet() 

29 

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 

42 

43 

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. 

49 

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")