Applescript behaves differently when compiled - applescript

This chunk of Applescript:
on collectionToJson(_collection)
tell application "Capture One 22" to return "{\"name\": " & "\"" & name of _collection & "\", \"id\": " & id of _collection & ", \"kind\": " & "\"" & kind of _collection & "\", \"user\": " & user of _collection & "}"
end collectionToJson
behaves differently when run interpreted and compiled. Output in interpreted mode:
> osascript target/classes/Collections.applescript --byId 14659
{"name": "StoppingDown", "id": 14659, "kind": "project", "user": true}
Output in compiled mode:
> osascript target/classes/Collections.scpt --byId 14659
{"name": "StoppingDown", "id": 14659, "kind": "«constant ****CCpj»", "user": true}
The 'kind' property (which is an enum) is output in a different way. Does it depend on my scarce knowledge of Applescript or on the specific application I'm talking to?
Full script:
on run (_args)
tell front document of application "Capture One 22"
set _command to item 1 of _args
if _command is "--byId" then
set _collection to my findCollectionByIdPath(_args)
my collectionToJson(_collection)
else if _command is "--byName" then
set _collection to collection named (item 2 of _args)
repeat with _i from 3 to count of _args
tell _collection to set _collection to collection named (item _i of _args)
end repeat
my collectionToJson(_collection)
else if _command is "--children" then
set _collection to my findCollectionByIdPath(_args)
tell _collection to my collectionsToJson(collections)
else if _command is "--variants" then
set _collection to my findCollectionByIdPath(_args)
tell _collection to my variantsToJson(variants)
else
log "Unknown command: " & _command
end if
end tell
end run
on findCollectionByIdPath(_args)
tell front document of application "Capture One 22"
set _collection to first collection whose its id is item 2 of _args
repeat with _i from 3 to count of _args
tell _collection to set _collection to (first collection whose its id is (item _i of _args))
end repeat
return _collection
end tell
end findCollectionByIdPath
on collectionsToJson(_collections)
set _result to "["
set _separator to ""
repeat with _collection in _collections
set _result to _result & _separator & my collectionToJson(_collection)
set _separator to ","
end repeat
return _result & "]"
end collectionsToJson
on collectionToJson(_collection)
tell application "Capture One 22" to return "{\"name\": " & "\"" & name of _collection & "\", \"id\": \"" & id of _collection & "\", \"kind\": " & "\"" & kind of _collection & "\", \"user\": " & user of _collection & "}"
end collectionToJson
on variantsToJson(_variants)
set _result to "["
set _separator to ""
repeat with _variant in _variants
set _result to _result & _separator & my variantToJson(_variant)
set _separator to ","
end repeat
return _result & "]"
end variantsToJson
on variantToJson(_variant)
-- FIXME: it seems that this 'tell' slows down a lot
tell application "Capture One 22" to return ("{\"name\": \"" & (name of _variant) as text) & "\", \"id\": \"" & id of _variant & "\", \"rating\": " & rating of _variant & ", \"colorTag\": " & color tag of _variant & "}"
end variantToJson

That behavior is normal and to be expected. AppleScript only loads application dictionaries when compiling and decompiling a script. It doesn’t load the dictionary when executing a compiled script because it doesn’t need it.
A compiled script stores application-defined keywords as “four-char codes”, e.g. the keyword project maps to the code CCpj, which AppleScript displays as «constant ****CCpj» when the dictionary definition isn’t available.
While AS can be “forced” to load an application’s dictionary even when it’s not needed (using the run script command to compile a trivial script targeting that application), the obvious straightforward solution is to translate keywords to strings yourself:
to formatKind(aKind)
if aKind is project then
return "project"
else if ...
...
else
return aKind as string
end
end formatKind
Or, in your particular case, since you’re running the script via osascript, just keep using the uncompiled form: unlike early System 7 days, where compiling took an appreciable length of time, modern machines are fast enough that it really doesn’t make a noticeable difference to running time.

Related

Export Apple photos library for importing it elsewhere

