pagechanges/main.go

126 lines
2.5 KiB
Go

package main
import (
"encoding/json"
"fmt"
"io/ioutil"
"net/http"
"strconv"
"time"
)
// SiteAlertConfig is an instance of a site to be monitored
// in the config file
type SiteAlertConfig struct {
URL string `json:"url"`
}
// Config is the config that we're running with
type Config struct {
RefreshInterval int `json:"refresh"`
Alerts []SiteAlertConfig `json:"alerts"`
}
var config *Config
var allAlerts []Alert
func main() {
loadConfig()
for {
fmt.Println("Kicking off refresh.")
for i := range allAlerts {
fmt.Println("Checking URL: " + allAlerts[i].url + "...")
if allAlerts[i].Refresh() {
for j := 0; j < 25; j++ {
fmt.Println(" CHANGE DETECTED!")
}
}
}
fmt.Println("Refresh Completed.")
time.Sleep(time.Minute)
}
}
func loadConfig() {
fmt.Print("Loading Config...")
jsonInp, err := ioutil.ReadFile("config.json")
assertError(err)
assertError(json.Unmarshal(jsonInp, &config))
t, e := json.Marshal(config)
if e != nil {
fmt.Println(e)
} else {
fmt.Println(string(t))
}
for i := range config.Alerts {
allAlerts = append(allAlerts, *CreateNewAlert(config.Alerts[i].URL))
}
fmt.Println("Found " + strconv.Itoa(len(allAlerts)) + " alerts")
}
// Alert is for monitoring a page
type Alert struct {
url string
contents string
response *http.Response
err error
updateTime time.Time
lastChangeContents string
lastChangeResponse *http.Response
lastChangeError error
lastChangeTime time.Time
}
// CreateNewAlert returns an alert object for url 'u'
func CreateNewAlert(u string) *Alert {
a := Alert{url: u}
a.response, a.err = http.Get(u)
return &a
}
// Refresh refetches the url for the alert and returns
// true if it changed.
func (a *Alert) Refresh() bool {
var changed bool
r, e := http.Get(a.url)
if e != a.err {
a.Update(r, "", e)
return true
}
if body, err := ioutil.ReadAll(r.Body); err == nil {
b := string(body)
if b != a.contents {
changed = true
a.Update(r, b, e)
}
} else {
e = err
}
r.Body.Close()
if e != a.err {
a.Update(r, "", e)
return true
}
return changed
}
// Update updates the contents of the alert with the new changes
func (a *Alert) Update(r *http.Response, body string, e error) {
a.lastChangeContents = a.contents
a.lastChangeResponse = a.response
a.lastChangeError = a.err
a.lastChangeTime = a.updateTime
a.contents = body
a.response = r
a.err = e
a.updateTime = time.Now()
}
func assertError(err error) {
if err != nil {
panic(err)
}
}