<div dir="ltr">Hi,<br>i am now doing some prototypes for my projects which will be dealing with tones of files. After a little scouting i decided to try z3c.extfile. Every thing works fine. But i found it strange that there is no delete feature in z3c.extfile. ie, even if i can delete a ExtFile object, the file in the hash directory is not getting deleted! and it keeps on accumulating... <br>
<br>So i&nbsp; thought i &#39;ll add a delete feature... but&nbsp; my&nbsp; __del__() approach doesn&#39;t&nbsp; work for me. but i added an additional delete() function too which can be invoked explicitly to delete the file before trying to delete ExtFile object.<br>
<br>i made following&nbsp; changes to the source...<br>inside&nbsp; z3c.extfile.file.file.ExtFile,<br><br>----------------------------------------------------------------------------------------------<br>class ExtFile(Persistent):<br>
<br>&nbsp;&nbsp;&nbsp; &quot;&quot;&quot;A zope file implementation based on z3c.extfile&quot;&quot;&quot;<br><br>&nbsp;&nbsp;&nbsp; interface.implements(IExtFile)<br>&nbsp;&nbsp;&nbsp; data = ExtBytesProperty(&#39;data&#39;)<br>&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp; def __init__(self, data=&#39;&#39;, contentType=&#39;&#39;):<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; self.data = data<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; self.contentType = contentType<br><br>&nbsp;&nbsp;&nbsp; # added the following lines#<br><br><i>&nbsp;&nbsp;&nbsp; def __del__(self):&nbsp;&nbsp; # &lt;- this is not being invoked when i try to delete an extfile object<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; del self.data<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; #print &quot;deleted data via destructor&quot;<br><br>&nbsp;&nbsp;&nbsp; def delete(self):&nbsp;&nbsp;&nbsp;&nbsp; # &lt;- added this to be able to manually able to delete files<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; del self.data<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; #print &quot;deleted data via delete()&quot;<br>
<br>&nbsp;&nbsp;&nbsp; # # # # # # #&nbsp; # # # # # # #&nbsp; #<br></i>&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp; def getSize(self):<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return len(self.data)<br><br>----------------------------------------------------------------------------------------------<br><br>and the &#39;data&#39; is a &#39;property&#39;&nbsp; (ExtBytesProperty)<br>
so i made following changes to z3c.extfile.property.ExtBytesProperty<br><br>----------------------------------------------------------------------------------------------<br>class ExtBytesProperty(object):<br><br>&nbsp;&nbsp;&nbsp; &quot;&quot;&quot;a property which&#39;s values are stored as external files&quot;&quot;&quot;<br>
<br>&nbsp;&nbsp;&nbsp; def __init__(self, name):<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; self.__name = name<br><br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp; # added the following lines#<br><br><i>&nbsp;&nbsp;&nbsp; def __delete__(self,inst):<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; digest = inst.__dict__[self.__name]&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; self.hd.delete(digest)<br><br></i>&nbsp;&nbsp;&nbsp;  <i># # # # # # #&nbsp; # # # # # # #&nbsp; #<br><br><br><br></i>&nbsp;&nbsp;&nbsp; @property<br>&nbsp;&nbsp;&nbsp; def hd(self):<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return component.getUtility(interfaces.IHashDir)<br><br>&nbsp;&nbsp;&nbsp; def __get__(self, inst, klass):<br>
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if inst is None:<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return self<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; digest = inst.__dict__.get(self.__name, _marker)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if digest is _marker:<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return None<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return getFile(digest)<br><br>&nbsp;&nbsp;&nbsp; def __set__(self, inst, value):<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; # ignore if value is None<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if value is None:<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if inst.__dict__.has_key(self.__name):<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; del inst.__dict__[self.__name]<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; # Handle case when value is a string<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if isinstance(value, unicode):<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; value = value.encode(&#39;UTF-8&#39;)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if isinstance(value, str):<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; value = StringIO(value)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; value.seek(0)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; f = self.hd.new()<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; while True:<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; chunk = value.read(BLOCK_SIZE)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if not chunk:<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; newDigest = f.commit()<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; oldDigest = inst.__dict__.get(self.__name, _marker)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if newDigest == oldDigest:<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; # we have no change, so we have to seek to zero<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; # because this is normal behaviour when setting a<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; # new value<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if hasattr(_storage, &#39;dataManager&#39;):<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if newDigest in _storage.dataManager.files:<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; f = _storage.dataManager.files[newDigest]<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; f.seek(0)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; else:<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; inst.__dict__[self.__name] = newDigest<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; break<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; f.write(chunk)<br>----------------------------------------------------------------------------------------------------<br><br>and at last added the real code which delete the file in hash directory too<br>
<br>i added following codes inside z3c.extfile.hashdir.HashDir class<br>---------------------------------------------------<br>def delete(self,digest):<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &quot;&quot;&quot;delete the file&quot;&quot;&quot;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; path=self.getPath(digest)<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if os.path.exists(path):&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; os.remove(path)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return <br>----------------------------------------------------<br><br>Now, everything works fine when i try to delete an ExtFile object in ZODB, __del__() is not being invoked!!!!!<br>
<br>can anyone tell me how can i fix this??? <br><br>thanks in advance<br><br>jayaraj<br></div>