I intented to export all my photos from Mac to any other environment and this suggestion finally provided the base to solve this with applescript. That way the photos are always scaled (getting bigger than the original) but at least it works.
I know it's long but as I struggled that long with this problem, so I post the whole working solution below as an answer. Maybe someone has a better suggestion. I have refused to reverse engineer the contents in sqlite tables Photos is using, as this just may change with the next version.
Problems are various
There is no guarantee how Photos walks through the albums and folders. And as it sometimes just stops working, you have to guarantee some order, or you will never finish. So I introduced a way to start at a particular album at a particular photo. The order within the album seems to be stable. The log output written shows the unique ids of album and photo (as names may not be unique) to be able to restart it at this point. Most of the time the second attempt just works.
I did not find a way to store photos in order, so I created one single directory for each photo and stored each photo in a separate directory, so I can reimport them in order. Problem is that Photos always uses the original file name and just counts upwards if the name exists already. Using different cameras just makes it worse.
All attributes I wrote into a text file per photo, so I can reimport them later.
Error handling is quite tricky. The photos library sometimes just requests the user to press a button, which makes it hard to script it.
That's unfortunately the best I was able to come up with, it is my 1st applescript. This worked on an old Mac with Sierra and it works on more recent versions with Catalina as well. I'm almost sure the newest version will not complain. I'm still searching for a better solution.
There is little support to run it from inside Apple's script editor, only command line provides all options.
#!/usr/bin/osascript
global startAlbum, startPhoto, match, dummy, match, photoCnt, infoFd
global errorIndicator
on writePhotoAndData(thePath, mediaItem, mediaAlbum)
set ind to "X"
using terms from application "Photos"
set fName to filename of mediaItem
set fId to id of mediaItem
set photoCnt to photoCnt + 1
-- export each media to separate directory -> only chance to keep the order
if dummy then
if infoFd ≠ missing value then
set s to id of mediaAlbum & tab & id of mediaItem & tab & thePath & linefeed as text
write s to infoFd as «class utf8»
end if
else
makeEmptyPosixPath(thePath)
set exportPath to POSIX file thePath
set infoFile to POSIX file (thePath & "/" & "info.txt")
set infoText to "id" & tab & id of mediaItem & linefeed & "file" & tab & filename of mediaItem & linefeed & "album" & tab & name of mediaAlbum & linefeed
if exists name of mediaItem then set infoText to infoText & "name" & tab & name of mediaItem & linefeed
if exists description of mediaItem then set infoText to infoText & "desc" & tab & description of mediaItem & linefeed
if exists date of mediaItem then
set d to date of mediaItem
set infoText to infoText & "date" & tab & short date string of d & space & time string of d & linefeed
end if
if exists altitude of mediaItem then set infoText to infoText & "alt" & tab & altitude of mediaItem & linefeed
if exists location of mediaItem then set infoText to infoText & "location" & tab & location of mediaItem & linefeed
if exists keywords of mediaItem then
tell mediaItem to set myKeywords to keywords
repeat with keyword in myKeywords
set infoText to infoText & "keyword" & tab & keyword & linefeed
end repeat
end if
set fd to open for access infoFile with write permission
set eof fd to 0 -- of fd?
write infoText to fd starting at eof as «class utf8»
close access fd
try
tell mediaAlbum
--Not sure whether this does anything, so removed
--set settings to "JPEG - Original Size"
export {mediaItem} to (exportPath as alias)
end tell
set errorIndicator to 0
on error errStr number errNum
if errNum = -1712 then --timeout
set ind to "E"
set errorIndicator to errorIndicator + 1
if errorIndicator >= 3 then
error "3 errors in a row - exiting"
end if
else
error errStr number errNum
end if
end try
end if
log ind & tab & photoCnt & tab & id of mediaAlbum & tab & id of mediaItem & tab & name of mediaAlbum & tab & filename of mediaItem
end using terms from
end writePhotoAndData
on walkAlbum(theAlbum, thePath)
if match = 0 then
if id of theAlbum = startAlbum then
set match to 1
if startPhoto is missing value then
set match to 2
end if
else
return
end if
else if match = 1 then
if id of theAlbum is not equal to startAlbum then
set match to 3
end if
end if
set photoNum to 0
using terms from application "Photos"
set albumPath to thePath & name of theAlbum & "/"
repeat with mediaItem in media items of theAlbum
set photoNum to photoNum + 1
if match = 1 then
if id of mediaItem = startPhoto then
set match to 2
end if
else if match = 2 then
set match to 3 --photo after the photo chosen
end if
if match = 3 then
writePhotoAndData(albumPath & photoNum, mediaItem, theAlbum)
end if
end repeat
end using terms from
end walkAlbum
on walkFolder(theFolder, thePath)
using terms from application "Photos"
repeat with containedFolder in folders of theFolder
walkFolder(containedFolder, thePath & name of containedFolder & "/")
end repeat
repeat with containedAlbum in albums of theFolder
walkAlbum(containedAlbum, thePath)
end repeat
end using terms from
end walkFolder
on makePosixPath(tPath)
do shell script "mkdir -p " & quoted form of tPath
end makePosixPath
on makeEmptyPosixPath(tPath)
do shell script "rm -rf " & quoted form of tPath & " && mkdir -p " & quoted form of tPath
end makeEmptyPosixPath
on makeFolder(tPath)
do shell script "mkdir -p " & quoted form of POSIX path of tPath
end makeFolder
on walkFile(fileName, fileOffset as integer)
set thisOffset to 0
set saveDelim to text item delimiters of AppleScript
set walkFd to open for access POSIX file fileName
set rawLine to read walkFd before linefeed as «class utf8»
repeat
set thisOffset to thisOffset + 1
if fileOffset = 0 or thisOffset ≥ fileOffset then
set thisLine to rawLine as text
set text item delimiters of AppleScript to tab
set splitLine to text items of thisLine
set text item delimiters of AppleScript to saveDelim
set albumIdString to item 1 of splitLine
set photoIdString to item 2 of splitLine
set pathString to item 3 of splitLine
tell application "Photos"
set thisAlbum to album id albumIdString
set thisMedia to media item id photoIdString
end tell
writePhotoAndData(pathString, thisMedia, thisAlbum)
log "O" & tab & thisOffset
end if
try
set rawLine to read walkFd before linefeed as «class utf8»
on error errTxt number errNum
if errNum = -39 then --end of file
exit repeat
else
error "Error reading inputfile: " & errTxt
end if
end try
end repeat
end walkFile
on run (args)
set caller to class of args as string
set errorIndicator to 0
set destPath to POSIX path of (get path to home folder) & "export/photos/"
set photoCnt to 0
set startAlbum to missing value
set startPhoto to missing value
set match to 3
set dummy to false
set walkFileName to missing value
set walkFileOffset to 0
set infoFd to missing value
set infoFileName to missing value
set chooseDestinationFolder to "Select start folder (defaults to " & destPath & ")"
set chooseStart to "Give start album and photo"
set chooseDryRun to "dry-run"
if caller = "script" then
log "Running in ScriptEditor:" & name of me
set options to choose from list {chooseDestinationFolder, chooseStart, chooseDryRun} with title "Configure run" with prompt "Select options" with multiple selections allowed and empty selection allowed
if options contains chooseDryRun then set dummy to true
if options contains chooseDestinationFolder then
try
set destFolder to choose folder with prompt "Choose export directory or cancel for default location" default location (get path to home folder as alias)
set destPath to POSIX path of destFolder
end try
end if
if options contains chooseStart then
set res to display dialog "Enter Id of album to start" default answer "" buttons {"OK"} default button 1
if length of text returned of res > 0 then
set startAlbum to text returned of res
set match to 0
end if
if match = 0 then
set res to display dialog "Enter id of photo to resume after (leave empty to start with album)" default answer "" buttons {"OK"} default button 1
if length of text returned of res > 0 then
set startPhoto to text returned of res
end if
end if
end if
else if caller = "list" then
log "Running on the command line:" & name of me
set cnt to 1
repeat while cnt ≤ length of args
if item cnt of args = "-t" then
set cnt to (cnt + 1)
set destPath to item cnt of args
set cnt to (cnt + 1)
else if item cnt of args = "-a" then
set match to 0
set cnt to (cnt + 1)
set startAlbum to item cnt of args
else if item cnt of args = "-p" then
set cnt to (cnt + 1)
set startPhoto to item cnt of args
else if item cnt of args = "-h" then
return name of me & " [-t target path] [-a start album id] [-a start photo id] [-d] [-i info file path]" & linefeed ¬
& name of me & "[-t target path] -f info file [-o offset]" & linefeed ¬
& name of me & " -h .. this help"
else if item cnt of args = "-d" then
set dummy to true
else if item cnt of args = "-i" then
set cnt to (cnt + 1)
set infoFileName to item cnt of args
else if item cnt of args = "-f" then
set cnt to (cnt + 1)
set walkFileName to item cnt of args
else if item cnt of args = "-o" then
set cnt to cnt + 1
set walkFileOffset to item cnt of args
else
error "Invalid option:" & item cnt of args & " - use -h for help"
end if
set cnt to (cnt + 1)
end repeat
end if
set mySettings to "Destination directory:" & destPath
if startAlbum is not missing value then set mySettings to mySettings & linefeed & tab & "Start album id:" & tab & startAlbum
if startPhoto is not missing value then set mySettings to mySettings & linefeed & tab & "Start photo id:" & tab & startPhoto
if infoFileName ≠ missing value then
set mySettings to mySettings & linefeed & tab & "Write file '" & infoFileName & "'" & linefeed
set dummy to true
end if
if dummy then set mySettings to mySettings & linefeed & tab & "Dry run only"
if caller = "script" then
display dialog mySettings with title "Start exporting?" with icon note
else if caller = "list" then
log mySettings
else
error "Internal error - caller interface unknown"
end if
if infoFileName ≠ missing value then
set infoFd to open for access POSIX file infoFileName with write permission
set eof infoFd to 1
end if
if walkFileName ≠ missing value then
walkFile(walkFileName, walkFileOffset)
else
walkFolder(application "Photos", destPath)
end if
if infoFd ≠ missing value then close access infoFd
return "Done!"
end run

