Friday, July 19, 2019

#1 2019-02-10 08:13:49 pm

dewshi
Member
Registered: 2009-08-09
Posts: 56

Finder doesn't recognise renamed folder

This script has stopped working since updating to High Sierra (& presumably Mojave).

I use it to back up a website (though it works for any folder!): select the folder & it makes a time-stamped copy to the back up location.

It's failing because Finder no longer finds the copy it makes once it renames it, so can't move it. Any ideas how to fix?? Thanks.

Applescript:


--"Backup Site"
---------------------

(* ==== PROPERTIES ==== *)

global saveFolder
global saveFolderLocation
global myFolder
global theDuplicateAlias

property saveFolderName : "BACKUP" --!!


(* ==== HANDLERS ==== *)

--VERIFY FOLDER
on verifyFolder()
   tell application "Finder"
       try
           --check backup folder
           if not (exists folder saveFolderName of folder saveFolderLocation) then
               make folder at folder saveFolderLocation with properties {name:saveFolderName}
           end if
       on error the error_message number the error_number
           beep
           display dialog "Error: " & the error_number & ". " & the error_message buttons {"Cancel"} default button 1 with icon 0
       end try
   end tell
end verifyFolder


--TIME STAMP DUPLICATE
--NB: for both files & folders
on timestampedduplicate(theItem)
   tell application "Finder"
       set folderCheck to theItem
       if folder (folderCheck as text) exists then
       else
           set extensionhidden to extension hidden of theItem
           set extension hidden of theItem to true
       end if
       set theItemName to displayed name of theItem
       if folder (folderCheck as text) exists then
       else
           set theItemExtension to name extension of theItem
       end if
       set upOneLevelFolder to folder of theItem as alias
       set {year:y, month:m, day:d, time string:t} to (current date)
       set date_format to (y * 10000 + m * 100 + d) as string
       set time_format to (t) as string
       set t to (do shell script "echo " & "'" & t & "'" & " | sed 's/://g' ")
       set thedate to date_format & " " & t as text
       if folder (folderCheck as text) exists then
           set theNewName to theItemName & " " & thedate as text
       else
           set theNewName to theItemName & " " & thedate & "." & theItemExtension as text
       end if
       log theNewName
       set theDuplicate to duplicate theItem to upOneLevelFolder replacing no
       set theDuplicateAlias to theDuplicate as alias
       set name of theDuplicateAlias to theNewName
       if folder (folderCheck as text) exists then
       else
           if extensionhidden then
               set extension hidden of theDuplicateAlias to true
               set extension hidden of theItem to true
           else
               set extension hidden of theDuplicateAlias to false
               set extension hidden of theItem to false
           end if
       end if
   end tell
end timestampedduplicate


(* ==== SCRIPT ==== *)

--initialise
set path2home to (path to home folder) as text
set saveFolderLocation to path2home & "Library:Application Support:"
set saveFolder to saveFolderLocation & saveFolderName & ":"
set defaultLocation to path2home & "Sites:"
my verifyFolder()

--dialog
display dialog "Backup site?" buttons {"Cancel", "View Backups", "Choose Site"} default button 3 with icon 1
set button_returned to button returned of the result

--view
if button_returned is "View Backups" then
   tell application "Finder"
       open folder saveFolder
   end tell
   
   --dialog
   activate me
   display dialog "Backup folder opened..." buttons {"Backup Site", "Done"} default button 2 with icon 1
   set button_returned to button returned of the result
   
end if

--backup
if button_returned is in {"Choose Site", "Backup Site"} then
   
   tell application "Finder"
       set myFolder to choose folder default location defaultLocation as alias --choose site
   end tell
   
   my timestampedduplicate(myFolder) --make duplicate
   
   tell application "Finder"
       move folder theDuplicateAlias to folder saveFolder --move to backup folder
       (*FAILING HERE!!*)
   end tell
   
   --dialog
   activate me
   display dialog "Site backed up." buttons {"Done"} default button 1 with icon 1
   
end if


(* ==== END ==== *)

Offline

 

#2 2019-02-11 07:51:09 am

Yvan Koenig
Member
Registered: 2006-09-14
Posts: 3471

Re: Finder doesn't recognise renamed folder

I can't test because I don't use networks.
I just guess that the site is not aware of the new name when the Finder try to move the renamed folder.
For my own use I would not trigger Finder but would rely upon ASObjC which is more efficient but just to play I edited your script in a way which, I guess, would work.
It no longer use a renamed temporary folder but duplicate directly into the BACKUP folder then rename the replicate.
I changed also the structure so that there is no "living" global values which are stored on disk.

Applescript:


--"Backup Site"
---------------------

my germaine()

(* ==== HANDLERS ==== *)

--VERIFY FOLDER
on verifyFolder(saveFolderName, saveFolderLocation)
   tell application "Finder"
       try
           --check backup folder
           if not (exists folder saveFolderName of folder saveFolderLocation) then
               make folder at folder saveFolderLocation with properties {name:saveFolderName}
           end if
       on error the error_message number the error_number
           beep
           display dialog "Error: " & the error_number & ". " & the error_message buttons {"Cancel"} default button 1 with icon 0
       end try
   end tell
