Skip to content

Commit 57f0c99

Browse files
authored
Include holidays in summary and calendar (#10)
1 parent 3314b4b commit 57f0c99

File tree

6 files changed

+139
-10
lines changed

6 files changed

+139
-10
lines changed

CHANGELOG.md

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,10 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
66

77
## [Unreleased]
88

9+
## [0.7.0] - 2024-05-05
10+
### Added
11+
- Fetch national holidays from [date.nager.at](https://date.nager.at) if LC_TIME is present in environment. Holidays will be marked on calendar and excluded from month summary.
12+
913
## [0.6.0] - 2024-03-30
1014
### Changed
1115
- Replace [manifoldco/promptui](https://github.com/charmbracelet/huh) with [charmbracelet/huh](https://github.com/charmbracelet/huh) due to lack of maintainer
@@ -96,7 +100,8 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
96100
### Added
97101
- Initial release of gojira
98102

99-
[Unreleased]: https://github.com/jzyinq/gojira/compare/0.6.0...master
103+
[Unreleased]: https://github.com/jzyinq/gojira/compare/0.7.0...master
104+
[0.7.0]: https://github.com/jzyinq/gojira/compare/0.6.0...0.7.0
100105
[0.6.0]: https://github.com/jzyinq/gojira/compare/0.5.4...0.6.0
101106
[0.5.4]: https://github.com/jzyinq/gojira/compare/0.5.3...0.5.4
102107
[0.5.3]: https://github.com/jzyinq/gojira/compare/0.5.2...0.5.3
@@ -109,4 +114,4 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
109114
[0.2.2]: https://github.com/jzyinq/gojira/compare/0.2.1...0.2.2
110115
[0.2.1]: https://github.com/jzyinq/gojira/compare/0.2.0...0.2.1
111116
[0.2.0]: https://github.com/jzyinq/gojira/compare/0.1.0...0.2.0
112-
[0.1.0]: https://github.com/jzyinq/gojira/tree/0.1.0
117+
[0.1.0]: https://github.com/jzyinq/gojira/tree/0.1.0

gojira/calendar.go

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -35,21 +35,29 @@ func NewCalendar() *Calendar {
3535
}
3636

3737
func (c *Calendar) update() {
38+
c.setDate()
39+
c.setWeekdays()
40+
c.setDays()
41+
}
42+
43+
func (c *Calendar) setDate() {
3844
c.day = app.time.Day()
3945
c.month = app.time.Month()
4046
c.year = app.time.Year()
41-
c.Clear()
42-
43-
t := time.Date(c.year, c.month, 1, 0, 0, 0, 0, time.Local)
44-
daysInMonth := time.Date(c.year, c.month+1, 0, 0, 0, 0, 0, time.Local).Day()
47+
}
4548

46-
// Weekdays
49+
func (c *Calendar) setWeekdays() {
4750
weekdays := []string{"Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"}
4851
for i, day := range weekdays {
4952
c.SetCell(0, i, tview.NewTableCell(day))
5053
}
54+
}
55+
56+
func (c *Calendar) setDays() {
57+
c.Clear()
58+
t := time.Date(c.year, c.month, 1, 0, 0, 0, 0, time.Local)
59+
daysInMonth := time.Date(c.year, c.month+1, 0, 0, 0, 0, 0, time.Local).Day()
5160

52-
// Days
5361
week := 1
5462
for i := 1; i <= daysInMonth; i++ {
5563
dayOfWeek := int(t.Weekday()) - 1 // Weekday() returns 1 (Monday) to 7 (Sunday)
@@ -63,6 +71,7 @@ func (c *Calendar) update() {
6371
if calendarDay.Before(time.Now().Local()) {
6472
cell.SetBackgroundColor(tcell.ColorGray)
6573
}
74+
6675
if len(app.workLogs.logs) > 0 {
6776
worklogs, err := app.workLogs.LogsOnDate(&calendarDay)
6877
if err != nil {
@@ -78,6 +87,9 @@ func (c *Calendar) update() {
7887
}
7988
}
8089
}
90+
if app.holidays.IsHoliday(&calendarDay) {
91+
cell.SetTextColor(tcell.ColorRed)
92+
}
8193
if i == c.day {
8294
cell.SetTextColor(tcell.ColorWhite)
8395
cell.SetBackgroundColor(tcell.ColorDimGray)

gojira/cli.go

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,25 @@ var WorklogsCommand = &cli.Command{
2626
Usage: "Edit your today's work log",
2727
Action: func(c *cli.Context) error {
2828
newUi()
29-
loadWorklogs()
29+
var wg sync.WaitGroup
30+
wg.Add(1)
31+
go func() {
32+
defer wg.Done()
33+
loadWorklogs()
34+
}()
35+
wg.Add(1)
36+
go func() {
37+
defer wg.Done()
38+
countryCode, err := GetCountryFromLCTime(os.Getenv("LC_TIME"))
39+
if err != nil {
40+
logrus.Error("getting country code from LC_TIME failed:" + err.Error())
41+
}
42+
app.holidays, err = NewHolidays(countryCode)
43+
if err != nil {
44+
logrus.Error("fetching national holidays failed:" + err.Error())
45+
}
46+
}()
47+
wg.Wait()
3048
err := app.ui.app.Run()
3149
if err != nil {
3250
return err

gojira/gojira.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ type gojira struct {
1212
cli *cli.App
1313
ui *UserInteface
1414
time *time.Time
15+
holidays *Holidays
1516
workLogs Worklogs
1617
workLogsIssues WorklogsIssues
1718
}
@@ -31,6 +32,7 @@ func Run() {
3132
logrus.Infof("current time %s", appTimer)
3233
app.ui = &UserInteface{}
3334
app.time = &appTimer
35+
app.holidays = &Holidays{}
3436
app.cli = &cli.App{
3537
Name: "gojira",
3638
Usage: `quickly log time to jira/tempo through cli.

gojira/hoilidays.go

Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
package gojira
2+
3+
import (
4+
"encoding/json"
5+
"fmt"
6+
"github.com/sirupsen/logrus"
7+
"net/http"
8+
"regexp"
9+
"time"
10+
)
11+
12+
type Holiday struct {
13+
Date string `json:"date"`
14+
LocalName string `json:"localName"`
15+
Name string `json:"name"`
16+
CountryCode string `json:"countryCode"`
17+
}
18+
19+
type Holidays []Holiday
20+
21+
func (h *Holidays) GetHolidaysForMonth(month time.Month) Holidays {
22+
var holidaysForMonth Holidays
23+
for _, holiday := range *h {
24+
t, err := time.Parse("2006-01-02", holiday.Date)
25+
if err != nil {
26+
fmt.Println(err)
27+
continue
28+
}
29+
if t.Month() == month {
30+
holidaysForMonth = append(holidaysForMonth, holiday)
31+
}
32+
}
33+
return holidaysForMonth
34+
}
35+
36+
func (h *Holidays) IsHoliday(t *time.Time) bool {
37+
for _, holiday := range *h {
38+
t2, err := time.Parse("2006-01-02", holiday.Date)
39+
if err != nil {
40+
fmt.Println(err)
41+
continue
42+
}
43+
if t2.Equal(*t) {
44+
return true
45+
}
46+
}
47+
return false
48+
}
49+
50+
func (h *Holiday) GetTime() (*time.Time, error) {
51+
t, err := time.Parse("2006-01-02", h.Date)
52+
if err != nil {
53+
return nil, err
54+
}
55+
return &t, nil
56+
}
57+
58+
func getHolidaysForCountry(countryCode string) (*Holidays, error) {
59+
url := fmt.Sprintf("https://date.nager.at/api/v3/PublicHolidays/2024/%s", countryCode)
60+
logrus.Infof("fetching holidays from url: %s", url)
61+
resp, err := http.Get(url) //nolint:gosec
62+
if err != nil {
63+
logrus.Error("could not fetch holidays from url: ", url)
64+
return nil, err
65+
}
66+
defer resp.Body.Close()
67+
var holidays Holidays
68+
err = json.NewDecoder(resp.Body).Decode(&holidays)
69+
if err != nil {
70+
return nil, err
71+
}
72+
return &holidays, nil
73+
}
74+
75+
func NewHolidays(countryCode string) (*Holidays, error) {
76+
holidays, err := getHolidaysForCountry(countryCode)
77+
if err != nil {
78+
logrus.Error(err)
79+
return &Holidays{}, err
80+
}
81+
82+
return holidays, nil
83+
}
84+
85+
func GetCountryFromLCTime(timeString string) (string, error) {
86+
r, _ := regexp.Compile("([A-Z]{2})")
87+
match := r.FindString(timeString)
88+
if match == "" {
89+
return "", fmt.Errorf("could not parse country from LC_TIME")
90+
}
91+
return match, nil
92+
}

gojira/summary.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ func workingHoursInMonthToPresentDay(year int, month time.Month) int {
4141
totalWorkHours := 0
4242

4343
for t.Month() == month && t.Before(time.Now().Local()) {
44-
if t.Weekday() != time.Saturday && t.Weekday() != time.Sunday {
44+
if t.Weekday() != time.Saturday && t.Weekday() != time.Sunday && !app.holidays.IsHoliday(&t) {
4545
totalWorkHours += 8
4646
}
4747
t = t.AddDate(0, 0, 1)

0 commit comments

Comments
 (0)