I have made a folder action AppleScript which mainly gets the folder name with path of the attached folder and calls a ruby script with the pathname as the argument. This works perfectly but is there a way to embed this ruby file inside the AppleScript as a variable, so I don’t have to deal with two files?
I am new to this so if an example is provided would be great.
Thanks.
I am trying the code given below but getting an error "-e:82: syntax error, unexpected end-of-input, expecting keyword_end" number 1.
As instructed I have copied the file and inserted the escape \ character, not changed any code. the third commented line will run the program without any error.
set folder_name to quoted form of "/Volumes/HackSSD/Testing Space"
display dialog folder_name
--set makeDateFolders to "/Users/raj/Documents/ivfolders.rb " & folder_name
set rubyScript to "# ivfolder.rb
require 'set'
require 'benchmark'
require 'date'
require 'fileutils'
require 'open3'
raise ArgumentError, 'Expecting single command-line value' if ARGV.length > 1
def file_created_date(ivfile)
# Not all images have a uniform EXIF/IPTC tag name for created date/time.
# Use exiftool if installed and attempt three different date tags. If these
# find no creation date, return the System creation date.
# returns created_date as 'yyyy-mm-dd' string
exiftool = '/usr/local/bin/exiftool'
create_date = ''
if File.exist?(exiftool)
create_date, = Open3.capture2(exiftool, '-s3', '-d', '%F',
'-DateTimeOriginal',
'-FileModifyDate',
'-CreateDate',
ivfile)[0]
if create_date && create_date.count(\"\\n\") > 1
# n-tuple dates found, usually the same, but take oldest if present.
datestr = create_date.split(\"\\n\").min
elsif create_date
# one date, likely the FileModifyDate. Remove trailing newline
datestr = create_date.chomp
end
return datestr unless create_date.empty?
end
File.birthtime(ivfile).strftime('%F') if create_date.empty?
end
# check folder name to see if it is in YYYY-MM-DD format
def valid_date?(str, format = '%F')
Date.strptime(str, format)
rescue ArgumentError
false
end
# file excluded if not in this set.
extensions = Set.new(['.cr2', '.cr3', '.nef', 'dng', '.arw', '.gif', '.jpg',
'.jpeg', '.jp2', '.png', '.ai', '.psd', '.svg', '.tif',
'.tiff', '.heic', '.heif', '.mp4', '.hevc', '.mov',
'.m4v', '.avi', '.mts', '.mpg'])
folders = Set.new
matched_files = Set.new
filecnt = 0
foldercnt = 0
elapsed = Benchmark.realtime do
start_folder = File.expand_path(ARGV.first)
Dir.chdir(start_folder) do
Dir.glob(\"#{start_folder}/*.*\").select do |f|
matched_files << f if extensions.include?(File.extname(f.downcase))
end
# if previous run, collect existing folders matching yyyy-mm-dd
Dir.glob(\"#{start_folder}/*\").select do |f|
z = File.basename(f)
folders << z if valid_date?(z) && z.length == 10
end
matched_files.each do |f|
# create_date = File.birthtime(f).strftime('%F') # yyyy-mm-dd
create_date = file_created_date(f)
FileUtils.mkdir(create_date, mode: 0o0755, verbose: false)
unless folders.include?(create_date)
folders << create_date
FileUtils.mv(File.basename(f), create_date, verbose: false)
end
filecnt = matched_files.count
foldercnt = folders.count
end
end"
do shell script ("ruby -e " & (quoted form of rubyScript) & space & folder_name) -- run it
In my folder action script which is working fine I am taking care of when the folder action is triggered after a folder is created, the actual working script is given below. As mentioned earlier I want to embed the ruby script to not bother with an external file.
The Working Folder Action Script
on adding folder items to this_folder after receiving added_items
try
repeat with theCurrent_item in added_items
set filePosixPath to quoted form of (POSIX path of (theCurrent_item as alias))
set fileType to (do shell script "file -b " & filePosixPath) --Test if it is a directory
if fileType = "directory" then
return
end if
end repeat
set folder_name to quoted form of (POSIX path of (this_folder as alias))
set makeDateFolders to "/Users/raj/Documents/ivfolders.rb " & folder_name
do shell script makeDateFolders
end try
end adding folder items to
Best Answer
A Ruby script can be placed into an AppleScript string for use with
do shell script
, but note that special characters in the string such as backslash and double quotes will need to be escaped with a backslash. There are a couple of different arrangements you can use, my preference is a here document, for example:The
-e
option can also be used instead of the here document (see the Ruby man page), for example: