From b0013263427a0e6b0b86dfe3dacc156187198e48 Mon Sep 17 00:00:00 2001 From: Dan Buch Date: Mon, 18 Dec 2017 11:11:26 -0500 Subject: [PATCH] A bit more with wherewhen becaus --- wherewhen/.gitignore | 1 + wherewhen/Makefile | 2 + wherewhen/find-wherewhen | 59 ------------------ wherewhen/{cmd/wherewhen => }/main.go | 87 +++++++++++++++++---------- 4 files changed, 58 insertions(+), 91 deletions(-) create mode 100644 wherewhen/Makefile delete mode 100755 wherewhen/find-wherewhen rename wherewhen/{cmd/wherewhen => }/main.go (67%) diff --git a/wherewhen/.gitignore b/wherewhen/.gitignore index c2487f2..c81cdbe 100644 --- a/wherewhen/.gitignore +++ b/wherewhen/.gitignore @@ -1 +1,2 @@ client_secret.json +/wherewhen diff --git a/wherewhen/Makefile b/wherewhen/Makefile new file mode 100644 index 0000000..1f875d9 --- /dev/null +++ b/wherewhen/Makefile @@ -0,0 +1,2 @@ +wherewhen: $(shell git ls-files '*.go') + go build diff --git a/wherewhen/find-wherewhen b/wherewhen/find-wherewhen deleted file mode 100755 index 1fd1a73..0000000 --- a/wherewhen/find-wherewhen +++ /dev/null @@ -1,59 +0,0 @@ -#!/usr/bin/env bash -set -o errexit - -main() { - if [[ "${DEBUG}" ]]; then - set -o xtrace - fi - - if [[ "${*}" =~ -h|--help|help|wat ]]; then - __usage "${@}" - exit 0 - fi - - : "${TMPDIR:=/var/tmp}" - - local tmpout="${TMPDIR}/find-wherewhen-$(date +%s).tmp" - local calendar_id="${1}" - shift || true - - : "${START_TIME:=$(date --date='1 years ago' -Iseconds)}" - : "${END_TIME:=$(date -Iseconds)}" - - if [[ ! "${calendar_id}" ]]; then - echo Missing \ positional argument - exit 1 - fi - - if [[ ! "${GOOGLE_API_TOKEN}" ]]; then - echo Missing \$GOOGLE_API_TOKEN - exit 1 - fi - - local url='https://www.googleapis.com/calendar/v3/calendars' - url="${url}/${calendar_id}/events" - local qs="${qs}maxResults=2500&orderBy=startTime&singleEvents=true" - qs="${qs}&timeMax=$(__qsval "${END_TIME}")" - qs="${qs}&timeMin=$(__qsval "${START_TIME}")" - qs="${qs}&fields=items(summary%2Cend%2FdateTime%2Clocation%2Cstart%2FdateTime)" - qs="${qs}&key=${GOOGLE_API_TOKEN}" - - echo "GET ${url}?${qs}" - curl -X GET -s "${url}?${qs}" | jq . >"${tmpout}" - echo "${tmpout}" -} - - -__qsval() { - jq -r '.|@uri' <<<"\"${1}\"" -} - -__usage() { - cat < [-s|--start-time|-e|--end-time] - -Find where and when in a given time range (default past 1y). -EOF -} - -main "${@}" diff --git a/wherewhen/cmd/wherewhen/main.go b/wherewhen/main.go similarity index 67% rename from wherewhen/cmd/wherewhen/main.go rename to wherewhen/main.go index afb64cc..c03dfca 100644 --- a/wherewhen/cmd/wherewhen/main.go +++ b/wherewhen/main.go @@ -5,15 +5,16 @@ import ( "flag" "fmt" "io/ioutil" - "log" "net/http" "net/url" "os" "os/user" "path/filepath" "strings" + "syscall" "time" + "github.com/sirupsen/logrus" "golang.org/x/net/context" "golang.org/x/oauth2" "golang.org/x/oauth2/google" @@ -21,13 +22,23 @@ import ( ) var ( - nowTime = time.Now() - oneYear, _ = time.ParseDuration("365d") - clientSecretFlag = flag.String("s", "client_secret.json", "client secret json file") - calendarIDFlag = flag.String("i", "primary", "calendar ID to search") - endTimeFlag = flag.String("e", nowTime.Format(time.RFC3339), "end time for search") - timeWindowFlag = flag.Duration("t", oneYear, "time window duration from before end time") - defaultLocationFlag = flag.String("l", "notset", "default location for where") + nowTime = time.Now() + oneYearString = fmt.Sprintf("%dh", 365*24) + oneYear, _ = time.ParseDuration(oneYearString) + clientSecretFlag = flag.String( + "s", getEnvDefault("CLIENT_SECRET", "client_secret.json"), "client secret json file") + calendarIDFlag = flag.String( + "i", getEnvDefault("CALENDAR", "primary"), "calendar ID to search") + endTimeFlag = flag.String( + "e", getEnvDefault("END_TIME", nowTime.Format(dateFmt)), "end time for search") + timeWindowFlag = flag.Duration( + "t", func() time.Duration { + stringVal := getEnvDefault("DURATION", oneYearString) + val, _ := time.ParseDuration(stringVal) + return val + }(), "time window duration from before end time") + defaultLocationFlag = flag.String( + "l", getEnvDefault("DEFAULT_LOCATION", "notset"), "default location for where") locationAliases = map[string]string{ "pittsburgh": "dan", @@ -40,6 +51,15 @@ const ( dateFmt = "2006-01-02" ) +func getEnvDefault(key, defVal string) string { + for _, k := range []string{"WHEREWHEN_" + key, key} { + if v, ok := syscall.Getenv(k); ok { + return v + } + } + return defVal +} + func main() { flag.Parse() @@ -47,23 +67,23 @@ func main() { b, err := ioutil.ReadFile(*clientSecretFlag) if err != nil { - log.Fatalf("Unable to read client secret file: %v", err) + logrus.Fatalf("Unable to read client secret file: %v", err) } config, err := google.ConfigFromJSON(b, calendar.CalendarReadonlyScope) if err != nil { - log.Fatalf("Unable to parse client secret file to config: %v", err) + logrus.Fatalf("Unable to parse client secret file to config: %v", err) } client := getClient(ctx, config) srv, err := calendar.New(client) if err != nil { - log.Fatalf("Unable to retrieve calendar Client %v", err) + logrus.Fatalf("Unable to retrieve calendar Client %v", err) } - endT, err := time.Parse(time.RFC3339, *endTimeFlag) + endT, err := time.Parse(dateFmt, *endTimeFlag) if err != nil { - log.Fatalf("Unable to parse end time %q: %v", *endTimeFlag, err) + logrus.Fatalf("Unable to parse end time %q: %v", *endTimeFlag, err) } maxResults := int64(2500) @@ -73,17 +93,17 @@ func main() { SingleEvents(true).TimeMin(t).TimeMax(endT.Format(time.RFC3339)). MaxResults(maxResults).OrderBy("startTime").Do() if err != nil { - log.Fatalf("Unable to retrieve next %d events. %v", maxResults, err) + logrus.Fatalf("Unable to retrieve next %d events. %v", maxResults, err) } - log.Printf("found %d events", len(events.Items)) - log.Printf("generating days between %v and %v", startT, endT) + logrus.WithField("count", len(events.Items)).Infof("found events") + logrus.Debugf("generating days between %v and %v", startT, endT) days := generateDays(startT, endT) foundEvents := []*lilEvent{} defaultLocation := *defaultLocationFlag - log.Printf("generated %d days between %v and %v", len(days), startT, endT) + logrus.Debugf("generated %d days between %v and %v", len(days), startT, endT) if len(events.Items) > 0 { for _, i := range events.Items { @@ -95,13 +115,13 @@ func main() { if i.Start.DateTime != "" { startT, err := time.Parse(time.RFC3339, i.Start.DateTime) if err != nil { - log.Printf("error parsing start date: %v", err) + logrus.Errorf("error parsing start date: %v", err) continue } endT, err := time.Parse(time.RFC3339, i.End.DateTime) if err != nil { - log.Printf("error parsing end date: %v", err) + logrus.Errorf("error parsing end date: %v", err) continue } startDate = startT.Format(dateFmt) @@ -137,21 +157,23 @@ func main() { evt.Location = loc if evt.Start == evt.End { - log.Printf("skipping same-day event on %s (%s)", evt.Start, evt.Summary) + logrus.Debugf("skipping same-day event on %s (%s)", evt.Start, evt.Summary) continue } foundEvents = append(foundEvents, evt) } } else { - log.Println("No events found") + logrus.Info("No events found") } for _, day := range days { - log.Printf("working on date %v", day) + logrus.Debugf("working on date %v", day) + for _, evt := range foundEvents { - log.Printf("checking if %s is in range %s %s", day.Date, evt.Start, evt.End) + logrus.Debugf("checking if %s is in range %s %s", day.Date, evt.Start, evt.End) + if evt.HasDate(day.Date) { - log.Printf("match found for %s in range %s %s, setting location to %s", day.Date, evt.Start, evt.End, evt.Location) + logrus.Debugf("match found for %s in range %s %s, setting location to %s", day.Date, evt.Start, evt.End, evt.Location) day.Location = evt.Location } } @@ -160,9 +182,10 @@ func main() { for _, day := range days { asJson, err := json.Marshal(day) if err != nil { - log.Printf("ERROR: %v", err) + logrus.Error(err) continue } + fmt.Println(string(asJson)) } } @@ -170,7 +193,7 @@ func main() { func getClient(ctx context.Context, config *oauth2.Config) *http.Client { cacheFile, err := tokenCacheFile() if err != nil { - log.Fatalf("Unable to get path to cached credential file. %v", err) + logrus.Fatalf("Unable to get path to cached credential file. %v", err) } tok, err := tokenFromFile(cacheFile) if err != nil { @@ -187,12 +210,12 @@ func getTokenFromWeb(config *oauth2.Config) *oauth2.Token { var code string if _, err := fmt.Scan(&code); err != nil { - log.Fatalf("Unable to read authorization code %v", err) + logrus.Fatalf("Unable to read authorization code %v", err) } tok, err := config.Exchange(oauth2.NoContext, code) if err != nil { - log.Fatalf("Unable to retrieve token from web %v", err) + logrus.Fatalf("Unable to retrieve token from web %v", err) } return tok } @@ -223,7 +246,7 @@ func saveToken(file string, token *oauth2.Token) { fmt.Printf("Saving credential file to: %s\n", file) f, err := os.OpenFile(file, os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0600) if err != nil { - log.Fatalf("Unable to cache oauth token: %v", err) + logrus.Fatalf("Unable to cache oauth token: %v", err) } defer f.Close() json.NewEncoder(f).Encode(token) @@ -238,13 +261,13 @@ type lilEvent struct { func (e *lilEvent) HasDate(d string) bool { if e.Start == d { - log.Printf("match for %s at %s", d, e.Start) + logrus.Debugf("match for %s at %s", d, e.Start) return true } dT, err := time.Parse(dateFmt, d) if err != nil { - log.Printf("ERROR: %v", err) + logrus.Error(err) return false } @@ -257,7 +280,7 @@ func (e *lilEvent) dateRange() []time.Time { for _, t := range []string{e.Start, e.End} { parsedDate, err := time.Parse(dateFmt, t) if err != nil { - log.Printf("ERROR: %v", err) + logrus.Error(err) ret = append(ret, time.Time{}) continue }