Why does this throw up an error? - applescript

tell application "VoodooPad"
tell document 1
repeat with thisPage from 1 to number of items in pages
set theName to display name of page thisPage
set creationDate to created of page thisPage
set theText to text of page thisPage
tell application "Evernote"
create note with text theText title theName notebook "VoodooPad Imported Notes" tags "imported_from_VoodooPad" created creationDate
end tell
end repeat
end tell
end tell
This produces the following error:
error "VoodooPad got an error: every item of every page of document 1 doesn’t understand the count message." number -1708 from every item of every page of document 1
Any Idea on how to get the script to run?

Try this:
set allPages to pages as list // now you have items in a list
repeat with thisPage from 1 to number of items in allPages
...

Related

AppleScript read data every few minutes

I run a screen which display some data on the menu bar
the variables are taken from "~/Desktop/_MyData.plist"
everything work fine, however when the data change on _MyData.plist
How, can I make the script getting the new data ? I guess we can't expect AppleScript to detect file change and then run the script but is there a way to get the plist data on idle maybe and keeping running the whole script.
Here is the part that only getting the data :
property theAccountNumberFromPlist : ""
property SNNumber : ""
property appName : ""
property devicesID : ""
property domainEMAIL : ""
property fullEmail : ""
property purchaseDate : ""
property thename : ""
property theList : ""
set the plistfile_path to "~/Desktop/_MyData.plist.plist"
tell application "System Events"
set p_list to property list file (plistfile_path)
-- read the plist data
set theAccountNumberFromPlist to value of property list item "AccountNumber" of p_list as text
set SNNumber to value of property list item "SNNUMBER" of p_list as text
set appName to value of property list item "appName" of p_list as text
set devicesID to value of property list item "devicesID" of p_list as text
set domainEMAIL to value of property list item "domainEMAIL" of p_list as text
set fullEmail to value of property list item "fullEmail" of p_list as text
set purchaseDate to value of property list item "purchaseDate" of p_list as text
set thename to value of property list item "thename" of p_list as text
end tell
Here is the whole script :
use AppleScript version "2.4"
use scripting additions
use framework "Foundation"
use framework "AppKit"
property StatusItem : missing value
property selectedMenu : ""
property theDisplay : ""
property defaults : class "NSUserDefaults"
property internalMenuItem : class "NSMenuItem"
property externalMenuItem : class "NSMenuItem"
property newMenu : class "NSMenu"
property theAccountNumberFromPlist : ""
property SNNumber : ""
property appName : ""
property devicesID : ""
property domainEMAIL : ""
property fullEmail : ""
property purchaseDate : ""
property thename : ""
property theList : ""
set the plistfile_path to "~/Desktop/_MyData.plist.plist"
tell application "System Events"
set p_list to property list file (plistfile_path)
-- read the plist data
set theAccountNumberFromPlist to value of property list item "AccountNumber" of p_list as text
set SNNumber to value of property list item "SNNUMBER" of p_list as text
set appName to value of property list item "appName" of p_list as text
set devicesID to value of property list item "devicesID" of p_list as text
set domainEMAIL to value of property list item "domainEMAIL" of p_list as text
set fullEmail to value of property list item "fullEmail" of p_list as text
set purchaseDate to value of property list item "purchaseDate" of p_list as text
set thename to value of property list item "thename" of p_list as text
end tell
if not (current application's NSThread's isMainThread()) as boolean then
display alert "This script must be run from the main thread." buttons {"Cancel"} as critical
error number -128
end if
on menuNeedsUpdate:(menu)
my makeMenus()
end menuNeedsUpdate:
on makeMenus()
newMenu's removeAllItems()
repeat with i from 1 to number of items in someListInstances
set this_item to item i of someListInstances
set thisMenuItem to (current application's NSMenuItem's alloc()'s initWithTitle:this_item action:"someAction:" keyEquivalent:"")
(newMenu's addItem:thisMenuItem)
(thisMenuItem's setTarget:me) -- required for enabling the menu item
if i is equal to 3 then
(newMenu's addItem:(current application's NSMenuItem's separatorItem)) -- add a seperator
end if
end repeat
end makeMenus
on someAction:sender
--MenuItem
end someAction:
-- create an NSStatusBar
on makeStatusBar()
set bar to current application's NSStatusBar's systemStatusBar
set StatusItem to bar's statusItemWithLength:-1.0
-- set up the initial NSStatusBars title
StatusItem's setTitle:(theAccountNumberFromPlist & " " & thename & " " & fullEmail & " " & SNNumber & " " & appName)
-- set up the initial NSMenu of the statusbar
set newMenu to current application's NSMenu's alloc()'s initWithTitle:"Custom"
newMenu's setDelegate:me (*
*)
StatusItem's setMenu:newMenu
end makeStatusBar
my makeStatusBar()
Make use of an idle handler.
on idle
-- do your stuff
return 5 -- idle handler will be executed again in 5 seconds.
end
Therefore you need to save your script as application. Here's the essential part from apples docs:
idle and quit Handlers for Stay-Open Applications
By default, a script application that receives a run or open command
handles that single command and then quits. In contrast, a stay-open
script application (one saved as Stay Open in Script Editor) stays
open after it is launched.
A stay-open script application can be useful for several reasons:
Stay-open script applications can receive and handle other commands in
addition to run and open. This allows you to use a script application
as a script server that, when it is running, provides a collection of
handlers that can be invoked by any other script.
Stay-open script applications can perform periodic actions, even in
the background, as long as the script application is running.
Two particular handlers that stay-open script applications often
provide are an idle handler and a quit handler.
idle Handlers
If a stay-open script application includes an idle handler,
AppleScript sends the script application periodic idle commands—by
default, every 30 seconds—allowing it to perform background tasks when
it is not performing other actions.
If an idle handler returns a positive number, that number becomes the
rate (in seconds) at which the handler is called. If the handler
returns a non-numeric value, the rate is not changed. You can return 0
to maintain the default delay of 30 seconds.
For example, when saved as a stay-open application, the following
script beeps every 5 seconds:
on idle
    beep
    return 5
end idle
The result returned from a handler is just the result of the last statement, even if it doesn’t include the word return explicitly.

Applescript and empty mail signature / input in value list

I have two questions with my applescript. The script is supposed to send a dropped file as attachment by email and asking the object of the mail from a list.
The content of the message MUST be empty.
1) How to set an "empty" email signature because the content of my mail should be empty. I receive an error code "error in mail impossible to solve signature..."
2) I wish that the user can modify the value list {"00111111111111-number1, "0011111111111-number2"...} and add more numbers. What is the best approach to do this ?
Thanks very much in advance for your suggestions.
property theSubject : "subject"
property theNumber : ""
property theContent : ""
property theSignature : "none"
property onRun : ""
on run
tell application "Finder"
set sel to (get selection)
end tell
set onRun to 1
new_mail(sel)
end run
on open droppedFiles
new_mail(droppedFiles)
end open
on new_mail(theFiles)
set chosen to choose from list {"0011111111111-number1", "0011111111111-number2"} with prompt "Thanks to select"
if chosen is false then return "" -- in case of 'Cancel' return empty string
set theNumber to text 1 thru 13 of (item 1 of chosen) -- as chosen returns a list by default it must be flattened
tell application "Mail"
set newMessage to make new outgoing message with properties {visible:true, subject:theNumber}
tell newMessage
make new to recipient with properties {address:faxboxEmail}
if onRun < 1 then
make new attachment with properties {file name:theFiles as alias} at after last paragraph
end if
set the content to theContent
set message signature of newMessage to signature theSignature
end tell
activate
if onRun < 1 then
send
end if
end tell
end new_mail
to add new item in the list, may be this could help you ?
set BaseList to {"0011111111111-number1", "0011111111111-number2"}
set CList to BaseList & {"Add new item"}
set chosen to choose from list CList with prompt "Thanks to select"
if chosen is false then return "" -- in case of 'Cancel' return empty string
if "Add new item" is in chosen then
set OKNew to false
repeat until OKNew
set NewItem to display dialog "Enter new value :" default answer ""
set OKNew to (button returned of NewItem is "OK") and (text returned of NewItem is not "")
set theNumber to text returned of NewItem
set BaseList to baseList & {theNumber} -- to add the new item in the BaseList
end repeat
else
set theNumber to text 1 thru 13 of (item 1 of chosen) -- as chosen returns a list by default it must be flattened
end if
I also experienced some issues with the signature and the attachement together. if you remove the line "make new attachment..." the signature line is working. Also if you move the signature line before the attachement line, and make a break before the attachement, the signature will be OK. bug ?
Then, based on my tests, if you do not want signature at all, just delete the line "set message signature..." by default, no signature will be set.
My last comment is to reduce your script by adding the content directly in property list of the "make new outgoing message..."
tell application "Mail"
set newMessage to make new outgoing message with properties {visible:true, subject:TheNumber, content:TheContent}
tell newMessage
make new to recipient with properties {address:faxboxmail}
if onRun > 1 then
make new attachment with properties {file name:theFile as alias} at after last paragraph
end if
end tell
activate
end tell
I tried it, and it is creates mail with no content and no signature as expected (Mail 8.2)

Pass Multiple Applescript Variables to Ruby

I'm working on a Ruby script that requires some variables from Applescript. Right now I'm having success grabbing them one at a time, but it seems inelegant and possibly slow. For example:
note = %x{ osascript <<APPLESCRIPT
tell application "Evernote"
if selection is not {} then
set the_selection to selection
if notebook of item 1 of the_selection is (notebook named "Writing") then
return HTML content of item 1 of the_selection
end if
else
return ""
end if
end tell
APPLESCRIPT}
title = %x{ osascript <<APPLESCRIPT
tell application "Evernote"
if selection is not {} then
set the_selection to selection
if notebook of item 1 of the_selection is (notebook named "Writing") then
return title of item 1 of the_selection
end if
else
return ""
end if
end tell
APPLESCRIPT}
I know I'm probably overlooking something obvious, but is there an easy way I can do this with just a single snippet of Applescript that returns both variables into Ruby (note, title)?
Getting multiple values out of AppleScript is the easy part. Instead of returning a single value, return a list:
result = %x{ osascript <<APPLESCRIPT
tell application "Evernote"
if selection is not {} then
set the_selection to selection
if notebook of item 1 of the_selection is (notebook named "Writing") then
set title to title of item 1 of the_selection
set html to HTML content of item 1 of the_selection
return { title, html }
end if
else
return ""
end if
end tell
APPLESCRIPT}
The hard part is parsing the output. Supposing your title is This is a note and html is <h1>Hello World</h1>, osascript will return this:
This is a note, <h1>Hello World</h1>
You could split it on the , but if title happens to contain a comma, you've got a problem. You can also pass the -ss option to osascript, which makes it return formatted AppleScript objects, but you don't want to have to write your own AppleScript parser in Ruby.
An alternative, if you know title will never contain a line break, is to put a line break after the title:
result = %x{ osascript <<APPLESCRIPT
...
if notebook of item 1 of the_selection is (notebook named "Writing") then
set title to title of item 1 of the_selection
set html to HTML content of item 1 of the_selection
return title & "\n" & html
end if
...
APPLESCRIPT}.chomp
Now the output (result) will look like this:
This is a note
<h1>Hello World</h1>
...and you can get the title and HTML like this:
title, html = result.split("\n", 2)
puts title
# => This is a note
puts html
# => <h1>Hello World</h1>
Now, if you have line breaks in any of your titles (I can't remember if Evernote allows that or not), or if you want to return more than two values, this will be problematic as well. The next simplest solution would be to choose some kind of delimiter that's unlikely to appear in any part of the output, for example %!%:
DELIMITER = '%!%'
result = %x{ osascript <<APPLESCRIPT
...
if notebook of item 1 of the_selection is (notebook named "Writing") then
set title to title of item 1 of the_selection
set html to HTML content of item 1 of the_selection
return title & "#{DELIMITER}" & html
end if
...
APPLESCRIPT}.chomp
# =>This is a note%!%<h1>Hello World</h1>
title, html = result.split(DELIMITER, 2)
If all else fails, you could use an addon to make osascript output a known format that Ruby knows how to parse. Just now I found this free JSON Helper that looks pretty handy.

Choose from list and write to plist as string, not as array

I've got the following which displays two text input prompts and then queries for PPTP VPN configs and asks the user to 'choose from list'. The results are then saved to a plist file however vpn_name is always encoded inside of two blank arrays. I've tried setting the datatype of vpn_name to string but the same applies.
How can I get this to encode simply as:
<dict>
<key>password</key>
<string>fnkdslfsd</string>
<key>username</key>
<string>fnsdkfnds</string>
<key>vpn_name</key>
<string>SAMSUNG_Android</string>
</dict>
as opposed to how it's currently encoding:
<dict>
<key>password</key>
<string>fnkdslfsd</string>
<key>username</key>
<string>fnsdkfnds</string>
<key>vpn_name</key>
<array>
<array>
<string>SAMSUNG_Android</string>
</array>
</array>
</dict>
Applescript:
property key_path : "~/Library/Preferences/vpn-keys.plist"
property user_name : ""
property pass_word : ""
property vpn_name : ""
tell application "Finder"
if user_name is "" then
set dialog_1 to display dialog "Please enter your server username: " default answer ""
set the user_name to the text returned of dialog_1
end if
if pass_word is "" then
set dialog_2 to display dialog "Please enter your server password: " default answer ""
set the pass_word to the text returned of dialog_2
end if
if vpn_name is "" then
tell application "System Events"
tell current location of network preferences
set VPN_list to get name of every service whose (kind is greater than 11 and kind is less than 17)
end tell
end tell
vpn_name as string
set vpn_name to {choose from list VPN_list with prompt "Select Office VPN"}
end if
tell application "System Events"
set the parent_dictionary to make new property list item with properties {kind:record}
set the plistfile_path to key_path
set this_plistfile to ¬
make new property list file with properties {contents:parent_dictionary, name:plistfile_path}
make new property list item at end of property list items of contents of this_plistfile ¬
with properties {kind:string, name:"username", value:user_name}
make new property list item at end of property list items of contents of this_plistfile ¬
with properties {kind:string, name:"password", value:pass_word}
make new property list item at end of property list items of contents of this_plistfile ¬
with properties {kind:string, name:"vpn_name", value:vpn_name}
end tell
end tell
choose from list returns a list of items selected and returns false when canceled. You defined an empty string before choose from list command is invoked but in AppleScript that doesn't have any effect between lines. So what you can do is test if the results are false before continuing because unlike a display dialog the script continues when the user pressed the cancel button. Then set value of new property list item to item 1 of vpn_name.
property key_path : "~/Library/Preferences/vpn-keys.plist"
property user_name : ""
property pass_word : ""
property vpn_name : ""
tell application "Finder"
if user_name is "" then
set dialog_1 to display dialog "Please enter your server username: " default answer ""
set the user_name to the text returned of dialog_1
end if
if pass_word is "" then
set dialog_2 to display dialog "Please enter your server password: " default answer ""
set the pass_word to the text returned of dialog_2
end if
if vpn_name is "" then
set vpn_name to false
tell application "System Events"
tell current location of network preferences
set VPN_list to get name of every service whose (kind is greater than 11 and kind is less than 17)
end tell
end tell
set vpn_name to choose from list VPN_list with prompt "Select Office VPN"
if vpn_name is false then return --stop, user pressed cancel
end if
tell application "System Events"
set the parent_dictionary to make new property list item with properties {kind:record}
set the plistfile_path to key_path
set this_plistfile to ¬
make new property list file with properties {contents:parent_dictionary, name:plistfile_path}
make new property list item at end of property list items of contents of this_plistfile ¬
with properties {kind:string, name:"username", value:user_name}
make new property list item at end of property list items of contents of this_plistfile ¬
with properties {kind:string, name:"password", value:pass_word}
make new property list item at end of property list items of contents of this_plistfile ¬
with properties {kind:string, name:"vpn_name", value:item 1 of vpn_name}
end tell
end tell

Trying to Add Episode ID to TV Shows via Applescript in iTunes

I have the following code:
tell application "iTunes"
repeat with thetrack in tracks of playlist "foo"
set showName to name of thetrack
set showName to ((characters 17 through -1 of showName) as string)
set episode ID of thetrack to name of thetrack
end repeat
end tell
I am trying to set the episode ID of TV Shows to the track name. If I comment out the set episode ID line, showName is definititely set to the correct string. When I try to actually set the episode ID however I get the following error:
iTunes got an error: Can’t set episode ID of item 1 of every track of playlist "Fitness & Nutrition" to name of item 1 of every track of playlist "Fitness & Nutrition".
I admit, I'm stumped.
Try:
set episode ID of thetrack to (name of thetrack as text)
because
return class of name of thetrack --> property
and
return class of (name of thetrack as text) --> text

Resources