|
1 """Email backend that writes messages to a file.""" |
|
2 |
|
3 import datetime |
|
4 import os |
|
5 |
|
6 from django.conf import settings |
|
7 from django.core.exceptions import ImproperlyConfigured |
|
8 from django.core.mail.backends.console import EmailBackend as ConsoleEmailBackend |
|
9 |
|
10 class EmailBackend(ConsoleEmailBackend): |
|
11 def __init__(self, *args, **kwargs): |
|
12 self._fname = None |
|
13 if 'file_path' in kwargs: |
|
14 self.file_path = kwargs.pop('file_path') |
|
15 else: |
|
16 self.file_path = getattr(settings, 'EMAIL_FILE_PATH',None) |
|
17 # Make sure self.file_path is a string. |
|
18 if not isinstance(self.file_path, basestring): |
|
19 raise ImproperlyConfigured('Path for saving emails is invalid: %r' % self.file_path) |
|
20 self.file_path = os.path.abspath(self.file_path) |
|
21 # Make sure that self.file_path is an directory if it exists. |
|
22 if os.path.exists(self.file_path) and not os.path.isdir(self.file_path): |
|
23 raise ImproperlyConfigured('Path for saving email messages exists, but is not a directory: %s' % self.file_path) |
|
24 # Try to create it, if it not exists. |
|
25 elif not os.path.exists(self.file_path): |
|
26 try: |
|
27 os.makedirs(self.file_path) |
|
28 except OSError, err: |
|
29 raise ImproperlyConfigured('Could not create directory for saving email messages: %s (%s)' % (self.file_path, err)) |
|
30 # Make sure that self.file_path is writable. |
|
31 if not os.access(self.file_path, os.W_OK): |
|
32 raise ImproperlyConfigured('Could not write to directory: %s' % self.file_path) |
|
33 # Finally, call super(). |
|
34 # Since we're using the console-based backend as a base, |
|
35 # force the stream to be None, so we don't default to stdout |
|
36 kwargs['stream'] = None |
|
37 super(EmailBackend, self).__init__(*args, **kwargs) |
|
38 |
|
39 def _get_filename(self): |
|
40 """Return a unique file name.""" |
|
41 if self._fname is None: |
|
42 timestamp = datetime.datetime.now().strftime("%Y%m%d-%H%M%S") |
|
43 fname = "%s-%s.log" % (timestamp, abs(id(self))) |
|
44 self._fname = os.path.join(self.file_path, fname) |
|
45 return self._fname |
|
46 |
|
47 def open(self): |
|
48 if self.stream is None: |
|
49 self.stream = open(self._get_filename(), 'a') |
|
50 return True |
|
51 return False |
|
52 |
|
53 def close(self): |
|
54 try: |
|
55 if self.stream is not None: |
|
56 self.stream.close() |
|
57 finally: |
|
58 self.stream = None |
|
59 |