Last active
August 29, 2015 14:23
-
-
Save mgalgs/642924e792e73e0de3ef to your computer and use it in GitHub Desktop.
itamaraty checker
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
/itamaraty |
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 | |
( | |
cat | msmtp -a default --read-recipients <<EOF | |
Subject: Summary of visa appointment checker | |
From: [email protected] | |
To: [email protected] | |
The earliest Visa appointment we were able to find today was: | |
$(cat /tmp/itamaraty-tracker) | |
EOF | |
) & | |
# for some reason the msmtp command above was hanging forever... Just sleep | |
# and then kill everything: | |
sleep 120 | |
rm -v /tmp/itamaraty-tracker | |
kill %1 |
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
// -*- compile-command: "go build itamaraty.go"; -*- | |
package main | |
import ( | |
"bufio" | |
"fmt" | |
"io/ioutil" | |
"log" | |
"os" | |
"os/exec" | |
"regexp" | |
"strings" | |
"time" | |
"github.com/andrew-d/go-termutil" | |
"github.com/PuerkitoBio/goquery" | |
) | |
const LAYOUT_ITMRTY = "20060102" | |
const LAYOUT_READABLE = "Monday, January 02, 2006" | |
const TRACKER_FILE = "/tmp/itamaraty-tracker" | |
func failOnError(err error, msg string) { | |
if err != nil { | |
log.Fatalf("%s: %s", msg, err) | |
panic(fmt.Sprintf("%s: %s", msg, err)) | |
} | |
} | |
func getDoc(url string) *goquery.Document { | |
if termutil.Isatty(os.Stdin.Fd()) { | |
doc, err := goquery.NewDocument(url) | |
failOnError(err, fmt.Sprintf("Couldn't download %s", url)) | |
return doc | |
} else { | |
doc, err := goquery.NewDocumentFromReader(bufio.NewReader(os.Stdin)) | |
failOnError(err, "Couldn't parse doc on stdin") | |
return doc | |
} | |
panic("BOGOMIPS") | |
} | |
func updateTrackerFile(earliest time.Time) { | |
contents, err := ioutil.ReadFile(TRACKER_FILE) | |
if err == nil { | |
timestr := strings.TrimSpace(string(contents[:])) | |
existing, err := time.Parse(LAYOUT_READABLE, timestr) | |
failOnError(err, fmt.Sprintf("Couldn't convert time string from tracker file: %s", timestr)) | |
if existing.Before(earliest) { | |
fmt.Printf("Not updating tracker file since %q is not earlier than %q\n", | |
earliest, existing) | |
return | |
} else { | |
fmt.Printf("Updating tracker file since %q is earlier than %q\n", | |
earliest, existing) | |
} | |
} else { | |
fmt.Println("Updating tracker file since we failed to open it") | |
} | |
data := []byte(earliest.Format(LAYOUT_READABLE + "\n")) | |
err = ioutil.WriteFile(TRACKER_FILE, data, 0777) | |
failOnError(err, fmt.Sprintf("Couldn't write to tracker file: %s", TRACKER_FILE)) | |
} | |
func main() { | |
url := "https://booknow.appointment-plus.com/1egll91k/?selection_form=yes&wt_c_id=&wt_d=&d=appointplus184&page=10&m=2&type=72&auth=yes&action=log_in&action2=&customer_id=&show_services=&temp_addon_id=&customer_location_id=321&vo=&selected_pets=&pet_count=&pet_list=&selected_children=&child_count=&children_list=&staff_switch_loc=&day_name=any&rep_id=&location_id=321&id=321&headquarters_id=321&service_id=1366&event=" | |
target_date_str := "20150721" | |
target_date, _ := time.Parse(LAYOUT_ITMRTY, target_date_str) | |
doc := getDoc(url) | |
earliest, _ := time.Parse("2006", "3000") | |
doc.Find("#cv-leftnav-item-calendar-available-id").Each(func(i int, s *goquery.Selection) { | |
href, exists := s.Attr("href") | |
if !exists { | |
panic(fmt.Sprintf("Bogus calendar item: %s", s)) | |
} | |
// javascript:dosubmit('20150825', 'viewappts', 'no','Child', 2) | |
re := regexp.MustCompile(`.*dosubmit\('(\d+)',.*`) | |
matches := re.FindStringSubmatch(href) | |
datestr := matches[1] | |
t, err := time.Parse(LAYOUT_ITMRTY, datestr) | |
failOnError(err, fmt.Sprintf("Couldn't parse date string: %s", datestr)) | |
if t.Before(earliest) { | |
earliest = t | |
} | |
if t.Before(target_date) { | |
pretty_t := t.Format("Monday, January 2") | |
fmt.Printf("Found an earlier appointment! It's on %s. Sending mail now...\n", pretty_t) | |
msgfmt := "Subject: Found an earlier visa appointment\n" + | |
"From: [email protected]\n" + | |
"To: [email protected], [email protected]\n\n" + | |
"It's on %s\n" + | |
"Go book it now (after responding to this message so that mitchallen\n" + | |
"and sonnierae don't both book it):\n\n" + | |
"https://booknow.appointment-plus.com/1egll91k/\n" | |
msg := fmt.Sprintf(msgfmt, pretty_t) | |
mailcmd := exec.Command("msmtp", "-a", "default", "--read-recipients") | |
mailcmd.Stdin = strings.NewReader(msg) | |
err := mailcmd.Run() | |
failOnError(err, "Failed to run msmtp command!") | |
} | |
}) | |
fmt.Printf("Couldn't find an earlier appointment :(.\nEarliest we found was %s\n", earliest.Format(LAYOUT_READABLE)) | |
updateTrackerFile(earliest) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment