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

1from io import BytesIO 

2 

3from sqlalchemy.orm import subqueryload 

4from sqlalchemy.orm.session import Session 

5import xlsxwriter 

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 

13 

14from .responses import attachment 

15 

16 

17def _generate_xlsx(session: Session, project: Project) -> BytesIO: 

18 

19 q = session.query(QuestionInstance)\ 

20 .filter(QuestionInstance.project == project)\ 

21 .options(subqueryload(QuestionInstance.question_def))\ 

22 .order_by(QuestionInstance.number) 

23 

24 buff = BytesIO() 

25 workbook = xlsxwriter.Workbook(buff, {'in_memory': True}) 

26 worksheet = workbook.add_worksheet() 

27 

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 

40 

41 

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. 

47 

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