Hello to everyone,
I’m new in Applescript and obviously I have some trouble…
I would like to extract from my website, some files used for one extension, the problem is that they are a ton of files and they are around the whole filesystem…
So, I would like to have an Applescript who:
ask a for a reference folder, who is used to detect the stricuture of folders and files to copy,
ask for a source folder
ask a destination folder
copy all the files from the source using reference as file list, to the destination folder
Is it complicated? I tryed but nothing good…
Applescript copy files/folders from a source using a second source
To help, we would need a better description of what this script is supposed to do. I don’t understand what the script does differently from simply copying files from one folder to another:
I’m not sure what this means. Can you provide the structure of samples of the three folders, showing the initial condition and desired result for the destination folder?
Reference: is the original structure files for the plugin, and this is the source list of files and folder I should to copy example
Folder A
File 1
File 2
Subfolder A
File 3
File 4
Source: is the whole website installation, contains thousands of files and plugins
Folder A
File 1
File 2
File 5
File 6
Subfolder A
File 3
File 4
Folder B
Folder C
Destination: the location where the script should copy and replicate the files and folders from source
I’m not sure is well explained, tell me if something isn’t clear.
Sorry, I’m still not getting it… If Reference contains all the files and folders you need copied, laid out correctly, then why not just copy it to the destination? Why is “Source” even involved?
I don’t understand what information is being extracted from “Reference,” or how it is to be applied to the data in “Source.”
Hello Tom,
yes as is isn’t pretty clear, you need some explanation…
Reference contains original files.
Source contains files in the production enviroment who probably are not the same version as in the reference, so I need to extract the files from the source and not from the reference.
So, I know which files I need (reference) but it’s hard to extract manually from source because there are tons of files and directory.
If I understand well what you need, the script below will do the job.
use AppleScript version "2.4" -- Yosemite (10.10) or later
use framework "Foundation"
use scripting additions
property skipHiddenFiles : false
--> true means : skip the hidden files
--> false means : copy the hidden files
on run
my germaine()
end run
on germaine()
set templateFolder to POSIX path of ((path to desktop folder as text) & "Charts for Adam") # Edit to fit your needs
set templateFolder to POSIX path of "Macintosh HD:Macintosh …2.0:Dossier ClarisWorks 5.0:"
set sourceFolder to POSIX path of ((path to desktop folder as text) & "sourceFolder") # Edit to fit your needs
set targetFolder to POSIX path of ((path to desktop folder as text) & "targetFolder") # Edit to fit your needs
(*
set templateFolder to POSIX path of (choose folder with prompt "Reference")
set sourceFolder to POSIX path of (choose folder with prompt "Source")
set targetFolder to POSIX path of (choose folder with prompt "Destination")
*)
set |⌘| to current application
set fileManager to |⌘|'s NSFileManager's defaultManager()
set rootURL to |⌘|'s |NSURL|'s fileURLWithPath:templateFolder
set rootLength to (rootURL's |path|()'s |length|()) + 1 -- used to trim paths
if skipHiddenFiles then
# Use this one if hidden files must be ignored.
set theOptions to (|⌘|'s NSDirectoryEnumerationSkipsPackageDescendants as integer) + (|⌘|'s NSDirectoryEnumerationSkipsHiddenFiles as integer)
else
# Use this one if hidden files must be copied
set theOptions to (|⌘|'s NSDirectoryEnumerationSkipsPackageDescendants as integer)
end if
set theEnumerator to fileManager's enumeratorAtURL:rootURL includingPropertiesForKeys:{} options:theOptions errorHandler:(missing value)
set sourceFolder to |⌘|'s NSString's stringWithString:sourceFolder
set targetFolder to |⌘|'s NSString's stringWithString:targetFolder
repeat with oneURL in theEnumerator's allObjects()
# Got one URL
# Drop the path to the templateFolder
set oneRelative to (oneURL's |path|()'s substringFromIndex:rootLength)
# Build the URL of the source item
set theSourceURL to (|⌘|'s |NSURL|'s fileURLWithPath:(sourceFolder's stringByAppendingPathComponent:oneRelative))
# Build the URL of the target item
set theDestURL to (|⌘|'s |NSURL|'s fileURLWithPath:(targetFolder's stringByAppendingPathComponent:oneRelative))
# Copy the source item in the target item
(my copyFromURL:theSourceURL toURL:theDestURL withReplacing:true)
end repeat
end germaine
#=====#=====#=====#=====#=====#=====
-- This handler - borrowed from Shane STANLEY - 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:
#=====#=====#=====#=====#=====#=====
Yvan KOENIG running Sierra 10.12.2 in French (VALLAURIS, France) mardi 17 janvier 2017 11:59:55
How did you extracted the script from my message ?
The correct way is to use the dedicated button [Open this Scriplet in your Editor]
If you didn’t use it, please redo the entire process to be sure that what you are trying to use is the correct code.
Second question: which system are you running ?
When a question doesn’t name a specific system, I assume that the asker use the current system but here, as you may see, the first instruction clearly state that the script is designed for Yosemite (10.10) or later.
Third question: as you edited the instructions defining the three required path, are the new values of the correct format : POSIX path ?
I can’t help more because I am unable to reproduce what you got.
May you paste here the instructions defining your three required paths ? I’m wondering if the problem may be linked to the fact that at least the first path is pointing to a website.
It may be useful to explain why I use the structure :
on run
my germaine()
end run
on germaine()
.
It just gets rid of the boring message claiming "Can’t save the script because ASObjC pointers can’t be saved"
I rewrote the message according to what my memory said. It may be far from perfect because I didn’t saw it for months.
Yvan KOENIG running Sierra 10.12.2 in French (VALLAURIS, France) mardi 17 janvier 2017 14:30:51
yes, I used the link “Open this Scriplet in your Editor:”
my system is 10.12.2
I changed the code:
set templateFolder to POSIX path of ((path to desktop folder as text) & "Charts for Adam") # Edit to fit your needs
set sourceFolder to POSIX path of ((path to desktop folder as text) & "sourceFolder") # Edit to fit your needs
set targetFolder to POSIX path of ((path to desktop folder as text) & "targetFolder") # Edit to fit your needs
With che code:
set templateFolder to choose folder with prompt "Reference"
set tempplateFolder to POSIX path of templateFolder
set sourceFolder to choose folder with prompt "Source"
set sourceFolder to POSIX path of sourceFolder
set targetFolder to choose folder with prompt "Destination"
set targetFolder to POSIX path of targetFolder
Your instructions are correct but they say nothing about the used paths.
I assume that the problem is linked to the fact that at least the first path - templateFolder - is supposed to point to a webSite.
It would be useful to know exactly the pathnames, at this time mainly the first one, because the command using |length| apply to this one.
If you are reluctant to pass it in the thread, you may send it (better to pass the three) to my mailbox :
[format]k o e n i g . y v a n @ s f r . f r[/format]
With these infos I would be able to ask for complementary help if I can’t solve the problem on my side.
Yvan KOENIG running Sierra 10.12.2 in French (VALLAURIS, France) mardi 17 janvier 2017 15:33:32
Well, I think I understand what you need now… but thanks Yvan for stepping in, because now that I understand the problem, I don’t think I would have contributed a solution, because I think it would have taken me longer to write than my threshold for helping people on forums.
If what you posted match your real code, there is a sad typo in it. I commented it above and post the code modified to fit your needs in message #6.
I tested here and, when - as your code does - the script try to execute the instruction
set aURL to |⌘|'s |NSURL|'s fileURLWithPath:templateFolder
with templateFolder defined as an alias (what is returned by choose folder) I really get the offending :
[format]error “-[NSURL length]: unrecognized selector sent to instance 0x6000012af0c0” number -10000[/format]
I concatenated some instructions to get a more compact code.
Yvan KOENIG running Sierra 10.12.2 in French (VALLAURIS, France) mardi 17 janvier 2017 17:56:50