Using a "use" in a repeat for Applescript (error: Expected “end” but found “use”.)

I want to use this code to wait until the shift key is pressed, and i want to loop it
set mouseToolsPath to (path to home folder as text) & "Downloads:MouseTools"
property NSShiftKeyMask : a reference to 131072
property NSAlternateKeyMask : a reference to 524288
property NSEvent : a reference to current application's NSEvent
repeat while true
activate application "Google Chrome"
repeat 10 times
set x to 1093
set y to 392
do shell script quoted form of POSIX path of mouseToolsPath & " -x " & (x as text) & " -y " & (y as text) & " -leftClick"
delay (0.5)
do shell script quoted form of POSIX path of mouseToolsPath & " -x " & (x as text) & " -y " & (y as text) & " -leftClick"
delay (0.5)
end repeat
use framework "AppKit"
set modifier_down to true
repeat while modifier_down
set modifier_flags to NSEvent's modifierFlags()
set shift_down to ((modifier_flags div (get NSShiftKeyMask)) mod 2) = 0
set modifier_down to option_down or shift_down
end repeat
end repeat
Heres the problem: If I use the use framework at the start of the code, (before the repeat while true), the "do shell script quoted from..." part wouldn't work.
If I do it in the way I am now, (The code I inserted above) AppleScript will not let me use "use framework" in the repeat loop.
Is there a workaround to this problem? Thanks!

