rb-scpt 1.0.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.
Files changed (94) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGES +497 -0
  3. data/doc/aem-manual/01_introduction.html +60 -0
  4. data/doc/aem-manual/02_apioverview.html +107 -0
  5. data/doc/aem-manual/03_packingandunpackingdata.html +135 -0
  6. data/doc/aem-manual/04_references.html +409 -0
  7. data/doc/aem-manual/05_targetingapplications.html +164 -0
  8. data/doc/aem-manual/06_buildingandsendingevents.html +229 -0
  9. data/doc/aem-manual/07_findapp.html +63 -0
  10. data/doc/aem-manual/08_examples.html +94 -0
  11. data/doc/aem-manual/aemreferenceinheritance.gif +0 -0
  12. data/doc/aem-manual/index.html +56 -0
  13. data/doc/appscript-manual/01_introduction.html +94 -0
  14. data/doc/appscript-manual/02_aboutappscripting.html +247 -0
  15. data/doc/appscript-manual/03_quicktutorial.html +167 -0
  16. data/doc/appscript-manual/04_gettinghelp.html +188 -0
  17. data/doc/appscript-manual/05_keywordconversion.html +106 -0
  18. data/doc/appscript-manual/06_classesandenums.html +192 -0
  19. data/doc/appscript-manual/07_applicationobjects.html +211 -0
  20. data/doc/appscript-manual/08_realvsgenericreferences.html +96 -0
  21. data/doc/appscript-manual/09_referenceforms.html +241 -0
  22. data/doc/appscript-manual/10_referenceexamples.html +154 -0
  23. data/doc/appscript-manual/11_applicationcommands.html +245 -0
  24. data/doc/appscript-manual/12_commandexamples.html +138 -0
  25. data/doc/appscript-manual/13_performanceissues.html +142 -0
  26. data/doc/appscript-manual/14_notes.html +80 -0
  27. data/doc/appscript-manual/application_architecture.gif +0 -0
  28. data/doc/appscript-manual/application_architecture2.gif +0 -0
  29. data/doc/appscript-manual/finder_to_textedit_event.gif +0 -0
  30. data/doc/appscript-manual/index.html +62 -0
  31. data/doc/appscript-manual/relationships_example.gif +0 -0
  32. data/doc/appscript-manual/ruby_to_itunes_event.gif +0 -0
  33. data/doc/full.css +106 -0
  34. data/doc/index.html +45 -0
  35. data/doc/mactypes-manual/01_introduction.html +54 -0
  36. data/doc/mactypes-manual/02_aliasclass.html +124 -0
  37. data/doc/mactypes-manual/03_fileurlclass.html +126 -0
  38. data/doc/mactypes-manual/04_unitsclass.html +100 -0
  39. data/doc/mactypes-manual/index.html +53 -0
  40. data/doc/osax-manual/01_introduction.html +67 -0
  41. data/doc/osax-manual/02_interface.html +147 -0
  42. data/doc/osax-manual/03_examples.html +73 -0
  43. data/doc/osax-manual/04_notes.html +61 -0
  44. data/doc/osax-manual/index.html +53 -0
  45. data/doc/rb-appscript-logo.png +0 -0
  46. data/extconf.rb +65 -0
  47. data/rb-scpt.gemspec +14 -0
  48. data/sample/AB_export_vcard.rb +31 -0
  49. data/sample/AB_list_people_with_emails.rb +13 -0
  50. data/sample/Add_iCal_event.rb +21 -0
  51. data/sample/Create_daily_iCal_todos.rb +75 -0
  52. data/sample/Export_Address_Book_phone_numbers.rb +59 -0
  53. data/sample/Hello_world.rb +21 -0
  54. data/sample/List_iTunes_playlist_names.rb +11 -0
  55. data/sample/Make_Mail_message.rb +33 -0
  56. data/sample/Open_file_in_TextEdit.rb +13 -0
  57. data/sample/Organize_Mail_messages.rb +61 -0
  58. data/sample/Print_folder_tree.rb +16 -0
  59. data/sample/Select_all_HTML_files.rb +14 -0
  60. data/sample/Set_iChat_status.rb +24 -0
  61. data/sample/Simple_Finder_GUI_Scripting.rb +18 -0
  62. data/sample/Stagger_Finder_windows.rb +25 -0
  63. data/sample/TextEdit_demo.rb +130 -0
  64. data/sample/iTunes_top40_to_html.rb +71 -0
  65. data/src/SendThreadSafe.c +380 -0
  66. data/src/SendThreadSafe.h +139 -0
  67. data/src/lib/_aem/aemreference.rb +1022 -0
  68. data/src/lib/_aem/codecs.rb +662 -0
  69. data/src/lib/_aem/connect.rb +205 -0
  70. data/src/lib/_aem/encodingsupport.rb +77 -0
  71. data/src/lib/_aem/findapp.rb +85 -0
  72. data/src/lib/_aem/mactypes.rb +251 -0
  73. data/src/lib/_aem/send.rb +279 -0
  74. data/src/lib/_aem/typewrappers.rb +59 -0
  75. data/src/lib/_appscript/defaultterminology.rb +277 -0
  76. data/src/lib/_appscript/referencerenderer.rb +245 -0
  77. data/src/lib/_appscript/reservedkeywords.rb +116 -0
  78. data/src/lib/_appscript/safeobject.rb +249 -0
  79. data/src/lib/_appscript/terminology.rb +471 -0
  80. data/src/lib/aem.rb +253 -0
  81. data/src/lib/appscript.rb +1075 -0
  82. data/src/lib/kae.rb +1489 -0
  83. data/src/lib/osax.rb +659 -0
  84. data/src/rbae.c +979 -0
  85. data/test/README +3 -0
  86. data/test/test_aemreference.rb +118 -0
  87. data/test/test_appscriptcommands.rb +152 -0
  88. data/test/test_appscriptreference.rb +106 -0
  89. data/test/test_codecs.rb +186 -0
  90. data/test/test_findapp.rb +26 -0
  91. data/test/test_mactypes.rb +79 -0
  92. data/test/test_osax.rb +54 -0
  93. data/test/testall.sh +10 -0
  94. metadata +145 -0
