How to change filename before duplicating Applescript - applescript

Currently I have a Applescript that does the following:
Copy a file from a certain directory to the current opened finder window.
Open a dialog box to rename this file.
However, it would be nicer if the dialog box to specify a name pops up before the moving takes place, so the original file is not copied first and then renamed. Could anyone help me how to achieve this?
property y : POSIX file "/Users/thijmendam/Documents/Newfile/Naamloos.txt" as alias
tell application "Finder"
set x to target of window 1 as alias
duplicate y to x
set name of file "Naamloos.txt" of folder x to the text returned of (display dialog "Rename" default answer "")
end tell

This should do it:
property y : POSIX file "/Users/thijmendam/Documents/Newfile/Naamloos.txt" as alias
tell application "Finder"
set x to target of window 1 as alias
set newFileName to text returned of (display dialog "Rename" default answer "")
set name of (duplicate y to x with replacing) to newFileName
end tell
I added with replacing to prevent an error being thrown if a file of that name already exists. You can remove this or just add a try...on error...end try error-catching block to cater for this situation.
The Terminal command cp can also be used to copy files from the command line. This will copy the file myfile.ext from the Desktop to the Documents folder without renaming it:
cp ~/Desktop/myfile.ext ~/Documents/
This will copy and rename the file in one go:
cp ~/Desktop/myfile.ext ~/Documents/renamed.ext
Note that cp will overwrite existing files without warning.
You can execute Terminal commands directly from within AppleScript using do shell script.
Implementing this with the AppleScript above could be done like this:
property y : POSIX file "/Users/CK/Desktop/syringet.jpg" as alias
tell application "Finder"
set x to POSIX path of (target of front window as alias)
set newFileName to text returned of (display dialog "Rename" default answer "")
set y to POSIX path of y
end tell
set command to "cp " & quoted form of y & " " & quoted form of ([x, newFileName] as text)
do shell script command
On a final note, if you didn't want to have to specify the file's extension in the dialog box (as it's unlikely you'll need to change that), you can make use of the name extension property. In the case of Naamloos.txt, the value of this property will be "txt".
Amend the scripts to reflect this implementation:
set name of (duplicate y to x with replacing) to newFileName & "." & name extension of y
in the first instance, or:
...
set [ext, y] to [name extension, POSIX path] of y
end tell
set command to "cp " & quoted form of y & " " & quoted form of ([x, newFileName, ".", ext] as text)

Related

Applescript: can't make file "xx" into type <<class fsrf>>