Applescript or .sh script to add a bookmark to Chrome in MacOS

I am trying to automate the process of adding a bookmark to Chrome in MacOS and therefore need an applescript or bash script that can be sent to a Mac machine in order for this to happen.
The vbscript below works in a Windows environment. Is there a way to convert it to MacOS?
Many thanks for your comments
Imports System
Imports System.IO
Imports System.Text
Imports Microsoft.Win32
Imports System.Diagnostics
Module Module1
Dim AppPath As String
Dim PathFileVar As String
Dim TestText As String
Dim Workbench As String
Dim TriggerFound As Boolean
Dim UserProfileVar As String = Environment.GetEnvironmentVariable("UserProfile")
'Dim lineArray As New ArrayList()
Sub Main()
'MsgBox("start " & UserProfileVar)
AppPath = My.Application.Info.DirectoryPath
If My.Computer.FileSystem.FileExists(UserProfileVar & "\AppData\Local\Google\Chrome\User Data\Default\Bookmarks.txt") Then
Try
My.Computer.FileSystem.DeleteFile(UserProfileVar & "\AppData\Local\Google\Chrome\User Data\Default\Bookmarks.txt")
Catch ex As Exception
End Try
End If
'MsgBox("before section")
If My.Computer.FileSystem.FileExists(UserProfileVar & "\AppData\Local\Google\Chrome\User Data\Default\Bookmarks") Then
Dim lineArray As New ArrayList()
PathFileVar = UserProfileVar & "\AppData\Local\Google\Chrome\User Data\Default\bookmarks"
Dim lines() As String = IO.File.ReadAllLines(PathFileVar)
For x As Integer = 0 To lines.GetUpperBound(0)
lineArray.Add(lines(x))
Next
Dim file As System.IO.StreamWriter
file = My.Computer.FileSystem.OpenTextFileWriter(UserProfileVar & "\AppData\Local\Google\Chrome\User Data\Default\Bookmarks.txt", True)
For x = 0 To lineArray.Count - 1
TestText = (lineArray.Item(x))
Dim dIndex = TestText.IndexOf("[")
If TriggerFound = False Then
If (dIndex > -1) Then
TriggerFound = True
'************** start inserting my bookmark ***************************
Workbench = TestText.Substring(0, dIndex)
Workbench = Workbench & "[ {"
file.WriteLine(Workbench)
file.WriteLine(" " & Chr(34) & "date_added" & Chr(34) & ": " & Chr(34) & "13116611233249308" & Chr(34) & ",")
file.WriteLine(" " & Chr(34) & "id" & Chr(34) & ": " & Chr(34) & "222" & Chr(34) & ",")
file.WriteLine(" " & Chr(34) & "name" & Chr(34) & ": " & Chr(34) & "xxxx Emp Service" & Chr(34) & ",")
file.WriteLine(" " & Chr(34) & "type" & Chr(34) & ": " & Chr(34) & "url" & Chr(34) & ",")
file.WriteLine(" " & Chr(34) & "url" & Chr(34) & ": " & Chr(34) & "https://example.com" & Chr(34))
file.WriteLine(" },")
dIndex = dIndex + 1
Workbench = TestText.Substring(dIndex)
file.WriteLine(" " & Workbench)
'***************** end of insert *************************************
Else
file.WriteLine(TestText)
End If
Else
file.WriteLine(TestText)
End If
Next
file.Close()
Try
My.Computer.FileSystem.DeleteFile(PathFileVar)
Catch ex As Exception
End Try
Threading.Thread.Sleep(500)
Try
My.Computer.FileSystem.RenameFile(UserProfileVar & "\AppData\Local\Google\Chrome\User Data\Default\Bookmarks.txt", "Bookmarks")
Catch ex As Exception
End Try
Else
'MsgBox("file does not exist and userprofilevar " & UserProfileVar)
Try
My.Computer.FileSystem.CopyFile(AppPath & "\bookmarks", UserProfileVar & "\AppData\Local\Google\Chrome\User Data\Default\Bookmarks", overwrite:=True)
Catch ex As Exception
End Try
End If
Try
My.Computer.FileSystem.CopyFile(AppPath & "\Employee Selfservice.lnk", UserProfileVar & "\Desktop\Employee Selfservice.lnk", overwrite:=True)
Catch ex As Exception
End Try
Try
My.Computer.FileSystem.CopyDirectory(AppPath & "\_crx_bdicdcflgnjilflenkmoicnpflehicin", UserProfileVar & "\AppData\Local\Google\Chrome\User Data\Default\Web Applications\_crx_bdicdcflgnjilflenkmoicnpflehicin", True)
Catch ex As Exception
End Try
If (Not System.IO.Directory.Exists("C:\In-temp")) Then
Try
System.IO.Directory.CreateDirectory("C:\In-temp")
Catch ex As Exception
End Try
End If
Try
System.IO.File.Create("C:\In-temp\InforCRMdetect.txt").Dispose()
Catch ex As Exception
End Try
End Sub
End Module
Any help is much appreciated,
regards
Since you tagged your question with and mentioned AppleScript, you need to know that in order to use AppleScript directly with Google Chrome, you need to first see if Google Chrome is running before trying to execute any AppleScript code to create the bookmark directly with Google Chrome.
If it's not running, you must wait until Google Chrome's bookmark model is loaded before trying to add a bookmark with ApplesScript. Or if Google Chrome is running without a window open, you must also code to account for that so it won't fail without a window open.
Note: Because the other answer was edited after I posted, I had to change some of the content, but not the code. See the edit history if there's any confusion in my edit.
The following example AppleScript code makes sure conditions are right so those scenarios will not happen.
set newBookmark to "https://www.google.com"
set theTitle to "Google"
set bookmarkFolder to "Bookmarks Bar"
if application "Google Chrome" is running then
tell application "Google Chrome"
tell its bookmark folder bookmarkFolder
set theResult to make new bookmark item with properties {URL:newBookmark}
set title of theResult to theTitle
end tell
end tell
else
tell application "Google Chrome"
repeat until (loading of tab 1 of window 1 is false)
delay 0.5
end repeat
tell its bookmark folder bookmarkFolder
set theResult to make new bookmark item with properties {URL:newBookmark}
set title of theResult to theTitle
end tell
quit
end tell
end if
Obviously you'll set the value of the newBookmark, theTitle and bookmarkFolder variables as wanted.
It's not totally clear in your OP how you're going to deploy this however, if not as an AppleScript .scpt or .app, having been saved in Script Editor, then you could deploy it as a shell script by saving the example AppleScript code in a plain text file with a #!/usr/bin/osascript shebang as its first line and make it executable with chmod.
It can then be executed from the command line in Terminal or just double-clicked in Finder.
Another alternative, if Google Chrome is not running, would be to modify the User's Google Chrome bookmark file directly, but AppleScript is probably not the best for that scenario.
This AppleScript works for me using the latest version of Sierra.
This will automatically add a bookmark directly to the Bookmarks Bar folder
property newBookmark : "https://stackoverflow.com" -- Insert the desired URL
property theTitle : "Whatever Title You Want"
property bookmarkFolder : "Bookmarks Bar" -- The bookmark folder where the new bookmark item will be created
tell application "Google Chrome"
try
tell active tab of window 1
repeat while loading is true
delay 0.3
end repeat
end tell
end try
tell its bookmark folder bookmarkFolder
set theResult to make new bookmark item with properties {URL:newBookmark}
set title of theResult to theTitle
end tell
end tell
Here is a little bit of a different spin… If you want to add a bookmark to a bookmark folder located within the bookmarks bar folder, this will allow you to choose from a list of the existing bookmark folders, as to where you would like to add your new bookmark
property newBookmark : "https://www.google.com" -- Insert the desired URL
property theTitle : "Google"
property MainBookmarkFolder : "Bookmarks Bar" -- The bookmark folder where the new bookmark item will be created
property foldersInMainBookmarkFolder : {}
tell application "Google Chrome"
try
tell active tab of window 1
repeat while loading is true
delay 0.3
end repeat
end tell
end try
set foldersInMainBookmarkFolder to title of every bookmark folder of bookmark folder MainBookmarkFolder
end tell
set chooseBookmarkFolder to (choose from list foldersInMainBookmarkFolder)
set saveTID to AppleScript's text item delimiters
set AppleScript's text item delimiters to {","}
set chooseBookmarkFolder to chooseBookmarkFolder as string
set AppleScript's text item delimiters to saveTID
tell application "Google Chrome"
tell its bookmark folder MainBookmarkFolder
tell its bookmark folder chooseBookmarkFolder
set theResult to make new bookmark item with properties {URL:newBookmark}
set title of theResult to theTitle
end tell
end tell
end tell

