mirror of
https://github.com/taigrr/wtf
synced 2025-01-18 04:03:14 -08:00
95
modules/gitter/client.go
Normal file
95
modules/gitter/client.go
Normal file
@@ -0,0 +1,95 @@
|
||||
package gitter
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"github.com/wtfutil/wtf/logger"
|
||||
"github.com/wtfutil/wtf/wtf"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"os"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
func GetMessages(roomId string, numberOfMessages int) ([]Message, error) {
|
||||
var messages []Message
|
||||
|
||||
resp, err := apiRequest("rooms/" + roomId + "/chatMessages?limit=" + strconv.Itoa(numberOfMessages))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
parseJson(&messages, resp.Body)
|
||||
|
||||
return messages, nil
|
||||
}
|
||||
|
||||
func GetRoom(roomUri string) (*Room, error) {
|
||||
var rooms Rooms
|
||||
|
||||
resp, err := apiRequest("rooms?q=" + roomUri)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
parseJson(&rooms, resp.Body)
|
||||
|
||||
for _, room := range rooms.Results {
|
||||
logger.Log(fmt.Sprintf("room: %s", room))
|
||||
if room.URI == roomUri {
|
||||
return &room, nil
|
||||
}
|
||||
}
|
||||
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
/* -------------------- Unexported Functions -------------------- */
|
||||
|
||||
var (
|
||||
apiBaseURL = "https://api.gitter.im/v1/"
|
||||
)
|
||||
|
||||
func apiRequest(path string) (*http.Response, error) {
|
||||
req, err := http.NewRequest("GET", apiBaseURL+path, nil)
|
||||
bearer := fmt.Sprintf("Bearer %s", apiToken())
|
||||
req.Header.Add("Authorization", bearer)
|
||||
|
||||
httpClient := &http.Client{}
|
||||
resp, err := httpClient.Do(req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if resp.StatusCode < 200 || resp.StatusCode > 299 {
|
||||
return nil, fmt.Errorf(resp.Status)
|
||||
}
|
||||
|
||||
return resp, nil
|
||||
}
|
||||
|
||||
func parseJson(obj interface{}, text io.Reader) {
|
||||
jsonStream, err := ioutil.ReadAll(text)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
decoder := json.NewDecoder(bytes.NewReader(jsonStream))
|
||||
|
||||
for {
|
||||
if err := decoder.Decode(obj); err == io.EOF {
|
||||
break
|
||||
} else if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func apiToken() string {
|
||||
return wtf.Config.UString(
|
||||
"wtf.mods.gitter.apiToken",
|
||||
os.Getenv("WTF_GITTER_API_TOKEN"),
|
||||
)
|
||||
}
|
||||
28
modules/gitter/gitter.go
Normal file
28
modules/gitter/gitter.go
Normal file
@@ -0,0 +1,28 @@
|
||||
package gitter
|
||||
|
||||
import "time"
|
||||
|
||||
type Rooms struct {
|
||||
Results []Room `json:"results"`
|
||||
}
|
||||
|
||||
type Room struct {
|
||||
ID string `json:"id"`
|
||||
Name string `json:"name"`
|
||||
URI string `json:"uri"`
|
||||
}
|
||||
|
||||
type User struct {
|
||||
ID string `json:"id"`
|
||||
Username string `json:"username"`
|
||||
DisplayName string `json:"displayName"`
|
||||
}
|
||||
|
||||
type Message struct {
|
||||
ID string `json:"id"`
|
||||
Text string `json:"text"`
|
||||
HTML string `json:"html"`
|
||||
Sent time.Time `json:"sent"`
|
||||
From User `json:"fromUser"`
|
||||
Unread bool `json:"unread"`
|
||||
}
|
||||
181
modules/gitter/widget.go
Normal file
181
modules/gitter/widget.go
Normal file
@@ -0,0 +1,181 @@
|
||||
package gitter
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/gdamore/tcell"
|
||||
"github.com/rivo/tview"
|
||||
"github.com/wtfutil/wtf/wtf"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
const HelpText = `
|
||||
Keyboard commands for Gitter:
|
||||
|
||||
/: Show/hide this help window
|
||||
j: Select the next message in the list
|
||||
k: Select the previous message in the list
|
||||
r: Refresh the data
|
||||
|
||||
arrow down: Select the next message in the list
|
||||
arrow up: Select the previous message in the list
|
||||
`
|
||||
|
||||
type Widget struct {
|
||||
wtf.HelpfulWidget
|
||||
wtf.TextWidget
|
||||
|
||||
messages []Message
|
||||
selected int
|
||||
}
|
||||
|
||||
func NewWidget(app *tview.Application, pages *tview.Pages) *Widget {
|
||||
widget := Widget{
|
||||
HelpfulWidget: wtf.NewHelpfulWidget(app, pages, HelpText),
|
||||
TextWidget: wtf.NewTextWidget(app, "Gitter", "gitter", true),
|
||||
}
|
||||
|
||||
widget.HelpfulWidget.SetView(widget.View)
|
||||
widget.unselect()
|
||||
|
||||
widget.View.SetScrollable(true)
|
||||
widget.View.SetRegions(true)
|
||||
widget.View.SetInputCapture(widget.keyboardIntercept)
|
||||
|
||||
return &widget
|
||||
}
|
||||
|
||||
/* -------------------- Exported Functions -------------------- */
|
||||
|
||||
func (widget *Widget) Refresh() {
|
||||
if widget.Disabled() {
|
||||
return
|
||||
}
|
||||
|
||||
room, err := GetRoom(wtf.Config.UString("wtf.mods.gitter.roomUri", "wtfutil/Lobby"))
|
||||
if err != nil {
|
||||
widget.View.SetWrap(true)
|
||||
widget.View.SetTitle(widget.Name)
|
||||
widget.View.SetText(err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
if room == nil {
|
||||
return
|
||||
}
|
||||
|
||||
messages, err := GetMessages(room.ID, wtf.Config.UInt("wtf.mods.gitter.numberOfMessages", 10))
|
||||
|
||||
if err != nil {
|
||||
widget.View.SetWrap(true)
|
||||
widget.View.SetTitle(widget.Name)
|
||||
widget.View.SetText(err.Error())
|
||||
} else {
|
||||
widget.messages = messages
|
||||
}
|
||||
|
||||
widget.display()
|
||||
widget.View.ScrollToEnd()
|
||||
}
|
||||
|
||||
/* -------------------- Unexported Functions -------------------- */
|
||||
|
||||
func (widget *Widget) display() {
|
||||
if widget.messages == nil {
|
||||
return
|
||||
}
|
||||
|
||||
widget.View.SetWrap(true)
|
||||
widget.View.Clear()
|
||||
widget.View.SetTitle(widget.ContextualTitle(fmt.Sprintf("%s - %s", widget.Name, wtf.Config.UString("wtf.mods.gitter.roomUri", "wtfutil/Lobby"))))
|
||||
widget.View.SetText(widget.contentFrom(widget.messages))
|
||||
widget.View.Highlight(strconv.Itoa(widget.selected)).ScrollToHighlight()
|
||||
}
|
||||
|
||||
func (widget *Widget) contentFrom(messages []Message) string {
|
||||
var str string
|
||||
for idx, message := range messages {
|
||||
str = str + fmt.Sprintf(
|
||||
`["%d"][""][%s] [blue]%s [lightslategray]%s: [%s]%s [aqua]%s`,
|
||||
idx,
|
||||
widget.rowColor(idx),
|
||||
message.From.DisplayName,
|
||||
message.From.Username,
|
||||
widget.rowColor(idx),
|
||||
message.Text,
|
||||
message.Sent.Format("Jan 02, 15:04 MST"),
|
||||
)
|
||||
|
||||
str = str + "\n"
|
||||
}
|
||||
|
||||
return str
|
||||
}
|
||||
|
||||
func (widget *Widget) rowColor(idx int) string {
|
||||
if widget.View.HasFocus() && (idx == widget.selected) {
|
||||
return wtf.DefaultFocussedRowColor()
|
||||
}
|
||||
|
||||
return wtf.RowColor("gitter", idx)
|
||||
}
|
||||
|
||||
func (widget *Widget) next() {
|
||||
widget.selected++
|
||||
if widget.messages != nil && widget.selected >= len(widget.messages) {
|
||||
widget.selected = 0
|
||||
}
|
||||
|
||||
widget.display()
|
||||
}
|
||||
|
||||
func (widget *Widget) prev() {
|
||||
widget.selected--
|
||||
if widget.selected < 0 && widget.messages != nil {
|
||||
widget.selected = len(widget.messages) - 1
|
||||
}
|
||||
|
||||
widget.display()
|
||||
}
|
||||
|
||||
func (widget *Widget) openMessage() {
|
||||
sel := widget.selected
|
||||
if sel >= 0 && widget.messages != nil && sel < len(widget.messages) {
|
||||
message := &widget.messages[widget.selected]
|
||||
wtf.OpenFile(message.Text)
|
||||
}
|
||||
}
|
||||
|
||||
func (widget *Widget) unselect() {
|
||||
widget.selected = -1
|
||||
widget.display()
|
||||
}
|
||||
|
||||
func (widget *Widget) keyboardIntercept(event *tcell.EventKey) *tcell.EventKey {
|
||||
switch string(event.Rune()) {
|
||||
case "/":
|
||||
widget.ShowHelp()
|
||||
case "j":
|
||||
widget.next()
|
||||
return nil
|
||||
case "k":
|
||||
widget.prev()
|
||||
return nil
|
||||
case "r":
|
||||
widget.Refresh()
|
||||
return nil
|
||||
}
|
||||
|
||||
switch event.Key() {
|
||||
case tcell.KeyDown:
|
||||
widget.next()
|
||||
return nil
|
||||
case tcell.KeyEsc:
|
||||
widget.unselect()
|
||||
return event
|
||||
case tcell.KeyUp:
|
||||
widget.prev()
|
||||
return nil
|
||||
default:
|
||||
return event
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user