bot: Added channel handler and the actual logging.
This commit is contained in:
@@ -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
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
`
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
`
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
`
|
||||
@@ -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"`
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
`
|
||||
Reference in New Issue
Block a user