Submit Hint Search The Forums LinksStatsPollsHeadlinesRSS
14,000 hints and counting!


Click here to return to the 'COMPLEX script posted online' hint
The following comments are owned by whoever posted them. This site is not responsible for what they say.
COMPLEX script posted online
Authored by: Krioni on Aug 11, '09 07:53:41PM
OK. I was frustrated that my old script posted here was incorrect, so I put together a fairly complex script that does the following:

It allows you to run it, or use it as a droplet (save it as an Application from Script Editor). You can process multiple files/folders. You can change the modification date, the creation date, or both (with same or different new dates). It tries to use Apple's SetFile (comes with Developer Tools). If that is not available, it asks whether it can download and install ChangeFileDates by HAMSoft Engineering (they make it freely available, but do not support it), which it installs in ~/Library/Application Support/ChangeFileDates/

A copy of my script is on my website at http://www.danshockley.com/files/MacFileDatesChanger-1.1.applescript. I will also post it here in this comment, but it is pretty long, so going to the link and then saving the file might be easier than copy/paste.


-- MacFileDatesChanger
-- version 1.1
-- Daniel A. Shockley, http://www.danshockley.com
--    Includes some code from Paul Berkowitz and Nigel Garvey on applescript-users mailing list
--    May use or download/install ChangeFileDates, an unsupported command line tool, that
--     was made by HAMSoft Engineering. Read more at: 
--     http://www.hamsoftengineering.com/codeSharing/ChangeFileDates/ChangeFileDates.html
--   Will first attempt to use SetFile, found in Apple's Developer Tools

-- NOTES
-- Save this script as an application to enable drag-and-drop file/folder processing


-- VERSION HISTORY
-- 1.1 - posted online, initial release, not all errors captured
-- 1.0 - test version only

property ScriptName : "MacFileDatesChanger"
property dateFormatString : "%m/%d/%Y %H:%M:%S"
property debugMode : false


on open someItems
	-- someItems could be files or folders
	
	if (count of someItems) is 1 then
		if folder of (info for item 1 of someItems without size) then
			-- user dropped ONE folder on this, ask whether to modify it or contents
			
			display dialog "You dropped a single folder. Change date(s) of that Folder " & ¬
				" itself, or of its Contents?" buttons {"Cancel", "Folder", "Contents"} default button "Folder"
			if button returned of result is "Contents" then
				set oneFolder to item 1 of someItems
				tell application "Finder"
					set someItems to (items of oneFolder) as alias list
				end tell
			end if
			
		end if
	end if
	
	changeFileDates(someItems)
	
end open



on run
	set dialogMsg to "Choose a folder of files to change, or file(s)?"
	set buttonChoices to {"Cancel", "Folder", "Files"}
	set openChoice to button returned of (display dialog dialogMsg buttons buttonChoices default button "Files")
	
	if openChoice is "Files" then
		set chooseFileDialog to "Choose the file(s) you want to change:"
		set fileList to choose file with prompt chooseFileDialog with multiple selections allowed
		
	else if openChoice is "Folder" then
		set oneFolder to choose folder with prompt "Choose the folder whose contents (files/folders) you want to change:"
		tell application "Finder"
			set fileList to (items of oneFolder) as alias list
		end tell
	end if
	
	changeFileDates(fileList)
	
end run


