| 73 | """ |
| 74 | |
| 75 | def save(self, filename, content): |
| 76 | filename = super().save(filename, content) |
| 77 | orig_path = self.path(filename) |
| 78 | compressed_path = "%s.gz" % orig_path |
| 79 | |
| 80 | with open(orig_path, "rb") as f_in, open(compressed_path, "wb") as f_out: |
| 81 | with gzip.GzipFile(fileobj=f_out, mode="wb") as gz_out: |
| 82 | gz_out.write(f_in.read()) |
| 83 | |
| 84 | # Ensure the file timestamps match. |
| 85 | # os.stat() returns nanosecond resolution on Linux, but os.utime() |
| 86 | # only sets microsecond resolution. Set times on both files to |
| 87 | # ensure they are equal. |
| 88 | stamp = time.time() |
| 89 | os.utime(orig_path, (stamp, stamp)) |
| 90 | os.utime(compressed_path, (stamp, stamp)) |
| 91 | |
| 92 | return filename |
| 93 | |
| 94 | |
| 95 | class BrotliCompressorFileStorage(CompressorFileStorage): |