diff --git a/.config/default.toml b/.config/default.toml index 7cb8e56..f69283e 100644 --- a/.config/default.toml +++ b/.config/default.toml @@ -13,6 +13,9 @@ [google] [google.alias] +[googleworkspace] + [googleworkspace.alias] + [youtube] [youtube.alias] diff --git a/README.md b/README.md index 6ea6bde..c45fce8 100644 --- a/README.md +++ b/README.md @@ -36,6 +36,7 @@ - [GCP](#gcp) - [Github](#github) - [Google](#google) + - [GoogleWorkspace](#googleworkspace) - [Pagerduty](#pagerduty) - [Youtube](#youtube) - [(Advanced): Docker image](#advanced-docker-image) @@ -382,6 +383,29 @@ $ biko g s -q "How to configure biko" Blazing fast. +### Google Workspace + +* Open Google Workspace search from your terminal. + +``` +$ biko googleworkspace [product] [flag(s)] +# or +$ biko gw [product] [flag(s)] +``` + +| Product | What | Command | Flags(Optional) | +| :----: | :----: | :----: | :----: | +| drive | Search on Google Drive | `drive`, `dr` | `--query, -q` | +| document | Search on Google Docs | `document`, `doc` | `--query, -q` | +| document | Create a new Google Docs | `document`, `doc` | `--new, -n` | +| spreadsheets | Search on Google Sheets | `spreadsheets`, `ss` | `--query, -q` | +| spreadsheets | Create a new Google Sheets | `spreadsheets`, `ss` | `--new, -n` | +| presentation | Search on Google Slides | `presentation`, `pr` | `--query, -q` | +| presentation | Create a new Google Slides | `presentation`, `pr` | `--new, -n` | +| forms | Search on Google Forms | `forms`, `fm` | `--query, -q` | +| forms | Create a new Google Forms | `forms`, `fm` | `--new, -n` | + + ### Pagerduty * If you are using SSO, you need to pass `--org` or configure `BIKO_PAGERDUTY` diff --git a/alias/alias.go b/alias/alias.go index 9edd1a7..02a02e2 100644 --- a/alias/alias.go +++ b/alias/alias.go @@ -27,17 +27,18 @@ var ( // TomlConfig ... type TomlConfig struct { - AWS map[string]interface{} `toml:"aws"` - Azure map[string]interface{} `toml:"azure"` - GCP map[string]interface{} `toml:"gcp"` - Datadog map[string]interface{} `toml:"datadog"` - Google map[string]interface{} `toml:"google"` - Youtube map[string]interface{} `toml:"youtube"` - PagerDuty map[string]interface{} `toml:"pagerduty"` - Github map[string]interface{} `toml:"github"` - CircleCI map[string]interface{} `toml:"circleci"` - Firebase map[string]interface{} `toml:"firebase"` - JIRA map[string]interface{} `toml:"jira"` + AWS map[string]interface{} `toml:"aws"` + Azure map[string]interface{} `toml:"azure"` + GCP map[string]interface{} `toml:"gcp"` + Datadog map[string]interface{} `toml:"datadog"` + Google map[string]interface{} `toml:"google"` + GoogleWorkspace map[string]interface{} `toml:"googleworkspace"` + Youtube map[string]interface{} `toml:"youtube"` + PagerDuty map[string]interface{} `toml:"pagerduty"` + Github map[string]interface{} `toml:"github"` + CircleCI map[string]interface{} `toml:"circleci"` + Firebase map[string]interface{} `toml:"firebase"` + JIRA map[string]interface{} `toml:"jira"` } // GetConfig ... diff --git a/cli/googleworkspace.go b/cli/googleworkspace.go new file mode 100644 index 0000000..62973d2 --- /dev/null +++ b/cli/googleworkspace.go @@ -0,0 +1,171 @@ +// Copyright 2019 The Biko Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package cli + +import ( + "github.com/KeisukeYamashita/biko/browser" + "github.com/KeisukeYamashita/biko/providers/googleworkspace" + "github.com/urfave/cli" +) + +func newGoogleWorkspaceCmd() cli.Command { + return cli.Command{ + Name: "googleworkspace", + Aliases: []string{"gw"}, + Usage: "Open Google Workspace resource", + Category: categoryWebService, + Flags: []cli.Flag{}, + Action: func(c *cli.Context) error { + g, err := googleworkspace.GetProvider() + if err != nil { + return err + } + return browser.Open(c, g) + }, + Subcommands: []cli.Command{ + newDriveCmd(), + newDocumentCmd(), + newSpreadsheetsCmd(), + newPresentationCmd(), + newFormsCmd(), + }, + } +} + +func newDriveCmd() cli.Command { + return cli.Command{ + Name: "drive", + Aliases: []string{"dr"}, + Usage: "Open Google Drive directory", + Flags: []cli.Flag{ + cli.StringFlag{ + Name: "query, q", + Usage: "Query to search", + }, + }, + Action: func(c *cli.Context) error { + g, err := googleworkspace.GetProvider() + if err != nil { + return err + } + return browser.Open(c, g) + }, + } + +} + +func newDocumentCmd() cli.Command { + return cli.Command{ + Name: "document", + Aliases: []string{"doc"}, + Usage: "Open Google Document page", + Flags: []cli.Flag{ + cli.StringFlag{ + Name: "query, q", + Usage: "Query a page", + }, + cli.BoolFlag{ + Name: "new, n", + Usage: "Create a new document (this flag prioritize over query flag)", + }, + }, + Action: func(c *cli.Context) error { + g, err := googleworkspace.GetProvider() + if err != nil { + return err + } + return browser.Open(c, g) + }, + } + +} + +func newSpreadsheetsCmd() cli.Command { + return cli.Command{ + Name: "spreadsheets", + Aliases: []string{"ss"}, + Usage: "Open Google Spreadsheets page", + Flags: []cli.Flag{ + cli.StringFlag{ + Name: "query, q", + Usage: "Query a page", + }, + cli.BoolFlag{ + Name: "new, n", + Usage: "Create a new spreadsheet (this flag prioritize over query flag)", + }, + }, + Action: func(c *cli.Context) error { + g, err := googleworkspace.GetProvider() + if err != nil { + return err + } + return browser.Open(c, g) + }, + } + +} + +func newPresentationCmd() cli.Command { + return cli.Command{ + Name: "presentation", + Aliases: []string{"pr"}, + Usage: "Open Google Slides page", + Flags: []cli.Flag{ + cli.StringFlag{ + Name: "query, q", + Usage: "Query a page", + }, + cli.BoolFlag{ + Name: "new, n", + Usage: "Create a new presentation (this flag prioritize over query flag)", + }, + }, + Action: func(c *cli.Context) error { + g, err := googleworkspace.GetProvider() + if err != nil { + return err + } + return browser.Open(c, g) + }, + } + +} + +func newFormsCmd() cli.Command { + return cli.Command{ + Name: "forms", + Aliases: []string{"fm"}, + Usage: "Open Google Forms page", + Flags: []cli.Flag{ + cli.StringFlag{ + Name: "query, q", + Usage: "Query a page", + }, + cli.BoolFlag{ + Name: "new, n", + Usage: "Create a new form (this flag prioritize over query flag)", + }, + }, + Action: func(c *cli.Context) error { + g, err := googleworkspace.GetProvider() + if err != nil { + return err + } + return browser.Open(c, g) + }, + } + +} diff --git a/cli/root.go b/cli/root.go index a99f719..4827ffd 100644 --- a/cli/root.go +++ b/cli/root.go @@ -44,6 +44,7 @@ func rootSubCommands() []cli.Command { newGCPCmd(), newGithubCmd(), newGoogleCmd(), + newGoogleWorkspaceCmd(), newJIRACmd(), newPagerDutyCmd(), newVersionCmd(), diff --git a/providers/googleworkspace/googleworkspace.go b/providers/googleworkspace/googleworkspace.go new file mode 100644 index 0000000..1567c5f --- /dev/null +++ b/providers/googleworkspace/googleworkspace.go @@ -0,0 +1,166 @@ +// Copyright 2019 The Biko Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package googleworkspace + +import ( + "net/url" + "path" + + "github.com/KeisukeYamashita/biko/alias" + "github.com/urfave/cli" +) + +const ( + drive = "drive" + document = "document" + spreadsheets = "spreadsheets" + presentation = "presentation" + forms = "forms" +) + +// Provider ... +type Provider struct { + baseURL *url.URL + URL *url.URL + Ctx *cli.Context + Aliases map[string]interface{} +} + +// GetProvider ... +func GetProvider() (*Provider, error) { + conf, err := alias.GetConfig() + if err != nil { + return nil, err + } + + return &Provider{ + Aliases: conf.GoogleWorkspace["alias"].(map[string]interface{}), + }, nil +} + +// Init ... +func (p *Provider) Init(c *cli.Context) error { + p.Ctx = c + return nil +} + +// GetTargetURL ... +func (p *Provider) GetTargetURL() (string, error) { + newFlag := p.GetCtxString("new") + if newFlag == "true" { // HACK: need to fix GetCtxString + return p.getNewCmdURL(), nil + } + + var baseURL string + product := p.Ctx.Command.Name + switch product { + case drive: + baseURL = "https://drive.google.com" + case document, spreadsheets, presentation, forms: + baseURL = "https://docs.google.com/" + } + + var err error + if p.baseURL, err = url.Parse(baseURL); err != nil { + return "", err + } + p.addProductPath(product) + return p.URL.String(), nil +} + +func (p *Provider) addProductPath(product string) { + p.URL = p.baseURL + switch product { + case drive: + p.join(drive) + param := url.Values{} + var query string + if query = p.GetCtxString("query"); query != "" { + p.join("search") + param.Add("q", query) + p.URL.RawQuery = param.Encode() + } + case document: + p.join(document) + param := url.Values{} + var query string + if query = p.GetCtxString("query"); query != "" { + param.Add("q", query) + p.URL.RawQuery = param.Encode() + } + case spreadsheets: + p.join(spreadsheets) + param := url.Values{} + var query string + if query = p.GetCtxString("query"); query != "" { + param.Add("q", query) + p.URL.RawQuery = param.Encode() + } + case presentation: + p.join(presentation) + param := url.Values{} + var query string + if query = p.GetCtxString("query"); query != "" { + param.Add("q", query) + p.URL.RawQuery = param.Encode() + } + case forms: + p.join(forms) + param := url.Values{} + var query string + if query = p.GetCtxString("query"); query != "" { + param.Add("q", query) + p.URL.RawQuery = param.Encode() + } + } +} + +func (p *Provider) join(additionPath string) { + if p.URL == nil { + p.URL = p.baseURL + } + p.URL.Path = path.Join(p.URL.Path, additionPath) +} + +func (p *Provider) getNewCmdURL() string { + product := p.Ctx.Command.Name + switch product { + case document: + return "https://document.new" + case spreadsheets: + return "https://spreadsheets.new" + case presentation: + return "https://presentation.new" + case forms: + return "https://forms.new" + } + return "" +} + +// GetCtxString ... +func (p *Provider) GetCtxString(str string) string { + key := p.Ctx.String(str) + if key == "" { + return "" + } + value, ok := p.Aliases[key].(string) + if !ok { + return key + } + if value == "" { + return key + } + return value +}