on changeFileDates(fileList)
	
	set filePluralSingle to ""
	if (count of fileList) is greater than 1 then
		set filePluralSingle to "s"
	end if
	
	set dialogMsg to "Change Mod date, Creation date, or Both?"
	set buttonChoices to {"Mod", "Creation", "Both"}
	set dateChangeChoice to button returned of (display dialog dialogMsg buttons buttonChoices default button "Both")
	
	if dateChangeChoice is "Both" then
		set sameOrNot to button returned of (display dialog ¬
			"Change modification and creation to the Same or Different?" buttons ¬
			{"Cancel", "Different", "Same"} default button "Same")
		
		if sameOrNot is "Same" then
			set newDate to dateDialog("Please choose a new creation/mod date for the file" & filePluralSingle & ".")
			set newCreationDate to newDate
			set newModDate to newDate
		else -- Different, so ask for each
			set newCreationDate to dateDialog("Please choose a new creation date for the file" & filePluralSingle & ".")
			set modDateAsk to true
			
			set modDialog to "Please choose a new modification date for the file" & filePluralSingle & "."
			repeat while modDateAsk
				set newModDate to dateDialog(modDialog)
				if newModDate is less than newCreationDate then
					set modDialog to "The modification date can NOT be earlier than the creation date (" & ¬
						dateUnixFormat(newCreationDate, dateFormatString) & ")"
				else -- if it is not before creation, we're done
					set modDateAsk to false
				end if
			end repeat
			
		end if
		set changerPrefs to {doCreation:true, doMod:true, creationDateString:dateUnixFormat(newCreationDate, dateFormatString)} ¬
			& {modDateString:dateUnixFormat(newModDate, dateFormatString)}
		
		
		
	else if dateChangeChoice is "Creation" then
		set newCreationDate to dateDialog("Please choose a new creation date for the file" & filePluralSingle & ".")
		set changerPrefs to {doCreation:true, creationDateString:dateUnixFormat(newCreationDate, dateFormatString)}
	else if dateChangeChoice is "Mod" then
		set newModDate to dateDialog("Please choose a new modification date for the file" & filePluralSingle & ".")
		set changerPrefs to {doMod:true, modDateString:dateUnixFormat(newModDate, dateFormatString)}
	else -- should be impossible
	end if
	
	set cfdPosix to POSIX path of ((path to application support folder from user domain as text) & ¬
		"ChangeFileDates:ChangeFileDates")
	
	repeat with oneFilePath in fileList
		
		macFileDatesChanger(changerPrefs & {filePath:oneFilePath}) --& {binName:"ChangeFileDates", binPosix:cfdPosix})
		
	end repeat
	
end changeFileDates


on dateDialog(dialogMsg)
	-- for now, just handle files, not folders
	set chosenDate to date (text returned of (display dialog dialogMsg ¬
		default answer my dateUnixFormat(current date, dateFormatString)))
	return chosenDate
end dateDialog


on macFileDatesChanger(prefs)
	-- version 1.0, Daniel A. Shockley, http://www.danshockley.com
	
	set binPrefs to getBinaryInfo({installCFD:"ASK"}) -- need to 
	-- {binPosix:POSIX PATH TO BIN, binName:NAME OF BIN}
	set defaultPrefs to {doCreation:false, doMod:false, modDateString:"", creationDateString:""} & binPrefs
	
	if (class of prefs is not record) then
		error "macFileDatesChanger FAILED: parameter should be a single record, " & ¬
			"not just separated parameters." number 1024
	end if
	
	set prefs to prefs & defaultPrefs -- add on default preferences, if needed
	set filePath to filePath of prefs
	set binPosix to binPosix of prefs
	set binName to binName of prefs
	set doCreation to doCreation of prefs
	set creationDateString to creationDateString of prefs
	set doMod to doMod of prefs
	set modDateString to modDateString of prefs
	
	
	
	if binName is "SetFile" then
		set dateOptions to ""
		if doCreation then
			set dateOptions to "-d " & quoted form of creationDateString
		end if
		if doMod then
			set dateOptions to dateOptions & " -m " & quoted form of modDateString
		end if
		
		set shellCommand to binPosix & space & dateOptions & space & ¬
			quoted form of POSIX path of filePath
		
	else if binName is "ChangeFileDates" then
		
		if not doMod or not doCreation then
			-- need to get EXISTING dates, since tool needs both 
			set fileInfo to info for filePath without size
			set currentModDate to modification date of fileInfo
			set currentCreationDate to creation date of fileInfo
			if not doMod then set modDateString to dateUnixFormat(currentModDate, dateFormatString)
			if not doCreation then set creationDateString to dateUnixFormat(currentCreationDate, dateFormatString)
		end if
		
		set shellCommand to quoted form of binPosix & ¬
			" -cDate " & quoted form of creationDateString & " -mDate " & ¬
			quoted form of modDateString & " -file " & ¬
			quoted form of POSIX path of filePath
	end if
	
	try
		if debugMode then logConsole(ScriptName, "COMMAND: " & shellCommand)
		
		do shell script shellCommand
		
	on error theError number errorNumber
		display dialog "There was an error:" & return & theError & return & return & ¬
			"Error Number: " & errorNumber as text buttons {"OK"} default button 1 with icon stop
	end try
	
	
	
	
	
	
