Skip to content

Commit

Permalink
Merge pull request #11 from AarynSmith/styling-options
Browse files Browse the repository at this point in the history
Styling options
  • Loading branch information
YouEclipse authored Jul 10, 2020
2 parents 223d9bc + 2b2c478 commit 61f1ea5
Show file tree
Hide file tree
Showing 6 changed files with 210 additions and 23 deletions.
5 changes: 4 additions & 1 deletion .github/workflows/schedule.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,12 @@ jobs:
name: Update-gist
runs-on: ubuntu-latest
env:
WAKATIME_API_KEY: ${{ secrets.WAKATIME_API_KEY }}
GH_TOKEN: ${{ secrets.GH_TOKEN }}
GIST_ID: 9bc7025496e478f439b9cd43eba989a4
WAKATIME_API_KEY: ${{ secrets.WAKATIME_API_KEY }}
GIST_BARSTYLE: SOLIDLT
GIST_BARLENGTH: -1
GIST_TIMESTYLE: SHORT

steps:

Expand Down
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
.vscode
.env
3 changes: 3 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,9 @@ English | [简体中文](./README_zh.md)
1. Edit the [environment variable](https://github.com/YouEclipse/waka-box-go/actions/runs/126970182/workflow#L17-L19) in `.github/workflows/schedule.yml`:

- **GIST_ID:** The ID portion from your gist url: `https://gist.github.com/YouEclipse/`**`9bc7025496e478f439b9cd43eba989a4`**.
- **GIST_BARSTYLE:** Background of the progress bar. Default is "SOLIDLT" other options include "SOLIDMD", "SOLIDDK" for medium and dark backgrounds, "EMPTY" for blank background, and "UNDERSCORE" for a line along the bottom.
- **GIST_BARLENGTH:** Length of the progress bar. Default is 21. Set to -1 to auto size the bar.
- **GIST_TIMESTYLE** Abbreviate the time text. Default is "LONG" ( "# hrs # mins" ). "SHORT" updates the text to "#h#m".

1. Go to the repo **Settings > Secrets**
1. Add the following environment variables:
Expand Down
8 changes: 7 additions & 1 deletion cmd/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,13 @@ func main() {
ghUsername := os.Getenv("GH_USER")
gistID := os.Getenv("GIST_ID")

box := wakabox.NewBox(wakaAPIKey, ghUsername, ghToken)
style := wakabox.BoxStyle{
BarStyle: os.Getenv("GIST_BARSTYLE"),
BarLength: os.Getenv("GIST_BARLENGTH"),
TimeStyle: os.Getenv("GIST_TIMESTYLE"),
}

box := wakabox.NewBox(wakaAPIKey, ghUsername, ghToken, style)

lines, err := box.GetStats(context.Background())
if err != nil {
Expand Down
119 changes: 102 additions & 17 deletions pkg/box.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,19 +4,47 @@ import (
"context"
"fmt"
"math"
"strconv"
"strings"
"unicode/utf8"

wakatime "github.com/YouEclipse/wakatime-go/pkg"
"github.com/google/go-github/github"
)

// maxLineLength is the visible number of characters in a pinned gist box
// (accounting for the clock emoji)
const maxLineLength = 53

// BarStyle defines valid styles for the progress bar
var BarStyle = map[string][]rune{
"SOLIDLT": []rune(`░▏▎▍▌▋▊▉█`),
"SOLIDMD": []rune(`▒▏▎▍▌▋▊▉█`),
"SOLIDDK": []rune(`▓▏▎▍▌▋▊▉█`),
"EMPTY": []rune(` ▏▎▍▌▋▊▉█`),
"UNDERSCORE": []rune(`▁▏▎▍▌▋▊▉█`),
}

// BoxStyle contains information for initalizing a gist box style
type BoxStyle struct {
BarStyle string // Style of the progress bar as defined by BarStyle
BarLength string // Length of the bar as a string (gets converted to an Int)
TimeStyle string // Style of the time text. "SHORT" will be abbreviated.
barLengthInt int // Set automatically from the Length defined above
maxLangLen int // Set automatically from the list of languages from wakatime
maxTimeLen int // Set automatically from the list of times from wakatime

}

// Box contains a github and wakatime client and styling information for the gist box
type Box struct {
github *github.Client
wakatime *wakatime.Client
style BoxStyle
}

func NewBox(wakaAPIKey, ghUsername, ghToken string) *Box {
// NewBox creates a box struct with appropriate wakatime and github information and gist styling information
func NewBox(wakaAPIKey, ghUsername, ghToken string, style BoxStyle) *Box {
box := &Box{}

box.wakatime = wakatime.NewClient(wakaAPIKey, nil)
Expand All @@ -27,6 +55,16 @@ func NewBox(wakaAPIKey, ghUsername, ghToken string) *Box {
}
box.github = github.NewClient(tp.Client())

length, err := strconv.Atoi(style.BarLength)
if err != nil {
length = 21 //Default to 21
}
style.barLengthInt = length
if style.BarStyle == "" {
style.BarStyle = "SOLIDLT" // Default to SOLIDLT
}
box.style = style

return box
}

Expand All @@ -36,22 +74,13 @@ func (b *Box) GetStats(ctx context.Context) ([]string, error) {
if err != nil {
return nil, err
}
max := 0

if languages := stats.Data.Languages; len(languages) > 0 {
lines := make([]string, 0)
for _, stat := range languages {
if max >= 5 {
break
}

line := pad(*stat.Name, " ", 9) + " " +
pad("🕓 "+*stat.Text, " ", 15) + " " +
GenerateBarChart(ctx, *stat.Percent, 21) + " " +
pad(fmt.Sprintf("%.1f%%", *stat.Percent), " ", 5)
lines = append(lines, line)
max++
lines, err := b.GenerateGistLines(ctx, languages)
if err != nil {
return nil, err
}

return lines, nil
}
return []string{"Still Gathering Statistics..."}, nil
Expand All @@ -63,7 +92,6 @@ func (b *Box) GetGist(ctx context.Context, id string) (*github.Gist, error) {
if err != nil {
return nil, err
}

return gist, nil
}

Expand All @@ -73,10 +101,56 @@ func (b *Box) UpdateGist(ctx context.Context, id string, gist *github.Gist) erro
return err
}

// GenerateGistLines takes an slice of wakatime.StatItems, and generates a line for the gist.
func (b *Box) GenerateGistLines(ctx context.Context, languages []wakatime.StatItem) ([]string, error) {
max := 0
lines := make([]string, 0)
for _, stat := range languages {
if b.style.TimeStyle == "SHORT" {
*stat.Text = convertDuration(*stat.Text)
}
if b.style.maxTimeLen < len(*stat.Text) {
b.style.maxTimeLen = len(*stat.Text)
}
if b.style.maxLangLen < len(*stat.Name) {
b.style.maxLangLen = len(*stat.Name)
}
}
if b.style.barLengthInt < 0 {
b.style.barLengthInt = maxLineLength - (b.style.maxLangLen + b.style.maxTimeLen + 10)
}
for _, stat := range languages {
if max >= 5 {
break
}
lines = append(lines, b.ConstructLine(ctx, stat))
max++
}
return lines, nil
}

// ConstructLine formats a gist line from stat infomation
func (b *Box) ConstructLine(ctx context.Context, stat wakatime.StatItem) string {
return fmt.Sprintf("%-*s🕓 %-*s%s%5.1f%%",
b.style.maxLangLen+1, *stat.Name,
b.style.maxTimeLen+1, *stat.Text,
GenerateBarChart(ctx, *stat.Percent, b.style.barLengthInt, b.style.BarStyle),
*stat.Percent)
}

// GenerateBarChart generates a bar chart with the given percent and size.
func GenerateBarChart(ctx context.Context, percent float64, size int) string {
// Percent is a float64 from 0-100 representing the progress bar percentage
// Size is an int representing the length of the progress bar in characters
// BarType is a BarType representing the type of barchart: It can be one of the following:
// SOLIDLT SOLIDMD SOLIDDK: Block characters with a dotted background
// UNDERSCORE: Block characters with an line accross the boottom
// EMPTY: Block characters with an empty background
func GenerateBarChart(ctx context.Context, percent float64, size int, barType string) string {
// using rune as for utf-8 encoding
var syms = []rune(`░▏▎▍▌▋▊▉█`)
syms := BarStyle[barType]
if len(syms) > 9 {
panic("No Syms")
}

frac := int(math.Floor((float64(size) * 8 * percent) / 100))
barsFull := int(math.Floor(float64(frac) / 8))
Expand All @@ -100,3 +174,14 @@ func pad(s, pad string, targetLength int) string {

return s + strings.Repeat(pad, padding)
}

func convertDuration(t string) string {
r := strings.NewReplacer(
"hr", "h",
"min", "m",
"sec", "s",
" ", "",
"s", "",
)
return r.Replace(t)
}
97 changes: 93 additions & 4 deletions pkg/box_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package wakabox

import (
"context"
"fmt"
"os"
"strings"
"testing"
Expand All @@ -20,6 +21,7 @@ func TestGenerateBarChart(t *testing.T) {
ctx context.Context
percent float64
size int
style string
}

ctx := context.Background()
Expand All @@ -28,12 +30,33 @@ func TestGenerateBarChart(t *testing.T) {
args args
want string
}{
{
name: "barchart-0%-Empty",
args: args{
ctx: ctx,
percent: 0,
size: 21,
style: "EMPTY",
},
want: " ",
},
{
name: "barchart-23.5%-Underscore",
args: args{
ctx: ctx,
percent: 23.5,
size: 21,
style: "UNDERSCORE",
},
want: "████▉▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁",
},
{
name: "barchart-0%",
args: args{
ctx: ctx,
percent: 0,
size: 21,
style: "SOLIDLT",
},
want: "░░░░░░░░░░░░░░░░░░░░░",
},
Expand All @@ -43,6 +66,7 @@ func TestGenerateBarChart(t *testing.T) {
ctx: ctx,
percent: 23.5,
size: 21,
style: "SOLIDLT",
},
want: "████▉░░░░░░░░░░░░░░░░",
},
Expand All @@ -52,6 +76,7 @@ func TestGenerateBarChart(t *testing.T) {
ctx: ctx,
percent: 72.5,
size: 21,
style: "SOLIDLT",
},
want: "███████████████▏░░░░░",
},
Expand All @@ -61,25 +86,33 @@ func TestGenerateBarChart(t *testing.T) {
ctx: ctx,
percent: 100,
size: 21,
style: "SOLIDLT",
},
want: "█████████████████████",
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if got := GenerateBarChart(tt.args.ctx, tt.args.percent, tt.args.size); got != tt.want {
if got := GenerateBarChart(tt.args.ctx, tt.args.percent, tt.args.size, tt.args.style); got != tt.want {
t.Errorf("GenerateBarChart() = %v, want %v", got, tt.want)
}
})
}
}

func TestBox_GetStats(t *testing.T) {

wakaAPIKey := os.Getenv("WAKATIME_API_KEY")

ghToken := os.Getenv("GH_TOKEN")
ghUsername := os.Getenv("GH_USER")
box := NewBox(wakaAPIKey, ghUsername, ghToken)
style := BoxStyle{
BarStyle: os.Getenv("GIST_BARSTYLE"),
BarLength: os.Getenv("GIST_BARLENGTH"),
TimeStyle: os.Getenv("GIST_TIMESTYLE"),
}
fmt.Printf("%+v - %+v", style, BarStyle[style.BarStyle])
box := NewBox(wakaAPIKey, ghUsername, ghToken, style)

lines, err := box.GetStats(context.Background())
if err != nil {
Expand All @@ -94,10 +127,17 @@ func TestBox_Gist(t *testing.T) {

ghToken := os.Getenv("GH_TOKEN")
ghUsername := os.Getenv("GH_USER")
box := NewBox(wakaAPIKey, ghUsername, ghToken)
gistID := os.Getenv("GIST_ID")

style := BoxStyle{
BarStyle: os.Getenv("GIST_BARSTYLE"),
BarLength: os.Getenv("GIST_BARLENGTH"),
TimeStyle: os.Getenv("GIST_TIMESTYLE"),
}

box := NewBox(wakaAPIKey, ghUsername, ghToken, style)

ctx := context.Background()
gistID := os.Getenv("GIST_ID")
filename := "📊 Weekly development breakdown"
gist, err := box.GetGist(ctx, gistID)
if err != nil {
Expand All @@ -113,3 +153,52 @@ func TestBox_Gist(t *testing.T) {
t.Error(err)
}
}
func Test_convertTime(t *testing.T) {
type args struct {
t string
}
tests := []struct {
name string
want string
}{
{
name: "10 hrs",
want: "10h",
},
{
name: "18 hrs 40 mins",
want: "18h40m",
},
{
name: "1 hr 13 mins",
want: "1h13m",
},
{
name: "2 mins",
want: "2m",
},
{
name: "0 secs",
want: "0s",
},
{
name: "99 hrs 99 mins 99 secs",
want: "99h99m99s",
},
{
name: "1 sec",
want: "1s",
},
{
name: "1 min",
want: "1m",
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if got := convertDuration(tt.name); got != tt.want {
t.Errorf("convertTime() = %v, want %v", got, tt.want)
}
})
}
}

0 comments on commit 61f1ea5

Please sign in to comment.