rb-scrpt 1.0.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (96) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGES +497 -0
  3. data/README.md +8 -0
  4. data/Rakefile +32 -0
  5. data/doc/aem-manual/01_introduction.html +60 -0
  6. data/doc/aem-manual/02_apioverview.html +107 -0
  7. data/doc/aem-manual/03_packingandunpackingdata.html +135 -0
  8. data/doc/aem-manual/04_references.html +409 -0
  9. data/doc/aem-manual/05_targetingapplications.html +164 -0
  10. data/doc/aem-manual/06_buildingandsendingevents.html +229 -0
  11. data/doc/aem-manual/07_findapp.html +63 -0
  12. data/doc/aem-manual/08_examples.html +94 -0
  13. data/doc/aem-manual/aemreferenceinheritance.gif +0 -0
  14. data/doc/aem-manual/index.html +56 -0
  15. data/doc/appscript-manual/01_introduction.html +94 -0
  16. data/doc/appscript-manual/02_aboutappscripting.html +247 -0
  17. data/doc/appscript-manual/03_quicktutorial.html +167 -0
  18. data/doc/appscript-manual/04_gettinghelp.html +188 -0
  19. data/doc/appscript-manual/05_keywordconversion.html +106 -0
  20. data/doc/appscript-manual/06_classesandenums.html +192 -0
  21. data/doc/appscript-manual/07_applicationobjects.html +211 -0
  22. data/doc/appscript-manual/08_realvsgenericreferences.html +96 -0
  23. data/doc/appscript-manual/09_referenceforms.html +241 -0
  24. data/doc/appscript-manual/10_referenceexamples.html +154 -0
  25. data/doc/appscript-manual/11_applicationcommands.html +245 -0
  26. data/doc/appscript-manual/12_commandexamples.html +138 -0
  27. data/doc/appscript-manual/13_performanceissues.html +142 -0
  28. data/doc/appscript-manual/14_notes.html +80 -0
  29. data/doc/appscript-manual/application_architecture.gif +0 -0
  30. data/doc/appscript-manual/application_architecture2.gif +0 -0
  31. data/doc/appscript-manual/finder_to_textedit_event.gif +0 -0
  32. data/doc/appscript-manual/index.html +62 -0
  33. data/doc/appscript-manual/relationships_example.gif +0 -0
  34. data/doc/appscript-manual/ruby_to_itunes_event.gif +0 -0
  35. data/doc/full.css +106 -0
  36. data/doc/index.html +45 -0
  37. data/doc/mactypes-manual/01_introduction.html +54 -0
  38. data/doc/mactypes-manual/02_aliasclass.html +124 -0
  39. data/doc/mactypes-manual/03_fileurlclass.html +126 -0
  40. data/doc/mactypes-manual/04_unitsclass.html +100 -0
  41. data/doc/mactypes-manual/index.html +53 -0
  42. data/doc/osax-manual/01_introduction.html +67 -0
  43. data/doc/osax-manual/02_interface.html +147 -0
  44. data/doc/osax-manual/03_examples.html +73 -0
  45. data/doc/osax-manual/04_notes.html +61 -0
  46. data/doc/osax-manual/index.html +53 -0
  47. data/doc/rb-appscript-logo.png +0 -0
  48. data/extconf.rb +63 -0
  49. data/rb-scrpt.gemspec +16 -0
  50. data/sample/AB_export_vcard.rb +31 -0
  51. data/sample/AB_list_people_with_emails.rb +13 -0
  52. data/sample/Add_iCal_event.rb +21 -0
  53. data/sample/Create_daily_iCal_todos.rb +75 -0
  54. data/sample/Export_Address_Book_phone_numbers.rb +59 -0
  55. data/sample/Hello_world.rb +21 -0
  56. data/sample/List_iTunes_playlist_names.rb +11 -0
  57. data/sample/Make_Mail_message.rb +33 -0
  58. data/sample/Open_file_in_TextEdit.rb +13 -0
  59. data/sample/Organize_Mail_messages.rb +61 -0
  60. data/sample/Print_folder_tree.rb +16 -0
  61. data/sample/Select_all_HTML_files.rb +14 -0
  62. data/sample/Set_iChat_status.rb +24 -0
  63. data/sample/Simple_Finder_GUI_Scripting.rb +18 -0
  64. data/sample/Stagger_Finder_windows.rb +25 -0
  65. data/sample/TextEdit_demo.rb +130 -0
  66. data/sample/iTunes_top40_to_html.rb +69 -0
  67. data/src/SendThreadSafe.c +380 -0
  68. data/src/SendThreadSafe.h +139 -0
  69. data/src/lib/_aem/aemreference.rb +1021 -0
  70. data/src/lib/_aem/codecs.rb +661 -0
  71. data/src/lib/_aem/connect.rb +205 -0
  72. data/src/lib/_aem/encodingsupport.rb +74 -0
  73. data/src/lib/_aem/findapp.rb +85 -0
  74. data/src/lib/_aem/mactypes.rb +250 -0
  75. data/src/lib/_aem/send.rb +279 -0
  76. data/src/lib/_aem/typewrappers.rb +59 -0
  77. data/src/lib/_appscript/defaultterminology.rb +277 -0
  78. data/src/lib/_appscript/referencerenderer.rb +242 -0
  79. data/src/lib/_appscript/reservedkeywords.rb +116 -0
  80. data/src/lib/_appscript/safeobject.rb +250 -0
  81. data/src/lib/_appscript/terminology.rb +470 -0
  82. data/src/lib/aem.rb +253 -0
  83. data/src/lib/kae.rb +1489 -0
  84. data/src/lib/osax.rb +659 -0
  85. data/src/lib/rb-scrpt.rb +1073 -0
  86. data/src/lib/version.rb +3 -0
  87. data/src/rbae.c +979 -0
  88. data/test/README +3 -0
  89. data/test/test_aemreference.rb +115 -0
  90. data/test/test_appscriptcommands.rb +149 -0
  91. data/test/test_appscriptreference.rb +103 -0
  92. data/test/test_codecs.rb +181 -0
  93. data/test/test_findapp.rb +23 -0
  94. data/test/test_mactypes.rb +77 -0
  95. data/test/test_osax.rb +52 -0
  96. metadata +146 -0
data/src/lib/aem.rb ADDED
@@ -0,0 +1,253 @@
1
+ #
2
+ # rb-appscript
3
+ #
4
+ # aem -- a mid-level object-oriented API for creating and sending Apple events
5
+ # using raw AE codes; may be used directly or via high-level appscript wrapper
6
+ #
7
+
8
+ require "ae"
9
+ require "kae"
10
+ require "_aem/findapp"
11
+ require "_aem/mactypes"
12
+
13
+ module AEM
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
253
+ end