end verifyFolder


on germaine()
   --initialise
   set saveFolderName to "BACKUP"
   set path2home to (path to home folder) as text
   set saveFolderLocation to path2home & "Library:Application Support:"
   set saveFolder to saveFolderLocation & saveFolderName & ":"
   set defaultLocation to path2home & "Sites:"
   my verifyFolder(saveFolderName, saveFolderLocation)
   
   --dialog
   display dialog "Backup site?" buttons {"Cancel", "View Backups", "Choose Site"} default button 3 with icon 1
   set button_returned to button returned of the result
   
   --view
   if button_returned is "View Backups" then
       tell application "Finder"
           open folder saveFolder
       end tell
       
       --dialog
       activate me
       display dialog "Backup folder opened..." buttons {"Backup Site", "Done"} default button 2 with icon 1
       set button_returned to button returned of the result
       
   end if
   
   --backup
   if button_returned is in {"Choose Site", "Backup Site"} then
       
       tell application "Finder"
           set myFolder to choose folder default location defaultLocation as alias --choose site
           
           set replicate to duplicate myFolder to folder saveFolder
       end tell
       
       # As we want to rename a folder, no need to play with extension hidden
       set {year:y, month:m, day:d, hours:h, minutes:mm, seconds:s} to (current date)
       set date_format to (y * 10000 + m * 100 + d) as string
       set time_format to (h * 10000 + mm * 100 + s) as string
       set thedate to date_format & " " & time_format
       
       tell application "Finder"
           set newName to (name of myFolder) & " " & thedate
           set name of replicate to newName
       end tell
       
       --dialog
       activate me
       display dialog "Site backed up." buttons {"Done"} default button 1 with icon 1
       
       
   end if
end germaine

(* ==== END ==== *)

Yvan KOENIG running High Sierra 10.13.6 in French (VALLAURIS, France) lundi 11 février 2019 14:49:36

Last edited by Yvan Koenig (2019-02-11 09:42:25 am)

Offline

 

#3 2019-02-11 09:18:09 am

Nigel Garvey
Moderator
From:: Warwickshire, England
Registered: 2002-11-20
Posts: 4908

Re: Finder doesn't recognise renamed folder

dewshi wrote:

Applescript:

tell application "Finder"
   
   set upOneLevelFolder to folder of theItem as alias


   set theDuplicate to duplicate theItem to upOneLevelFolder replacing no
   set theDuplicateAlias to theDuplicate as alias
   set name of item theDuplicateAlias to theNewName

end tell


I'm seeing a bug in Mojave whereby theDuplicateAlias isn't tracking the name change here. It seems workroundable:

Applescript:

set theNewName to "BACKUP"

tell application "Finder"
   
   set upOneLevelFolder to container of theItem as alias -- 'folder of theItem' is incorrect.
   
   
   set theDuplicate to duplicate theItem -- to upOneLevelFolder replacing no
   set name of theDuplicate to theNewName -- Change the name before setting the alias.
   set theDuplicateAlias to (item theNewName of upOneLevelFolder) as alias
   
end tell

But Yvan's script looks as if it may be better.


NG

Online

 

#4 2019-02-12 02:48:17 am

dewshi
Member
Registered: 2009-08-09
Posts: 56

Re: Finder doesn't recognise renamed folder

@Yvan Thanks! That works.

@Nigel The workaround solves issue too smile Good to know for other scripts

Offline

 

#5 2019-02-12 05:14:16 am

Yvan Koenig
Member
Registered: 2006-09-14
Posts: 3471

Re: Finder doesn't recognise renamed folder

Here is a version using ASObjC.

Applescript:

use AppleScript version "2.5"

use framework "Foundation"
use scripting additions

my germaine()

#=====#=====#=====#=====#=====#=====
# Some handlers borrowed to Shane STANLEY

