Skip to content

Instantly share code, notes, and snippets.

@zdennis
Last active December 20, 2019 18:31
Show Gist options
  • Save zdennis/239984ef068952e6fb1a2d99956768ea to your computer and use it in GitHub Desktop.
Save zdennis/239984ef068952e6fb1a2d99956768ea to your computer and use it in GitHub Desktop.
Ruby script to manually load/close URLs in Safari
#!/usr/bin/env ruby
##
# ruby load-manual-urls.rb --urls manual-urls.txt
#
require 'optparse'
require 'csv'
STDOUT.sync = true
options = {
seconds_between_load: 5,
close_after_seconds: 30,
max_open_urls: 5
}
OptionParser.new do |opts|
opts.banner = "Usage: load-manual-urls.rb [options]"
opts.on("-fFILE", "--file=FILE", "Path to file containing URLs to load") do |file|
options[:file] = file
end
opts.on("-sSECONDS", "--seconds-between-load=SECONDS") do |seconds|
options[:seconds_between_load] = seconds.to_i
end
opts.on("-cSECONDS", "--close-after-seconds=SECONDS") do |seconds|
options[:close_after_seconds] = seconds.to_i
end
opts.on("-mNUM", "--max-open-urls=NUM") do |num|
options[:max_open_urls] = num.to_i
end
opts.on("-h", "--help", "Print help") do
puts opts
exit!
end
end.parse!
if options[:file].nil? || !File.exist?(options[:file])
abort "A file containing URLs must be passed. e.g. #{$0} -f path/to/file-containing-urls.txt"
end
if options[:seconds_between_load].to_i <= 0
abort "Seconds between load must be a positive number. Failed on: #{options[:seconds_between_load].inspect}"
end
if options[:close_after_seconds].to_i <= 0
abort "Close after seconds must be a positive number. Failed on: #{options[:close_after_seconds].inspect}"
end
# Open Safari and log in
puts <<~MESSAGE
Before continuing open safari, go to https://genius-staging.com and log in.
Press enter when done.
MESSAGE
gets
def open_url(url)
puts "opening: #{url}"
command = <<~SHELL
bash -c 'osascript -e "
tell application \\"Safari\\"
tell window 1
set current tab to (make new tab with properties {URL:\\"#{url}\\"})
end tell
end tell
"'
SHELL
system(command)
end
def close_url(url)
puts "closing: #{url}"
command = <<~SHELL
bash -c 'osascript -e "
tell application \\"Safari\\"
repeat with i from (count of windows) to 1 by -1
repeat with j from (count of tabs of window i) to 1 by -1
set thistab to tab j of window i
set foo to url of thistab
if foo is equal to \\"#{url}\\" then close thistab
end repeat
end repeat
end tell
"'
SHELL
system(command)
end
threads = []
URLS_TO_LOAD = []
MANUAL_URLS = []
CSV.foreach(options[:file]) do |row|
next if row.length == 0
urls = row.flat_map(&:lines).
reject { |line| line.strip.empty? }
.map(&:chomp)
.group_by { |line| line.start_with?('http') }
URLS_TO_LOAD.concat(urls.fetch(true, []))
MANUAL_URLS.concat(urls.fetch(false, []))
end
URLS_TO_LOAD.each_with_index do |url, i|
if i+1 % options[:max_open_urls] == 0
wait_time = options[:seconds_between_load] * options[:close_after_seconds]
puts "Waiting #{wait_time} seconds"
sleep options[:max_open_urls]
end
thr = Thread.new {
open_url(url)
sleep options[:close_after_seconds]
close_url(url)
}
thr.abort_on_exception = true
threads << thr
sleep options[:seconds_between_load]
end
threads.map(&:join)
puts MANUAL_URLS
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment