From cbccac18e248e9c5a86c2f5ac03787cfa185f8cb Mon Sep 17 00:00:00 2001 From: xzebra Date: Tue, 9 Feb 2021 02:57:36 +0100 Subject: [PATCH 1/5] new semester constructor --- internal/semester/semester.go | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/internal/semester/semester.go b/internal/semester/semester.go index f58908d..d320256 100644 --- a/internal/semester/semester.go +++ b/internal/semester/semester.go @@ -1,6 +1,7 @@ package semester import ( + "encoding/json" "time" "github.com/xzebra/unizar-calendar/pkg/gcal" @@ -79,6 +80,12 @@ func NewSemester(cal *gcal.GoogleCalendar, number int) (semester *Semester, err return semester, nil } +func NewSemesterFromData(data []byte) (semester *Semester, err error) { + semester = &Semester{} + err = json.Unmarshal(data, semester) + return +} + type timeRange struct { Start, End time.Time } From a9d522bfd2e705ed549c90be2676e9cb6c3d3501 Mon Sep 17 00:00:00 2001 From: xzebra Date: Tue, 9 Feb 2021 02:57:54 +0100 Subject: [PATCH 2/5] merged data semester parameter --- internal/semester/merged.go | 15 ++------------- 1 file changed, 2 insertions(+), 13 deletions(-) diff --git a/internal/semester/merged.go b/internal/semester/merged.go index 531fa85..f4c23be 100644 --- a/internal/semester/merged.go +++ b/internal/semester/merged.go @@ -3,7 +3,6 @@ package semester import ( "fmt" - "github.com/xzebra/unizar-calendar/pkg/gcal" "github.com/xzebra/unizar-calendar/pkg/schedules" ) @@ -14,25 +13,15 @@ type Data struct { // Merged is an association between class ids and a list of all // days when the class should occur. - Merged map[string][]timeRange `json:"-"` + Merged map[string][]timeRange } -func NewData(files *schedules.SemesterFiles, number int) (*Data, error) { +func NewData(semester *Semester, files *schedules.SemesterFiles, number int) (*Data, error) { parsed, err := schedules.ParseSemesterFiles(files) if err != nil { return nil, err } - cal, err := gcal.NewGoogleCalendar() - if err != nil { - return nil, err - } - - semester, err := NewSemester(cal, number) - if err != nil { - return nil, err - } - s := &Data{ Semester: semester, Schedule: parsed.Schedule, From 321537b048c8786f8374130f241a97e55b00f24f Mon Sep 17 00:00:00 2001 From: xzebra Date: Tue, 9 Feb 2021 02:58:13 +0100 Subject: [PATCH 3/5] update uzcalendar to use only http request --- cmd/uzcalendar/main.go | 34 +++++++++++++++++++++++++++++++--- 1 file changed, 31 insertions(+), 3 deletions(-) diff --git a/cmd/uzcalendar/main.go b/cmd/uzcalendar/main.go index 08c66b5..1b0ed80 100644 --- a/cmd/uzcalendar/main.go +++ b/cmd/uzcalendar/main.go @@ -3,13 +3,16 @@ package main import ( "errors" "fmt" - "github.com/xzebra/unizar-calendar/internal/exports" - "github.com/xzebra/unizar-calendar/internal/semester" - "github.com/xzebra/unizar-calendar/pkg/schedules" + "io/ioutil" + "net/http" "os" "path/filepath" "strings" + "github.com/xzebra/unizar-calendar/internal/exports" + "github.com/xzebra/unizar-calendar/internal/semester" + "github.com/xzebra/unizar-calendar/pkg/schedules" + "flag" "log" ) @@ -18,6 +21,10 @@ var ( ErrInvalidSemester = errors.New("semester parameter invalid") ) +var ( + semesterDataURL = "https://xzebra.github.io/unizar-calendar/data/semester%d.json" +) + func cliUsage() { fmt.Fprintf(flag.CommandLine.Output(), "Usage: %s [options] subjectsFile scheduleFile\n\n", @@ -86,7 +93,18 @@ func main() { os.Exit(1) } + semesterData, err := getSemesterData(semesterNum) + if err != nil { + log.Fatal(err) + } + + sem, err := semester.NewSemesterFromData(semesterData) + if err != nil { + log.Fatal(err) + } + data, err := semester.NewData( + sem, &schedules.SemesterFiles{ Subjects: subjectsFile, Schedule: scheduleFile, @@ -107,3 +125,13 @@ func main() { log.Print(exports.Export(data, exportType)) } + +func getSemesterData(semesterNum int) ([]byte, error) { + resp, err := http.Get(fmt.Sprintf(semesterDataURL, semesterNum)) + if err != nil { + return nil, err + } + defer resp.Body.Close() + + return ioutil.ReadAll(resp.Body) +} From e73f96bd53e3f474bea35ad9359df5ea34172cf4 Mon Sep 17 00:00:00 2001 From: xzebra Date: Tue, 9 Feb 2021 02:58:24 +0100 Subject: [PATCH 4/5] get rid of token --- pkg/gcal/token.go | 67 ----------------------------------------------- 1 file changed, 67 deletions(-) delete mode 100644 pkg/gcal/token.go diff --git a/pkg/gcal/token.go b/pkg/gcal/token.go deleted file mode 100644 index e09b911..0000000 --- a/pkg/gcal/token.go +++ /dev/null @@ -1,67 +0,0 @@ -package gcal - -import ( - "encoding/json" - "fmt" - "log" - "net/http" - "os" - - "golang.org/x/net/context" - "golang.org/x/oauth2" -) - -// Retrieve a token, saves the token, then returns the generated client. -func getClient(config *oauth2.Config) *http.Client { - // The file token.json stores the user's access and refresh tokens, and is - // created automatically when the authorization flow completes for the first - // time. - tokFile := "token.json" - tok, err := tokenFromFile(tokFile) - if err != nil { - tok = getTokenFromWeb(config) - saveToken(tokFile, tok) - } - return config.Client(context.Background(), tok) -} - -// Request a token from the web, then returns the retrieved token. -func getTokenFromWeb(config *oauth2.Config) *oauth2.Token { - authURL := config.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 authCode string - if _, err := fmt.Scan(&authCode); err != nil { - log.Fatalf("Unable to read authorization code: %v", err) - } - - tok, err := config.Exchange(context.TODO(), authCode) - if err != nil { - log.Fatalf("Unable to retrieve token from web: %v", err) - } - return tok -} - -// Retrieves a token from a local file. -func tokenFromFile(file string) (*oauth2.Token, error) { - f, err := os.Open(file) - if err != nil { - return nil, err - } - defer f.Close() - tok := &oauth2.Token{} - err = json.NewDecoder(f).Decode(tok) - return tok, err -} - -// Saves a token to a file path. -func saveToken(path string, token *oauth2.Token) { - fmt.Printf("Saving credential file to: %s\n", path) - f, err := os.OpenFile(path, os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0600) - if err != nil { - log.Fatalf("Unable to cache oauth token: %v", err) - } - defer f.Close() - json.NewEncoder(f).Encode(token) -} From e741c6495cac9a844f0a58ceb73d0be9580293d0 Mon Sep 17 00:00:00 2001 From: xzebra Date: Tue, 9 Feb 2021 03:14:46 +0100 Subject: [PATCH 5/5] update README --- README.md | 37 +++++++++++++++---------------------- 1 file changed, 15 insertions(+), 22 deletions(-) diff --git a/README.md b/README.md index cb0b014..e3e3830 100644 --- a/README.md +++ b/README.md @@ -4,26 +4,6 @@ [![GoReportCard](https://goreportcard.com/badge/github.com/xzebra/unizar-calendar?.svg)](https://goreportcard.com/report/github.com/xzebra/unizar-calendar) [![Docs](https://godoc.org/github.com/xzebra/unizar-calendar?status.svg)](https://godoc.org/github.com/xzebra/unizar-calendar) -## Compile - -Compilation is automatic thanks to Go modules. That means you have to -enable modules support by setting the environment variable -`GO111MODULE=on`. - - go build - -## Setup - -First of all, go to [Google Calendar API site](https://developers.google.com/calendar/quickstart/go), create a new project -with the Calendar API enabled, and save the `credentials.json` file in -this project root folder. - -After that, compile and run the application. It will ask you to login -and paste the authorization code returned by Google. - -Once `token.json` and `credentials.json` are present in project root -folder, you are good to go. - ## Usage You can interact with the CLI by running the executable from a @@ -32,11 +12,24 @@ flag `-h`. $ ./unizar-calendar -h +## Compile + +Compilation is automatic thanks to Go modules. That means you have to +enable modules support by setting the environment variable +`GO111MODULE=on`. + + go build ## Requirements - Go 1.14 (or higher). - Go modules enabled. -- Project with Google Calendar API enabled. -- `credentials.json` and `token.json` generated. + +If you are going to use the `webdata` module or `pkg/gcal`, you need +the following: +- Project with [Google Calendar API site](https://developers.google.com/calendar/quickstart/go) enabled. +- Create a Service Account. +- Download JSON credentials of Service Account. +- Set the path to the JSON file in the + `GOOGLE_APPLICATION_CREDENTIALS` environment variable.