@@ -0,0 +1,245 @@
1
+ #
2
+ # rb-appscript
3
+ #
4
+ # referencerenderer -- obtain an appscript-style string representation of an aem reference
5
+ #
6
+
7
+ require "_aem/aemreference"
8
+
9
+
10
+ class ReferenceRenderer
11
+ # Generates string representations of appscript references from aem object specifiers.
12
+
13
+ private_class_method :new
14
+ attr_reader :result
15
+
16
+ def initialize(app_data)
17
+ @_app_data = app_data
18
+ @result = ""
19
+ end
20
+
21
+ def _format(val)
22
+ if val.is_a?(AEMReference::Query)
23
+ return ReferenceRenderer.render(@_app_data, val)
24
+ else
25
+ return val.inspect
26
+ end
27
+ end
28
+
29
+ ##
30
+
31
+ def property(code)
32
+ name = @_app_data.reference_by_code.fetch('p'+code) { @_app_data.reference_by_code.fetch('e'+code) }
33
+ @result += ".#{name}"
34
+ return self
35
+ end
36
+
37
+ def elements(code)
38
+ name = @_app_data.reference_by_code.fetch('e'+code) { @_app_data.reference_by_code.fetch('p'+code) }
39
+ @result += ".#{name}"
40
+ return self
41
+ end
42
+
43
+ def by_name(name)
44
+ @result += "[#{_format(name)}]"
45
+ return self
46
+ end
47
+
48
+ def by_index(index)
49
+ @result += "[#{_format(index)}]"
50
+ return self
51
+ end
52
+
53
+ def by_id(id)
54
+ @result += ".ID(#{_format(id)})"
55
+ return self
56
+ end
57
+
58
+ def by_range(sel1, sel2)
59
+ @result += "[#{_format(sel1)}, #{_format(sel2)}]"
60
+ return self
61
+ end
62
+
63
+ def by_filter(sel)
64
+ @result += "[#{_format(sel)}]"
65
+ return self
66
+ end
67
+
68
+ def previous(sel)
69
+ @result += ".previous(#{_format(@_app_data.type_by_code[sel])})"
70
+ return self
71
+ end
72
+
73
+ def next(sel)
74
+ @result += ".next(#{_format(@_app_data.type_by_code[sel])})"
75
+ return self
76
+ end
77
+
78
+ ##
79
+
80
+ def custom_root(value)
81
+ app
82
+ @result += ".AS_new_reference(#{value.inspect})"
83
+ return self
84
+ end
85
+
86
+ def app
87
+ case @_app_data.constructor
88
+ when :current
89
+ @result = "app.current"
90
+ when :by_path
91
+ @result = "app(#{@_app_data.identifier.inspect})"
92
+ else
93
+ @result = "app.#{@_app_data.constructor}(#{@_app_data.identifier.inspect})"
94
+ end
95
+ return self
96
+ end
97
+
98
+ def con
99
+ @result = "con"
100
+ return self
101
+ end
102
+
103
+ def its
104
+ @result = "its"
105
+ return self
106
+ end
107
+
108
+ ##
109
+
110
+ def beginning
111
+ @result += ".beginning"
112
+ return self
113
+ end
114
+
115
+ def end
116
+ @result += ".end"
117
+ return self
118
+ end
119
+
120
+ def before
121
+ @result += ".before"
122
+ return self
123
+ end
124
+
125
+ def after
126
+ @result += ".after"
127
+ return self
128
+ end
129
+
130
+ ##
131
+
132
+ def first
133
+ @result += ".first"
134
+ return self
135
+ end
136
+
137
+ def middle
138
+ @result += ".middle"
139
+ return self
140
+ end
141
+
142
+ def last
143
+ @result += ".last"
144
+ return self
145
+ end
146
+
147
+ def any
148
+ @result += ".any"
149
+ return self
150
+ end
151
+
152
+ ##
153
+
154
+ def gt(val)
155
+ @result += ".gt(#{_format(val)})"
156
+ return self
157
+ end
158
+
159
+ def ge(val)
160
+ @result += ".ge(#{_format(val)})"
161
+ return self
162
+ end
163
+
164
+ def eq(val)
165
+ @result += ".eq(#{_format(val)})"
166
+ return self
167
+ end
168
+
169
+ def ne(val)
170
+ @result += ".ne(#{_format(val)})"
171
+ return self
172
+ end
173
+
174
+ def lt(val)
175
+ @result += ".lt(#{_format(val)})"
176
+ return self
177
+ end
178
+
179
+ def le(val)
180
+ @result += ".le(#{_format(val)})"
181
+ return self
182
+ end
183
+
184
+ def begins_with(val)
185
+ @result += ".begins_with(#{_format(val)})"
186
+ return self
187
+ end
188
+
189
+ def ends_with(val)
190
+ @result += ".ends_with(#{_format(val)})"
191
+ return self
192
+ end
193
+
194
+ def contains(val)
195
+ @result += ".contains(#{_format(val)})"
196
+ return self
197
+ end
198
+
199
+ def is_in(val)
200
+ @result += ".is_in(#{_format(val)})"
201
+ return self
202
+ end
203
+
204
+ def and(*operands)
205
+ @result += ".and(#{(operands.map { |val| _format(val) }).join(', ')})"
206
+ return self
207
+ end
208
+
209
+ def or(*operands)
210
+ @result += ".or(#{(operands.map { |val| _format(val) }).join(', ')})"
211
+ return self
212
+ end
213
+
214
+ def not
215
+ @result += ".not"
216
+ return self
217
+ end
218
+
219
+ # public
220
+
221
+ def ReferenceRenderer.render(app_data, aem_reference)
222
+ # Take an aem reference, e.g.:
223
+ #
224
+ # app.elements('docu').by_index(1).property('ctxt')
225
+ #
226
+ # and an AppData instance containing application's location and terminology,
227
+ # and render an appscript-style reference string, e.g.:
228
+ #
229
+ # "AS.app('/Applications/TextEdit.app').documents[1].text"
230
+ #
231
+ # Used by AS::Reference#to_s
232
+ #
233
+ f = new(app_data)
234
+ begin
235
+ aem_reference.AEM_resolve(f)
236
+ return f.result
237
+ rescue
238
+ return "#{new(app_data).app.result}.AS_new_reference(#{aem_reference.inspect})"
239
+ end
240
+ end
241
+
242
+ end
243
+
244
+
245
+
@@ -0,0 +1,116 @@
1
+ #
2
+ # rb-appscript
3
+ #
4
+ # reservedkeywords -- names of methods already used by Ruby's Object class
5
+ # and appscript's Reference class
6
+ #
7
+
8
+ # This list is mirrored in ch.6 of the appscript manual and in py-osaterminology's makeidentifier module
9
+
10
+ ReservedKeywords = [
11
+ "==",
12
+ "===",
13
+ "=~",
14
+ "AS_aem_reference",
15
+ "AS_aem_reference=",
16
+ "AS_app_data",
17
+ "AS_app_data=",
18
+ "AS_new_reference",
19
+ "AS_resolve",
20
+ "ID",
21
+ "[]",
22
+ "__id__",
23
+ "__send__",
24
+ "_aem_application_class",
25
+ "_call",
26
+ "_resolve_range_boundary",
27
+ "_send_command",
28
+ "abort_transaction",
29
+ "after",
30
+ "and",
31
+ "any",
32
+ "app",
33
+ "before",
34
+ "begin_transaction",
35
+ "beginning",
36
+ "begins_with",
37
+ "by_aem_app",
38
+ "by_creator",
39
+ "by_id",
40
+ "by_name",
41
+ "by_pid",
42
+ "by_url",
43
+ "class",
44
+ "clone",
45
+ "commands",
46
+ "con",
47
+ "contains",
48
+ "current",
49
+ "display",
50
+ "does_not_contain",
51
+ "does_not_end_with",
52
+ "does_not_begin_with",
53
+ "dup",
54
+ "elements",
55
+ "end",
56
+ "end_transaction",
57
+ "ends_with",
58
+ "eq",
59
+ "eql?",
60
+ "equal?",
61
+ "extend",
62
+ "first",
63
+ "freeze",
64
+ "frozen?",
65
+ "ge",
66
+ "gt",
67
+ "hash",
68
+ "help",
69
+ "id",
70
+ "ignore",
71
+ "inspect",
72
+ "instance_eval",
73
+ "instance_of?",
74
+ "instance_variable_get",
75
+ "instance_variable_set",
76
+ "instance_variables",
77
+ "is_a?",
78
+ "is_in",
79
+ "is_not_in",
80
+ "is_running?",
81
+ "its",
82
+ "keywords",
83
+ "kind_of?",
84
+ "last",
85
+ "launch",
86
+ "le",
87
+ "lt",
88
+ "method",
89
+ "method_missing",
90
+ "methods",
91
+ "middle",
92
+ "ne",
93
+ "next",
94
+ "nil?",
95
+ "not",
96
+ "object_id",
97
+ "or",
98
+ "parameters",
99
+ "previous",
100
+ "private_methods",
101
+ "properties",
102
+ "protected_methods",
103
+ "public_methods",
104
+ "respond_to?",
105
+ "result_type",
106
+ "send",
107
+ "singleton_methods",
108
+ "taint",
109
+ "tainted?",
110
+ "timeout",
111
+ "to_a",
112
+ "to_s",
113
+ "type",
114
+ "untaint",
115
+ "wait_reply",
116
+ ]
@@ -0,0 +1,249 @@
1
+ #
2
+ # rb-appscript
3
+ #
4
+ # safeobject -- ensure Appscript::Reference#method_missing works reliably
5
+ #
6
+ # Original code Copyright (C) 2005 Thomas Sawyer, Jim Weirich; see below for original copyright
7
+ #
8
+
9
+ # Notes:
10
+
11
+ # A modified, updated version of basicobject (http://facets.rubyforge.org/), used to provide
12
+ # Appscript::Reference and Appscript#GenericReference with stable superclasses.
13
+
14
+ # Unfortunately, Ruby makes it ludicrously easy for users to accidentally add new methods
15
+ # to the Object class. And if these methods' names are the same as application keywords,
16
+ # Ruby will invoke them instead of Reference#method_missing, resulting in incorrect behaviour.
17
+ #
18
+ # e.g. The following code demonstrates the problem in an unpatched copy of appscript 0.2.1.
19
+ # Including modules in the main script for convenience is a not-uncommon practice; unfortunately,
20
+ # because main's class is Object, this causes the additional methods to appear on every other
21
+ # object in the system as well (very bad).
22
+ #
23
+ #######
24
+ # require 'appscript'
25
+ #
26
+ # module X
27
+ # def name
28
+ # puts 'X.name was called'
29
+ # return 999
30
+ # end
31
+ # end
32
+ # include X
33
+ #
34
+ # Appscript.app('textedit').name.get
35
+ ########
36
+ #
37
+ # Result:
38
+ #
39
+ # # X.name was called
40
+ # # /tmp/tmpscript:13: undefined method `get' for 999:Fixnum (NoMethodError)
41
+
42
+ # The AS_SafeObject class undefines any methods not on the EXCLUDE safe list; traps are
43
+ # then applied to Module#method_added and Module#included to detect any subsequent
44
+ # method additions and immediately remove those from AS_SafeObject as well.
45
+
46
+ # Having to insert traps into other users' runtimes isn't exactly an ideal solution, but
47
+ # unless/until Ruby comes up with a safe, sane system for including modules in main that
48
+ # doesn't pollute every other namespace as well, it may be the only practical solution. The
49
+ # only other alternative would be a major redesign+rewrite of the appscript module to use
50
+ # metaclasses (c.f. js-appscript) instead of method_missing, but this is not really desireable
51
+ # as it'd be much more complicated to implement, slower to initialise, and less elegant to
52
+ # use (since GenericReferences would have to be dropped).
53
+
54
+ ######################################################################
55
+ # ORIGINAL COPYRIGHT
56
+ ######################################################################
57
+
58
+ # = basicobject.rb
59
+ #
60
+ # == Copyright (c) 2005 Thomas Sawyer, Jim Weirich
61
+ #
62
+ # THE RUBY LICENSE
63
+ # (http://www.ruby-lang.org/en/LICENSE.txt)
64
+ #
65
+ # You may redistribute this software and/or modify it under either the terms of
66
+ # the GPL (see below), or the conditions below:
67
+ #
68
+ # 1. You may make and give away verbatim copies of the source form of the
69
+ # software without restriction, provided that you duplicate all of the
70
+ # original copyright notices and associated disclaimers.
71
+ #
72
+ # 2. You may modify your copy of the software in any way, provided that
73
+ # you do at least ONE of the following:
74
+ #
75
+ # a) place your modifications in the Public Domain or otherwise
76
+ # make them Freely Available, such as by posting said
77
+ # modifications to Usenet or an equivalent medium, or by allowing
78
+ # the author to include your modifications in the software.
79
+ #
80
+ # b) use the modified software only within your corporation or
81
+ # organization.
82
+ #
83
+ # c) rename any non-standard executables so the names do not conflict
84
+ # with standard executables, which must also be provided.
85
+ #
86
+ # d) make other distribution arrangements with the author.
87
+ #
88
+ # 3. You may distribute the software in object code or executable
89
+ # form, provided that you do at least ONE of the following:
90
+ #
91
+ # a) distribute the executables and library files of the software,
92
+ # together with instructions (in the manual page or equivalent)
93
+ # on where to get the original distribution.
94
+ #
95
+ # b) accompany the distribution with the machine-readable source of
96
+ # the software.
97
+ #
98
+ # c) give non-standard executables non-standard names, with
99
+ # instructions on where to get the original software distribution.
100
+ #
101
+ # d) make other distribution arrangements with the author.
102
+ #
103
+ # 4. You may modify and include the part of the software into any other
104
+ # software (possibly commercial). But some files in the distribution
105
+ # are not written by the author, so that they are not under these terms.
106
+ #
107
+ # For the list of those files and their copying conditions, see the
108
+ # file LEGAL.
109
+ #
110
+ # 5. The scripts and library files supplied as input to or produced as
111
+ # output from the software do not automatically fall under the
112
+ # copyright of the software, but belong to whomever generated them,
113
+ # and may be sold commercially, and may be aggregated with this
114
+ # software.
115
+ #
116
+ # 6. THIS SOFTWARE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR
117
+ # IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
118
+ # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
119
+ # PURPOSE.
120
+
121
+ ######################################################################
122
+ # PUBLIC
123
+ ######################################################################
124
+
125
+ require '_appscript/reservedkeywords'
126
+
127
+ class AS_SafeObject
128
+
129
+ EXCLUDE = ReservedKeywords + [
130
+ "Array",
131
+ "Float",
132
+ "Integer",
133
+ "String",
134
+ "`",
135
+ "abort",
136
+ "at_exit",
137
+ "autoload",
138
+ "autoload?",
139
+ "binding",
140
+ "block_given?",
141
+ "callcc",
142
+ "caller",
143
+ "catch",
144
+ "chomp",
145
+ "chomp!",
146
+ "chop",
147
+ "chop!",
148
+ "eval",
149
+ "exec",
150
+ "exit",
151
+ "exit!",
152
+ "fail",
153
+ "fork",
154
+ "format",
155
+ "getc",
156
+ "gets",
157
+ "global_variables",
158
+ "gsub",
159
+ "gsub!",
160
+ "initialize",
161
+ "initialize_copy",
162
+ "iterator?",
163
+ "lambda",
164
+ "load",
165
+ "local_variables",
166
+ "loop",
167
+ "open",
168
+ "p",
169
+ "print",
170
+ "printf",
171
+ "proc",
172
+ "putc",
173
+ "puts",
174
+ "raise",
175
+ "rand",
176
+ "readline",
177
+ "readlines",
178
+ "remove_instance_variable",
179
+ "require",
180
+ "scan",
181
+ "select",
182
+ "set_trace_func",
183
+ "singleton_method_added",
184
+ "singleton_method_removed",
185
+ "singleton_method_undefined",
186
+ "sleep",
187
+ "split",
188
+ "sprintf",
189
+ "srand",
190
+ "sub",
191
+ "sub!",
192
+ "syscall",
193
+ "system",
194
+ "test",
195
+ "throw",
196
+ "trace_var",
197
+ "trap",
198
+ "untrace_var",
199
+ "warn"
200
+ ] + [
201
+ /^__/, /^instance_/, /^object_/, /\?$/, /^\W$/,
202
+ ]
203
+
204
+ def self.hide(name)
205
+ case name.to_s # Ruby1.9 returns method names as symbols, not strings as in 1.8
206
+ when *EXCLUDE
207
+ else
208
+ undef_method(name) rescue nil
209
+ end
210
+ end
211
+
212
+ public_instance_methods(true).each { |m| hide(m) }
213
+ #private_instance_methods(true).each { |m| hide(m) }
214
+ protected_instance_methods(true).each { |m| hide(m) }
215
+
216
+ end
217
+
218
+
219
+
220
+ ######################################################################
221
+ # PRIVATE
222
+ ######################################################################
223
+ # Since Ruby is very dynamic, methods added to the ancestors of
224
+ # AS_SafeObject after AS_SafeObject is defined will show up in the
225
+ # list of available AS_SafeObject methods. We handle this by defining
226
+ # hooks in Module that will hide any defined.
227
+
228
+ class Module
229
+ madded = method(:method_added)
230
+ define_method(:method_added) do |name|
231
+ # puts "ADDED %-32s %s" % [name, self]
232
+ result = madded.call(name)
233
+ if self == Object
234
+ AS_SafeObject.hide(name)
235
+ end
236
+ return result
237
+ end
238
+ mincluded = method(:included)
239
+ define_method(:included) do |mod|
240
+ result = mincluded.call(mod)
241
+ # puts "INCLUDED %-32s %s" % [mod, self]
242
+ if mod == Object
243
+ public_instance_methods(true).each { |name| AS_SafeObject.hide(name) }
244
+ #private_instance_methods(true).each { |name| AS_SafeObject.hide(name) }
245
+ protected_instance_methods(true).each { |name| AS_SafeObject.hide(name) }
246
+ end
247
+ return result
248
+ end
249
+ end