bot: Added channel handler and the actual logging.

This commit is contained in:
2018-11-22 22:24:33 +01:00
parent 7336ea2b47
commit c08bd6c05a
9 changed files with 630 additions and 6 deletions
+31
View File
@@ -0,0 +1,31 @@
package models
import "time"
// A Log represents a log session.
type Log struct {
ID string `json:"id"`
Date time.Time `json:"date"`
ChannelName string `json:"channelName"`
Title string `json:"title"`
EventName string `json:"eventName"`
Description string `json:"description"`
Open bool `json:"open"`
Posts []Post `json:"posts"`
}
// LatestTime gets the latest timestamp in the log.
func (log *Log) LatestTime() time.Time {
if len(log.Posts) == 0 {
return log.Date
}
latest := log.Date
for _, post := range log.Posts {
if post.Time.After(latest) {
latest = post.Time
}
}
return latest
}
+67
View File
@@ -0,0 +1,67 @@
package logs
import (
"context"
"encoding/json"
"time"
"git.aiterp.net/rpdata/logbot3/internal/api"
"git.aiterp.net/rpdata/logbot3/internal/models"
)
// Add adds a log file.
func Add(ctx context.Context, channelName string, date time.Time, open bool, event string) (models.Log, error) {
input := addInput{
Date: date,
Channel: channelName,
Open: &open,
Event: &event,
}
data, err := api.Global().Query(ctx, addGQL, map[string]interface{}{"input": input}, []string{"log.add"})
if err != nil {
return models.Log{}, err
}
res := addResult{}
err = json.Unmarshal(data, &res)
if err != nil {
return models.Log{}, err
}
return res.Log, nil
}
type addResult struct {
Log models.Log `json:"addLog"`
}
type addInput struct {
Date time.Time `json:"date"`
Channel string `json:"channel"`
Title *string `json:"title"`
Open *bool `json:"open"`
Event *string `json:"event"`
Description *string `json:"description"`
}
const addGQL = `
mutation AddLog($input:LogAddInput!) {
addLog(input:$input) {
id
date
channelName
title
eventName
description
open
posts {
id
time
kind
nick
text
}
}
}
`
+67
View File
@@ -0,0 +1,67 @@
package logs
import (
"context"
"encoding/json"
"git.aiterp.net/rpdata/logbot3/internal/api"
"git.aiterp.net/rpdata/logbot3/internal/models"
)
// SetOpen changes the open state of a log.
func SetOpen(ctx context.Context, log models.Log, open bool) (models.Log, error) {
return edit(ctx, editInput{ID: log.ID, Open: &open})
}
// SetEventName changes the event name of a log.
func SetEventName(ctx context.Context, log models.Log, event string) (models.Log, error) {
return edit(ctx, editInput{ID: log.ID, Event: &event})
}
func edit(ctx context.Context, input editInput) (models.Log, error) {
data, err := api.Global().Query(ctx, editGQL, map[string]interface{}{"input": input}, []string{"log.edit"})
if err != nil {
return models.Log{}, err
}
res := editResult{}
err = json.Unmarshal(data, &res)
if err != nil {
return models.Log{}, err
}
return res.Log, nil
}
type editResult struct {
Log models.Log `json:"editLog"`
}
type editInput struct {
ID string `json:"id"`
Title *string `json:"title"`
Event *string `json:"event"`
Description *string `json:"description"`
Open *bool `json:"open"`
}
const editGQL = `
mutation EditLog($input:LogEditInput!) {
editLog(input:$input) {
id
date
channelName
title
eventName
description
open
posts {
id
time
kind
nick
text
}
}
}
`
+66
View File
@@ -0,0 +1,66 @@
package logs
import (
"context"
"encoding/json"
"errors"
"git.aiterp.net/rpdata/logbot3/internal/api"
"git.aiterp.net/rpdata/logbot3/internal/models"
)
// ErrNoneOpen is returned by FindOpen if no logs are open, but the query did succeed.
var ErrNoneOpen = errors.New("No open logs")
// FindOpen lists all changes according to the filter.
func FindOpen(ctx context.Context, channelName string) (models.Log, error) {
data, err := api.Global().Query(ctx, findOpenGQL, map[string]interface{}{"channel": channelName}, nil)
if err != nil {
return models.Log{}, err
}
res := findOpenResult{}
err = json.Unmarshal(data, &res)
if err != nil {
return models.Log{}, err
}
if len(res.Logs) == 0 {
return models.Log{}, ErrNoneOpen
}
// This shouldn't happen, but if there are more than one
// open logs for a channel, select the most recent one.
selected := res.Logs[0]
for _, log := range res.Logs[1:] {
if log.Date.After(selected.Date) {
selected = log
}
}
return selected, nil
}
type findOpenResult struct {
Logs []models.Log `json:"logs"`
}
var findOpenGQL = `
query FindOpen($channel:String!) {
logs(filter:{open:true, channels:[$channel]}) {
id
date
channelName
title
eventName
description
open
posts {
id
time
kind
nick
text
}
}
}
`
+12
View File
@@ -0,0 +1,12 @@
package models
import "time"
// A Post is a post.
type Post struct {
ID string `json:"id"`
Time time.Time `json:"time"`
Kind string `json:"kind"`
Nick string `json:"nick"`
Text string `json:"text"`
}
+58
View File
@@ -0,0 +1,58 @@
package posts
import (
"context"
"encoding/json"
"time"
"git.aiterp.net/rpdata/logbot3/internal/api"
"git.aiterp.net/rpdata/logbot3/internal/models"
)
// Add adds a log file.
func Add(ctx context.Context, log models.Log, time time.Time, kind, nick, text string) (models.Post, error) {
input := addInput{
LogID: log.ID,
Time: time,
Kind: kind,
Nick: nick,
Text: text,
}
data, err := api.Global().Query(ctx, addGQL, map[string]interface{}{"input": input}, []string{"post.add"})
if err != nil {
return models.Post{}, err
}
res := addResult{}
err = json.Unmarshal(data, &res)
if err != nil {
return models.Post{}, err
}
return res.Post, nil
}
type addResult struct {
Post models.Post `json:"addPost"`
}
type addInput struct {
LogID string `json:"logId"`
Time time.Time `json:"time"`
Kind string `json:"kind"`
Nick string `json:"nick"`
Text string `json:"text"`
}
const addGQL = `
mutation AddPost($input:PostAddInput!) {
addPost(input:$input) {
id
time
kind
nick
text
}
}
`