Skip to content

Commit

Permalink
Add weekly and daily commands
Browse files Browse the repository at this point in the history
  • Loading branch information
charlieegan3 committed Jul 3, 2021
1 parent 08b0836 commit c4be7c7
Show file tree
Hide file tree
Showing 9 changed files with 238 additions and 52 deletions.
51 changes: 51 additions & 0 deletions cmd/day.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
package cmd

import (
"log"
"time"

psh "github.com/gregdel/pushover"
air "github.com/mehanizm/airtable"
"github.com/spf13/cobra"

"github.com/charlieegan3/airtable-contacts/pkg/airtable"
"github.com/charlieegan3/airtable-contacts/pkg/pushover"
"github.com/charlieegan3/airtable-contacts/pkg/specialdays"
"github.com/spf13/viper"
)

var dayCmd = &cobra.Command{
Use: "day",
Short: "send events for current day",
Run: func(cmd *cobra.Command, args []string) {
// get the latest data
airtableClient := air.NewClient(viper.GetString("airtable.key"))
records, err := airtable.Download(
airtableClient,
viper.GetString("airtable.base"),
viper.GetString("airtable.table"),
viper.GetString("airtable.view"),
)
if err != nil {
log.Fatalf("failed to download contacts: %s", err)
}

// set the notification period
periodStart := time.Date(time.Now().Year(), time.Now().Month(), time.Now().Day(), 0, 0, 0, 0, time.UTC)
alert, title, message, err := specialdays.Generate(records, periodStart, 1)
if err != nil {
log.Fatalf("failed to generate alert message: %s", err)
}

// send the alert if needed
if alert {
pushoverRecipient := psh.NewRecipient(viper.GetString("pushover.user_key"))
pushoverApp := psh.New(viper.GetString("pushover.app_token"))
pushover.Notify(pushoverApp, pushoverRecipient, title, message)
}
},
}

func init() {
notifyCmd.AddCommand(dayCmd)
}
19 changes: 19 additions & 0 deletions cmd/notify.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package cmd

import (
"fmt"

"github.com/spf13/cobra"
)

var notifyCmd = &cobra.Command{
Use: "notify",
Short: "send alerts for events related to contacts",
Run: func(cmd *cobra.Command, args []string) {
fmt.Println("notify called")
},
}

