Big News: Socket raises $60M Series C at a $1B valuation to secure software supply chains for AI-driven development.Announcement
Sign In

rubyosa

Package Overview
Dependencies
Maintainers
1
Versions
5
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

rubyosa - rubygems Package Compare versions

Comparing version
0.1.0
to
0.2.0
+19
sample/BBEdit_unix_script.rb
# Ask BBEdit to run the uptime(1) command and get the result.
begin require 'rubygems'; rescue LoadError; end
require 'rbosa'
puts 'Asking for uptime...'
bbedit = OSA.app('BBEdit')
bbedit.make(OSA::BBEdit::TextDocument).text = <<EOS
#!/bin/sh
uptime
EOS
bbedit.run_unix_script
output_doc = bbedit.text_documents.find { |x| x.name == 'Unix Script Output' }
puts output_doc.text.get
# Periodically set your iChat image to one of the default images.
begin require 'rubygems'; rescue LoadError; end
require 'rbosa'
ichat = OSA.app('iChat')
old_image = ichat.image
trap('INT') { ichat.image = old_image; exit 0 }
paths = Dir.glob("/Library/User Pictures/**/*.tif")
while true do
paths.each do |path|
ichat.image = File.read(path)
sleep 2
end
end
# Open the artwork of the current iTunes track in Preview.
begin require 'rubygems'; rescue LoadError; end
require 'rbosa'
artworks = OSA.app('iTunes').current_track.artworks
if artworks.size == 0
puts "No artwork for current track."
exit 1
end
fname = '/tmp/foo.' + artworks[0].format.downcase.strip
File.open(fname, 'w') { |io| io.write(artworks[0].data) }
system("open -a Preview #{fname}")
# Create new TextEdit documents with a 'Hello World' text.
begin require 'rubygems'; rescue LoadError; end
require 'rbosa'
textedit = OSA.app('TextEdit')
# Complex way.
textedit.make(OSA::TextEdit::Document, nil, nil, {:ctxt => 'Hello World #1'})
# Easier way.
textedit.make(OSA::TextEdit::Document).text = 'Hello World #2'
=begin
# Easiest way, not implemented for now.
document = OSA::TextEdit::Document.new
document.text = 'Hello World #3'
textedit << document
=end
+2
-2

@@ -1,3 +0,3 @@

Maintainer:
Laurent Sansonetti <lsansonett@apple.com>
Maintainer & Author:
Laurent Sansonetti <lsansonetti@apple.com>

@@ -4,0 +4,0 @@ Contributors:

+4
-1

@@ -36,5 +36,8 @@ == Introduction ==

Feel free to send feedback to lsansonetti@apple.com.
Feel free to send feedback to rubyosa-discuss@rubyforge.org.
You can also file bugs, patches and feature requests to the tracker:
http://rubyforge.org/tracker/?group_id=1845.
When reporting a bug, please set the AEDebugSends and AEDebugReceives
environment variables to 1 and attach the logs.

@@ -0,1 +1,4 @@

# Lists the content of the Finder desktop.
begin require 'rubygems'; rescue LoadError; end
require 'rbosa'

@@ -2,0 +5,0 @@

# Periodically set your iChat status to the output of uptime(1).
begin require 'rubygems'; rescue LoadError; end
require 'rbosa'

@@ -8,5 +9,8 @@

trap('INT') { app.status_message = previous_status_message; exit 0 }
while true
app.status_message = `uptime`.strip
while true
u = `uptime`
hours = u.scan(/^\s*(\d+:\d+)\s/).to_s + ' hours'
days = u.scan(/\d+\sdays/).to_s
app.status_message = "OSX up #{days} #{hours}"
sleep 5
end
# Simple iTunes controller.
begin require 'rubygems'; rescue LoadError; end
require 'rbosa'

@@ -8,2 +9,3 @@ require 'curses'

app = OSA.app('iTunes')
OSA.utf8_strings = true

@@ -10,0 +12,0 @@ if app.current_track.nil?