end macFileDatesChanger


on getBinaryInfo(installOptions)
	-- version 1.0, Daniel A. Shockley, http://www.danshockley.com
	-- Finds out whether SetFile is installed
	-- If not, looks for ChangeFileDates, by HAMSoft Engineering
	-- option to install
	
	set cfdPosix to POSIX path of ((path to application support folder from user domain as text) & ¬
		"ChangeFileDates:ChangeFileDates")
	
	-- Put possible places to look for binary tools into this list, first priority first
	set posixToTry to {"SetFile", "/Developer/Tools/SetFile", "/Developer/usr/bin/SetFile", "ChangeFileDates", cfdPosix}
	
	set foundBinPosix to tryBinPosixList(posixToTry)
	
	if length of foundBinPosix is greater than 0 then
		set binName to do shell script "basename " & quoted form of foundBinPosix
		
	else
		-- could not find it, see whether we are allowed to download and install
		if installCFD of installOptions is not "" then
			if installChangeFileDatesBinary(installOptions) then
				set foundBinPosix to POSIX path of ((path to application support folder from ¬
					user domain as text) & "ChangeFileDates:ChangeFileDates")
				set binName to "ChangeFileDates"
			else -- install failed or was not allowed
				error "Could not find a binary tool that allows creation date changing." number 1024
				
			end if
		end if
	end if
	
	return {binPosix:foundBinPosix, binName:binName}
	
end getBinaryInfo


on tryBinPosixList(posixList)
	
	repeat with tryPath in posixList
		set tryPath to contents of tryPath
		try
			do shell script quoted form of tryPath
		on error errMsg number errNum
			if errNum is 1 then
				-- binary was found, since nonexistence is 127
				return tryPath
			end if
		end try
	end repeat
	
	return ""
	
end tryBinPosixList


on installChangeFileDatesBinary(installOptions)
	-- version 1.0, Daniel A. Shockley, http://www.danshockley.com	
	if installCFD of installOptions is "YES" then
		-- don't ask, just allow to continue download and install
	else if installCFD of installOptions is "ASK" then
		display dialog "No binary tool for changing dates could be found. Attempt to download " & ¬
			"and install ChangeFileDates by HAMSoft Engineering (unsupported free tool)?" buttons {" Cancel ", "Install"}
		if button returned of result is " Cancel " then return false
		display dialog "You chose to download and install ChangeFileDates. It will be placed at " & ¬
			"~/Library/Application Support/ChangeFileDates/" & return & "Please Confirm that you wish to download " & ¬
			"and install ChangeFileDates." buttons {" Cancel ", "Confirm"} default button "Confirm"
		if button returned of result is " Cancel " then return false
	else
		return false
	end if
	
	-- only should get here if user CHOSE to allow, or if installCFD was "YES" 
	
	try
		set binaryURL to "http://www.hamsoftengineering.com/assets/ChangeFileDates.zip"
		set installToFolderPosix to POSIX path of ((path to application support folder from ¬
			user domain as text) & "ChangeFileDates:")
		
		set tmpZip to (do shell script "mktemp -t changefiledatesbinary")
		-- generate a random filepath to save zip
		-- (using the randomized temp-dir increases security)
		
		set curlCommand to "curl " & (quoted form of binaryURL) & space & "-o" & ¬
			space & tmpZip
		do shell script curlCommand
		
		set unzipCommand to "unzip " & quoted form of tmpZip & " -d " & quoted form of installToFolderPosix
		do shell script unzipCommand
		
	on error errMsg number errNum
		return false
	end try
	
	return true
	
