def _write_binary(self, instance, content): """ Do the actual writing of binary data to the table. This method is called after the model has been saved, and can therefore be used to insert data based on information which was not accessible in the save method on the model. """ cursor = connections[self.using].cursor() if not (hasattr(instance, "_created") and instance._created is True): cursor.execute("select checksum from files_attachment where id = %s", (instance.pk, )) new, orig = md5buffer(content), cursor.fetchone()[0] if new == orig: return # If still here, either the file is a new upload, # or it has changed. In either case, write the # file to the database. content.seek(0) blob_data = buffer(content.read()) instance.slug = slugify(instance.pre_slug) instance.checksum = md5buffer(content) cursor.execute("update files_attachment set blob = %s, slug = %s, \ checksum = %s where id = %s", (blob_data, instance.slug, instance.checksum, instance.pk)) transaction.commit_unless_managed(using=self.using)
def _write_binary(self, instance, content): """ Do the actual writing of binary data to the table. This method is called after the model has been saved, and can therefore be used to insert data based on information which was not accessible in the save method on the model. """ cursor = connections[self.using].cursor() if not (hasattr(instance, "_created") and instance._created is True): cursor.execute("select checksum from files_attachment where id = %s", (instance.pk, )) new, orig = md5buffer(content), cursor.fetchone()[0] if new == orig: return # If still here, either the file is a new upload, # or it has changed. In either case, write the # file to the database content.seek(0) blob_data = content.read() instance.slug = slugify(instance.pre_slug) instance.checksum = md5buffer(content) try: sid = transaction.savepoint(self.using) lobject = cursor.db.connection.lobject(0, "n", 0, None) lobject.write(blob_data) cursor.execute("update files_attachment set blob = %s, slug = %s, \ checksum = %s where id = %s", (lobject.oid, instance.slug, instance.checksum, instance.pk)) lobject.close() transaction.savepoint_commit(sid, using=self.using) except IntegrityError, e: transaction.savepoint_rollback(sid, using=self.using) raise e
def _open(self, name, mode="rb"): """ Return a File object. """ attachment = Attachment.objects.using(self.using).get(attachment__exact=name) fname = File(StringIO(attachment.blob), attachment.filename) # Make sure the checksum match before returning the file if not md5buffer(fname) == attachment.checksum: raise IntegrityError("Checksum mismatch") fname.size = attachment.size fname.mode = mode return fname
def _open(self, name, mode="rb"): """ Read the file from the database, and return as a File instance. """ attachment = Attachment.objects.using(self.using).get(attachment__exact=name) cursor = connections[self.using].cursor() lobject = cursor.db.connection.lobject(attachment.blob, "r") fname = File(StringIO(lobject.read()), attachment.filename) lobject.close() # Make sure the checksum match before returning the file if not md5buffer(fname) == attachment.checksum: raise IntegrityError("Checksum mismatch") fname.size = attachment.size fname.mode = mode return fname
def save(self, *args, **kwargs): """ Check what storage backend which are being used. If backend is any of the provided database backends, emit the `write_binary` signal to write the file to the blob field. """ # self.backend = 'PostgreSQLStorage' self.slug = slugify(self.pre_slug) if self.backend in ["PostgreSQLStorage", "MySQLStorage", "SQLiteStorage", "OracleStorage"]: # If using one of the included database backends, # save the instance and emit the `write_binary` signal # to write the binary data into the blob field. try: content = self.attachment.file super(Attachment, self).save(*args, **kwargs) write_binary.send(sender=Attachment, instance=self, content=content) except Exception as e: raise e elif self.backend == "FileSystemStorage": # If using the default FileSystemStorage, # save some extra attributes as well. if not self.pk: super(Attachment, self).save(*args, **kwargs) self.slug = slugify(self.pre_slug) self.checksum = md5buffer(self.attachment.file) super(Attachment, self).save(force_update=True) else: raise UnsupportedBackend("Unsupported storage backend.") # Send the post_write signal after save even if backend does not # use the write_binary method (such as the FileStorageBackend), to # keep consistancy between all backends. post_write.send(sender=Attachment, instance=self)
def checksum_match(self): """ If this is False, something fishy is going on. """ return md5buffer(self.attachment.file) == self.checksum
# to write the binary data into the blob field. try: content = self.attachment.file super(Attachment, self).save(*args, **kwargs) write_binary.send(sender=Attachment, instance=self, content=content) except Exception, e: raise e elif self.backend == "FileSystemStorage": # If using the default FileSystemStorage, # save some extra attributes as well. if not self.pk: super(Attachment, self).save(*args, **kwargs) self.slug = slugify(self.pre_slug) self.checksum = md5buffer(self.attachment.file) super(Attachment, self).save(force_update=True) else: raise UnsupportedBackend("Unsupported storage backend.") # Send the post_write signal after save even if backend does not # use the write_binary method (such as the FileStorageBackend), to # keep consistancy between all backends. post_write.send(sender=Attachment, instance=self) @property def pre_slug(self): """ Create a nice "semi unique" slug. This is not the real slug, only a helper method to create the string which is slugified. """ s = "-".join(
# If using one of the included database backends, # save the instance and emit the `write_binary` signal # to write the binary data into the blob field. try: content = self.attachment.file super(Attachment, self).save(*args, **kwargs) write_binary.send(sender=Attachment, instance=self, content=content) except Exception, e: raise e elif self.backend == "FileSystemStorage": # If using the default FileSystemStorage, # save some extra attributes as well. if not self.pk: super(Attachment, self).save(*args, **kwargs) self.slug = slugify(self.pre_slug) self.checksum = md5buffer(self.attachment.file) super(Attachment, self).save(force_update=True) else: raise UnsupportedBackend("Unsupported storage backend.") # Send the post_write signal after save even if backend does not # use the write_binary method (such as the FileStorageBackend), to # keep consistancy between all backends. post_write.send(sender=Attachment, instance=self) @property def pre_slug(self): """ Create a nice "semi unique" slug. This is not the real slug, only a helper method to create the string which is slugified. """ s = "-".join(map(str, (self.content_type, self.pk,