1
0
mirror of https://github.com/taigrr/wtf synced 2025-01-18 04:03:14 -08:00

First commit

This commit is contained in:
Chris Cummer 2018-03-28 09:54:09 -07:00 committed by Chris Cummer
commit 176052c78f
8 changed files with 249 additions and 0 deletions

17
bamboohr/bamboohr.go Normal file
View File

@ -0,0 +1,17 @@
package bamboohr
import (
"time"
)
func Fetch() []Item {
client := NewClient()
result := client.Away("timeOff", today(), today())
return result
}
func today() string {
localNow := time.Now().Local()
return localNow.Format("2006-01-02")
}

39
bamboohr/calendar.go Normal file
View File

@ -0,0 +1,39 @@
package bamboohr
import ()
type Calendar struct {
Items []Item `xml:"item"`
}
/* -------------------- Public Functions -------------------- */
func (calendar *Calendar) Holidays() []Item {
return calendar.filteredItems("holiday")
}
func (calendar *Calendar) ItemsByType(itemType string) []Item {
if itemType == "timeOff" {
return calendar.TimeOffs()
}
return calendar.Holidays()
}
func (calendar *Calendar) TimeOffs() []Item {
return calendar.filteredItems("timeOff")
}
/* -------------------- Private Functions -------------------- */
func (calendar *Calendar) filteredItems(itemType string) []Item {
items := []Item{}
for _, item := range calendar.Items {
if item.Type == itemType {
items = append(items, item)
}
}
return items
}

55
bamboohr/client.go Normal file
View File

@ -0,0 +1,55 @@
package bamboohr
import (
"encoding/xml"
"fmt"
"os"
)
// A Client represents the data required to connect to the BambooHR API
type Client struct {
apiBase string
apiKey string
subdomain string
}
// NewClient creates and returns a new BambooHR client
func NewClient() *Client {
client := Client{
apiBase: "https://api.bamboohr.com/api/gateway.php",
apiKey: os.Getenv("WTF_BAMBOO_HR_TOKEN"),
subdomain: os.Getenv("WTF_BAMBOO_HR_SUBDOMAIN"),
}
return &client
}
/* -------------------- Public Functions -------------------- */
// Away returns a string representation of the people who are out of the office during the defined period
func (client *Client) Away(itemType, startDate, endDate string) []Item {
calendar, _ := client.away(startDate, endDate)
items := calendar.ItemsByType(itemType)
return items
}
/* -------------------- Private Functions -------------------- */
// away is the private interface for retrieving structural data about who will be out of the office
// This method does the actual communication with BambooHR and returns the raw Go
// data structures used by the public interface
func (client *Client) away(startDate, endDate string) (cal Calendar, err error) {
apiURL := fmt.Sprintf(
"%s/%s/v1/time_off/whos_out?start=%s&end=%s",
client.apiBase,
client.subdomain,
startDate,
endDate,
)
data, err := Request(client.apiKey, apiURL)
err = xml.Unmarshal(data, &cal)
return
}

12
bamboohr/employee.go Normal file
View File

@ -0,0 +1,12 @@
package bamboohr
import ()
/*
* Note: this currently implements the minimum number of fields to fulfill the Away functionality.
* Undoubtedly there are more fields than this to an employee
*/
type Employee struct {
ID int `xml:"id,attr"`
Name string `xml:",chardata"`
}

42
bamboohr/item.go Normal file
View File

@ -0,0 +1,42 @@
package bamboohr
import (
"fmt"
"time"
)
// DateFormat defines the format we expect to receive dates from BambooHR in
const DateFormat = "2006-01-02"
type Item struct {
Employee Employee `xml:"employee"`
End string `xml:"end"`
Holiday string `xml:"holiday"`
Start string `xml:"start"`
Type string `xml:"type,attr"`
}
func (item *Item) String() string {
return fmt.Sprintf("Item: %s, %s, %s, %s", item.Type, item.Employee.Name, item.Start, item.End)
}
/* -------------------- Public Functions -------------------- */
func (item *Item) Name() string {
if (item.Employee != Employee{}) {
return item.Employee.Name
}
return item.Holiday
}
func (item *Item) PrettyStart() string {
newTime, _ := time.Parse(DateFormat, item.Start)
return fmt.Sprint(newTime.Format("Jan 2, 2006"))
}
func (item *Item) PrettyEnd() string {
newTime, _ := time.Parse(DateFormat, item.End)
end := fmt.Sprint(newTime.Format("Jan 2, 2006"))
return end
}

39
bamboohr/request.go Normal file
View File

@ -0,0 +1,39 @@
package bamboohr
import (
"bytes"
"net/http"
)
func Request(apiKey string, apiURL string) ([]byte, error) {
req, err := http.NewRequest("GET", apiURL, nil)
if err != nil {
panic(err)
}
req.SetBasicAuth(apiKey, "x")
client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
panic(err)
}
defer resp.Body.Close()
data, err := ParseBody(resp)
if err != nil {
panic(err)
}
return data, err
}
func ParseBody(resp *http.Response) ([]byte, error) {
var buffer bytes.Buffer
_, err := buffer.ReadFrom(resp.Body)
if err != nil {
return nil, err
}
return buffer.Bytes(), nil
}

3
github/github.go Normal file
View File

@ -0,0 +1,3 @@
package wtfgithub
import ()

42
wtf.go Normal file
View File

@ -0,0 +1,42 @@
package main
import (
"fmt"
"github.com/rivo/tview"
"github.com/senorprogrammer/wtf/bamboohr"
)
func main() {
app := tview.NewApplication()
grid := tview.NewGrid()
grid.SetRows(10, 40) // 10 high, 40 high
grid.SetColumns(40, 40) // 40 wide, 40 wide
grid.SetBorder(false)
grid.AddItem(bambooView(), 0, 0, 1, 1, 0, 0, false)
if err := app.SetRoot(grid, true).Run(); err != nil {
panic(err)
}
}
func bambooView() tview.Primitive {
items := bamboohr.Fetch()
bamboo := tview.NewTextView()
bamboo.SetBorder(true)
bamboo.SetDynamicColors(true)
bamboo.SetTitle(" 🐨 Away ")
data := ""
for _, item := range items {
str := fmt.Sprintf("[green]%s[white]\n%s - %s\n\n", item.Name(), item.PrettyStart(), item.PrettyEnd())
data = data + str
}
fmt.Fprintf(bamboo, "%s", data)
return bamboo
}