From 7b7971d6bf3b403634878ae5351c4350ac6f969f Mon Sep 17 00:00:00 2001 From: Bryan Austin Date: Mon, 2 Jul 2018 17:20:39 -0700 Subject: [PATCH 01/16] Make Jira module list interactable Using the todo module as a template, this change adds interactivity to the Jira module to allow selecting individual issues and opening them in a web browser. The j and k keys (or arrow keys) move up and down, and pressing enter will open the URL for a given issue in the system's default URL handler. --- jira/widget.go | 117 ++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 102 insertions(+), 15 deletions(-) diff --git a/jira/widget.go b/jira/widget.go index 9ca26540..f9ac3c1c 100644 --- a/jira/widget.go +++ b/jira/widget.go @@ -3,18 +3,24 @@ package jira import ( "fmt" + "github.com/gdamore/tcell" "github.com/senorprogrammer/wtf/wtf" ) type Widget struct { wtf.TextWidget + + result *SearchResult + selected int } func NewWidget() *Widget { widget := Widget{ - TextWidget: wtf.NewTextWidget(" Jira ", "jira", false), + TextWidget: wtf.NewTextWidget(" Jira ", "jira", true), } + widget.unselect() + widget.View.SetInputCapture(widget.keyboardIntercept) return &widget } @@ -29,38 +35,71 @@ func (widget *Widget) Refresh() { widget.UpdateRefreshedAt() - var content string if err != nil { + widget.result = nil widget.View.SetWrap(true) widget.View.SetTitle(widget.Name) - content = err.Error() + widget.View.SetText(err.Error()) } else { - widget.View.SetWrap(false) - widget.View.SetTitle( - fmt.Sprintf( - "%s- [green]%s[white]", - widget.Name, - wtf.Config.UString("wtf.mods.jira.project"), - ), - ) - content = widget.contentFrom(searchResult) + widget.result = searchResult } - widget.View.SetText(content) + widget.display() } /* -------------------- Unexported Functions -------------------- */ +func (widget *Widget) display() { + if widget.result == nil { + return + } + widget.View.SetWrap(false) + widget.View.SetTitle( + fmt.Sprintf( + "%s- [green]%s[white]", + widget.Name, + wtf.Config.UString("wtf.mods.jira.project"), + ), + ) + widget.View.SetText(fmt.Sprintf("%s", widget.contentFrom(widget.result))) +} + +func (widget *Widget) next() { + widget.selected++ + if widget.result != nil && widget.selected >= len(widget.result.Issues) { + widget.selected = 0 + } +} + +func (widget *Widget) prev() { + widget.selected-- + if widget.selected < 0 && widget.result != nil { + widget.selected = len(widget.result.Issues) - 1 + } +} + +func (widget *Widget) openItem() { + sel := widget.selected + if sel >= 0 && widget.result != nil && sel < len(widget.result.Issues) { + issue := &widget.result.Issues[widget.selected] + wtf.OpenFile(wtf.Config.UString("wtf.mods.jira.domain") + "/browse/" + issue.Key) + } +} + +func (widget *Widget) unselect() { + widget.selected = -1 +} + func (widget *Widget) contentFrom(searchResult *SearchResult) string { str := " [red]Assigned Issues[white]\n" for idx, issue := range searchResult.Issues { str = str + fmt.Sprintf( - " [%s]%-6s[white] [green]%-10s[%s] %s\n", + " [%s]%-6s[white] [green]%-10s [%s]%s\n", widget.issueTypeColor(&issue), issue.IssueFields.IssueType.Name, issue.Key, - wtf.RowColor("jira", idx), + widget.rowColor(idx), issue.IssueFields.Summary, ) } @@ -68,6 +107,15 @@ func (widget *Widget) contentFrom(searchResult *SearchResult) string { return str } +func (widget *Widget) rowColor(idx int) string { + if widget.View.HasFocus() && (idx == widget.selected) { + foreColor := wtf.Config.UString("wtf.mods.jira.colors.highlight.fore", "black") + backColor := wtf.Config.UString("wtf.mods.jira.colors.highlight.back", "white") + return fmt.Sprintf("%s:%s", foreColor, backColor) + } + return wtf.RowColor("jira", idx) +} + func (widget *Widget) issueTypeColor(issue *Issue) string { switch issue.IssueFields.IssueType.Name { case "Bug": @@ -98,3 +146,42 @@ func getProjects() []string { } return ret } + +func (widget *Widget) keyboardIntercept(event *tcell.EventKey) *tcell.EventKey { + switch string(event.Rune()) { + case "j": + // Select the next item down + widget.next() + widget.display() + return nil + case "k": + // Select the next item up + widget.prev() + widget.display() + return nil + } + + switch event.Key() { + case tcell.KeyDown: + // Select the next item down + widget.next() + widget.display() + return nil + case tcell.KeyEnter: + widget.openItem() + return nil + case tcell.KeyEsc: + // Unselect the current row + widget.unselect() + widget.display() + return event + case tcell.KeyUp: + // Select the next item up + widget.prev() + widget.display() + return nil + default: + // Pass it along + return event + } +} From f1c464462068bf2a2ec20ab4b33ec384c7e32f6f Mon Sep 17 00:00:00 2001 From: Bill Keenan Date: Fri, 29 Jun 2018 09:20:44 -0400 Subject: [PATCH 02/16] now will load weather api key from config if not in env --- _sample_configs/complex_config.yml | 1 + weatherservices/weather/widget.go | 10 +++++++++- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/_sample_configs/complex_config.yml b/_sample_configs/complex_config.yml index 5983683e..69ae0afb 100644 --- a/_sample_configs/complex_config.yml +++ b/_sample_configs/complex_config.yml @@ -207,6 +207,7 @@ wtf: cityids: - 3370352 - 1283240 + WTF_OWM_API_KEY: [YOUR API KEY] colors: current: "lightblue" enabled: true diff --git a/weatherservices/weather/widget.go b/weatherservices/weather/widget.go index 86208480..46dea7f9 100644 --- a/weatherservices/weather/widget.go +++ b/weatherservices/weather/widget.go @@ -1,11 +1,13 @@ package weather import ( + "fmt" "os" owm "github.com/briandowns/openweathermap" "github.com/gdamore/tcell" "github.com/rivo/tview" + "github.com/senorprogrammer/wtf/logger" "github.com/senorprogrammer/wtf/wtf" ) @@ -34,8 +36,9 @@ type Widget struct { // NewWidget creates and returns a new instance of the weather Widget. func NewWidget(app *tview.Application, pages *tview.Pages) *Widget { + configKey := "weather" widget := Widget{ - TextWidget: wtf.NewTextWidget(" Weather ", "weather", true), + TextWidget: wtf.NewTextWidget(" Weather ", configKey, true), app: app, pages: pages, @@ -44,6 +47,11 @@ func NewWidget(app *tview.Application, pages *tview.Pages) *Widget { Idx: 0, } + if widget.APIKey == "" { + logger.Log("loading weather WTF_OWM_API_KEY key from config") + widget.APIKey = wtf.Config.UString(fmt.Sprintf("wtf.mods.%s.WTF_OWM_API_KEY", configKey), "") + } + widget.View.SetInputCapture(widget.keyboardIntercept) return &widget From 2c07ccce464cd2a4ce7e71ec3bbac20494ae5c9d Mon Sep 17 00:00:00 2001 From: Konstantin Vorobyev Date: Sun, 1 Jul 2018 20:58:20 +0200 Subject: [PATCH 03/16] gcal module improvements: - Simplify Google OAuth client creation - Read OAuth code via text dialog Same approach can be re-used for gspreadsheets --- gcal/client.go | 106 +++++------------------------------------------- gcal/google.go | 107 +++++++++++++++++++++++++++++++++++++++++++++++++ gcal/widget.go | 9 +++-- wtf.go | 2 +- 4 files changed, 123 insertions(+), 101 deletions(-) create mode 100644 gcal/google.go diff --git a/gcal/client.go b/gcal/client.go index 4523ebb7..b34a249d 100644 --- a/gcal/client.go +++ b/gcal/client.go @@ -8,43 +8,28 @@ package gcal import ( - "context" - "encoding/json" - "fmt" - "io/ioutil" - "log" - "net/http" - "net/url" - "os" - "os/user" - "path/filepath" "sort" "time" "github.com/senorprogrammer/wtf/wtf" - "golang.org/x/oauth2" - "golang.org/x/oauth2/google" "google.golang.org/api/calendar/v3" ) /* -------------------- Exported Functions -------------------- */ -func Fetch() ([]*CalEvent, error) { - ctx := context.Background() - - secretPath, _ := wtf.ExpandHomeDir(wtf.Config.UString("wtf.mods.gcal.secretFile")) - - b, err := ioutil.ReadFile(secretPath) +func Fetch(oauthHandler OAuthUIHandler) ([]*CalEvent, error) { + secretFile, _ := wtf.ExpandHomeDir(wtf.Config.UString("wtf.mods.gcal.secretFile")) + tokenFile, _ := wtf.ExpandHomeDir(wtf.Config.UString("wtf.mods.gcal.tokenFile", "~/.gcal.token")) + config := OAuthClientConfig{ + SecretFile: secretFile, + TokenFile: tokenFile, + Scope: calendar.CalendarReadonlyScope, + } + client, err := BuildOAuthClient(config, oauthHandler) if err != nil { return nil, err } - config, err := google.ConfigFromJSON(b, calendar.CalendarReadonlyScope) - if err != nil { - return nil, err - } - client := getClient(ctx, config) - srv, err := calendar.New(client) if err != nil { return nil, err @@ -100,79 +85,6 @@ func fromMidnight() time.Time { return time.Date(now.Year(), now.Month(), now.Day(), 0, 0, 0, 0, now.Location()) } -// getClient uses a Context and Config to retrieve a Token -// then generate a Client. It returns the generated Client. -func getClient(ctx context.Context, config *oauth2.Config) *http.Client { - cacheFile, err := tokenCacheFile() - if err != nil { - log.Fatalf("Unable to get path to cached credential file. %v", err) - } - tok, err := tokenFromFile(cacheFile) - if err != nil { - tok = getTokenFromWeb(config) - saveToken(cacheFile, tok) - } - return config.Client(ctx, tok) -} - -// getTokenFromWeb uses Config to request a Token. -// It 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 code string - if _, err := fmt.Scan(&code); err != nil { - log.Fatalf("Unable to read authorization code %v", err) - } - - tok, err := config.Exchange(oauth2.NoContext, code) - if err != nil { - log.Fatalf("Unable to retrieve token from web %v", err) - } - return tok -} - -// tokenCacheFile generates credential file path/filename. -// It returns the generated credential path/filename. -func tokenCacheFile() (string, error) { - usr, err := user.Current() - if err != nil { - return "", err - } - tokenCacheDir := filepath.Join(usr.HomeDir, ".credentials") - os.MkdirAll(tokenCacheDir, 0700) - return filepath.Join(tokenCacheDir, - url.QueryEscape("calendar-go-quickstart.json")), err -} - -// tokenFromFile retrieves a Token from a given file path. -// It returns the retrieved Token and any read error encountered. -func tokenFromFile(file string) (*oauth2.Token, error) { - f, err := os.Open(file) - if err != nil { - return nil, err - } - t := &oauth2.Token{} - err = json.NewDecoder(f).Decode(t) - defer f.Close() - return t, err -} - -// saveToken uses a file path to create a file and store the -// token in it. -func saveToken(file string, token *oauth2.Token) { - fmt.Printf("Saving credential file to: %s\n", file) - f, err := os.OpenFile(file, 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) -} - func getCalendarIdList(srv *calendar.Service) ([]string, error) { // Return single calendar if settings specify we should if !wtf.Config.UBool("wtf.mods.gcal.multiCalendar", false) { diff --git a/gcal/google.go b/gcal/google.go new file mode 100644 index 00000000..1c1dfa08 --- /dev/null +++ b/gcal/google.go @@ -0,0 +1,107 @@ +package gcal + +import ( + "context" + "encoding/json" + "fmt" + "io/ioutil" + "net/http" + "os" + + "github.com/senorprogrammer/wtf/logger" + "golang.org/x/oauth2" + "golang.org/x/oauth2/google" +) + +// OAuthClientConfig describes Google oauth2 client configuration +type OAuthClientConfig struct { + SecretFile string + TokenFile string + Scope string +} + +// OAuthUIHandler returns oauth2 authorization code, implements user interaction +type OAuthUIHandler = func(string, chan string) + +func BuildOAuthClient(config OAuthClientConfig, handler OAuthUIHandler) (*http.Client, error) { + ctx := context.Background() + + b, err := ioutil.ReadFile(config.SecretFile) + if err != nil { + logger.Log(fmt.Sprintf("Invalid secret file provided (%s): %v", config.SecretFile, err)) + return nil, err + } + + oauthConfig, err := google.ConfigFromJSON(b, config.Scope) + if err != nil { + logger.Log(fmt.Sprintf("Secret file is not readable as JSON (%s): %v", config.SecretFile, err)) + return nil, err + } + + tok, err := tokenFromFile(config.TokenFile) + if err != nil { + result := make(chan string) + go handler(oauthConfig.AuthCodeURL("state-token", oauth2.AccessTypeOffline), result) + code, ok := <-result + if !ok { + // Cancelled + return nil, err + } + tok, err = oauthConfig.Exchange(oauth2.NoContext, code) + if err != nil { + logger.Log(fmt.Sprintf("Invalid exchange code provided (%s): %v", code, err)) + return nil, err + } + err = saveToken(config.TokenFile, tok) + if err != nil { + logger.Log(fmt.Sprintf("Unable to store oauth token (%s): %v", config.TokenFile, err)) + } + + } + return oauthConfig.Client(ctx, tok), nil +} + +// CreateCodeInputDialog shows oauth2 code input dialog +func CreateCodeInputDialog(title string, widget *Widget) OAuthUIHandler { + return func(url string, result chan string) { + readInput := func() { + fmt.Printf("\r\nOAuth authorization [%s]\r\n", title) + fmt.Printf("Please open the following URL in your browser and paste authorization code below:\r\n") + fmt.Printf("%s\r\nAuthorization code: ", url) + var code string + if _, err := fmt.Scan(&code); err != nil { + logger.Log(fmt.Sprintf("Unable to read authorization code: %v", err)) + close(result) + } else { + result <- code + } + } + widget.app.Suspend(readInput) + } +} + +// tokenFromFile retrieves a Token from a given file path. +// It returns the retrieved Token and any read error encountered. +func tokenFromFile(file string) (*oauth2.Token, error) { + f, err := os.Open(file) + if err != nil { + return nil, err + } + t := &oauth2.Token{} + err = json.NewDecoder(f).Decode(t) + defer f.Close() + return t, err +} + +// saveToken uses a file path to create a file and store the +// token in it. +func saveToken(file string, token *oauth2.Token) error { + // fmt.Printf("Saving credential file to: %s\n", file) + f, err := os.OpenFile(file, os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0600) + if err != nil { + return err + } + defer f.Close() + json.NewEncoder(f).Encode(token) + return nil +} diff --git a/gcal/widget.go b/gcal/widget.go index 7ad4bc25..7d75da6f 100644 --- a/gcal/widget.go +++ b/gcal/widget.go @@ -4,6 +4,7 @@ import ( "sync" "time" + "github.com/rivo/tview" "github.com/senorprogrammer/wtf/wtf" ) @@ -13,11 +14,13 @@ type Widget struct { calEvents []*CalEvent ch chan struct{} mutex sync.Mutex + app *tview.Application } -func NewWidget() *Widget { +func NewWidget(app *tview.Application) *Widget { widget := Widget{ - TextWidget: wtf.NewTextWidget(" Calendar ", "gcal", false), + TextWidget: wtf.NewTextWidget(" Calendar ", "gcal", true), + app: app, ch: make(chan struct{}), } @@ -34,7 +37,7 @@ func (widget *Widget) Disable() { } func (widget *Widget) Refresh() { - calEvents, err := Fetch() + calEvents, err := Fetch(CreateCodeInputDialog(" Calendar ", widget)) if err != nil { widget.calEvents = []*CalEvent{} } else { diff --git a/wtf.go b/wtf.go index 79b2a6d8..39a8b99e 100644 --- a/wtf.go +++ b/wtf.go @@ -179,7 +179,7 @@ func addWidget(app *tview.Application, pages *tview.Pages, widgetName string) { case "cryptolive": Widgets = append(Widgets, cryptolive.NewWidget()) case "gcal": - Widgets = append(Widgets, gcal.NewWidget()) + Widgets = append(Widgets, gcal.NewWidget(app)) case "gerrit": Widgets = append(Widgets, gerrit.NewWidget(app, pages)) case "git": From 8ad0d348755a452ac026c30c423b975d0863dc81 Mon Sep 17 00:00:00 2001 From: Bill Keenan Date: Wed, 4 Jul 2018 10:45:16 -0400 Subject: [PATCH 04/16] fixed bargraph test --- wtftests/bargraph/bargraph_test.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/wtftests/bargraph/bargraph_test.go b/wtftests/bargraph/bargraph_test.go index 3135c925..41c2ef7b 100644 --- a/wtftests/bargraph/bargraph_test.go +++ b/wtftests/bargraph/bargraph_test.go @@ -14,10 +14,10 @@ func makeData() [][2]int64 { const lineCount = 2 var stats [lineCount][2]int64 - stats[0][1] = 1530122942 + stats[0][1] = 1530122942000 stats[0][0] = 100 - stats[1][1] = 1530132942 + stats[1][1] = 1531142942000 stats[1][0] = 210 return stats[:] @@ -29,5 +29,5 @@ func TestOutput(t *testing.T) { result := BuildStars(makeData(), 20, "*") - Equal(t, result, "Jan 18, 1970 -\t [red]*[white] - (100)\nJan 18, 1970 -\t [red]********************[white] - (210)\n") + Equal(t, "Jun 27, 2018 -\t [red]*[white] - (100)\nJul 09, 2018 -\t [red]********************[white] - (210)\n", result) } From e288eef8ddd02d46d1d03e79604c53f4ed1b17df Mon Sep 17 00:00:00 2001 From: Lineu Felipe Date: Thu, 5 Jul 2018 00:47:35 -0300 Subject: [PATCH 05/16] add todoist widget --- Gopkg.lock | 8 +- Gopkg.toml | 4 + _site/content/posts/modules/todoist.md | 88 ++++++++++++++ _site/static/imgs/modules/todoist.png | Bin 0 -> 3335 bytes .../hyde-hyde/layouts/partials/sidebar.html | 1 + todoist/display.go | 64 ++++++++++ todoist/list.go | 79 ++++++++++++ todoist/widget.go | 113 ++++++++++++++++++ wtf.go | 4 +- 9 files changed, 359 insertions(+), 2 deletions(-) create mode 100644 _site/content/posts/modules/todoist.md create mode 100644 _site/static/imgs/modules/todoist.png create mode 100644 todoist/display.go create mode 100644 todoist/list.go create mode 100644 todoist/widget.go diff --git a/Gopkg.lock b/Gopkg.lock index 9211154d..8a0e37d8 100644 --- a/Gopkg.lock +++ b/Gopkg.lock @@ -25,6 +25,12 @@ packages = ["."] revision = "6a9abf92e34f4de62ac671caee3143f10b98892d" +[[projects]] + branch = "master" + name = "github.com/darkSasori/todoist" + packages = ["."] + revision = "ec6b38b374ab9c60cc9716d2083ae66eb9383d03" + [[projects]] name = "github.com/davecgh/go-spew" packages = ["spew"] @@ -201,6 +207,6 @@ [solve-meta] analyzer-name = "dep" analyzer-version = 1 - inputs-digest = "a7a00554f9040d7617458773eafa64b82f9502eace145152cb50eb082800e936" + inputs-digest = "b2141b5945354e95e2f3e8f1f6eb182de11e21f0fe1188862c6dc57983c8cbc4" solver-name = "gps-cdcl" solver-version = 1 diff --git a/Gopkg.toml b/Gopkg.toml index 6221a4d7..9261787d 100644 --- a/Gopkg.toml +++ b/Gopkg.toml @@ -85,6 +85,10 @@ branch = "master" name = "github.com/adlio/trello" +[[constraint]] + branch = "master" + name = "github.com/darkSasori/todoist" + [prune] go-tests = true unused-packages = true diff --git a/_site/content/posts/modules/todoist.md b/_site/content/posts/modules/todoist.md new file mode 100644 index 00000000..bb3beb11 --- /dev/null +++ b/_site/content/posts/modules/todoist.md @@ -0,0 +1,88 @@ +--- +title: "Todoist" +date: 2018-07-05T22:55:55-03:00 +draft: false +--- + +Displays all itens on specified project. + +todoist screenshot + +## Source Code + +```bash +wtf/todoist/ +``` + +## Required ENV Variables + +Key: `WTF_TODOIST_TOKEN`
+Value: Your Todoist API Token.
+ +_You can get your API Token at: todoist.com/prefs/integrations._ + +## Keyboard Commands + +Key: `h`
+Action: Show the previous project. + +Key: `←`
+Action: Show the previous project. + +Key: `l`
+Action: Show the next project. + +Key: `→`
+Action: Show the next project. + +Key: `j`
+Action: Select the next item in the list. + +Key: `↓`
+Action: Select the next item in the list. + +Key: `k`
+Action: Select the previous item in the list. + +Key: `↑`
+Action: Select the previous item in the list. + +Key: `c`
+Action: Close current item. + +Key: `d`
+Action: Delete current item. + +Key: `r`
+Action: Reload all projects. + +## Configuration + +```yaml +todoist: + projects: + - project_id + enabled: true + position: + height: 1 + left: 2 + top: 0 + width: 1 + refreshInterval: 3600 +``` + +### Attributes + +`enabled`
+Determines whether or not this module is executed and if its data displayed onscreen.
+Values: `true`, `false`. + +`projects`
+The todoist projects to fetch items from.
+ +`refreshInterval`
+How often, in seconds, this module will update its data.
+Values: A positive integer, `0..n`. + +`position`
+Where in the grid this module's widget will be displayed.
diff --git a/_site/static/imgs/modules/todoist.png b/_site/static/imgs/modules/todoist.png new file mode 100644 index 0000000000000000000000000000000000000000..086d0ec8673a4f407e2b0c382fd9e547711a0909 GIT binary patch literal 3335 zcmeHK=Q|r*8xLBvwOW)uXpEK)qtq&DRqPl|Q8QX2_KrPDNs6ZwwTs8D{lt94hzh0k zSPf#u4$_)Mh!Jo63Gb)(%X?qfIrljq&hOmUz0U8%n;7Y^Uj5@L003as)75$o0MJ>} z*4@nXwArPB97j`Ed~_}S0RXn1i$RzEkc|%jU}@FU(s&X4X_MgT!3m4$+J&i*FYzmH z%k$M}iRjd@m0k}r%eiVa?ibMZN!XXzT#;oiS+G@e)s5lo3v@h>g1YGp zKfZ0SI)7_sStsPQM}m%KA^`Blu9?7_rh7t0GGl_(NS^wDpb*cs`gPm-#us{C7RnArGrsT#}GaP!20 zCFO;I{(ygZ5lTqLm-fdh=`C73ia${jp&MC>dqH6j*RGRo!yv`Vn0a?yb1Ew z_EwlR&vW}Wm%7vBvu{4uJa_Xp^ZXQC=Nm*^a)1T5-Rmw_`dZ3juiCCj_j>N2xtZAk zdB$5uIK>-tMs8ipud1!>^j${aNT;WJ!^NZP@tk6>x8)3<)YsK{e;?E?Hbr7h&COSL zgKKSCQ-@$BN@kwffhTHSe6K`gcqycA;}E%!XeoN(2QQG785O3+vH^Ext2}>Of%Aer z2V?fj443K_ii(7>kHR}Kr@-GsdCI-Ly^)yt?ZZAJ>C?!lJ2$euRswQ2*ViZi@hzU& zOwtn0%gf_5etKguunicxUU)<}K0ZErG8B=W0Pf}}J<)dv;s(dFX~%I;*)X2PHDk7J zT7QlXjV@%{FP&ho$$>;WO$HCCS4eAn6fV$xaq&OTAX4}5?}m2R)#05RvJFLT@tc8d zQy%$Vj^WBFx;>6E;8_p%3;Fdu{bA6?zXgj&C!IdWHstPDAed?U?1{;OlExhg-j-k=p?ni-D36hrMjd6 ze6Fat&N(4-8wf0zvHFUFL+JhmJ9ieo zu(9#r{Yq;ruY=^keEj@ewEI~E^;{oxm-N0vA`qH|BddeC%kF7k@3dw}zqwONs($t3 zbq^McJv%#NWo6ANbImcQ1=r3_GSzNi(ox1W$5|$ON#Qx=(;M-RWe%}(b93WW7A-9; zztD5Dv;54LX1#)FoyXcbx3ZFffnghS-pNr^UtizaI_1_x>%w~Ow~TXCiN)2H4XdS@ zb_s;YrFb#6+bT!BJkXNGDLPByTvH)rHxC53#^L^qA!}j`w7#`*eiehbx7 za2&T#4p1t1KU!r*7}sTTGy*)0BFCT^)|np#u@?P2Jt z^*TXzCp`Cm!Bbv$DT(SEfF>QPe(-w7K16s=pl&QpdY{W<`rZDxvR)Axqb{#U1An$y zR-Au~8IY2a-QG??o+(E`0&skuE||^6im>z6mFdkLiKu{x_n!9m+N(~C@8q67H zxe91COKpcJXzl6btM~hyXSTRHY0NMp-EJ^EOF6{sUJ-gAkg?i#tvcu1<3Hf%bIREL zFkq1niiD49c*(q*>y+pa6|#w2q*{mHrOPV4UyCsM5_FSJT-}D1)!qtc!y0k_k^Fc{ zh|ER$U2LUC3siK&@4SgiZeRr5pk?U?nmYn)^9G1YJ`3vlespY-FU9nsmpr`w@AUJ$;617ZY0$?yW zr)=;riNR8GW&*)>i9T9=p*UI9s>y9!Bw6JL9)vPowbvt5zltxT)2UqzNyf&s9V8OwPPlwt1 zA5^olu87wn7#~SYAQ%Nv^0I*V3y**Rf~J@Lul_eK$aXjmha#|Bn#^gIyyy{l zA@g0_34K!E1PbOR#)*Xi3xeXlF4cB?VG$L|j{gg+f2H-RstT#ru^B q7|y|lR6E(8uUO$TD6+?G5-OUl?^}u literal 0 HcmV?d00001 diff --git a/_site/themes/hyde-hyde/layouts/partials/sidebar.html b/_site/themes/hyde-hyde/layouts/partials/sidebar.html index 3bb31b75..2da8d975 100644 --- a/_site/themes/hyde-hyde/layouts/partials/sidebar.html +++ b/_site/themes/hyde-hyde/layouts/partials/sidebar.html @@ -47,6 +47,7 @@ + diff --git a/todoist/display.go b/todoist/display.go new file mode 100644 index 00000000..8cbfa858 --- /dev/null +++ b/todoist/display.go @@ -0,0 +1,64 @@ +package todoist + +import ( + "fmt" + + "github.com/gdamore/tcell" + "github.com/rivo/tview" + "github.com/senorprogrammer/wtf/wtf" +) + +func (w *Widget) display() { + if len(w.list) == 0 { + return + } + list := w.list[w.idx] + + w.View.SetTitle(fmt.Sprintf("%s- [green]%s[white] ", w.Name, list.Project.Name)) + str := wtf.SigilStr(len(w.list), w.idx, w.View) + "\n" + + for index, item := range list.items { + if index == list.index { + str = str + fmt.Sprintf("[%s]", wtf.Config.UString("wtf.colors.border.focused", "grey")) + } + str = str + fmt.Sprintf("| | %s[white]\n", tview.Escape(item.Content)) + } + + w.View.Clear() + w.View.SetText(str) +} + +func (w *Widget) keyboardIntercept(event *tcell.EventKey) *tcell.EventKey { + if len(w.list) == 0 { + return event + } + + switch string(event.Rune()) { + case "r": + w.Refresh() + return nil + case "d": + w.Delete() + return nil + case "c": + w.Close() + return nil + } + + switch fromVim(event) { + case tcell.KeyLeft: + w.Prev() + return nil + case tcell.KeyRight: + w.Next() + return nil + case tcell.KeyUp: + w.UP() + return nil + case tcell.KeyDown: + w.Down() + return nil + } + + return event +} diff --git a/todoist/list.go b/todoist/list.go new file mode 100644 index 00000000..81b9d55e --- /dev/null +++ b/todoist/list.go @@ -0,0 +1,79 @@ +package todoist + +import ( + "fmt" + + "github.com/darkSasori/todoist" +) + +type List struct { + todoist.Project + items []todoist.Task + index int +} + +func NewList(id int) *List { + project, err := todoist.GetProject(id) + if err != nil { + panic(err) + } + + list := &List{ + Project: project, + index: -1, + } + list.loadItems() + return list +} + +func (l List) isFirst() bool { + return l.index == 0 +} + +func (l List) isLast() bool { + return l.index >= len(l.items)-1 +} + +func (l *List) up() { + l.index = l.index - 1 + if l.index < 0 { + l.index = len(l.items) - 1 + } +} + +func (l *List) down() { + if l.index == -1 { + l.index = 0 + return + } + + l.index = l.index + 1 + if l.index >= len(l.items) { + l.index = 0 + } +} + +func (l *List) loadItems() { + tasks, err := todoist.ListTask(todoist.QueryParam{"project_id": fmt.Sprintf("%d", l.ID)}) + if err != nil { + panic(err) + } + + l.items = tasks +} + +func (l *List) close() { + if err := l.items[l.index].Close(); err != nil { + panic(err) + } + + l.loadItems() +} + +func (l *List) delete() { + if err := l.items[l.index].Delete(); err != nil { + panic(err) + } + + l.loadItems() +} diff --git a/todoist/widget.go b/todoist/widget.go new file mode 100644 index 00000000..e40089fa --- /dev/null +++ b/todoist/widget.go @@ -0,0 +1,113 @@ +package todoist + +import ( + "os" + + "github.com/darkSasori/todoist" + "github.com/gdamore/tcell" + "github.com/rivo/tview" + "github.com/senorprogrammer/wtf/wtf" +) + +type Widget struct { + wtf.TextWidget + + app *tview.Application + pages *tview.Pages + list []*List + idx int +} + +func NewWidget(app *tview.Application, pages *tview.Pages) *Widget { + widget := Widget{ + TextWidget: wtf.NewTextWidget(" Todoist ", "todoist", true), + + app: app, + pages: pages, + } + + todoist.Token = os.Getenv("WTF_TODOIST_TOKEN") + widget.list = loadProjects() + widget.View.SetInputCapture(widget.keyboardIntercept) + + return &widget +} + +func (w *Widget) Refresh() { + if w.Disabled() || len(w.list) == 0 { + return + } + + w.UpdateRefreshedAt() + w.display() +} + +func (w *Widget) Next() { + w.idx = w.idx + 1 + if w.idx == len(w.list) { + w.idx = 0 + } + + w.display() +} + +func (w *Widget) Prev() { + w.idx = w.idx - 1 + if w.idx < 0 { + w.idx = len(w.list) - 1 + } + + w.display() +} + +func (w *Widget) Down() { + w.list[w.idx].down() + w.display() +} + +func (w *Widget) UP() { + w.list[w.idx].up() + w.display() +} + +func (w *Widget) Close() { + w.list[w.idx].close() + if w.list[w.idx].isLast() { + w.UP() + return + } + w.Down() +} + +func (w *Widget) Delete() { + w.list[w.idx].close() + if w.list[w.idx].isLast() { + w.UP() + return + } + w.Down() +} + +func loadProjects() []*List { + lists := []*List{} + for _, id := range wtf.Config.UList("wtf.mods.todoist.projects") { + list := NewList(id.(int)) + lists = append(lists, list) + } + + return lists +} + +func fromVim(event *tcell.EventKey) tcell.Key { + switch string(event.Rune()) { + case "h": + return tcell.KeyLeft + case "l": + return tcell.KeyRight + case "k": + return tcell.KeyUp + case "j": + return tcell.KeyDown + } + return event.Key() +} diff --git a/wtf.go b/wtf.go index 39a8b99e..ad536aaa 100644 --- a/wtf.go +++ b/wtf.go @@ -39,6 +39,7 @@ import ( "github.com/senorprogrammer/wtf/system" "github.com/senorprogrammer/wtf/textfile" "github.com/senorprogrammer/wtf/todo" + "github.com/senorprogrammer/wtf/todoist" "github.com/senorprogrammer/wtf/trello" "github.com/senorprogrammer/wtf/weatherservices/prettyweather" "github.com/senorprogrammer/wtf/weatherservices/weather" @@ -218,6 +219,8 @@ func addWidget(app *tview.Application, pages *tview.Pages, widgetName string) { Widgets = append(Widgets, textfile.NewWidget(app, pages)) case "todo": Widgets = append(Widgets, todo.NewWidget(app, pages)) + case "todoist": + Widgets = append(Widgets, todoist.NewWidget(app, pages)) case "trello": Widgets = append(Widgets, trello.NewWidget()) case "weather": @@ -233,7 +236,6 @@ func makeWidgets(app *tview.Application, pages *tview.Pages) { if enabled := Config.UBool("wtf.mods."+mod+".enabled", false); enabled { addWidget(app, pages, mod) } - } } From 195fa331cdd028dac2eefb9a287aa2927f264a25 Mon Sep 17 00:00:00 2001 From: Chris Cummer Date: Wed, 11 Jul 2018 10:24:49 -0700 Subject: [PATCH 06/16] Add @darkSasori as a contributor --- .all-contributorsrc | 7 +++++++ README.md | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/.all-contributorsrc b/.all-contributorsrc index f0232bd6..b8879094 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -217,6 +217,13 @@ "name": "Jagdeep Singh", "avatar_url": "https://avatars3.githubusercontent.com/u/3717137?v=4", "profile": "https://jagdeep.me", + "contributions": [] + }, + { + "login": "darkSasori", + "name": "Lineu Felipe", + "avatar_url": "https://avatars0.githubusercontent.com/u/889171?v=4", + "profile": "https://github.com/darkSasori", "contributions": [ ] } diff --git a/README.md b/README.md index ab4e5848..0ae15796 100644 --- a/README.md +++ b/README.md @@ -55,7 +55,7 @@ Thanks goes to these wonderful people: | [
baustinanki](https://github.com/baustinanki)
| [
lucus lee](https://github.com/lixin9311)
| [
Mike Lloyd](https://github.com/mxplusb)
| [
Sergio Rubio](http://rubiojr.rbel.co)
| [
Farhad Farahi](https://github.com/FarhadF)
| [
Lasantha Kularatne](http://lasantha.blogspot.com/)
| [
Mark Old](https://github.com/dlom)
| | [
flw](http://flw.tools/)
| [
David Barda](https://github.com/davebarda)
| [
Geoff Lee](https://github.com/matrinox)
| [
George Opritescu](http://international.github.io)
| [
Grazfather](https://twitter.com/Grazfather)
| [
Michael Cordell](http://www.mikecordell.com/)
| [
Patrick José Pereira](http://patrick.ibexcps.com)
| | [
sherod taylor](https://github.com/sherodtaylor)
| [
Andrew Scott](http://cogentia.io)
| [
Anand Sudhir Prayaga](https://github.com/anandsudhir)
| [
Lassi Piironen](https://github.com/lsipii)
| [
BlackWebWolf](https://github.com/BlackWebWolf)
| [
andrewzolotukhin](https://github.com/andrewzolotukhin)
| [
Leon Stigter](https://retgits.github.io)
| -| [
Amr Tamimi](https://tamimi.se)
| [
Jagdeep Singh](https://jagdeep.me)
| +| [
Amr Tamimi](https://tamimi.se)
| [
Jagdeep Singh](https://jagdeep.me)
| [
Lineu Felipe](https://github.com/darkSasori)
[💻](https://github.com/senorprogrammer/wtf/commits?author=darkSasori "Code") | This project follows the [all-contributors](https://github.com/kentcdodds/all-contributors) specification. Contributions of any kind welcome! From 81cc0e4450a2e577c1683f155f5244ff71ad3e35 Mon Sep 17 00:00:00 2001 From: Chris Cummer Date: Wed, 11 Jul 2018 10:27:57 -0700 Subject: [PATCH 07/16] Add documentation for Todoist module --- _site/content/posts/modules/todoist.md | 4 +++- docs/404.html | 1 + docs/categories/index.html | 1 + docs/index.html | 1 + docs/index.xml | 18 +++++++++++++++++- docs/posts/configuration/attributes/index.html | 1 + docs/posts/configuration/index.html | 1 + docs/posts/configuration/iterm2/index.html | 1 + docs/posts/glossary/index.html | 1 + docs/posts/index.html | 8 ++++++++ docs/posts/index.xml | 18 +++++++++++++++++- docs/posts/installation/index.html | 1 + docs/posts/modules/bamboohr/index.html | 1 + docs/posts/modules/circleci/index.html | 1 + docs/posts/modules/clocks/index.html | 1 + docs/posts/modules/cmdrunner/index.html | 1 + .../cryptocurrencies/bittrex/index.html | 1 + .../cryptocurrencies/blockfolio/index.html | 1 + .../cryptocurrencies/cryptolive/index.html | 1 + docs/posts/modules/gcal/index.html | 1 + docs/posts/modules/gerrit/index.html | 1 + docs/posts/modules/git/index.html | 1 + docs/posts/modules/github/index.html | 1 + docs/posts/modules/gitlab/index.html | 1 + docs/posts/modules/gspreadsheet/index.html | 1 + docs/posts/modules/index.html | 1 + docs/posts/modules/ipapi/index.html | 1 + docs/posts/modules/ipinfo/index.html | 1 + docs/posts/modules/jenkins/index.html | 1 + docs/posts/modules/jira/index.html | 1 + docs/posts/modules/logger/index.html | 1 + docs/posts/modules/newrelic/index.html | 1 + docs/posts/modules/opsgenie/index.html | 1 + docs/posts/modules/power/index.html | 1 + docs/posts/modules/prettyweather/index.html | 1 + docs/posts/modules/security/index.html | 1 + docs/posts/modules/textfile/index.html | 1 + docs/posts/modules/todo/index.html | 1 + docs/posts/modules/trello/index.html | 1 + docs/posts/modules/weather/index.html | 1 + docs/posts/overview/index.html | 1 + docs/sitemap.xml | 9 +++++++-- docs/tags/index.html | 1 + 43 files changed, 90 insertions(+), 5 deletions(-) diff --git a/_site/content/posts/modules/todoist.md b/_site/content/posts/modules/todoist.md index bb3beb11..4467f165 100644 --- a/_site/content/posts/modules/todoist.md +++ b/_site/content/posts/modules/todoist.md @@ -4,7 +4,9 @@ date: 2018-07-05T22:55:55-03:00 draft: false --- -Displays all itens on specified project. +Added in `v0.0.11`. + +Displays all items on specified project. todoist screenshot diff --git a/docs/404.html b/docs/404.html index 2e9ef6b7..0fb566ce 100644 --- a/docs/404.html +++ b/docs/404.html @@ -100,6 +100,7 @@ height="0" width="0" style="display:none;visibility:hidden"> + diff --git a/docs/categories/index.html b/docs/categories/index.html index 1893a8de..fb9a29ee 100644 --- a/docs/categories/index.html +++ b/docs/categories/index.html @@ -102,6 +102,7 @@ height="0" width="0" style="display:none;visibility:hidden"> + diff --git a/docs/index.html b/docs/index.html index 5808c8f2..a8edc4eb 100644 --- a/docs/index.html +++ b/docs/index.html @@ -101,6 +101,7 @@ height="0" width="0" style="display:none;visibility:hidden"> + diff --git a/docs/index.xml b/docs/index.xml index f9314eb0..b2e1c6e1 100644 --- a/docs/index.xml +++ b/docs/index.xml @@ -6,11 +6,27 @@ Recent content on WTF - A Terminal Dashboard Hugo -- gohugo.io en-us - Wed, 27 Jun 2018 15:55:42 -0700 + Thu, 05 Jul 2018 22:55:55 -0300 + + Todoist + https://wtfutil.com/posts/modules/todoist/ + Thu, 05 Jul 2018 22:55:55 -0300 + + https://wtfutil.com/posts/modules/todoist/ + Added in v0.0.11. +Displays all items on specified project. +Source Code wtf/todoist/ Required ENV Variables Key: WTF_TODOIST_TOKEN Value: Your Todoist API Token. You can get your API Token at: todoist.com/prefs/integrations. +Keyboard Commands Key: h Action: Show the previous project. +Key: ← Action: Show the previous project. +Key: l Action: Show the next project. +Key: → Action: Show the next project. +Key: j Action: Select the next item in the list. + + Gerrit https://wtfutil.com/posts/modules/gerrit/ diff --git a/docs/posts/configuration/attributes/index.html b/docs/posts/configuration/attributes/index.html index 8ad20352..49031ee4 100644 --- a/docs/posts/configuration/attributes/index.html +++ b/docs/posts/configuration/attributes/index.html @@ -100,6 +100,7 @@ height="0" width="0" style="display:none;visibility:hidden"> + diff --git a/docs/posts/configuration/index.html b/docs/posts/configuration/index.html index 3fb8a0a2..72bce846 100644 --- a/docs/posts/configuration/index.html +++ b/docs/posts/configuration/index.html @@ -100,6 +100,7 @@ height="0" width="0" style="display:none;visibility:hidden"> + diff --git a/docs/posts/configuration/iterm2/index.html b/docs/posts/configuration/iterm2/index.html index 428b0980..67c5b99d 100644 --- a/docs/posts/configuration/iterm2/index.html +++ b/docs/posts/configuration/iterm2/index.html @@ -100,6 +100,7 @@ height="0" width="0" style="display:none;visibility:hidden"> + diff --git a/docs/posts/glossary/index.html b/docs/posts/glossary/index.html index 31e18fdf..4e246476 100644 --- a/docs/posts/glossary/index.html +++ b/docs/posts/glossary/index.html @@ -100,6 +100,7 @@ height="0" width="0" style="display:none;visibility:hidden"> + diff --git a/docs/posts/index.html b/docs/posts/index.html index 837c5820..52b9ee6b 100644 --- a/docs/posts/index.html +++ b/docs/posts/index.html @@ -102,6 +102,7 @@ height="0" width="0" style="display:none;visibility:hidden"> + @@ -120,6 +121,13 @@ height="0" width="0" style="display:none;visibility:hidden">

Posts

  • + + Todoist + + + + +
  • Gerrit diff --git a/docs/posts/index.xml b/docs/posts/index.xml index ed56af43..1ca92370 100644 --- a/docs/posts/index.xml +++ b/docs/posts/index.xml @@ -6,11 +6,27 @@ Recent content in Posts on WTF - A Terminal Dashboard Hugo -- gohugo.io en-us - Wed, 27 Jun 2018 15:55:42 -0700 + Thu, 05 Jul 2018 22:55:55 -0300 + + Todoist + https://wtfutil.com/posts/modules/todoist/ + Thu, 05 Jul 2018 22:55:55 -0300 + + https://wtfutil.com/posts/modules/todoist/ + Added in v0.0.11. +Displays all items on specified project. +Source Code wtf/todoist/ Required ENV Variables Key: WTF_TODOIST_TOKEN Value: Your Todoist API Token. You can get your API Token at: todoist.com/prefs/integrations. +Keyboard Commands Key: h Action: Show the previous project. +Key: ← Action: Show the previous project. +Key: l Action: Show the next project. +Key: → Action: Show the next project. +Key: j Action: Select the next item in the list. + + Gerrit https://wtfutil.com/posts/modules/gerrit/ diff --git a/docs/posts/installation/index.html b/docs/posts/installation/index.html index 3d1a2a0e..34adb7d5 100644 --- a/docs/posts/installation/index.html +++ b/docs/posts/installation/index.html @@ -100,6 +100,7 @@ height="0" width="0" style="display:none;visibility:hidden">
  • +
diff --git a/docs/posts/modules/bamboohr/index.html b/docs/posts/modules/bamboohr/index.html index ead69742..23becca7 100644 --- a/docs/posts/modules/bamboohr/index.html +++ b/docs/posts/modules/bamboohr/index.html @@ -100,6 +100,7 @@ height="0" width="0" style="display:none;visibility:hidden"> + diff --git a/docs/posts/modules/circleci/index.html b/docs/posts/modules/circleci/index.html index 506d3835..5b0627fa 100644 --- a/docs/posts/modules/circleci/index.html +++ b/docs/posts/modules/circleci/index.html @@ -100,6 +100,7 @@ height="0" width="0" style="display:none;visibility:hidden"> + diff --git a/docs/posts/modules/clocks/index.html b/docs/posts/modules/clocks/index.html index a7a3fcc7..1113e5b7 100644 --- a/docs/posts/modules/clocks/index.html +++ b/docs/posts/modules/clocks/index.html @@ -100,6 +100,7 @@ height="0" width="0" style="display:none;visibility:hidden"> + diff --git a/docs/posts/modules/cmdrunner/index.html b/docs/posts/modules/cmdrunner/index.html index e23d45cc..5aed4c1d 100644 --- a/docs/posts/modules/cmdrunner/index.html +++ b/docs/posts/modules/cmdrunner/index.html @@ -100,6 +100,7 @@ height="0" width="0" style="display:none;visibility:hidden"> + diff --git a/docs/posts/modules/cryptocurrencies/bittrex/index.html b/docs/posts/modules/cryptocurrencies/bittrex/index.html index 1496dbfe..b728e8e2 100644 --- a/docs/posts/modules/cryptocurrencies/bittrex/index.html +++ b/docs/posts/modules/cryptocurrencies/bittrex/index.html @@ -100,6 +100,7 @@ height="0" width="0" style="display:none;visibility:hidden"> + diff --git a/docs/posts/modules/cryptocurrencies/blockfolio/index.html b/docs/posts/modules/cryptocurrencies/blockfolio/index.html index 5e67be49..6adfc5e6 100644 --- a/docs/posts/modules/cryptocurrencies/blockfolio/index.html +++ b/docs/posts/modules/cryptocurrencies/blockfolio/index.html @@ -100,6 +100,7 @@ height="0" width="0" style="display:none;visibility:hidden"> + diff --git a/docs/posts/modules/cryptocurrencies/cryptolive/index.html b/docs/posts/modules/cryptocurrencies/cryptolive/index.html index 8fe0beda..ae56f675 100644 --- a/docs/posts/modules/cryptocurrencies/cryptolive/index.html +++ b/docs/posts/modules/cryptocurrencies/cryptolive/index.html @@ -100,6 +100,7 @@ height="0" width="0" style="display:none;visibility:hidden"> + diff --git a/docs/posts/modules/gcal/index.html b/docs/posts/modules/gcal/index.html index 9c80a9b9..2f6df721 100644 --- a/docs/posts/modules/gcal/index.html +++ b/docs/posts/modules/gcal/index.html @@ -100,6 +100,7 @@ height="0" width="0" style="display:none;visibility:hidden"> + diff --git a/docs/posts/modules/gerrit/index.html b/docs/posts/modules/gerrit/index.html index ec7e5f5a..7b6b599e 100644 --- a/docs/posts/modules/gerrit/index.html +++ b/docs/posts/modules/gerrit/index.html @@ -100,6 +100,7 @@ height="0" width="0" style="display:none;visibility:hidden"> + diff --git a/docs/posts/modules/git/index.html b/docs/posts/modules/git/index.html index f90b4e13..fe40f145 100644 --- a/docs/posts/modules/git/index.html +++ b/docs/posts/modules/git/index.html @@ -100,6 +100,7 @@ height="0" width="0" style="display:none;visibility:hidden"> + diff --git a/docs/posts/modules/github/index.html b/docs/posts/modules/github/index.html index 4580bea5..188869f9 100644 --- a/docs/posts/modules/github/index.html +++ b/docs/posts/modules/github/index.html @@ -100,6 +100,7 @@ height="0" width="0" style="display:none;visibility:hidden"> + diff --git a/docs/posts/modules/gitlab/index.html b/docs/posts/modules/gitlab/index.html index e0e91c79..7812d6a6 100644 --- a/docs/posts/modules/gitlab/index.html +++ b/docs/posts/modules/gitlab/index.html @@ -100,6 +100,7 @@ height="0" width="0" style="display:none;visibility:hidden"> + diff --git a/docs/posts/modules/gspreadsheet/index.html b/docs/posts/modules/gspreadsheet/index.html index 48726ddc..1aa1d038 100644 --- a/docs/posts/modules/gspreadsheet/index.html +++ b/docs/posts/modules/gspreadsheet/index.html @@ -100,6 +100,7 @@ height="0" width="0" style="display:none;visibility:hidden"> + diff --git a/docs/posts/modules/index.html b/docs/posts/modules/index.html index 86ea00db..5a506e17 100644 --- a/docs/posts/modules/index.html +++ b/docs/posts/modules/index.html @@ -100,6 +100,7 @@ height="0" width="0" style="display:none;visibility:hidden"> + diff --git a/docs/posts/modules/ipapi/index.html b/docs/posts/modules/ipapi/index.html index 77be17f2..c7c06274 100644 --- a/docs/posts/modules/ipapi/index.html +++ b/docs/posts/modules/ipapi/index.html @@ -100,6 +100,7 @@ height="0" width="0" style="display:none;visibility:hidden"> + diff --git a/docs/posts/modules/ipinfo/index.html b/docs/posts/modules/ipinfo/index.html index 735a03fd..a11210a1 100644 --- a/docs/posts/modules/ipinfo/index.html +++ b/docs/posts/modules/ipinfo/index.html @@ -100,6 +100,7 @@ height="0" width="0" style="display:none;visibility:hidden"> + diff --git a/docs/posts/modules/jenkins/index.html b/docs/posts/modules/jenkins/index.html index 6bd495bf..f1fd8578 100644 --- a/docs/posts/modules/jenkins/index.html +++ b/docs/posts/modules/jenkins/index.html @@ -100,6 +100,7 @@ height="0" width="0" style="display:none;visibility:hidden"> + diff --git a/docs/posts/modules/jira/index.html b/docs/posts/modules/jira/index.html index a670349b..edcfcad4 100644 --- a/docs/posts/modules/jira/index.html +++ b/docs/posts/modules/jira/index.html @@ -100,6 +100,7 @@ height="0" width="0" style="display:none;visibility:hidden"> + diff --git a/docs/posts/modules/logger/index.html b/docs/posts/modules/logger/index.html index 9f9d0f24..4e052125 100644 --- a/docs/posts/modules/logger/index.html +++ b/docs/posts/modules/logger/index.html @@ -100,6 +100,7 @@ height="0" width="0" style="display:none;visibility:hidden"> + diff --git a/docs/posts/modules/newrelic/index.html b/docs/posts/modules/newrelic/index.html index b8d9b8af..7919546e 100644 --- a/docs/posts/modules/newrelic/index.html +++ b/docs/posts/modules/newrelic/index.html @@ -100,6 +100,7 @@ height="0" width="0" style="display:none;visibility:hidden"> + diff --git a/docs/posts/modules/opsgenie/index.html b/docs/posts/modules/opsgenie/index.html index d85f1fbd..3ec66dd1 100644 --- a/docs/posts/modules/opsgenie/index.html +++ b/docs/posts/modules/opsgenie/index.html @@ -100,6 +100,7 @@ height="0" width="0" style="display:none;visibility:hidden"> + diff --git a/docs/posts/modules/power/index.html b/docs/posts/modules/power/index.html index 106b6276..47cf3131 100644 --- a/docs/posts/modules/power/index.html +++ b/docs/posts/modules/power/index.html @@ -100,6 +100,7 @@ height="0" width="0" style="display:none;visibility:hidden"> + diff --git a/docs/posts/modules/prettyweather/index.html b/docs/posts/modules/prettyweather/index.html index fc8807ae..3c3c89ad 100644 --- a/docs/posts/modules/prettyweather/index.html +++ b/docs/posts/modules/prettyweather/index.html @@ -100,6 +100,7 @@ height="0" width="0" style="display:none;visibility:hidden"> + diff --git a/docs/posts/modules/security/index.html b/docs/posts/modules/security/index.html index 1c3892e3..86fcfe76 100644 --- a/docs/posts/modules/security/index.html +++ b/docs/posts/modules/security/index.html @@ -100,6 +100,7 @@ height="0" width="0" style="display:none;visibility:hidden"> + diff --git a/docs/posts/modules/textfile/index.html b/docs/posts/modules/textfile/index.html index 37684dfa..76082334 100644 --- a/docs/posts/modules/textfile/index.html +++ b/docs/posts/modules/textfile/index.html @@ -100,6 +100,7 @@ height="0" width="0" style="display:none;visibility:hidden"> + diff --git a/docs/posts/modules/todo/index.html b/docs/posts/modules/todo/index.html index 64eabf95..afb9c6df 100644 --- a/docs/posts/modules/todo/index.html +++ b/docs/posts/modules/todo/index.html @@ -100,6 +100,7 @@ height="0" width="0" style="display:none;visibility:hidden"> + diff --git a/docs/posts/modules/trello/index.html b/docs/posts/modules/trello/index.html index 30f0dc0d..0bcd3488 100644 --- a/docs/posts/modules/trello/index.html +++ b/docs/posts/modules/trello/index.html @@ -100,6 +100,7 @@ height="0" width="0" style="display:none;visibility:hidden"> + diff --git a/docs/posts/modules/weather/index.html b/docs/posts/modules/weather/index.html index c9e28f90..44ce4cd4 100644 --- a/docs/posts/modules/weather/index.html +++ b/docs/posts/modules/weather/index.html @@ -100,6 +100,7 @@ height="0" width="0" style="display:none;visibility:hidden"> + diff --git a/docs/posts/overview/index.html b/docs/posts/overview/index.html index f77aaaef..e0fdfea6 100644 --- a/docs/posts/overview/index.html +++ b/docs/posts/overview/index.html @@ -100,6 +100,7 @@ height="0" width="0" style="display:none;visibility:hidden"> + diff --git a/docs/sitemap.xml b/docs/sitemap.xml index 8e94ebea..fbd256d7 100644 --- a/docs/sitemap.xml +++ b/docs/sitemap.xml @@ -2,6 +2,11 @@ + + https://wtfutil.com/posts/modules/todoist/ + 2018-07-05T22:55:55-03:00 + + https://wtfutil.com/posts/modules/gerrit/ 2018-06-27T15:55:42-07:00 @@ -179,7 +184,7 @@ https://wtfutil.com/posts/ - 2018-06-27T15:55:42-07:00 + 2018-07-05T22:55:55-03:00 0 @@ -190,7 +195,7 @@ https://wtfutil.com/ - 2018-06-27T15:55:42-07:00 + 2018-07-05T22:55:55-03:00 0 diff --git a/docs/tags/index.html b/docs/tags/index.html index 3a799d0c..cc1bd7e3 100644 --- a/docs/tags/index.html +++ b/docs/tags/index.html @@ -102,6 +102,7 @@ height="0" width="0" style="display:none;visibility:hidden"> + From 37bb02571e2cc47e2d14ec5ebf61f38969352153 Mon Sep 17 00:00:00 2001 From: Chris Cummer Date: Wed, 11 Jul 2018 10:30:22 -0700 Subject: [PATCH 08/16] Update documentation for Todoist module --- docs/imgs/modules/todoist.png | Bin 0 -> 3335 bytes docs/posts/modules/todoist/index.html | 226 ++++++++++++++++++++++++++ 2 files changed, 226 insertions(+) create mode 100644 docs/imgs/modules/todoist.png create mode 100644 docs/posts/modules/todoist/index.html diff --git a/docs/imgs/modules/todoist.png b/docs/imgs/modules/todoist.png new file mode 100644 index 0000000000000000000000000000000000000000..086d0ec8673a4f407e2b0c382fd9e547711a0909 GIT binary patch literal 3335 zcmeHK=Q|r*8xLBvwOW)uXpEK)qtq&DRqPl|Q8QX2_KrPDNs6ZwwTs8D{lt94hzh0k zSPf#u4$_)Mh!Jo63Gb)(%X?qfIrljq&hOmUz0U8%n;7Y^Uj5@L003as)75$o0MJ>} z*4@nXwArPB97j`Ed~_}S0RXn1i$RzEkc|%jU}@FU(s&X4X_MgT!3m4$+J&i*FYzmH z%k$M}iRjd@m0k}r%eiVa?ibMZN!XXzT#;oiS+G@e)s5lo3v@h>g1YGp zKfZ0SI)7_sStsPQM}m%KA^`Blu9?7_rh7t0GGl_(NS^wDpb*cs`gPm-#us{C7RnArGrsT#}GaP!20 zCFO;I{(ygZ5lTqLm-fdh=`C73ia${jp&MC>dqH6j*RGRo!yv`Vn0a?yb1Ew z_EwlR&vW}Wm%7vBvu{4uJa_Xp^ZXQC=Nm*^a)1T5-Rmw_`dZ3juiCCj_j>N2xtZAk zdB$5uIK>-tMs8ipud1!>^j${aNT;WJ!^NZP@tk6>x8)3<)YsK{e;?E?Hbr7h&COSL zgKKSCQ-@$BN@kwffhTHSe6K`gcqycA;}E%!XeoN(2QQG785O3+vH^Ext2}>Of%Aer z2V?fj443K_ii(7>kHR}Kr@-GsdCI-Ly^)yt?ZZAJ>C?!lJ2$euRswQ2*ViZi@hzU& zOwtn0%gf_5etKguunicxUU)<}K0ZErG8B=W0Pf}}J<)dv;s(dFX~%I;*)X2PHDk7J zT7QlXjV@%{FP&ho$$>;WO$HCCS4eAn6fV$xaq&OTAX4}5?}m2R)#05RvJFLT@tc8d zQy%$Vj^WBFx;>6E;8_p%3;Fdu{bA6?zXgj&C!IdWHstPDAed?U?1{;OlExhg-j-k=p?ni-D36hrMjd6 ze6Fat&N(4-8wf0zvHFUFL+JhmJ9ieo zu(9#r{Yq;ruY=^keEj@ewEI~E^;{oxm-N0vA`qH|BddeC%kF7k@3dw}zqwONs($t3 zbq^McJv%#NWo6ANbImcQ1=r3_GSzNi(ox1W$5|$ON#Qx=(;M-RWe%}(b93WW7A-9; zztD5Dv;54LX1#)FoyXcbx3ZFffnghS-pNr^UtizaI_1_x>%w~Ow~TXCiN)2H4XdS@ zb_s;YrFb#6+bT!BJkXNGDLPByTvH)rHxC53#^L^qA!}j`w7#`*eiehbx7 za2&T#4p1t1KU!r*7}sTTGy*)0BFCT^)|np#u@?P2Jt z^*TXzCp`Cm!Bbv$DT(SEfF>QPe(-w7K16s=pl&QpdY{W<`rZDxvR)Axqb{#U1An$y zR-Au~8IY2a-QG??o+(E`0&skuE||^6im>z6mFdkLiKu{x_n!9m+N(~C@8q67H zxe91COKpcJXzl6btM~hyXSTRHY0NMp-EJ^EOF6{sUJ-gAkg?i#tvcu1<3Hf%bIREL zFkq1niiD49c*(q*>y+pa6|#w2q*{mHrOPV4UyCsM5_FSJT-}D1)!qtc!y0k_k^Fc{ zh|ER$U2LUC3siK&@4SgiZeRr5pk?U?nmYn)^9G1YJ`3vlespY-FU9nsmpr`w@AUJ$;617ZY0$?yW zr)=;riNR8GW&*)>i9T9=p*UI9s>y9!Bw6JL9)vPowbvt5zltxT)2UqzNyf&s9V8OwPPlwt1 zA5^olu87wn7#~SYAQ%Nv^0I*V3y**Rf~J@Lul_eK$aXjmha#|Bn#^gIyyy{l zA@g0_34K!E1PbOR#)*Xi3xeXlF4cB?VG$L|j{gg+f2H-RstT#ru^B q7|y|lR6E(8uUO$TD6+?G5-OUl?^}u literal 0 HcmV?d00001 diff --git a/docs/posts/modules/todoist/index.html b/docs/posts/modules/todoist/index.html new file mode 100644 index 00000000..6891cd30 --- /dev/null +++ b/docs/posts/modules/todoist/index.html @@ -0,0 +1,226 @@ + + + + + + + + + + + + +Todoist | WTF - A Terminal Dashboard + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+

Todoist

+ +
+ +
+ + + +

Added in v0.0.11.

+ +

Displays all items on specified project.

+ +

todoist screenshot

+ +

Source Code

+
wtf/todoist/
+

Required ENV Variables

+ +

Key: WTF_TODOIST_TOKEN
+Value: Your Todoist API Token.

+ +

You can get your API Token at: todoist.com/prefs/integrations.

+ +

Keyboard Commands

+ +

Key: h
+Action: Show the previous project.

+ +

Key:
+Action: Show the previous project.

+ +

Key: l
+Action: Show the next project.

+ +

Key:
+Action: Show the next project.

+ +

Key: j
+Action: Select the next item in the list.

+ +

Key:
+Action: Select the next item in the list.

+ +

Key: k
+Action: Select the previous item in the list.

+ +

Key:
+Action: Select the previous item in the list.

+ +

Key: c
+Action: Close current item.

+ +

Key: d
+Action: Delete current item.

+ +

Key: r
+Action: Reload all projects.

+ +

Configuration

+
todoist:
+  projects:
+    - project_id
+  enabled: true
+  position:
+    height: 1
+    left: 2
+    top: 0
+    width: 1
+  refreshInterval: 3600
+

Attributes

+ +

enabled
+Determines whether or not this module is executed and if its data displayed onscreen.
+Values: true, false.

+ +

projects
+The todoist projects to fetch items from.

+ +

refreshInterval
+How often, in seconds, this module will update its data.
+Values: A positive integer, 0..n.

+ +

position
+Where in the grid this module’s widget will be displayed.

+ +
+ + +
+ + + + From 995cd59176f0f7279be0c200ffdf14f8b4441aa9 Mon Sep 17 00:00:00 2001 From: Chris Cummer Date: Wed, 11 Jul 2018 13:46:43 -0700 Subject: [PATCH 09/16] Clean up the Todoist documentation a bit --- _site/content/posts/modules/todoist.md | 17 +++++++++-------- docs/posts/modules/todoist/index.html | 19 ++++++++++--------- 2 files changed, 19 insertions(+), 17 deletions(-) diff --git a/_site/content/posts/modules/todoist.md b/_site/content/posts/modules/todoist.md index 4467f165..b1a431bc 100644 --- a/_site/content/posts/modules/todoist.md +++ b/_site/content/posts/modules/todoist.md @@ -32,7 +32,7 @@ _You can get your API Token at: todoist.com/prefs/integrations._ Action: Show the previous project. Key: `l`
-Action: Show the next project. +Action: Show the next project. Key: `→`
Action: Show the next project. @@ -62,14 +62,14 @@ _You can get your API Token at: todoist.com/prefs/integrations._ ```yaml todoist: - projects: - - project_id enabled: true position: - height: 1 - left: 2 top: 0 + left: 2 + height: 1 width: 1 + projects: + - 122247497 refreshInterval: 3600 ``` @@ -79,12 +79,13 @@ todoist: Determines whether or not this module is executed and if its data displayed onscreen.
Values: `true`, `false`. +`position`
+Where in the grid this module's widget will be displayed.
+ `projects`
The todoist projects to fetch items from.
+Values: The integer ID of the project. `refreshInterval`
How often, in seconds, this module will update its data.
Values: A positive integer, `0..n`. - -`position`
-Where in the grid this module's widget will be displayed.
diff --git a/docs/posts/modules/todoist/index.html b/docs/posts/modules/todoist/index.html index 6891cd30..f4404ac4 100644 --- a/docs/posts/modules/todoist/index.html +++ b/docs/posts/modules/todoist/index.html @@ -159,7 +159,7 @@ height="0" width="0" style="display:none;visibility:hidden"> Action: Show the previous project.

Key: l
-Action: Show the next project.

+Action: Show the next project.

Key:
Action: Show the next project.

@@ -187,14 +187,14 @@ height="0" width="0" style="display:none;visibility:hidden">

Configuration

todoist:
-  projects:
-    - project_id
   enabled: true
   position:
-    height: 1
-    left: 2
     top: 0
+    left: 2
+    height: 1
     width: 1
+  projects:
+    - 122247497
   refreshInterval: 3600

Attributes

@@ -202,16 +202,17 @@ height="0" width="0" style="display:none;visibility:hidden"> Determines whether or not this module is executed and if its data displayed onscreen.
Values: true, false.

+

position
+Where in the grid this module’s widget will be displayed.

+

projects
-The todoist projects to fetch items from.

+The todoist projects to fetch items from.
+Values: The integer ID of the project.

refreshInterval
How often, in seconds, this module will update its data.
Values: A positive integer, 0..n.

-

position
-Where in the grid this module’s widget will be displayed.

-