I'm trying to get a script working which is able to batch export .mts format video files via quicktime into .mov files in 1080p. The script fails with the following error: "The action “Run AppleScript” encountered an error: “QuickTime Player got an error: Can’t make file (document "00000.MTS") into type «class fsrf».”". I assume this has something to do with using text file paths? Note I'm not experienced with Applescript and would really appreciate any help to get this simple bit of script working. Currently it's in automator as a service:
on run {inputFiles}
if inputFiles is equal to {} then
set inputFiles to (choose file with prompt "Select the file(s) to convert:" with multiple selections allowed without invisibles)
end if
open inputFiles
end run
on open droppedItems
tell application "Finder" to set inputFolder to (container of first item of droppedItems) as Unicode text
set outputFolder to (choose folder with prompt "Select output folder:" default location (inputFolder as alias)) as Unicode text
set exportPreset to (choose from list {"Movie", "iPhone", "iPod", "480p", "720p", "1080p"} with prompt "Choose QuickTime Export Preset:") as Unicode text
if exportPreset is equal to "false" then
return
end if
repeat with currentItem in droppedItems
repeat until getProcessPercentCPU("CoreMediaAuthoringSessionHelper") is equal to ""
end repeat
tell application "Finder" to set fileName to name of currentItem as Unicode text
set fileName to text 1 thru ((fileName's length) - (offset of "." in ¬
(the reverse of every character of fileName) as text)) of fileName
convertFile(currentItem, outputFolder & fileName & ".mov", exportPreset)
end repeat
end open
on convertFile(inputFile, outputFile, exportPreset)
tell application "QuickTime Player"
set thisMovie to open inputFile
open for access file thisMovie
close access file thisMovie
export thisMovie in (outputFile) using settings preset exportPreset
close thisMovie
end tell
end convertFile
on getProcessPercentCPU(processName)
do shell script "/bin/ps -xco %cpu,command | /usr/bin/awk '/" & processName & "$/ {print $1}'"
end getProcessPercentCPU
Try changing:
set outputFolder to (choose folder with prompt "Select output folder:" default location (inputFolder as alias)) as Unicode text
to:
set outputFolder to POSIX path of (choose folder with prompt "Select output folder:" default location (inputFolder as alias))
and:
convertFile(currentItem, outputFolder & fileName & ".mov", exportPreset)
to:
set outputFile to POSIX file (outputFolder & fileName & ".mov")
convertFile(currentItem, outputFile, exportPreset)
and remove the open for access/close access commands.
Sandboxed apps don't like receiving path strings to open/save commands, but accept alias/POSIX file values okay. (If it still doesn't work then it's some other issue at play, but that's always the first thing to check when you get a filesystem permissions error as you describe.)
The error occurs because thisMovie is a document reference of QuickTime Player and this class cannot be converted / coerced to a file system reference («class fsrf»).
That's what the error message says
Can’t make file (document "00000.MTS") into type «class fsrf»
The Standard Additions command open for access does not support QuickTime Player documents anyway. What is the purpose of the open / close lines?
Note:
as Unicode text as coercion to string is outdated since macOS 10.5 Leopard. It's only used with read and write commands to handle UTF16 encoded text. A coercion to standard AppleScript text is simply written as text. In case of name of currentItem it's redundant anyway because the class of name is always text.

OSX: How can check whether a file exists in current directory using applescript?

I want to make an automator app which creates an empty file in current directory.
I did some google search and found:
http://hints.macworld.com/article.php?story=20050219134457298 and http://hints.macworld.com/article.php?story=20100509134904820
However, I want to do something more powerful.
If the specified file already exists, I want to show a warning instead of overwriting the original file, which is what one of the above link does. (The other one creates a text file using textEdit. I do not want to create text file. I want an empty file like what linux/unix does)
I already figured out how to do most of the part, but
How can check whether a file exists in current directory using applescript??
How can I concatenate two variable in applescript?
Checking if a file exists (assuming thefullpath is already set as in the referenced question):
tell application "Finder"
if exists POSIX file thefullpath then
--do something here like
display alert "Warning: the file already exists"
end if
end tell
Not sure what you mean by the second part but if you want to concatenate strings stored in var1 and var2 you could simply do
var1 & var2
Something I have been using a lot of late for this sort of thing is the command /bin/test
The test test for the existence of in this case a file
if (do shell script "/bin/test -e " & quoted form of (POSIX path of theFile) & " ; echo $?") is "1" then
-- 1 is false
--do something
end if
The -e option:
-e file True if file exists (regardless of type).
The are tons of other test options shown in the /bin/test man page
The following code, adapted from your second link, is usually right, but it doesn't always work. The current directory is better specified as the directory of the document that is being opened which is most likely from the Finder's front window, but not necessarily. I like to write code that will work no matter what.
on run {input, parameters}
tell application "Finder"
set currentPath to insertion location as text
set x to POSIX path of currentPath
display dialog "currentPath: " & (x as text)
end tell
return x
end run
I wrote a whole "Run AppleScript" action to put things into context:
on run {input, parameters}
# count the number of files
set numFiles to 0
repeat with f in input
# warn the user that folders are not processed in this app
tell application "Finder"
if (kind of f is "Folder") then
display dialog "The item: " & (f as text) & " is a folder. Only files are allowed. Do you want to continue processing files or do you want to cancel?"
else
set numFiles to numFiles + 1
end if
end tell
end repeat
# require that at least one file is being opened
if numFiles < 1 then
display alert "Error: the application Test1.app cannot be run because it requires at least one file as input"
error number -128
end if
# get the current directory from the first file
set theFirstFile to (item 1 of input)
tell application "System Events" to set theFolder to (container of theFirstFile)
# ask the user for a file name
set thefilename to text returned of (display dialog "Create file named:" default answer "filename")
# create the file
tell application "System Events" to set thefullpath to (POSIX path of theFolder) & "/" & thefilename
set theCommand to "touch \"" & thefullpath & "\""
do shell script theCommand
# return the input as the output
return input
end run
The "touch" command is OK. If the file doesn't exist, it is created and if it does exist, only the modification date is changed (which isn't too bad) but it doesn't overwrite the file. If your file is being overwritten, it's not the touch command that is doing it.
I changed the default file name to remove the extension ".txt" This extension may default to being opened by TextEdit.app, but you can change this in the Finder by choosing "Get Info" for a file and changing the "Open With" property. You can change which application opens the file with that extension or you can change them all. For example, all of my ".txt" files are opened with BBEdit.app
Will you vote my answer up?
Another option that doesn't require Finder or System Events is to try to coerce a POSIX file or file object to an alias:
try
POSIX file "/tmp/test" as alias
true
on error
false
end try

