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

Migrate all modules to their own subfolder

Handles #375
This commit is contained in:
Sean Smith
2019-02-18 11:16:34 -05:00
parent c28c31aedb
commit 8030380f89
123 changed files with 51 additions and 51 deletions

View File

@@ -0,0 +1,37 @@
package bamboohr
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
}

View File

@@ -0,0 +1,61 @@
package bamboohr
import (
"encoding/xml"
"fmt"
)
// 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(url string, apiKey string, subdomain string) *Client {
client := Client{
apiBase: url,
apiKey: apiKey,
subdomain: 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, err := client.away(startDate, endDate)
if err != nil {
return []Item{}
}
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)
if err != nil {
return cal, err
}
err = xml.Unmarshal(data, &cal)
return
}

View File

@@ -0,0 +1,10 @@
package bamboohr
/*
* 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
modules/bamboohr/item.go Normal file
View File

@@ -0,0 +1,42 @@
package bamboohr
import (
"fmt"
//"time"
"github.com/wtfutil/wtf/wtf"
)
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)
}
/* -------------------- Exported Functions -------------------- */
func (item *Item) IsOneDay() bool {
return item.Start == item.End
}
func (item *Item) Name() string {
if (item.Employee != Employee{}) {
return item.Employee.Name
}
return item.Holiday
}
func (item *Item) PrettyStart() string {
return wtf.PrettyDate(item.Start)
}
func (item *Item) PrettyEnd() string {
return wtf.PrettyDate(item.End)
}

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 {
return nil, err
}
req.SetBasicAuth(apiKey, "x")
client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
return nil, err
}
defer resp.Body.Close()
data, err := ParseBody(resp)
if err != nil {
return nil, 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
}

View File

@@ -0,0 +1,73 @@
package bamboohr
import (
"fmt"
"os"
"github.com/rivo/tview"
"github.com/wtfutil/wtf/wtf"
)
type Widget struct {
wtf.TextWidget
}
func NewWidget(app *tview.Application) *Widget {
widget := Widget{
TextWidget: wtf.NewTextWidget(app, "BambooHR", "bamboohr", false),
}
return &widget
}
/* -------------------- Exported Functions -------------------- */
func (widget *Widget) Refresh() {
apiKey := wtf.Config.UString(
"wtf.mods.bamboohr.apiKey",
os.Getenv("WTF_BAMBOO_HR_TOKEN"),
)
subdomain := wtf.Config.UString(
"wtf.mods.bamboohr.subdomain",
os.Getenv("WTF_BAMBOO_HR_SUBDOMAIN"),
)
client := NewClient("https://api.bamboohr.com/api/gateway.php", apiKey, subdomain)
todayItems := client.Away(
"timeOff",
wtf.Now().Format(wtf.DateFormat),
wtf.Now().Format(wtf.DateFormat),
)
widget.View.SetTitle(widget.ContextualTitle(widget.Name))
widget.View.SetText(widget.contentFrom(todayItems))
}
/* -------------------- Unexported Functions -------------------- */
func (widget *Widget) contentFrom(items []Item) string {
if len(items) == 0 {
return fmt.Sprintf("\n\n\n\n\n\n\n\n%s", wtf.CenterText("[grey]no one[white]", 50))
}
str := ""
for _, item := range items {
str = str + widget.format(item)
}
return str
}
func (widget *Widget) format(item Item) string {
var str string
if item.IsOneDay() {
str = fmt.Sprintf(" [green]%s[white]\n %s\n\n", item.Name(), item.PrettyEnd())
} else {
str = fmt.Sprintf(" [green]%s[white]\n %s - %s\n\n", item.Name(), item.PrettyStart(), item.PrettyEnd())
}
return str
}