rb-scpt 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/CHANGES +497 -0
- data/doc/aem-manual/01_introduction.html +60 -0
- data/doc/aem-manual/02_apioverview.html +107 -0
- data/doc/aem-manual/03_packingandunpackingdata.html +135 -0
- data/doc/aem-manual/04_references.html +409 -0
- data/doc/aem-manual/05_targetingapplications.html +164 -0
- data/doc/aem-manual/06_buildingandsendingevents.html +229 -0
- data/doc/aem-manual/07_findapp.html +63 -0
- data/doc/aem-manual/08_examples.html +94 -0
- data/doc/aem-manual/aemreferenceinheritance.gif +0 -0
- data/doc/aem-manual/index.html +56 -0
- data/doc/appscript-manual/01_introduction.html +94 -0
- data/doc/appscript-manual/02_aboutappscripting.html +247 -0
- data/doc/appscript-manual/03_quicktutorial.html +167 -0
- data/doc/appscript-manual/04_gettinghelp.html +188 -0
- data/doc/appscript-manual/05_keywordconversion.html +106 -0
- data/doc/appscript-manual/06_classesandenums.html +192 -0
- data/doc/appscript-manual/07_applicationobjects.html +211 -0
- data/doc/appscript-manual/08_realvsgenericreferences.html +96 -0
- data/doc/appscript-manual/09_referenceforms.html +241 -0
- data/doc/appscript-manual/10_referenceexamples.html +154 -0
- data/doc/appscript-manual/11_applicationcommands.html +245 -0
- data/doc/appscript-manual/12_commandexamples.html +138 -0
- data/doc/appscript-manual/13_performanceissues.html +142 -0
- data/doc/appscript-manual/14_notes.html +80 -0
- data/doc/appscript-manual/application_architecture.gif +0 -0
- data/doc/appscript-manual/application_architecture2.gif +0 -0
- data/doc/appscript-manual/finder_to_textedit_event.gif +0 -0
- data/doc/appscript-manual/index.html +62 -0
- data/doc/appscript-manual/relationships_example.gif +0 -0
- data/doc/appscript-manual/ruby_to_itunes_event.gif +0 -0
- data/doc/full.css +106 -0
- data/doc/index.html +45 -0
- data/doc/mactypes-manual/01_introduction.html +54 -0
- data/doc/mactypes-manual/02_aliasclass.html +124 -0
- data/doc/mactypes-manual/03_fileurlclass.html +126 -0
- data/doc/mactypes-manual/04_unitsclass.html +100 -0
- data/doc/mactypes-manual/index.html +53 -0
- data/doc/osax-manual/01_introduction.html +67 -0
- data/doc/osax-manual/02_interface.html +147 -0
- data/doc/osax-manual/03_examples.html +73 -0
- data/doc/osax-manual/04_notes.html +61 -0
- data/doc/osax-manual/index.html +53 -0
- data/doc/rb-appscript-logo.png +0 -0
- data/extconf.rb +65 -0
- data/rb-scpt.gemspec +14 -0
- data/sample/AB_export_vcard.rb +31 -0
- data/sample/AB_list_people_with_emails.rb +13 -0
- data/sample/Add_iCal_event.rb +21 -0
- data/sample/Create_daily_iCal_todos.rb +75 -0
- data/sample/Export_Address_Book_phone_numbers.rb +59 -0
- data/sample/Hello_world.rb +21 -0
- data/sample/List_iTunes_playlist_names.rb +11 -0
- data/sample/Make_Mail_message.rb +33 -0
- data/sample/Open_file_in_TextEdit.rb +13 -0
- data/sample/Organize_Mail_messages.rb +61 -0
- data/sample/Print_folder_tree.rb +16 -0
- data/sample/Select_all_HTML_files.rb +14 -0
- data/sample/Set_iChat_status.rb +24 -0
- data/sample/Simple_Finder_GUI_Scripting.rb +18 -0
- data/sample/Stagger_Finder_windows.rb +25 -0
- data/sample/TextEdit_demo.rb +130 -0
- data/sample/iTunes_top40_to_html.rb +71 -0
- data/src/SendThreadSafe.c +380 -0
- data/src/SendThreadSafe.h +139 -0
- data/src/lib/_aem/aemreference.rb +1022 -0
- data/src/lib/_aem/codecs.rb +662 -0
- data/src/lib/_aem/connect.rb +205 -0
- data/src/lib/_aem/encodingsupport.rb +77 -0
- data/src/lib/_aem/findapp.rb +85 -0
- data/src/lib/_aem/mactypes.rb +251 -0
- data/src/lib/_aem/send.rb +279 -0
- data/src/lib/_aem/typewrappers.rb +59 -0
- data/src/lib/_appscript/defaultterminology.rb +277 -0
- data/src/lib/_appscript/referencerenderer.rb +245 -0
- data/src/lib/_appscript/reservedkeywords.rb +116 -0
- data/src/lib/_appscript/safeobject.rb +249 -0
- data/src/lib/_appscript/terminology.rb +471 -0
- data/src/lib/aem.rb +253 -0
- data/src/lib/appscript.rb +1075 -0
- data/src/lib/kae.rb +1489 -0
- data/src/lib/osax.rb +659 -0
- data/src/rbae.c +979 -0
- data/test/README +3 -0
- data/test/test_aemreference.rb +118 -0
- data/test/test_appscriptcommands.rb +152 -0
- data/test/test_appscriptreference.rb +106 -0
- data/test/test_codecs.rb +186 -0
- data/test/test_findapp.rb +26 -0
- data/test/test_mactypes.rb +79 -0
- data/test/test_osax.rb +54 -0
- data/test/testall.sh +10 -0
- metadata +145 -0
Binary file
|
data/extconf.rb
ADDED
@@ -0,0 +1,65 @@
|
|
1
|
+
# appscript install script
|
2
|
+
# Based on RubyOSA extconf.rb
|
3
|
+
# Original copyright below:
|
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 'mkmf'
|
32
|
+
require 'rbconfig'
|
33
|
+
|
34
|
+
$CFLAGS << ' -Wall'
|
35
|
+
$LDFLAGS << ' -framework Carbon -framework ApplicationServices'
|
36
|
+
|
37
|
+
# Avoid `ID' and `T_DATA' symbol collisions between Ruby and Carbon.
|
38
|
+
# (adapted code from RubyAEOSA - FUJIMOTO Hisakuni <hisa -at- fobj - com>)
|
39
|
+
|
40
|
+
maj, min = RUBY_VERSION.split('.')
|
41
|
+
is_ruby_18 = (maj <= '1' and min.to_i < 9)
|
42
|
+
if is_ruby_18
|
43
|
+
header_path = RbConfig::CONFIG['archdir']
|
44
|
+
else
|
45
|
+
header_path = File.join(RbConfig::CONFIG['rubyhdrdir'], 'ruby')
|
46
|
+
end
|
47
|
+
ruby_h = File.join(header_path, 'ruby.h')
|
48
|
+
intern_h = File.join(header_path, 'intern.h')
|
49
|
+
new_filename_prefix = 'osx_'
|
50
|
+
|
51
|
+
[ ruby_h, intern_h ].each do |src_path|
|
52
|
+
dst_fname = File.join('./src', new_filename_prefix + File.basename(src_path))
|
53
|
+
$stderr.puts "create #{File.expand_path(dst_fname)} ..."
|
54
|
+
File.open(dst_fname, 'w') do |dstfile|
|
55
|
+
IO.foreach(src_path) do |line|
|
56
|
+
line = line.gsub(/\bID\b/, 'RB_ID')
|
57
|
+
line = line.gsub(/\bT_DATA\b/, 'RB_T_DATA')
|
58
|
+
line = line.gsub(/\b(?:ruby\/)?intern.h\b/, "#{new_filename_prefix}intern.h")
|
59
|
+
line = line.gsub('#include "defines.h"', '#include "ruby/defines.h"') if not is_ruby_18
|
60
|
+
dstfile.puts line
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
create_makefile('ae', 'src')
|
data/rb-scpt.gemspec
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
require "rubygems"
|
2
|
+
|
3
|
+
Gem::Specification.new do |s|
|
4
|
+
s.name = "rb-scpt"
|
5
|
+
s.version = "1.0.0"
|
6
|
+
s.homepage = "https://github.com/BrendanThompson/rb-scpt"
|
7
|
+
s.summary="This is a fork of the original rb-appscript. Ruby AppleScript (rb-scpt) is a high-level, user-friendly Apple event bridge that allows you to control scriptable Mac OS X applications using ordinary Ruby scripts."
|
8
|
+
s.files = Dir["**/*"].delete_if { |name| ["MakeFile", "ae.bundle", "mkmf.log", "rbae.o", "SendThreadSafe.o", "src/osx_ruby.h", "src/osx_intern.h"].include?(name) }
|
9
|
+
s.extensions = "extconf.rb"
|
10
|
+
s.test_files = Dir["test/test_*.rb"]
|
11
|
+
s.authors = ["hhas","Brendan Thompson"]
|
12
|
+
s.email = 'brendan@btsystems.com.au'
|
13
|
+
s.required_ruby_version = ">= 1.8"
|
14
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
# Exports all Address Book entries as vcards to current working folder.
|
4
|
+
#
|
5
|
+
# Files are named as 'NAME.vcard' (note: existing files will be overwritten).
|
6
|
+
# If the name is missing, 'unknown' is used instead. If two or more people
|
7
|
+
# share the same name, files will be named 'NAME.vcard', 'NAME 1.vcard',
|
8
|
+
# 'NAME 2.vcard', etc.
|
9
|
+
|
10
|
+
|
11
|
+
# Note: if using the appscript gem, rubygems must be required first:
|
12
|
+
begin; require 'rubygems'; rescue LoadError; end
|
13
|
+
|
14
|
+
require 'appscript'
|
15
|
+
include Appscript
|
16
|
+
|
17
|
+
people = app('Address Book').people
|
18
|
+
|
19
|
+
found_names = []
|
20
|
+
people.name.get.zip(people.vcard.get).each do |name, vcard|
|
21
|
+
name = 'unknown' if name == ''
|
22
|
+
name = name.gsub('/', ':')
|
23
|
+
filename = "#{name}.vcard"
|
24
|
+
i = 1
|
25
|
+
while found_names.include?(filename.downcase)
|
26
|
+
filename = "#{name} #{i}.vcard"
|
27
|
+
i += 1
|
28
|
+
end
|
29
|
+
found_names.push(filename.downcase)
|
30
|
+
File.open(filename, 'w') { |f| f.puts vcard }
|
31
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
# Lists the name and email(s) of every person in Address Book with
|
4
|
+
# one or more email addresses.
|
5
|
+
|
6
|
+
# Note: if using the appscript gem, rubygems must be required first:
|
7
|
+
begin; require 'rubygems'; rescue LoadError; end
|
8
|
+
|
9
|
+
require "appscript"
|
10
|
+
include Appscript
|
11
|
+
|
12
|
+
people_ref = app('Address Book').people[its.emails.ne([])]
|
13
|
+
p people_ref.name.get.zip(people_ref.emails.value.get)
|
@@ -0,0 +1,21 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
# Add an event to Home calendar that runs from 7am to 9 am tomorrow
|
4
|
+
|
5
|
+
# Note: if using the appscript gem, rubygems must be required first:
|
6
|
+
begin; require 'rubygems'; rescue LoadError; end
|
7
|
+
|
8
|
+
require 'appscript'
|
9
|
+
include Appscript
|
10
|
+
|
11
|
+
calendar_name = 'Home'
|
12
|
+
t = Time.now + 60 * 60 * 24
|
13
|
+
start = Time.local(t.year, t.month, t.day, 7)
|
14
|
+
end_ = start + 60 * 60 * 2
|
15
|
+
summary = 'First pants, then shoes.'
|
16
|
+
|
17
|
+
app('iCal').calendars[calendar_name].events.end.make(
|
18
|
+
:new => :event, :with_properties => {
|
19
|
+
:start_date => start,
|
20
|
+
:end_date => end_,
|
21
|
+
:summary => summary})
|
@@ -0,0 +1,75 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
# Creates daily recurring todo items in iCal.
|
4
|
+
#
|
5
|
+
# Ported from 'Create daily todos.scpt' by Alexander Kellett
|
6
|
+
# <http://web.mac.com/lypanov>
|
7
|
+
#
|
8
|
+
# While iCal makes it easy to create recurring events, it lacks a similar
|
9
|
+
# feature for To Do items. This script can be used to create a daily checklist
|
10
|
+
# of things to do.
|
11
|
+
#
|
12
|
+
# To begin, create a new calendar with the name "Shadow". Then, add a number
|
13
|
+
# of recurring events to this calendar. All Daily To Dos events must be
|
14
|
+
# recurring events as only recurring events are converted to To Dos. Start and
|
15
|
+
# end dates are ignored.
|
16
|
+
#
|
17
|
+
# Now, create a calendar called "Personal". When the script is run, all the
|
18
|
+
# To Do items will be added to this calendar. Finally, set up a cron job to
|
19
|
+
# run this script first thing every morning.
|
20
|
+
#
|
21
|
+
# See also:
|
22
|
+
# <http://web.mac.com/lypanov/iWeb/Web/Diary/1EDF1B30-C4AF-4A99-BC4D-
|
23
|
+
# 4A8AF14BFC96.html>
|
24
|
+
# <http://web.mac.com/lypanov/iWeb/Web/Diary/9950DF91-726E-42B2-A639-
|
25
|
+
# 1967D1DE7545.html>
|
26
|
+
|
27
|
+
# Note: if using the appscript gem, rubygems must be required first:
|
28
|
+
begin; require 'rubygems'; rescue LoadError; end
|
29
|
+
|
30
|
+
require "appscript"
|
31
|
+
include Appscript
|
32
|
+
|
33
|
+
ICal = app("iCal")
|
34
|
+
|
35
|
+
# The calendar in which recurring todo items should appear:
|
36
|
+
ToDoCalendarName = "Personal"
|
37
|
+
|
38
|
+
def create_to_do(summary_text)
|
39
|
+
# Adds To Dos to calendar "Personal"
|
40
|
+
now = Time.new
|
41
|
+
midnight = Time.local(now.year(), now.month(), now.day())
|
42
|
+
to_dos = ICal.calendars[ToDoCalendarName].todos
|
43
|
+
# don't create an item if it already exists for today!
|
44
|
+
if to_dos[its.due_date.ge(midnight).and(
|
45
|
+
its.summary.eq(summary_text))].count < 1
|
46
|
+
to_dos.end.make(:new=>:todo, :with_properties=>{
|
47
|
+
:due_date=>midnight, :summary=>summary_text})
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
def get_label(recurrence, label)
|
52
|
+
match = Regexp.new("(?:^|;)#{label}=(.*?)(?:$|;)").match(recurrence)
|
53
|
+
return match ? match[1] : nil
|
54
|
+
end
|
55
|
+
|
56
|
+
weekday_code = ["SU", "MO", "TU", "WE", "TH", "FR", "SA"][Time.new.wday]
|
57
|
+
events = ICal.calendars["Shadow"].events
|
58
|
+
|
59
|
+
events.recurrence.get.zip(events.summary.get).each do |recurrence, summary|
|
60
|
+
recurs_on_this_weekday = false
|
61
|
+
frequency = get_label(recurrence, "FREQ")
|
62
|
+
case frequency
|
63
|
+
when "WEEKLY"
|
64
|
+
days = get_label(recurrence, "BYDAY")
|
65
|
+
if days and days.split(",").include?(weekday_code)
|
66
|
+
recurs_on_this_weekday = true
|
67
|
+
end
|
68
|
+
when "DAILY"
|
69
|
+
recurs_on_this_weekday = true
|
70
|
+
end
|
71
|
+
if recurs_on_this_weekday
|
72
|
+
puts summary
|
73
|
+
create_to_do(summary)
|
74
|
+
end
|
75
|
+
end
|
@@ -0,0 +1,59 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
# Exports phone numbers from Address Book.
|
4
|
+
|
5
|
+
# Note: if using the appscript gem, rubygems must be required first:
|
6
|
+
begin; require 'rubygems'; rescue LoadError; end
|
7
|
+
|
8
|
+
require "osax"
|
9
|
+
include Appscript, OSAX
|
10
|
+
|
11
|
+
# create Application object for Address Book
|
12
|
+
AB = app("Address Book")
|
13
|
+
|
14
|
+
# prompt user for name of Address Book group to export from
|
15
|
+
DefaultChoice = ["<All>"]
|
16
|
+
|
17
|
+
groups = DefaultChoice + AB.groups.name.get
|
18
|
+
choice = osax.choose_from_list(groups, :default_items => DefaultChoice)
|
19
|
+
if choice == false # user cancelled
|
20
|
+
exit
|
21
|
+
elsif choice == DefaultChoice
|
22
|
+
ref = AB
|
23
|
+
else
|
24
|
+
ref = AB.groups[choice[0]]
|
25
|
+
end
|
26
|
+
|
27
|
+
# build a reference identifying those people with one or more phone numbers
|
28
|
+
p = ref.people[its.phones.ne([])]
|
29
|
+
|
30
|
+
# get first and last names for those people, replacing any :missing_value
|
31
|
+
# entries with empty strings
|
32
|
+
last_names = p.last_name.get.collect { |val| val.is_a?(String) ? val : "" }
|
33
|
+
first_names = p.first_name.get.collect { |val| val.is_a?(String) ? val : "" }
|
34
|
+
|
35
|
+
# get lists of phone numbers and locations for those people
|
36
|
+
locations = p.phones.label.get
|
37
|
+
numbers = p.phones.value.get
|
38
|
+
|
39
|
+
# build an array containing each person's details:
|
40
|
+
# [[last name, first name, locations, numbers], ...]
|
41
|
+
people = last_names.zip(first_names, locations, numbers)
|
42
|
+
|
43
|
+
# sort array by last and first name
|
44
|
+
people.sort! do |a, b|
|
45
|
+
a[0,2].collect { |s| s.downcase } <=> b[0,2].collect { |s| s.downcase }
|
46
|
+
end
|
47
|
+
|
48
|
+
# print table
|
49
|
+
puts " #{'_' * 70} "
|
50
|
+
people.each do |last_name, first_name, locations, numbers|
|
51
|
+
name = [last_name, first_name].delete_if { |s| s == "" }.join(', ')
|
52
|
+
puts "|#{' ' * 70}|"
|
53
|
+
# print each phone number in turn
|
54
|
+
numbers.zip(locations).each do |number, location|
|
55
|
+
puts "| #{name.ljust(32)} #{number.ljust(20)} (#{(location + ')').ljust(13)} |"
|
56
|
+
name = ""
|
57
|
+
end
|
58
|
+
puts "|#{'_' * 70}|"
|
59
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
# Note: if using the appscript gem, rubygems must be required first:
|
4
|
+
begin; require 'rubygems'; rescue LoadError; end
|
5
|
+
|
6
|
+
# 1. "Hello world" in TextEdit:
|
7
|
+
|
8
|
+
require "appscript"
|
9
|
+
include Appscript
|
10
|
+
|
11
|
+
te = app('TextEdit')
|
12
|
+
te.activate
|
13
|
+
te.documents.end.make(:new => :document, :with_properties => {:text => "Hello World!\n"})
|
14
|
+
|
15
|
+
|
16
|
+
# 2. "Hello world" using StandardAdditions:
|
17
|
+
|
18
|
+
require "osax"
|
19
|
+
include OSAX
|
20
|
+
|
21
|
+
osax.display_dialog("Hello World")
|
@@ -0,0 +1,11 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
# List names of playlists in iTunes.
|
4
|
+
|
5
|
+
# Note: if using the appscript gem, rubygems must be required first:
|
6
|
+
begin; require 'rubygems'; rescue LoadError; end
|
7
|
+
|
8
|
+
require "appscript"
|
9
|
+
include Appscript
|
10
|
+
|
11
|
+
p app('iTunes').sources[1].user_playlists.name.get
|
@@ -0,0 +1,33 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
# Compose an outgoing message in Apple's Mail.app.
|
4
|
+
|
5
|
+
# Note: if using the appscript gem, rubygems must be required first:
|
6
|
+
begin; require 'rubygems'; rescue LoadError; end
|
7
|
+
|
8
|
+
require "appscript"
|
9
|
+
include Appscript
|
10
|
+
|
11
|
+
def make_message(addresses, subject, content, show_window=false)
|
12
|
+
# Make an outgoing message in Mail.
|
13
|
+
# addresses : list of unicode -- a list of email addresses
|
14
|
+
# subject : unicode -- the message subject
|
15
|
+
# content : unicode -- the message content
|
16
|
+
# show_window : Boolean -- show message window in Mail
|
17
|
+
# Result : reference -- reference to the new outgoing message
|
18
|
+
mail = app('Mail')
|
19
|
+
msg = mail.make(
|
20
|
+
:new => :outgoing_message,
|
21
|
+
:with_properties => {:visible => show_window})
|
22
|
+
addresses.each do |an_address|
|
23
|
+
msg.to_recipients.end.make(
|
24
|
+
:new => :recipient,
|
25
|
+
:with_properties => {:address => an_address})
|
26
|
+
end
|
27
|
+
msg.subject.set(subject)
|
28
|
+
msg.content.set(content)
|
29
|
+
return msg
|
30
|
+
end
|
31
|
+
|
32
|
+
# test
|
33
|
+
p make_message(['joe@foo.com', 'jane@bar.net'], 'Hello World', 'Some body text.', true)
|
@@ -0,0 +1,13 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
# Opens a file in TextEdit. (Demonstrates mactypes module usage.)
|
4
|
+
|
5
|
+
# Note: if using the appscript gem, rubygems must be required first:
|
6
|
+
begin; require 'rubygems'; rescue LoadError; end
|
7
|
+
|
8
|
+
require "appscript"
|
9
|
+
include Appscript
|
10
|
+
|
11
|
+
te = app('TextEdit')
|
12
|
+
te.activate
|
13
|
+
te.open(MacTypes::Alias.path('/Users/USERNAME/ReadMe.txt'))
|
@@ -0,0 +1,61 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
# Set up a Mail mailbox folder for organising incoming emails from a
|
4
|
+
# particular sender.
|
5
|
+
#
|
6
|
+
# Based on an AppleScript by Michelle Steiner.
|
7
|
+
#
|
8
|
+
# To use: in Mail, select an incoming email message from the desired sender
|
9
|
+
# (e.g. a mailing list), then run this script. The script will first make a
|
10
|
+
# new mailbox folder for storing messages from this sender if one doesn't
|
11
|
+
# already exist. It will then create a new Mail rule that automatically moves
|
12
|
+
# incoming messages from this sender directly into this mailbox.
|
13
|
+
|
14
|
+
# Note: if using the appscript gem, rubygems must be required first:
|
15
|
+
begin; require 'rubygems'; rescue LoadError; end
|
16
|
+
|
17
|
+
require "appscript"
|
18
|
+
include Appscript
|
19
|
+
|
20
|
+
mail = app('Mail')
|
21
|
+
|
22
|
+
# get the current selection in Mail and make sure it's an email message
|
23
|
+
selection = mail.selection.get
|
24
|
+
|
25
|
+
if selection == [] or selection[0].class_.get != :message
|
26
|
+
puts "Please select a message and try again."
|
27
|
+
exit
|
28
|
+
end
|
29
|
+
|
30
|
+
# get a reference to the first selected message
|
31
|
+
msg = selection[0]
|
32
|
+
|
33
|
+
recipient = msg.to_recipients[1]
|
34
|
+
address = recipient.address.get
|
35
|
+
|
36
|
+
# determine the new mailbox's name based on the sender's name/address
|
37
|
+
if recipient.name.exists
|
38
|
+
folder_name = recipient.name.get
|
39
|
+
else
|
40
|
+
folder_name = /^[^@]*/.match(address)[0]
|
41
|
+
end
|
42
|
+
|
43
|
+
# make a new mailbox if one doesn't already exist
|
44
|
+
if not mail.mailboxes[folder_name].exists
|
45
|
+
mail.mailboxes.end.make(:new=>:mailbox, :with_properties=>{
|
46
|
+
:name=>folder_name})
|
47
|
+
end
|
48
|
+
|
49
|
+
# make a new mail rule to move list messages to the mailbox
|
50
|
+
if not mail.rules[folder_name].exists
|
51
|
+
new_rule = mail.rules[1].after.make(:new=>:rule, :with_properties=>{
|
52
|
+
:name=>folder_name,
|
53
|
+
:should_move_message=>true,
|
54
|
+
:move_message=>app.mailboxes[folder_name],
|
55
|
+
:stop_evaluating_rules=>true})
|
56
|
+
new_rule.make(:new=>:rule_condition, :with_properties=>{
|
57
|
+
:expression=>address,
|
58
|
+
:rule_type=>:to_header,
|
59
|
+
:qualifier=>:does_contain_value})
|
60
|
+
new_rule.enabled.set(true)
|
61
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
# Prints the sub-folder hierarchy of a given folder as a list of folder names indented according to depth.
|
4
|
+
|
5
|
+
# Note: if using the appscript gem, rubygems must be required first:
|
6
|
+
begin; require 'rubygems'; rescue LoadError; end
|
7
|
+
|
8
|
+
require "appscript"
|
9
|
+
include Appscript
|
10
|
+
|
11
|
+
def print_folder_tree(folder, indent='')
|
12
|
+
puts indent + folder.name.get
|
13
|
+
folder.folders.get.each { |folder| print_folder_tree(folder, indent + "\t") }
|
14
|
+
end
|
15
|
+
|
16
|
+
print_folder_tree(app('Finder').home.folders['Documents'])
|