diff --git a/.gitignore b/.gitignore index 6cd1df2..fa031c9 100755 --- a/.gitignore +++ b/.gitignore @@ -19,4 +19,6 @@ _cgo_export.* _testmain.go -*.exe \ No newline at end of file +*.exe + +pagechanges \ No newline at end of file diff --git a/config.json b/config.json new file mode 100644 index 0000000..7c7d438 --- /dev/null +++ b/config.json @@ -0,0 +1 @@ +{"alerts":[{"url":"http://bullercodeworks.com"}],"refresh":60} \ No newline at end of file diff --git a/main.go b/main.go new file mode 100644 index 0000000..4947156 --- /dev/null +++ b/main.go @@ -0,0 +1,125 @@ +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) + } +}