# Start playing, then fade the volume from 0 to the original setting.
begin require 'rubygems'; rescue LoadError; end
require 'rbosa'

@@ -4,0 +5,0 @@

# Quick inspection of iTunes' sources, playlists and tracks.
begin require 'rubygems'; rescue LoadError; end
require 'rbosa'
app = OSA.app('iTunes')
OSA.utf8_strings = true
app.sources.each do |source|

@@ -7,0 +9,0 @@ puts source.name

# Opens given movies and in QuickTime and starts playing them indefinitely in fullscreen mode.
begin require 'rubygems'; rescue LoadError; end
require 'rbosa'

@@ -4,0 +5,0 @@

# Print the given application's sdef(5).
begin require 'rubygems'; rescue LoadError; end
require 'rbosa'

@@ -4,0 +5,0 @@ require 'rexml/document'

@@ -27,7 +27,11 @@ # Copyright (c) 2006, Apple Computer, Inc. All rights reserved.

$KCODE = 'u' # we will use UTF-8 strings
require 'osa'
require 'date'
require 'uri'
require 'iconv'
# Try to load RubyGems first, libxml-ruby may have been installed by it.
begin require 'rubygems' rescue LoadError end
begin require 'rubygems'; rescue LoadError; end

@@ -73,3 +77,3 @@ # If libxml-ruby is not present, switch to REXML.

def to_4cc
OSA.__four_char_code__(self)
OSA.__four_char_code__(Iconv.iconv('MACROMAN', 'UTF-8', self).to_s)
end

@@ -117,3 +121,4 @@ end

def self.from_rbobj(requested_type, value, enum_group_codes)
self.__new__(*OSA.convert_to_osa(requested_type, value, enum_group_codes))
obj = OSA.convert_to_osa(requested_type, value, enum_group_codes)
obj.is_a?(OSA::Element) ? obj : self.__new__(*obj)
end

@@ -158,2 +163,6 @@ end

def empty?
length == 0
end
def [](idx)

@@ -243,3 +252,3 @@ idx += 1 # AE starts counting at 1.

def self.convert_to_ruby(osa_object)
osa_type = osa_object.__type__.to_s
osa_type = osa_object.__type__
osa_data = osa_object.__data__(osa_type) if osa_type and osa_type != 'null'

@@ -253,2 +262,20 @@ if conversion = @conversions_to_ruby[osa_type]

def self.convert_to_osa(requested_type, value, enum_group_codes=nil)
if requested_type.nil?
case value
when OSA::Element
return value
when String
requested_type = 'text'
when Array
requested_type = 'list'
when Hash
requested_type = 'record'
when Integer
requested_type = 'integer'
else
STDERR.puts "can't determine OSA type for #{value}" if $VERBOSE
['null', nil]
end
end
if conversion = @conversions_to_osa[requested_type]

@@ -259,3 +286,6 @@ args = [value, requested_type]

['enum', value.code.to_4cc]
else
elsif md = /^list_of_(.+)$/.match(requested_type)
ary = value.to_a.map { |x| convert_to_osa(md[1], x, enum_group_codes) }
ElementList.__new__(ary)
else
STDERR.puts "unrecognized type #{requested_type}" if $VERBOSE

@@ -373,8 +403,14 @@ ['null', nil]

# Creates properties.
element.find('property').each do |pelement|
name = pelement['name']
code = pelement['code']
type = pelement['type']
access = pelement['access']
description = pelement['description']
# Add basic properties that might be missing to the Item class (if any).
props = {}
element.find('property').each do |x|
props[x['name']] = [x['code'], x['type'], x['access'], x['description']]
end
if klass.name[-6..-1] == '::Item'
unless props.has_key?('id')
props['id'] = ['ID ', 'integer', 'r', 'the unique ID of the item']
end
end
props.each do |name, pary|
code, type, access, description = pary
setter = (access == nil or access.include?('w'))

@@ -420,3 +456,3 @@

end
klass.class_eval(method_code)

@@ -477,3 +513,3 @@ ptypedoc = if pklass.nil?

