-
-
Notifications
You must be signed in to change notification settings - Fork 31.6k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
newforms-admin: Merged from trunk up to [7814].
git-svn-id: http://code.djangoproject.com/svn/django/branches/newforms-admin@7815 bcc190cf-cafb-0310-a4f2-bffc1f526a37
- Loading branch information
Showing
42 changed files
with
2,319 additions
and
157 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
14 changes: 14 additions & 0 deletions
14
django/contrib/sitemaps/management/commands/ping_google.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
from django.core.management.base import BaseCommand | ||
from django.contrib.sitemaps import ping_google | ||
|
||
|
||
class Command(BaseCommand): | ||
help = "Ping google with an updated sitemap, pass optional url of sitemap" | ||
|
||
def execute(self, *args, **options): | ||
if len(args) == 1: | ||
sitemap_url = args[0] | ||
else: | ||
sitemap_url = None | ||
ping_google(sitemap_url=sitemap_url) | ||
|
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,66 @@ | ||
""" | ||
Portable file locking utilities. | ||
Based partially on example by Jonathan Feignberg <jdf@pobox.com> in the Python | ||
Cookbook, licensed under the Python Software License. | ||
http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/65203 | ||
Example Usage:: | ||
>>> from django.core.files import locks | ||
>>> f = open('./file', 'wb') | ||
>>> locks.lock(f, locks.LOCK_EX) | ||
>>> f.write('Django') | ||
>>> f.close() | ||
""" | ||
|
||
__all__ = ('LOCK_EX','LOCK_SH','LOCK_NB','lock','unlock') | ||
|
||
system_type = None | ||
|
||
try: | ||
import win32con | ||
import win32file | ||
import pywintypes | ||
LOCK_EX = win32con.LOCKFILE_EXCLUSIVE_LOCK | ||
LOCK_SH = 0 | ||
LOCK_NB = win32con.LOCKFILE_FAIL_IMMEDIATELY | ||
__overlapped = pywintypes.OVERLAPPED() | ||
system_type = 'nt' | ||
except (ImportError, AttributeError): | ||
pass | ||
|
||
try: | ||
import fcntl | ||
LOCK_EX = fcntl.LOCK_EX | ||
LOCK_SH = fcntl.LOCK_SH | ||
LOCK_NB = fcntl.LOCK_NB | ||
system_type = 'posix' | ||
except (ImportError, AttributeError): | ||
pass | ||
|
||
if system_type == 'nt': | ||
def lock(file, flags): | ||
hfile = win32file._get_osfhandle(file.fileno()) | ||
win32file.LockFileEx(hfile, flags, 0, -0x10000, __overlapped) | ||
|
||
def unlock(file): | ||
hfile = win32file._get_osfhandle(file.fileno()) | ||
win32file.UnlockFileEx(hfile, 0, -0x10000, __overlapped) | ||
elif system_type == 'posix': | ||
def lock(file, flags): | ||
fcntl.flock(file.fileno(), flags) | ||
|
||
def unlock(file): | ||
fcntl.flock(file.fileno(), fcntl.LOCK_UN) | ||
else: | ||
# File locking is not supported. | ||
LOCK_EX = LOCK_SH = LOCK_NB = None | ||
|
||
# Dummy functions that don't do anything. | ||
def lock(file, flags): | ||
pass | ||
|
||
def unlock(file): | ||
pass |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
""" | ||
Move a file in the safest way possible:: | ||
>>> from django.core.files.move import file_move_save | ||
>>> file_move_save("/tmp/old_file", "/tmp/new_file") | ||
""" | ||
|
||
import os | ||
from django.core.files import locks | ||
|
||
__all__ = ['file_move_safe'] | ||
|
||
try: | ||
import shutil | ||
file_move = shutil.move | ||
except ImportError: | ||
file_move = os.rename | ||
|
||
def file_move_safe(old_file_name, new_file_name, chunk_size = 1024*64, allow_overwrite=False): | ||
""" | ||
Moves a file from one location to another in the safest way possible. | ||
First, try using ``shutils.move``, which is OS-dependent but doesn't break | ||
if moving across filesystems. Then, try ``os.rename``, which will break | ||
across filesystems. Finally, streams manually from one file to another in | ||
pure Python. | ||
If the destination file exists and ``allow_overwrite`` is ``False``, this | ||
function will throw an ``IOError``. | ||
""" | ||
|
||
# There's no reason to move if we don't have to. | ||
if old_file_name == new_file_name: | ||
return | ||
|
||
if not allow_overwrite and os.path.exists(new_file_name): | ||
raise IOError("Cannot overwrite existing file '%s'." % new_file_name) | ||
|
||
try: | ||
file_move(old_file_name, new_file_name) | ||
return | ||
except OSError: | ||
# This will happen with os.rename if moving to another filesystem | ||
pass | ||
|
||
# If the built-in didn't work, do it the hard way. | ||
new_file = open(new_file_name, 'wb') | ||
locks.lock(new_file, locks.LOCK_EX) | ||
old_file = open(old_file_name, 'rb') | ||
current_chunk = None | ||
|
||
while current_chunk != '': | ||
current_chunk = old_file.read(chunk_size) | ||
new_file.write(current_chunk) | ||
|
||
new_file.close() | ||
old_file.close() | ||
|
||
os.remove(old_file_name) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,190 @@ | ||
""" | ||
Classes representing uploaded files. | ||
""" | ||
|
||
import os | ||
try: | ||
from cStringIO import StringIO | ||
except ImportError: | ||
from StringIO import StringIO | ||
|
||
__all__ = ('UploadedFile', 'TemporaryUploadedFile', 'InMemoryUploadedFile') | ||
|
||
class UploadedFile(object): | ||
""" | ||
A abstract uploadded file (``TemporaryUploadedFile`` and | ||
``InMemoryUploadedFile`` are the built-in concrete subclasses). | ||
An ``UploadedFile`` object behaves somewhat like a file object and | ||
represents some file data that the user submitted with a form. | ||
""" | ||
DEFAULT_CHUNK_SIZE = 64 * 2**10 | ||
|
||
def __init__(self, file_name=None, content_type=None, file_size=None, charset=None): | ||
self.file_name = file_name | ||
self.file_size = file_size | ||
self.content_type = content_type | ||
self.charset = charset | ||
|
||
def __repr__(self): | ||
return "<%s: %s (%s)>" % (self.__class__.__name__, self.file_name, self.content_type) | ||
|
||
def _set_file_name(self, name): | ||
# Sanitize the file name so that it can't be dangerous. | ||
if name is not None: | ||
# Just use the basename of the file -- anything else is dangerous. | ||
name = os.path.basename(name) | ||
|
||
# File names longer than 255 characters can cause problems on older OSes. | ||
if len(name) > 255: | ||
name, ext = os.path.splitext(name) | ||
name = name[:255 - len(ext)] + ext | ||
|
||
self._file_name = name | ||
|
||
def _get_file_name(self): | ||
return self._file_name | ||
|
||
file_name = property(_get_file_name, _set_file_name) | ||
|
||
def chunk(self, chunk_size=None): | ||
""" | ||
Read the file and yield chucks of ``chunk_size`` bytes (defaults to | ||
``UploadedFile.DEFAULT_CHUNK_SIZE``). | ||
""" | ||
if not chunk_size: | ||
chunk_size = UploadedFile.DEFAULT_CHUNK_SIZE | ||
|
||
if hasattr(self, 'seek'): | ||
self.seek(0) | ||
# Assume the pointer is at zero... | ||
counter = self.file_size | ||
|
||
while counter > 0: | ||
yield self.read(chunk_size) | ||
counter -= chunk_size | ||
|
||
def multiple_chunks(self, chunk_size=None): | ||
""" | ||
Returns ``True`` if you can expect multiple chunks. | ||
NB: If a particular file representation is in memory, subclasses should | ||
always return ``False`` -- there's no good reason to read from memory in | ||
chunks. | ||
""" | ||
if not chunk_size: | ||
chunk_size = UploadedFile.DEFAULT_CHUNK_SIZE | ||
return self.file_size < chunk_size | ||
|
||
# Abstract methods; subclasses *must* default read() and probably should | ||
# define open/close. | ||
def read(self, num_bytes=None): | ||
raise NotImplementedError() | ||
|
||
def open(self): | ||
pass | ||
|
||
def close(self): | ||
pass | ||
|
||
# Backwards-compatible support for uploaded-files-as-dictionaries. | ||
def __getitem__(self, key): | ||
import warnings | ||
warnings.warn( | ||
message = "The dictionary access of uploaded file objects is deprecated. Use the new object interface instead.", | ||
category = DeprecationWarning, | ||
stacklevel = 2 | ||
) | ||
backwards_translate = { | ||
'filename': 'file_name', | ||
'content-type': 'content_type', | ||
} | ||
|
||
if key == 'content': | ||
return self.read() | ||
elif key == 'filename': | ||
return self.file_name | ||
elif key == 'content-type': | ||
return self.content_type | ||
else: | ||
return getattr(self, key) | ||
|
||
class TemporaryUploadedFile(UploadedFile): | ||
""" | ||
A file uploaded to a temporary location (i.e. stream-to-disk). | ||
""" | ||
|
||
def __init__(self, file, file_name, content_type, file_size, charset): | ||
super(TemporaryUploadedFile, self).__init__(file_name, content_type, file_size, charset) | ||
self.file = file | ||
self.path = file.name | ||
self.file.seek(0) | ||
|
||
def temporary_file_path(self): | ||
""" | ||
Returns the full path of this file. | ||
""" | ||
return self.path | ||
|
||
def read(self, *args, **kwargs): | ||
return self.file.read(*args, **kwargs) | ||
|
||
def open(self): | ||
self.seek(0) | ||
|
||
def seek(self, *args, **kwargs): | ||
self.file.seek(*args, **kwargs) | ||
|
||
class InMemoryUploadedFile(UploadedFile): | ||
""" | ||
A file uploaded into memory (i.e. stream-to-memory). | ||
""" | ||
def __init__(self, file, field_name, file_name, content_type, charset, file_size): | ||
super(InMemoryUploadedFile, self).__init__(file_name, content_type, charset, file_size) | ||
self.file = file | ||
self.field_name = field_name | ||
self.file.seek(0) | ||
|
||
def seek(self, *args, **kwargs): | ||
self.file.seek(*args, **kwargs) | ||
|
||
def open(self): | ||
self.seek(0) | ||
|
||
def read(self, *args, **kwargs): | ||
return self.file.read(*args, **kwargs) | ||
|
||
def chunk(self, chunk_size=None): | ||
self.file.seek(0) | ||
yield self.read() | ||
|
||
def multiple_chunks(self, chunk_size=None): | ||
# Since it's in memory, we'll never have multiple chunks. | ||
return False | ||
|
||
class SimpleUploadedFile(InMemoryUploadedFile): | ||
""" | ||
A simple representation of a file, which just has content, size, and a name. | ||
""" | ||
def __init__(self, name, content, content_type='text/plain'): | ||
self.file = StringIO(content or '') | ||
self.file_name = name | ||
self.field_name = None | ||
self.file_size = len(content or '') | ||
self.content_type = content_type | ||
self.charset = None | ||
self.file.seek(0) | ||
|
||
def from_dict(cls, file_dict): | ||
""" | ||
Creates a SimpleUploadedFile object from | ||
a dictionary object with the following keys: | ||
- filename | ||
- content-type | ||
- content | ||
""" | ||
return cls(file_dict['filename'], | ||
file_dict['content'], | ||
file_dict.get('content-type', 'text/plain')) | ||
|
||
from_dict = classmethod(from_dict) |
Oops, something went wrong.