Sunday, June 13, 2021

#1 2021-05-26 10:38:41 am

traegheitsmoment
Member
Registered: 2021-01-13
Posts: 43

Script stops unexpectedly after 'delete' command

Hi there,

with the kind help of some of the members here I managed to 'bake' a folder action that does the following:

It analyses the name of each file that is added to the folder.
Based on some part of the file name it identifies a certain folder an a server.
And within this folder it looks for a matching flag file in the folder substructure.
Then it moves the original file to the folder that contains the flag file.

It works like a charm, but:
If no matching flag file is found the script is supposed to move the original file to a special folder called 'orphans'.

This works as well. But each time this happens the script stops unexpectedly and does not continue to work on the remaining files in the watched folder.

I have no clue why the script stops. If there is no orphan in the queue the script manages to move every file of the watched folder without stopping.

Has anybody an idea?

Please see the script below...:

Thank you very much for any help
traegheitsmoment


Applescript:


use scripting additions
use framework "Foundation"

on adding folder items to this_folder after receiving these_items
   repeat with i from 1 to number of items in these_items
       set sourceFile to item i of these_items
       set searchPath to "/Volumes/space/data/projects/" -- this should be path to folder on server
       set ATID to AppleScript's text item delimiters
       set AppleScript's text item delimiters to {":"}
       set sourceFileName to text item -1 of (sourceFile as text)
       set AppleScript's text item delimiters to {"-"}
       set theProjektPrefix to text item 1 of sourceFileName
       set theCompanyName to text item 2 of sourceFileName
       set AppleScript's text item delimiters to ATID
       set targetProjektFolder to getProjektfolder(searchPath, theProjektPrefix)
       set targetProjektFolder to (targetProjektFolder as string) & theProjektPrefix & "-team:"
       set locationFileName to theProjektPrefix & "-" & theCompanyName & "-huhu.txt"
       set theCheckFile to (getFlag(targetProjektFolder, locationFileName) & sourceFileName) as string
       set targetFolder to getFlag(targetProjektFolder, locationFileName)

       tell application "System Events"

           if exists file (theCheckFile) then
               set targetFolder to alias "Macintosh HD:Users:me:Documents:deposit:double:"
               tell application "Finder"
                   move sourceFile to targetFolder with replacing
               end tell
           else
               tell application "Finder"
                   move sourceFile to targetFolder without replacing
                   delete sourceFile

-- This is where the script stops if the file was moved to the orphans folder.

               end tell
           end if
       end tell
       
   end repeat
   
   display dialog "Es wurden " & (number of items in these_items) & " Files moved."
end adding folder items to


