Jump to content
Deye

@Removing File\Folder clutter

Recommended Posts

Posted (edited)

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 ..

Only note that the DirMove and FileMove parts will actually move\Rename any prefixed naming into an none prefixed name, Only when the none prefixed file or folder Don't already exist, Possibly will get the Newest latest File or Dir renamed  and UnPrefixed because of Reading the sorted array backwards, No special checking or other implementations for the example at this time ..  Just a small kick start

For any added functionality, ideas, improvement, Bug, Other versions (with\without borrowed parts) .etc 

Be My Git ;)

 

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

$pattern = "*(?)*;*(??)*;*?-?Copy*"
$FOLDER = _WinAPI_ShellGetKnownFolderPath($FOLDERID_Downloads)

ConsoleWrite(@LF & " [Duplicate: File Clutter Preview] " & @LF)
_Files(_FileListToArrayRec($FOLDER, $pattern, 1, $FLTAR_NORECUR, $FLTAR_SORT, 2))

ConsoleWrite(@LF & " [Duplicate: Folder Clutter Preview]" & @LF)
_Dirs(_FileListToArrayRec($FOLDER, $pattern, 2, $FLTAR_RECUR, $FLTAR_SORT, 2))

ConsoleWrite(@LF)

Func _Files($aArray)

    Local $sFile, $sFile1, $FileExt, $aFiles2, $sarray = _ArrayToString($aArray, @LF)
    For $i = UBound($aArray) - 1 To 1 Step -1
        $sFile = StringRegExpReplace($aArray[$i], "\s\(.*\)|( - Copy)", "")
        If Not FileExists($sFile) Then
            ConsoleWrite(" Renaming " & $aArray[$i] & " to " & $sFile & @LF)
            FileMove($aArray[$i], $sFile, 9)
            $sarray = StringReplace($sarray, $aArray[$i], @LF)
            ContinueLoop
        EndIf
        $aFiles = StringRegExp($sarray, "(?i:.*\\" & StringRegExpReplace($sFile, "^.*\\|\..*$", "") & ").*", 3)

        If Compare_1($sFile, $aFiles[UBound($aFiles) - 1]) Then
            ConsoleWrite(" " & $aFiles[UBound($aFiles) - 1] & "  ==  " & $sFile & @LF)
        EndIf

        If UBound($aFiles) < 2 Then ContinueLoop

        $i -= UBound($aFiles)
        $s = _ArrayToString($aFiles, @LF)
        $FileExtMain = StringRegExpReplace($sFile, "^.*\.", ".$1")
        $aFiles2 = StringRegExp($s, ".*" & StringRegExpReplace($FileExtMain, "^.*\.", ".$1"), 3)

        ;looking for $aFiles2 files in $aFiles, where $aFiles may have files with no extention or other files with extra parts of $sFile

        For $j = UBound($aFiles) - 1 To 0 Step -1
            If $FileExt <> StringRegExpReplace($aFiles[$j], "^.*\.", ".$1") Then
                $FileExt = StringRegExpReplace($aFiles[$j], "^.*\.", ".$1")
                If $FileExt = $aFiles[$j] Then ; file has no extention
                    $aFiles2 = _ArrayExtract($aFiles, 0, $j)
                    $sFile1 = StringRegExpReplace($aFiles[$j], "\s\(.*\)|( - Copy)", "")
                    If Not FileExists($sFile1) Then
                        ConsoleWrite(" Renaming " & $aFiles[$j] & " to " & $sFile1 & @LF)
                        FileMove($aFiles[$j], $sFile1, 9)
                    EndIf
                    $FileExtMain = $sFile1
                    $FileExt = $sFile1
                    Compare_1($sFile1)
                Else
                    $aFiles2 = StringRegExp($s, ".*" & StringRegExpReplace($FileExt, "^.*\.", ".$1"), 3)
                EndIf
                If Compare_1("", $aFiles2[UBound($aFiles2) - 1]) Then
                    ConsoleWrite(" " & $aFiles2[UBound($aFiles2) - 1] & "  ==  " & ($sFile1 ? $sFile1 : $sFile) & @LF)
                EndIf
                If UBound($aFiles2) < 2 Then ContinueLoop
            EndIf
            For $k = UBound($aFiles2) - 1 To 0 Step -1
                If $FileExtMain = $FileExt Then
                    If Compare_1("", $aFiles2[$k]) Then
                        ConsoleWrite(" " & $aFiles2[$k] & "  ==  " & ($sFile1 ? $sFile1 : $sFile) & @LF)
                        ContinueLoop
                    EndIf
                EndIf
                Local $KHash = Compare_2($aFiles2[$k])
                For $f = $k - 1 To 0 Step -1
                    If $KHash = Compare_2($aFiles2[$f]) Then
                        ConsoleWrite(" " & (StringLen($aFiles2[$k]) < StringLen($aFiles2[$f]) ? $aFiles2[$f] : $aFiles2[$k]) & "  ==  " & (StringLen($aFiles2[$k]) > StringLen($aFiles2[$f]) ? $aFiles2[$f] : $aFiles2[$k]) & @LF)
                        ExitLoop
                    EndIf
                Next
            Next
            Compare_1($sFile)
            $FileExtMain = StringRegExpReplace($sFile, "^.*\.", ".$1")
            $sFile1 = ""
            $j -= UBound($aFiles2) - 1
        Next
    Next
