Last Update: 22.12.2006. By kerim in hddcleaner | python
I had the time do rework my hddcleaner a bit.
It’s now ready to be shown.
Performance has increased dramatically.
Scanning my c and d drives and displaying the results on windows xp using python 2.5 takes now only around 31 seconds.
Memory usage for the task maxes at 77 MB. Tested on a two partition drive with a total of aound 40 GB (some 4-5GB free)
It does what it is supposed to do.
As a default it will look in all drives (windows) or root(unix). You may specify a folder or drive as command line parameter e.g. “HDDCleaner c:\mydrive”
Ok, here is a final version ready for download as exe, python source or simply copy paste from below.
What would be nice for the future is a feature to sort the columns in the frame and to limit the filetypes that are looked for.
Next version perhaps ;)
*** binary dependencies *** Your executable(s) also depend on these dlls which are not included, you may or may not need to distribute them. Make sure you have the license if you distribute any of them, and make sure you don't distribute files belonging to the operating system. OLEAUT32.dll - C:\WINDOWS\system32\OLEAUT32.dll USER32.dll - C:\WINDOWS\system32\USER32.dll COMCTL32.dll - C:\WINDOWS\system32\COMCTL32.dll SHELL32.dll - C:\WINDOWS\system32\SHELL32.dll ole32.dll - C:\WINDOWS\system32\ole32.dll WINMM.dll - C:\WINDOWS\system32\WINMM.dll WSOCK32.dll - C:\WINDOWS\system32\WSOCK32.dll comdlg32.dll - C:\WINDOWS\system32\comdlg32.dll ADVAPI32.dll - C:\WINDOWS\system32\ADVAPI32.dll MSVCP71.dll - D:\Programmierung\python25\lib\site-packages\wx-2.8-msw-unicode \wx\MSVCP71.dll GDI32.dll - C:\WINDOWS\system32\GDI32.dll KERNEL32.dll - C:\WINDOWS\system32\KERNEL32.dll gdiplus.dll - D:\Programmierung\python25\lib\site-packages\wx-2.8-msw-unicode \wx\gdiplus.dll RPCRT4.dll - C:\WINDOWS\system32\RPCRT4.dll
SourceVersion:
Needed is wxPython and win32api optional
Source for copy paste:
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import sys, os, wx
from wx.lib.mixins.listctrl import CheckListCtrlMixin
from stat import *
ID_DELETE=100
def listDrives():
if sys.platform == 'win32':
try:
import win32api,string
drives=win32api.GetLogicalDriveStrings()
drives=string.splitfields(drives,'\000')
return drives
except: # in case PyWin is not present we do it the classical way
drives = []
for i in range(ord('a'), ord('z')+1):
drive = chr(i)
if(os.path.exists(drive +":\\")):
drives.append(drive+":\\")
return drives
def listFreeSpace(drive):
try:
if sys.platform == 'win32':
import win32api,string
info=win32api.GetDiskFreeSpaceEx(drive)
return info
except: # most probably pywin is not present
print "Unexpected error:", sys.exc_info()
def listFilesByName(listOfFiles,directory,files):
for fileName in files:
filepath = os.path.join(directory,fileName)
if os.path.isfile(filepath):
filesize = os.stat(filepath)[ST_SIZE]
listOfFiles[filepath] = filesize
def scan(directories):
listOfFiles = {}
for directory in directories:
sys.stdout.write('Scanning directory '+directory+'...\n')
directory = os.path.abspath(directory)
os.path.walk(directory,listFilesByName,listOfFiles)
sys.stdout.write('Done scanning all dirs. Now sorting and building GUI.\n')
allFiles = listOfFiles.items()
allFiles.sort(list_compare)
sortedList = allFiles
return sortedList
def list_compare(listX, listY):
if listX[1]>listY[1]:
return -1
elif listX[1]==listY[1]:
return 0
else: # x<y
return 1
class CheckListCtrl(wx.ListCtrl, CheckListCtrlMixin):
def __init__(self, parent):
wx.ListCtrl.__init__(self, parent, -1, style=wx.LC_REPORT)
CheckListCtrlMixin.__init__(self)
self.log = sys.stdout
self.Bind(wx.EVT_LIST_ITEM_ACTIVATED, self.OnItemActivated)
def OnItemActivated(self, evt):
self.ToggleItem(evt.m_itemIndex)
class FilesFrame(wx.Frame):
def __init__(self, parent, files):
wx.Frame.__init__(
self, parent, -1, "HDD Clean", size=(640,480)
)
p = wx.Panel(self, -1, style=0)
b = wx.Button(p, -1, "Delete...")
b.SetDefault()
self.Bind(wx.EVT_BUTTON, self.OnDelete, b)
self.files=files
self.list = CheckListCtrl(p)
sizer = wx.BoxSizer(wx.VERTICAL)
sizer.Add(b, 0, wx.EXPAND)
sizer.Add(self.list, 1, wx.EXPAND)
p.SetSizer(sizer)
self.list.InsertColumn(0, "Delete")
self.list.InsertColumn(1, "Size",wx.LIST_FORMAT_RIGHT)
self.list.InsertColumn(2, "File")
self.list.InsertColumn(3, "Type")
for i in self.files:
index = self.list.InsertStringItem(sys.maxint,"")
self.list.SetStringItem(index, 1, str(i[1]))
self.list.SetStringItem(index, 2, str(i[0]))
indexForFileType=str(i[0]).rfind(".")+1
filetype="None"
if indexForFileType!=0 and (len(str(i[0]))-indexForFileType<10):
filetype=str(i[0])[indexForFileType:]
self.list.SetStringItem(index, 3, filetype)
self.list.SetColumnWidth(0, wx.LIST_AUTOSIZE)
self.list.SetColumnWidth(1, wx.LIST_AUTOSIZE)
self.list.SetColumnWidth(2, wx.LIST_AUTOSIZE)
self.list.SetColumnWidth(3, wx.LIST_AUTOSIZE)
self.Show(1)
def OnDelete(self, evt):
items=self.list.GetItemCount()
allItems = range(0,items)
allItems.reverse()
for item in allItems:
if self.list.IsChecked(item):
listItem=self.list.GetItem(item,col=2)
self.list.DeleteItem(item)
os.remove(listItem.GetText())
myapp=wx.PySimpleApp()
files={}
if len(sys.argv)>1:
files=scan(sys.argv[1:])
else:
allDrives = listDrives()
if allDrives==None:
files = scan("/")
else:
files= scan(allDrives)
if len(files)>0:
FilesFrame(None,files)
myapp.MainLoop()
else:
print "No files found, exiting !"