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