Coverage for jutil/responses.py: 42%
39 statements
« prev ^ index » next coverage.py v6.5.0, created at 2022-10-07 16:40 -0500
« prev ^ index » next coverage.py v6.5.0, created at 2022-10-07 16:40 -0500
1import mimetypes
2import os
3from typing import Any, List
4from django.http import HttpResponse, FileResponse, Http404
5from django.utils.translation import gettext as _
6from jutil.format import format_xml_file, format_xml_bytes, format_csv
9class FileSystemFileResponse(FileResponse):
10 """
11 File system download HTTP response.
12 :param full_path: Full path to file
13 :param filename: Filename (optional) passed to client. Defaults to basename of the full path.
14 :param disposition: Content-Disposition, default attachment; filename=xxx
15 """
17 def __init__(self, full_path: str, filename: str = "", disposition: 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) # pylint: disable=consider-using-with
24 if content_type:
25 self["Content-Type"] = content_type
26 self["Content-Length"] = os.path.getsize(full_path)
27 self["Content-Disposition"] = disposition if disposition else "attachment; filename={}".format(filename)
30class CsvResponse(HttpResponse):
31 """
32 CSV download HTTP response.
33 """
35 def __init__(self, rows: List[List[Any]], filename: str, dialect="excel", **kw):
36 """
37 Returns CSV response.
38 :param rows: List of column lists
39 :param filename: Download response file name
40 :param dialect: See csv.writer dialect
41 :param kw: Parameters to be passed to HttpResponse __init__
42 """
43 buf = format_csv(rows, dialect=dialect).encode("utf-8")
44 super().__init__(content=buf, content_type="text/csv", **kw)
45 self["Content-Disposition"] = 'attachment;filename="{}"'.format(filename)
48class FormattedXmlFileResponse(HttpResponse):
49 def __init__(self, filename: str):
50 content = format_xml_file(filename)
51 super().__init__(content)
52 self["Content-Type"] = "application/xml"
53 self["Content-Length"] = len(content)
54 self["Content-Disposition"] = "attachment; filename={}".format(os.path.basename(filename))
57class XmlResponse(HttpResponse):
58 def __init__(self, content: bytes, filename: str):
59 super().__init__(content)
60 self["Content-Type"] = "application/xml"
61 self["Content-Length"] = len(content)
62 self["Content-Disposition"] = "attachment; filename={}".format(os.path.basename(filename))
65class FormattedXmlResponse(XmlResponse):
66 def __init__(self, content: bytes, filename: str, encoding: str = "UTF-8", exceptions: bool = True):
67 super().__init__(format_xml_bytes(content, encoding=encoding, exceptions=exceptions), filename)