rb-appscript 0.5.0 → 0.5.1
Sign up to get free protection for your applications and to get access to all the features.
- 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
|