rb-appscript 0.5.0 → 0.5.1
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 +19 -0
- data/LICENSE +1 -1
- data/README +5 -5
- data/TODO +3 -1
- data/doc/aem-manual/01_introduction.html +2 -2
- data/doc/aem-manual/02_apioverview.html +2 -2
- data/doc/aem-manual/03_packingandunpackingdata.html +2 -2
- data/doc/aem-manual/04_references.html +9 -21
- data/doc/aem-manual/05_targettingapplications.html +3 -3
- data/doc/aem-manual/06_buildingandsendingevents.html +2 -2
- data/doc/aem-manual/07_findapp.html +2 -2
- data/doc/aem-manual/08_examples.html +3 -3
- data/doc/aem-manual/index.html +2 -2
- data/doc/appscript-manual/01_introduction.html +2 -2
- data/doc/appscript-manual/02_aboutappscripting.html +2 -2
- data/doc/appscript-manual/03_quicktutorial.html +2 -2
- data/doc/appscript-manual/04_gettinghelp.html +2 -2
- data/doc/appscript-manual/05_keywordconversion.html +2 -2
- data/doc/appscript-manual/06_classesandenums.html +2 -2
- data/doc/appscript-manual/07_applicationobjects.html +2 -2
- data/doc/appscript-manual/08_realvsgenericreferences.html +2 -2
- data/doc/appscript-manual/09_referenceforms.html +3 -3
- data/doc/appscript-manual/10_referenceexamples.html +2 -2
- data/doc/appscript-manual/11_applicationcommands.html +2 -2
- data/doc/appscript-manual/12_commandexamples.html +2 -2
- data/doc/appscript-manual/13_performanceissues.html +2 -2
- data/doc/appscript-manual/14_notes.html +2 -2
- data/doc/appscript-manual/index.html +2 -2
- data/doc/{appscript-manual/full.css → full.css} +0 -0
- data/doc/index.html +2 -2
- data/doc/mactypes-manual/index.html +2 -2
- data/doc/osax-manual/index.html +6 -6
- data/extconf.rb +13 -3
- data/rb-appscript.gemspec +2 -1
- data/src/lib/_aem/aemreference.rb +22 -31
- data/src/lib/_aem/codecs.rb +21 -19
- data/src/lib/_aem/connect.rb +7 -3
- data/src/lib/_aem/findapp.rb +7 -3
- data/src/lib/_aem/mactypes.rb +22 -14
- data/src/lib/_aem/send.rb +7 -3
- data/src/lib/_aem/typewrappers.rb +7 -3
- data/src/lib/_appscript/defaultterminology.rb +7 -3
- data/src/lib/_appscript/referencerenderer.rb +7 -3
- data/src/lib/_appscript/reservedkeywords.rb +8 -3
- data/src/lib/_appscript/safeobject.rb +12 -2
- data/src/lib/_appscript/terminology.rb +31 -15
- data/src/lib/aem.rb +8 -3
- data/src/lib/appscript.rb +74 -46
- data/src/lib/osax.rb +7 -6
- data/src/rbae.c +46 -77
- data/test/test_aemreference.rb +10 -4
- data/test/test_appscriptcommands.rb +3 -1
- data/test/test_appscriptreference.rb +5 -3
- data/test/test_codecs.rb +3 -1
- data/test/test_findapp.rb +3 -1
- data/test/test_mactypes.rb +12 -6
- data/test/test_osax.rb +3 -6
- metadata +44 -38
- data/doc/aem-manual/full.css +0 -21
data/src/lib/_aem/send.rb
CHANGED
@@ -1,6 +1,10 @@
|
|
1
|
-
|
2
|
-
#
|
3
|
-
#
|
1
|
+
#
|
2
|
+
# rb-appscript
|
3
|
+
#
|
4
|
+
# send -- Event class represents a packed AppleEvent that's ready to send via AESendMessage
|
5
|
+
#
|
6
|
+
# Copyright (C) 2006-2008 HAS. Released under MIT License.
|
7
|
+
#
|
4
8
|
|
5
9
|
module Send
|
6
10
|
|
@@ -1,6 +1,10 @@
|
|
1
|
-
|
2
|
-
#
|
3
|
-
#
|
1
|
+
#
|
2
|
+
# rb-appscript
|
3
|
+
#
|
4
|
+
# typewrappers -- Ruby classes representing type, enumerator, property and keyword AEDescs
|
5
|
+
#
|
6
|
+
# Copyright (C) 2006-2008 HAS. Released under MIT License.
|
7
|
+
#
|
4
8
|
|
5
9
|
module TypeWrappers
|
6
10
|
|
@@ -1,6 +1,10 @@
|
|
1
|
-
|
2
|
-
#
|
3
|
-
#
|
1
|
+
#
|
2
|
+
# rb-appscript
|
3
|
+
#
|
4
|
+
# defaultterminology -- lookup tables for default type, enumerator and command definitions
|
5
|
+
#
|
6
|
+
# Copyright (C) 2006-2008 HAS. Released under MIT License.
|
7
|
+
#
|
4
8
|
|
5
9
|
module DefaultTerminology
|
6
10
|
# Defines built-in terminology available for any application. When constructing the terminology tables for a particular application, the Terminology module will duplicate these tables and then add application-specific terms to create the finished lookup tables.
|
@@ -1,6 +1,10 @@
|
|
1
|
-
|
2
|
-
#
|
3
|
-
#
|
1
|
+
#
|
2
|
+
# rb-appscript
|
3
|
+
#
|
4
|
+
# referencerenderer -- obtain an appscript-style string representation of an aem reference
|
5
|
+
#
|
6
|
+
# Copyright (C) 2006-2008 HAS. Released under MIT License.
|
7
|
+
#
|
4
8
|
|
5
9
|
require "_aem/aemreference"
|
6
10
|
|
@@ -1,6 +1,11 @@
|
|
1
|
-
|
2
|
-
#
|
3
|
-
#
|
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
|
+
# Copyright (C) 2006-2008 HAS. Released under MIT License.
|
8
|
+
#
|
4
9
|
|
5
10
|
# This list is mirrored in ch.6 of the appscript manual and in py-appscript's osaterminology.makeidentifier module
|
6
11
|
|
@@ -1,4 +1,14 @@
|
|
1
|
-
|
1
|
+
#
|
2
|
+
# rb-appscript
|
3
|
+
#
|
4
|
+
# safeobject -- ensure Appscript::Reference#method_missing works reliably
|
5
|
+
#
|
6
|
+
# New code Copyright (C) 2006-2008 HAS
|
7
|
+
# Original code Copyright (C) 2005 Thomas Sawyer, Jim Weirich; see below for original copyright
|
8
|
+
#
|
9
|
+
|
10
|
+
# Notes:
|
11
|
+
|
2
12
|
# A modified, updated version of basicobject (http://facets.rubyforge.org/), used to provide
|
3
13
|
# Appscript::Reference and Appscript#GenericReference with stable superclasses.
|
4
14
|
|
@@ -143,7 +153,7 @@ class AS_SafeObject
|
|
143
153
|
]
|
144
154
|
|
145
155
|
def self.hide(name)
|
146
|
-
case name
|
156
|
+
case name.to_s # Ruby1.9 returns method names as symbols, not strings as in 1.8
|
147
157
|
when *EXCLUDE
|
148
158
|
else
|
149
159
|
undef_method(name) rescue nil
|
@@ -1,6 +1,10 @@
|
|
1
|
-
|
2
|
-
#
|
3
|
-
#
|
1
|
+
#
|
2
|
+
# rb-appscript
|
3
|
+
#
|
4
|
+
# terminology -- retrieve and convert an application's terminology into lookup tables
|
5
|
+
#
|
6
|
+
# Copyright (C) 2006-2008 HAS. Released under MIT License.
|
7
|
+
#
|
4
8
|
|
5
9
|
######################################################################
|
6
10
|
# TERMINOLOGY PARSER
|
@@ -51,9 +55,21 @@ module TerminologyParser
|
|
51
55
|
return @_str[@_ptr - 4, 4] # big-endian
|
52
56
|
end
|
53
57
|
|
58
|
+
# Ruby 1.9 has changed the way that a character ordinal is obtained
|
59
|
+
maj, min, rev = RUBY_VERSION.split('.')
|
60
|
+
if (maj == '1' and min.to_i < 9) # is Ruby 1.8
|
61
|
+
def _length
|
62
|
+
return @_str[@_ptr]
|
63
|
+
end
|
64
|
+
else
|
65
|
+
def _length
|
66
|
+
return @_str[@_ptr].ord
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
54
70
|
def _name
|
55
71
|
# Read a MacRoman-encoded Pascal keyword string.
|
56
|
-
count =
|
72
|
+
count = _length
|
57
73
|
@_ptr += 1 + count
|
58
74
|
s = @_str[@_ptr - count, count]
|
59
75
|
if not @@_name_cache.has_key?(s)
|
@@ -89,17 +105,17 @@ module TerminologyParser
|
|
89
105
|
|
90
106
|
def parse_command
|
91
107
|
name = _name
|
92
|
-
@_ptr += 1 +
|
108
|
+
@_ptr += 1 + _length # description string
|
93
109
|
@_ptr += @_ptr & 1 # align
|
94
110
|
code = _word + _word # event class + event id
|
95
111
|
# skip result
|
96
112
|
@_ptr += 4 # datatype word
|
97
|
-
@_ptr += 1 +
|
113
|
+
@_ptr += 1 + _length # description string
|
98
114
|
@_ptr += @_ptr & 1 # align
|
99
115
|
@_ptr += 2 # flags integer
|
100
116
|
# skip direct parameter
|
101
117
|
@_ptr += 4 # datatype word
|
102
|
-
@_ptr += 1 +
|
118
|
+
@_ptr += 1 + _length # description string
|
103
119
|
@_ptr += @_ptr & 1 # align
|
104
120
|
@_ptr += 2 # flags integer
|
105
121
|
#
|
@@ -117,7 +133,7 @@ module TerminologyParser
|
|
117
133
|
@_ptr += @_ptr & 1 # align
|
118
134
|
parameter_code = _word
|
119
135
|
@_ptr += 4 # datatype word
|
120
|
-
@_ptr += 1 +
|
136
|
+
@_ptr += 1 + _length # description string
|
121
137
|
@_ptr += @_ptr & 1 # align
|
122
138
|
@_ptr += 2 # flags integer
|
123
139
|
current_command_args.push([parameter_name, parameter_code])
|
@@ -128,7 +144,7 @@ module TerminologyParser
|
|
128
144
|
name = _name
|
129
145
|
@_ptr += @_ptr & 1 # align
|
130
146
|
code = _word
|
131
|
-
@_ptr += 1 +
|
147
|
+
@_ptr += 1 + _length # description string
|
132
148
|
@_ptr += @_ptr & 1 # align
|
133
149
|
is_plural = false
|
134
150
|
_integer.times do # properties
|
@@ -136,7 +152,7 @@ module TerminologyParser
|
|
136
152
|
@_ptr += @_ptr & 1 # align
|
137
153
|
propcode = _word
|
138
154
|
@_ptr += 4 # datatype word
|
139
|
-
@_ptr += 1 +
|
155
|
+
@_ptr += 1 + _length # description string
|
140
156
|
@_ptr += @_ptr & 1 # align
|
141
157
|
flags = _integer
|
142
158
|
if propcode != 'c@#^' # not a superclass definition (see kAEInheritedProperties)
|
@@ -170,10 +186,10 @@ module TerminologyParser
|
|
170
186
|
end
|
171
187
|
|
172
188
|
def parse_comparison # comparison info isn't used
|
173
|
-
@_ptr += 1 +
|
189
|
+
@_ptr += 1 + _length # name string
|
174
190
|
@_ptr += @_ptr & 1 # align
|
175
191
|
@_ptr += 4 # code word
|
176
|
-
@_ptr += 1 +
|
192
|
+
@_ptr += 1 + _length # description string
|
177
193
|
@_ptr += @_ptr & 1 # align
|
178
194
|
end
|
179
195
|
|
@@ -183,7 +199,7 @@ module TerminologyParser
|
|
183
199
|
name = _name
|
184
200
|
@_ptr += @_ptr & 1 # align
|
185
201
|
code = _word
|
186
|
-
@_ptr += 1 +
|
202
|
+
@_ptr += 1 + _length # description string
|
187
203
|
@_ptr += @_ptr & 1 # align
|
188
204
|
if not @_found_enumerators.has_key?(name + code)
|
189
205
|
@enumerators.push([name, code])
|
@@ -193,8 +209,8 @@ module TerminologyParser
|
|
193
209
|
end
|
194
210
|
|
195
211
|
def parse_suite
|
196
|
-
@_ptr += 1 +
|
197
|
-
@_ptr += 1 +
|
212
|
+
@_ptr += 1 + _length # name string
|
213
|
+
@_ptr += 1 + _length # description string
|
198
214
|
@_ptr += @_ptr & 1 # align
|
199
215
|
@_ptr += 4 # code word
|
200
216
|
@_ptr += 4 # level, version integers
|
data/src/lib/aem.rb
CHANGED
@@ -1,6 +1,11 @@
|
|
1
|
-
|
2
|
-
#
|
3
|
-
#
|
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
|
+
# Copyright (C) 2006-2008 HAS. Released under MIT License.
|
8
|
+
#
|
4
9
|
|
5
10
|
require "ae"
|
6
11
|
require "kae"
|
data/src/lib/appscript.rb
CHANGED
@@ -1,6 +1,11 @@
|
|
1
|
-
|
2
|
-
#
|
3
|
-
#
|
1
|
+
#
|
2
|
+
# rb-appscript
|
3
|
+
#
|
4
|
+
# appscript -- syntactically sugared wrapper around the mid-level aem API;
|
5
|
+
# provides a high-level, easy-to-use API for creating and sending Apple events
|
6
|
+
#
|
7
|
+
# Copyright (C) 2006-2008 HAS. Released under MIT License.
|
8
|
+
#
|
4
9
|
|
5
10
|
require "_aem/mactypes"
|
6
11
|
|
@@ -187,15 +192,15 @@ module Appscript
|
|
187
192
|
# if hash contains a 'class' property containing a class name, coerce the AEDesc to that class
|
188
193
|
new_val = Hash[val]
|
189
194
|
if new_val.has_key?(:class_)
|
190
|
-
|
195
|
+
val2 = new_val.delete(:class_)
|
191
196
|
else
|
192
|
-
|
197
|
+
val2 = new_val.delete(ClassType)
|
193
198
|
end
|
194
|
-
if
|
195
|
-
|
199
|
+
if val2.is_a?(Symbol) # get the corresponding AEType (assuming there is one)
|
200
|
+
val2 = @type_by_name.fetch(val2, val2)
|
196
201
|
end
|
197
|
-
if
|
198
|
-
record = record.coerce(
|
202
|
+
if val2.is_a?(AEM::AEType) # coerce the record to the desired type
|
203
|
+
record = record.coerce(val2.code)
|
199
204
|
val = new_val
|
200
205
|
end # else value wasn't a class name, so it'll be packed as a normal record property instead
|
201
206
|
end
|
@@ -241,8 +246,8 @@ module Appscript
|
|
241
246
|
key, value = desc.get_item(i + 1, KAE::TypeWildCard)
|
242
247
|
if key == KAE::KeyASUserRecordFields
|
243
248
|
lst = unpack_aelist(value)
|
244
|
-
(lst.length / 2).times do |
|
245
|
-
dct[lst[
|
249
|
+
(lst.length / 2).times do |j|
|
250
|
+
dct[lst[j * 2]] = lst[j * 2 + 1]
|
246
251
|
end
|
247
252
|
else
|
248
253
|
dct[@type_by_code.fetch(key) { AEM::AEType.new(key) }] = unpack(value)
|
@@ -259,7 +264,7 @@ module Appscript
|
|
259
264
|
return Reference.new(self, @reference_codecs.unpack(desc))
|
260
265
|
end
|
261
266
|
|
262
|
-
def unpack_contains_comp_descriptor(op1, op2)
|
267
|
+
def unpack_contains_comp_descriptor(op1, op2)
|
263
268
|
if op1.is_a?(Appscript::Reference) and op1.AS_aem_reference.AEM_root == AEMReference::Its
|
264
269
|
return op1.contains(op2)
|
265
270
|
else
|
@@ -300,6 +305,7 @@ module Appscript
|
|
300
305
|
protected :_call
|
301
306
|
|
302
307
|
def initialize(call)
|
308
|
+
super()
|
303
309
|
@_call = call
|
304
310
|
end
|
305
311
|
|
@@ -363,22 +369,18 @@ module Appscript
|
|
363
369
|
attr_writer :AS_aem_reference, :AS_app_data
|
364
370
|
|
365
371
|
def initialize(app_data, aem_reference)
|
372
|
+
super()
|
366
373
|
@AS_app_data = app_data
|
367
374
|
@AS_aem_reference = aem_reference
|
368
375
|
end
|
369
376
|
|
370
|
-
def _resolve_range_boundary(selector
|
371
|
-
if selector == nil
|
372
|
-
selector = value_if_none
|
373
|
-
end
|
377
|
+
def _resolve_range_boundary(selector)
|
374
378
|
if selector.is_a?(Appscript::GenericReference)
|
375
379
|
return selector.AS_resolve(@AS_app_data).AS_aem_reference
|
376
380
|
elsif selector.is_a?(Reference)
|
377
381
|
return selector.AS_aem_reference
|
378
|
-
elsif selector.is_a?(String)
|
379
|
-
return AEM.con.elements(@AS_aem_reference.AEM_want).by_name(selector)
|
380
382
|
else
|
381
|
-
return
|
383
|
+
return selector
|
382
384
|
end
|
383
385
|
end
|
384
386
|
|
@@ -505,28 +507,41 @@ module Appscript
|
|
505
507
|
begin
|
506
508
|
return @AS_app_data.target.event(code, params, atts,
|
507
509
|
KAE::KAutoGenerateReturnID, @AS_app_data).send(timeout, send_flags)
|
508
|
-
rescue => e
|
509
|
-
if e.
|
510
|
-
|
511
|
-
|
512
|
-
|
513
|
-
|
514
|
-
|
515
|
-
|
516
|
-
|
517
|
-
|
518
|
-
|
519
|
-
|
520
|
-
|
521
|
-
|
522
|
-
|
510
|
+
rescue AEM::CommandError => e
|
511
|
+
if e.number == -1708 and code == 'ascrnoop'
|
512
|
+
return # 'launch' events always return 'not handled' errors; just ignore these
|
513
|
+
elsif [-600, -609].include?(e.number) and @AS_app_data.constructor == :by_path
|
514
|
+
#
|
515
|
+
# Event was sent to a local app for which we no longer have a valid address
|
516
|
+
# (i.e. the application has quit since this AEM::Application object was made).
|
517
|
+
#
|
518
|
+
# - If application is running under a new process id, we just update the
|
519
|
+
# AEM::Application object and resend the event.
|
520
|
+
#
|
521
|
+
# - If application isn't running, then we see if the event being sent is one of
|
522
|
+
# those allowed to relaunch the application (i.e. 'run' or 'launch'). If it is, the
|
523
|
+
# application is relaunched, the process id updated and the event resent;
|
524
|
+
# if not, the error is rethrown.
|
525
|
+
#
|
526
|
+
if not AEM::Application.process_exists_for_path?(@AS_app_data.identifier)
|
527
|
+
if code == 'ascrnoop'
|
528
|
+
AEM::Application.launch(@AS_app_data.identifier)
|
529
|
+
elsif code != 'aevtoapp'
|
530
|
+
raise CommandError.new(self, name, args, e)
|
523
531
|
end
|
524
|
-
|
525
|
-
|
532
|
+
end
|
533
|
+
# update AEMApplication object's AEAddressDesc
|
534
|
+
@AS_app_data.target.reconnect
|
535
|
+
# re-send command
|
536
|
+
begin
|
537
|
+
return @AS_app_data.target.event(code, params, atts,
|
538
|
+
KAE::KAutoGenerateReturnID, @AS_app_data).send(timeout, send_flags)
|
539
|
+
rescue AEM::CommandError => e
|
540
|
+
raise CommandError.new(self, name, args, e)
|
526
541
|
end
|
527
542
|
end
|
528
|
-
raise CommandError.new(self, name, args, e)
|
529
543
|
end
|
544
|
+
raise CommandError.new(self, name, args, e)
|
530
545
|
end
|
531
546
|
|
532
547
|
|
@@ -627,7 +642,7 @@ module Appscript
|
|
627
642
|
return _send_command(args, name, code[0], code[1])
|
628
643
|
else
|
629
644
|
# see if it's a method that has been added to Object class [presumably] at runtime, but excluded
|
630
|
-
# by
|
645
|
+
# by AS_SafeObject to avoid potential conflicts with property/element/command names
|
631
646
|
begin
|
632
647
|
# Notes:
|
633
648
|
# rb-appscript has to prevent arbitrary methods that are added to Ruby's base Object class
|
@@ -665,19 +680,28 @@ module Appscript
|
|
665
680
|
end
|
666
681
|
|
667
682
|
def [](selector, end_range_selector=nil)
|
683
|
+
raise TypeError, "Bad selector: nil not allowed." if selector == nil
|
668
684
|
if end_range_selector != nil
|
669
685
|
new_ref = @AS_aem_reference.by_range(
|
670
|
-
self._resolve_range_boundary(selector
|
671
|
-
self._resolve_range_boundary(end_range_selector
|
686
|
+
self._resolve_range_boundary(selector),
|
687
|
+
self._resolve_range_boundary(end_range_selector))
|
672
688
|
else
|
673
689
|
case selector
|
674
690
|
when String
|
675
691
|
new_ref = @AS_aem_reference.by_name(selector)
|
676
|
-
when Appscript::GenericReference
|
677
|
-
|
678
|
-
|
679
|
-
|
680
|
-
|
692
|
+
when Appscript::GenericReference, Appscript::Reference, AEMReference::Test
|
693
|
+
case selector
|
694
|
+
when Appscript::GenericReference
|
695
|
+
test_clause = selector.AS_resolve(@AS_app_data).AS_aem_reference
|
696
|
+
when Appscript::Reference
|
697
|
+
test_clause = selector.AS_aem_reference
|
698
|
+
else
|
699
|
+
test_clause = selector
|
700
|
+
end
|
701
|
+
if not test_clause.is_a?(AEMReference::Test)
|
702
|
+
raise TypeError, "Not an its-based test: #{selector}"
|
703
|
+
end
|
704
|
+
new_ref = @AS_aem_reference.by_filter(test_clause)
|
681
705
|
else
|
682
706
|
new_ref = @AS_aem_reference.by_index(selector)
|
683
707
|
end
|
@@ -881,7 +905,11 @@ module Appscript
|
|
881
905
|
AEM::Application.launch(@AS_app_data.identifier)
|
882
906
|
@AS_app_data.target.reconnect
|
883
907
|
else
|
884
|
-
|
908
|
+
begin
|
909
|
+
@AS_app_data.target.event('ascrnoop').send # will send launch event to app if already running; else will error
|
910
|
+
rescue AEM::CommandError => e
|
911
|
+
raise if e.to_i != -1708
|
912
|
+
end
|
885
913
|
end
|
886
914
|
end
|
887
915
|
end
|
data/src/lib/osax.rb
CHANGED
@@ -1,13 +1,14 @@
|
|
1
|
-
|
1
|
+
#
|
2
|
+
# rb-appscript
|
3
|
+
#
|
4
|
+
# osax -- invoke scripting addition (OSAX) commands from Ruby
|
5
|
+
#
|
6
|
+
# Copyright (C) 2006-2008 HAS. Released under MIT License.
|
7
|
+
#
|
2
8
|
|
3
9
|
require "appscript"
|
4
10
|
|
5
11
|
module OSAX
|
6
|
-
|
7
|
-
# Allows scripting additions (a.k.a. OSAXen) to be called from Ruby.
|
8
|
-
#
|
9
|
-
# Note: currently 32-bit only; attempting to create a new ScriptingAddition instance
|
10
|
-
# in a 64-bit process will result in a NotImplementedError.
|
11
12
|
|
12
13
|
######################################################################
|
13
14
|
# PRIVATE
|