rb-scpt 1.0.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.
- 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'])
|