func init() {
rootCmd.AddCommand(notifyCmd)
}
3 changes: 3 additions & 0 deletions cmd/sync.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ var syncCmd = &cobra.Command{
Use: "sync",
Short: "download data from airtable and upload to dropbox",
Run: func(cmd *cobra.Command, args []string) {
// get the latest data
airtableClient := air.NewClient(viper.GetString("airtable.key"))
records, err := airtable.Download(
airtableClient,
Expand All @@ -46,13 +47,15 @@ var syncCmd = &cobra.Command{
log.Fatalf("failed to download contacts: %s", err)
}

// generate vcard for upload
vcardString, err := vcard.Generate(records, viper.GetInt("vcard.photo.size"))

err = os.WriteFile("out.vcard", []byte(vcardString), 0644)
if err != nil {
log.Fatal(err)
}

// store in dropbox for sync
dropboxClient := files.New(dbx.Config{
Token: viper.GetString("dropbox.token"),
LogLevel: dbx.LogOff,
Expand Down
52 changes: 52 additions & 0 deletions cmd/week.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
package cmd

import (
"log"
"time"

"github.com/charlieegan3/airtable-contacts/pkg/airtable"
"github.com/charlieegan3/airtable-contacts/pkg/pushover"
"github.com/charlieegan3/airtable-contacts/pkg/specialdays"
psh "github.com/gregdel/pushover"
air "github.com/mehanizm/airtable"
"github.com/spf13/cobra"
"github.com/spf13/viper"
)

var weekCmd = &cobra.Command{
Use: "week",
Short: "send events for the current week",
Run: func(cmd *cobra.Command, args []string) {
// get the latest data
airtableClient := air.NewClient(viper.GetString("airtable.key"))
records, err := airtable.Download(
airtableClient,
viper.GetString("airtable.base"),
viper.GetString("airtable.table"),
viper.GetString("airtable.view"),
)
if err != nil {
log.Fatalf("failed to download contacts: %s", err)
}

// set the notification period
periodStart := time.Date(time.Now().Year(), time.Now().Month(), time.Now().Day(), 0, 0, 0, 0, time.UTC)
alert, title, message, err := specialdays.Generate(records, periodStart, 14)
if err != nil {
log.Fatalf("failed to generate alert message: %s", err)
}

// send the alert if needed
pushoverRecipient := psh.NewRecipient(viper.GetString("pushover.user_key"))
pushoverApp := psh.New(viper.GetString("pushover.app_token"))
if alert {
pushover.Notify(pushoverApp, pushoverRecipient, title, message)
} else {
pushover.Notify(pushoverApp, pushoverRecipient, "No Events", "There are no events in the next two weeks")
}
},
}

func init() {
notifyCmd.AddCommand(weekCmd)
}
2 changes: 2 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,15 @@ go 1.16
require (
github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883 // indirect
github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6 // indirect
github.com/charlieegan3/special-days v0.0.0-20210701231319-175bc74510e3 // indirect
github.com/coreos/go-etcd v2.0.0+incompatible // indirect
github.com/cpuguy83/go-md2man v1.0.10 // indirect
github.com/d4l3k/messagediff v1.2.1 // indirect
github.com/disintegration/imaging v1.6.2 // indirect
github.com/dropbox/dropbox-sdk-go-unofficial/v6 v6.0.1 // indirect
github.com/emersion/go-vcard v0.0.0-20210521075357-3445b9171995 // indirect
github.com/fsnotify/fsnotify v1.4.7 // indirect
github.com/gregdel/pushover v1.1.0 // indirect
github.com/mehanizm/airtable v0.2.4 // indirect
github.com/sergi/go-diff v1.2.0 // indirect
github.com/spf13/cobra v1.1.3 // indirect
Expand Down
6 changes: 6 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,8 @@ github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kB
github.com/bketelsen/crypt v0.0.3-0.20200106085610-5cbc8cc4026c/go.mod h1:MKsuJmJgSg28kpZDP6UIiPt0e0Oz0kqKNGyRaWEPv84=
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc=
github.com/charlieegan3/special-days v0.0.0-20210701231319-175bc74510e3 h1:8QwBaAB9UJ+Br7K15qN1veIG8RKiguoz99LUQWxwQKw=
github.com/charlieegan3/special-days v0.0.0-20210701231319-175bc74510e3/go.mod h1:n8HAe2Qma8/hBTJecDNnyZ8h21Zi9EwGHteN6/hEi+g=
github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI=
github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI=
github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=
Expand Down Expand Up @@ -140,6 +142,8 @@ github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+
github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk=
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
github.com/gregdel/pushover v1.1.0 h1:dwHyvrcpZCOS9V1fAnKPaGRRI5OC55cVaKhMybqNsKQ=
github.com/gregdel/pushover v1.1.0/go.mod h1:EcaO66Nn1StkpEm1iKtBTV3d2A16SoMsVER1PthX7to=
github.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs=
github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk=
github.com/grpc-ecosystem/grpc-gateway v1.9.0/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY=
Expand Down Expand Up @@ -254,6 +258,8 @@ github.com/subosito/gotenv v1.2.0 h1:Slr1R9HxAlEKefgq5jn9U+DnETlIUa6HfgEzj0g5d7s
github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw=
github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0=
github.com/vjeantet/eastertime v1.0.0 h1:1jKWtfYLmSzl+aA4Oxz3arR8xy/2QDkJ1oxMtZimNZc=
github.com/vjeantet/eastertime v1.0.0/go.mod h1:oyhoGGL+4Xkm1kcuSRx/Cncj4UCur/fg7nd9MEJbAto=
github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU=
github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q=
github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
Expand Down
18 changes: 18 additions & 0 deletions pkg/pushover/notify.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package pushover

import (
"fmt"

"github.com/gregdel/pushover"
psh "github.com/gregdel/pushover"
)

func Notify(app *psh.Pushover, recipient *psh.Recipient, title, body string) error {
message := pushover.NewMessageWithTitle(body, title)

_, err := app.SendMessage(message, recipient)
if err != nil {
return fmt.Errorf("failed to send pushover notification: %s", err)
}
return nil
}
22 changes: 19 additions & 3 deletions pkg/specialdays/specialdays.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@ import (
"fmt"
"strings"
"time"

"github.com/charlieegan3/special-days/pkg/fathersday"
"github.com/charlieegan3/special-days/pkg/motheringsunday"
)

func Generate(contacts []map[string]interface{}, checkDate time.Time, period int) (bool, string, string, error) {
Expand Down Expand Up @@ -49,9 +52,22 @@ func Generate(contacts []map[string]interface{}, checkDate time.Time, period int
return false, "", "", fmt.Errorf("failed to parse JSON Special Days value for: %v", contact)
}
for _, day := range days {
date, err := time.Parse("2006-01-02", day.Date)
if err != nil {
return false, "", "", fmt.Errorf("failed to parse special day date value for: %v", contact)
var date time.Time
if day.Date == "fathers-day-uk" {
date, err = fathersday.FathersDay("uk", periodStart.Year())
if err != nil {
return false, "", "", fmt.Errorf("failed to get fathers day for: %v, %s", contact, err)
}
} else if day.Date == "mothering-sunday" {
date, err = motheringsunday.MotheringSunday(periodStart.Year())
if err != nil {
return false, "", "", fmt.Errorf("failed to get mothering sunday for: %v, %s", contact, err)
}
} else {
date, err = time.Parse("2006-01-02", day.Date)
if err != nil {
return false, "", "", fmt.Errorf("failed to parse special day date value for: %v, %s", contact, err)
}
}

dateThisYear := time.Date(time.Now().UTC().Year(), date.Month(), date.Day(), 0, 0, 0, 0, time.UTC)
Expand Down
117 changes: 68 additions & 49 deletions pkg/specialdays/specialdays_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,55 @@ import (
"time"
)

func TestDateInPeriod(t *testing.T) {
testCases := []struct {
PeriodStart time.Time
PeriodEnd time.Time
Date time.Time
Result bool
}{
{
PeriodStart: time.Date(2021, time.March, 21, 0, 0, 0, 0, time.UTC),
PeriodEnd: time.Date(2021, time.March, 23, 0, 0, 0, 0, time.UTC),
Date: time.Date(2021, time.March, 22, 0, 0, 0, 0, time.UTC),
Result: true,
},
{
PeriodStart: time.Date(2021, time.March, 21, 0, 0, 0, 0, time.UTC),
PeriodEnd: time.Date(2021, time.March, 21, 0, 0, 0, 0, time.UTC),
Date: time.Date(2021, time.March, 21, 0, 0, 0, 0, time.UTC),
Result: true,
},
{
PeriodStart: time.Date(2021, time.March, 21, 0, 0, 0, 0, time.UTC),
PeriodEnd: time.Date(2021, time.March, 23, 0, 0, 0, 0, time.UTC),
Date: time.Date(2021, time.March, 23, 0, 0, 0, 0, time.UTC),
Result: true,
},
{
PeriodStart: time.Date(2021, time.March, 21, 0, 0, 0, 0, time.UTC),
PeriodEnd: time.Date(2021, time.March, 23, 0, 0, 0, 0, time.UTC),
Date: time.Date(2021, time.March, 24, 0, 0, 0, 0, time.UTC),
Result: false,
},
{
PeriodStart: time.Date(2021, time.March, 21, 0, 0, 0, 0, time.UTC),
PeriodEnd: time.Date(2021, time.March, 23, 0, 0, 0, 0, time.UTC),
Date: time.Date(2021, time.March, 20, 0, 0, 0, 0, time.UTC),
Result: false,
},
}

for i, test := range testCases {
t.Run(fmt.Sprintf("%d", i), func(t *testing.T) {
result := dateInPeriod(test.PeriodStart, test.PeriodEnd, test.Date)
if result != test.Result {
t.Fatalf("unexpected result: %v", result)
}
})
}
}

func TestGenerate(t *testing.T) {
testCases := []struct {
Description string
Expand Down Expand Up @@ -140,6 +189,25 @@ func TestGenerate(t *testing.T) {
ExpectedTitle: "John & Jane have special days",
ExpectedBody: `* John has a special day labelled 'aniversary'
* Jane has a special day labelled 'other'`,
},
{
Description: "it alerts on named special days",
Contacts: []map[string]interface{}{
{
"Display Name": "John",
"JSON Special Days": `[{ "date": "fathers-day-uk", "label": "fathers-day-uk"}]`,
},
{
"Display Name": "Jane",
"JSON Special Days": `[{ "date": "mothering-sunday", "label": "mothering-sunday"}]`,
},
},
CheckDate: time.Date(2021, time.March, 1, 0, 0, 0, 0, time.UTC),
Period: 200, // just a big period to catch and test the above
Alert: true,
ExpectedTitle: "John & Jane have special days",
ExpectedBody: `* John has a special day labelled 'fathers-day-uk'
* Jane has a special day labelled 'mothering-sunday'`,
},
{
Description: "it alerts on birthdays and special days",
Expand Down Expand Up @@ -209,52 +277,3 @@ func TestGenerate(t *testing.T) {
})
}
}

func TestDateInPeriod(t *testing.T) {
testCases := []struct {
PeriodStart time.Time
PeriodEnd time.Time
Date time.Time
Result bool
}{
{
PeriodStart: time.Date(2021, time.March, 21, 0, 0, 0, 0, time.UTC),
PeriodEnd: time.Date(2021, time.March, 23, 0, 0, 0, 0, time.UTC),
Date: time.Date(2021, time.March, 22, 0, 0, 0, 0, time.UTC),
Result: true,
},
{
PeriodStart: time.Date(2021, time.March, 21, 0, 0, 0, 0, time.UTC),
PeriodEnd: time.Date(2021, time.March, 21, 0, 0, 0, 0, time.UTC),
Date: time.Date(2021, time.March, 21, 0, 0, 0, 0, time.UTC),
Result: true,
},
{
PeriodStart: time.Date(2021, time.March, 21, 0, 0, 0, 0, time.UTC),
PeriodEnd: time.Date(2021, time.March, 23, 0, 0, 0, 0, time.UTC),
Date: time.Date(2021, time.March, 23, 0, 0, 0, 0, time.UTC),
Result: true,
},
{
PeriodStart: time.Date(2021, time.March, 21, 0, 0, 0, 0, time.UTC),
PeriodEnd: time.Date(2021, time.March, 23, 0, 0, 0, 0, time.UTC),
Date: time.Date(2021, time.March, 24, 0, 0, 0, 0, time.UTC),
Result: false,
},
{
PeriodStart: time.Date(2021, time.March, 21, 0, 0, 0, 0, time.UTC),
PeriodEnd: time.Date(2021, time.March, 23, 0, 0, 0, 0, time.UTC),
Date: time.Date(2021, time.March, 20, 0, 0, 0, 0, time.UTC),
Result: false,
},
}

for i, test := range testCases {
t.Run(fmt.Sprintf("%d", i), func(t *testing.T) {
result := dateInPeriod(test.PeriodStart, test.PeriodEnd, test.Date)
if result != test.Result {
t.Fatalf("unexpected result: %v", result)
}
})
}
}

0 comments on commit c4be7c7

Please sign in to comment.