AppleScript to read text file containing file names, search for each file name, and if a file is found copy it to a folder

Sorry to ask a question without even pasting my coding attempt, but I've never used AppleScript before and I have no idea how I would do this. I've found bits of code online that do small parts of each step of this, but some of the key parts I can't figure out how to do. If I can get this figured out it would save a lot of time. Basically my problem is that a client sent over thousands of photos, all in multiple levels of sub folders, along with an Excel document containing about 300 file names that I need to pull out and use. I can copy the file names from the Excel document into a plain text file, either multi-line or comma separated.
So this is what I need to do:
Open folder selector dialog to select the destination folder
Open file selector dialog to select the text file
Loop through each line (or comma separated value) of the text file
Take that string and search for a file name containing the string
Copy the first result into a folder (let's say Desktop:Found Photos)
If a file could not be found matching the string then add the search string into a text file (so I could email it to the client and ask them to send it to me)
If you can't code this whole process, if you could help me with looping through the text file, searching for the file name and copying the first result to another folder, and adding the file name to a text file if a file wasn't found, then I could probably piece it it all together. Thanks for any help.
You can try something along the lines of:
set newFolder to POSIX path of (path to desktop as text) & "Found Photos"
do shell script "mkdir -p " & quoted form of newFolder
set filePaths to paragraphs of (read (choose file with prompt "Select file list") as «class utf8»)
set fileFolder to POSIX path of (choose folder with prompt "Select folder containing files")
set foundFiles to {}
repeat with fileName in filePaths
set fileName to (contents of fileName)
set xxx to do shell script "find " & quoted form of fileFolder & " -name " & quoted form of fileName
if xxx ≠ "" then
tell application "System Events" to move file xxx to newFolder
set end of foundFiles to fileName & return
end if
end repeat
set foundFiles to (foundFiles as text)
do shell script "echo " & quoted form of foundFiles & " > " & quoted form of POSIX path of ((path to desktop as text) & "FoundFiles.txt")
It might have been easier to use shell scripting:
IFS=$'\n'
mkdir -p ~/Desktop/target/
for l in $(cat ~/Desktop/files.txt); do
found=$(find ~/Documents/source -type f -name "*$l*")
[[ -n $found ]] && cp $found ~/Desktop/target/ || echo "$l"
done

applescript get rid of full path

I've got a choose file in my AppleScript. When I run the script and choose a file, the output is always the full file path with the file extension on the end. For example:
Macintosh HD:Developer:About Xcode.pdf
is what I don't want. I only want:
About Xcode
The below answer by Kassym Dorsel doesn't work when there is more than one . in it.
The below answer by Lri doesn't work with set x to choose file:
error "Can’t make quoted form of alias \"Macintosh HD:Applications:Firefox.app:\" into type Unicode text." number -1700 from quoted form of alias "Macintosh HD:Applications:Firefox.app:" to Unicode text
You can use the Finder to manipulate the names of Finder items:
choose file with prompt "Pick one"
set filepath to result
tell application "Finder" to set {dispName, nameExt, isHidden} to ¬
the {displayed name, name extension, extension hidden} of the filepath
if isHidden or nameExt is equal to "" then
dispName
else
(characters 1 through (-2 - (count of nameExt)) of dispName) as text
end if
set baseName to result
This will work :
set a to "Macintosh HD:Developer:About.Xcode.pdf"
set text item delimiters to ":"
set temp to last text item of a
set text item delimiters to "."
set temp to text items 1 thru -2 of temp as text
Gives => About.Xcode

Getting the file name of files dropped on the script

I made this Applescript script to create symbolic links.
Appart from POSIX path of, how can I get the file name, without the path, of the dropped file?
on open filelist
repeat with i in filelist
do shell script "ln -s " & POSIX path of i & " /Users/me/Desktop/symlink"
end repeat
end open
PS: I know this expects many files to be dropped and tries to create many links with the same name, which gives an error. Actually I copied this example from a website and as I don't know almost anything about Applescript, I don't know how to do this for a single file, help on that would be appreciated too.
I'm not sure what precisely you're trying to do, but I have a guess. Is the idea that you want to take every file dropped on the script and create a symbolic link to each one on the Desktop? So if I drop ~/look/at/me and ~/an/example, you'll have ~/Desktop/me and ~/Desktop/example? If that's what you want, then you're in luck: ln -s <file1> <file2> ... <directory> does exactly that. (Edit: Although you have to watch out for the two-argument case.) Thus, your code could look like this:
-- EDITED: Added the conditional setting of `dest` to prevent errors in the
-- two-arguments-to-ln case (see my comment).
on quoted(f)
return quoted form of POSIX path of f
end quoted
on open filelist
if filelist is {} then return
set dest to missing value
if (count of filelist) is 1 then
tell application "System Events" to set n to the name of item 1 of filelist
set dest to (path to desktop as string) & n
else
set dest to path to desktop
end if
set cmd to "ln -s"
repeat with f in filelist & dest
set cmd to cmd & " " & quoted(f)
end repeat
do shell script cmd
end open
Note the use of quoted form of; it wraps its argument in single quotes so executing in in the shell won't do anything funny.
If you want to get at the name of the file for another reason, you don't need to call out to the Finder; you can use System Events instead:
tell application "System Events" to get name of myAlias
will return the name of the file stored in myAlias.
Edit: If you want to do something to a single file, it's pretty easy. Instead of using repeat to iterate over every file, just perform the same action on the first file, accessed by item 1 of theList. So in this case, you might want something like this:
-- EDITED: Fixed the "linking a directory" case (see my comment).
on quoted(f)
return quoted form of POSIX path of f
end quoted
on open filelist
if filelist is {} then return
set f to item 1 of filelist
tell application "System Events" to set n to the name of f
do shell script "ln -s " & ¬
quoted(f) & " " & quoted((path to desktop as string) & n)
end open
It's pretty much the same, but we grab the first item in filelist and ignore the rest. Additionally, at the end, we display a dialog containing the name of the symlink, so the user knows what just happened.
As an example, you can work with the Finder instead of a shell script to get the name of a single file that is dropped on the script that is saved as an application. If you don't need the display dialog, you can remove it, but you have the file name as a variable to work with:
on open the_files
repeat with i from 1 to the count of the_files
tell application "Finder"
set myFileName to name of (item i of the_files)
end tell
display dialog "The file's name is " & myFileName
end repeat
end open

Resources