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.
+
+
+
+## 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.
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
+
+ Jul 05, 2018
+
+
+
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
+
+
+
+
+
+ Jul 05, 2018
+
+
+
+
+
+
+
+
+
+
+
+
Added in v0.0.11
.
+
+
Displays all items on specified project.
+
+
+
+
Source Code
+
+
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.
-