Hello Paul,
Sorry for late reply. It took me some time to try LiveCode Community myself. It is an open-source HyperCard of present day. Thanks for letting me know about this interesting software. 😉
Before writing about LiveCode specific issue, I'd like to post another version of script which will process every alias file in given directory tree as described in your last message. The first is Ruby script and the second is its AppleScript wrapper. Both scripts will accept a folder where target directory tree is rooted at and will process every alias file in the tree (except for those in package file) and print [unresolved alias path] => [retrieved target path].
1) Ruby script
#!/System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/bin/ruby -w
#
# This script will -
# 0) scan every alias file under given directory tree (except for those in package file); and
# 1) try to obtain bookmark data from alias file and if failed then return nothing;
# 2) try to resolve alias (bookmark data) and if successful then return the target path;
# 3) try to retrieve target path from bookmark data and if successful then return the target path;
#
# For 1), use NSURL +bookmarkDataWithContentsOfURL:error:
# For 2), use NSURL +URLByResolvingBookmarkData:options:relativeToURL:bookmarkDataIsStale:error:
# For 3), use NSURL +resourceValuesForKeys:fromBookmarkData:
#
# These methods are available under 10.6 or later.
# However, 3) uses NSURLPathKey, which is only available under 10.8 or later.
#
require 'osx/cocoa'
include OSX
begin
URLKEY = NSURLPathKey # 10.8 or later
rescue
URLKEY = NSURLNameKey # 10.6 or later (fallback)
end
def resolve_alias(f, opts = {})
#
# string f : POSIX path of alias file
# hash opts : {:quiet => boolean}
# :quiet => true to suppress error message, false otherwise; default = false
# return array : [rc, f1]
# rc = return code
# 0 = alias is resolved
# 1 = alias is not resolved but target is retrieved
# 2 = target is not retrieved
# 3 = bookmark data is not obtained (e.g., f is not alias)
# f1 = POSIX path of target file or nil if failed
#
opts = {:quiet => false}.merge(opts)
url = NSURL.fileURLWithPath(f)
err = OCObject.new
bmrk = NSURL.objc_send(
:bookmarkDataWithContentsOfURL, url,
:error, err)
unless bmrk
$stderr.puts %[#\t%s\t=>\tError: failed to get bookmark data - %s] % [f, err] unless opts[:quiet]
return [3, nil]
end
stale = ObjcPtr.new(:char) # BOOL*
err = OCObject.new
url1 = NSURL.objc_send(
:URLByResolvingBookmarkData, bmrk,
:options, NSURLBookmarkResolutionWithoutMounting | NSURLBookmarkResolutionWithoutUI,
:relativeToURL, nil,
:bookmarkDataIsStale, stale,
:error, err)
unless url1
$stderr.puts %[#\t%s\t=>\tWarning: failed to resolve alias - %s] % [f, err] unless opts[:quiet]
dict = NSURL.objc_send(
:resourceValuesForKeys, [URLKEY],
:fromBookmarkData, bmrk)
path2 = dict[URLKEY]
unless path2
$stderr.puts %[#\t%s\t=>\tError: failed to get target path - %s] % [f, err] unless opts[:quiet]
return [2, nil]
else
return [1, path2]
end
end
if stale.bool != 0
$stderr.puts %[#\t%s\t=>\tWarning: stale alias.] % f unless opts[:quiet]
end
return [0, url1.path]
end
raise ArgumentError, %Q[Usage: #{File.basename($0)} directory] unless ARGV.length == 1
dir, = ARGV.map { |a| a == '/' ? a : a.chomp('/')}
denum = NSFileManager.defaultManager.enumeratorAtPath(dir)
wks = NSWorkspace.sharedWorkspace
aa = [] # list of aliases under dir
while (f = denum.nextObject) != nil do
file = dir + '/' + f.to_s
denum.skipDescendants if wks.isFilePackageAtPath(file) # ignore package contents
if denum.fileAttributes.objectForKey(NSFileType) == NSFileTypeRegular
aa << file if wks.objc_send(:typeOfFile, file, :error, nil) == 'com.apple.alias-file'
end
end
aa.each do |f|
rc, f1 = resolve_alias(f, :quiet => true)
# puts %[%s\t=>\t%s] % [f, f1] if rc < 2 # shows all aliases that is resolved or whose target is retrieved.
puts %[%s\t=>\t%s] % [f, f1] if rc == 1 # shows aliases that is not resolved but whose target is retrieved.
end
2) AppleScript wrapper
_main()
on _main()
set d to (choose folder with prompt "Choose folder where target directory tree is rooted at.")'s POSIX path
do shell script "/System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/bin/ruby -w <<'EOF' - " & d's quoted form & "
#
# This script will -
# 0) scan every alias file under given directory tree (except for those in package file); and
# 1) try to obtain bookmark data from alias file and if failed then return nothing;
# 2) try to resolve alias (bookmark data) and if successful then return the target path;
# 3) try to retrieve target path from bookmark data and if successful then return the target path;
#
# For 1), use NSURL +bookmarkDataWithContentsOfURL:error:
# For 2), use NSURL +URLByResolvingBookmarkData:options:relativeToURL:bookmarkDataIsStale:error:
# For 3), use NSURL +resourceValuesForKeys:fromBookmarkData:
#
# These methods are available under 10.6 or later.
# However, 3) uses NSURLPathKey, which is only available under 10.8 or later.
#
require 'osx/cocoa'
include OSX
begin
URLKEY = NSURLPathKey # 10.8 or later
rescue
URLKEY = NSURLNameKey # 10.6 or later (fallback)
end
def resolve_alias(f, opts = {})
#
# string f : POSIX path of alias file
# hash opts : {:quiet => boolean}
# :quiet => true to suppress error message, false otherwise; default = false
# return array : [rc, f1]
# rc = return code
# 0 = alias is resolved
# 1 = alias is not resolved but target is retrieved
# 2 = target is not retrieved
# 3 = bookmark data is not obtained (e.g., f is not alias)
# f1 = POSIX path of target file or nil if failed
#
opts = {:quiet => false}.merge(opts)
url = NSURL.fileURLWithPath(f)
err = OCObject.new
bmrk = NSURL.objc_send(
:bookmarkDataWithContentsOfURL, url,
:error, err)
unless bmrk
$stderr.puts %[#\\t%s\\t=>\\tError: failed to get bookmark data - %s] % [f, err] unless opts[:quiet]
return [3, nil]
end
stale = ObjcPtr.new(:char) # BOOL*
err = OCObject.new
url1 = NSURL.objc_send(
:URLByResolvingBookmarkData, bmrk,
:options, NSURLBookmarkResolutionWithoutMounting | NSURLBookmarkResolutionWithoutUI,
:relativeToURL, nil,
:bookmarkDataIsStale, stale,
:error, err)
unless url1
$stderr.puts %[#\\t%s\\t=>\\tWarning: failed to resolve alias - %s] % [f, err] unless opts[:quiet]
dict = NSURL.objc_send(
:resourceValuesForKeys, [URLKEY],
:fromBookmarkData, bmrk)
path2 = dict[URLKEY]
unless path2
$stderr.puts %[#\\t%s\\t=>\\tError: failed to get target path - %s] % [f, err] unless opts[:quiet]
return [2, nil]
else
return [1, path2]
end
end
if stale.bool != 0
$stderr.puts %[#\\t%s\\t=>\\tWarning: stale alias.] % f unless opts[:quiet]
end
return [0, url1.path]
end
raise ArgumentError, %Q[Usage: #{File.basename($0)} directory] unless ARGV.length == 1
dir, = ARGV.map { |a| a == '/' ? a : a.chomp('/')}
denum = NSFileManager.defaultManager.enumeratorAtPath(dir)
wks = NSWorkspace.sharedWorkspace
aa = [] # list of aliases under dir
while (f = denum.nextObject) != nil do
file = dir + '/' + f.to_s
denum.skipDescendants if wks.isFilePackageAtPath(file) # ignore package contents
if denum.fileAttributes.objectForKey(NSFileType) == NSFileTypeRegular
aa << file if wks.objc_send(:typeOfFile, file, :error, nil) == 'com.apple.alias-file'
end
end
aa.each do |f|
rc, f1 = resolve_alias(f, :quiet => true)
# puts %[%s\\t=>\\t%s] % [f, f1] if rc < 2 # shows all aliases that is resolved or whose target is retrieved.
puts %[%s\\t=>\\t%s] % [f, f1] if rc == 1 # shows aliases that is not resolved but whose target is retrieved.
end
EOF"
end _main
I'm going to write about LiveCode specific issues in separate reply.
Regards,
H