rubyosa 0.1.0

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/AUTHORS ADDED
@@ -0,0 +1,9 @@
1
+ Maintainer:
2
+ Laurent Sansonetti <lsansonett@apple.com>
3
+
4
+ Contributors:
5
+ Aaron Patterson <aaron.patterson@gmail.com>
6
+ James MacAulay <jmacaulay@gmail.com>
7
+ Michael Pruett <michael@68k.org>
8
+ Sebastian Delmont <sd@notso.net>
9
+ Vincent Isambart <vincent.isambart@gmail.com>
data/COPYRIGHT ADDED
@@ -0,0 +1,25 @@
1
+ Copyright (c) 2006, Apple Computer, Inc. All rights reserved.
2
+
3
+ Redistribution and use in source and binary forms, with or without
4
+ modification, are permitted provided that the following conditions
5
+ are met:
6
+ 1. Redistributions of source code must retain the above copyright
7
+ notice, this list of conditions and the following disclaimer.
8
+ 2. Redistributions in binary form must reproduce the above copyright
9
+ notice, this list of conditions and the following disclaimer in the
10
+ documentation and/or other materials provided with the distribution.
11
+ 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
12
+ its contributors may be used to endorse or promote products derived
13
+ from this software without specific prior written permission.
14
+
15
+ THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND
16
+ ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18
+ ARE DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR
19
+ ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21
+ OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22
+ HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
23
+ STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
24
+ IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
25
+ POSSIBILITY OF SUCH DAMAGE.
data/README ADDED
@@ -0,0 +1,39 @@
1
+ == Introduction ==
2
+
3
+ RubyOSA is a bridge that connects Ruby to the Apple Event Manager
4
+ infrastructure.
5
+
6
+ It automatically populates the API (classes, methods, constants) according
7
+ to the target application's scriptable definition.
8
+
9
+ RubyOSA is an alternative to RubyAEOSA, and meant to replace it.
10
+
11
+ RubyOSA is licensied under a BSD license, see the COPYRIGHT file for more
12
+ information.
13
+
14
+ More information on the project home page: http://rubyosa.rubyforge.org.
15
+
16
+ == Requirements ==
17
+
18
+ Mac OS X 10.4.X or greater
19
+ ruby 1.8.X or greater
20
+ libxml-ruby 0.3.8 or greater
21
+
22
+ == Get started ==
23
+
24
+ $ ruby extconf.rb
25
+ $ make
26
+ $ sudo make install
27
+
28
+ == Support ==
29
+
30
+ Sample code is available in the `sample' sub-directory.
31
+
32
+ The rdoc-osa tool can be used to generate API reference documentation
33
+ for the given application. See its --help flag for more information
34
+ about how to use it.
35
+
36
+ Feel free to send feedback to lsansonetti@apple.com.
37
+
38
+ When reporting a bug, please set the AEDebugSends and AEDebugReceives
39
+ environment variables to 1 and attach the logs.
data/bin/rdoc-osa ADDED
@@ -0,0 +1,144 @@
1
+ #!/usr/bin/env ruby
2
+ # RDoc frontend for RubyOSA. Generate API referene documentation for the
3
+ # given application, based on the descriptions in the sdef(5).
4
+ #
5
+ # Copyright (c) 2006, Apple Computer, Inc. All rights reserved.
6
+ #
7
+ # Redistribution and use in source and binary forms, with or without
8
+ # modification, are permitted provided that the following conditions
9
+ # are met:
10
+ # 1. Redistributions of source code must retain the above copyright
11
+ # notice, this list of conditions and the following disclaimer.
12
+ # 2. Redistributions in binary form must reproduce the above copyright
13
+ # notice, this list of conditions and the following disclaimer in the
14
+ # documentation and/or other materials provided with the distribution.
15
+ # 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
16
+ # its contributors may be used to endorse or promote products derived
17
+ # from this software without specific prior written permission.
18
+ #
19
+ # THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND
20
+ # ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21
+ # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22
+ # ARE DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR
23
+ # ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24
+ # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25
+ # OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26
+ # HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
27
+ # STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
28
+ # IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29
+ # POSSIBILITY OF SUCH DAMAGE.
30
+
31
+ require 'rbosa'
32
+ require 'tmpdir'
33
+
34
+ def usage
35
+ STDERR.puts <<-EOS
36
+ Usage: #{$0} [--name | --path | --bundle_id | --signature] <criterion> [rdoc-options...]
37
+ Examples:
38
+ # Generate HTML documentation for iTunes:
39
+ #{$0} --name iTunes
40
+ # Generate RI documentation for iTunes:
41
+ #{$0} --name iTunes --ri
42
+ See rdoc --help for additional options.
43
+ EOS
44
+ exit 1
45
+ end
46
+
47
+ def unique_tmp_path(base, extension='', dir=Dir.tmpdir)
48
+ i = 0
49
+ loop do
50
+ p = File.join(dir, "#{base}-#{i}-#{Process.pid}" + extension)
51
+ return p unless File.exists?(p)
52
+ i += 1
53
+ end
54
+ end
55
+
56
+ usage unless ARGV.length >= 2
57
+
58
+ msg = case ARGV.first
59
+ when '--name'
60
+ :app_with_name
61
+ when '--path'
62
+ :app_with_path
63
+ when '--bundle_id'
64
+ :app_with_bundle_id
65
+ when '--signature'
66
+ :app_with_signature
67
+ else
68
+ usage
69
+ end
70
+
71
+ app = OSA.send(msg, ARGV[1])
72
+ mod = OSA.const_get(app.class.name.scan(/^OSA::(.+)::Application$/).to_s)
73
+ fake_ruby_src = mod.constants.map do |const_name|
74
+ obj = mod.const_get(const_name)
75
+ case obj
76
+ when Class
77
+ # Class.
78
+ methods_desc = obj.const_get('METHODS_DESCRIPTION').map do |method|
79
+ args_doc, args_def = '', ''
80
+ if method.args and !method.args.empty?
81
+ args_doc = method.args.map do |x|
82
+ arg = x.name.dup
83
+ optional = arg.sub!(/=.+$/, '') != nil
84
+ " # #{arg}::\n # #{x.description}" + (optional ? ' Optional.' : '')
85
+ end.join("\n")
86
+ args_def = '(' + method.args.map { |x| x.name }.join(', ') + ')'
87
+ end
88
+ if method.result
89
+ args_doc << "\n" unless args_doc.empty?
90
+ args_doc << " # Returns::\n # #{method.result.description}\n"
91
+ end
92
+ <<EOS
93
+ # #{method.description}
94
+ #{args_doc}
95
+ def #{method.name}#{args_def}; end
96
+ EOS
97
+ end
98
+ <<EOS
99
+ # #{(obj.const_get('DESCRIPTION') || 'n/a')}
100
+ class #{obj.name} < #{obj.superclass}
101
+ #{methods_desc.join.rstrip}
102
+ end
103
+
104
+ EOS
105
+ when Module
106
+ # Enumeration group.
107
+ next unless obj.const_defined?(:DESCRIPTION)
108
+ enums_desc = obj.const_get(:DESCRIPTION).map do |item|
109
+ <<EOS
110
+ # #{item.description}
111
+ #{item.name} = '#{obj.const_get(item.name).code}'
112
+ EOS
113
+ end
114
+ <<EOS
115
+ module #{mod.name}::#{const_name}
116
+ #{enums_desc}
117
+ end
118
+
119
+ EOS
120
+ end
121
+ end.
122
+ join
123
+
124
+ fake_ruby_src = <<EOS + fake_ruby_src
125
+ # This documentation describes the RubyOSA API for the #{app.name} application. It has been automatically generated.
126
+ #
127
+ # The main class is #{mod.name}::Application, of which an instance is created likewise:
128
+ #
129
+ # OSA.app('#{app.name}')
130
+ #
131
+ # For more information about RubyOSA, please visit the project homepage: http://rubyosa.rubyforge.org.
132
+ module OSA; end
133
+ # The #{app.name} module.
134
+ module #{mod.name}; end
135
+ EOS
136
+
137
+ path = unique_tmp_path(app.name, '.rb')
138
+ File.open(path, 'w') { |io| io.puts fake_ruby_src }
139
+ line = "rdoc #{ARGV[2..-1].join(' ')} \"#{path}\""
140
+ unless system(line)
141
+ STDERR.puts "Error when executing `#{line}' : #{$?}"
142
+ exit 1
143
+ end
144
+ File.unlink(path)
data/extconf.rb ADDED
@@ -0,0 +1,53 @@
1
+ # Copyright (c) 2006, Apple Computer, Inc. All rights reserved.
2
+ #
3
+ # Redistribution and use in source and binary forms, with or without
4
+ # modification, are permitted provided that the following conditions
5
+ # are met:
6
+ # 1. Redistributions of source code must retain the above copyright
7
+ # notice, this list of conditions and the following disclaimer.
8
+ # 2. Redistributions in binary form must reproduce the above copyright
9
+ # notice, this list of conditions and the following disclaimer in the
10
+ # documentation and/or other materials provided with the distribution.
11
+ # 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
12
+ # its contributors may be used to endorse or promote products derived
13
+ # from this software without specific prior written permission.
14
+ #
15
+ # THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND
16
+ # ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17
+ # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18
+ # ARE DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR
19
+ # ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20
+ # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21
+ # OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22
+ # HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
23
+ # STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
24
+ # IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
25
+ # POSSIBILITY OF SUCH DAMAGE.
26
+
27
+ require 'mkmf'
28
+
29
+ $CFLAGS << ' -Wall '
30
+ $LDFLAGS = '-framework Carbon -framework ApplicationServices'
31
+
32
+ exit 1 unless have_func('OSACopyScriptingDefinition')
33
+ exit 1 unless have_func('LSFindApplicationForInfo')
34
+
35
+ # Avoid `ID' and `T_DATA' symbol collisions between Ruby and Carbon.
36
+ # (adapted code from RubyAEOSA - FUJIMOTO Hisakuni <hisa@fobj.com>)
37
+ ruby_h = "#{Config::CONFIG['archdir']}/ruby.h"
38
+ intern_h = "#{Config::CONFIG['archdir']}/intern.h"
39
+ new_filename_prefix = 'osx_'
40
+ [ ruby_h, intern_h ].each do |src_path|
41
+ dst_fname = File.join('./src', new_filename_prefix + File.basename(src_path))
42
+ $stderr.puts "create #{File.expand_path(dst_fname)} ..."
43
+ File.open(dst_fname, 'w') do |dstfile|
44
+ IO.foreach(src_path) do |line|
45
+ line = line.gsub(/\bID\b/, 'RB_ID')
46
+ line = line.gsub(/\bT_DATA\b/, 'RB_T_DATA')
47
+ line = line.gsub(/\bintern.h\b/, "#{new_filename_prefix}intern.h")
48
+ dstfile.puts line
49
+ end
50
+ end
51
+ end
52
+
53
+ create_makefile('osa', 'src')
@@ -0,0 +1,7 @@
1
+ require 'rbosa'
2
+
3
+ ary = OSA.app('Finder').desktop.entire_contents.get
4
+ ary.each do |x|
5
+ next unless x.is_a?(OSA::Finder::Item)
6
+ puts "#{x.class.name.sub(/^.+::/, '').sub(/_/, ' ').ljust(25)} #{x.name}"
7
+ end
@@ -0,0 +1,29 @@
1
+ # Opens given movies and in QuickTime and starts playing them indefinitely in fullscreen mode.
2
+
3
+ require 'rbosa'
4
+
5
+ if ARGV.empty?
6
+ STDERR.puts "Usage: #{$0} <movies-files>"
7
+ exit 1
8
+ end
9
+
10
+ app = OSA.app('QuickTime Player')
11
+ ARGV.each { |p| app.open(p) }
12
+ l = app.movies.to_a
13
+ exit if l.length == 0
14
+ last = nil
15
+ loop do
16
+ l2 = []
17
+ l.length.times { l2 << l.slice!(rand(l.length)) }
18
+ l2[0], l2[1] = l2[1], l2[0] if l2[0] == last and l2.length > 1 # not to have the same file playing twice consecutively
19
+ l2.each do |m|
20
+ m.rewind # to be sure that we start at the beginning of the movie
21
+ m.present
22
+ sleep 0.1 while m.playing?
23
+ m.stop # to be sure we are not in presentation mode anymore
24
+ # if we do not end with a stop, and the movie has been stopped by the user,
25
+ # the next present will not play the movie because an other movie is still in presentation mode
26
+ last = m
27
+ end
28
+ l = l2
29
+ end
@@ -0,0 +1,11 @@
1
+ # Periodically set your iChat status to the output of uptime(1).
2
+
3
+ require 'rbosa'
4
+
5
+ app = OSA.app('iChat')
6
+ previous_status_message = app.status_message
7
+ trap('INT') { app.status_message = previous_status_message; exit 0 }
8
+ while true
9
+ app.status_message = `uptime`.strip
10
+ sleep 5
11
+ end
@@ -0,0 +1,64 @@
1
+ # Simple iTunes controller.
2
+
3
+ require 'rbosa'
4
+ require 'curses'
5
+ include Curses
6
+
7
+ app = OSA.app('iTunes')
8
+
9
+ if app.current_track.nil?
10
+ # We don't support write access now, so...
11
+ puts "Please select a track in iTunes and retry again."
12
+ exit 1
13
+ end
14
+
15
+ init_screen
16
+
17
+ addstr <<EOS
18
+ Keys available:
19
+ SPACE toggle play/pause
20
+ p go to previous song
21
+ n go to next song
22
+ f toggle fast forward
23
+ r toggle rewind
24
+ m toggle mute
25
+ q exit the program
26
+
27
+ On track:
28
+ EOS
29
+
30
+ begin
31
+ noecho
32
+ while true
33
+ setpos(9, 2)
34
+ addstr "#{app.player_state.to_s.capitalize} : #{app.current_track.name}".ljust(cols - 3)
35
+ refresh
36
+ x = getch
37
+ case x.chr
38
+ when ' '
39
+ app.playpause
40
+ when 'p'
41
+ app.previous_track
42
+ when 'n'
43
+ app.next_track
44
+ when 'f'
45
+ if app.player_state == OSA::ITunes::EPLS::FAST_FORWARDING
46
+ app.resume
47
+ else
48
+ app.fast_forward
49
+ end
50
+ when 'r'
51
+ if app.player_state == OSA::ITunes::EPLS::REWINDING
52
+ app.resume
53
+ else
54
+ app.rewind
55
+ end
56
+ when 'm'
57
+ app.mute = !app.mute?
58
+ when 'q'
59
+ break
60
+ end
61
+ end
62
+ ensure
63
+ echo
64
+ end
@@ -0,0 +1,22 @@
1
+ # Start playing, then fade the volume from 0 to the original setting.
2
+
3
+ require 'rbosa'
4
+
5
+ app = OSA.app('iTunes')
6
+
7
+ original_volume = app.sound_volume
8
+
9
+ if original_volume == 0 or app.current_track.nil?
10
+ puts "Please select a track and/or set a higher volume."
11
+ exit 1
12
+ end
13
+
14
+ app.sound_volume = 0
15
+ app.play
16
+
17
+ 0.step(original_volume, original_volume / 8.0) do |volume|
18
+ app.sound_volume = volume
19
+ sleep(0.1)
20
+ end
21
+
22
+ app.sound_volume = original_volume
@@ -0,0 +1,14 @@
1
+ # Quick inspection of iTunes' sources, playlists and tracks.
2
+
3
+ require 'rbosa'
4
+
5
+ app = OSA.app('iTunes')
6
+ app.sources.each do |source|
7
+ puts source.name
8
+ source.playlists.each do |playlist|
9
+ puts " -> #{playlist.name}"
10
+ playlist.tracks.each do |track|
11
+ puts " -> #{track.name}" if track.enabled?
12
+ end
13
+ end
14
+ end
data/sample/sdef.rb ADDED
@@ -0,0 +1,36 @@
1
+ # Print the given application's sdef(5).
2
+
3
+ require 'rbosa'
4
+ require 'rexml/document'
5
+
6
+ def usage
7
+ STDERR.puts <<-EOS
8
+ Usage: #{$0} [--name | --path | --bundle_id | --signature] ...
9
+ Examples:
10
+ #{$0} --name iTunes
11
+ #{$0} --path /Applications/iTunes.app
12
+ #{$0} --bundle_id com.apple.iTunes
13
+ #{$0} --signature hook
14
+ EOS
15
+ exit 1
16
+ end
17
+
18
+ usage unless ARGV.length == 2
19
+
20
+ msg = case ARGV.first
21
+ when '--name'
22
+ :app_with_name
23
+ when '--path'
24
+ :app_with_path
25
+ when '--bundle_id'
26
+ :app_with_bundle_id
27
+ when '--signature'
28
+ :app_with_signature
29
+ else
30
+ usage
31
+ end
32
+
33
+ app = OSA.send(msg, ARGV.last)
34
+ doc = REXML::Document.new(app.sdef)
35
+ doc.write(STDOUT, 0)
36
+ puts ""