1"""Email backend that writes messages to a file.""" 2 3importdatetime 4importos 5 6fromplain.exceptionsimportImproperlyConfigured 7fromplain.runtimeimportsettings 8 9from.consoleimportEmailBackendasConsoleEmailBackend101112classEmailBackend(ConsoleEmailBackend):13def__init__(self,*args,file_path=None,**kwargs):14self._fname=None15iffile_pathisnotNone:16self.file_path=file_path17else:18self.file_path=getattr(settings,"EMAIL_FILE_PATH",None)19self.file_path=os.path.abspath(self.file_path)20try:21os.makedirs(self.file_path,exist_ok=True)22exceptFileExistsError:23raiseImproperlyConfigured(24f"Path for saving email messages exists, but is not a directory: {self.file_path}"25)26exceptOSErroraserr:27raiseImproperlyConfigured(28f"Could not create directory for saving email messages: {self.file_path} ({err})"29)30# Make sure that self.file_path is writable.31ifnotos.access(self.file_path,os.W_OK):32raiseImproperlyConfigured(33f"Could not write to directory: {self.file_path}"34)35# Finally, call super().36# Since we're using the console-based backend as a base,37# force the stream to be None, so we don't default to stdout38kwargs["stream"]=None39super().__init__(*args,**kwargs)4041defwrite_message(self,message):42self.stream.write(message.message().as_bytes()+b"\n")43self.stream.write(b"-"*79)44self.stream.write(b"\n")4546def_get_filename(self):47"""Return a unique file name."""48ifself._fnameisNone:49timestamp=datetime.datetime.now().strftime("%Y%m%d-%H%M%S")50fname=f"{timestamp}-{abs(id(self))}.log"51self._fname=os.path.join(self.file_path,fname)52returnself._fname5354defopen(self):55ifself.streamisNone:56self.stream=open(self._get_filename(),"ab")57returnTrue58returnFalse5960defclose(self):61try:62ifself.streamisnotNone:63self.stream.close()64finally:65self.stream=None