EndFunc   ;==>_Files

Func _Dirs($aArray)
    Local $DirName, $Dirsize, $DirsizeX, $HashX
    For $i = UBound($aArray) - 1 To 1 Step -1
        $DirName = StringRegExpReplace($aArray[$i], "\s\(.*\)|( - Copy)", "")
        If Not FileExists($DirName) Then
            ConsoleWrite(" Moving " & $aArray[$i] & " ==> " & $DirName & @LF)
            DirMove($aArray[$i], $DirName)
            ContinueLoop
        EndIf
        If StringRegExpReplace($aArray[$i - 1], "\s\(.*\)|( - Copy)", "") = $DirName Then
            $Hash = _Hash($DirName)
            $Dirsize = DirGetSize($DirName)
            $x = $i
            While StringRegExpReplace($aArray[$x], "\s\(.*\)|( - Copy)", "") = $DirName
                If Not IsDeclared("Dirsize" & $x) Then Assign("Dirsize" & $x, DirGetSize($aArray[$x]))
                If $Dirsize = Eval("Dirsize" & $x) Then
                    If Not IsDeclared("Hash" & $x) Then Assign("Hash" & $x, _Hash($aArray[$x]))
                    If $Hash = Eval("Hash" & $x) Then
                        ConsoleWrite(" 1 " & $aArray[$x] & " == " & $DirName & @LF)
                        $x -= 1
                        ContinueLoop
                    EndIf
                EndIf
                $y = $x - 1
                While StringRegExpReplace($aArray[$y], "\s\(.*\)|( - Copy)", "") = $DirName
                    If Not IsDeclared("Dirsize" & $y) Then Assign("Dirsize" & $y, DirGetSize($aArray[$y]))
                    If Eval("Dirsize" & $x) = Eval("Dirsize" & $y) Then
                        If Not IsDeclared("Hash" & $y) Then Assign("Hash" & $y, _Hash($aArray[$y]))
                        If Eval("Hash" & $x) = Eval("Hash" & $y) Then
                            ConsoleWrite(" 1 " & $aArray[$x] & " == " & $aArray[$y] & @LF)
                        EndIf
                    EndIf
                    $y -= 1
                WEnd
                $x -= 1
                $i = $y
            WEnd
        EndIf
    Next
EndFunc   ;==>_Dirs

Func Compare_1($sStatic = "", $aFile = "")
    Local Static $sFile = "", $sFileSize, $CRC32, $MD5
    If $sStatic Then
        $sFile = $sStatic
        $sFileSize = FileGetSize($sFile)
        $CRC32 = _CRC32ForFile($sFile)
        $MD5 = _MD5ForFile($sFile)
    EndIf
    If $aFile And FileGetSize($aFile) = $sFileSize Then
        If $CRC32 == _CRC32ForFile($aFile) And $MD5 == _MD5ForFile($aFile) Then Return 1
    EndIf
EndFunc   ;==>Compare_1

Func Compare_2($aFile = "")
    Return _CRC32ForFile($aFile) & _MD5ForFile($aFile)
EndFunc   ;==>Compare_2

Func _Hash($DirName, $bRet = False)
    Local $Hash, $add
    Local $Array = _FileListToArrayRec($DirName, "*", 1, $FLTAR_RECUR, $FLTAR_SORT, 2)
    For $1 = UBound($Array) - 1 To 1 Step -1
        $Hash &= _CRC32ForFile($Array[$1]) & _MD5ForFile($Array[$1]) & @LF
    Next
    Return $Hash
EndFunc   ;==>_Hash

Func _MD5ForFile($sFile)
    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)
    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
Posted (edited)

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

  • 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...