rb-appscript 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGES +243 -0
- data/LICENSE +1 -0
- data/README +42 -0
- data/TODO +31 -0
- data/doc/aem-manual/01_introduction.html +48 -0
- data/doc/aem-manual/02_apioverview.html +89 -0
- data/doc/aem-manual/03_packingandunpackingdata.html +98 -0
- data/doc/aem-manual/04_references.html +401 -0
- data/doc/aem-manual/05_targettingapplications.html +133 -0
- data/doc/aem-manual/06_buildingandsendingevents.html +175 -0
- data/doc/aem-manual/07_findapp.html +54 -0
- data/doc/aem-manual/08_examples.html +85 -0
- data/doc/aem-manual/09_notes.html +41 -0
- data/doc/aem-manual/aemreferenceinheritance.gif +0 -0
- data/doc/aem-manual/full.css +21 -0
- data/doc/aem-manual/index.html +43 -0
- data/doc/appscript-manual/01_introduction.html +82 -0
- data/doc/appscript-manual/02_aboutappscripting.html +244 -0
- data/doc/appscript-manual/03_quicktutorial.html +154 -0
- data/doc/appscript-manual/04_gettinghelp.html +101 -0
- data/doc/appscript-manual/05_keywordconversion.html +91 -0
- data/doc/appscript-manual/06_classesandenums.html +174 -0
- data/doc/appscript-manual/07_applicationobjects.html +181 -0
- data/doc/appscript-manual/08_realvsgenericreferences.html +86 -0
- data/doc/appscript-manual/09_referenceforms.html +232 -0
- data/doc/appscript-manual/10_referenceexamples.html +142 -0
- data/doc/appscript-manual/11_applicationcommands.html +204 -0
- data/doc/appscript-manual/12_commandexamples.html +129 -0
- data/doc/appscript-manual/13_performanceissues.html +115 -0
- data/doc/appscript-manual/14_problemapps.html +193 -0
- data/doc/appscript-manual/15_notes.html +84 -0
- data/doc/appscript-manual/application_architecture.gif +0 -0
- data/doc/appscript-manual/application_architecture2.gif +0 -0
- data/doc/appscript-manual/finder_to_textedit_event.gif +0 -0
- data/doc/appscript-manual/full.css +21 -0
- data/doc/appscript-manual/index.html +49 -0
- data/doc/appscript-manual/relationships_example.gif +0 -0
- data/doc/appscript-manual/ruby_to_itunes_event.gif +0 -0
- data/doc/index.html +30 -0
- data/doc/mactypes-manual/index.html +216 -0
- data/doc/osax-manual/index.html +169 -0
- data/extconf.rb +54 -0
- data/misc/adobeunittypes.rb +14 -0
- data/misc/dump.rb +72 -0
- data/rb-appscript.gemspec +20 -0
- data/sample/AB_list_people_with_emails.rb +8 -0
- data/sample/Create_daily_iCal_todos.rb +72 -0
- data/sample/Hello_world.rb +9 -0
- data/sample/List_iTunes_playlist_names.rb +7 -0
- data/sample/Make_Mail_message.rb +29 -0
- data/sample/Open_file_in_TextEdit.rb +9 -0
- data/sample/Organize_Mail_messages.rb +57 -0
- data/sample/Print_folder_tree.rb +12 -0
- data/sample/Select_all_HTML_files.rb +8 -0
- data/sample/Set_iChat_status.rb +20 -0
- data/sample/Simple_Finder_GUI_Scripting.rb +14 -0
- data/sample/Stagger_Finder_windows.rb +21 -0
- data/sample/TextEdit_demo.rb +126 -0
- data/sample/iTunes_top40_to_html.rb +64 -0
- data/src/lib/_aem/aemreference.rb +1006 -0
- data/src/lib/_aem/codecs.rb +617 -0
- data/src/lib/_aem/connect.rb +100 -0
- data/src/lib/_aem/findapp.rb +83 -0
- data/src/lib/_aem/mactypes.rb +228 -0
- data/src/lib/_aem/send.rb +257 -0
- data/src/lib/_aem/typewrappers.rb +57 -0
- data/src/lib/_appscript/defaultterminology.rb +245 -0
- data/src/lib/_appscript/referencerenderer.rb +132 -0
- data/src/lib/_appscript/reservedkeywords.rb +107 -0
- data/src/lib/_appscript/terminology.rb +314 -0
- data/src/lib/aem.rb +216 -0
- data/src/lib/appscript.rb +830 -0
- data/src/lib/kae.rb +1484 -0
- data/src/lib/osax.rb +171 -0
- data/src/rbae.c +766 -0
- data/test/README +1 -0
- data/test/test_aemreference.rb +112 -0
- data/test/test_appscriptreference.rb +102 -0
- data/test/test_codecs.rb +159 -0
- data/test/test_findapp.rb +24 -0
- data/test/test_mactypes.rb +67 -0
- data/test/testall.sh +9 -0
- metadata +143 -0
@@ -0,0 +1,57 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
# Set up a Mail mailbox folder for organising incoming emails from a
|
4
|
+
# particular sender.
|
5
|
+
#
|
6
|
+
# Based on an AppleScript by Michelle Steiner.
|
7
|
+
#
|
8
|
+
# To use: in Mail, select an incoming email message from the desired sender
|
9
|
+
# (e.g. a mailing list), then run this script. The script will first make a
|
10
|
+
# new mailbox folder for storing messages from this sender if one doesn't
|
11
|
+
# already exist. It will then create a new Mail rule that automatically moves
|
12
|
+
# incoming messages from this sender directly into this mailbox.
|
13
|
+
|
14
|
+
require "appscript"
|
15
|
+
|
16
|
+
mail = AS.app('Mail')
|
17
|
+
|
18
|
+
# get the current selection in Mail and make sure it's an email message
|
19
|
+
selection = mail.selection.get
|
20
|
+
|
21
|
+
if selection == [] or selection[0].class_.get != :message
|
22
|
+
puts "Please select a message and try again."
|
23
|
+
exit
|
24
|
+
end
|
25
|
+
|
26
|
+
# get a reference to the first selected message
|
27
|
+
msg = selection[0]
|
28
|
+
|
29
|
+
recipient = msg.to_recipients[1]
|
30
|
+
address = recipient.address.get
|
31
|
+
|
32
|
+
# determine the new mailbox's name based on the sender's name/address
|
33
|
+
if recipient.name.exists
|
34
|
+
folder_name = recipient.name.get
|
35
|
+
else
|
36
|
+
folder_name = /^[^@]*/.match(address)[0]
|
37
|
+
end
|
38
|
+
|
39
|
+
# make a new mailbox if one doesn't already exist
|
40
|
+
if not mail.mailboxes[folder_name].exists
|
41
|
+
mail.mailboxes.end.make(:new=>:mailbox, :with_properties=>{
|
42
|
+
:name=>folder_name})
|
43
|
+
end
|
44
|
+
|
45
|
+
# make a new mail rule to move list messages to the mailbox
|
46
|
+
if not mail.rules[folder_name].exists
|
47
|
+
new_rule = mail.rules[1].after.make(:new=>:rule, :with_properties=>{
|
48
|
+
:name=>folder_name,
|
49
|
+
:should_move_message=>true,
|
50
|
+
:move_message=>AS.app.mailboxes[folder_name],
|
51
|
+
:stop_evaluating_rules=>true})
|
52
|
+
new_rule.make(:new=>:rule_condition, :with_properties=>{
|
53
|
+
:expression=>address,
|
54
|
+
:rule_type=>:to_header,
|
55
|
+
:qualifier=>:does_contain_value})
|
56
|
+
new_rule.enabled.set(true)
|
57
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
# Prints the sub-folder hierarchy of a given folder as a list of folder names indented according to depth.
|
4
|
+
|
5
|
+
require "appscript"
|
6
|
+
|
7
|
+
def print_folder_tree(folder, indent='')
|
8
|
+
puts indent + folder.name.get
|
9
|
+
folder.folders.get.each { |folder| print_folder_tree(folder, indent + "\t") }
|
10
|
+
end
|
11
|
+
|
12
|
+
print_folder_tree(AS.app('Finder').home.folders['Documents'])
|
@@ -0,0 +1,20 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
# Set iChat's status message to the name of the currently selected
|
4
|
+
# iTunes track.
|
5
|
+
#
|
6
|
+
# Based on an AppleScript example from:
|
7
|
+
# <http://developer.apple.com/cocoa/applescriptforapps.html>
|
8
|
+
|
9
|
+
require "appscript"
|
10
|
+
|
11
|
+
begin
|
12
|
+
track_name = AS.app("iTunes").current_track.name.get
|
13
|
+
rescue AS::CommandError => e
|
14
|
+
if e.to_i == -1728 # Can't get reference.
|
15
|
+
track_name = 'No track selected.'
|
16
|
+
else
|
17
|
+
raise
|
18
|
+
end
|
19
|
+
end
|
20
|
+
AS.app("iChat").status_message.set(track_name)
|
@@ -0,0 +1,14 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'appscript'
|
4
|
+
|
5
|
+
# Opens a new Finder smart folder that searches for 'ruby', via GUI Scripting
|
6
|
+
|
7
|
+
# (Note: to use GUI Scripting, 'Enable access for assistive devices' option must
|
8
|
+
# be enabled in the Universal Access panel of System Preferences.)
|
9
|
+
|
10
|
+
se = AS.app('System Events')
|
11
|
+
|
12
|
+
AS.app('Finder').activate
|
13
|
+
se.keystroke('n', :using=>[:command_down, :option_down])
|
14
|
+
se.keystroke('ruby')
|
@@ -0,0 +1,21 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
# Rearranges Finder windows diagonally across screen with title bars one above
|
4
|
+
# another. (Could easily be adapted to work with any scriptable application
|
5
|
+
# that uses standard window class terminology.)
|
6
|
+
|
7
|
+
require "appscript"
|
8
|
+
|
9
|
+
x, y = 0, 44
|
10
|
+
offset = 22
|
11
|
+
|
12
|
+
# Get list of window references, ignoring any minimised windows
|
13
|
+
window_list = AS.app('Finder').windows[AS.its.collapsed.not].get
|
14
|
+
|
15
|
+
# Move windows while preserving their original sizes
|
16
|
+
window_list.reverse.each do |window|
|
17
|
+
x1, y1, x2, y2 = window.bounds.get
|
18
|
+
window.bounds.set([x, y, x2 - x1 + x, y2 - y1 + y])
|
19
|
+
x += offset
|
20
|
+
y += offset
|
21
|
+
end
|
@@ -0,0 +1,126 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
# Demonstrates various references and commands in action.
|
4
|
+
|
5
|
+
require "appscript"
|
6
|
+
|
7
|
+
textedit = AS.app('TextEdit') # get an application object for TextEdit
|
8
|
+
|
9
|
+
|
10
|
+
# tell application "TextEdit" to activate
|
11
|
+
textedit.activate
|
12
|
+
|
13
|
+
|
14
|
+
# tell application "TextEdit" to make new document at end of documents
|
15
|
+
textedit.documents.end.make(:new => :document)
|
16
|
+
|
17
|
+
|
18
|
+
# tell application "TextEdit" to set text of document 1 to "Hello World\n"
|
19
|
+
textedit.documents[1].text.set('Hello World\n')
|
20
|
+
|
21
|
+
|
22
|
+
# tell application "TextEdit" to get a reference to every window
|
23
|
+
p textedit.windows
|
24
|
+
|
25
|
+
|
26
|
+
# tell application "TextEdit" to get a reference to document 1
|
27
|
+
p textedit.documents
|
28
|
+
|
29
|
+
|
30
|
+
# tell application "TextEdit" to get every document
|
31
|
+
p textedit.documents.get
|
32
|
+
|
33
|
+
|
34
|
+
# tell application "TextEdit" to get a reference to document 1
|
35
|
+
p textedit.documents[1]
|
36
|
+
|
37
|
+
|
38
|
+
# tell application "TextEdit" to get document 1
|
39
|
+
p textedit.documents[1].get
|
40
|
+
|
41
|
+
|
42
|
+
# tell application "TextEdit" to get window id 3210
|
43
|
+
# p textedit.windows.ID(3210).get
|
44
|
+
|
45
|
+
|
46
|
+
# tell application "TextEdit" to get a reference to text of document 1
|
47
|
+
p textedit.documents[1].text
|
48
|
+
|
49
|
+
|
50
|
+
# tell application "TextEdit" to get text of document 1
|
51
|
+
p textedit.documents[1].text.get
|
52
|
+
|
53
|
+
|
54
|
+
# tell application "TextEdit" to make new document at end of documents
|
55
|
+
textedit.documents.end.make(:new => :document)
|
56
|
+
|
57
|
+
|
58
|
+
# tell application "TextEdit" to set text of document 1 to "Happy Happy Joy Joy\n"
|
59
|
+
textedit.documents[1].text.set("Happy Happy Joy Joy\n")
|
60
|
+
|
61
|
+
|
62
|
+
# tell application "TextEdit" to get text of every document
|
63
|
+
p textedit.documents.text.get
|
64
|
+
|
65
|
+
|
66
|
+
# tell application "TextEdit" to count each word of text of document 1
|
67
|
+
p textedit.documents[1].text.count(:each => :word)
|
68
|
+
|
69
|
+
|
70
|
+
# tell application "TextEdit" to get words 3 thru -1 of document 1
|
71
|
+
p textedit.documents[1].words[3, -1].get
|
72
|
+
|
73
|
+
|
74
|
+
# tell application "TextEdit" to set size of character 1 of every word
|
75
|
+
# of document 1 to 24
|
76
|
+
textedit.documents[1].words.characters[1].size.set(24)
|
77
|
+
|
78
|
+
|
79
|
+
# tell application "TextEdit" to set color of any word of document 1 to {65535, 0, 0}
|
80
|
+
textedit.documents[1].words.any.color.set([65535, 0, 0])
|
81
|
+
|
82
|
+
|
83
|
+
# tell application "TextEdit" to make new paragraph at
|
84
|
+
# (after last paragraph of text of document 1) with data "Silly Rabbit\n"
|
85
|
+
textedit.documents[1].text.paragraphs.last.after.make(
|
86
|
+
:new => :paragraph, :with_data => "Silly Rabbit\n")
|
87
|
+
|
88
|
+
|
89
|
+
# tell application "TextEdit" to get paragraph after paragraph 1 of document 1
|
90
|
+
p textedit.documents[1].paragraphs[1].next(:paragraph).get
|
91
|
+
|
92
|
+
|
93
|
+
# tell application "TextEdit" to make new document at end of documents
|
94
|
+
# with properties {text:"foo\nbar\n\n\nbaz\n\nfub\n"}
|
95
|
+
textedit.documents.end.make(:new => :document,
|
96
|
+
:with_properties => {:text => "foo\nbar\n\n\nbaz\n\nfub\n"})
|
97
|
+
|
98
|
+
|
99
|
+
# tell application "TextEdit" to get every paragraph of text of document 1
|
100
|
+
p textedit.documents[1].text.paragraphs.get
|
101
|
+
|
102
|
+
|
103
|
+
# tell application "TextEdit" to get every paragraph of document 1
|
104
|
+
# where it is not "\n" -- get non-empty paragraphs
|
105
|
+
p textedit.documents[1].paragraphs[AS.its.ne("\n")].get
|
106
|
+
|
107
|
+
|
108
|
+
# tell application "TextEdit" to get text of every document
|
109
|
+
# whose text begins with "H"
|
110
|
+
p textedit.documents[AS.its.text.starts_with('H')].text.get
|
111
|
+
|
112
|
+
|
113
|
+
|
114
|
+
# The following examples don't work in TextEdit but will work in,
|
115
|
+
# for example, Tex-Edit Plus:
|
116
|
+
#
|
117
|
+
# # tell application "Tex-Edit Plus" to get words (character 5)
|
118
|
+
# # thru (paragraph 9) of document 1
|
119
|
+
# p app('Tex-Edit Plus').documents[1] \
|
120
|
+
# .words[AS.con.characters[5], AS.con.paragraphs[9]].get
|
121
|
+
#
|
122
|
+
#
|
123
|
+
# # tell application "Tex-Edit Plus" to get every word of text
|
124
|
+
# # of document 1 whose color is {0, 0, 0}
|
125
|
+
# p app('Tex-Edit Plus').documents[1].text.paragraphs \
|
126
|
+
# [AS.its.color.equals((0, 0, 0))].get
|
@@ -0,0 +1,64 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
# This script renders the track and album names of the top 40 most played
|
4
|
+
# iTunes tracks to an HTML file, then opens it in Safari.
|
5
|
+
#
|
6
|
+
# Requires the Amrita templating engine: http://amrita.sourceforge.jp
|
7
|
+
|
8
|
+
require 'appscript'
|
9
|
+
require 'osax'
|
10
|
+
require "amrita/template"
|
11
|
+
include Amrita
|
12
|
+
|
13
|
+
# Amrita HTML template
|
14
|
+
tmpl = TemplateText.new <<END
|
15
|
+
<html>
|
16
|
+
<head>
|
17
|
+
<title> iTunes Top 40 Tracks</title>
|
18
|
+
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
19
|
+
<style type="text/css" media="all">
|
20
|
+
body {padding:0; margin:0;}
|
21
|
+
table {color:black; background-color:#448; width:100%; padding:2px;}
|
22
|
+
th, td {padding:2px; border-width:0;}
|
23
|
+
th {color:#fff; background-color:#114;}
|
24
|
+
td {color:black; background-color:#bbd;}
|
25
|
+
</style>
|
26
|
+
</head>
|
27
|
+
<body>
|
28
|
+
<table border="1">
|
29
|
+
<thead>
|
30
|
+
<tr><th>#</th><th>Track</th><th>Album</th></tr>
|
31
|
+
</thead>
|
32
|
+
<tbody>
|
33
|
+
<tr id="table_row"><td id="table_column"></td></tr>
|
34
|
+
</tbody>
|
35
|
+
</table>
|
36
|
+
</body>
|
37
|
+
</html>
|
38
|
+
END
|
39
|
+
|
40
|
+
# Choose the file to write
|
41
|
+
sa = OSAX.osax('StandardAdditions')
|
42
|
+
out_file = sa.choose_file_name(:default_name=>'My iTunes Top 40.html')
|
43
|
+
|
44
|
+
# Get the played count, name and album for every track in iTunes
|
45
|
+
tracks = AS.app('iTunes').library_playlists[1].tracks
|
46
|
+
info = tracks.played_count.get.zip(tracks.name.get, tracks.album.get)
|
47
|
+
# Extract the top 40 most played entries
|
48
|
+
top40 = info.sort.reverse[0, 40]
|
49
|
+
|
50
|
+
# Assemble input data for Amrita
|
51
|
+
data = {
|
52
|
+
:table_row=>top40.collect { |row_data| {:table_column=>row_data} }
|
53
|
+
}
|
54
|
+
|
55
|
+
# Render HTML file
|
56
|
+
tmpl.prettyprint = true
|
57
|
+
File.open(out_file.to_s, 'w') { |f| tmpl.expand(f, data) }
|
58
|
+
|
59
|
+
# Open file in Safari for viewing
|
60
|
+
safari = AS.app('Safari')
|
61
|
+
safari.activate
|
62
|
+
safari.open(out_file)
|
63
|
+
|
64
|
+
|