mirror of
https://github.com/taigrr/wtf
synced 2025-01-18 04:03:14 -08:00
First commit
This commit is contained in:
commit
176052c78f
17
bamboohr/bamboohr.go
Normal file
17
bamboohr/bamboohr.go
Normal 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
39
bamboohr/calendar.go
Normal 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
55
bamboohr/client.go
Normal 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
12
bamboohr/employee.go
Normal 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
42
bamboohr/item.go
Normal 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
39
bamboohr/request.go
Normal 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
3
github/github.go
Normal file
@ -0,0 +1,3 @@
|
||||
package wtfgithub
|
||||
|
||||
import ()
|
42
wtf.go
Normal file
42
wtf.go
Normal 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
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user