rb-appscript 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|
+
|