-- Creates a new folder. There is no error if the folder already exists, and it will also create intermediate folders if required
on createFolderNamed:proposedName inFolder:POSIXPath
   local |⌘|, theFolderURL, theDestURL, theFileManager
   
   set |⌘| to current application
   set theFolderURL to |⌘|'s |NSURL|'s fileURLWithPath:POSIXPath
   if class of proposedName is text then set proposedName to |⌘|'s NSString's stringWithString:proposedName
   set proposedName to proposedName's stringByReplacingOccurrencesOfString:"/" withString:":"
   set theDestURL to theFolderURL's URLByAppendingPathComponent:proposedName
   set theFileManager to |⌘|'s NSFileManager's |defaultManager|()
   -- set {theResult, theError} to theFileManager's createDirectoryAtURL:theDestURL withIntermediateDirectories:true attributes:(missing value) |error|:(reference)
   theFileManager's createDirectoryAtURL:theDestURL withIntermediateDirectories:true attributes:(missing value) |error|:(missing value)
   -- if not (theResult as boolean) then error (theError's |localizedDescription|() as text)
   
   return theDestURL's |path| as text
end createFolderNamed:inFolder:

#=====#=====#=====#=====#=====#=====

on copyThis:POSIXPath intoFolder:folderOrPath addingString:theStamp
   local |⌘|, theSourceURL, destName, theFolderURL, theDestURL
   
   set |⌘| to current application
   set theSourceURL to |⌘|'s |NSURL|'s fileURLWithPath:POSIXPath
   set destName to theSourceURL's |lastPathComponent|()
   set destName to destName's stringByAppendingString:(space & theStamp)
   set theFolderURL to |⌘|'s |NSURL|'s fileURLWithPath:folderOrPath
   set theDestURL to theFolderURL's URLByAppendingPathComponent:destName
   my copyFromURL:theSourceURL toURL:theDestURL withReplacing:true
   
end copyThis:intoFolder:addingString:

#=====

-- This handler is called by other handlers, and is not meant to called directly
on copyFromURL:sourceURL toURL:destinationURL withReplacing:replaceFlag
   set |⌘| to current application
   set theFileManager to |⌘|'s NSFileManager's |defaultManager|()
   set {theResult, theError} to (theFileManager's copyItemAtURL:sourceURL toURL:destinationURL |error|:(reference))
   if not theResult as boolean then
       if replaceFlag and (theError's code() as integer = |⌘|'s NSFileWriteFileExistsError as integer) then -- it already exists, so try replacing
           -- create suitable temporary directory in destinationURL's parent folder
           set {tempFolderURL, theError} to theFileManager's URLForDirectory:(|⌘|'s NSItemReplacementDirectory) inDomain:(|⌘|'s NSUserDomainMask) appropriateForURL:(destinationURL's |URLByDeletingLastPathComponent|()) create:true |error|:(reference)
           if tempFolderURL = missing value then error (theError's |localizedDescription|() as text) -- failed, so return error
           -- copy sourceURL to temp directory
           set tempDestURL to tempFolderURL's URLByAppendingPathComponent:(destinationURL's |lastPathComponent|())
           set {theResult, theError} to theFileManager's copyItemAtURL:sourceURL toURL:tempDestURL |error|:(reference)
           if not theResult as boolean then
               -- copy failed, so delete temporary directory and return error
               theFileManager's removeItemAtURL:tempFolderURL |error|:(missing value)
               error (theError's |localizedDescription|() as text)
           end if
           -- replace existing file with temp file atomically, then delete temp directory
           set {theResult, theError} to theFileManager's replaceItemAtURL:destinationURL withItemAtURL:tempDestURL backupItemName:(missing value) options:(|⌘|'s NSFileManagerItemReplacementUsingNewMetadataOnly) resultingItemURL:(missing value) |error|:(reference)
           theFileManager's removeItemAtURL:tempFolderURL |error|:(missing value)
           -- if replacement failed, return error
           if not theResult as boolean then error (theError's |localizedDescription|() as text)
       else -- replaceFlag is false or an error other than file already exists, so return error
           error (theError's |localizedDescription|() as text)
       end if
   end if
end copyFromURL:toURL:withReplacing:

#=====#=====#=====#=====#=====#=====

on formatDate:theDate usingFormat:formatString
   set theFormatter to current application's NSDateFormatter's new()
   theFormatter's setDateFormat:formatString
   set theString to theFormatter's stringFromDate:theDate
   return theString as text
end formatDate:usingFormat:

#=====#=====#=====#=====#=====#=====

on germaine()
   --initialise
   set saveFolderName to "BACKUP"
   set path2home to (path to home folder) as text
   set saveFolderLocation to path2home & "Library:Application Support:"
   set defaultLocation to path2home & "Sites:"
   
   set POSIXSaveFolder to my createFolderNamed:saveFolderName inFolder:(POSIX path of saveFolderLocation)
   
   --dialog
   display dialog "Backup site?" buttons {"Cancel", "View Backups", "Choose Site"} default button 3 with icon 1
   set button_returned to button returned of the result
   
   --view
   if button_returned is "View Backups" then
       tell application "Finder"
           open folder (POSIX file POSIXSaveFolder)
       end tell
       
       --dialog
       activate me
       display dialog "Backup folder opened..." buttons {"Backup Site", "Done"} default button 2 with icon 1
       set button_returned to button returned of the result
       
   end if
   
   --backup
   if button_returned is in {"Choose Site", "Backup Site"} then
       
       set myFolder to choose folder default location defaultLocation as alias --choose site
       
       # As we want to rename a folder, no need to play with extension hidden
       set theStamp to my formatDate:(current date) usingFormat:"yyyyMMdd HHmmss"
       
       # Copy myFolder into saveFolder adding theStamp to the final name
       my copyThis:(POSIX path of myFolder) intoFolder:POSIXSaveFolder addingString:theStamp
       
       --dialog
       activate me
       display dialog "Site backed up." buttons {"Done"} default button 1 with icon 1
       
       
   end if
end germaine

(* ==== END ==== *)

This one creates the replicate directly with the stamped name.

Yvan KOENIG running High Sierra 10.13.6 in French (VALLAURIS, France) mardi 12 février 2019 12:13:46

Last edited by Yvan Koenig (2019-02-12 09:58:02 am)

Offline

 

Board footer

Powered by FluxBB

RSS (new topics) RSS (active topics)