Initial Commit
This commit is contained in:
commit
a9d880a486
2
.gitignore
vendored
Normal file
2
.gitignore
vendored
Normal file
@ -0,0 +1,2 @@
|
||||
client_secret.json
|
||||
gocal
|
84
calclient.go
Normal file
84
calclient.go
Normal file
@ -0,0 +1,84 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"log"
|
||||
"net/http"
|
||||
|
||||
calendar "google.golang.org/api/calendar/v3"
|
||||
|
||||
"golang.org/x/oauth2"
|
||||
"golang.org/x/oauth2/google"
|
||||
)
|
||||
|
||||
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)
|
||||
}
|
||||
|
||||
c.tkn, err = c.cfg.Exchange(oauth2.NoContext, code)
|
||||
return err
|
||||
}
|
||||
|
||||
func (c *CalClient) TokenToRaw() {
|
||||
var tmpToken bytes.Buffer
|
||||
t := c.tkn
|
||||
json.NewEncoder(&tmpToken).Encode(t)
|
||||
c.rawToken = tmpToken.Bytes()
|
||||
}
|
135
main.go
Normal file
135
main.go
Normal file
@ -0,0 +1,135 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"os"
|
||||
"time"
|
||||
|
||||
calendar "google.golang.org/api/calendar/v3"
|
||||
|
||||
"github.com/br0xen/user-config"
|
||||
)
|
||||
|
||||
const (
|
||||
AppName = "gocal"
|
||||
AppVersion = 1
|
||||
)
|
||||
|
||||
type AppState struct {
|
||||
Name string
|
||||
Version int
|
||||
ClientSecret []byte
|
||||
cfg *userConfig.Config
|
||||
}
|
||||
|
||||
var state *AppState
|
||||
|
||||
func main() {
|
||||
var err error
|
||||
state = &AppState{Name: AppName, Version: AppVersion}
|
||||
state.cfg, err = userConfig.NewConfig(state.Name)
|
||||
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
for i := range os.Args {
|
||||
switch {
|
||||
case os.Args[i] == "--reinit":
|
||||
// Reset all config
|
||||
for _, v := range state.cfg.GetKeyList() {
|
||||
state.cfg.DeleteKey(v)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
DoVersionCheck()
|
||||
|
||||
sec := state.cfg.GetBytes("ClientSecret")
|
||||
tkn := state.cfg.GetBytes("Token")
|
||||
|
||||
c := CreateClient(sec, tkn)
|
||||
|
||||
c.TokenToRaw()
|
||||
state.cfg.SetBytes("Token", c.rawToken)
|
||||
|
||||
srv, err := calendar.New(c.client)
|
||||
|
||||
if err != nil {
|
||||
log.Fatalf("unable to retrieve calendar Client %v", err)
|
||||
}
|
||||
|
||||
listSvc := srv.CalendarList.List()
|
||||
list, err := listSvc.Do()
|
||||
if err != nil {
|
||||
log.Fatalf("unable to retrieve calendar list %v", err)
|
||||
}
|
||||
if len(list.Items) > 0 {
|
||||
for i := range list.Items {
|
||||
if list.Items[i].Deleted {
|
||||
// Deleted calendar, next please
|
||||
continue
|
||||
}
|
||||
fmt.Print("(" + list.Items[i].Id + ") ")
|
||||
fmt.Print(list.Items[i].Summary + "; ")
|
||||
fmt.Println(list.Items[i].Description)
|
||||
}
|
||||
} else {
|
||||
fmt.Printf("No calendars found.\n")
|
||||
}
|
||||
|
||||
fmt.Println("\n-====-\n")
|
||||
|
||||
t := time.Now().Format(time.RFC3339)
|
||||
events, err := srv.Events.List("primary").ShowDeleted(false).
|
||||
SingleEvents(true).TimeMin(t).MaxResults(10).OrderBy("startTime").Do()
|
||||
if err != nil {
|
||||
log.Fatalf("Unable to retrieve next ten of the user's events. %v", err)
|
||||
}
|
||||
|
||||
fmt.Println("Upcoming events:")
|
||||
if len(events.Items) > 0 {
|
||||
for _, i := range events.Items {
|
||||
var when string
|
||||
// If the DateTime is an empty string the Event is an all-day Event.
|
||||
// So only Date is available.
|
||||
if i.Start.DateTime != "" {
|
||||
when = i.Start.DateTime
|
||||
} else {
|
||||
when = i.Start.Date
|
||||
}
|
||||
fmt.Printf("%s (%s)\n", i.Summary, when)
|
||||
}
|
||||
} else {
|
||||
fmt.Printf("No upcoming events found.\n")
|
||||
}
|
||||
}
|
||||
|
||||
func DoVersionCheck() {
|
||||
confVer, _ := state.cfg.GetInt("version")
|
||||
for confVer < state.Version {
|
||||
// Update from confVer to state.Version
|
||||
switch confVer {
|
||||
case 0: // Initializing the app
|
||||
fmt.Println("Initializing gocal")
|
||||
for {
|
||||
fmt.Println("Client Secret Filename (Ctrl-C to exit): ")
|
||||
var fn string
|
||||
if _, err := fmt.Scan(&fn); err == nil {
|
||||
var b []byte
|
||||
b, err = ioutil.ReadFile(fn)
|
||||
if len(b) > 0 && err == nil {
|
||||
state.cfg.SetBytes("ClientSecret", b)
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
state.cfg.SetInt("version", 1)
|
||||
}
|
||||
state.ClientSecret = state.cfg.GetBytes("ClientSecret")
|
||||
// Refetch the version from the config
|
||||
confVer, _ = state.cfg.GetInt("version")
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user