[['----', Element.__new_object_specifier__(
'#{eklass::CODE}', @app == self ? Element.__new__('null', nil) : self,
'#{eklass::CODE}'.to_4cc, @app == self ? Element.__new__('null', nil) : self,
'indx', Element.__new__('abso', 'all '.to_4cc))]],

@@ -582,2 +618,4 @@ true).to_rbobj

code = Iconv.iconv('MACROMAN', 'UTF-8', code).to_s
method_code = <<EOC

@@ -677,6 +715,3 @@ def %METHOD_NAME%(#{p_dec.join(', ')})

def self.new_element_code(type, varname, enum_group_codes)
if md = /^list_of_(.+)$/.match(type)
return "#{varname}.is_a?(OSA::Element) ? #{varname} : ElementList.__new__(#{varname}.to_a.map { |x| #{new_element_code(md[1], 'x', enum_group_codes)} })"
end
"#{varname}.is_a?(OSA::Element) ? #{varname} : Element.from_rbobj('#{type}', #{varname}, #{enum_group_codes.inspect})"
"#{varname}.is_a?(OSA::Element) ? #{varname} : Element.from_rbobj('#{type}', #{varname}, #{enum_group_codes.keys.inspect})"
end

@@ -689,7 +724,8 @@

def self.rubyfy_constant_string(string, upcase=false)
if /^\d/.match(string)
string = 'C' << string
else
string = string.dup
string[0] = string[0].chr.upcase
string = string.gsub(/[^\w\s]/, '')
first = string[0]
if (?a..?z).include?(first)
string[0] = first.chr.upcase
elsif !(?A..?Z).include?(first)
string.insert(0, 'C')
end

@@ -699,6 +735,6 @@ escape_string(upcase ? string.upcase : string.gsub(/\s(.)/) { |s| s[1].chr.upcase })

RUBY_RESERVED_KEYWORDS = ['for', 'in']
RUBY_RESERVED_KEYWORDS = ['for', 'in', 'class']
def self.rubyfy_string(string, handle_ruby_reserved_keywords=false)
# Prefix with '_' parameter names to avoid possible collisions with reserved Ruby keywords (for, etc...).
if RUBY_RESERVED_KEYWORDS.include?(string)
if handle_ruby_reserved_keywords and RUBY_RESERVED_KEYWORDS.include?(string)
'_' + string

@@ -711,14 +747,17 @@ else

def self.rubyfy_method(string, klass, return_type=nil, setter=false)
s = rubyfy_string(string)
if setter
# Suffix setters with '='.
s << '='
elsif return_type == 'boolean'
# Suffix predicates with '?'.
s << '?'
base = rubyfy_string(string)
s, i = base.dup, 1
loop do
if setter
# Suffix setters with '='.
s << '='
elsif return_type == 'boolean'
# Suffix predicates with '?'.
s << '?'
end
break unless klass.method_defined?(s)
# Suffix with an integer if the class already has a method with such a name.
i += 1
s = base + i.to_s
end
# Prefix with 'osa_' in case the class already has a method with such a name.
if klass.method_defined?(s)
s = 'osa_' + s
end
return s

@@ -736,11 +775,17 @@ end

# String, force TEXT type to not get Unicode.
OSA.add_conversion_to_ruby('TEXT', 'utxt') { |value, type, object| object.__data__('TEXT') }
OSA.add_conversion_to_osa('string', 'text', 'Unicode text') { |value| ['TEXT', value.to_s] }
# String, for unicode stuff force utf8 type if specified.
OSA.add_conversion_to_ruby('TEXT') { |value, type, object| object.__data__('TEXT') }
OSA.add_conversion_to_ruby('utxt', 'utf8') { |value, type, object| object.__data__(OSA.utf8_strings ? 'utf8' : 'TEXT') }
OSA.add_conversion_to_osa('string', 'text') { |value| ['TEXT', value.to_s] }
OSA.add_conversion_to_osa('Unicode text') { |value| [OSA.utf8_strings ? 'utf8' : 'TEXT', value.to_s] }
# Signed/unsigned integer.
OSA.add_conversion_to_ruby('shor', 'long', 'comp') { |value| value.unpack('l').first }
OSA.add_conversion_to_ruby('shor', 'long') { |value| value.unpack('l').first }
OSA.add_conversion_to_ruby('comp') { |value| value.unpack('q').first }
OSA.add_conversion_to_ruby('magn') { |value| value.unpack('d').first }
OSA.add_conversion_to_osa('integer', 'double integer') { |value| ['magn', [value].pack('l')] }
# Float
OSA.add_conversion_to_ruby('sing') { |value| value.unpack('f').first }
# Boolean.

@@ -765,11 +810,29 @@ OSA.add_conversion_to_ruby('bool') { |value| value.unpack('c').first != 0 }

OSA.add_conversion_to_osa('alias', 'file') { |value| ['furl', value.to_s] }
OSA.add_conversion_to_ruby('alis') { |value, type, object| URI.parse(object.__data__('furl')).path }
# Hash.
OSA.add_conversion_to_ruby('reco') { |value, type, object| object.is_a?(OSA::ElementRecord) ? object.to_hash : self }
OSA.add_conversion_to_ruby('reco') { |value, type, object| object.is_a?(OSA::ElementRecord) ? object.to_hash : value }
OSA.add_conversion_to_osa('record') do |value|
if value.is_a?(Hash)
value.each { |key, val| value[key] = OSA::Element.from_rbobj(nil, val, nil) }
OSA::ElementRecord.__new__(value)
else
value
end
end
# Enumerator.
OSA.add_conversion_to_ruby('enum') { |value, type, object| OSA::Enumerator.enum_for_code(object.__data__('TEXT')) or self }
OSA.add_conversion_to_ruby('enum') { |value, type, object| OSA::Enumerator.enum_for_code(object.__data__('TEXT')) or object }
# Class.
OSA.add_conversion_to_osa('type class') { |value| value.is_a?(Class) and value.ancestors.include?(OSA::Element) ? ['type', value::CODE.to_4cc] : self }
OSA.add_conversion_to_osa('type class') { |value| value.is_a?(Class) and value.ancestors.include?(OSA::Element) ? ['type', value::CODE.to_4cc] : value }
OSA.add_conversion_to_ruby('type') do |value, type, object|
if value == 'msng'
# Missing values.
nil
else
hash = object.instance_variable_get(:@app).instance_variable_get(:@classes)
hash[value] or value
end
end

@@ -779,1 +842,8 @@ # QuickDraw Rectangle, aka "bounding rectangle".

OSA.add_conversion_to_osa('bounding rectangle') { |value| ['qdrt', value.pack('S4')] }
# Pictures (just return the raw data).
OSA.add_conversion_to_ruby('PICT') { |value, type, object| value[222..-1] } # Removing trailing garbage.
OSA.add_conversion_to_osa('picture') { |value| ['PICT', value.to_s] }
OSA.add_conversion_to_ruby('imaA') { |value, type, object| value }
OSA.add_conversion_to_osa('Image') { |value| ['imaA', value.to_s] }
OSA.add_conversion_to_osa('TIFF picture') { |value| ['TIFF', value.to_s] }

@@ -30,2 +30,3 @@ /*

#include "rbosa.h"
#include <st.h>

@@ -198,2 +199,50 @@ static VALUE mOSA;

static void
__rbosa_raise_potential_app_error (AEDesc *reply)
{
OSErr error;
AEDesc errorNumDesc;
AEDesc errorStringDesc;
int errorNum;
char exception[128];
if (AEGetParamDesc (reply, keyErrorNumber, typeInteger, &errorNumDesc) != noErr)
return;
if (AEGetDescData (&errorNumDesc, &errorNum, sizeof errorNum) != noErr
|| (errorNum = CFSwapInt32HostToBig (errorNum)) == 0) {
AEDisposeDesc (&errorNumDesc);
return;
}
/* The reply is an application error. */
exception[0] = '\0';
error = AEGetParamDesc (reply, keyErrorString, typeChar, &errorStringDesc);
if (error == noErr) {
Size size;
size = AEGetDescDataSize (&errorStringDesc);
if (size > 0) {
char *msg;
msg = (char *)malloc (size);
if (msg != NULL) {
if (AEGetDescData (&errorStringDesc, &msg, size) == noErr)
snprintf (exception, sizeof exception, "application returned error %d with message '%s'", errorNum, msg);
free (msg);
}
}
AEDisposeDesc (&errorStringDesc);
}
if (exception[0] == '\0')
snprintf (exception, sizeof exception, "application returned error %d", errorNum);
AEDisposeDesc (&errorNumDesc);
rb_raise (rb_eRuntimeError, exception);
}
static VALUE

