rb-scpt 1.0.1 → 1.0.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (50) hide show
  1. checksums.yaml +4 -4
  2. data/bin/rb-scpt-1.0.1.gem +0 -0
  3. data/extconf.rb +12 -12
  4. data/rb-scpt.gemspec +10 -10
  5. data/sample/AB_export_vcard.rb +16 -16
  6. data/sample/AB_list_people_with_emails.rb +4 -4
  7. data/sample/Add_iCal_event.rb +12 -12
  8. data/sample/Create_daily_iCal_todos.rb +28 -28
  9. data/sample/Export_Address_Book_phone_numbers.rb +52 -52
  10. data/sample/Hello_world.rb +10 -10
  11. data/sample/List_iTunes_playlist_names.rb +3 -3
  12. data/sample/Make_Mail_message.rb +24 -24
  13. data/sample/Open_file_in_TextEdit.rb +5 -5
  14. data/sample/Organize_Mail_messages.rb +46 -46
  15. data/sample/Print_folder_tree.rb +5 -5
  16. data/sample/Select_all_HTML_files.rb +6 -6
  17. data/sample/Set_iChat_status.rb +12 -12
  18. data/sample/Simple_Finder_GUI_Scripting.rb +6 -6
  19. data/sample/Stagger_Finder_windows.rb +9 -9
  20. data/sample/TextEdit_demo.rb +71 -71
  21. data/sample/iTunes_top40_to_html.rb +28 -30
  22. data/src/SendThreadSafe.c +293 -293
  23. data/src/SendThreadSafe.h +108 -108
  24. data/src/lib/_aem/aemreference.rb +997 -998
  25. data/src/lib/_aem/codecs.rb +609 -610
  26. data/src/lib/_aem/connect.rb +197 -197
  27. data/src/lib/_aem/encodingsupport.rb +67 -67
  28. data/src/lib/_aem/findapp.rb +75 -75
  29. data/src/lib/_aem/mactypes.rb +241 -242
  30. data/src/lib/_aem/send.rb +268 -268
  31. data/src/lib/_aem/typewrappers.rb +52 -52
  32. data/src/lib/_appscript/defaultterminology.rb +266 -266
  33. data/src/lib/_appscript/referencerenderer.rb +230 -233
  34. data/src/lib/_appscript/reservedkeywords.rb +106 -106
  35. data/src/lib/_appscript/safeobject.rb +125 -125
  36. data/src/lib/_appscript/terminology.rb +448 -449
  37. data/src/lib/aem.rb +238 -238
  38. data/src/lib/kae.rb +1487 -1487
  39. data/src/lib/osax.rb +647 -647
  40. data/src/lib/rb-scpt.rb +1065 -1065
  41. data/src/rbae.c +595 -595
  42. data/test/test_aemreference.rb +104 -107
  43. data/test/test_appscriptcommands.rb +131 -134
  44. data/test/test_appscriptreference.rb +96 -99
  45. data/test/test_codecs.rb +166 -168
  46. data/test/test_findapp.rb +13 -16
  47. data/test/test_mactypes.rb +70 -72
  48. data/test/test_osax.rb +46 -48
  49. data/test/testall.sh +4 -4
  50. metadata +8 -7
@@ -12,242 +12,242 @@ require "_aem/mactypes"
12
12
 
13
13
  module AEM
14
14
 
