osascript 0.4.5
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.github/workflows/gem-push.yml +48 -0
- data/.gitignore +8 -0
- data/.travis.yml +6 -0
- data/CHANGELOG +27 -0
- data/Gemfile +7 -0
- data/Gemfile.lock +30 -0
- data/README.md +294 -0
- data/Rakefile +10 -0
- data/bin/console +14 -0
- data/bin/setup +8 -0
- data/gitignore +2 -0
- data/lib/osascript/Key.rb +170 -0
- data/lib/osascript/Osascript.rb +38 -0
- data/lib/osascript/Preview.rb +64 -0
- data/lib/osascript/Safari.rb +100 -0
- data/lib/osascript/any_app.rb +167 -0
- data/lib/osascript/constants.rb +7 -0
- data/lib/osascript/version.rb +3 -0
- data/lib/osascript.rb +12 -0
- data/osascript.gemspec +35 -0
- metadata +97 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 55227c6447a1cb286e91c4db2fc1393f6ef51fa3ca883557516bb3a38d02da26
|
4
|
+
data.tar.gz: 68f08c97cf40f7c5182573bc7e9c67fa45ba02b9065c3999b4b0479091de501d
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 027fbb71cc95313b7d55ec2aa48cfef6bc30ef0cd34a23119ef4858841b450d25f89c01a2c035f89dba86618ee4fe99dc5e1ff1b3fc3fe7d4ebb8932d2a4bddd
|
7
|
+
data.tar.gz: 3258242c68365096110f402512641232338144cf05486faf577fa30f3be6c551eb16a6cbcfe41597b7c15024185670ab3eeedb1f55019db705e83b2b2da2ebf6
|
@@ -0,0 +1,48 @@
|
|
1
|
+
name: Ruby Gem
|
2
|
+
|
3
|
+
on:
|
4
|
+
push:
|
5
|
+
branches: [ "main" ]
|
6
|
+
pull_request:
|
7
|
+
branches: [ "main" ]
|
8
|
+
|
9
|
+
jobs:
|
10
|
+
build:
|
11
|
+
name: Build + Publish
|
12
|
+
runs-on: ubuntu-latest
|
13
|
+
permissions:
|
14
|
+
contents: read
|
15
|
+
packages: write
|
16
|
+
|
17
|
+
steps:
|
18
|
+
- uses: actions/checkout@v3
|
19
|
+
- name: Set up Ruby 2.6
|
20
|
+
# To automatically get bug fixes and new Ruby versions for ruby/setup-ruby,
|
21
|
+
# change this to (see https://github.com/ruby/setup-ruby#versioning):
|
22
|
+
# uses: ruby/setup-ruby@v1
|
23
|
+
uses: ruby/setup-ruby@55283cc23133118229fd3f97f9336ee23a179fcf # v1.146.0
|
24
|
+
with:
|
25
|
+
ruby-version: 2.6.x
|
26
|
+
|
27
|
+
- name: Publish to GPR
|
28
|
+
run: |
|
29
|
+
mkdir -p $HOME/.gem
|
30
|
+
touch $HOME/.gem/credentials
|
31
|
+
chmod 0600 $HOME/.gem/credentials
|
32
|
+
printf -- "---\n:github: ${GEM_HOST_API_KEY}\n" > $HOME/.gem/credentials
|
33
|
+
gem build *.gemspec
|
34
|
+
gem push --KEY github --host https://rubygems.pkg.github.com/${OWNER} *.gem
|
35
|
+
env:
|
36
|
+
GEM_HOST_API_KEY: "Bearer ${{secrets.GITHUB_TOKEN}}"
|
37
|
+
OWNER: ${{ github.repository_owner }}
|
38
|
+
|
39
|
+
- name: Publish to RubyGems
|
40
|
+
run: |
|
41
|
+
mkdir -p $HOME/.gem
|
42
|
+
touch $HOME/.gem/credentials
|
43
|
+
chmod 0600 $HOME/.gem/credentials
|
44
|
+
printf -- "---\n:rubygems_api_key: ${GEM_HOST_API_KEY}\n" > $HOME/.gem/credentials
|
45
|
+
gem build *.gemspec
|
46
|
+
gem push *.gem
|
47
|
+
env:
|
48
|
+
GEM_HOST_API_KEY: "${{secrets.RUBYGEMS_AUTH_TOKEN}}"
|
data/.gitignore
ADDED
data/.travis.yml
ADDED
data/CHANGELOG
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
0.4.5
|
2
|
+
* Essai de gem-push (workflow github).
|
3
|
+
0.4.4
|
4
|
+
* Minor change (retrait des messages degub)
|
5
|
+
0.4.3
|
6
|
+
* Correction bugs sur get_window_properties
|
7
|
+
* Renseignement (aide) dans read me file.
|
8
|
+
0.4.2
|
9
|
+
* Possibilité d'envoyer une liste avec des listes de clés
|
10
|
+
0.4.1
|
11
|
+
* Correction sur le test des dimensions (height too small)
|
12
|
+
0.4.0
|
13
|
+
* Dimension and position of windows (any application)
|
14
|
+
* Setter/getter window properties of any application
|
15
|
+
0.3.1
|
16
|
+
* Osascript::Key, ajout du délai supplémentaire pour une touche
|
17
|
+
0.3.0
|
18
|
+
* Osascript::Key
|
19
|
+
0.2.2
|
20
|
+
* New methods: Safari#document_source_code & Safari#document_text
|
21
|
+
0.2.1
|
22
|
+
* Methods document_name and get_url for Safari
|
23
|
+
0.2.0
|
24
|
+
* First Safari methods.
|
25
|
+
0.1.0
|
26
|
+
* First Any application methods
|
27
|
+
* First Preview methods
|
data/Gemfile
ADDED
data/Gemfile.lock
ADDED
@@ -0,0 +1,30 @@
|
|
1
|
+
PATH
|
2
|
+
remote: .
|
3
|
+
specs:
|
4
|
+
osascript (0.4.4)
|
5
|
+
|
6
|
+
GEM
|
7
|
+
remote: https://rubygems.org/
|
8
|
+
specs:
|
9
|
+
ansi (1.5.0)
|
10
|
+
builder (3.2.4)
|
11
|
+
minitest (5.16.3)
|
12
|
+
minitest-reporters (1.5.0)
|
13
|
+
ansi
|
14
|
+
builder
|
15
|
+
minitest (>= 5.0)
|
16
|
+
ruby-progressbar
|
17
|
+
rake (12.3.3)
|
18
|
+
ruby-progressbar (1.11.0)
|
19
|
+
|
20
|
+
PLATFORMS
|
21
|
+
ruby
|
22
|
+
|
23
|
+
DEPENDENCIES
|
24
|
+
minitest (~> 5.0)
|
25
|
+
minitest-reporters
|
26
|
+
osascript!
|
27
|
+
rake (~> 12.0)
|
28
|
+
|
29
|
+
BUNDLED WITH
|
30
|
+
2.1.4
|
data/README.md
ADDED
@@ -0,0 +1,294 @@
|
|
1
|
+
# Osascript
|
2
|
+
|
3
|
+
Welcome to this *MacOs-Only* new gem!
|
4
|
+
|
5
|
+
## Installation
|
6
|
+
|
7
|
+
Add this line to your application's Gemfile:
|
8
|
+
|
9
|
+
```ruby
|
10
|
+
gem 'osascript'
|
11
|
+
```
|
12
|
+
|
13
|
+
And then execute:
|
14
|
+
|
15
|
+
$ bundle install
|
16
|
+
|
17
|
+
Or install it yourself as:
|
18
|
+
|
19
|
+
$ gem install osascript
|
20
|
+
|
21
|
+
## Usage
|
22
|
+
|
23
|
+
Only with MacOs.
|
24
|
+
|
25
|
+
### With any application
|
26
|
+
|
27
|
+
~~~ruby
|
28
|
+
require 'osascript'
|
29
|
+
|
30
|
+
Osascript.on?("applicationName")
|
31
|
+
# => true if application <applicationName> is running
|
32
|
+
|
33
|
+
# p.e.
|
34
|
+
|
35
|
+
Osascript.on?('Preview')
|
36
|
+
|
37
|
+
~~~
|
38
|
+
|
39
|
+
~~~ruby
|
40
|
+
require 'osascript'
|
41
|
+
|
42
|
+
Osascript.get_window_properties("Finder", {window: "front window"})
|
43
|
+
# => return window’s properties of front window of Finder app
|
44
|
+
# {:bounds, :name, :index, :id, :zoomable, :zoomed, :visible, :miniaturizable
|
45
|
+
# :miniaturized, :closeable, :closed, :titled, :floating, :modal}
|
46
|
+
~~~
|
47
|
+
|
48
|
+
~~~ruby
|
49
|
+
require 'osascript'
|
50
|
+
|
51
|
+
Osascript.quit("applicationName")
|
52
|
+
# => quit application applicationName
|
53
|
+
|
54
|
+
# p.e.
|
55
|
+
Osascript.quit("Final Cut Pro")
|
56
|
+
|
57
|
+
~~~
|
58
|
+
|
59
|
+
---
|
60
|
+
|
61
|
+
<a name="keystroke"></a>
|
62
|
+
|
63
|
+
### Keystroke
|
64
|
+
|
65
|
+
The `Osascript::Key` class and its `press` method let you simulate key strokes.
|
66
|
+
|
67
|
+
**Syntax**
|
68
|
+
|
69
|
+
~~~ruby
|
70
|
+
require 'osascript'
|
71
|
+
|
72
|
+
Osascript::Key.press(
|
73
|
+
<key or array of key>[, <application>|nil][, <options>]
|
74
|
+
)
|
75
|
+
~~~
|
76
|
+
|
77
|
+
|
78
|
+
You can "press" a simple key:
|
79
|
+
|
80
|
+
~~~ruby
|
81
|
+
require 'osascript'
|
82
|
+
|
83
|
+
Osascript::Key.press("a")
|
84
|
+
~~~
|
85
|
+
|
86
|
+
… in a particular application:
|
87
|
+
|
88
|
+
~~~ruby
|
89
|
+
require 'osascript'
|
90
|
+
|
91
|
+
Osascript::Key.press("a", "TextEdit")
|
92
|
+
~~~
|
93
|
+
|
94
|
+
… or a word:
|
95
|
+
|
96
|
+
~~~ruby
|
97
|
+
Osascript::Key.press("Hello world !")
|
98
|
+
~~~
|
99
|
+
|
100
|
+
… or a list of keys:
|
101
|
+
|
102
|
+
~~~ruby
|
103
|
+
Osascript::Key.press(["a","b","c"])
|
104
|
+
~~~
|
105
|
+
|
106
|
+
You can set a delay between each stroke:
|
107
|
+
|
108
|
+
~~~ruby
|
109
|
+
Osascript::Key.press(["a","b","c"], nil, {delay: 2.5})
|
110
|
+
# 2.5 seconds between each stroke
|
111
|
+
~~~
|
112
|
+
|
113
|
+
… or a list of words:
|
114
|
+
|
115
|
+
~~~ruby
|
116
|
+
Osascript::Key.press(["Hello", 'world'])
|
117
|
+
~~~
|
118
|
+
|
119
|
+
You can press a key with a modifier:
|
120
|
+
|
121
|
+
~~~ruby
|
122
|
+
Osascript::Key.press({"a", modifiers:[:command]})
|
123
|
+
# => select all
|
124
|
+
Osascript::Key.press({"c", modifiers:[:option]})
|
125
|
+
# => stroke a "Ç"
|
126
|
+
~~~
|
127
|
+
|
128
|
+
… or a list of keys with modifiers:
|
129
|
+
|
130
|
+
~~~ruby
|
131
|
+
Osascript::Key.press([
|
132
|
+
{key:"z", modifiers:[:command]},
|
133
|
+
{key:"z", modifiers:[:command, :shift]},
|
134
|
+
{key:"z", modifiers:[:command]},
|
135
|
+
])
|
136
|
+
~~~
|
137
|
+
|
138
|
+
… or a key with (supplementary) delay before:
|
139
|
+
|
140
|
+
~~~ruby
|
141
|
+
Osascript::Key.press([
|
142
|
+
{key:"z", delay: 4}, # wait 4 seconds before press "z"
|
143
|
+
])
|
144
|
+
~~~
|
145
|
+
|
146
|
+
You can press a key as a `Symbol`:
|
147
|
+
|
148
|
+
~~~ruby
|
149
|
+
Osascript::Key.press(:space)
|
150
|
+
~~~
|
151
|
+
|
152
|
+
… or a list of keys as `Symbol`:
|
153
|
+
|
154
|
+
~~~ruby
|
155
|
+
Osascript::Key.press(["a", :space, :enter, :left_arrow])
|
156
|
+
~~~
|
157
|
+
|
158
|
+
… or any of these above:
|
159
|
+
|
160
|
+
~~~ruby
|
161
|
+
Osascript::Key.press([
|
162
|
+
"a",
|
163
|
+
"hello",
|
164
|
+
:left_arrow
|
165
|
+
{key: "v", modifiers:[:command]},
|
166
|
+
{key: :BACKSPACE, modifiers:[:command]}
|
167
|
+
])
|
168
|
+
~~~
|
169
|
+
|
170
|
+
#### Available Symbol Keys
|
171
|
+
|
172
|
+
~~~ruby
|
173
|
+
# min or maj
|
174
|
+
|
175
|
+
:down_arrow # or :DOWN_ARROW
|
176
|
+
:up_arrow # idem
|
177
|
+
:left_arrow
|
178
|
+
:right_arrow
|
179
|
+
:enter
|
180
|
+
:return
|
181
|
+
:backspace
|
182
|
+
:escape
|
183
|
+
:space
|
184
|
+
:caps_lock
|
185
|
+
:tab
|
186
|
+
|
187
|
+
~~~
|
188
|
+
|
189
|
+
> Tip: to simulate the "Delete" button in a dialog box, use `{key: :backspace, modifiers:[:command]}`
|
190
|
+
|
191
|
+
#### Available modifiers
|
192
|
+
|
193
|
+
~~~ruby
|
194
|
+
# Only min
|
195
|
+
|
196
|
+
:command
|
197
|
+
:option
|
198
|
+
:control
|
199
|
+
:shift
|
200
|
+
|
201
|
+
~~~
|
202
|
+
|
203
|
+
> They are AppleScript modifiers.
|
204
|
+
|
205
|
+
---
|
206
|
+
|
207
|
+
<a name="terminal"></a>
|
208
|
+
|
209
|
+
### With Terminal
|
210
|
+
|
211
|
+
~~~ruby
|
212
|
+
require 'osascript'
|
213
|
+
|
214
|
+
def run_in_terminal(keys, **options)
|
215
|
+
Osascript::Key.press(keys, 'Terminal', **options)
|
216
|
+
end
|
217
|
+
|
218
|
+
#
|
219
|
+
# Open a new window in Terminal console
|
220
|
+
#
|
221
|
+
run_in_terminal({key: "n", modifiers:[:command]})
|
222
|
+
#
|
223
|
+
# Run a script (to see all files in current folder, even hidden ones)
|
224
|
+
#
|
225
|
+
run_in_terminal("ls -la")
|
226
|
+
|
227
|
+
~~~
|
228
|
+
|
229
|
+
---
|
230
|
+
|
231
|
+
<a name="preview"></a>
|
232
|
+
|
233
|
+
### With Preview
|
234
|
+
|
235
|
+
~~~ruby
|
236
|
+
require 'osascript'
|
237
|
+
|
238
|
+
Osascript::Preview.open_document("/path/to/doc.pdf")
|
239
|
+
# => open document in Preview
|
240
|
+
|
241
|
+
Osascript::Preview.document_opened?("/path/to/doc.pdf")
|
242
|
+
# => return true if document is opened in Preview
|
243
|
+
|
244
|
+
Osascript::Preview.documents_paths
|
245
|
+
# => return {Array} of path {String} of every document
|
246
|
+
# opened in Preview
|
247
|
+
|
248
|
+
Osascript::Preview.documents_names
|
249
|
+
# => return {Array} of name {String} of every document
|
250
|
+
# opened in Preview
|
251
|
+
~~~
|
252
|
+
|
253
|
+
<a name="safari"></a>
|
254
|
+
|
255
|
+
### With Safari
|
256
|
+
|
257
|
+
~~~ruby
|
258
|
+
Osascript::Safari.open_url("https://my.url/to/open.html")
|
259
|
+
# => open the ur in the front document
|
260
|
+
|
261
|
+
Osascript::Safari.open_url("https://my.url/to/open.html", {new_window: true})
|
262
|
+
# => open the url in a new tab of front window
|
263
|
+
|
264
|
+
Osascript::Safari.get_url
|
265
|
+
# => return the url of the front document
|
266
|
+
|
267
|
+
Osascript::Safari.get_url(where: 'tab 3 of window 2')
|
268
|
+
# => return the url of the tab 3 of window 2
|
269
|
+
|
270
|
+
Osascript::Safari.window_name
|
271
|
+
# => return the displayed name of the front window
|
272
|
+
|
273
|
+
Osascript::Safari.window_name(where: 'window 3')
|
274
|
+
# => return the displayed name of the window 3
|
275
|
+
|
276
|
+
Osascript::Safari.run_javascript("alert('Hello word!')")
|
277
|
+
# => run the javascript code in the front document
|
278
|
+
|
279
|
+
Osascript::Safari.run_javascript("alert('Hello word!')", {where:'tab 2 of window 1'})
|
280
|
+
# => run the javascript code in the tab 2 of window 1
|
281
|
+
|
282
|
+
~~~
|
283
|
+
|
284
|
+
|
285
|
+
## Development
|
286
|
+
|
287
|
+
After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake test` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
|
288
|
+
|
289
|
+
To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
|
290
|
+
|
291
|
+
## Contributing
|
292
|
+
|
293
|
+
Bug reports and pull requests are welcome on GitHub at https://github.com/PhilippePerret/osascript.
|
294
|
+
|
data/Rakefile
ADDED
data/bin/console
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require "bundler/setup"
|
4
|
+
require "osascript"
|
5
|
+
|
6
|
+
# You can add fixtures and/or initialization code here to make experimenting
|
7
|
+
# with your gem easier. You can also use a different console, if you like.
|
8
|
+
|
9
|
+
# (If you use this, don't forget to add pry to your Gemfile!)
|
10
|
+
# require "pry"
|
11
|
+
# Pry.start
|
12
|
+
|
13
|
+
require "irb"
|
14
|
+
IRB.start(__FILE__)
|
data/bin/setup
ADDED
data/gitignore
ADDED
@@ -0,0 +1,170 @@
|
|
1
|
+
=begin
|
2
|
+
Pour activer des touches dans une application quelconque avec :
|
3
|
+
Osascript::Key.press(:down_arrow, 'Terminal')
|
4
|
+
|
5
|
+
@Examples
|
6
|
+
---------
|
7
|
+
|
8
|
+
Osascript::Key.press([
|
9
|
+
"Hello",
|
10
|
+
{key:"a", modifiers:[:command]},
|
11
|
+
"Bonjour",
|
12
|
+
{key:" tout le monde ", delay: 3},
|
13
|
+
{key:"a", modifiers:[:command]},
|
14
|
+
{key:"c", modifiers:[:command]},
|
15
|
+
:RIGHT_ARROW,
|
16
|
+
{key:"v", modifiers:[:command]},
|
17
|
+
{key:"s", modifiers:[:command]},
|
18
|
+
"my document",
|
19
|
+
:RETURN
|
20
|
+
],
|
21
|
+
"TextEdit",
|
22
|
+
{delay: 1}
|
23
|
+
)
|
24
|
+
|
25
|
+
Should: write "Hello" in a TextEdit document, then select "Hello"
|
26
|
+
and replace it with "Bonjour", then write " tout le monde ", then
|
27
|
+
select all, then copy all in the clipboard, then move to the end,
|
28
|
+
then paste the phrase, then save document as "my document.txt".
|
29
|
+
|
30
|
+
@usage
|
31
|
+
|
32
|
+
Osacript::Key.press([<keys>][,"<application>"][,{<options>}])
|
33
|
+
|
34
|
+
keys {Array|String|Integer|Hash|Symbol}
|
35
|
+
|
36
|
+
When {Integer} : a key code — exemple 125 for arrow down
|
37
|
+
When {String} : the key to press, for example "v"
|
38
|
+
When {Symbol} : a value among : :down_arrow, :up_arrow, :left_arrow,
|
39
|
+
right_arrow, :enter, :return, :erase, :backspace,
|
40
|
+
:space, :escape, :caps_lock, :tab
|
41
|
+
When {Hash} : a key with modifiers
|
42
|
+
{
|
43
|
+
key: the key (integer, string, symbol),
|
44
|
+
modifiers: {Array} with values among :shift, :control,
|
45
|
+
:command, :option
|
46
|
+
delay: {Integer} wait before this seconds time
|
47
|
+
}
|
48
|
+
For examples:
|
49
|
+
{key:"v", modifiers:[:option]}
|
50
|
+
[key:123, modifiers:[:shift, :control]]
|
51
|
+
|
52
|
+
When {Array} : list of keys defined as above
|
53
|
+
|
54
|
+
|
55
|
+
with options
|
56
|
+
|
57
|
+
delay: Time between strokes (default: 0.5)
|
58
|
+
|
59
|
+
'option', 'shift', 'command', 'control'
|
60
|
+
|
61
|
+
|
62
|
+
|
63
|
+
See also:
|
64
|
+
https://eastmanreference.com/complete-list-of-applescript-key-codes
|
65
|
+
|
66
|
+
=end
|
67
|
+
module Osascript
|
68
|
+
class Key
|
69
|
+
class << self
|
70
|
+
def press(keys, app = nil, options = nil)
|
71
|
+
options ||= {}
|
72
|
+
options.key?(:delay) || options.merge!(delay: 0.5)
|
73
|
+
# Rationalize keys to not contain Array
|
74
|
+
keys = rationalize_keys(keys)
|
75
|
+
if app.nil?
|
76
|
+
press_without_app(keys, options)
|
77
|
+
else
|
78
|
+
press_with_app(keys, app, options)
|
79
|
+
end
|
80
|
+
end
|
81
|
+
##
|
82
|
+
# +key+ must contain only Integer, Float, String or Hash
|
83
|
+
def rationalize_keys(keys)
|
84
|
+
return keys unless keys.is_a?(Array)
|
85
|
+
only_keys = []
|
86
|
+
keys.each do |ii|
|
87
|
+
case ii
|
88
|
+
when Array then only_keys += rationalize_keys(ii)
|
89
|
+
else only_keys << ii
|
90
|
+
end
|
91
|
+
end
|
92
|
+
return only_keys
|
93
|
+
end
|
94
|
+
def press_with_app(keys, app, options)
|
95
|
+
code = <<~CODE
|
96
|
+
activate
|
97
|
+
activate
|
98
|
+
#{code_system_events(keys, options)}
|
99
|
+
CODE
|
100
|
+
# puts "code :\n#{code}"
|
101
|
+
Osascript::__asrun(code, app)
|
102
|
+
end
|
103
|
+
|
104
|
+
def press_without_app(keys, options)
|
105
|
+
code = <<~CODE
|
106
|
+
#{code_system_events(key, options)}
|
107
|
+
CODE
|
108
|
+
Osascript::__asrun(code)
|
109
|
+
end
|
110
|
+
|
111
|
+
def code_system_events(keys, options)
|
112
|
+
keys = [keys] unless keys.is_a?(Array)
|
113
|
+
keys_stroke = keys.map do |key|
|
114
|
+
"delay #{options[:delay]}\n#{key_to_sysevents_code(key)}"
|
115
|
+
end.join("\n")
|
116
|
+
<<~CODE
|
117
|
+
tell application "System Events"
|
118
|
+
#{keys_stroke}
|
119
|
+
end tell
|
120
|
+
CODE
|
121
|
+
end
|
122
|
+
|
123
|
+
def key_to_sysevents_code(key)
|
124
|
+
if key.is_a?(Hash)
|
125
|
+
modifiers = key[:modifiers]
|
126
|
+
delay_sup = key[:delay] # délai ajouté
|
127
|
+
key = key[:key]
|
128
|
+
else
|
129
|
+
modifiers = nil
|
130
|
+
delay_sup = nil
|
131
|
+
end
|
132
|
+
code = case key
|
133
|
+
when String
|
134
|
+
key = key.gsub(/"/, '\\\"') unless key.match?(/\\"/)
|
135
|
+
# key = key.gsub(/\~/, '\\~')
|
136
|
+
"keystroke \"#{key}\""
|
137
|
+
when Integer
|
138
|
+
"key code #{key}"
|
139
|
+
when Symbol
|
140
|
+
"key code #{KEY2CODE[key]}"
|
141
|
+
else
|
142
|
+
raise "Unvalid class pour key: #{key.class}"
|
143
|
+
end
|
144
|
+
if modifiers
|
145
|
+
modifiers = modifiers.map {|mod| "#{mod} down" }.join(', ')
|
146
|
+
code = "#{code} using {#{modifiers}}"
|
147
|
+
end
|
148
|
+
if not(delay_sup.nil?)
|
149
|
+
code = "delay #{delay_sup}\n#{code}"
|
150
|
+
end
|
151
|
+
return code
|
152
|
+
end
|
153
|
+
end #/<< self Key
|
154
|
+
|
155
|
+
KEY2CODE = {
|
156
|
+
down_arrow: 125, DOWN_ARROW: 125, DOWN: 125,
|
157
|
+
up_arrow: 126, UP_ARROW: 126, UP: 126,
|
158
|
+
left_arrow: 123, LEFT_ARROW: 123, LEFT: 123,
|
159
|
+
right_arrow: 124, RIGHT_ARROW: 124, RIGHT: 124,
|
160
|
+
enter: 76, ENTER: 76,
|
161
|
+
return: 36, RETURN: 36, RET: 36,
|
162
|
+
backspace: 51, BACKSPACE: 51,
|
163
|
+
escape: 53, ESCAPE: 53, ESC: 53,
|
164
|
+
space: 49, SPACE: 49,
|
165
|
+
caps_lock: 57, CAPS_LOCK: 57,
|
166
|
+
tab: 48, TAB: 48
|
167
|
+
|
168
|
+
}
|
169
|
+
end #/class Key
|
170
|
+
end #/module Osascript
|
@@ -0,0 +1,38 @@
|
|
1
|
+
module Osascript
|
2
|
+
|
3
|
+
##
|
4
|
+
# = main =
|
5
|
+
#
|
6
|
+
# Méthode principale qui exécute le code +code+
|
7
|
+
#
|
8
|
+
def self.__asrun(code, application = nil)
|
9
|
+
if application
|
10
|
+
code = <<~TEXT
|
11
|
+
tell application "#{application}"
|
12
|
+
#{code}
|
13
|
+
end tell
|
14
|
+
TEXT
|
15
|
+
end
|
16
|
+
resultat = `osascript <<'TEXT'
|
17
|
+
#{code.strip}
|
18
|
+
TEXT
|
19
|
+
`
|
20
|
+
return resultat.strip
|
21
|
+
end
|
22
|
+
|
23
|
+
|
24
|
+
# @return true if application +app_name+ is running
|
25
|
+
def self.on?(app_name)
|
26
|
+
retour = __asrun("tell application \"System Events\" to return (name of processes) contains \"#{app_name}\"")
|
27
|
+
# puts "retour = #{retour.inspect}"
|
28
|
+
return retour == "true"
|
29
|
+
end
|
30
|
+
|
31
|
+
# Quit application +app_name+ if it's running
|
32
|
+
def self.quit(app_name)
|
33
|
+
if on?(app_name)
|
34
|
+
__asrun("tell application \"#{app_name}\" to quit")
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
end #/module Osascript
|
@@ -0,0 +1,64 @@
|
|
1
|
+
=begin
|
2
|
+
|
3
|
+
Module spécial pour l'application Preview/Aperçu
|
4
|
+
|
5
|
+
=end
|
6
|
+
module Osascript
|
7
|
+
class Preview
|
8
|
+
class << self
|
9
|
+
|
10
|
+
# Ouvre le document +filepath+
|
11
|
+
def open_document(filepath)
|
12
|
+
Osascript::__asrun("open POSIX file \"#{filepath}\"", 'Preview')
|
13
|
+
end
|
14
|
+
|
15
|
+
# @return true si le document de path +filepath+ est ouvert
|
16
|
+
def document_opened?(filepath)
|
17
|
+
code = <<~CODE
|
18
|
+
repeat 10 times
|
19
|
+
try
|
20
|
+
set doc to first document whose path is "#{filepath}"
|
21
|
+
return true
|
22
|
+
on error errMsg
|
23
|
+
delay 0.5
|
24
|
+
end try
|
25
|
+
end repeat
|
26
|
+
return false
|
27
|
+
CODE
|
28
|
+
retour = Osascript::__asrun(code, 'Preview')
|
29
|
+
return retour == 'true'
|
30
|
+
end
|
31
|
+
|
32
|
+
# @return {Array} La liste de tous les documents ouverts dans
|
33
|
+
# preview
|
34
|
+
def documents_names
|
35
|
+
liste = Osascript::__asrun(<<~CODE)
|
36
|
+
tell application "Preview"
|
37
|
+
set names to name of every document
|
38
|
+
end tell
|
39
|
+
set text item delimiters to {"', '"}
|
40
|
+
set names to names as text
|
41
|
+
set text item delimiters to {}
|
42
|
+
return "['" & names & "']"
|
43
|
+
CODE
|
44
|
+
# puts "liste = #{liste.inspect}"
|
45
|
+
return liste == "['']" ? [] : eval(liste)
|
46
|
+
end
|
47
|
+
|
48
|
+
def documents_paths
|
49
|
+
liste = Osascript::__asrun(<<~CODE)
|
50
|
+
tell application "Preview"
|
51
|
+
set paths to path of every document
|
52
|
+
end tell
|
53
|
+
set text item delimiters to {"', '"}
|
54
|
+
set paths to paths as text
|
55
|
+
set text item delimiters to {}
|
56
|
+
return "['" & paths & "']"
|
57
|
+
CODE
|
58
|
+
# puts "liste = #{liste.inspect}"
|
59
|
+
return liste == "['']" ? [] : eval(liste)
|
60
|
+
end
|
61
|
+
|
62
|
+
end #/<< self
|
63
|
+
end #/class Preview
|
64
|
+
end #/module Osascript
|
@@ -0,0 +1,100 @@
|
|
1
|
+
module Osascript
|
2
|
+
class Safari
|
3
|
+
class << self
|
4
|
+
|
5
|
+
# Open URL +url+ in front document or a new window if
|
6
|
+
# +options[new_window]+ is true
|
7
|
+
#
|
8
|
+
def open_url(url, options = nil)
|
9
|
+
options ||= {}
|
10
|
+
where =
|
11
|
+
if options[:new_window]
|
12
|
+
"(make new tab in window 1)"
|
13
|
+
else
|
14
|
+
"front document"
|
15
|
+
end
|
16
|
+
code = <<~CODE
|
17
|
+
if count of window is 0
|
18
|
+
make new document
|
19
|
+
end
|
20
|
+
set the URL of #{where} to \"#{url}\"
|
21
|
+
CODE
|
22
|
+
Osascript::__asrun(code, 'Safari')
|
23
|
+
end
|
24
|
+
|
25
|
+
# Run a javascript code in the front document or the
|
26
|
+
# +options[:where]+ tab.
|
27
|
+
#
|
28
|
+
def run_javascript(code, options = nil)
|
29
|
+
options ||= {}
|
30
|
+
where = options[:where] || 'front document'
|
31
|
+
code = <<~CODE
|
32
|
+
do Javascript "#{code}" in #{where}
|
33
|
+
CODE
|
34
|
+
Osascript::__asrun(code, 'Safari')
|
35
|
+
end
|
36
|
+
|
37
|
+
# @return the name of the front document
|
38
|
+
def window_name(options = nil)
|
39
|
+
options ||= {}
|
40
|
+
where = options[:where] || 'front window'
|
41
|
+
code = <<~CODE
|
42
|
+
if count of window is 0
|
43
|
+
return null
|
44
|
+
else
|
45
|
+
return name of (#{where})
|
46
|
+
end
|
47
|
+
CODE
|
48
|
+
Osascript::__asrun(code, 'Safari')
|
49
|
+
end
|
50
|
+
|
51
|
+
# @return the URL of front document or of the options[:where]
|
52
|
+
# tab (for instance : options[:where] = 'tab 2 of window 1').
|
53
|
+
def get_url(options = nil)
|
54
|
+
options ||= {}
|
55
|
+
where = options[:where] || 'front document'
|
56
|
+
code = <<~CODE
|
57
|
+
if count of window is 0
|
58
|
+
return null
|
59
|
+
else
|
60
|
+
return URL of (#{where})
|
61
|
+
end
|
62
|
+
CODE
|
63
|
+
Osascript::__asrun(code, 'Safari')
|
64
|
+
end
|
65
|
+
|
66
|
+
# @return the text displayed of front document or of the
|
67
|
+
# +options[:where] tab (for instance : options[:where] = 'tab 2 of
|
68
|
+
# window 1').
|
69
|
+
def document_text
|
70
|
+
options ||= {}
|
71
|
+
where = options[:where] || 'front document'
|
72
|
+
code = <<~CODE
|
73
|
+
if count of window is 0
|
74
|
+
return null
|
75
|
+
else
|
76
|
+
return text of (#{where})
|
77
|
+
end
|
78
|
+
CODE
|
79
|
+
Osascript::__asrun(code, 'Safari')
|
80
|
+
end
|
81
|
+
|
82
|
+
# @return the HTML source code of front document or of the
|
83
|
+
# +options[:where] tab (for instance : options[:where] = 'tab 2 of
|
84
|
+
# window 1').
|
85
|
+
def document_source_code
|
86
|
+
options ||= {}
|
87
|
+
where = options[:where] || 'front document'
|
88
|
+
code = <<~CODE
|
89
|
+
if count of window is 0
|
90
|
+
return null
|
91
|
+
else
|
92
|
+
return source of (#{where})
|
93
|
+
end
|
94
|
+
CODE
|
95
|
+
Osascript::__asrun(code, 'Safari')
|
96
|
+
end
|
97
|
+
|
98
|
+
end #/<< self Safari
|
99
|
+
end #/class Safari
|
100
|
+
end #/module Osascript
|
@@ -0,0 +1,167 @@
|
|
1
|
+
=begin
|
2
|
+
Work with any application.
|
3
|
+
=end
|
4
|
+
module Osascript
|
5
|
+
|
6
|
+
# Return the front window (or other window defined in options)
|
7
|
+
# properties.
|
8
|
+
# @return Window properties or nil if application is not launched
|
9
|
+
# * :name [String] Window name
|
10
|
+
# * :bounds [Array] Window bounds
|
11
|
+
# * :index [Integer] Window index
|
12
|
+
# * :id [Integer] Window ID
|
13
|
+
# * :zoomable [Boolean] True if window is zoomable
|
14
|
+
# * :zoomed [Boolean] True if window is zoomed
|
15
|
+
# * :visible [Boolean] etc.
|
16
|
+
# * :miniaturizable [Boolean]
|
17
|
+
# * :miniaturized [Boolean]
|
18
|
+
# * closeable [Boolean]
|
19
|
+
# * :closed [Boolean]
|
20
|
+
# * :titled [Boolean]
|
21
|
+
# * :floating [Boolean]
|
22
|
+
# * :modal [Boolean]
|
23
|
+
# @param [String] app_name Name of the application
|
24
|
+
# @param [Hash] options
|
25
|
+
# @option options [String|Integer] :window Other window to consider
|
26
|
+
#
|
27
|
+
def self.get_window_properties(app_name, options = nil)
|
28
|
+
if on?(app_name)
|
29
|
+
window = (options && options[:window]) || 'front window'
|
30
|
+
code = "return (properties of #{window})"
|
31
|
+
ret = __asrun(code, app_name)
|
32
|
+
# On se retrouve avec un texte du type :
|
33
|
+
# "document:Mon doc, floating:false, bounds:4, 12, 23, 45 etc."
|
34
|
+
#
|
35
|
+
ret = ret.split(/(?:, )?([a-z]+)\:/)
|
36
|
+
ret.shift if ret[0].empty? || ret[0].nil?
|
37
|
+
# puts "ret = #{ret.inspect}"
|
38
|
+
table = {}
|
39
|
+
while ret.count > 0
|
40
|
+
prop = ret.shift.to_sym
|
41
|
+
value = ret.shift
|
42
|
+
# puts "prop = #{prop.inspect} / value: #{value}::#{value.class}"
|
43
|
+
value = case prop
|
44
|
+
when :bounds, :position
|
45
|
+
eval("[#{value}]")
|
46
|
+
else
|
47
|
+
begin
|
48
|
+
eval(value)
|
49
|
+
rescue NameError
|
50
|
+
value
|
51
|
+
rescue Exception => e
|
52
|
+
if value.match?(',')
|
53
|
+
value.split(',').map {|n|n.strip}
|
54
|
+
else
|
55
|
+
raise e
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
table.merge!(prop => value)
|
60
|
+
end
|
61
|
+
return table
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
# Set any properties of front window of +app_name+ app (or other
|
66
|
+
# window defined in options) to +properties+
|
67
|
+
# @param [String] app_name Name of the application
|
68
|
+
# @param [Hash] properties Properties of the window to set (depends
|
69
|
+
# on application)
|
70
|
+
# @option properties [Rectangle] :bounds Position and size of window
|
71
|
+
# @option properties [String] :name The window name
|
72
|
+
# @option properties [Integer] :index Index of window
|
73
|
+
# @option properties [Boolean] :zoomed true if window must be zoomed
|
74
|
+
# @option properties [Boolean] :miniaturized true if window must be miniaturized
|
75
|
+
# @option properties [Boolean] :visible false if window must be hidden
|
76
|
+
# @param [Hash] options Table with {:window}
|
77
|
+
def self.set_window(app_name, properties, options = nil)
|
78
|
+
if on?(app_name)
|
79
|
+
window = (options && options[:window]) || 'front window'
|
80
|
+
table = properties.map do |k, v|
|
81
|
+
"{\"#{k}\", #{v.inspect}}"
|
82
|
+
end.join(', ')
|
83
|
+
code = <<~CODE
|
84
|
+
set table to {#{table}}
|
85
|
+
tell #{window}
|
86
|
+
repeat with dprop in table
|
87
|
+
set propName to item 1 of dprop
|
88
|
+
set propValue to item 2 of dprop
|
89
|
+
if propName is "bounds" then
|
90
|
+
set bounds of it to propValue
|
91
|
+
else if propName is "name" then
|
92
|
+
set name of it to propValue
|
93
|
+
else if propName is "index" then
|
94
|
+
set index of it to propValue
|
95
|
+
else if propName is "zoomed" then
|
96
|
+
set zoomed of it to propValue
|
97
|
+
else if propName is "miniaturized" then
|
98
|
+
set miniaturized of it to provalue
|
99
|
+
else if propName is "visible" then
|
100
|
+
set visible of it to propValue
|
101
|
+
end if
|
102
|
+
end repeat
|
103
|
+
end tell
|
104
|
+
CODE
|
105
|
+
__asrun(code, app_name)
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
# Set bounds of front window of +app_name+ app (or other
|
110
|
+
# window defined in options) to +bounds+
|
111
|
+
# @param app_name [String] Name of the application
|
112
|
+
# @param bounds [Array] [top-left, bottom-left, top-right, bottom-right]
|
113
|
+
# @param options [Hash] Table with {:window}
|
114
|
+
def self.set_window_bounds(app_name, bounds, options = nil)
|
115
|
+
if on?(app_name)
|
116
|
+
window = (options && options[:window]) || 'front window'
|
117
|
+
code = <<~CODE
|
118
|
+
set bounds of #{window} to {#{bounds.join(', ')}}
|
119
|
+
CODE
|
120
|
+
__asrun(code, app_name)
|
121
|
+
end
|
122
|
+
end
|
123
|
+
|
124
|
+
# Set dimension of front window of app +app_name+ (or other window
|
125
|
+
# defined with options) to +dim+
|
126
|
+
# @param app_name [String] Name of the application
|
127
|
+
# @param dim [Hash] Table with {:width, :height}
|
128
|
+
# @param options [Hash] Table with {:window}
|
129
|
+
def self.set_window_dimension(app_name, dim, options = nil)
|
130
|
+
if on?(app_name)
|
131
|
+
window = (options && options[:window]) || 'front window'
|
132
|
+
code = <<~CODE
|
133
|
+
tell #{window}
|
134
|
+
set theBounds to bounds of it
|
135
|
+
set topRight to (item 1 of theBounds) + #{dim[:width]}
|
136
|
+
set bottomRight to (item 2 of theBounds) + #{dim[:height]}
|
137
|
+
set bounds of it to {item 1 of theBounds, item 2 of theBounds, topRight, bottomRight}
|
138
|
+
end
|
139
|
+
CODE
|
140
|
+
__asrun(code, app_name)
|
141
|
+
end
|
142
|
+
end
|
143
|
+
|
144
|
+
# Set position of front window of +app_name+ application (or other
|
145
|
+
# window defined with options) to +pos+
|
146
|
+
# @param app_name [String] Name of the application
|
147
|
+
# @param pos [Hash] Table with {:top, :left}
|
148
|
+
# @param options [Hash] Table with {:window}
|
149
|
+
def self.set_window_position(app_name, pos, options = nil)
|
150
|
+
if on?(app_name)
|
151
|
+
window = (options && options[:window]) || 'front window'
|
152
|
+
code = <<~CODE
|
153
|
+
tell #{window}
|
154
|
+
set theBounds to bounds of it
|
155
|
+
set width to (item 3 of theBounds) - (item 1 of theBounds)
|
156
|
+
set topRight to #{pos[:left]} + width
|
157
|
+
set height to (item 4 of theBounds) - (item 2 of theBounds)
|
158
|
+
set bottomRight to #{pos[:top]} + height
|
159
|
+
set bounds of it to {#{pos[:left]}, #{pos[:top]}, topRight, bottomRight}
|
160
|
+
end
|
161
|
+
CODE
|
162
|
+
__asrun(code, app_name)
|
163
|
+
end
|
164
|
+
end
|
165
|
+
|
166
|
+
|
167
|
+
end
|
data/lib/osascript.rb
ADDED
@@ -0,0 +1,12 @@
|
|
1
|
+
require "osascript/version"
|
2
|
+
require 'osascript/constants'
|
3
|
+
require 'osascript/Osascript'
|
4
|
+
require 'osascript/Preview'
|
5
|
+
require 'osascript/Safari'
|
6
|
+
require 'osascript/any_app'
|
7
|
+
require 'osascript/Key'
|
8
|
+
|
9
|
+
module Osascript
|
10
|
+
class Error < StandardError; end
|
11
|
+
# Your code goes here...
|
12
|
+
end
|
data/osascript.gemspec
ADDED
@@ -0,0 +1,35 @@
|
|
1
|
+
require_relative 'lib/osascript/version'
|
2
|
+
|
3
|
+
Gem::Specification.new do |s|
|
4
|
+
s.name = "osascript"
|
5
|
+
s.version = Osascript::VERSION
|
6
|
+
s.authors = ["PhilippePerret"]
|
7
|
+
s.email = ["philippe.perret@yahoo.fr"]
|
8
|
+
s.licenses = ['Nonstandard']
|
9
|
+
|
10
|
+
s.summary = %q{Interaction per AppleScript with world}
|
11
|
+
s.description = %q{Gem macOS-only permettant de communiquer avec les autres applications par AppleScript}
|
12
|
+
s.homepage = "https://github.com/PhilippePerret/osascript"
|
13
|
+
s.required_ruby_version = Gem::Requirement.new(">= 2.3.0")
|
14
|
+
|
15
|
+
# s.metadata["allowed_push_host"] = "https://github.com/PhilippePerret/osascript"
|
16
|
+
s.metadata["allowed_push_host"] = "https://rubygems.org"
|
17
|
+
|
18
|
+
s.add_development_dependency 'minitest', '~> 5.10'
|
19
|
+
s.add_development_dependency 'minitest-reporters', '>= 2'
|
20
|
+
|
21
|
+
s.metadata["homepage_uri"] = s.homepage
|
22
|
+
# J’ai essayé d’ajouter ça pour pouvoir déposer le gem
|
23
|
+
s.metadata["github_repo"] = 'git@github.com:PhilippePerret/osascript.git'
|
24
|
+
s.metadata["source_code_uri"] = "https://github.com/PhilippePerret/osascript"
|
25
|
+
s.metadata["changelog_uri"] = "https://github.com/PhilippePerret/osascript/CHANGE.log"
|
26
|
+
|
27
|
+
# Specify which files should be added to the gem when it is released.
|
28
|
+
# The `git ls-files -z` loads the files in the RubyGem that have been added into git.
|
29
|
+
s.files = Dir.chdir(File.expand_path('..', __FILE__)) do
|
30
|
+
`git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|features)/}) }
|
31
|
+
end
|
32
|
+
s.bindir = "exe"
|
33
|
+
s.executables = s.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
34
|
+
s.require_paths = ["lib"]
|
35
|
+
end
|
metadata
ADDED
@@ -0,0 +1,97 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: osascript
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.4.5
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- PhilippePerret
|
8
|
+
autorequire:
|
9
|
+
bindir: exe
|
10
|
+
cert_chain: []
|
11
|
+
date: 2024-07-15 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: minitest
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '5.10'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '5.10'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: minitest-reporters
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '2'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '2'
|
41
|
+
description: Gem macOS-only permettant de communiquer avec les autres applications
|
42
|
+
par AppleScript
|
43
|
+
email:
|
44
|
+
- philippe.perret@yahoo.fr
|
45
|
+
executables: []
|
46
|
+
extensions: []
|
47
|
+
extra_rdoc_files: []
|
48
|
+
files:
|
49
|
+
- ".github/workflows/gem-push.yml"
|
50
|
+
- ".gitignore"
|
51
|
+
- ".travis.yml"
|
52
|
+
- CHANGELOG
|
53
|
+
- Gemfile
|
54
|
+
- Gemfile.lock
|
55
|
+
- README.md
|
56
|
+
- Rakefile
|
57
|
+
- bin/console
|
58
|
+
- bin/setup
|
59
|
+
- gitignore
|
60
|
+
- lib/osascript.rb
|
61
|
+
- lib/osascript/Key.rb
|
62
|
+
- lib/osascript/Osascript.rb
|
63
|
+
- lib/osascript/Preview.rb
|
64
|
+
- lib/osascript/Safari.rb
|
65
|
+
- lib/osascript/any_app.rb
|
66
|
+
- lib/osascript/constants.rb
|
67
|
+
- lib/osascript/version.rb
|
68
|
+
- osascript.gemspec
|
69
|
+
homepage: https://github.com/PhilippePerret/osascript
|
70
|
+
licenses:
|
71
|
+
- Nonstandard
|
72
|
+
metadata:
|
73
|
+
allowed_push_host: https://rubygems.org
|
74
|
+
homepage_uri: https://github.com/PhilippePerret/osascript
|
75
|
+
github_repo: git@github.com:PhilippePerret/osascript.git
|
76
|
+
source_code_uri: https://github.com/PhilippePerret/osascript
|
77
|
+
changelog_uri: https://github.com/PhilippePerret/osascript/CHANGE.log
|
78
|
+
post_install_message:
|
79
|
+
rdoc_options: []
|
80
|
+
require_paths:
|
81
|
+
- lib
|
82
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
83
|
+
requirements:
|
84
|
+
- - ">="
|
85
|
+
- !ruby/object:Gem::Version
|
86
|
+
version: 2.3.0
|
87
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
88
|
+
requirements:
|
89
|
+
- - ">="
|
90
|
+
- !ruby/object:Gem::Version
|
91
|
+
version: '0'
|
92
|
+
requirements: []
|
93
|
+
rubygems_version: 3.1.6
|
94
|
+
signing_key:
|
95
|
+
specification_version: 4
|
96
|
+
summary: Interaction per AppleScript with world
|
97
|
+
test_files: []
|