Jump to content
Deye

@Removing File\Folder clutter

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

Share this post


Link to post
Share on other sites

Updated the $pattern so it will get any files without extensions too

None intended "Bug" left over Changed  FileListToArrayRec  to use $FLTAR_NORECUR to read only from the root Dir (Files part)

Edited by Deye

Share this post


Link to post
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

Share this post


Link to post
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

  • Recently Browsing   0 members

    No registered users viewing this page.

  • Similar Content

    • By argumentum
      by  eltorro Posted April 26, 2010
      Most print preview solutions use the MFC Doc/View architecture which limits it usefulness outside of c++. I found an article where a Delphi programmer used Enhanced Meta Files wrapped in a custom header and packaged together to create a print preview control. After a little more searching, It looks like using EMFs is a solution that would work.
      Some people suggest to create the document in Word or HTML and use Word or a browser to view it. Indeed, I have rendered documents to HTML and used the IE UDF to display the contents and/or print them. Not quite as ideal as one would like.
      Using GRS's printwin.au3 as a start, I came up with a print preview solution which others may be able to expand upon
    • By MrCreatoR
      This utility allows to preview image file by holding down left (main) mouse button on selected file in explorer window (or on desktop).

      Notes:

      Tested on Win 7/Win XP Rus Professional. If Tray icon is hidden, use «Ctrl + Shift + Q» to exit the program. Screenshot:


      Changelog:




      Download:
      SIP.zip (Counter: )
×
×
  • Create New...