end installChangeFileDatesBinary













on dateUnixFormat(theDate, unixFormatString)
	-- version 1.2, Daniel A. Shockley, http://www.danshockley.com
	-- includes code from Paul Berkowitz and Nigel Garvey on applescript-users mailing list
	-- updates suggested by Jonn8 on macscripter.net BBS
	
	-- dateUnixFormat DID NOT SEEM TO WORK with new Daylight Savings Time ! ! ! !
	-- BUT, subtracting an hour seems to fix it.
	
	-- run 'man strftime' in a shell to read the formatting options
	-- basics are: %d = dd, %m = mm, %Y = yyyy, %F = %Y-%m-%d, %M = MM (minutes), %H = HH (military), %S = SS
	
	try
		-- get the starting Unix date as an AppleScript date
		set theEpoch to (date (do shell script "date -r 0 '+%a %b %e %Y %H:%M:%S'"))
		set unixSecs to theDate - (theEpoch)
		
		set unixSecs to unixSecs - 1 * hours -- HACK to get around bug, seemingly caused by new DST
		
		set unixSecs to my NumberToString(unixSecs)
		
		set theDate to do shell script "date -r " & unixSecs & " +" & quoted form of unixFormatString & ""
		
	on error errMsg number errNum
		error "dateUnixFormat FAILED: " & errMsg number errNum
	end try
end dateUnixFormat

on NumberToString(bigNumber)
	-- by Paul Berkowitz
	
	set bigNumber to bigNumber as string
	if bigNumber does not contain "E+" then return bigNumber
	
	set {tids, AppleScript's text item delimiters} to {AppleScript's text item delimiters, {"E+"}}
	try
		set {basicReal, powersOfTen} to {bigNumber's text item 1, (bigNumber's text item 2) as integer}
	on error -- e.g. Python strings have lower-case "e", tids case-sensitive
		set AppleScript's text item delimiters to {"e+"}
		set {basicReal, powersOfTen} to {bigNumber's text item 1, (bigNumber's text item 2) as integer}
	end try
	set AppleScript's text item delimiters to {"."}
	try
		set {integerPart, decimalPart} to basicReal's {text item 1, text item 2}
		set decimalSign to "."
	on error
		set AppleScript's text item delimiters to {","}
		set {integerPart, decimalPart} to basicReal's {text item 1, text item 2}
		set decimalSign to ","
	end try
	set AppleScript's text item delimiters to tids
	set n to count decimalPart
	if powersOfTen is greater than or equal to n then
		repeat (powersOfTen - n) times
			set decimalPart to decimalPart & "0"
		end repeat
		set bigNumber to integerPart & decimalPart
	else
		set bigNumber to integerPart & decimalPart
		set bigNumber to text 1 thru (powersOfTen + 1) of bigNumber & ¬
			decimalSign & text (powersOfTen + 2) thru -1 of bigNumber
	end if
	
	return bigNumber
	
end NumberToString



on logConsole(processName, consoleMsg)
	-- version 1.7 - Daniel A. Shockley, http://www.danshockley.com
	-- 1.7 - now works with Leopard by using the "logger" command instead of just appending to log file
	-- 1.6- the 'space' constant instead of literal spaces for readability, removed trailing space from the hostname command
	-- 1.5- uses standard date-stamp format	
	
	set shellCommand to "logger" & space & "-t" & space & quoted form of processName & space & quoted form of consoleMsg
	
	do shell script shellCommand
	return shellCommand
end logConsole


---
http://www.danshockley.com

[ Reply to This | # ]

COMPLEX script posted online
Authored by: bugs7007 on Jan 06, '10 02:14:00PM

Not sure if I'm doing this right or not but for some reason this script is ignoring the time, the date is set correctly but the time defaults to 16:00 (4:00p).

The date/time format I use is something like this: "10/10/2004 11:15:00".

I'm using this script with Snow Leopard.


--Sam



[ Reply to This | # ]