Hey All,
I’ve been working on this for a couple days and tried many different approaches (some of which were unnecessarily complicated) and the script itself may contain some unnecessary variables that I have yet to clean out. Anyway, this is supposed to be a backup script that will backup a folder or multiple folders and all their contents if it has not been backed up before and then will only backup any file therein that has been modified. The script works basically, but I wanted to make it a stay open app that would do its thing at a certain time of the day. When I added the on idle handler, and the app activates, it starts fine but ends up erroring saying that the variable “mainName” is not defined. If I move the on idle statement to just under the property declaration, then it has the same error but with a different variable. Is this error because of the call to the recursion handler and returning some sort of conflicting info or what? Thank you all.
PreTech
property backupList : {}
global foldCont, primeName, foldPath, filePath, testDate, thePath, thisPath, theDate, theTime, mainFold, theName, classCheck
set dun to 0
set astid to AppleScript's text item delimiters
set arch to "untitled archive.sit"
set tempList to {}
set tNames to {}
set iList to {}
set iNames to {}
set bMainNames to {}
set mainName to {}
set theName to ""
set backList to {}
set foldCont to {}
set bName to {}
set classCheck to {}
set searchCont to {}
set searchContName to {}
set theTime to time of (current date)
set testDate to ((current date) - theTime) -- Sets the test time to 12 AM of the current day. If modification date (time) of a file is greater than this, it is backed up.
tell (current date) to tell (its month as string) & year * 100 + day to set theDate to text -2 thru -1 & text 1 thru 3 & text -4 thru -3
-- I believe thanks go to kai for the preceeding line.
on idle
if theTime is greater than 43200 then
tell application "Finder"
-- set initial destination for backup
if not (exists folder "theBackupFolder" of desktop) then
make new folder at desktop with properties {name:"theBackupFolder"}
set label index of folder "theBackupFolder" to 4
end if
-- set final destination for backup
if not (exists folder "compressedFolders" of desktop) then
make new folder at desktop with properties {name:"compressedFolders"}
set label index of folder "compressedFolders" to 4
end if
set destFold to folder "compressedFolders" of desktop
-- choose to run the backup, search for files previously backed up, or quit.
display dialog "What do you need to do?" buttons {"Search", "Backup", "Cancel"} default button 2 giving up after 10
set buttChoice to button returned of the result
if buttChoice is "Search" or "" then
display dialog "Enter partial, or complete, file name to search for." default answer ""
set search to text returned of the result
repeat with aFile in destFold
set theName to name of aFile
if theName contains search then
set searchCont's end to aFile as alias
set searchContName's end to theName
end if
end repeat
try
set choice to choose from list searchContName with prompt "Choose files to retrieve." with multiple selections allowed
on error
display dialog "Sorry, nothing matching " & "\"" & search & "\"" & " was found."
end try
if choice is not false then
set theDate to (current date)
set m to month of theDate as text
set d to day of theDate
set t to time of theDate as text
make new folder at desktop with properties {name:m & d & t}
repeat with choiceItem in choice
repeat with anItem in searchCont
set thisName to name of anItem
if thisName is (choiceItem as text) then
copy anItem to folder (m & d & t) of desktop
end if
end repeat
end repeat
end if
else if buttChoice is "Cancel" then
quit me
else
-- if continuing with backup, this sets up to add or remove folders from the backup list or to continue with the folders already designated.
display dialog "Do you need to add or remove more folders for backup?" & return & return & "If you have not used this program before, click add to setup folders for backup." buttons {"Add", "Remove", "Continue"} default button "Continue" giving up after 10
set butChoice to button returned of the result
if butChoice is not "Continue" then
if butChoice is "Add" then
choose folder with prompt "Choose folders for addition." with multiple selections allowed
set addList to result
repeat with anItem in addList
set backupList's end to anItem
end repeat
else if butChoice is "Remove" then
if backupList is not {} then
choose from list backList with prompt "Choose folders to remove." with multiple selections allowed
set removeList to result
repeat with anItem in backupList
if name of anItem is not in removeList then
set tempList to tempList & anItem
end if
end repeat
set backupList to tempList
else
display dialog "There are no folders in the Backup List to remove."
end if
end if
end if
-- get the names of all folders for backup
repeat with aName in backupList
set mainName's end to name of aName
repeat with folName in aName
set backList's end to name of folName
end repeat
end repeat
set thisPath to folder "theBackupFolder" of desktop as string
-- if the initial backup folder destination has files then this sets a list of all folders in the backup folder.
if entire contents of folder "theBackupFolder" of desktop is not {} then
repeat with bFold in folder "theBackupFolder" of desktop
set bMainNames's end to name of bFold
repeat with backName in bFold
set bName's end to name of backName
end repeat
end repeat
end if
-- start the process of getting folders and files out of the folder needing backup.
repeat with aFolder in backupList
-- this gets a folder of one of the folders for backing up.
repeat with anFold in aFolder
set theFold to anFold as alias
-- if a folder has never been backed up, then this backs up the entire folder.
if (name of theFold) is not in bMainNames then
duplicate theFold to thisPath
end if
-- set a unique name for the files being backed up for ease of location when necessary.
set theName to name of theFold & theDate & "~" & theTime as text
-- set the path to the folder and subfolders
make new folder in folder thisPath with properties {name:theName}
set mainFold to (result)
set primeName to mainFold
-- call subroutine for getting nested folders.
my theRecur(theFold)
end repeat
end repeat
-- after the files are moved to the initial backup folder, then this compresses the folders and moves them to their final destination.
set folToComp to folder "theBackupFolder" of desktop
set destFold to folder "compressedFolders" of desktop
set dest to destFold as string
-- get list of names for comparison.
repeat with anItem in folToComp
set tempList's end to anItem as alias
set tNames's end to (name of anItem)
end repeat
repeat with anItem in destFold
set iList's end to anItem as alias
set AppleScript's text item delimiters to "."
set thisName to name of anItem
set iNames's end to (first text item of thisName)
end repeat
set AppleScript's text item delimiters to ""
repeat with aName in tNames
if iNames does not contain aName then
repeat with theItem in tempList
if entire contents of theItem is not {} then
set theName to name of theItem as text
if theName is (aName as text) then
-- set initial archive name to untitled archive.sit so it can be named later.
set initArch to dest & arch
set fullName to theName & ".sit"
-- make compressed file.
tell application "StuffIt Deluxe"
with timeout of 6000 seconds
make new archive with properties {location:file initArch}
stuff {theItem} into archive arch with replacing
close archive arch
end timeout
end tell
-- rename the archive to that of the folder it was made of.
select file "untitled archive.sit" of folder dest
set thisFile to selection as alias
set name of thisFile to fullName
end if
end if
end repeat
end if
end repeat
set AppleScript's text item delimiters to astid
end if
tell application "StuffIt Deluxe"
quit
end tell
end tell
set dun to 1
else if dun is 1 then
quit
end if
return 30
end idle
-- the recursion handler. This gets every subfolder of the parent.
on theRecur(thisFold)
tell application "Finder"
repeat with anItem in folder thisFold
set thisItem to anItem as alias
if class of anItem is folder then
set theName to name of thisItem
make new folder in mainFold with properties {name:theName}
set mainFold to (result)
set newFold to anItem as alias
my theRecur(newFold)
end if
if class of anItem is document file then
if modification date of thisItem is greater than testDate then
duplicate anItem to mainFold
end if
set foldCont's end to thisItem
end if
if class of anItem is folder then
set classCheck's end to 1
end if
if contents of classCheck contains 1 then
set mainFold to primeName
set classCheck to {}
end if
end repeat
end tell
end theRecur