Commit 58b704d8 authored by Jannis Leidel's avatar Jannis Leidel
Browse files

Fixed #10497 -- Added a few time-related methods to the storage API. Thanks...

Fixed #10497 -- Added a few time-related methods to the storage API. Thanks for the report and patch to Stephan Jaekel.

git-svn-id: http://code.djangoproject.com/svn/django/trunk@14012 bcc190cf-cafb-0310-a4f2-bffc1f526a37
parent 4d4d68a2
Loading
Loading
Loading
Loading
+31 −0
Original line number Diff line number Diff line
@@ -2,6 +2,7 @@ import os
import errno
import urlparse
import itertools
from datetime import datetime

from django.conf import settings
from django.core.exceptions import ImproperlyConfigured, SuspiciousOperation
@@ -120,6 +121,27 @@ class Storage(object):
        """
        raise NotImplementedError()

    def accessed_time(self, name):
        """
        Returns the last accessed time (as datetime object) of the file
        specified by name.
        """
        raise NotImplementedError()

    def created_time(self, name):
        """
        Returns the creation time (as datetime object) of the file
        specified by name.
        """
        raise NotImplementedError()

    def modified_time(self, name):
        """
        Returns the last modified time (as datetime object) of the file
        specified by name.
        """
        raise NotImplementedError()

class FileSystemStorage(Storage):
    """
    Standard filesystem storage
@@ -220,6 +242,15 @@ class FileSystemStorage(Storage):
            raise ValueError("This file is not accessible via a URL.")
        return urlparse.urljoin(self.base_url, name).replace('\\', '/')

    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_storage_class(import_path=None):
    if import_path is None:
        import_path = settings.DEFAULT_FILE_STORAGE
+27 −0
Original line number Diff line number Diff line
@@ -13,6 +13,33 @@ The local filesystem path where the file can be opened using Python's standard
``open()``. For storage systems that aren't accessible from the local
filesystem, this will raise ``NotImplementedError`` instead.

``Storage.accessed_time(name)``
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

.. versionadded:: 1.3

Returns a ``datetime`` object containing the last accessed time of the file.
For storage systems that aren't able to return the last accessed time, this
will raise ``NotImplementedError`` instead.

``Storage.created_time(name)``
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

.. versionadded:: 1.3

Returns a ``datetime`` object containing the creation time of the file.
For storage systems that aren't able to return the creation time, this
will raise ``NotImplementedError`` instead.

``Storage.modified_time(name)``
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

.. versionadded:: 1.3

Returns a ``datetime`` object containing the last modified time. For storage
systems that aren't able to return the last modified time, this will raise
``NotImplementedError`` instead.

``Storage.size(name)``
~~~~~~~~~~~~~~~~~~~~~~

+56 −5
Original line number Diff line number Diff line
@@ -6,6 +6,7 @@ import tempfile
import time
import unittest
from cStringIO import StringIO
from datetime import datetime, timedelta
from django.conf import settings
from django.core.exceptions import SuspiciousOperation
from django.core.files.base import ContentFile, File
@@ -108,6 +109,56 @@ class FileStorageTests(unittest.TestCase):
        self.storage.delete('storage_test')
        self.failIf(self.storage.exists('storage_test'))

    def test_file_accessed_time(self):
        """
        File storage returns a Datetime object for the last accessed time of
        a file.
        """
        self.failIf(self.storage.exists('test.file'))

        f = ContentFile('custom contents')
        f_name = self.storage.save('test.file', f)
        atime = self.storage.accessed_time(f_name)

        self.assertEqual(atime, datetime.fromtimestamp(
            os.path.getatime(self.storage.path(f_name))))
        self.assertTrue(datetime.now() - self.storage.accessed_time(f_name) < timedelta(seconds=2))
        self.storage.delete(f_name)

    def test_file_created_time(self):
        """
        File storage returns a Datetime object for the creation time of
        a file.
        """
        self.failIf(self.storage.exists('test.file'))

        f = ContentFile('custom contents')
        f_name = self.storage.save('test.file', f)
        ctime = self.storage.created_time(f_name)

        self.assertEqual(ctime, datetime.fromtimestamp(
            os.path.getctime(self.storage.path(f_name))))
        self.assertTrue(datetime.now() - self.storage.created_time(f_name) < timedelta(seconds=2))

        self.storage.delete(f_name)

    def test_file_modified_time(self):
        """
        File storage returns a Datetime object for the last modified time of
        a file.
        """
        self.failIf(self.storage.exists('test.file'))

        f = ContentFile('custom contents')
        f_name = self.storage.save('test.file', f)
        mtime = self.storage.modified_time(f_name)

        self.assertEqual(mtime, datetime.fromtimestamp(
            os.path.getmtime(self.storage.path(f_name))))
        self.assertTrue(datetime.now() - self.storage.modified_time(f_name) < timedelta(seconds=2))

        self.storage.delete(f_name)

    def test_file_save_without_name(self):
        """
        File storage extracts the filename from the content object if no