Coverage for jutil/responses.py: 34%

# Coverage for jutil/responses.py : 34%

## 45 statements 18 run 27 missing 0 excluded 0 partial

Hot-keys on this page

r m x p toggle line displays

j k next/prev highlighted chunk

0 (zero) top of page

1 (one) first highlighted chunk

1 import mimetypes

2 import os

3 from io import StringIO

4 from typing import Any, List

5 from django.http import HttpResponse, FileResponse, Http404

6 from django.utils.translation import gettext as _

7 from jutil.format import format_xml_file, format_xml_bytes

8 import csv

9

10

11 class FileSystemFileResponse(FileResponse):

12 """

13 File system download HTTP response.

14 :param full_path: Full path to file

15 :param filename: Filename (optional) passed to client. Defaults to basename of the full path.

16 """

17 def __init__(self, full_path: str, filename: str = '', **kw):

18 if not os.path.isfile(full_path):

19 raise Http404(_("File {} not found").format(full_path))

20 if not filename:

21 filename = os.path.basename(full_path)

22 content_type = mimetypes.guess_type(filename)[0]

23 super().__init__(open(full_path, 'rb'), **kw)

24 if content_type:

25 self['Content-Type'] = content_type

26 self['Content-Length'] = os.path.getsize(full_path)

27 self['Content-Disposition'] = "attachment; filename={}".format(filename)

28

29

30 class CsvResponse(HttpResponse):

31 """

32 CSV download HTTP response.

33 """

34 def __init__(self, rows: List[List[Any]], filename: str, dialect='excel', **kw):

35 """

36 Returns CSV response.

37 :param rows: List of column lists

38 :param filename: Download response file name

39 :param dialect: csv.writer dialect

40 :param kw: Parameters to be passed to HttpResponse __init__

41 """

42 f = StringIO()

43 writer = csv.writer(f, dialect=dialect)

44 for row in rows:

45 writer.writerow(row)

46

47 buf = f.getvalue().encode('utf-8')

48 super().__init__(content=buf, content_type='text/csv', **kw)

49 self['Content-Disposition'] = 'attachment;filename="{}"'.format(filename)

50

51

52 class FormattedXmlFileResponse(HttpResponse):

53 def __init__(self, filename: str):

54 content = format_xml_file(filename)

55 super().__init__(content)

56 self['Content-Type'] = 'application/xml'

57 self['Content-Length'] = len(content)

58 self['Content-Disposition'] = "attachment; filename={}".format(os.path.basename(filename))

59

60

61 class XmlResponse(HttpResponse):

62 def __init__(self, content: bytes, filename: str):

63 super().__init__(content)

64 self['Content-Type'] = 'application/xml'

65 self['Content-Length'] = len(content)

66 self['Content-Disposition'] = "attachment; filename={}".format(os.path.basename(filename))

67

68

69 class FormattedXmlResponse(XmlResponse):

70 def __init__(self, content: bytes, filename: str, encoding: str = 'UTF-8', exceptions: bool = True):

71 super().__init__(format_xml_bytes(content, encoding=encoding, exceptions=exceptions), filename)