tags:

views:

177

answers:

3
#include <File.au3>
#include <Zip.au3>
#include <Array.au3>

; bad file extensions
Local $extData="ade|adp|app|asa|ashx|asp|bas|bat|cdx|cer|chm|class|cmd|com|cpl|crt|csh|der|exe|fxp|gadget|hlp|hta|htr|htw|ida|idc|idq|ins|isp|its|jse|ksh|lnk|mad|maf|mag|mam|maq|mar|mas|mat|mau|mav|maw|mda|mdb|mde|mdt|mdw|mdz|msc|msh|msh1|msh1xml|msh2|msh2xml|mshxml|msi|msp|mst|ops|pcd|pif|prf|prg|printer|pst|reg|rem|scf|scr|sct|shb|shs|shtm|shtml|soap|stm|url|vb|vbe|vbs|ws|wsc|wsf|wsh"
Local $extensions = StringSplit($extData, "|")

; What is the root directory?
$rootDirectory = InputBox("Root Directory", "Please enter the root directory...")

archiveDir($rootDirectory)

Func archiveDir($dir)

    $goDirs = True
    $goFiles = True

    ; Get all the files under the current dir
    $allOfDir = _FileListToArray($dir)
    $tmax = UBound($allOfDir)
    For $t = 0 to $tmax - 1
    Next

    Local $countDirs = 0
    Local $countFiles = 0

    $imax = UBound($allOfDir)
    For $i = 0 to $imax - 1
        If StringInStr(FileGetAttrib($dir & "\" & $allOfDir[$i]),"D") Then
            $countDirs = $countDirs + 1
        ElseIf StringInStr(($allOfDir[$i]),".") Then
            $countFiles = $countFiles + 1
        EndIf   
    Next

    If ($countDirs > 0) Then
        Local $allDirs[$countDirs]
        $goDirs = True
    Else
        $goDirs = False
    EndIf

    If ($countFiles > 0) Then
        Local $allFiles[$countFiles]
        $goFiles = True
    Else
        $goFiles = False
    EndIf

    $dirCount = 0
    $fileCount = 0

    For $i = 0 to $imax - 1
        If (StringInStr(FileGetAttrib($dir & "\" & $allOfDir[$i]),"D")) And ($goDirs == True) Then
            $allDirs[$dirCount] = $allOfDir[$i]
            $dirCount = $dirCount + 1
        ElseIf (StringInStr(($allOfDir[$i]),".")) And ($goFiles == True) Then
            $allFiles[$fileCount] = $allOfDir[$i]
            $fileCount = $fileCount + 1
        EndIf   
    Next

    ; Zip them if need be in current spot using 'ext_zip.zip' as file name, loop through each file ext.
    If ($goFiles == True) Then 
        $fmax = UBound($allFiles)
        For $f = 0 to $fmax - 1
            $currentExt = getExt($allFiles[$f])
            $position = _ArraySearch($extensions, $currentExt)
            If @error Then
                MsgBox(0, "Not Found", "Not Found")
            Else
                $zip = _Zip_Create($dir & "\" & $currentExt & "_zip.zip")
                _Zip_AddFile($zip, $dir & "\" & $allFiles[$f])
            EndIf
        Next
    EndIf

    ; Get all dirs under current DirCopy

    ; For each dir, recursive call from step 2

    If ($goDirs == True) Then
        $dmax = UBound($allDirs)
        $rootDirectory = $rootDirectory & "\"
        For $d = 0 to $dmax - 1
            archiveDir($rootDirectory & $allDirs[$d])
        Next
    EndIf

EndFunc

Func getExt($filename)

        $pos = StringInStr($filename, ".")
        $retval = StringTrimLeft($filename, $pos - 1)
        Return $retval

EndFunc

Updated, fixed a lot of bugs. Still not working. Like I said I have a list of 'bad' file extensions, this script should go through a directory of files (and subdirectories), and zip up (in separate zip files for each bad extension), all files WITH those bad extensions in the directories it finds them.

What is wrong???

+1  A: 

Two suggestions:

  1. Add MsgBox(0, "Zip", "Got here") inside your If ($currentExt == $extensions[$e]) Then. You should see that you are never getting there.
  2. Related to the above, your getExt function is not returning the correct value for the extension of the file.

UPDATE

You went a little too far with your edit to getExt.

Try this:

Func getExt($filename)
  $pos = StringInStr($filename, ".")
  $retval = StringTrimLeft($filename, $pos)
  Return $retval
EndFunc  


UPDATE 2

Regarding your problem where it doesn't process folders beyond the 2nd level, your issue is you are using $rootDirectory in your recursive call where you need to use $dir.

Change the last part of your archiveDir function to this:

  ; For each dir, recursive call from step 2
  If ($goDirs == True) Then
    $dmax = UBound($allDirs)
    $dir = $dir & "\"
    For $d = 0 to $dmax - 1
      archiveDir($dir & $allDirs[$d])
    Next
  EndIf
aphoria
I see that currently, however I am not sure why the method isn't returning the correct value...
Scott
+2  A: 

In the function StringTrimLeft("string", count), count is the number of characters to trim.

$filename = "filename.zip"

$pos = StringInStr($filename, ".") ; $pos will be equal to 9

so...

$retval = StringTrimLeft($filename, $pos + 1); this will remove 10 characters = ip
JohnForDummies
Scott
I'm about to head out the door, so I don't have time to look through this... but I wanted to tell you one thing, you could do away with your second For Loop by using _ArraySearch().$position = _ArraySearch($extensions, $currentExt)If it's not at Error, then you know you have an extension from your array.
JohnForDummies
Edit your question and show us the code changes you have made.
aphoria
A: 

I tried running your code as is, and sure enough, it failed. I then put a

MsgBox(0, "error", @error & " " & $currentExt)

in the "If @error" block to see if I could find out why it was failing. The result was the @error came back as 6. Looking into the documentation, it says that an error code of 6 means that the value searched for was not found in the array. And then the $currentExt told me it's value was set to ".asp".

The reason it could not be found was because there are no periods in the extension names in the array. If you look closer at the getExt() function, before you were adding 1 to the $position value... and now you are subtracting 1 from the value... Here's an illustration of how StringTrimLeft() works...

$filename = "filename.txt"

$pos = StringInStr($filename, ".") ; $pos will be equal to 9

$retval = StringTrimLeft($filename, $pos + 1); this will remove 10 characters = xt, that's too much.
$retval = StringTrimLeft($filename, $pos - 1); this will remove 8 characters = .txt, that's not enough.
$retval = StringTrimLeft($filename, $pos); this will remove 9 characters = txt, that's juuuuuuust right!

So the solution is to either add "." in front of all of the extensions in your array, or change your getExt() function:

Func getExt($filename)
    $pos = StringInStr($filename, ".")
    $retval = StringTrimLeft($filename, $pos)
    Return $retval
EndFunc

There is one more option you could look into, and that is using the _PathSplit() function found in File.au3, but since your script is so close to working at this point, I wouldn't worry about it, but maybe in the future you could use it instead.

And one last note... After I changed getExt() to drop the ".", your script ran great.

JohnForDummies
Did it run great for level 3 subdirectories though? That's where I ran into issues...
Scott
After making the changes that aphoria mentions in his second update, it works as expected.
JohnForDummies