set m_source_folder to "" set m_destination_folder to "" set m_deleted_folder to true
set m_log_file to false set m_log_errors to false set m_log_actions to false set m_log_decisions to false set m_log_folder_trace to false set m_log_file_trace to false
set m_diff_sec to 0 set m_copy_newer_files_only to false set m_filter_files to "/.DS_Store/Desktop DB/Desktop DF/ .FBCLockFolder/.FBCIndex/Network Trash Folder/" & Â "TheVolumeSettingsFolder/AppleShare PDS/Trash/.Trash/.Trashes/Temporary Items/"
set m_create_index2_files to false -- !!! EXTRA !!!
set m_quit to false
tell application "Finder" -- Get source and destination folders if (m_source_folder = "") then try set m_source_folder to choose folder with prompt "Items will be copied FROM this folder (Cancel to quit):" on error l_error set m_quit to true end try end if if (m_quit is false) then if (m_destination_folder = "") then try set m_destination_folder to choose folder with prompt "Items will be copied TO this folder (Cancel to quit):" on error l_error set m_quit to true end try end if end if if (m_quit is false) then if (m_diff_sec = 0) then try set l_record to display dialog  "Source/Destination with modification dates within these number of seconds are considered the same (Cancel to quit):" default answer 60 set m_diff_sec to text returned of l_record as integer on error l_error set m_quit to true end try end if end if if (m_quit is false) then if (m_deleted_folder is true) then try set m_deleted_folder to choose folder with prompt "Deleted items will be moved to this folder (Cancel to delete items instead):" on error l_error set m_deleted_folder to false end try end if if (m_log_file is false) then try set l_choices to "" set l_choices_string to "" set m_log_file to  choose file name with prompt  "Write synchronize log to this file (Cancel for no logging):" default name "Synchronize_Folder_Log.txt" set l_options to {"Errors", "Actions", "Decisions", "Folder Trace", "File Trace"} set l_defaults to {"Errors", "Actions"} set l_choices to choose from list l_options with prompt  "Select activities to log:" default items l_defaults with multiple selections allowed and empty selection allowed if ("Errors" is in l_choices) then set m_log_errors to true set l_choices_string to "Errors" end if if ("Actions" is in l_choices) then set m_log_actions to true if (l_choices_string is equal to "") then set l_choices_string to "Actions" else set l_choices_string to l_choices_string & ", Actions" end if end if if ("Decisions" is in l_choices) then set m_log_decisions to true if (l_choices_string is equal to "") then set l_choices_string to "Decisions" else set l_choices_string to l_choices_string & ", Decisions" end if end if if ("Folder Trace" is in l_choices) then set m_log_folder_trace to true if (l_choices_string is equal to "") then set l_choices_string to "Folder Trace" else set l_choices_string to l_choices_string & ", Folder Trace" end if end if if ("File Trace" is in l_choices) then set m_log_file_trace to true if (l_choices_string is equal to "") then set l_choices_string to "File Trace" else set l_choices_string to l_choices_string & ", File Trace" end if end if on error l_error end try end if -- Should we only copy newer files? set l_record to display dialog "Copy only if source file is newer?" buttons {"yes", "no"} if (button returned of l_record is "yes") then set m_copy_newer_files_only to true end if -- Should we copy system files? set l_record to display dialog "Copy system files?" buttons {"yes", "no"} if (button returned of l_record is "yes") then set m_filter_files to "" end if -- !!! EXTRA !!! -- Should we create index2.html files? set l_record to display dialog "Copy index.html to index2.html?" buttons {"yes", "no"} if (button returned of l_record is "yes") then set m_create_index2_files to true end if -- Log start time set l_start_time to current date log "+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++" log "Backup source: " & m_source_folder as string log "Backup destination: " & m_destination_folder as string log "Deleted folder: " & m_deleted_folder as string log "Log file: " & m_log_file log "Log options: " & l_choices_string log "Copy only if source is newer: " & m_copy_newer_files_only log "Filter files: " & m_filter_files log "Copy index.html to index2.html: " & m_create_index2_files log "Backup start time: " & l_start_time as string log "+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++" if (class of m_log_file is not boolean) then try close access m_log_file on error l_error end try try open for access m_log_file with write permission on error l_error log l_error as string log "Disabling log file..." set m_log_file to false end try write "+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ " starting at (get eof m_log_file) + 1 to m_log_file write "Backup source: " & m_source_folder & " " to m_log_file write "Backup destination: " & m_destination_folder & " " to m_log_file write "Deleted folder: " & m_deleted_folder & " " to m_log_file write "Log file: " & m_log_file & " " to m_log_file write "Log options: " & l_choices_string & " " to m_log_file write "Copy only if source is newer: " & m_copy_newer_files_only & " " to m_log_file write "Filter files: " & m_filter_files & " " to m_log_file write "Copy index.html to index2.html: " & m_create_index2_files & " " to m_log_file write "Backup start time: " & l_start_time & " " to m_log_file write "+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ " to m_log_file end if -- Get source folder length so that we can strip it out of each source folder's path set l_source_length to (length of (m_source_folder as string)) + 1 -- Convert folder class to string (":...") set l_destination_folder_string to m_destination_folder as string -- Set queue items and start main repeat loop. set l_pending_folders to {m_source_folder} -- While items remain in queue, process each one repeat while ((length of l_pending_folders) > 0) -- Remove the first item from l_pending_folders set l_current_folder to first item of l_pending_folders if (length of l_pending_folders = 1) then set l_pending_folders to {} else set l_pending_folders to rest of l_pending_folders end if -- Log current folder if (m_log_folder_trace is true) then log "Checking folder for copy: " & l_current_folder as string if (class of m_log_file is not boolean) then write "Checking folder for copy: " & l_current_folder & " " to m_log_file end if end if -- Determine destination folder string set l_string to l_current_folder as string try set l_string to (text l_source_length through (length of l_string) of l_string) on error l_error -- error if this is the source folder base string set l_string to "" end try set l_string to l_destination_folder_string & l_string try -- Determine destination folder. set l_dest_folder to alias l_string -- Cycle through items in the current folder and process each item set l_items to list folder of l_current_folder on error l_error -- If there's an error, chances are dest folder doesn't exist. -- Occurs when copying from Mac OS X to Mac OS 9 and file name -- of source folder is illegal in Mac OS 9. set l_dest_folder to "" set l_items to {} if (m_log_errors is true) then log "*****Error getting destination folder " & l_string log "*****" & l_error if (class of m_log_file is not boolean) then write "*****Error getting destination folder " & l_string & " " to m_log_file write "*****" & l_error & " " to m_log_file end if end if end try -- l_temp_folders keeps track of folder list, so that we can -- prepend it to l_pending_folders and do a depth-first search. set l_temp_folders to {} repeat with l_source_item_name in l_items if (m_log_file_trace is true) then log "....Checking file " & l_current_folder & l_source_item_name if (class of m_log_file is not boolean) then write "....Checking file " & l_current_folder & l_source_item_name & " " to m_log_file end if end if set l_source_invalid to false try set l_source_item to (get item l_source_item_name of l_current_folder) set l_copy_item to false set l_dest_item to "" on error l_error set l_source_invalid to true if (m_log_errors is true) then log "*****Error processing source item " & l_current_folder & l_source_item_name log "*****" & l_error if (class of m_log_file is not boolean) then write "*****Error processing source item " & l_current_folder & l_source_item_name & " " to m_log_file write "*****" & l_error & " " to m_log_file end if end if end try if ("/" & l_source_item_name & "/" is in m_filter_files) then -- Check to see if this is a file we should skip set l_source_invalid to true if (m_log_decisions is true) then log "////Skipping filtered file " & l_current_folder & l_source_item_name if (class of m_log_file is not boolean) then write "////Skipping filtered file " & l_current_folder & l_source_item_name & " " to m_log_file end if end if end if if (l_source_invalid is false) then set l_source_kind to (get kind of l_source_item) if (l_source_kind is "Application") then set l_source_date to (get creation date of l_source_item) else set l_source_date to (get modification date of l_source_item) end if -- See if the item exists at the destination try set l_dest_item to (get item l_source_item_name of l_dest_folder) set l_dest_kind to (get kind of l_dest_item) if (l_source_kind is "Application") then set l_dest_date to (get creation date of l_dest_item) else set l_dest_date to (get modification date of l_dest_item) end if on error l_error set l_copy_item to true end try -- Check to see if source and destination differ. if (l_copy_item is false) then if (l_source_kind is not equal to l_dest_kind) then -- First check class of items set l_copy_item to true if (m_log_decisions is true) then log "////Source kind (" & l_source_kind & ") differs from destination kind (" & l_dest_kind & ")" if (class of m_log_file is not boolean) then write "////Source kind (" & l_source_kind & ") differs from destination kind (" & l_dest_kind & ") " to m_log_file end if end if else if (m_copy_newer_files_only is true and  l_source_kind is not "Folder" and  ((l_source_date - l_dest_date) - m_diff_sec) > 0) then -- Second, check source item is newer than destination. Only for non-folders set l_copy_item to true if (m_log_decisions is true) then log "////Source date (" & l_source_date & ") is newer than destination date (" & l_dest_date & ")" if (class of m_log_file is not boolean) then write "////Source date (" & l_source_date & ") is newer than destination date (" & l_dest_date & ") " to m_log_file end if end if else if (m_copy_newer_files_only is false and  l_source_kind is not "Folder" and  (((l_source_date - l_dest_date) - m_diff_sec) > 0 or  ((l_dest_date - l_source_date) - m_diff_sec) > 0)) then -- Or, check date of source item is different than destination. Only for non-folders set l_copy_item to true if (m_log_decisions is true) then log "////Source date (" & l_source_date & ") is different than destination date (" & l_dest_date & ")" if (class of m_log_file is not boolean) then write "////Source date (" & l_source_date & ") is different than destination date (" & l_dest_date & ") " to m_log_file end if end if end if end if -- If we need to copy the item... if (l_copy_item is true) then -- Log event if (m_log_actions is true) then log "++++Copying item " & l_source_item as string if (class of m_log_file is not boolean) then write "++++Copying item " & l_source_item & " " to m_log_file end if end if -- Copy source to destination if (l_source_kind is not "Folder") then -- If source is not a folder then copy it to destination with timeout of 86400 seconds -- 1 day timeout try duplicate l_source_item to l_dest_folder with replacing on error l_error if (m_log_errors is true) then log "****" & l_error if (class of m_log_file is not boolean) then write "****" & l_error & " " to m_log_file end if end if end try end timeout else try -- move or delete non-folder item if (class of l_dest_item is not string and l_dest_kind is not "Folder") then if (class of m_deleted_folder is alias) then move l_dest_item to m_deleted_folder with replacing else delete l_dest_item end if end if -- If source is a folder then create destination folder set l_folder to make new folder at l_dest_folder set name of l_folder to (l_source_item_name) on error l_error if (m_log_errors is true) then log "****" & l_error if (class of m_log_file is not boolean) then write "****" & l_error & " " to m_log_file end if end if end try end if -- !!! EXTRA !!! -- If this item is index.html, duplicate it to index2.html and copy it over. -- We only need to create index2.html if we're copying over index.html. -- Extra copy covers case when index2.html did not initially exist. if (m_create_index2_files is true and l_source_item_name is "index.html") then try delete file "index2.html" of l_current_folder set l_dup to (duplicate l_source_item) set name of l_dup to "index2.html" on error l_error end try if (m_log_actions is true) then log "++++Copying item index2.html" if (class of m_log_file is not boolean) then write "++++Copying item index2.html " to m_log_file end if end if with timeout of 86400 seconds -- 1 day timeout try duplicate file "index2.html" of l_current_folder to l_dest_folder with replacing on error l_error if (m_log_errors is true) then log "****" & l_error if (class of m_log_file is not boolean) then write "****" & l_error & " " to m_log_file end if end if end try end timeout end if end if -- If source item is a folder, add it to pending folders list if (l_source_kind is "Folder") then set l_temp_folders to l_temp_folders & {l_source_item as alias} end if end if end repeat -- Prepend new folders to l_pending_folders if ((count of l_temp_folders) > 0) then set l_pending_folders to l_temp_folders & l_pending_folders end if -- !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -- Delete Destination Files Not In Source -- !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! if (class of l_dest_folder is not string) then -- Log current folder if (m_log_folder_trace is true) then log "Checking folder for delete: " & l_dest_folder as string if (class of m_log_file is not boolean) then write "Checking folder delete: " & l_dest_folder & " " to m_log_file end if end if -- Cycle through items in the current folder and process each item set l_items to list folder of (l_dest_folder as alias) repeat with l_destination_item_name in l_items if (m_log_file_trace is true) then log "....Checking file " & l_dest_folder & l_destination_item_name if (class of m_log_file is not boolean) then write "....Checking file " & l_dest_folder & l_destination_item_name & " " to m_log_file end if end if set l_dest_invalid to false try set l_destination_item to (get item l_destination_item_name of l_dest_folder) set l_delete_item to false set l_source_item to "" on error l_error set l_dest_invalid to true if (m_log_errors is true) then log "*****Error processing destination item " & l_dest_folder & l_destination_item_name log "*****" & l_error if (class of m_log_file is not boolean) then write "*****Error processing destination item " & l_dest_folder & l_destination_item_name & " " to m_log_file write "*****" & l_error & " " to m_log_file end if end if end try if ("/" & l_destination_item_name & "/" is in m_filter_files) then -- Check to see if this is a file we should skip set l_dest_invalid to true if (m_log_decisions is true) then log "////Skipping filtered file " & l_dest_folder & l_destination_item_name if (class of m_log_file is not boolean) then write "////Skipping filtered file " & l_dest_folder & l_destination_item_name & " " to m_log_file end if end if end if if (l_dest_invalid is false) then -- See if the item exists at the destination try set l_source_item to (get item l_destination_item_name of l_current_folder) on error l_error set l_delete_item to true end try -- If we need to delete the item... if (l_delete_item is true) then -- Log event if (m_log_actions is true) then log "----Deleting item " & l_destination_item as string if (class of m_log_file is not boolean) then write "----Deleting item " & l_destination_item & " " to m_log_file end if end if -- Delete destination try if (class of m_deleted_folder is alias) then move l_destination_item to m_deleted_folder with replacing else delete l_destination_item end if on error l_error if (m_log_errors is true) then log "****" & l_error if (class of m_log_file is not boolean) then write "****" & l_error & " " to m_log_file end if end if end try end if end if end repeat end if end repeat -- Log end time log "=============================================================" log "Backup source: " & m_source_folder as string log "Backup destination: " & m_destination_folder as string log "Deleted folder: " & m_deleted_folder as string log "Log file: " & m_log_file log "Log options: " & l_choices_string log "Copy only if source is newer: " & m_copy_newer_files_only log "Filter files: " & m_filter_files log "Copy index.html to index2.html: " & m_create_index2_files log "Backup start time: " & l_start_time as string log "Backup end time: " & (current date) log "=============================================================" if (class of m_log_file is not boolean) then write "============================================================= " to m_log_file write "Backup source: " & m_source_folder & " " to m_log_file write "Backup destination: " & m_destination_folder & " " to m_log_file write "Deleted folder: " & m_deleted_folder & " " to m_log_file write "Log file: " & m_log_file & " " to m_log_file write "Log options: " & l_choices_string & " " to m_log_file write "Copy only if source is newer: " & m_copy_newer_files_only & " " to m_log_file write "Filter files: " & m_filter_files & " " to m_log_file write "Copy index.html to index2.html: " & m_create_index2_files & " " to m_log_file write "Backup start time: " & l_start_time & " " to m_log_file write "Backup end time: " & (current date) & " " to m_log_file write "============================================================= " to m_log_file close access m_log_file end if end if end tell
|
|