rubyosa 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
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 ""