15
- # Mid-level wrapper for building and sending Apple events to local and remote applications.
16
-
17
- require "_aem/codecs"
18
- require "_aem/aemreference"
19
- require "_aem/typewrappers"
20
- require "_aem/connect"
21
- require "_aem/send"
22
-
23
- #######
24
- # Constants
25
-
26
- Codecs = Codecs
27
- DefaultCodecs = DefaultCodecs
28
- MacOSError = AE::MacOSError
29
- CantLaunchApplicationError = Connect::CantLaunchApplicationError
30
-
31
-
32
- AEDesc = AE::AEDesc
33
-
34
- AETypeBase = TypeWrappers::AETypeBase
35
- AEType = TypeWrappers::AEType
36
- AEEnum = TypeWrappers::AEEnum
37
- AEProp = TypeWrappers::AEProp
38
- AEKey = TypeWrappers::AEKey
39
-
40
- EventError = Send::EventError
41
- CommandError = Send::EventError # deprecated class name; kept for backwards compatibility
42
-
43
- #######
44
- # Reference roots
45
-
46
- def AEM.app
47
- return AEMReference::App
48
- end
49
-
50
- def AEM.con
51
- return AEMReference::Con
52
- end
53
-
54
- def AEM.its
55
- return AEMReference::Its
56
- end
57
-
58
- def AEM.custom_root(value)
59
- return AEMReference::CustomRoot.new(value)
60
- end
61
-
62
- #######
63
- # Application class
64
-
65
- class Application < AEMReference::Query
66
- # Identifies an application and provides an #event method for constructing Apple events targetted at it.
67
-
68
- require "weakref"
69
-
70
- private_class_method :new
71
- attr_reader :hash, :identity, :address_desc
72
-
73
- #######
74
- # Workaround for lack of proper destructors in Ruby; see #initialize method.
75
-
76
- @@_app_number_count = 0
77
- @@_transaction_ids_by_app_no = {}
78
-
79
- #######
80
-
81
- Event = Send::Event # Application subclasses can override this class constant (usually with a subclass of Send::Event) to modify how Apple events are created and/or sent.
82
-
83
- #######
84
-
85
- def initialize(path, address_desc, identity)
86
- # called by constructor method
87
- # path is used by #reconnect
88
- # address_desc is an AEAddressDesc identifying the target application
89
- # identity is used by #inspect, #hash, #==
90
- @_transaction = KAE::KAnyTransactionID
91
- @_path = path
92
- @address_desc = address_desc
93
- @identity = identity
94
- @hash = identity.hash
95
- # workaround for lack of proper destructors; if a transaction is still open when Application instance is garbage collected, the following finalizer will automatically close it. Note: object IDs were different for some reason, so class maintains its own unique ids.
96
- @app_number = app_number = (@@_app_number_count += 1)
97
- @@_transaction_ids_by_app_no[app_number] = @_transaction
98
- ObjectSpace.define_finalizer(WeakRef.new(self), proc do
99
- transaction_id = @@_transaction_ids_by_app_no.delete(app_number)
100
- if transaction_id != KAE::KAnyTransactionID
101
- self.class::Event.new(@address_desc, 'miscendt', {}, {}, transaction_id).send(60, KAE::KAENoReply)
102
- end
103
- end)
104
- end
105
-
106
- #######
107
- # utility class methods; placed here for convenience
108
-
109
- def Application.launch(path)
110
- # Launches a local application without sending it the usual 'run' event (aevtoapp).
111
- Connect.launch_app_with_launch_event(path)
112
- end
113
-
114
- def Application.process_exists_for_path?(path)
115
- # Does a local process launched from the specified application file exist?
116
- # Note: if path is invalid, an AE::MacOSError is raised.
117
- return Connect.process_exists_for_path?(path)
118
- end
119
-
120
- def Application.process_exists_for_pid?(pid)
121
- # Is there a local application process with the given unix process id?
122
- return Connect.process_exists_for_pid?(pid)
123
- end
124
-
125
- def Application.process_exists_for_url?(url)
126
- # Does an application process specified by the given eppc:// URL exist?
127
- # Returns false if process doesn't exist or if access to it isn't allowed.
128
- # (Implementation note: this method sends an Apple event to the specified process and checks for errors.)
129
- return Connect.process_exists_for_url?(url)
130
- end
131
-
132
- def Application.process_exists_for_desc?(desc)
133
- # Does an application process specified by the given AEAddressDesc exist?
134
- # Returns false if process doesn't exist or if access to it isn't allowed.
135
- # (Implementation note: this method sends an Apple event to the specified process and checks for errors.)
136
- return Connect.process_exists_for_desc?(desc)
137
- end
138
-
139
- #######
140
- # constructors
141
-
142
- def Application.by_path(path)
143
- # path : string -- full path to local application
144
- #
145
- # Note: application will be launched if not already running.
146
- return new(path, Connect.local_app(path), [:path, path])
147
- end
148
-
149
- def Application.by_url(url)
150
- # url : string -- eppc URL for remote process
151
- return new(nil, Connect.remote_app(url), [:url, url])
152
- end
153
-
154
- def Application.by_pid(pid)
155
- # pid : integer -- Unix process id
156
- return new(nil, Connect.local_app_by_pid(pid), [:pid, pid])
157
- end
158
-
159
- def Application.by_desc(desc)
160
- # desc : AEDesc -- an AEAddressDesc
161
- return new(nil, desc, [:desc, desc.type, desc.data])
162
- end
163
-
164
- def Application.current
165
- return new(nil, Connect::CurrentApp, [:current])
166
- end
167
-
168
- #######
169
- # methods
170
-
171
- def inspect
172
- if @identity[0] == :current
173
- return "#{self.class}.current"
174
- else
175
- con_name = {:path => 'by_path', :url => 'by_url', :pid => 'by_pid', :desc => 'by_desc'}[@identity[0]]
176
- return "#{self.class}.#{con_name}(#{@identity[1].inspect})"
177
- end
178
- end
179
-
180
- alias_method :to_s, :inspect
181
-
182
- def ==(val)
183
- return (self.class == val.class and @identity == val.identity)
184
- end
185
-
186
- alias_method :eql?, :==
187
-
188
- # (hash method is provided by attr_reader :hash)
189
-
190
- def AEM_comparable
191
- return ['AEMApplication', @identity]
192
- end
193
-
194
- def AEM_pack_self(codecs)
195
- return @address_desc
196
- end
197
-
198
- def reconnect
199
- # If application has quit since this Application object was created, its AEAddressDesc
200
- # is no longer valid so this Application object will not work even when application is restarted.
201
- # #reconnect will update this Application object's AEAddressDesc so it's valid again.
202
- #
203
- # Note that this only works for Application objects created via the by_path constructor.
204
- # Also note that any Event objects created prior to calling #reconnect will still be invalid.
205
- if @_path
206
- @address_desc = Connect.local_app(@_path)
207
- end
208
- return
209
- end
210
-
211
- def event(event, params={}, atts={}, return_id=KAE::KAutoGenerateReturnID, codecs=DefaultCodecs)
212
- # Construct an Apple event targetted at this application.
213
- # event : string -- 8-letter code indicating event's class, e.g. 'coregetd'
214
- # params : hash -- a dict of form {AE_code:anything,...} containing zero or more event parameters (message arguments)
215
- # atts : hash -- a dict of form {AE_code:anything,...} containing zero or more event attributes (event info)
216
- # return_id : integer -- reply event's ID
217
- # codecs : Codecs -- codecs object to use when packing/unpacking this event
218
- return self.class::Event.new(@address_desc, event, params, atts, @_transaction, return_id, codecs)
219
- end
220
-
221
- def begin_transaction(session=nil)
222
- # Begin a new transaction.
223
- if @_transaction != KAE::KAnyTransactionID
224
- raise RuntimeError, "Transaction is already active."
225
- end
226
- @_transaction = self.class::Event.new(@address_desc, 'miscbegi', session != nil ? {'----' => session} : {}).send
227
- @@_transaction_ids_by_app_no[@app_number] = @_transaction
228
- return
229
- end
230
-
231
- def abort_transaction
232
- # Abort the current transaction.
233
- if @_transaction == KAE::KAnyTransactionID
234
- raise RuntimeError, "No transaction is active."
235
- end
236
- self.class::Event.new(@address_desc, 'miscttrm', {}, {}, @_transaction).send
237
- @_transaction = KAE::KAnyTransactionID
238
- @@_transaction_ids_by_app_no[@app_number] = KAE::KAnyTransactionID
239
- return
240
- end
241
-
242
- def end_transaction
243
- # End the current transaction.
244
- if @_transaction == KAE::KAnyTransactionID
245
- raise RuntimeError, "No transaction is active."
246
- end
247
- self.class::Event.new(@address_desc, 'miscendt', {}, {}, @_transaction).send
248
- @_transaction = KAE::KAnyTransactionID
249
- @@_transaction_ids_by_app_no[@app_number] = KAE::KAnyTransactionID
250
- return
251
- end
252
- end
15
+ # Mid-level wrapper for building and sending Apple events to local and remote applications.
16
+
17
+ require "_aem/codecs"
18
+ require "_aem/aemreference"
19
+ require "_aem/typewrappers"
20
+ require "_aem/connect"
21
+ require "_aem/send"
22
+
23
+ #######
24
+ # Constants
25
+
26
+ Codecs = Codecs
27
+ DefaultCodecs = DefaultCodecs
28
+ MacOSError = AE::MacOSError
29
+ CantLaunchApplicationError = Connect::CantLaunchApplicationError
30
+
31
+
32
+ AEDesc = AE::AEDesc
33
+
34
+ AETypeBase = TypeWrappers::AETypeBase
35
+ AEType = TypeWrappers::AEType
36
+ AEEnum = TypeWrappers::AEEnum
37
+ AEProp = TypeWrappers::AEProp
38
+ AEKey = TypeWrappers::AEKey
39
+
40
+ EventError = Send::EventError
41
+ CommandError = Send::EventError # deprecated class name; kept for backwards compatibility
42
+
43
+ #######
44
+ # Reference roots
45
+
46
+ def AEM.app
47
+ return AEMReference::App
48
+ end
49
+
50
+ def AEM.con
51
+ return AEMReference::Con
52
+ end
53
+
54
+ def AEM.its
55
+ return AEMReference::Its
56
+ end
57
+
58
+ def AEM.custom_root(value)
59
+ return AEMReference::CustomRoot.new(value)
60
+ end
61
+
62
+ #######
63
+ # Application class
64
+
65
+ class Application < AEMReference::Query
66
+ # Identifies an application and provides an #event method for constructing Apple events targetted at it.
67
+
68
+ require "weakref"
69
+
70
+ private_class_method :new
71
+ attr_reader :hash, :identity, :address_desc
72
+
73
+ #######
74
+ # Workaround for lack of proper destructors in Ruby; see #initialize method.
75
+
76
+ @@_app_number_count = 0
77
+ @@_transaction_ids_by_app_no = {}
78
+
79
+ #######
80
+
81
+ Event = Send::Event # Application subclasses can override this class constant (usually with a subclass of Send::Event) to modify how Apple events are created and/or sent.
82
+
83
+ #######
84
+
85
+ def initialize(path, address_desc, identity)
86
+ # called by constructor method
87
+ # path is used by #reconnect
88
+ # address_desc is an AEAddressDesc identifying the target application
89
+ # identity is used by #inspect, #hash, #==
90
+ @_transaction = KAE::KAnyTransactionID
91
+ @_path = path
92
+ @address_desc = address_desc
93
+ @identity = identity
94
+ @hash = identity.hash
95
+ # workaround for lack of proper destructors; if a transaction is still open when Application instance is garbage collected, the following finalizer will automatically close it. Note: object IDs were different for some reason, so class maintains its own unique ids.
96
+ @app_number = app_number = (@@_app_number_count += 1)
97
+ @@_transaction_ids_by_app_no[app_number] = @_transaction
98
+ ObjectSpace.define_finalizer(WeakRef.new(self), proc do
99
+ transaction_id = @@_transaction_ids_by_app_no.delete(app_number)
100
+ if transaction_id != KAE::KAnyTransactionID
101
+ self.class::Event.new(@address_desc, 'miscendt', {}, {}, transaction_id).send(60, KAE::KAENoReply)
102
+ end
103
+ end)
104
+ end
105
+
106
+ #######
107
+ # utility class methods; placed here for convenience
108
+
109
+ def Application.launch(path)
110
+ # Launches a local application without sending it the usual 'run' event (aevtoapp).
111
+ Connect.launch_app_with_launch_event(path)
112
+ end
113
+
114
+ def Application.process_exists_for_path?(path)
115
+ # Does a local process launched from the specified application file exist?
116
+ # Note: if path is invalid, an AE::MacOSError is raised.
117
+ return Connect.process_exists_for_path?(path)
118
+ end
119
+
120
+ def Application.process_exists_for_pid?(pid)
121
+ # Is there a local application process with the given unix process id?
122
+ return Connect.process_exists_for_pid?(pid)
123
+ end
124
+
125
+ def Application.process_exists_for_url?(url)
126
+ # Does an application process specified by the given eppc:// URL exist?
127
+ # Returns false if process doesn't exist or if access to it isn't allowed.
128
+ # (Implementation note: this method sends an Apple event to the specified process and checks for errors.)
129
+ return Connect.process_exists_for_url?(url)
130
+ end
131
+
132
+ def Application.process_exists_for_desc?(desc)
133
+ # Does an application process specified by the given AEAddressDesc exist?
134
+ # Returns false if process doesn't exist or if access to it isn't allowed.
135
+ # (Implementation note: this method sends an Apple event to the specified process and checks for errors.)
136
+ return Connect.process_exists_for_desc?(desc)
137
+ end
138
+
139
+ #######
140
+ # constructors
141
+
142
+ def Application.by_path(path)
143
+ # path : string -- full path to local application
144
+ #
145
+ # Note: application will be launched if not already running.
146
+ return new(path, Connect.local_app(path), [:path, path])
147
+ end
148
+
149
+ def Application.by_url(url)
150
+ # url : string -- eppc URL for remote process
151
+ return new(nil, Connect.remote_app(url), [:url, url])
152
+ end
153
+
154
+ def Application.by_pid(pid)
155
+ # pid : integer -- Unix process id
156
+ return new(nil, Connect.local_app_by_pid(pid), [:pid, pid])
157
+ end
158
+
159
+ def Application.by_desc(desc)
160
+ # desc : AEDesc -- an AEAddressDesc
161
+ return new(nil, desc, [:desc, desc.type, desc.data])
162
+ end
163
+
164
+ def Application.current
165
+ return new(nil, Connect::CurrentApp, [:current])
166
+ end
167
+
168
+ #######
169
+ # methods
170
+
171
+ def inspect
172
+ if @identity[0] == :current
173
+ return "#{self.class}.current"
174
+ else
175
+ con_name = {:path => 'by_path', :url => 'by_url', :pid => 'by_pid', :desc => 'by_desc'}[@identity[0]]
176
+ return "#{self.class}.#{con_name}(#{@identity[1].inspect})"
177
+ end
178
+ end
179
+
180
+ alias_method :to_s, :inspect
181
+
182
+ def ==(val)
183
+ return (self.class == val.class and @identity == val.identity)
184
+ end
185
+
186
+ alias_method :eql?, :==
187
+
188
+ # (hash method is provided by attr_reader :hash)
189
+
190
+ def AEM_comparable
191
+ return ['AEMApplication', @identity]
192
+ end
193
+
194
+ def AEM_pack_self(codecs)
195
+ return @address_desc
196
+ end
197
+
198
+ def reconnect
199
+ # If application has quit since this Application object was created, its AEAddressDesc
200
+ # is no longer valid so this Application object will not work even when application is restarted.
201
+ # #reconnect will update this Application object's AEAddressDesc so it's valid again.
202
+ #
203
+ # Note that this only works for Application objects created via the by_path constructor.
204
+ # Also note that any Event objects created prior to calling #reconnect will still be invalid.
205
+ if @_path
206
+ @address_desc = Connect.local_app(@_path)
207
+ end
208
+ return
209
+ end
210
+
211
+ def event(event, params={}, atts={}, return_id=KAE::KAutoGenerateReturnID, codecs=DefaultCodecs)
212
+ # Construct an Apple event targetted at this application.
213
+ # event : string -- 8-letter code indicating event's class, e.g. 'coregetd'
214
+ # params : hash -- a dict of form {AE_code:anything,...} containing zero or more event parameters (message arguments)
215
+ # atts : hash -- a dict of form {AE_code:anything,...} containing zero or more event attributes (event info)
216
+ # return_id : integer -- reply event's ID
217
+ # codecs : Codecs -- codecs object to use when packing/unpacking this event
218
+ return self.class::Event.new(@address_desc, event, params, atts, @_transaction, return_id, codecs)
219
+ end
220
+
221
+ def begin_transaction(session=nil)
222
+ # Begin a new transaction.
223
+ if @_transaction != KAE::KAnyTransactionID
224
+ raise RuntimeError, "Transaction is already active."
225
+ end
226
+ @_transaction = self.class::Event.new(@address_desc, 'miscbegi', session != nil ? {'----' => session} : {}).send
227
+ @@_transaction_ids_by_app_no[@app_number] = @_transaction
228
+ return
229
+ end
230
+
231
+ def abort_transaction
232
+ # Abort the current transaction.
233
+ if @_transaction == KAE::KAnyTransactionID
234
+ raise RuntimeError, "No transaction is active."
235
+ end
236
+ self.class::Event.new(@address_desc, 'miscttrm', {}, {}, @_transaction).send
237
+ @_transaction = KAE::KAnyTransactionID
238
+ @@_transaction_ids_by_app_no[@app_number] = KAE::KAnyTransactionID
239
+ return
240
+ end
241
+
242
+ def end_transaction
243
+ # End the current transaction.
244
+ if @_transaction == KAE::KAnyTransactionID
245
+ raise RuntimeError, "No transaction is active."
246
+ end
247
+ self.class::Event.new(@address_desc, 'miscendt', {}, {}, @_transaction).send
248
+ @_transaction = KAE::KAnyTransactionID
249
+ @@_transaction_ids_by_app_no[@app_number] = KAE::KAnyTransactionID
250
+ return
251
+ end
252
+ end
253
253
  end