Not sure if any of these are relevant, but FWIW some composable Lego bricks:
use AppleScript version "2.4"
use framework "Foundation"
use scripting additions
-- Write a string to the end of a file.
-- Returns true if the path exists
-- and the write succeeded.
-- Otherwise returns false.
-- appendFile :: FilePath -> String -> IO Bool
on appendFile(strPath, txt)
set ca to current application
set oFullPath to (ca's NSString's stringWithString:strPath)'s ¬
stringByStandardizingPath
set {blnExists, intFolder} to (ca's NSFileManager's defaultManager()'s ¬
fileExistsAtPath:oFullPath isDirectory:(reference))
if blnExists then
if intFolder = 0 then
set oData to (ca's NSString's stringWithString:txt)'s ¬
dataUsingEncoding:(ca's NSUTF8StringEncoding)
set h to ca's NSFileHandle's fileHandleForWritingAtPath:oFullPath
h's seekToEndOfFile
h's writeData:oData
h's closeFile()
true
else
-- text appended to folder is undefined
false
end if
else
if doesDirectoryExist(takeDirectory(oFullPath as string)) then
writeFile(oFullPath, txt)
true
else
false
end if
end if
end appendFile
-- Write a string to the end of a file.
-- Returns a Just FilePath value if the
-- path exists and the write succeeded.
-- Otherwise returns Nothing.
-- appendFileMay :: FilePath -> String -> Maybe IO FilePath
on appendFileMay(strPath, txt)
set ca to current application
set oFullPath to (ca's NSString's stringWithString:strPath)'s ¬
stringByStandardizingPath
set strFullPath to oFullPath as string
set {blnExists, intFolder} to (ca's NSFileManager's defaultManager()'s ¬
fileExistsAtPath:oFullPath isDirectory:(reference))
if blnExists then
if intFolder = 0 then -- Not a directory
set oData to (ca's NSString's stringWithString:txt)'s ¬
dataUsingEncoding:(ca's NSUTF8StringEncoding)
set h to ca's NSFileHandle's fileHandleForWritingAtPath:oFullPath
h's seekToEndOfFile
h's writeData:oData
h's closeFile()
Just(strFullPath)
else
Nothing()
end if
else
if doesDirectoryExist(takeDirectory(strFullPath)) then
writeFile(oFullPath, txt)
Just(strFullPath)
else
Nothing()
end if
end if
end appendFileMay
-- createDirectoryIfMissingMay :: Bool -> FilePath -> Maybe IO ()
on createDirectoryIfMissingMay(blnParents, fp)
if doesPathExist(fp) then
Nothing()
else
set e to reference
set ca to current application
set oPath to (ca's NSString's stringWithString:(fp))'s ¬
stringByStandardizingPath
set {bool, nse} to ca's NSFileManager's ¬
defaultManager's createDirectoryAtPath:(oPath) ¬
withIntermediateDirectories:(blnParents) ¬
attributes:(missing value) |error|:(e)
if bool then
Just(fp)
else
Nothing()
end if
end if
end createDirectoryIfMissingMay
-- doesDirectoryExist :: FilePath -> IO Bool
on doesDirectoryExist(strPath)
set ca to current application
set oPath to (ca's NSString's stringWithString:strPath)'s ¬
stringByStandardizingPath
set {bln, int} to (ca's NSFileManager's defaultManager's ¬
fileExistsAtPath:oPath isDirectory:(reference))
bln and (int = 1)
end doesDirectoryExist
-- doesFileExist :: FilePath -> IO Bool
on doesFileExist(strPath)
set ca to current application
set oPath to (ca's NSString's stringWithString:strPath)'s ¬
stringByStandardizingPath
set {bln, int} to (ca's NSFileManager's defaultManager's ¬
fileExistsAtPath:oPath isDirectory:(reference))
bln and (int ≠1)
end doesFileExist
-- doesPathExist :: FilePath -> IO Bool
on doesPathExist(strPath)
set ca to current application
ca's NSFileManager's defaultManager's ¬
fileExistsAtPath:((ca's NSString's ¬
stringWithString:strPath)'s ¬
stringByStandardizingPath)
end doesPathExist
-- filePath :: String -> FilePath
on filePath(s)
((current application's ¬
NSString's stringWithString:s)'s ¬
stringByStandardizingPath()) as string
end filePath
-- fileSize :: FilePath -> Either String Int
on fileSize(fp)
script fs
on |λ|(rec)
|Right|(NSFileSize of rec)
end |λ|
end script
bindLR(my fileStatus(fp), fs)
end fileSize
-- fileStatus :: FilePath -> Either String Dict
on fileStatus(fp)
set e to reference
set {v, e} to current application's NSFileManager's defaultManager's ¬
attributesOfItemAtPath:fp |error|:e
if v is not missing value then
|Right|(v as record)
else
|Left|((localizedDescription of e) as string)
end if
end fileStatus
-- getCurrentDirectory :: IO FilePath
on getCurrentDirectory()
set ca to current application
ca's NSFileManager's defaultManager()'s currentDirectoryPath as string
end getCurrentDirectory
-- getDirectoryContents :: FilePath -> IO [FilePath]
on getDirectoryContents(strPath)
set ca to current application
unwrap(ca's NSFileManager's defaultManager()'s ¬
contentsOfDirectoryAtPath:unwrap(stringByStandardizingPath of wrap(strPath)) |error|:(missing value))
end getDirectoryContents
-- getFinderDirectory :: IO FilePath
on getFinderDirectory()
tell application "Finder" to POSIX path of (insertion location as alias)
end getFinderDirectory
-- getHomeDirectory :: IO FilePath
on getHomeDirectory()
current application's NSHomeDirectory() as string
end getHomeDirectory
-- getTemporaryDirectory :: IO FilePath
on getTemporaryDirectory()
current application's NSTemporaryDirectory() as string
end getTemporaryDirectory
-- listDirectory :: FilePath -> [FilePath]
on listDirectory(strPath)
set ca to current application
unwrap(ca's NSFileManager's defaultManager()'s ¬
contentsOfDirectoryAtPath:(unwrap(stringByStandardizingPath of ¬
wrap(strPath))) |error|:(missing value))
end listDirectory
-- readFile :: FilePath -> IO String
on readFile(strPath)
set ca to current application
set e to reference
set {s, e} to (ca's NSString's ¬
stringWithContentsOfFile:((ca's NSString's ¬
stringWithString:strPath)'s ¬
stringByStandardizingPath) ¬
encoding:(ca's NSUTF8StringEncoding) |error|:(e))
if e is missing value then
s as string
else
(localizedDescription of e) as string
end if
end readFile
-- readFileMay :: FilePath -> Maybe String
on readFileMay(strPath)
set ca to current application
set e to reference
set {s, e} to (ca's NSString's ¬
stringWithContentsOfFile:((ca's NSString's ¬
stringWithString:strPath)'s ¬
stringByStandardizingPath) ¬
encoding:(ca's NSUTF8StringEncoding) |error|:(e))
if e is missing value then
Just(s as string)
else
Nothing()
end if
end readFileMay
-- setCurrentDirectory :: String -> IO ()
on setCurrentDirectory(strPath)
if doesDirectoryExist(strPath) then
set ca to current application
set oPath to (ca's NSString's stringWithString:strPath)'s ¬
stringByStandardizingPath
ca's NSFileManager's defaultManager()'s ¬
changeCurrentDirectoryPath:oPath
end if
end setCurrentDirectory
-- Split a filename into directory and file. combine is the inverse.
-- splitFileName :: FilePath -> (String, String)
on splitFileName(strPath)
if strPath ≠"" then
if last character of strPath ≠"/" then
set xs to splitOn("/", strPath)
set stem to init(xs)
if stem ≠{} then
Tuple(intercalate("/", stem) & "/", |last|(xs))
else
Tuple("./", |last|(xs))
end if
else
Tuple(strPath, "")
end if
else
Tuple("./", "")
end if
end splitFileName
-- takeBaseName :: FilePath -> String
on takeBaseName(strPath)
if strPath ≠"" then
if text -1 of strPath = "/" then
""
else
set fn to item -1 of splitOn("/", strPath)
if fn contains "." then
intercalate(".", items 1 thru -2 of splitOn(".", fn))
else
fn
end if
end if
else
""
end if
end takeBaseName
-- takeDirectory :: FilePath -> FilePath
on takeDirectory(strPath)
if strPath ≠"" then
if character -1 of strPath = "/" then
text 1 thru -2 of strPath
else
set xs to init(splitOn("/", strPath))
if xs ≠{} then
intercalate("/", xs)
else
"."
end if
end if
else
"."
end if
end takeDirectory
-- takeExtension :: FilePath -> String
on takeExtension(strPath)
set xs to splitOn(".", strPath)
if length of xs > 1 then
"." & item -1 of xs
else
""
end if
end takeExtension
-- takeFileName :: FilePath -> FilePath
on takeFileName(strPath)
if strPath ≠"" and character -1 of strPath ≠"/" then
item -1 of splitOn("/", strPath)
else
""
end if
end takeFileName
-- tempFilePath :: String -> IO FilePath
on tempFilePath(template)
(current application's ¬
NSTemporaryDirectory() as string) & ¬
takeBaseName(template) & ¬
text 3 thru -1 of ((random number) as string) & ¬
takeExtension(template)
end tempFilePath
-- writeFile :: FilePath -> String -> IO ()
on writeFile(strPath, strText)
set ca to current application
(ca's NSString's stringWithString:strText)'s ¬
writeToFile:(stringByStandardizingPath of ¬
(ca's NSString's stringWithString:strPath)) atomically:true ¬
encoding:(ca's NSUTF8StringEncoding) |error|:(missing value)
end writeFile
-- writeFileMay :: FilePath -> String -> Maybe FilePath
on writeFileMay(strPath, strText)
set ca to current application
set strFullPath to stringByStandardizingPath of ¬
wrap(strPath)
if wrap(strText)'s writeToFile:(strFullPath) atomically:false ¬
encoding:(ca's NSUTF8StringEncoding) |error|:(missing value) then
Just(unwrap(strFullPath))
else
Nothing()
end if
end writeFileMay
-- File name template -> string data -> temporary path
-- (Random digit sequence inserted between template base and extension)
-- writeTempFile :: String -> String -> IO FilePath
on writeTempFile(template, txt)
set strPath to (current application's ¬
NSTemporaryDirectory() as string) & ¬
takeBaseName(template) & ¬
text 3 thru -1 of ((random number) as string) & ¬
takeExtension(template)
-- Effect
writeFile(strPath, txt)
-- Value
strPath
end writeTempFile
-- intercalate :: String -> [String] -> String
on intercalate(sep, xs)
set {dlm, my text item delimiters} to {my text item delimiters, sep}
set s to xs as text
set my text item delimiters to dlm
return s
end intercalate
-- splitOn :: String -> String -> [String]
on splitOn(strDelim, strMain)
set {dlm, my text item delimiters} to {my text item delimiters, strDelim}
set xs to text items of strMain
set my text item delimiters to dlm
return xs
end splitOn
-- unwrap :: NSObject -> a
on unwrap(objCValue)
if objCValue is missing value then
missing value
else
set ca to current application
item 1 of ((ca's NSArray's arrayWithObject:objCValue) as list)
end if
end unwrap
-- wrap :: a -> NSObject
on wrap(v)
set ca to current application
ca's (NSArray's arrayWithObject:v)'s objectAtIndex:0
end wrap
-- Just :: a -> Just a
on Just(x)
{type:"Maybe", Nothing:false, Just:x}
end Just
-- Nothing :: () -> Nothing
on Nothing()
{type:"Maybe", Nothing:true}
end Nothing
-- Left :: a -> Either a b
on |Left|(x)
{type:"Either", |Left|:x, |Right|:missing value}
end |Left|
-- Right :: b -> Either a b
on |Right|(x)
{type:"Either", |Left|:missing value, |Right|:x}
end |Right|
-- Tuple (,) :: a -> b -> (a, b)
on Tuple(a, b)
{type:"Tuple", |1|:a, |2|:b}
end Tuple