diff --git a/.all-contributorsrc b/.all-contributorsrc index 4e7ab7a1..5cf33286 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -693,6 +693,13 @@ "name": "Lawrence Craft", "avatar_url": "https://avatars0.githubusercontent.com/u/660580?v=4", "profile": "https://github.com/lawrencecraft", + "contributions": [] + }, + { + "login": "aviaviavi", + "name": "Avi Press", + "avatar_url": "https://avatars1.githubusercontent.com/u/1388071?v=4", + "profile": "http://avi.press", "contributions": [ ] } diff --git a/CHANGELOG.md b/CHANGELOG.md index 553f337d..22b1eb65 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,10 +8,16 @@ * [Dev.to](https://wtfutil.com/modules/devto/) module added, by [@VictorAvelar](https://github.com/VictorAvelar) * [TravisCI]() module now supports enterprise endpoints, [#652](https://github.com/wtfutil/wtf/issues/652) by [@scw007](https://github.com/scw007) * [Subreddit](https://wtfutil.com/modules/subreddit/) module added, by [@lawrencecraft](https://github.com/lawrencecraft) +* [gCal](https://wtfutil.com/modules/google/gcal/) module now supports a `hourFormat` setting for defining whether to display 12 or 24-hour times, [#665](https://github.com/wtfutil/wtf/issues/665) by [@senorprogrammer](https://github.com/senorprogrammer) +* [Scarf](https://scarf.sh) installation instructions added to README, by [@aviaviavi](https://github.com/aviaviavi) ### 🐞 Fixed * gCal calendar event time colour can now be changed by setting the `eventTime` configuration setting, [#638](https://github.com/wtfutil/wtf/issues/638) by [@indradhanush](https://github.com/indradhanush) +* [Clocks](https://wtfutil.com/modules/clocks/) now obeys global row colour settings, [#658](https://github.com/wtfutil/wtf/issues/658) by [@senorprogrammer](https://github.com/senorprogrammer) +* [Transmission](https://wtfutil.com/modules/transmission/) module no longer blocks rendering when a Transmission daemon cannot be found, [#661](https://github.com/wtfutil/wtf/issues/661) by [@senorprogrammer](https://github.com/senorprogrammer) +* [Trello](https://wtfutil.com/modules/trello/) module now respects project list order, [#664](https://github.com/wtfutil/wtf/issues/664) by [@Seanstoppable](https://github.com/Seanstoppable) +* [Todo](https://wtfutil.com/modules/todo/) module now respects checkbox settings, [#616](https://github.com/wtfutil/wtf/issues/616) by [@Seanstoppable](https://github.com/Seanstoppable) ### 👍 Updated diff --git a/README.md b/README.md index bca669a5..6ef384f2 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,5 @@ -[![All Contributors](https://img.shields.io/badge/all_contributors-98-orange.svg?style=flat-square)](#contributors) +[![All Contributors](https://img.shields.io/badge/all_contributors-99-orange.svg?style=flat-square)](#contributors) [![Build Status](https://travis-ci.com/wtfutil/wtf.svg?branch=master)](https://travis-ci.com/wtfutil/wtf) [![Twitter](https://img.shields.io/badge/follow-on%20twitter-blue.svg)](https://twitter.com/wtfutil) [![Go Report Card](https://goreportcard.com/badge/github.com/wtfutil/wtf)](https://goreportcard.com/report/github.com/wtfutil/wtf) @@ -65,6 +65,16 @@ sudo port install wtfutil wtfutil ``` +### Install via Scarf + +If you're interested in supporting wtfutil, please consider installing via [Scarf](https://scarf.sh/package/senorprogrammer/wtfutil). + +```console +scarf install wtfutil + +wtfutil +``` + ### Install a Binary [Download the latest binary](https://github.com/wtfutil/wtf/releases) from GitHub. @@ -193,6 +203,7 @@ Dependency management in WTF is handled by [Go modules](https://github.com/golan | [Bob 'Wombat' Hogg
Bob 'Wombat' Hogg](https://github.com/rwhogg)
| [Christopher Hall
Christopher Hall](https://github.com/hxw)
| [Heitor Neiva
Heitor Neiva](https://github.com/hneiva)
| [Herby Gillot
Herby Gillot](https://github.com/herbygillot)
| [James Canning
James Canning](http://brudil.com)
| [jeffz
jeffz](https://twitter.com/jeffz4000)
| [Mikkel Jeppesen Juhl
Mikkel Jeppesen Juhl](https://mikkeljuhl.com)
| | [Erik
Erik](https://github.com/lesteenman)
| [Nate Yourchuck
Nate Yourchuck](https://github.com/nyourchuck)
| [Casey Primozic
Casey Primozic](https://cprimozic.net/)
| [Alvaro [Andor]
Alvaro [Andor]](http://pierdelacabeza.com/maruja)
| [Joel Valentine
Joel Valentine](https://github.com/Midnight-Conqueror)
| [Viktor Braun
Viktor Braun](https://www.viktor-braun.de)
| [ChrisDBrown
ChrisDBrown](https://www.chrisdbrown.co.uk/)
| | [Narendra L
Narendra L](https://narengowda.github.io/)
| [ibaum
ibaum](https://github.com/ibaum)
| [Tim Scheuermann
Tim Scheuermann](https://github.com/noxer)
| [Indradhanush Gupta
Indradhanush Gupta](https://indradhanush.github.io/)
| [Victor Hugo Avelar Ossorio
Victor Hugo Avelar Ossorio](https://victoravelar.com)
| [Steven Whitehead
Steven Whitehead](https://github.com/scw007)
| [Lawrence Craft
Lawrence Craft](https://github.com/lawrencecraft)
| +| [Avi Press
Avi Press](http://avi.press)
| ## Acknowledgments diff --git a/modules/clocks/display.go b/modules/clocks/display.go index 36379b1f..7c1a5bca 100644 --- a/modules/clocks/display.go +++ b/modules/clocks/display.go @@ -11,15 +11,9 @@ func (widget *Widget) display(clocks []Clock, dateFormat string, timeFormat stri } else { for idx, clock := range clocks { - rowColor := widget.settings.colors.rows.odd - - if idx%2 == 0 { - rowColor = widget.settings.colors.rows.even - } - str += fmt.Sprintf( " [%s]%-12s %-10s %7s[white]\n", - rowColor, + widget.CommonSettings().RowColor(idx), clock.Label, clock.Time(timeFormat), clock.Date(dateFormat), diff --git a/modules/clocks/settings.go b/modules/clocks/settings.go index 113f454e..4106dcaf 100644 --- a/modules/clocks/settings.go +++ b/modules/clocks/settings.go @@ -11,15 +11,8 @@ const ( defaultTitle = "Clocks" ) -type colors struct { - rows struct { - even string - odd string - } -} - +// Settings defines the configuration properties for this module type Settings struct { - colors common *cfg.Common dateFormat string `help:"The format of the date string for all clocks." values:"Any valid Go date layout which is handled by Time.Format. Defaults to Jan 2."` @@ -28,6 +21,7 @@ type Settings struct { sort string `help:"Defines the display order of the clocks in the widget." values:"'alphabetical' or 'chronological'. 'alphabetical' will sort in acending order by key, 'chronological' will sort in ascending order by date/time."` } +// NewSettingsFromYAML creates a new settings instance from a YAML config block func NewSettingsFromYAML(name string, ymlConfig *config.Config, globalConfig *config.Config) *Settings { settings := Settings{ common: cfg.NewCommonSettingsFromModule(name, defaultTitle, defaultFocusable, ymlConfig, globalConfig), @@ -38,8 +32,5 @@ func NewSettingsFromYAML(name string, ymlConfig *config.Config, globalConfig *co sort: ymlConfig.UString("sort"), } - settings.colors.rows.even = ymlConfig.UString("colors.rows.even", "white") - settings.colors.rows.odd = ymlConfig.UString("colors.rows.odd", "blue") - return &settings } diff --git a/modules/digitalclock/settings.go b/modules/digitalclock/settings.go index b4e6f4ea..669d3da3 100644 --- a/modules/digitalclock/settings.go +++ b/modules/digitalclock/settings.go @@ -24,10 +24,11 @@ type Settings struct { func NewSettingsFromYAML(name string, ymlConfig *config.Config, globalConfig *config.Config) *Settings { settings := Settings{ - common: cfg.NewCommonSettingsFromModule(name, defaultTitle, defaultFocusable, ymlConfig, globalConfig), + common: cfg.NewCommonSettingsFromModule(name, defaultTitle, defaultFocusable, ymlConfig, globalConfig), + color: ymlConfig.UString("color"), font: ymlConfig.UString("font"), - hourFormat: ymlConfig.UString("hourFormat"), + hourFormat: ymlConfig.UString("hourFormat", "24"), } return &settings diff --git a/modules/gcal/cal_event.go b/modules/gcal/cal_event.go index ff0cd82e..1cedcde6 100644 --- a/modules/gcal/cal_event.go +++ b/modules/gcal/cal_event.go @@ -97,12 +97,17 @@ func (calEvent *CalEvent) Start() time.Time { return start } -func (calEvent *CalEvent) Timestamp() string { +func (calEvent *CalEvent) Timestamp(hourFormat string) string { if calEvent.AllDay() { startTime, _ := time.ParseInLocation("2006-01-02", calEvent.event.Start.Date, time.Local) return startTime.Format(utils.FriendlyDateFormat) } startTime, _ := time.Parse(time.RFC3339, calEvent.event.Start.DateTime) - return startTime.Format(utils.MinimumTimeFormat) + + timeFormat := utils.MinimumTimeFormat24 + if hourFormat == "12" { + timeFormat = utils.MinimumTimeFormat12 + } + return startTime.Format(timeFormat) } diff --git a/modules/gcal/display.go b/modules/gcal/display.go index 57e7b63d..6bb843b2 100644 --- a/modules/gcal/display.go +++ b/modules/gcal/display.go @@ -48,7 +48,7 @@ func (widget *Widget) content() (string, string, bool) { } for _, calEvent := range calEvents { - timestamp := fmt.Sprintf("[%s]%s", widget.eventTimeColor(calEvent), calEvent.Timestamp()) + timestamp := fmt.Sprintf("[%s]%s", widget.eventTimeColor(calEvent), calEvent.Timestamp(widget.settings.hourFormat)) if calEvent.AllDay() { timestamp = "" } diff --git a/modules/gcal/settings.go b/modules/gcal/settings.go index afea75bf..3f5abf24 100644 --- a/modules/gcal/settings.go +++ b/modules/gcal/settings.go @@ -30,6 +30,7 @@ type Settings struct { displayResponseStatus bool `help:"Whether or not to display your response status to the calendar event." values:"true or false" optional:"true"` email string `help:"The email address associated with your Google account. Necessary for determining 'responseStatus'." values:"A valid email address string."` eventCount int `help:"The number of calendar events to display." values:"A positive integer, 0..n." optional:"true"` + hourFormat string `help:"The format of the clock." values:"12 or 24"` multiCalendar bool `help:"Whether or not to display your primary calendar or all calendars you have access to." values:"true or false" optional:"true"` secretFile string `help:"Your Google client secret JSON file." values:"A string representing a file path to the JSON secret file."` showDeclined bool `help:"Whether or not to display events you’ve declined to attend." values:"true or false" optional:"true"` @@ -48,6 +49,7 @@ func NewSettingsFromYAML(name string, ymlConfig *config.Config, globalConfig *co displayResponseStatus: ymlConfig.UBool("displayResponseStatus", true), email: ymlConfig.UString("email", ""), eventCount: ymlConfig.UInt("eventCount", 10), + hourFormat: ymlConfig.UString("hourFormat", "24"), multiCalendar: ymlConfig.UBool("multiCalendar", false), secretFile: ymlConfig.UString("secretFile", ""), showDeclined: ymlConfig.UBool("showDeclined", false), diff --git a/modules/todo/settings.go b/modules/todo/settings.go index 9bde93ad..247acbdb 100644 --- a/modules/todo/settings.go +++ b/modules/todo/settings.go @@ -13,15 +13,21 @@ const ( type Settings struct { common *cfg.Common - filePath string + filePath string + checked string + unchecked string } func NewSettingsFromYAML(name string, ymlConfig *config.Config, globalConfig *config.Config) *Settings { - settings := Settings{ - common: cfg.NewCommonSettingsFromModule(name, defaultTitle, defaultFocusable, ymlConfig, globalConfig), + common := cfg.NewCommonSettingsFromModule(name, defaultTitle, defaultFocusable, ymlConfig, globalConfig) - filePath: ymlConfig.UString("filename"), + settings := Settings{ + common: common, + + filePath: ymlConfig.UString("filename"), + checked: ymlConfig.UString("checkedIcon", common.Checkbox.Checked), + unchecked: ymlConfig.UString("uncheckedIcon", common.Checkbox.Unchecked), } return &settings diff --git a/modules/todo/widget.go b/modules/todo/widget.go index dc68435e..dfbc357d 100644 --- a/modules/todo/widget.go +++ b/modules/todo/widget.go @@ -155,8 +155,8 @@ func (widget *Widget) persist() { // items have the correct checked/unchecked icon per the user's preferences func (widget *Widget) setItemChecks() { for _, item := range widget.list.Items { - item.CheckedIcon = widget.settings.common.Checkbox.Checked - item.UncheckedIcon = widget.settings.common.Checkbox.Unchecked + item.CheckedIcon = widget.settings.checked + item.UncheckedIcon = widget.settings.unchecked } } diff --git a/modules/transmission/widget.go b/modules/transmission/widget.go index 2b39293e..7649cb19 100644 --- a/modules/transmission/widget.go +++ b/modules/transmission/widget.go @@ -34,15 +34,7 @@ func NewWidget(app *tview.Application, pages *tview.Pages, settings *Settings) * widget.KeyboardWidget.SetView(widget.View) - // Create a persisten transmission client for use in the calls below - client, err := transmissionrpc.New(widget.settings.host, widget.settings.username, widget.settings.password, - &transmissionrpc.AdvancedConfig{ - Port: widget.settings.port, - }) - if err != nil { - client = nil - } - widget.client = client + go buildClient(&widget) return &widget } @@ -52,7 +44,7 @@ func NewWidget(app *tview.Application, pages *tview.Pages, settings *Settings) * // Fetch retrieves torrent data from the Transmission daemon func (widget *Widget) Fetch() ([]*transmissionrpc.Torrent, error) { if widget.client == nil { - return nil, errors.New("client could not be initialized") + return nil, errors.New("client was not initialized") } torrents, err := widget.client.TorrentGetAll() @@ -102,6 +94,20 @@ func (widget *Widget) Unselect() { /* -------------------- Unexported Functions -------------------- */ +// buildClient creates a persisten transmission client +func buildClient(widget *Widget) { + client, err := transmissionrpc.New(widget.settings.host, widget.settings.username, widget.settings.password, + &transmissionrpc.AdvancedConfig{ + Port: widget.settings.port, + }) + if err != nil { + client = nil + } + widget.client = client + + widget.Refresh() +} + func (widget *Widget) currentTorrent() *transmissionrpc.Torrent { if len(widget.torrents) == 0 { return nil diff --git a/modules/trello/card.go b/modules/trello/card.go index e1487c94..31f3467c 100644 --- a/modules/trello/card.go +++ b/modules/trello/card.go @@ -6,3 +6,8 @@ type TrelloCard struct { List string Description string } + +type TrelloList struct { + ID string + Name string +} diff --git a/modules/trello/client.go b/modules/trello/client.go index e010ce1b..6df6cc22 100644 --- a/modules/trello/client.go +++ b/modules/trello/client.go @@ -6,13 +6,13 @@ import ( "github.com/adlio/trello" ) -func GetCards(client *trello.Client, username string, boardName string, lists map[string]string) (*SearchResult, error) { +func GetCards(client *trello.Client, username string, boardName string, listNames []string) (*SearchResult, error) { boardID, err := getBoardID(client, username, boardName) if err != nil { return nil, err } - lists, err = getListIDs(client, boardID, lists) + lists, err := getLists(client, boardID, listNames) if err != nil { return nil, err } @@ -20,8 +20,8 @@ func GetCards(client *trello.Client, username string, boardName string, lists ma searchResult := &SearchResult{Total: 0} searchResult.TrelloCards = make(map[string][]TrelloCard) - for listName, listID := range lists { - cards, err := getCardsOnList(client, listID) + for _, list := range lists { + cards, err := getCardsOnList(client, list.ID) if err != nil { return nil, err } @@ -32,14 +32,14 @@ func GetCards(client *trello.Client, username string, boardName string, lists ma for _, card := range cards { trelloCard := TrelloCard{ ID: card.ID, - List: listName, + List: list.Name, Name: card.Name, Description: card.Desc, } cardArray = append(cardArray, trelloCard) } - searchResult.TrelloCards[listName] = cardArray + searchResult.TrelloCards[list.Name] = cardArray } return searchResult, nil @@ -65,7 +65,13 @@ func getBoardID(client *trello.Client, username, boardName string) (string, erro return "", fmt.Errorf("could not find board with name %s", boardName) } -func getListIDs(client *trello.Client, boardID string, lists map[string]string) (map[string]string, error) { +func getLists(client *trello.Client, boardID string, listNames []string) ([]TrelloList, error) { + comparison := make(map[string]string, len(listNames)) + results := []TrelloList{} + //convert to a map for comparison + for _, item := range listNames { + comparison[item] = "" + } board, err := client.GetBoard(boardID, trello.Defaults()) if err != nil { return nil, err @@ -77,12 +83,12 @@ func getListIDs(client *trello.Client, boardID string, lists map[string]string) } for _, list := range boardLists { - if _, ok := lists[list.Name]; ok { - lists[list.Name] = list.ID + if _, ok := comparison[list.Name]; ok { + results = append(results, TrelloList{ID: list.ID, Name: list.Name}) } } - return lists, nil + return results, nil } func getCardsOnList(client *trello.Client, listID string) ([]*trello.Card, error) { diff --git a/modules/trello/settings.go b/modules/trello/settings.go index e43c7bad..aa36a7dc 100644 --- a/modules/trello/settings.go +++ b/modules/trello/settings.go @@ -18,7 +18,7 @@ type Settings struct { accessToken string apiKey string board string - list map[string]string + list []string username string } @@ -32,18 +32,18 @@ func NewSettingsFromYAML(name string, ymlConfig *config.Config, globalConfig *co username: ymlConfig.UString("username"), } - settings.list = mapifyList(ymlConfig, globalConfig) + settings.list = buildLists(ymlConfig, globalConfig) return &settings } -func mapifyList(ymlConfig *config.Config, globalConfig *config.Config) map[string]string { - lists := make(map[string]string) +func buildLists(ymlConfig *config.Config, globalConfig *config.Config) []string { + lists := []string{} // Single list list, err := ymlConfig.String("list") if err == nil { - lists[list] = list + lists = append(lists, list) return lists } @@ -51,7 +51,7 @@ func mapifyList(ymlConfig *config.Config, globalConfig *config.Config) map[strin listList := ymlConfig.UList("list") for _, listName := range listList { if list, ok := listName.(string); ok { - lists[list] = list + lists = append(lists, list) } } diff --git a/utils/utils.go b/utils/utils.go index 439ed81e..d01b79f8 100644 --- a/utils/utils.go +++ b/utils/utils.go @@ -13,9 +13,10 @@ import ( ) const ( - SimpleDateFormat = "Jan 2" - SimpleTimeFormat = "15:04 MST" - MinimumTimeFormat = "15:04" + SimpleDateFormat = "Jan 2" + SimpleTimeFormat = "15:04 MST" + MinimumTimeFormat12 = "3:04 PM" + MinimumTimeFormat24 = "15:04" FullDateFormat = "Monday, Jan 2" FriendlyDateFormat = "Mon, Jan 2"