97 lines
		
	
	
		
			3.0 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
			
		
		
	
	
			97 lines
		
	
	
		
			3.0 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
| from __future__ import unicode_literals
 | |
| import errno
 | |
| import gzip
 | |
| import os
 | |
| from datetime import datetime
 | |
| import time
 | |
| 
 | |
| from django.core.files.storage import FileSystemStorage, get_storage_class
 | |
| from django.utils.functional import LazyObject, SimpleLazyObject
 | |
| 
 | |
| from compressor.conf import settings
 | |
| 
 | |
| 
 | |
| class CompressorFileStorage(FileSystemStorage):
 | |
|     """
 | |
|     Standard file system storage for files handled by django-compressor.
 | |
| 
 | |
|     The defaults for ``location`` and ``base_url`` are ``COMPRESS_ROOT`` and
 | |
|     ``COMPRESS_URL``.
 | |
| 
 | |
|     """
 | |
|     def __init__(self, location=None, base_url=None, *args, **kwargs):
 | |
|         if location is None:
 | |
|             location = settings.COMPRESS_ROOT
 | |
|         if base_url is None:
 | |
|             base_url = settings.COMPRESS_URL
 | |
|         super(CompressorFileStorage, self).__init__(location, base_url,
 | |
|                                                     *args, **kwargs)
 | |
| 
 | |
|     def accessed_time(self, name):
 | |
|         return datetime.fromtimestamp(os.path.getatime(self.path(name)))
 | |
| 
 | |
|     def created_time(self, name):
 | |
|         return datetime.fromtimestamp(os.path.getctime(self.path(name)))
 | |
| 
 | |
|     def modified_time(self, name):
 | |
|         return datetime.fromtimestamp(os.path.getmtime(self.path(name)))
 | |
| 
 | |
|     def get_available_name(self, name, max_length=None):
 | |
|         """
 | |
|         Deletes the given file if it exists.
 | |
|         """
 | |
|         if self.exists(name):
 | |
|             self.delete(name)
 | |
|         return name
 | |
| 
 | |
|     def delete(self, name):
 | |
|         """
 | |
|         Handle deletion race condition present in Django prior to 1.4
 | |
|         https://code.djangoproject.com/ticket/16108
 | |
|         """
 | |
|         try:
 | |
|             super(CompressorFileStorage, self).delete(name)
 | |
|         except OSError as e:
 | |
|             if e.errno != errno.ENOENT:
 | |
|                 raise
 | |
| 
 | |
| 
 | |
| compressor_file_storage = SimpleLazyObject(
 | |
|     lambda: get_storage_class('compressor.storage.CompressorFileStorage')())
 | |
| 
 | |
| 
 | |
| class GzipCompressorFileStorage(CompressorFileStorage):
 | |
|     """
 | |
|     The standard compressor file system storage that gzips storage files
 | |
|     additionally to the usual files.
 | |
|     """
 | |
|     def save(self, filename, content):
 | |
|         filename = super(GzipCompressorFileStorage, self).save(filename, content)
 | |
|         orig_path = self.path(filename)
 | |
|         compressed_path = '%s.gz' % orig_path
 | |
| 
 | |
|         f_in = open(orig_path, 'rb')
 | |
|         f_out = open(compressed_path, 'wb')
 | |
|         try:
 | |
|             f_out = gzip.GzipFile(fileobj=f_out)
 | |
|             f_out.write(f_in.read())
 | |
|         finally:
 | |
|             f_out.close()
 | |
|             f_in.close()
 | |
|             # Ensure the file timestamps match.
 | |
|             # os.stat() returns nanosecond resolution on Linux, but os.utime()
 | |
|             # only sets microsecond resolution.  Set times on both files to
 | |
|             # ensure they are equal.
 | |
|             stamp = time.time()
 | |
|             os.utime(orig_path, (stamp, stamp))
 | |
|             os.utime(compressed_path, (stamp, stamp))
 | |
| 
 | |
|         return filename
 | |
| 
 | |
| 
 | |
| class DefaultStorage(LazyObject):
 | |
|     def _setup(self):
 | |
|         self._wrapped = get_storage_class(settings.COMPRESS_STORAGE)()
 | |
| 
 | |
| default_storage = DefaultStorage()
 | 
