Jump to content

@Removing File\Folder clutter


Deye
 Share

Recommended Posts

Time to clean up my downloads folder So I made this little Demo that gets a preview of what duplicate files or folders with prefixes of  "\(.*\)" or "?-?Copy" are spread around My downloads folder 

Modern browsers falt is @not giving the Two needed separate options:
1  replace existing file ?
2  Download and create the file prefixed with a (#)    (Default ..)

Anyways ..

 

Spoiler
#include <WinAPIShellEx.au3>
#include <File.au3>

$pattern = "*(?)*;*(??)*;*?-?Copy*"
$FOLDER = _WinAPI_ShellGetKnownFolderPath($FOLDERID_Downloads)
ConsoleWrite(@LF & " [Duplicate: File Clutter Preview] " & @LF)
$aArray = _FileListToArrayRec($FOLDER, $pattern, 1, $FLTAR_NORECUR, $FLTAR_SORT, 2)
Local $aToDelete[""], $1, $2, $sFile, $sFileBareFormat, $istart, $index, $sArray = _ArrayToString($aArray, @LF, 1)
For $i = UBound($aArray) - 1 To 1 Step -1
    $sFile = StringRegExpReplace($aArray[$i], "\s\(.*\)|\(.*\)|( - Copy)", "")
    $sFileBareFormat = StringRegExpReplace($sFile, "^.*\\|\..*$", "")
    $aFiles = StringRegExp($sArray, "(?i:.*\\" & $sFileBareFormat & ")+[\s-()\QCopy\E].*", 3)
    If Not IsArray($aFiles) Then     ; if the StringRegExp is not optimized to get all variations
        If Not FileExists($sFile) Then
            ConsoleWrite(" Renaming " & $aArray[$i] & " to " & $sFile & @LF)
            ;FileMove($aFiles[$i], $sFile, 9)
        ElseIf Compare_2($aArray[$i]) == Compare_2($sFile) Then
            ConsoleWrite(" " & $aArray[$i] & " = " & $sFile & @LF)
            _ArrayAdd($aToDelete, $aArray[$i])
        EndIf
        ContinueLoop
    ElseIf UBound($aFiles) = 1 Then
        If Not FileExists($sFile) Then
            ConsoleWrite(" Renaming " & $aFiles[0] & " to " & $sFile & @LF)
            ;FileMove($aFiles[0], $sFile, 9)
        ElseIf Compare_2($aFiles[0]) == Compare_2($sFile) Then
            ConsoleWrite(" " & $aFiles[0] & " = " & $sFile & @LF)
            _ArrayAdd($aToDelete, $aFiles[0])
        EndIf
        ContinueLoop
    EndIf
    If UBound($aFiles) > 1 Then
        $i -= UBound($aFiles) - 1
        Local $aArray2D[UBound($aFiles)][3]
        For $j = 0 To UBound($aFiles) - 1
            $aArray2D[$j][0] = $aFiles[$j]
            $aArray2D[$j][1] = FileGetTime($aFiles[$j], 1, 1)
            $aArray2D[$j][2] = StringRegExp($aFiles[$j], "^.*\.") ? StringRegExpReplace($aFiles[$j], "^.*\.", ".$1") : "False"
        Next
        Local $sFileHash, $index = 0, $istart = $index, $KHash
        Do
            _ArraySort($aArray2D, 1, Default, Default, 2)    ;Get indexes of matching extentions
            $istart = $index
            $index = _ArraySearch($aArray2D, $aArray2D[$istart + 1][2], $istart + 1, Default, 1, Default, 0, 2)
            If @error Then ExitLoop
            $istart += $istart > 0 ? 1 : 0
            If $istart = $index Then
                If UBound($aArray2D) - 1 > $index Then $index += 1
                ContinueLoop
            EndIf
            _ArraySort($aArray2D, 0, $istart, $index, 1)  ;Sort indexes to latest file
            For $k = $index To $istart Step -1
                If Not FileExists($aArray2D[$k][0]) Then ContinueLoop
                $sFile = StringRegExpReplace($aArray2D[$k][0], "\s\(.*\)|\(.*\)|( - Copy)|\..*$", "")
                $sFile &= $aArray2D[$k][2] = "False" ? "" : $aArray2D[$k][2]
                If Not FileExists($sFile) Then
                    ConsoleWrite(" Renaming latest file " & $aArray2D[$k][0] & " to " & $sFile & @LF)
                    FileCopy($aArray2D[$k][0], StringRegExpReplace($sFile, "(^.*\\)(.*)", "\1"))
                    ;FileMove($aArray2D[$k][0], $sFile, 9)
                    ContinueLoop
                EndIf
                $sFileHash = Compare_2($sFile)
                $KHash = Compare_2($aArray2D[$k][0])
                For $f = $k - 1 To $istart Step -1
                    If Not FileExists($aArray2D[$f][0]) Then ContinueLoop
                    If $KHash = Compare_2($aArray2D[$f][0]) Then
                        $1 = StringLen($aArray2D[$f][0]) > StringLen($aArray2D[$k][0]) ? $aArray2D[$f][0] : $aArray2D[$k][0]
                        $2 = ($1 = $aArray2D[$f][0] ? $aArray2D[$k][0] : $aArray2D[$f][0])
                        ConsoleWrite(" " & $1 & " = " & $2 & @LF)
                        _ArrayAdd($aToDelete, $1)
                        ;FileDelete($1)
                        If $sFileHash = $KHash Then
                            ConsoleWrite(" " & $2 & " = " & $sFile & @LF)
                            ;FileDelete($2)
                            _ArrayAdd($aToDelete, $2)
                        EndIf
                        ExitLoop
                    EndIf
                Next
            Next
        Until $index = UBound($aArray2D) - 1
    EndIf
Next

_ArrayDisplay($aToDelete, "Files To Delete")

Func Compare_2($File = "")
;~  Return _CRC32ForFile($File) & _MD5ForFile($File) ;add this back to get real dups when done testing
    Return FileGetSize($File)
EndFunc   ;==>Compare_2

Func _MD5ForFile($sFile) ; by trancexx
    Local $a_hCall = DllCall("kernel32.dll", "hwnd", "CreateFileW", "wstr", $sFile, "dword", 0x80000000, "dword", 3, "ptr", 0, "dword", 3, "dword", 0, "ptr", 0)
    If @error Or $a_hCall[0] = -1 Then
        Return SetError(1, 0, "")
    EndIf
    Local $hFile = $a_hCall[0]
    $a_hCall = DllCall("kernel32.dll", "ptr", "CreateFileMappingW", "hwnd", $hFile, "dword", 0, "dword", 2, "dword", 0, "dword", 0, "ptr", 0)
    If @error Or Not $a_hCall[0] Then
        DllCall("kernel32.dll", "int", "CloseHandle", "hwnd", $hFile)
        Return SetError(2, 0, "")
    EndIf
    DllCall("kernel32.dll", "int", "CloseHandle", "hwnd", $hFile)
    Local $hFileMappingObject = $a_hCall[0]
    $a_hCall = DllCall("kernel32.dll", "ptr", "MapViewOfFile", "hwnd", $hFileMappingObject, "dword", 4, "dword", 0, "dword", 0, "dword", 0)
    If @error Or Not $a_hCall[0] Then
        DllCall("kernel32.dll", "int", "CloseHandle", "hwnd", $hFileMappingObject)
        Return SetError(3, 0, "")
    EndIf
    Local $pFile = $a_hCall[0]
    Local $iBufferSize = FileGetSize($sFile)
    Local $tMD5_CTX = DllStructCreate("dword i[2];" & "dword buf[4];" & "ubyte in[64];" & "ubyte digest[16]")
    DllCall("advapi32.dll", "none", "MD5Init", "ptr", DllStructGetPtr($tMD5_CTX))
    If @error Then
        DllCall("kernel32.dll", "int", "UnmapViewOfFile", "ptr", $pFile)
        DllCall("kernel32.dll", "int", "CloseHandle", "hwnd", $hFileMappingObject)
        Return SetError(4, 0, "")
    EndIf
    DllCall("advapi32.dll", "none", "MD5Update", "ptr", DllStructGetPtr($tMD5_CTX), "ptr", $pFile, "dword", $iBufferSize)
    If @error Then
        DllCall("kernel32.dll", "int", "UnmapViewOfFile", "ptr", $pFile)
        DllCall("kernel32.dll", "int", "CloseHandle", "hwnd", $hFileMappingObject)
        Return SetError(5, 0, "")
    EndIf
    DllCall("advapi32.dll", "none", "MD5Final", "ptr", DllStructGetPtr($tMD5_CTX))
    If @error Then
        DllCall("kernel32.dll", "int", "UnmapViewOfFile", "ptr", $pFile)
        DllCall("kernel32.dll", "int", "CloseHandle", "hwnd", $hFileMappingObject)
        Return SetError(6, 0, "")
    EndIf
    DllCall("kernel32.dll", "int", "UnmapViewOfFile", "ptr", $pFile)
    DllCall("kernel32.dll", "int", "CloseHandle", "hwnd", $hFileMappingObject)
    Local $sMD5 = Hex(DllStructGetData($tMD5_CTX, "digest"))
    Return SetError(0, 0, $sMD5)
EndFunc   ;==>_MD5ForFile
Func _CRC32ForFile($sFile) ; by trancexx
    Local $a_hCall = DllCall("kernel32.dll", "hwnd", "CreateFileW", "wstr", $sFile, "dword", 0x80000000, "dword", 3, "ptr", 0, "dword", 3, "dword", 0, "ptr", 0)
    If @error Or $a_hCall[0] = -1 Then
        Return SetError(1, 0, "")
    EndIf
    Local $hFile = $a_hCall[0]
    $a_hCall = DllCall("kernel32.dll", "ptr", "CreateFileMappingW", "hwnd", $hFile, "dword", 0, "dword", 2, "dword", 0, "dword", 0, "ptr", 0)
    If @error Or Not $a_hCall[0] Then
        DllCall("kernel32.dll", "int", "CloseHandle", "hwnd", $hFile)
        Return SetError(2, 0, "")
    EndIf
    DllCall("kernel32.dll", "int", "CloseHandle", "hwnd", $hFile)
    Local $hFileMappingObject = $a_hCall[0]
    $a_hCall = DllCall("kernel32.dll", "ptr", "MapViewOfFile", "hwnd", $hFileMappingObject, "dword", 4, "dword", 0, "dword", 0, "dword", 0)
    If @error Or Not $a_hCall[0] Then
        DllCall("kernel32.dll", "int", "CloseHandle", "hwnd", $hFileMappingObject)
        Return SetError(3, 0, "")
    EndIf
    Local $pFile = $a_hCall[0]
    Local $iBufferSize = FileGetSize($sFile)
    Local $a_iCall = DllCall("ntdll.dll", "dword", "RtlComputeCrc32", "dword", 0, "ptr", $pFile, "int", $iBufferSize)
    If @error Or Not $a_iCall[0] Then
        DllCall("kernel32.dll", "int", "UnmapViewOfFile", "ptr", $pFile)
        DllCall("kernel32.dll", "int", "CloseHandle", "hwnd", $hFileMappingObject)
        Return SetError(4, 0, "")
    EndIf
    DllCall("kernel32.dll", "int", "UnmapViewOfFile", "ptr", $pFile)
    DllCall("kernel32.dll", "int", "CloseHandle", "hwnd", $hFileMappingObject)
    Local $iCRC32 = $a_iCall[0]
    Return SetError(0, 0, Hex($iCRC32))
EndFunc   ;==>_CRC32ForFile

 

Deye

Edited by Deye
Typos
Link to comment
Share on other sites

Next Update :

This will probably need some extra proofing and\or method cleanups here and there 

So far, It will be good to know how does it work for you  does it get all duplicates @ any "presented folder" ?

Thanks

Deye

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

×
×
  • Create New...