Add POST options

Signed-off-by: Etzelia <etzelia@hotmail.com>
master
Etzelia 2020-10-05 22:21:20 -05:00
parent 4069709a59
commit f9037f9598
No known key found for this signature in database
GPG Key ID: 708511AE7ABC5314
9 changed files with 143 additions and 49 deletions

47
ban.go
View File

@ -5,12 +5,27 @@ import (
"time"
)
// Unban is a Minecraft pardon
type Unban struct {
Target string `json:"target"`
}
// Kick is a Minecraft kick
type Kick struct {
Unban
Reason string `json:"reason"`
}
// Ban is a Minecraft ban
type Ban struct {
Target string `json:"target"`
Source string `jso:"source"`
Reason string `json:"reason"`
Kick
Source string `json:"source"`
Created int64 `json:"created"`
}
// Ban is a Minecraft ban with an expiration
type TempBan struct {
Ban
Expiration int64 `json:"expiration"`
}
@ -20,11 +35,31 @@ func (b *Ban) CreatedTime() time.Time {
}
// ExpirationTime is Expiration converted to a time.Time
func (b *Ban) ExpirationTime() time.Time {
return time.Unix(b.Expiration/1000, 0)
func (t *TempBan) ExpirationTime() time.Time {
return time.Unix(t.Expiration/1000, 0)
}
// Bans gets a list of Ban from a ServerAPI instance
func (c *Client) Bans() (bans Ban, err error) {
return bans, c.json(fmt.Sprintf("%s/bans", c.Endpoint), &bans)
return bans, c.jsonGET(fmt.Sprintf("%s/bans", c.endpoint), &bans)
}
// Kick kicks a player
func (c *Client) Kick(k Kick) (int, error) {
return c.jsonPOST(fmt.Sprintf("%s/kick", c.endpoint), k)
}
// Ban bans a player
func (c *Client) Ban(b Ban) (int, error) {
return c.jsonPOST(fmt.Sprintf("%s/ban", c.endpoint), b)
}
// TempBan temporarily bans a player
func (c *Client) TempBan(t TempBan) (int, error) {
return c.jsonPOST(fmt.Sprintf("%s/ban", c.endpoint), t)
}
// Unban pardons a player
func (c *Client) Unban(u Unban) (int, error) {
return c.jsonPOST(fmt.Sprintf("%s/unban", c.endpoint), u)
}

View File

@ -1,6 +1,7 @@
package serverapi
import (
"bytes"
"encoding/json"
"fmt"
"io/ioutil"
@ -10,49 +11,53 @@ import (
// Client is a client aimed at a specific ServerAPI endpoint
type Client struct {
Endpoint string
Options *ClientOptions
endpoint string
http *http.Client
token string
}
// ClientOptions are options that can be set for a Client
type ClientOptions struct {
HTTP *http.Client
Password string
}
// ClientOption is options for a Client
type ClientOption func(c *Client)
var (
// DefaultOptions are the default set of ClientOptions for a Client
DefaultOptions = &ClientOptions{
HTTP: http.DefaultClient,
}
defaultHeader = http.Header{
var defaultHeader = http.Header{
"Content-Type": []string{"application/json; charset=utf-8"},
"Accept": []string{"application/json; charset=utf-8"},
}
)
}
// NewClient returns a new Client for making ServerAPI requests
func NewClient(endpoint string, options *ClientOptions) *Client {
if options == nil {
options = DefaultOptions
}
func NewClient(endpoint string, opts ...ClientOption) *Client {
endpoint = strings.TrimSuffix(endpoint, "/")
return &Client{
Endpoint: endpoint,
Options: options,
c := &Client{
endpoint: endpoint,
http: http.DefaultClient,
token: "",
}
for _, opt := range opts {
opt(c)
}
return c
}
// WithHTTP is a ClientOption for setting the http.Client of a Client
func WithHTTP(http *http.Client) ClientOption {
return func(c *Client) {
c.http = http
}
}
func (c *Client) json(endpoint string, obj interface{}) error {
req, err := http.NewRequest(http.MethodGet, endpoint, nil)
if err != nil {
return fmt.Errorf("new JSON request: %v", err)
// WithToken is a ClientOption for setting the token of a Client
func WithToken(token string) ClientOption {
return func(c *Client) {
c.token = token
}
req.Header = defaultHeader
req.Header.Add("X-ServerAPI-Password", c.Options.Password)
}
res, err := c.Options.HTTP.Do(req)
func (c *Client) jsonGET(endpoint string, obj interface{}) error {
req, err := c.newRequest(endpoint, http.MethodGet, nil)
if err != nil {
return err
}
res, err := c.http.Do(req)
if err != nil {
return fmt.Errorf("sending request: %v", err)
}
@ -64,3 +69,32 @@ func (c *Client) json(endpoint string, obj interface{}) error {
return json.Unmarshal(body, obj)
}
func (c *Client) jsonPOST(endpoint string, obj interface{}) (int, error) {
body, err := json.Marshal(obj)
if err != nil {
return -1, err
}
req, err := c.newRequest(endpoint, http.MethodPost, body)
if err != nil {
return -1, err
}
res, err := c.http.Do(req)
if err != nil {
return -1, fmt.Errorf("sending request: %v", err)
}
return res.StatusCode, nil
}
func (c *Client) newRequest(endpoint, method string, body []byte) (*http.Request, error) {
req, err := http.NewRequest(method, endpoint, bytes.NewBuffer(body))
if err != nil {
return nil, fmt.Errorf("new JSON request: %v", err)
}
req.Header = defaultHeader
req.Header.Add("X-ServerAPI-Token", c.token)
return req, nil
}

25
custom.go 100644
View File

@ -0,0 +1,25 @@
package serverapi
import "fmt"
// Broadcast is a server-wide message
type Broadcast struct {
From string `json:"from"`
Message string `json:"message"`
}
// Broadcast sends a message to the server
func (c *Client) Broadcast(b Broadcast) (int, error) {
return c.jsonPOST(fmt.Sprintf("%s/broadcast", c.endpoint), b)
}
// Custom is for edge-cases
type Custom struct {
Command string `json:"command"`
Args []string `json:"args"`
}
// Custom sends a custom command to the server
func (c *Client) Custom(cu Custom) (int, error) {
return c.jsonPOST(fmt.Sprintf("%s/custom", c.endpoint), cu)
}

View File

@ -25,14 +25,14 @@ type Worlds []*World
// GraphQL returns a gql.Client for a ServerAPI instance
func (c *Client) GraphQL() *gql.Client {
return gql.NewClient(fmt.Sprintf("%s/graphql", c.Endpoint), &gql.ClientOptions{
HTTP: c.Options.HTTP,
return gql.NewClient(fmt.Sprintf("%s/graphql", c.endpoint), &gql.ClientOptions{
HTTP: c.http,
})
}
// GraphQLRequest returns a pre-filled gql.Request with the password set
func (c *Client) GraphQLRequest(query string) *gql.Request {
req := gql.NewRequest(query)
req.Header.Add("X-ServerAPI-Password", c.Options.Password)
req.Header.Add("X-ServerAPI-Token", c.token)
return req
}

View File

@ -13,5 +13,5 @@ type Ping struct {
// Ping returns a Ping
func (c *Client) Ping() (ping *Ping, err error) {
return ping, c.json(fmt.Sprintf("%s/ping", c.Endpoint), &ping)
return ping, c.jsonGET(fmt.Sprintf("%s/ping", c.endpoint), &ping)
}

View File

@ -10,5 +10,5 @@ type Player struct {
// Players returns a list of Player from a ServerAPI instance
func (c *Client) Players() (players Players, err error) {
return players, c.json(fmt.Sprintf("%s/players", c.Endpoint), &players)
return players, c.jsonGET(fmt.Sprintf("%s/players", c.endpoint), &players)
}

View File

@ -12,5 +12,5 @@ type Plugin struct {
// Plugins returns a list of Plugin from a ServerAPI instance
func (c *Client) Plugins() (plugins Plugins, err error) {
return plugins, c.json(fmt.Sprintf("%s/plugins", c.Endpoint), &plugins)
return plugins, c.jsonGET(fmt.Sprintf("%s/plugins", c.endpoint), &plugins)
}

2
tps.go
View File

@ -10,5 +10,5 @@ type TPS struct {
// TPS returns TPS from a ServerAPI instance
func (c *Client) TPS() (tps *TPS, err error) {
return tps, c.json(fmt.Sprintf("%s/tps", c.Endpoint), &tps)
return tps, c.jsonGET(fmt.Sprintf("%s/tps", c.endpoint), &tps)
}

View File

@ -48,10 +48,10 @@ func (w *World) FullTimeHours() int64 {
// World returns a single World from a ServerAPI instance
func (c *Client) World(name string) (world *World, err error) {
return world, c.json(fmt.Sprintf("%s/worlds/%s", c.Endpoint, name), &world)
return world, c.jsonGET(fmt.Sprintf("%s/worlds/%s", c.endpoint, name), &world)
}
// Worlds returns a list of World from a ServerAPI instance
func (c *Client) Worlds() (worlds Worlds, err error) {
return worlds, c.json(fmt.Sprintf("%s/worlds", c.Endpoint), &worlds)
return worlds, c.jsonGET(fmt.Sprintf("%s/worlds", c.endpoint), &worlds)
}