diff --git a/.gitignore b/.gitignore index e2666a8..7f519b2 100644 --- a/.gitignore +++ b/.gitignore @@ -2,3 +2,4 @@ *.database .env pigil +todo.md \ No newline at end of file diff --git a/go.mod b/go.mod index b0d7243..f0d4d94 100644 --- a/go.mod +++ b/go.mod @@ -7,10 +7,10 @@ require ( github.com/joho/godotenv v1.4.0 go.etcd.io/bbolt v1.3.6 golang.org/x/oauth2 v0.0.0-20220608161450-d0670ef3b1eb + google.golang.org/api v0.84.0 ) require ( - cloud.google.com/go v0.100.2 // indirect cloud.google.com/go/compute v1.6.1 // indirect github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect github.com/golang/protobuf v1.5.2 // indirect @@ -22,7 +22,6 @@ require ( golang.org/x/net v0.0.0-20220607020251-c690dde0001d // indirect golang.org/x/sys v0.0.0-20220614162138-6c1b26c55098 // indirect golang.org/x/text v0.3.7 // indirect - google.golang.org/api v0.84.0 // indirect google.golang.org/appengine v1.6.7 // indirect google.golang.org/genproto v0.0.0-20220614165028-45ed7f3ff16e // indirect google.golang.org/grpc v1.47.0 // indirect diff --git a/go.sum b/go.sum index 602eea8..49d2c3c 100644 --- a/go.sum +++ b/go.sum @@ -12,7 +12,6 @@ cloud.google.com/go v0.54.0/go.mod h1:1rq2OEkV3YMf6n/9ZvGWI3GWw0VoqH/1x2nd8Is/bP cloud.google.com/go v0.56.0/go.mod h1:jr7tqZxxKOVYizybht9+26Z/gUq7tiRzu+ACVAMbKVk= cloud.google.com/go v0.57.0/go.mod h1:oXiQ6Rzq3RAkkY7N6t3TcE6jE+CIBBbA36lwQ1JyzZs= cloud.google.com/go v0.62.0/go.mod h1:jmCYTdRCQuc1PHIIJ/maLInMho30T/Y0M4hTdTShOYc= -cloud.google.com/go v0.65.0 h1:Dg9iHVQfrhq82rUNu9ZxUDrJLaxFUe/HlCVaLyRruq8= cloud.google.com/go v0.65.0/go.mod h1:O5N8zS7uWy9vkA9vayVHs65eM1ubvY4h553ofrNHObY= cloud.google.com/go v0.72.0/go.mod h1:M+5Vjvlc2wnp6tjzE102Dw08nGShTscUx2nZMufOKPI= cloud.google.com/go v0.74.0/go.mod h1:VV1xSbzvo+9QJOxLDaJfTjx5e+MePCpCWwvftOeQmWk= @@ -117,7 +116,6 @@ github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrU github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8= -github.com/golang/protobuf v1.4.2 h1:+Z5KGCizgyZCbGh1KZqA0fcLLkwbsjIzS4aV2v7wJX0= github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= @@ -133,7 +131,6 @@ github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMyw github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.4.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.1 h1:JFrFEBb2xKufg6XkJsJr+WbKb4FQlURi5RUcBveYu9k= github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= @@ -297,7 +294,6 @@ golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v golang.org/x/net v0.0.0-20210316092652-d523dce5a7f4/go.mod h1:RBQZq4jEuRlivfhVLdyRGr576XBO4/greRjx4P4O3yc= golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= golang.org/x/net v0.0.0-20210503060351-7fd8e65b6420/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd h1:O7DYs+zxREGLKzKoMQrtrEacpb0ZVXA5rIwylE2Xchk= golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/net v0.0.0-20220325170049-de3da57026de/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= @@ -387,7 +383,6 @@ golang.org/x/sys v0.0.0-20210823070655-63515b42dcdf/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20210908233432-aa78b53d3365/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211124211545-fe61309f8881/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211210111614-af8b64212486/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e h1:fLOSk5Q00efkSvAm+4xcoXD+RRmLmmulPn5I3Y9F2EM= golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220128215802-99c3d69c2c27/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220209214540-3681064d5158/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= @@ -468,7 +463,6 @@ golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20220411194840-2f41105eb62f/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20220609144429-65e65417b02f h1:uF6paiQQebLeSXkrTqHqz0MXhXXS1KgF41eUdBNvxK0= @@ -517,7 +511,6 @@ google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7 google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0= google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= -google.golang.org/appengine v1.6.6 h1:lMO5rYAqUxkmaj76jAkRUvt5JZgFymx/+Q5Mzfivuhc= google.golang.org/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= google.golang.org/appengine v1.6.7 h1:FZR1q0exgwxzPzp/aF+VccGrSfxfPpkBqjIIEq3ru6c= google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= @@ -638,7 +631,6 @@ google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2 google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4= -google.golang.org/protobuf v1.25.0 h1:Ejskq+SyPohKW+1uil0JJMtmHCgJPJ/qWTxr8qp+R4c= google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= diff --git a/handlers.go b/handlers.go index 2266d55..1145eae 100644 --- a/handlers.go +++ b/handlers.go @@ -4,25 +4,30 @@ import ( "context" "fmt" "golang.org/x/oauth2" - "log" "pigil/internal/database" service2 "pigil/internal/service" "pigil/internal/types" "pigil/internal/utils" ) +const handlerTag = "handlers" + func InsertCommand(service database.Service, information types.CommandInformation) { err := service.Insert(information) if err != nil { - log.Fatal(err.Error()) + utils.ErrorLogger(err, handlerTag) } } func ListCommand(service database.Service) { data, err := service.List() if err != nil { - log.Fatal(err.Error()) + utils.ErrorLogger(err, handlerTag) + } + if len(*data) == 0 { + utils.InformationLogger("No history found yet!") + return } utils.PrintInformation(data) } @@ -30,10 +35,11 @@ func ListCommand(service database.Service) { func GoogleAuth(service database.Service) { email, err := service.GetConfig(utils.UserEmail) if err != nil { - log.Fatal(err.Error()) + utils.ErrorLogger(err, handlerTag) } if email != "" { - fmt.Printf("already logged in with %s\n", email) + utils.InformationLogger(fmt.Sprintf("already logged in with %s\n", + email)) return } config := service2.OAuthGoogleConfig() @@ -54,49 +60,52 @@ func GoogleAuth(service database.Service) { err = service.InsertConfig(userEmail) if err != nil { - log.Fatal(err.Error()) + utils.ErrorLogger(err, handlerTag) } err = service.InsertConfig(userRT) if err != nil { - log.Fatal(err.Error()) + utils.ErrorLogger(err, handlerTag) } err = service.InsertConfig(userAT) if err != nil { - log.Fatal(err.Error()) + utils.ErrorLogger(err, handlerTag) } } func Status(service database.Service) { list, err := service.ListConfig() if err != nil { - log.Fatal(err.Error()) + utils.ErrorLogger(err, handlerTag) + } + if len(*list) == 0 { + utils.InformationLogger("No settings found yet!") + return } - fmt.Println(list) + utils.StatusPrinter(list) } func Logout(service database.Service) { err := service.DeleteConfigDb() if err != nil { - log.Fatal(err.Error()) + utils.ErrorLogger(err, handlerTag) } } func Notify(service database.Service) { email, err := service.GetConfig(utils.UserEmail) if err != nil { - log.Fatal(err.Error()) + utils.ErrorLogger(err, handlerTag) } if email == "" { - fmt.Println("not authenticated") + utils.ErrorInformation("You are not authenticated! Pigil cannot" + + " notify via email, please run `pigil bumf auth`") + return } at, err := service.GetConfig(utils.UserAT) if err != nil { - log.Fatal(err.Error()) - } - if email == "" { - fmt.Println("not authenticated") + utils.ErrorLogger(err, handlerTag) } - creds := oauth2.Token{AccessToken: at} - client := service2.OAuthGoogleConfig().Client(context.Background(), &creds) + cred := oauth2.Token{AccessToken: at} + client := service2.OAuthGoogleConfig().Client(context.Background(), &cred) service2.SendEmail(client, email) } diff --git a/internal/service/emailer.go b/internal/service/emailer.go index a545f34..e8952f9 100644 --- a/internal/service/emailer.go +++ b/internal/service/emailer.go @@ -5,19 +5,21 @@ import ( "encoding/base64" "google.golang.org/api/gmail/v1" "google.golang.org/api/option" - "log" "net/http" + "pigil/internal/utils" ) +const mailerTag = "mailer" + func SendEmail(client *http.Client, email string) { srv, err := gmail.NewService(context.Background(), option.WithHTTPClient(client)) if err != nil { - log.Fatal(err.Error()) + utils.ErrorLogger(err, mailerTag) } emailBody := "This is an test email from pigil!" if err != nil { - log.Fatal(err.Error()) + utils.ErrorLogger(err, mailerTag) } var message gmail.Message @@ -30,6 +32,6 @@ func SendEmail(client *http.Client, email string) { message.Raw = base64.URLEncoding.EncodeToString(msg) _, err = srv.Users.Messages.Send("me", &message).Do() if err != nil { - log.Fatal(err.Error()) + utils.ErrorLogger(err, mailerTag) } } diff --git a/internal/service/oauth2.go b/internal/service/oauth2.go index 045b4c1..41fb280 100644 --- a/internal/service/oauth2.go +++ b/internal/service/oauth2.go @@ -6,12 +6,14 @@ import ( "fmt" "golang.org/x/oauth2" "golang.org/x/oauth2/google" - "log" "net/http" "os" "pigil/internal/types" + "pigil/internal/utils" ) +const oauthTag = "oauth2" + func OAuthGoogleConfig() *oauth2.Config { return &oauth2.Config{ RedirectURL: "http://localhost:6969", @@ -38,13 +40,13 @@ func GoogleCallback(config *oauth2.Config) types.UserInformation { http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { err := r.ParseForm() if err != nil { - fmt.Fprintf(os.Stdout, "could not parse query: %v", err) + utils.ErrorLogger(err, oauthTag) w.WriteHeader(http.StatusBadRequest) } code := r.FormValue("code") token, err := config.Exchange(context.Background(), code) if err != nil { - log.Fatal("could not rec", err.Error()) + utils.ErrorLogger(err, oauthTag) } fmt.Println(token.AccessToken) w.WriteHeader(http.StatusCreated) @@ -52,16 +54,16 @@ func GoogleCallback(config *oauth2.Config) types.UserInformation { "Your email has been linked via pigil! You can close this webpage"+ " now!") if err != nil { - log.Fatal(err.Error()) + utils.ErrorLogger(err, oauthTag) } resp, err := http.Get("https://www.googleapis.com/oauth2/v2/userinfo?access_token=" + token.AccessToken) if err != nil { - log.Fatal(err.Error()) + utils.ErrorLogger(err, oauthTag) } googleResponse := types.GoogleResponse{} err = json.NewDecoder(resp.Body).Decode(&googleResponse) if err != nil { - log.Fatal(err.Error()) + utils.ErrorLogger(err, oauthTag) } userData = types.UserInformation{ Name: googleResponse.GivenName + " " + googleResponse.FamilyName, @@ -72,13 +74,13 @@ func GoogleCallback(config *oauth2.Config) types.UserInformation { go func() { err = server.Shutdown(context.Background()) if err != nil { - log.Fatal("ono", err.Error()) + utils.ErrorLogger(err, oauthTag) } }() }) err := server.ListenAndServe() if err != nil && err != http.ErrServerClosed { - log.Fatal(err.Error(), "ggwp") + utils.ErrorLogger(err, oauthTag) } return userData } diff --git a/internal/utils/logger.go b/internal/utils/logger.go new file mode 100644 index 0000000..ed7ee4c --- /dev/null +++ b/internal/utils/logger.go @@ -0,0 +1,26 @@ +package utils + +import ( + "log" + "os" +) + +const ( + Red = "\033[31m" + Reset = "\033[0m" + Green = "\033[32m" + Yellow = "\033[33m" +) + +func ErrorLogger(err error, place string) { + log.Printf("%spigil error (%s) : %s%s\n", Red, place, err.Error(), Reset) + os.Exit(1) +} + +func ErrorInformation(information string) { + log.Printf("%spigil: %s%s\n", Red, information, Reset) +} + +func InformationLogger(information string) { + log.Printf("%spigil information: %s%s\n", Yellow, information, Reset) +} diff --git a/internal/utils/printer.go b/internal/utils/printer.go index 7149669..965d686 100644 --- a/internal/utils/printer.go +++ b/internal/utils/printer.go @@ -1,6 +1,7 @@ package utils import ( + "fmt" "github.com/jedib0t/go-pretty/v6/table" "os" "pigil/internal/types" @@ -22,3 +23,20 @@ func PrintInformation(data *[]types.CommandInformation) { } t.Render() } + +func GreenPrinter(information string) { + fmt.Printf("%s%s%s\n", Green, information, Reset) +} + +func StatusPrinter(data *[]types.ConfigurationInformation) { + t := table.NewWriter() + t.SetOutputMirror(os.Stdout) + t.AppendHeader(table.Row{"Setting Name", "Value"}) + t.SetAutoIndex(true) + for _, items := range *data { + if items.Key != UserAT && items.Key != UserRT { + t.AppendRow(table.Row{items.Key, items.Value}) + } + } + t.Render() +} diff --git a/main.go b/main.go index 1463c3a..3381345 100644 --- a/main.go +++ b/main.go @@ -1,11 +1,11 @@ package main import ( + "errors" "fmt" "github.com/joho/godotenv" bolt "go.etcd.io/bbolt" "io" - "log" "os" "os/exec" "pigil/internal/database" @@ -14,16 +14,18 @@ import ( "time" ) +const mainTag = "main" + func main() { db, err := bolt.Open(utils.DatabaseName, 0666, nil) if err != nil { - log.Fatal(err.Error()) + utils.ErrorLogger(err, mainTag) } err = godotenv.Load() if err != nil { - log.Fatal("Error loading .env file") + utils.ErrorLogger(errors.New("cannot load .env file"), mainTag) } boltLocalDb := database.NewBoltDbService(db, utils.LocalBucket) boltConfigDb := database.NewBoltDbService(db, utils.ConfigBucket) @@ -57,11 +59,11 @@ func executor(args []string, service database.Service) { stderr, err := cmd.StderrPipe() stdout, err := cmd.StdoutPipe() if err != nil { - log.Println("stderr fails") + utils.ErrorInformation("stderr pipe broke") } start := time.Now() if err := cmd.Start(); err != nil { - log.Fatal("pigil info:", err) + utils.ErrorLogger(err, mainTag) } ci := types.CommandInformation{ CommandName: args[1], @@ -71,16 +73,16 @@ func executor(args []string, service database.Service) { } results, _ := io.ReadAll(stdout) fmt.Printf("%s", results) - errors, _ := io.ReadAll(stderr) - fmt.Printf("%s", errors) + errorOutput, _ := io.ReadAll(stderr) + fmt.Printf("%s", errorOutput) if err := cmd.Wait(); err != nil { ci.WasSuccessful = false Notify(service) - //log.Fatal(err.Error()) + utils.ErrorInformation(err.Error()) } end := time.Now() life := end.Sub(start) - fmt.Printf("runtime: %f seconds\n", life.Seconds()) + utils.GreenPrinter(fmt.Sprintf("runtime: %f seconds", life.Seconds())) ci.ExecutionTime = life.Seconds() InsertCommand(service, ci) }