AppleScript error: 'Expected "else", etc. but found unknown token'

I'm new to AppleScript. The editor isn't giving me syntax highlighting so I'm a bit stuck with this error.
set exportPath to path to documents folder as text
with timeout of (30 * 60) seconds
tell application "Evernote"
repeat with nb in every notebook of application "Evernote"
set theName to the name of nb
set matches to find notes "notebook:" & "\"" & theName & "\""
set f to exportPath & theName & ".enex"
export matches to f
if (count of matches) > 0 then
set p to POSIX path of f
do shell script "/usr/bin/gzip -f " & quoted form of p
end if
end repeat
end tell
end timeout
When I click OK on the error the cursor position is changed to before the end in the end if line.
You have some weird, unknown character just before end if.
Take that line out and re-type it and it will work.
set exportPath to path to documents folder as text
with timeout of (30 * 60) seconds
tell application "Evernote"
repeat with nb in every notebook of application "Evernote"
set theName to the name of nb
set matches to find notes "notebook:" & "\"" & theName & "\""
set f to exportPath & theName & ".enex"
export matches to f
if (count of matches) > 0 then
set p to POSIX path of f
do shell script "/usr/bin/gzip -f " & quoted form of p
end if
end repeat
end tell
end timeout

AppleScript - Skype Interface

