Last active
December 20, 2015 13:29
-
-
Save pyrat/6139061 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env ruby | |
# Author: Alastair Brunton | |
require 'rubygems' | |
require 'appscript' | |
require './sdefToRBAppscriptModule' | |
include Appscript | |
file_path = ARGV[0] | |
f = FindApp.by_id('com.apple.finder') | |
Finder = SDEFParser.makeModule(f) | |
finder = Appscript.app("Finder", Finder) | |
finder.desktop_picture.set(MacTypes::FileURL.path(file_path)) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/bash | |
utime=`date +%s` | |
file="/tmp/$utime.jpg" | |
curl -L http://flickr.app[update]/random_image > $file | |
/Users/alastairbrunton/scripts/mac/change_desktop.rb $file |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/bash | |
cd /tmp && rm *.jpg |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
0,30 * * * * /Users/alastairbrunton/scripts/mac/change_desktop.sh | |
30 14 * * * /Users/alastairbrunton/scripts/mac/cleanup_pics.sh |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
EDITOR=vim crontab -e |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
require 'rubygems' | |
require 'nokogiri' | |
# basically our goal is to do what Terminology.dump does... | |
# except that we start with a call to the sdef tool | |
module SDEFParser | |
# direct quote from TerminologyParser::BigEndianParser | |
# we need this in order to know what the reserved words are | |
@@_reserved_keywords = {} | |
ReservedKeywords.each { |name| @@_reserved_keywords[name] = nil } | |
def self.xform(s) | |
# turn AppleScript English-like term into rb-appscript style terminology | |
# imitates TerminologyParser::BigEndianParser._name | |
# might not do this perfectly, but we can refine later | |
s = s.gsub(" ", "_").gsub("-", "_").gsub("/", "_").gsub("&", "and") | |
# I've omitted some stuff; might not matter in practice | |
# for example, if a character c is not legal (in LegalFirst and then in LegalRest), | |
# he substitutes "0x#{c.unpack('HXh')}"; we could easily do this if necessary | |
# special cases | |
s += "_" if s.start_with?("AS_") or @@_reserved_keywords.has_key?(s) or s.start_with?("_") | |
s | |
end | |
def self.hexify(s) | |
# deal with sdef representation of nonprintables in codes | |
# put into the form appscript expects | |
s = [s[2..-1]].pack("H*") if s.length >= 10 | |
s | |
end | |
def self.makeModule(f, debugging=false) | |
# f is expected to be the path to a scriptable application | |
# TODO: how about a little error checking in case sdef doesn't work? | |
# orig = `sdef '#{f}'` | |
# use same underlying carbon call that sdef uses | |
orig = AE.copy_scripting_definition(f) | |
# anonymous module, to be returned when filled out | |
result = Module.new | |
# version and path, not sure what significance these have | |
result.const_set(:Version, 1.1) # hard-coded into Terminology.dump_tables, so imitated here | |
result.const_set(:Path, f) | |
# prepare to parse XML | |
doc = Nokogiri.parse(orig) | |
# I could have made this code more "elegant" by collapsing steps into a repeated subroutine... | |
# ...but I'd rather it be explicit and very plain | |
# Nevertheless, the first three categories (classes, enumerators, properties) are absolutely identical | |
# Classes =================== | |
klasses = doc.search("class") | |
klass_array = [] | |
klasses.each do |klass| | |
klass_array << [xform(klass["name"]),hexify(klass["code"])] | |
end | |
# sort array on name | |
klass_array.sort! {|a,b| a[0] <=> b[0]} | |
klass_array.uniq! | |
result.const_set(:Classes, klass_array) | |
# Enumerators ================ | |
enums = doc.search("enumerator") | |
enum_array = [] | |
enums.each do |enum| | |
enum_array << [xform(enum["name"]),hexify(enum["code"])] | |
end | |
enum_array.sort! {|a,b| a[0] <=> b[0]} | |
enum_array.uniq! | |
result.const_set(:Enumerators, enum_array) | |
# Properties ================= | |
props = doc.search("property") | |
prop_array = [] | |
props.each do |prop| | |
prop_array << [xform(prop["name"]),hexify(prop["code"])] | |
end | |
prop_array.sort! {|a,b| a[0] <=> b[0]} | |
prop_array.uniq! | |
result.const_set(:Properties, prop_array) | |
# Elements =============== | |
# Terminology.dump seems to use plurals in a slightly brute-force way | |
# here, I'm only getting actual elements, and fetching their plurals from the classes | |
# TODO: is that a problem? we'll cross that bridge when we come to it | |
# (I can see why it might be, if the dictionary just forgot to list a class as an element) | |
els = doc.search("element") | |
el_array = [] | |
els.each do |el| | |
# fetch corresponding property | |
klas = doc.search("class[@name='#{el["type"]}']") | |
# assume we caught at least one | |
klas = klas[0] | |
next unless klas and klas["plural"] # if we didn't get one or no plural, skip for now (TODO: ok?) | |
el_array << [xform(klas["plural"]),hexify(klas["code"])] | |
end | |
el_array.sort! {|a,b| a[0] <=> b[0]} | |
el_array.uniq! | |
result.const_set(:Elements, el_array) | |
# Commands ================ | |
# a little more elaborate because a command can have parameters | |
coms = doc.search("command") | |
com_array = [] | |
coms.each do |com| | |
params = com.search("parameter") | |
params_array = [] | |
params.each do |param| | |
params_array << [xform(param["name"]),hexify(param["code"])] | |
end | |
com_array << [xform(com["name"]),hexify(com["code"]),params_array] | |
end | |
com_array.sort! {|a,b| a[0] <=> b[0]} | |
com_array.uniq! | |
result.const_set(:Commands, com_array) | |
# output | |
if debugging | |
# instead of returning the module, return the text of the dumped module contents | |
# we get Appscript itself to make the dump | |
# thus the output can be easily diffed with the output from Terminology.dump | |
tempfile = `mktemp -t terminologydump` | |
tables = [klass_array, enum_array, prop_array, el_array, com_array] | |
Terminology.dump_tables(tables, "DumpedTerminology", f, tempfile) | |
return File.read(tempfile) | |
end | |
return result | |
end | |
end | |
=begin and here's how to use it: | |
# require appscript (must be at least version 0.6.1) | |
# require this file -- we will error out if appscript has not been required | |
# start with path to scriptable application | |
f = "/Applications/iTunes.app" | |
# if what you have isn't a path, use the FindApp module to get it | |
# e.g.: f = FindApp.by_id('com.apple.itunes') | |
Tunes = SDEFParser.makeModule(f) | |
itu = Appscript.app("iTunes", Tunes) | |
# and we're off to the races | |
p itu.selection.get # or whatever | |
=end | |
# ignore this, just some tests I was using | |
if __FILE__ == $0 | |
# f = '/Users/mattleopard/Desktop/rb-appscript-0.6.1/src/lib' | |
# $:.unshift f | |
require 'pp' | |
f = FindApp.by_id('com.apple.itunes') | |
# s = SDEFParser.makeModule(f,true) | |
# File.popen("bbedit", "w") {|io| io.write(s)} | |
# exit | |
result = SDEFParser.makeModule(f) | |
result.constants.each do |con| | |
puts | |
puts con | |
pp result.const_get(con) | |
end | |
itu = Appscript.app("iTunes", result) | |
sel = itu.selection.get | |
sel.each do |trk| | |
puts trk.name.get | |
end | |
p itu.count(itu.playlists["Library"], :each => :track) | |
p itu.playlists["Library"].tracks.count( :each => :item ) | |
#sel[0].play | |
end | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment