Ordner via AppleScript synchronisieren über md5 Prüfsumme

Hatte mal wieder keine Lust ins Bett zu gehen und dabei ist dann das hier heraus gekommen:

(**
Installation:

   1. Wenn Du es das erste mal startest, erzeugt es einen Ordner mit dem Namen "SyncFolders_Script_aliases" auf deinem Start-Volumen und öffnet diesen.
   2. In diesen Ordner ziehst Du zunächst Aliase der Quell-Ordner (ja Du kannst mehrere Ordner in einen Zielordner synchronisieren).
   3. Diese Ordner-Alias bennenst Du um in SOURCE.. irgendwas, wichtig ist nur, dass SOURCE am Anfang steht
   4. Dann erstellst Du da noch einen Alias deines Zielordners, den Du DESTINATION irgendwas nennst


Dann nur noch starten und das Skript legt los =)


Wie es funktioniert?:
Die Dateien werden an Hand von md5 Prüfsummen unterschieden. Jede Dateien, deren md5-Prüfsumme mit denen der Dateien im Zielordner nicht übereinstimmt, wird umbenannt, nach dem Schema (+OUT<aktuelles Datum>) und dann kopiert. Sollte es beim Kopieren zu Problemen kommen, wird die Datei wieder "zurück-benannt" und das Skript läuft weiter. Am Ende erscheint in dem Fall aber eine Fehlermeldung.
In dem Skript Ordner wird zudem ein Datei log.txt geführt, in der dann bei jedem Start geschrieben wird, wie viel wohin kopiert wurde und ob es Fehler gegeben hat...
**)
set script_folder to "SyncFolders_Script_aliases"
set copycount to 0
set copiedpaths to ""
set errorpaths to ""
checkup(script_folder)

tell application "Finder"
  
  set alias_folder to folder script_folder of startup disk
  set source_aliases to (every alias file of alias_folder whose name starts with "SOURCE")
  set destination_alias to (every alias file of alias_folder whose name starts with "DESTINATION")
end tell
set destination_files to md5_list(item 1 of destination_alias)
set source_files to {}
repeat with i from 1 to count of source_aliases
  set source_files to source_files & md5_list(item i of source_aliases)
end repeat

-- assume that all sources are new sources
set newsources to source_files

repeat with destination_file in destination_files
  set b to md5 of destination_file
  repeat with source_file in source_files
    if md5 of source_file = b then
      
      --finally only new sources will stay in the newsources list 
      set newsources to delete_from_list(source_file, newsources)
    end if
  end repeat
end repeat
set erroronmove to false
set prestring to "OUT+" & (do shell script "date +%Y%m%d")
repeat with newsource in newsources
  set current_file to MacOSPath of newsource
  tell application "Finder" to set current_file_name to (name of current_file)
  
  --If the would be files already named "OUT+..:" that are NOT in the destination path 
  --these would no be copied 
  --if current_file_name does not start with "OUT+" then
  
  set current_file to rename_file(current_file, prestring, current_file_name)
  try
    tell application "Finder"
      
      set copiedfile to duplicate current_file to (original item of (item 1 of destination_alias)) as alias
      set copycount to copycount + 1
      set copiedpaths to copiedpaths & (POSIX path of (copiedfile as alias) as text) & return
    end tell
  on error msg
    rename_file(current_file, "", current_file_name)
    set errorpaths to errorpaths & (POSIX path of (current_file as alias) as text) & return
    
    set erroronmove to true
  end try
  
  --end if
end repeat


--write Logfiles
set msg to "Copied " & copycount & " files at "
do shell script "echo " & quoted form of msg & "|cat>>" & quoted form of (POSIX path of (alias_folder as alias)) & "log.txt"
do shell script "date | cat>>" & quoted form of (POSIX path of (alias_folder as alias)) & "log.txt"
if copiedpaths ≠ "" then
  do shell script "echo " & quoted form of copiedpaths & "|cat>>" & quoted form of (POSIX path of (alias_folder as alias)) & "log.txt"
end if
if erroronmove = true then
  set msg to "Errors with files: "
  do shell script "echo " & quoted form of msg & "|cat>>" & quoted form of (POSIX path of (alias_folder as alias)) & "log.txt"
  do shell script "echo " & quoted form of errorpaths & "|cat>>" & quoted form of (POSIX path of (alias_folder as alias)) & "log.txt"
  
  display dialog "Some files could not be copied (name already exsist perhaps) and so presstring has been removed from there names again (just in case the prestring is :" & return & prestring giving up after 10
end if


on rename_file(thefile, new_start, thefile_name)
  tell application "Finder"
    set no_error to false
    set counter to 0
    try
      
      set name of thefile to new_start & thefile_name
    on error
      repeat until no_error = true
        set counter to counter + 1
        try
          set name of thefile to new_start & "##" & counter & "##" & thefile_name
          set no_error to true
          exit repeat
        on error
          set no_error to false
        end try
      end repeat
    end try
  end tell
  return thefile
end rename_file

on delete_from_list(item2delete, thelist)
  set cleanList to {}
  
  repeat with i from 1 to count thelist
    if {thelist's item i} is not in item2delete then set cleanList's end to thelist's item i
  end repeat
  return cleanList
end delete_from_list

on md5_list(alias_file)
  --INPUT: alias files of a folder
  --OUTPUT: Record list of all files within this folder (1. Level)
  -- each record contains (thepath & md5)
  tell application "Finder"
    
    set fileinfos to {}
    
    set a to original item of alias_file
    if kind of a ≠ (kind of folder 1 of startup disk) then
      error "ALERT, ALIAS FILE IS NOT A FOLDER STOPPED!"
    else
      
      set thefiles to every file of a
      repeat with thefile in thefiles
        if name of thefile does not start with "." then
          if (POSIX path of (thefile as alias)) does not end with "/" then
            set md5_sum to do shell script "md5 -q " & quoted form of POSIX path of (thefile as alias)
            set fileinfo to {md5:md5_sum, thepath:(POSIX path of (thefile as alias)), MacOSPath:(thefile as alias)}
            set fileinfos to fileinfos & {fileinfo}
          end if
        end if
      end repeat
    end if
    return fileinfos
  end tell
end md5_list

on checkup(script_folder)
  set orphan_alias to false
  set allok to false
  try
    tell application "Finder" to set alias_folder to folder script_folder of startup disk
  on error
    tell application "Finder" to set alias_folder to make new folder at startup disk with properties {name:script_folder}
    tell application "Finder" to open alias_folder
    
    tell me to activate
    error script_folder & " is empty, please place an ALIAS of each folders you would like to sync into this folder.
All aliases of Source folder you be named \"SOURCE...\" and the Destination Folder should be named \"DESTINATION...\""
  end try
  tell application "Finder"
    if (count of (every alias file of alias_folder)) > 1 then
      if (count of (every alias file of alias_folder whose name starts with "SOURCE")) > 0 then
        if (count of (every alias file of alias_folder whose name starts with "DESTINATION")) = 1 then
          set the_aliases to every alias file of alias_folder
          repeat with k in the_aliases
            try
              set h to original item of k
            on error
              delete k
              set orphan_alias to true
            end try
          end repeat
          if orphan_alias = true then
            error "Hm, there is something wrong with the aliases, orphan alias files have been deleted... script stops"
          else
            set allok to true
          end if
        end if
      end if
    end if
  end tell
  if allok = true then
    return allok
  else
    error "Hm, please check the alias folder, perhaps you have not placed all Aliases in in or maybe they are not name correctly"
  end if
end checkup