I am very new to AppleScript. I found this script to use with a GeekTool Geeklet to show the online Skype users. When I run the AppleScript I get an error that "skype_id" is undefined. I cannot find where/why it is undefined. Apparently this same script worked in the past.
Here is the error:
error "The variable skype_id is not defined." number -2753 from "skype_id"
Here is the script:
on remvix(ix, ls)
if ls is {} then
return {}
else if ix is 1 then
return rest of ls
else
return {item 1 of ls} & remvix(ix - 1, rest of ls)
end if
end remvix
on tail(astring, k)
return do shell script "echo '" & astring & "' | awk '{{i = " & k & "; while ( i <= NF-1 ) {printf $i \" \"; i++}; printf $i}}'"
end tail
property onlinegroup : 0
on getgroup()
tell application "Skype"
if my checkgroup(onlinegroup) is true then
return onlinegroup
else
set hardwired to send command "search groups hardwired" script name "online users"
set hardwired to my tail(hardwired, 2)
set hardwired to text items of hardwired
repeat with i in hardwired
if my checkgroup(i) is true then
return i
end if
end repeat
end if
end tell
end getgroup
on checkgroup(group_id)
tell application "Skype"
set grouptype to send command "get group " & group_id & " type" script name "online users"
set grouptype to my tail(grouptype, 4)
if grouptype is "ONLINE_FRIENDS" then
return true
else
return false
end if
end tell
end checkgroup
property dropped : 0
set text item delimiters to ", "
set onlineusers to {}
tell application "System Events"
set powerCheck to ((application processes whose (name is equal to "Skype")) count)
if powerCheck = 0 then
set end of onlineusers to " Skype not running"
else
tell application "Skype"
set onlinegroup to my getgroup()
set skype_id to send command "get group " & onlinegroup & " users" script name "online users"
set skype_id to my tail(skype_id, 4)
set skype_id to text items of skype_id
repeat with j from 1 to count skype_id
if item j of skype_id is "echo123" then
set skype_id_new to my remvix(j, skype_id)
set dropped to 1
end if
end repeat
if dropped is 1 then
set skype_id to skype_id_new
end if
repeat with i in skype_id
set aUser to send command "get user " & i & " fullname" script name "online users"
set aUser to my tail(aUser, 4)
if aUser is "" then set aUser to i
set amoodtext to send command "get user " & i & " mood_text" script name "online users"
set amoodtext to my tail(amoodtext, 4)
if amoodtext is "" then
set end of onlineusers to aUser
else
set end of onlineusers to aUser & " (" & amoodtext & ")"
end if
end repeat
if (count skype_id) > 0 then
set item 1 of onlineusers to " " & item 1 of onlineusers
else
set beginning of onlineusers to " No Contacts Online"
end if
return onlineusers
end tell
end if
end tell
Thanks in advance for your help.
'my tail' is the script's own function/handler, which is just a wrapper for an awk (shell) script. For some reason that function is failing to return anything, and I notice that it includes no error checking. It would be useful to start debugging the 'on tail' chunk. For example, are the parameters astring and k meaningful? This error handling code could slot into the beginning of the tail handler:
if ((class of astring) is not string) or ((class of k) is not integer) then
display dialog "Screwy parameter sent to tail" buttons {"Rats"} default button 1
error number -128 -- abort script entirely
end if
If that doesn't find the error, then maybe awk is misbehaving, which seems unlikely, but could still be possible I suppose.
Just a general observation. I know appleScript is suppose to be a friendly, easy going language (although it isn't), and you probably got this script from someone else, but for debugging purposes, you are asking for trouble by redefining the skype_id variable so many times. (This is the reason for Chuck's response).

Resources