Brian Buller
23b8a190ec
* Can toggle default calendars * Though the interactive screen doesn't update :( * Colorize default view depending on time until event
144 lines
3.0 KiB
Go
144 lines
3.0 KiB
Go
package main
|
|
|
|
import (
|
|
"bytes"
|
|
"context"
|
|
"encoding/json"
|
|
"errors"
|
|
"fmt"
|
|
"log"
|
|
"net/http"
|
|
"time"
|
|
|
|
"golang.org/x/oauth2"
|
|
"golang.org/x/oauth2/google"
|
|
|
|
calendar "google.golang.org/api/calendar/v3"
|
|
)
|
|
|
|
type Account struct {
|
|
CC *CalClient
|
|
Service *calendar.Service
|
|
CalendarList []Calendar
|
|
CalListUseBy time.Time
|
|
}
|
|
|
|
func GetAccount(secret, token []byte) (*Account, error) {
|
|
var err error
|
|
a := new(Account)
|
|
|
|
// Create the CalClient
|
|
a.CC = CreateClient(secret, token)
|
|
a.CC.TokenToRaw()
|
|
|
|
// Create the Calendar Service
|
|
a.Service, err = calendar.New(a.CC.client)
|
|
if err != nil {
|
|
return nil, errors.New("Unable to retrieve calendar Client: " + err.Error())
|
|
}
|
|
return a, nil
|
|
}
|
|
|
|
func (a *Account) GetTodaysEvents() []Event {
|
|
var ret []Event
|
|
|
|
return ret
|
|
}
|
|
|
|
func (a *Account) GetDefaultCalendar() *Calendar {
|
|
c, _ := a.Service.CalendarList.Get("primary").Do()
|
|
return GoogleCalendarToLocal(c)
|
|
}
|
|
|
|
func (a *Account) GetCalendarList() []Calendar {
|
|
if time.Now().Before(a.CalListUseBy) {
|
|
return a.CalendarList
|
|
}
|
|
var ret []Calendar
|
|
calList, err := a.Service.CalendarList.List().Do()
|
|
if err != nil {
|
|
return ret
|
|
}
|
|
for _, c := range calList.Items {
|
|
ret = append(ret, *GoogleCalendarToLocal(c))
|
|
}
|
|
a.CalendarList = ret
|
|
a.CalListUseBy = time.Now().Add(time.Hour * 6)
|
|
return ret
|
|
}
|
|
|
|
type CalClient struct {
|
|
rawClientSecret []byte
|
|
rawToken []byte
|
|
ctx context.Context
|
|
cfg *oauth2.Config
|
|
tkn *oauth2.Token
|
|
client *http.Client
|
|
}
|
|
|
|
func CreateClient(secret, tkn []byte) *CalClient {
|
|
var err error
|
|
c := CalClient{
|
|
rawClientSecret: []byte(secret),
|
|
rawToken: []byte(tkn),
|
|
}
|
|
|
|
c.ctx = context.Background()
|
|
c.cfg, err = google.ConfigFromJSON(c.rawClientSecret, calendar.CalendarScope)
|
|
|
|
if err != nil {
|
|
log.Fatalf("unable to parse client secret file to config: %v", err)
|
|
}
|
|
|
|
// Try to create the client with the passed token
|
|
c.client, err = c.GetClient()
|
|
if err != nil {
|
|
log.Fatalf("unable to create client: %v", err)
|
|
}
|
|
return &c
|
|
}
|
|
|
|
func (c *CalClient) GetClient() (*http.Client, error) {
|
|
err := c.tokenFromRaw()
|
|
if err != nil {
|
|
err = c.tokenFromWeb()
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
}
|
|
return c.cfg.Client(c.ctx, c.tkn), nil
|
|
}
|
|
|
|
func (c *CalClient) tokenFromRaw() error {
|
|
c.tkn = &oauth2.Token{}
|
|
tmpToken := bytes.NewBuffer(c.rawToken)
|
|
err := json.NewDecoder(tmpToken).Decode(c.tkn)
|
|
return err
|
|
}
|
|
|
|
func (c *CalClient) tokenFromWeb() error {
|
|
var err error
|
|
authURL := c.cfg.AuthCodeURL("state-token", oauth2.AccessTypeOffline)
|
|
fmt.Printf("Go to the following link in your browser then type the authorization code:\n%v\n", authURL)
|
|
var code string
|
|
if _, err := fmt.Scan(&code); err != nil {
|
|
log.Fatalf("Unable to read authorization code %v", err)
|
|
}
|
|
|
|
if c.tkn, err = c.cfg.Exchange(oauth2.NoContext, code); err == nil {
|
|
c.TokenToRaw()
|
|
}
|
|
return err
|
|
}
|
|
|
|
func (c *CalClient) TokenToRaw() {
|
|
var tmpToken bytes.Buffer
|
|
t := c.tkn
|
|
json.NewEncoder(&tmpToken).Encode(t)
|
|
c.rawToken = tmpToken.Bytes()
|
|
}
|
|
|
|
func (c *CalClient) GetRawToken() []byte {
|
|
return c.rawToken
|
|
}
|