Skip to content

Instantly share code, notes, and snippets.

@cduong
Forked from kejadlen/goes_rescheduler.rb
Last active September 8, 2017 00:29
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save cduong/aff9bb2193b76a31a044 to your computer and use it in GitHub Desktop.
Save cduong/aff9bb2193b76a31a044 to your computer and use it in GitHub Desktop.
require 'logger'
require 'time'
require 'selenium-webdriver'
# Windows version
class Rescheduler
attr_reader :username, :password, :logger
def initialize(username, password)
@username, @password = 'username', 'password'
@logger = Logger.new(STDOUT)
logger.level = Logger::INFO
end
def get_body_text(browser)
return browser.find_element(tag_name: 'body').text
end
def reschedule!
browser = Selenium::WebDriver.for :chrome
# Sign in and go to the Nexus application
browser.navigate.to('https://goes-app.cbp.dhs.gov/main/goes')
browser.find_element(id: 'user').send_keys(username)
browser.find_element(id: 'password').send_keys(password)
browser.find_element(id: 'SignIn').click
browser.find_element(link: 'Enter').click
browser.find_element(name: 'manageAptm').click
# Get the current interview location and time
body_text = get_body_text(browser)
date = body_text[/Interview Date: (.+)/, 1]
time = body_text[/Interview Time: (.+)/, 1]
location = body_text[/Enrollment Center: (.+)/, 1]
current_interview = Time.parse("#{date} #{time}")
logger.info "Current interview: #{current_interview.strftime('%D %H:%M')} at #{location}"
browser.find_element(name: 'reschedule').click
browser.find_element(name: 'next').click
# Get the interview options
links = browser.find_elements(partial_link_text: 'Enrollment Center')
times = get_body_text(browser).scan(/Date:(.+),\s+Start Time:(\d{2})(\d{2}),/)
.map {|d,h,m| Time.parse("#{d} #{h}:#{m}") }
# Drop the time for Blaine, since there's a time for it but no link.
times.shift
interview_options = links.zip(times)
logger.info "Interview options:\n#{interview_options.map {|l,d| "#{d.strftime('%D %H:%M')} at #{l.text}" }.join("\n")}"
# Really, we only care about Seattle
seattle = interview_options.find {|l,_| l.text.include?('Seattle') } || interview_options.first
return if current_interview < seattle.last || !yield(seattle.last)
logger.info "Found a better time! Switching interview to #{seattle.last.strftime('%D %H:%M')}"
seattle.first.click
browser.find_element(class: 'entry').click
browser.find_element(name: 'comments').send_keys('Earlier time')
browser.find_element(name: 'Confirm').click
end
end
rescheduler = Rescheduler.new(ENV['GOES_USERNAME'], ENV['GOES_PASSWORD'])
while true
rescheduler.reschedule! do |time|
(time > Time.now + 24*60*60) # Require more than a day of warning
# && (time.saturday? || time.sunday?) # Only a weekend
end
sleep 10*60 # 10 minutes
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment