Skip navigation

Help with making a program recursive

683 Views 8 Replies Latest reply: Aug 6, 2012 2:03 PM by OutWeRoll RSS
OutWeRoll Calculating status...
Currently Being Moderated
Aug 2, 2012 10:45 AM

I was trying to add file extensions to some files on my old mac and the only solution I found was this applescript on this website:

http://techierambles.blogspot.com/2009/03/applescript-to-automatically-add-file. html

 

here's the code formatted correctly:

(*
EPSF (eps), AI (ai), PDF (pdf), ART5 is Illustrator

indd = Creator: InDn, Type: IDd5
indd = Creator: InDn, Type: IDd4
ai = Creator: ART5, Type: PDF
eps = Creator: ART5, Type: EPSF
psd = Creator: 8BIM, Type: 8BPS
pdf = Creator: CARO, Type: PDF
jpg = Creator: 8BIM, Type: JPEG
eps = Creator: 8BIM, Type: EPSF
qxd = Creator: XPR3, Type: XPRJ
tif = Creator: 8BIM, Type: TIFF
*)

-- THESE PROPERTIES ARE FOR THE NOTIFICATION ROUTINE
-- if true, the script will speak the alert. If false, the script will 
--display an alert

property speak_alert : false

-- set the amount of time before dialogs auto-answer.dialog
property dialog_timeout : 30

-- THIS PROPERTY IS USED TO INDICATE WHETHER THE SCRIPT 
--CHECKS THE INCOMING FILES FOR COMPLETED TRANSFER
-- SET THIS PROPERTY TO TRUE FOR FOLDERS SHARED VIA 
--FILE SHARING
-- NOTE THAT ITEMS DROPPED IN SHARED FOLDERS WILL 
--HAVE THEIR LABEL SET TO 7

property copy_checks_indicator : false

-- THESE PROPERTIES ARE FOR THE STATUS CHECKING 
--ROUTINES
property item_check_delay_time : 2
property folder_check_delay_time : 3
property special_label_index : 7

on adding folder items to this_folder after receiving added_items
     try
          
          if copy_checks_indicator is true then
               -- CHECK THE FILES TO MAKE SURE THEY'RE 
               --COMPLETELY AVAILABLE
               
               set the added_items to my check_added_items(the added_items)
               
               if the added_items is {} then return "no valid items"
          end if
          
          tell application "Finder"
               --get the name of the folder
               set this_folder_name to the name of this_folder
          end tell
          
          -- find out how many new items have been placed in the folder
          set new_item_count to the number of items in the added_items
          
          tell application "Finder"
               repeat with x in added_items
                    copy name of x as string to FileName
                    copy file type of x as string to FileType
                    copy creator type of x as string to FileCreator
                    
                    -- check for Quark
                    if FileType is "XPRJ" and FileCreator is "XPR3" then
                         if FileName does not end with ".qxd" then
                              set Suffix to ".qxd"
                              set the name of x to FileName & Suffix
                         end if
                         
                    else if FileType is "XDOC" and FileCreator is "XPR3" then
                         if FileName does not end with ".qxd" then
                              set Suffix to ".qxd"
                              set the name of x to FileName & Suffix
                         end if
                         
                         -- check for Illustrator ai
                    else if FileType is "PDF" and FileCreator is "ART5" then
                         if FileName does not end with ".ai" then
                              set Suffix to ".ai"
                              set the name of x to FileName & Suffix
                         end if
                         
                         -- check for InDesign 
                    else if FileType is "InDn" and FileCreator is "IDd5" then
                         if FileName does not end with ".indd" then
                              set Suffix to ".indd"
                              set the name of x to FileName & Suffix
                         end if
                         
                         --check for InDesign CS2
                    else if FileType is "InDn" and FileCreator is "IDd4" then
                         if FileName does not end with ".indd" then
                              set Suffix to ".indd"
                              set the name of x to FileName & Suffix
                         end if
                         
                         -- check for Illustrator eps
                    else if FileType is "EPSF" and FileCreator is "ART5" then
                         if FileName does not end with ".eps" then
                              set Suffix to ".eps"
                              set the name of x to FileName & Suffix
                         end if
                         
                         -- check for Photoshop psd
                    else if FileType is "8BPS" and FileCreator is "8BIM" then
                         if FileName does not end with ".psd" then
                              set Suffix to ".psd"
                              set the name of x to FileName & Suffix
                         end if
                         
                         -- check for Photoshop tif
                    else if FileType is "TIFF" and FileCreator is "8BIM" then
                         if FileName does not end with ".tif" then
                              set Suffix to ".tif"
                              set the name of x to FileName & Suffix
                         end if
                         
                         -- check for Photoshop jpg
                    else if FileType is "JPEG" and FileCreator is "8BIM" then
                         if FileName does not end with ".jpg" then
                              set Suffix to ".jpg"
                              set the name of x to FileName & Suffix
                         end if
                         
                         -- check for pdf
                    else if FileType is "PDF" and FileCreator is "CARO" then
                         if FileName does not end with ".pdf" then
                              set Suffix to ".pdf"
                              set the name of x to FileName & Suffix
                         end if
                         
                    end if
               end repeat
          end tell
          
     end try
     
end adding folder items to

on remove_labels(the added_items)
     tell application "Finder"
          repeat with this_item in the added_items
               set the label index of this_item to 0
          end repeat
     end tell
end remove_labels

on check_added_items(the added_items)
     -- check the transfer status of every added file to determine
     -- if each file has completed being moved into the 
     --attached folder
     
     set the notbusy_items to {}
     repeat with i from 1 to the number of items in the added_items
          set this_item to (item i of the added_items)
          if my check_busy_status(this_item) is false then
               set the end of the notbusy_items to this_item
          end if
     end repeat
     return the notbusy_items
end check_added_items

on check_busy_status(this_item)
     -- a folder can contain items partially transfered
     -- this routine will wait for all the folder contents to transfer
     
     if the last character of (this_item as text) is ":" then
          set the check_flag to false
          repeat
               
               -- look for any files within the folder that are still transferring
               tell application "Finder"
                    try
                         set the busy_items to the name of every file of the entire contents of this_item whose file type begins with "bzy"
                         
                    on error
                         set the busy_items to {}
                    end try
               end tell
               
               if the check_flag is true and the busy_items is {} then return false
               
               -- pause for the indicated time
               delay the folder_check_delay_time
               
               -- set the flag and check again
               set the check_flag to true
          end repeat
          
     else
          -- the passed item is a single file, suitcase, clipping, etc.
          -- check the label of the item. If it is the marked label 
          --then it's already been processed so ignore.
          
          tell application "Finder"
               if (the label index of this_item) as integer is the special_label_index then
                    return "ignore"
                    
               end if
          end tell
          
          set the check_flag to false
          repeat
               tell application "Finder"
                    set the item_file_type to the file type of this_item
               end tell
               
               if the check_flag is true and the item_file_type does not start with "bzy" then
                    
                    tell application "Finder"
                         set the label index of this_item to the special_label_index
                    end tell
                    
                    -- allow the Finder time to change the label
                    delay the item_check_delay_time
                    return false
                    
               else if the item_file_type does not start with "bzy" then
                    -- set the flag and check again
                    
                    set the check_flag to true
               end if
               
               -- pause for the indicated time
               delay the item_check_delay_time
          end repeat
     end if
end check_busy_status

--HANDLER FOR KEEPING THIS FOLDER OPEN

--To activate the handler, remove the comment 
--markers (the parens and asterisks)
--at the beginning and end of the following handler 
--and save this script.

(*
on closing folder window for this_folder
beep
tell application "Finder"
open this_folder
end tell
end closing folder window for
*)

It works well and does exactly what I want when I make it a folder action to a folder and then put files into it. The only problem is that if I put a folder into the folder it doesn't work. The files inside the folder aren't affected and don't have a file extension added to them. I have hundreds and hundreds of files all within subfolders. Does anyone know how to make this program recursive so that files within folders will be affected too. I know nothing about applescript and am really up the creek if I can't get this working. Any help is appreciated.

  • Camelot Level 8 Level 8 (45,670 points)
    Currently Being Moderated
    Aug 2, 2012 12:25 PM (in response to OutWeRoll)

    It's not quite clear what direction you're trying to take here.

     

    Are you trying to apply this script to all the files already on disk? or are you trying to get the folder action to apply to all subfolders, too? Because the solution is radically different.

     

    Folder Actions only ever apply to the folder they are attached to. Never to sub-folders.

    To get the Folder Action to apply to subfolders you have to attach it to those subfolders. Only then will files dropped in the subfolders get the script applied.

     

    So, if you want your script to run across all the existing files, that's pretty easy.

    If you want the Folder Action to be applied to subfolders you need to amend the rule so that it identifies new folders added to this folder (so that it can attach the folder action to the new folder) and then apply the Folder Action to script to every folder so that it runs when a file is dropped in any of those folders.

     

    So... which is it? or it is both?

  • Camelot Level 8 Level 8 (45,670 points)
    Currently Being Moderated
    Aug 2, 2012 2:00 PM (in response to OutWeRoll)

    One last question, for now...

     

    If I read your original post correctly, you current drop files into this folder and they're processed, correct?

    And that you want to drop a folder into this folder and have the files within that folder processed... is that correct?

     

    If so, does the folder just contain files? or does it (can it?) contain other folders?

    If it just contains files then it's simple. If it contains folders it gets a little more complex.

    One twist on that is what the 'typical' number of files in a folder is? It is tens? hundreds? thousands?

    The reason I ask is that it may be simpler to just have the Finder scan the folder for all files, rather than turn the script into a recursive script, but the Finder isn't efficient on large folders containing hundreds or thousands of files.

     

    So, if a folder just contains a few files, it's easy.

    If a folder contains sub-folders, but the total number of files isn't that great, it's pretty simple.

    If a folder contains many many sub-folders, totalling thousands of files, its gets more complex, but still do-able.

  • twtwtw Level 5 Level 5 (4,580 points)
    Currently Being Moderated
    Aug 2, 2012 3:56 PM (in response to OutWeRoll)

    a basic template for recursive file system handlers is as follows:

     

    on recursiveHandler(fRef)

      -- assumes fRef is a posix path to a folder

              tell application "System Events"

                        repeat with thisItem in files of folder fRef

      -- process files here

                        end repeat

                        repeat with thisfolder in folders of folder fRef

      -- loop through contents of sub folders

                                  my recursiveHandler(POSIX path of thisfolder)

                        end repeat

              end tell

    end recursiveHandler

     

    You'll have to adapt it to your needs, but it's pretty self-evident - feed it a posix path to a folder, and it runs through the contents processing files and recursing into folders.

  • twtwtw Level 5 Level 5 (4,580 points)
    Currently Being Moderated
    Aug 6, 2012 1:10 PM (in response to OutWeRoll)

    Well, getting rid of excess code and rewriting the routine more compactly, it looks like this:

     

    property transforms : {{FileType:"XPRJ", creator:"XPR3", extension:".qxd"}, {FileType:"XDOC", creator:"XPR3", extension:".qxd"}, {FileType:"PDF", creator:"ART5", extension:".ai"}, {FileType:"InDn", creator:"IDd5", extension:".indd"}, {FileType:"InDn", creator:"IDd4", extension:".indd"}, {FileType:"EPSF", creator:"ART5", extension:".eps"}, {FileType:"8BPS", creator:"8BIM", extension:".psd"}, {FileType:"TIFF", creator:"8BIM", extension:".tif"}, {FileType:"JPEG", creator:"8BIM", extension:".jpg"}, {FileType:"PDF", creator:"CARO", extension:".pdf"}}

     

    on adding folder items to this_folder after receiving added_items

              repeat with this_item in added_items

      recursiveHandler(POSIX path of this_item)

              end repeat

    end adding folder items to

     

    on recursiveHandler(anItem)

      -- assumes fRef is a posix path to a folder

              tell application "System Events"

                        if class of disk item anItem is folder then

                                  set theItems to (disk items of folder anItem whose visible is true)

                                  repeat with thisItem in theItems

                                            my recursiveHandler(POSIX path of thisItem)

                                  end repeat

                        else

                                  my changeExtensionFromFileType(alias anItem)

                        end if

              end tell

    end recursiveHandler

     

    on changeExtensionFromFileType(x)

              tell application "System Events"

                        copy name of x as string to FileName

                        copy file type of x as string to FileType

                        copy creator type of x as string to FileCreator

                        repeat with transformRecord in my transforms

                                  if FileType is FileType of transformRecord and FileCreator is creator of transformRecord and FileName does not end with extension of transformRecord then

                                            set the name of x to (FileName & extension of transformRecord)

                                            exit repeat

                                  end if

                        end repeat

              end tell

    end changeExtensionFromFileType

     

    (note that I wrote the recursive handler in a somewhat different form, but the principle is the same)

     

    Keep in mind that file type and creator are holdovers from os 9, so they may not be included in more modern files.

Actions

More Like This

  • Retrieving data ...

Bookmarked By (0)

Legend

  • This solved my question - 10 points
  • This helped me - 5 points
This site contains user submitted content, comments and opinions and is for informational purposes only. Apple disclaims any and all liability for the acts, omissions and conduct of any third parties in connection with or related to your use of the site. All postings and use of the content on this site are subject to the Apple Support Communities Terms of Use.