on getProjektfolder(theFolder, theProjektPrefix)
   
   set theFolder to current application's |NSURL|'s fileURLWithPath:theFolder
   set fileManager to current application's NSFileManager's defaultManager()
   set folderContents to (fileManager's enumeratorAtURL:theFolder includingPropertiesForKeys:{} options:((current application's NSDirectoryEnumerationSkipsPackageDescendants) + (current application's NSDirectoryEnumerationSkipsSubdirectoryDescendants as integer) + (current application's NSDirectoryEnumerationSkipsHiddenFiles as integer)) errorHandler:(missing value))'s allObjects()
   set thePred to current application's NSPredicate's predicateWithFormat_("(path MATCHES[c] %@)", (".*?/" & theProjektPrefix & ".*"))
   set theFiles to (folderContents's filteredArrayUsingPredicate:thePred)

   if (count theFiles) = 0 then errorDialog("No location files were found")
   return theFiles
end getProjektfolder

on getFlag(theFlagFolder, theName)
   set theFlagFolder to POSIX path of theFlagFolder
   set theFlagFolder to current application's |NSURL|'s fileURLWithPath:theFlagFolder
   set fileManager to current application's NSFileManager's defaultManager()
   set folderContents to (fileManager's enumeratorAtURL:theFlagFolder includingPropertiesForKeys:{} options:((current application's NSDirectoryEnumerationSkipsPackageDescendants) + (current application's NSDirectoryEnumerationSkipsHiddenFiles as integer)) errorHandler:(missing value))'s allObjects()
   
   set thePred to current application's NSPredicate's predicateWithFormat_("(lastPathComponent ==[c] %@)", theName)
   set theFiles to (folderContents's filteredArrayUsingPredicate:thePred)

   if (count theFiles) = 0 then

-- This is where the script checks for the orphans and returns the path to the orphans folder.    

       return ("Macintosh HD:Users:me:Documents:deposit:orphans:")
   else
       return ((theFiles's URLByDeletingLastPathComponent) as alias)
   end if
   
   
end getFlag

on errorDialog(dialogText)
   display dialog dialogText buttons {"OK"} default button 1 cancel button 1 with title "" with icon stop
end errorDialog


Offline

 

#2 2021-05-26 01:07:34 pm

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

Re: Script stops unexpectedly after 'delete' command

Rubbish reply withdrawn with apologies.  hmm

Last edited by Nigel Garvey (2021-05-28 05:30:24 am)


NG

Offline

 

#3 2021-05-26 03:40:27 pm

wch1zpink
Member
Registered: 2011-08-20
Posts: 25

Re: Script stops unexpectedly after 'delete' command

Instead of using this…

Applescript:

tell application "System Events"

           if exists file (theCheckFile) then
               set targetFolder to alias "Macintosh HD:Users:me:Documents:deposit:double:"
               tell application "Finder"
                   move sourceFile to targetFolder with replacing
               end tell
           else
               tell application "Finder"
                   move sourceFile to targetFolder without replacing
                   delete sourceFile

-- This is where the script stops if the file was moved to the orphans folder.

               end tell
           end if
       end tell
       
   end repeat

Try using this instead…

Applescript:

tell application "System Events" to set fileExists to file (theCheckFile) exists
tell application "Finder"
   if fileExists then
       set targetFolder to alias "Macintosh HD:Users:me:Documents:deposit:double:"
       set theSourceFile to move sourceFile to targetFolder with replacing
   else
       set targetFolder to alias "Macintosh HD:Users:me:Documents:deposit:orphans:"
       set theSourceFile to move sourceFile to targetFolder without replacing
       delete sourceFile
   end if
end tell

Last edited by wch1zpink (2021-05-26 11:45:29 pm)

Offline

 

#4 2021-05-27 01:27:36 pm

traegheitsmoment
Member
Registered: 2021-01-13
Posts: 43

Re: Script stops unexpectedly after 'delete' command

@ Nigel
Thank you for the hint. I haven't tested this yet, but I will try tomorrow, when I'm back in the office.

@ wch1zpink
Thank you very much as well. I also haven't tested it, but as far as I understand it, the result of the script might not match the purpose...

The purpose of the original script is to...

copy the respective file to a certain folder in the substructure of an external server.

To find the destination folder the script analyses the file name and based on the file name searches for a matching flag file.

If...
no flag file is found... then the file should be moved in a local folder called orphans.

If...
there already exists a file with the same file name, the respective file should be moved in local folder called 'double'.

It seems to me, that your code wouldn't copy the file to the destination folder on the external server in any case.

@ KniazidisR
Thank you very much as well.
I tried your code. Maybe I've done something wrong. It moves the first file in the queue to the 'double' folder even if it doesn't exist in the destination folder on the server and then stops.
I will do some more testing tomorrow...

Thank you all again for your time,
traegheitsmoment

Offline

 

#5 2021-05-28 01:00:33 am

StefanK
Member
From:: St. Gallen, Switzerland
Registered: 2006-10-21
Posts: 11748
Website

Re: Script stops unexpectedly after 'delete' command

That's a common mistake. If you modify the size of a list while being enumerated the indexes change and you could run out of index.

An alternative is the repeat with ... in loop. In conjunction with the get keyword the references to the items don't change

Applescript:

on adding folder items to this_folder after receiving these_items
   repeat with sourceFile in (get these_items)
...

Last edited by StefanK (2021-05-28 01:01:16 am)


regards

Stefan

Offline

 

#6 2021-05-28 03:48:42 am

KniazidisR
Member
From:: Greece
Registered: 2019-03-03
Posts: 1878

Re: Script stops unexpectedly after 'delete' command

My script contained an error again. So I decided to remove it too.

But it seemed strange to me that according to Nigel Garvey and StefanK, after the Finder deletes a certain file/folder, the list of AppleScript aliases changes. That would be a bad surprise for me. After all, the list of aliases belongs to AppleScript, not Finder, so it shouldn't change.

Perhaps my next test is wrong - it does not confirm that the list has changed. I even added 10 seconds delay to let Finder finish its deleting:

Applescript:


tell application "Finder"
   set thisItems to items of home as alias list --> 57 aliases
   log (count of thisItems) --> (*57*)
   delete (item 51 of thisItems) -- "OneDrive" folder on my Mac
end tell
delay 10
log (count of thisItems) --> --> (*57*)

Warning: put deleted item back from Trash, when finish the test.

Tip: to understand the reason for the failure of original script, the OP should test it as a script, not a hot folder. I cannot do this instead of OP, as I do not know the exact structure of OP folders.

Applescript:


tell application "Finder" to set these_items to items of (choose folder) as alias list
set hotFolder to choose folder with prompt "Choose Hot folder"

adding folder items to this_folder after receiving these_items


on adding folder items to this_folder after receiving these_items
-- do something
end adding folder items to

Last edited by KniazidisR (2021-05-28 05:13:06 am)


Model: MacBook Pro
OS X: Catalina 10.15.4
Web Browser: Safari 14.1
Ram: 4 GB

Offline

 

#7 2021-05-28 05:31:34 am

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

Re: Script stops unexpectedly after 'delete' command

KniazidisR wrote:

But it seemed strange to me that according to Nigel Garvey and StefanK, after the Finder deletes a certain file/folder, the list of AppleScript aliases changes. That would be a bad surprise for me. After all, the list of aliases belongs to AppleScript, not Finder, so it shouldn't change.


You're right! My apologies to all. 'theseItems' is a list, not the contents of a folder. I've now zapped my response in post #2.

I must be getting old.  hmm


NG

Offline

 

#8 2021-05-28 11:00:11 am

traegheitsmoment
Member
Registered: 2021-01-13
Posts: 43

Re: Script stops unexpectedly after 'delete' command

KniazidisR wrote:

My script contained an error again. So I decided to remove it too.

Tip: to understand the reason for the failure of original script, the OP should test it as a script, not a hot folder. I cannot do this instead of OP, as I do not know the exact structure of OP folders.

Applescript:


tell application "Finder" to set these_items to items of (choose folder) as alias list
set hotFolder to choose folder with prompt "Choose Hot folder"

adding folder items to this_folder after receiving these_items


on adding folder items to this_folder after receiving these_items
-- do something
end adding folder items to



Thank you KniazidisR,
I'm not sure if I did it correctly because when I start the modified script and choose two folders I stops and tells me 'the variable "this folder" is not defined'

Maybe I didn't modify the script correctly. I changed it like that...

Applescript:


use scripting additions
use framework "Foundation"

tell application "Finder" to set these_items to items of (choose folder) as alias list
set hotFolder to choose folder with prompt "Choose Hot folder"

adding folder items to this_folder after receiving these_items


on adding folder items to this_folder after receiving these_items
   
   
   repeat with sourceFile in (get these_items)
.
.
.
.
end repeat
end adding folder items to

Can you tell me a little bit about how it should work and how we can find the reason of the failure of the original script? I'm not sure what the first folder I need to choose is for and what the second folder (hot filder) is meant for.

Thanks again,
traegheitsmoment

Offline

 

#9 2021-05-28 11:02:47 am

traegheitsmoment
Member
Registered: 2021-01-13
Posts: 43

Re: Script stops unexpectedly after 'delete' command

StefanK wrote:

That's a common mistake. If you modify the size of a list while being enumerated the indexes change and you could run out of index.

An alternative is the repeat with ... in loop. In conjunction with the get keyword the references to the items don't change

Applescript:

on adding folder items to this_folder after receiving these_items
   repeat with sourceFile in (get these_items)
...



Thank you Stefan,

I tried that and it works as good as the original script but still shows the same error. It stops every time if there is an orphan found after it moves the orphan correctly to the orphans folder.

If there is no orphan found, than the whole queue is being worked off.

Offline

 

#10 2021-05-28 11:09:18 am

KniazidisR
Member
From:: Greece
Registered: 2019-03-03
Posts: 1878

Re: Script stops unexpectedly after 'delete' command

traegheitsmoment wrote:


I'm not sure if I did it correctly because when I start the modified script and choose two folders I stops and tells me 'the variable "this folder" is not defined'


My fault. Replace

Applescript:


set hotFolder to choose folder with prompt "Choose Hot folder"

with

Applescript:


set this_folder to choose folder with prompt "Choose Hot folder"

Hot folder is folder were arrive the files. Other folder provides files itself, which arrive to hot folder.

Last edited by KniazidisR (2021-05-28 11:12:03 am)


Model: MacBook Pro
OS X: Catalina 10.15.4
Web Browser: Safari 14.1
Ram: 4 GB

Offline

 

#11 2021-05-31 04:28:57 am

traegheitsmoment
Member
Registered: 2021-01-13
Posts: 43

Re: Script stops unexpectedly after 'delete' command

Thanks again,

I tried this as a script like you described it.
When I start it, it works for a while and then it renders the following error:


error "URLByDeletingLastPathComponent of «class ocid» id «data optr0000000060D8680000600000» kann nicht in Typ alias umgewandelt werden." number -1700 from URLByDeletingLastPathComponent of «class ocid» id «data optr0000000060D8680000600000» to alias

The error refers to the getFlag subroutine, particularly to the 5th line of the following part:

Applescript:


set theFiles to (folderContents's filteredArrayUsingPredicate:thePred)
   if (count theFiles) = 0 then
       return ("Macintosh HD:Users:cm:Documents:Donath Bickel:db orphans:")
   else
       return ((theFiles's URLByDeletingLastPathComponent) as alias)
   end if

Does this help in any way to check out the underlying problem?

Offline

 

#12 2021-06-01 03:17:56 am

KniazidisR
Member
From:: Greece
Registered: 2019-03-03
Posts: 1878

Re: Script stops unexpectedly after 'delete' command

Hi. Again.

Try to replace this:

Applescript:


return ((theFiles's URLByDeletingLastPathComponent) as alias)

with this:

Applescript:


return ((item 1 of theFiles)'s URLByDeletingLastPathComponent()) as alias

NOTE: basically, I can't understand what you try return in the else case: 1) list of aliases, 2) 1 alias, 3) list of HFS paths, 4) 1 HFS path (like in the case count theFiles = 0.

My last snippet returns 1 alias (case 2). If you try return 1 HFS path (case 4) then replace as alias with as text. If you want 1) or 3) then you should create empty list, and use repeat loop to add to it aliases or HFS paths, one by one.

Last edited by KniazidisR (2021-06-01 03:37:33 am)


Model: MacBook Pro
OS X: Catalina 10.15.4
Web Browser: Safari 14.1
Ram: 4 GB

Offline

 

#13 2021-06-01 07:14:58 am

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

Re: Script stops unexpectedly after 'delete' command

Hi.

Looking at the original script more carefully and at more leisure today, I see a number of potential snagging points:

Applescript:

set AppleScript's text item delimiters to {":"}
set sourceFileName to text item -1 of (sourceFile as text)

sourceFileName will be set to an empty string if the "file" is in fact a folder or a package. It's safer to use an application to extract the file name or else add a check to the TIDs process which gets the penultimate text item instead if the path ends with a colon.

Applescript:

set targetProjektFolder to getProjektfolder(searchPath, theProjektPrefix)
set targetProjektFolder to (targetProjektFolder as string) & theProjektPrefix & "-team:"

The getProjektfolder() handler returns an NSArray containing either an NSURL or nothing. Coercing such a result to 'string' isn't a good idea.

Applescript:

tell application "Finder"
   move sourceFile to targetFolder without replacing
   delete sourceFile
   
   -- This is where the script stops if the file was moved to the orphans folder.
   
end tell


   -- Skip ahead to :

if (count theFiles) = 0 then
   
   -- This is where the script checks for the orphans and returns the path to the orphans folder.    
   
   return ("Macintosh HD:Users:me:Documents:deposit:orphans:")
else
   return ((theFiles's URLByDeletingLastPathComponent) as alias)
end if

The "orphans" result returned at the end is text. It should be an alias like the other result so that the Finder doesn't try to move the file to text instead of to a folder!

If the "orphans" folder's on the same computer as the drop folder, and sourceFile is successfully moved to it, the file will be relocated from the drop folder to the "orphans" folder and the alias in the sourceFile variable will change to track it. So 1) there'll be no need to delete the file from the drop folder (since it will no longer be there) and 2) deleting sourceFile will delete the file from its new location in the the "orphans" folder.


NG

Offline

 

#14 2021-06-02 01:25:56 pm

traegheitsmoment
Member
Registered: 2021-01-13
Posts: 43

Re: Script stops unexpectedly after 'delete' command

@all
Thank you all for your input. I appreciate very much. Based on your feedback I decided to restructure the loops and conditions to make debugging more easy. I haven't finished yet but I'm sure it will help.

@KniazidisR

Thank you very much. I think you are right. The last thing you found in the script might be one of the things that may cause trouble.

@Nigel
Thank you very much as well for your insight. I think this will help and I learned alot thanks to your explanation.

Cheers
traegheitsmoment

Offline

 

#15 2021-06-03 06:50:27 am

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

Re: Script stops unexpectedly after 'delete' command

Here's an attempt to revamp the code, with a few comments to explain things. I haven't been able to test it in context though, so there are no guarantees that it'll actually do the job.

Applescript:

use AppleScript version "2.5" -- Mac OS X 10.11 (El Capitan) or later. (For NSURL to alias coercion.)
use scripting additions
use framework "Foundation"

on adding folder items to this_folder after receiving these_items
   set searchPath to "/Volumes/space/data/projects/" -- this should be path to folder on server
   repeat with i from 1 to (count these_items)
       set sourceFile to item i of these_items
       tell application "System Events" to set sourceFileName to name of sourceFile
       set ATID to AppleScript's text item delimiters
       set AppleScript's text item delimiters to {"-"}
       set theProjektPrefix to text item 1 of sourceFileName
       set theCompanyName to text item 2 of sourceFileName
       set AppleScript's text item delimiters to ATID
       
       set targetProjektFolder to (getProjektfolder(searchPath, theProjektPrefix) as text) & theProjektPrefix & "-team:" -- HFS path.
       set locationFileName to theProjektPrefix & "-" & theCompanyName & "-huhu.txt"
       set targetFolder to getFlag(targetProjektFolder, locationFileName) -- Alias.
       set checkFilePath to (targetFolder as text) & sourceFileName -- HFS path.
       
       tell application "System Events"
           
           if (file checkFilePath exists) then
               set targetFolder to alias "Macintosh HD:Users:me:Documents:deposit:double:"
               -- System Events version of the Finder's 'move … with replacing':
               if (file sourceFileName of targetFolder exists) then delete file sourceFileName of targetFolder
               move sourceFile to targetFolder
           else
               -- The original Finder code here specified moving the file 'without replacing', which would
               -- throw an error if a file with the same name already existed at the destination, so …
               try
                   move sourceFile to targetFolder
               end try
               (* Or:
               if not (file sourceFileName of targetFolder exists) then move sourceFile to targetFolder
               *)

               -- Delete the file from the drop folder if it couldn't be moved or was 'moved' to the server and still exists at this end too.
               if (file sourceFileName of this_folder exists) then delete file sourceFileName of this_folder
           end if
       end tell
       
   end repeat
   
   display dialog "Es wurden " & (number of items in these_items) & " Files moved."
end adding folder items to


on getProjektfolder(rootPath, theProjektPrefix)
   set theFolder to current application's |NSURL|'s fileURLWithPath:rootPath
   set fileManager to current application's NSFileManager's defaultManager()
   (* set folderContents to (fileManager's enumeratorAtURL:theFolder includingPropertiesForKeys:{} options:((current application's NSDirectoryEnumerationSkipsPackageDescendants) + (current application's NSDirectoryEnumerationSkipsSubdirectoryDescendants as integer) + (current application's NSDirectoryEnumerationSkipsHiddenFiles as integer)) errorHandler:(missing value))'s allObjects() *)
   -- Since you're skipping both package and subfolder contents, you can shorten the commented-out line above to this:
   set folderContents to fileManager's contentsOfDirectoryAtURL:theFolder includingPropertiesForKeys:{} options:(current application's NSDirectoryEnumerationSkipsHiddenFiles) |error|:(missing value)
   
   set thePred to current application's NSPredicate's predicateWithFormat_("(path MATCHES[c] %@)", (".*?/" & theProjektPrefix & ".*"))
   set theFiles to (folderContents's filteredArrayUsingPredicate:thePred) as list -- 'as list' gives an AppleScript list of AppleScript 'file' ojects.
   
   if (count theFiles) = 0 then errorDialog("No location files were found") -- NB. The errorDialog() handler stops the script immediately when the dialog's dismissed.
   return item 1 of theFiles -- Otherwise return the first (and only) 'file' (hopefully actually a folder) in the list.
end getProjektfolder

on getFlag(theFlagFolder, theName)
   set theFlagFolder to POSIX path of theFlagFolder
   set theFlagFolder to current application's |NSURL|'s fileURLWithPath:theFlagFolder
   set fileManager to current application's NSFileManager's defaultManager()
   set searchOptions to (current application's NSDirectoryEnumerationSkipsPackageDescendants) ¬
       + (current application's NSDirectoryEnumerationSkipsHiddenFiles as integer)
   set folderContents to (fileManager's enumeratorAtURL:theFlagFolder includingPropertiesForKeys:{} options:(searchOptions) errorHandler:(missing value))'s allObjects()
   
   set thePred to current application's NSPredicate's predicateWithFormat_("(lastPathComponent ==[c] %@)", theName)
   set theFiles to (folderContents's filteredArrayUsingPredicate:thePred) -- This is an NSArray containing 0 or more NSURLs.
   
   if (count theFiles) = 0 then
       
       -- This is where the script checks for the orphans and returns the path to the orphans folder.    
       
       return ("Macintosh HD:Users:me:Documents:deposit:orphans:") as alias -- 'as alias' assumes this folder already exists.
   else
       -- NB. firstObject(), and the parentheses after 'URLByDeletingLastPathComponent'.
       return (theFiles's firstObject()'s URLByDeletingLastPathComponent()) as alias
   end if
end getFlag

on errorDialog(dialogText)
   display dialog dialogText buttons {"OK"} default button 1 cancel button 1 with title "" with icon stop
end errorDialog


NG

Offline

 

#16 2021-06-06 01:40:17 pm

traegheitsmoment
Member
Registered: 2021-01-13
Posts: 43

Re: Script stops unexpectedly after 'delete' command

Hi Nigel,

thank you very much for your time.
I'm looking forward and I'm going to test it as soon as I'm in the office tomorrow...

Cheers
traegheitsmoment

Offline

 

#17 2021-06-07 11:08:05 am

traegheitsmoment
Member
Registered: 2021-01-13
Posts: 43

Re: Script stops unexpectedly after 'delete' command

Just a short update...

The script seems to fail to move the file to the targetFolder.
I haven't figured out why because it computes the targetFolder correctly.

I will let you know when I find out more...

Offline

 

Board footer

Powered by FluxBB

RSS (new topics) RSS (active topics)