@@ -254,2 +303,4 @@ rbosa_app_send_event (VALUE self, VALUE event_class, VALUE event_id, VALUE params, VALUE need_retval)

__rbosa_raise_potential_app_error (&reply);
if (RTEST (need_retval)) {

@@ -290,4 +341,6 @@ VALUE rb_reply;

VALUE retval;
bool to_4cc;
rb_scan_args (argc, argv, "01", &coerce_type);
to_4cc = false;

@@ -297,3 +350,6 @@ desc = rbosa_element_aedesc (self);

if (!NIL_P (coerce_type)) {
error = AECoerceDesc (desc, RVAL2FOURCHAR (coerce_type), &coerced_desc);
FourCharCode code;
code = RVAL2FOURCHAR (coerce_type);
error = AECoerceDesc (desc, code, &coerced_desc);
if (error != noErr)

@@ -304,2 +360,3 @@ rb_raise (rb_eRuntimeError, "Cannot coerce desc to type %s : %s (%d)",

desc = &coerced_desc;
to_4cc = code == 'type';
}

@@ -313,3 +370,10 @@

error = AEGetDescData (desc, data, datasize);
retval = error == noErr ? rb_str_new (data, datasize) : Qnil;
if (error == noErr) {
if (to_4cc)
*(DescType*)data = CFSwapInt32HostToBig (*(DescType*)data);
retval = rb_str_new (data, datasize);
}
else {
retval = Qnil;
}

@@ -492,3 +556,39 @@ if (!NIL_P (coerce_type))

static int
__rbosa_elementrecord_set (VALUE key, VALUE value, AEDescList *list)
{
OSErr error;
error = AEPutKeyDesc (list, RVAL2FOURCHAR (key), rbosa_element_aedesc (value));
if (error != noErr)
rb_raise (rb_eRuntimeError, "Cannot set value %p for key %p of record %p: %s (%d)",
value, key, list, GetMacOSStatusErrorString (error), error);
return ST_CONTINUE;
}
static VALUE
rbosa_elementrecord_new (int argc, VALUE *argv, VALUE self)
{
OSErr error;
AEDescList list;
VALUE hash;
rb_scan_args (argc, argv, "01", &hash);
if (!NIL_P (hash))
Check_Type (hash, T_HASH);
error = AECreateList (NULL, 0, true, &list);
if (error != noErr)
rb_raise (rb_eRuntimeError, "Cannot create Apple Event descriptor list : %s (%d)",
GetMacOSStatusErrorString (error), error);
if (!NIL_P (hash))
rb_hash_foreach (hash, __rbosa_elementrecord_set, (VALUE)&list);
return rbosa_element_make (self, &list, Qnil);
}
static VALUE
rbosa_elementrecord_to_a (VALUE self)

@@ -552,2 +652,3 @@ {

cOSAElementRecord = rb_define_class_under (mOSA, "ElementRecord", cOSAElement);
rb_define_singleton_method (cOSAElementRecord, "__new__", rbosa_elementrecord_new, -1);
rb_define_method (cOSAElementRecord, "to_a", rbosa_elementrecord_to_a, 0);

@@ -560,2 +661,3 @@

rbosa_define_param ("lazy_events", Qtrue);
rbosa_define_param ("utf8_strings", Qfalse);
}