added features

This commit is contained in:
Hendrik Schlehlein 2019-01-15 01:46:39 +01:00
parent 5c2d4d06ed
commit 5bbae9f4f7
10 changed files with 250 additions and 19 deletions

View file

@ -1 +1,55 @@
# go-tsviewer
# go-tsviewer **[WIP]**
## **WARNING** This API is not usable ATM
A REST API made for TS3 Viewer.
# Features
## Config
The config file is generated automatically on first startup.
```json
{
"ip": "127.0.0.1", // Server IP
"port": 10011, // Dataquery Port
"user": {
"name": "serveradmin", // Username
"password": "" // Password
},
"server": {
"port": 9987 // Port of the target server
}
}
```
## URL-Parameter
| Name | Type | Description |
| ---------- | -------- | ------------------------ |
| `pretty` | `bool` | pretty-prints JSON |
| `envelope` | `bool` | wraps JSON in data array |
## Channels
- **`GET`** `/v1/channels/:id`
- **`GET`** `/v1/channels`
```json
A channel object in JSON
{
"id": 1,
"databaseId": 1,
"nickname": "serveradmin from 127.0.0.1:58359",
"type": 1,
"away": false,
"awayMessage": ""
}
```
## Clients
- **`GET`** `/v1/clients/:id`
- **`GET`** `/v1/clients/`
```json
A client object in JSON
{
"id": 1,
"subchannels": [
... (contains all subchannel)
],
"name": "main1",
"totalClients": 0,
"neededSubscribePower": 0
},
```

View file

@ -8,9 +8,10 @@ import (
)
type Config struct {
IP string `json:"ip"`
Port uint16 `json:"port"`
User User `json:"user"`
IP string `json:"ip"`
Port uint16 `json:"port"`
User User `json:"user"`
Server Server `json:"server"`
}
type User struct {
@ -18,6 +19,10 @@ type User struct {
Password string `json:"password"`
}
type Server struct {
Port uint16 `json:"port"`
}
const FileName = "config.json"
func New() (*Config, error) {
@ -25,9 +30,7 @@ func New() (*Config, error) {
configFile, err := os.Open(FileName)
if err != nil {
log.Println("Made it")
if err := config.createFile(); err != nil {
log.Println("WUT?")
return nil, err
}
@ -59,5 +62,8 @@ func defaults() Config {
Name: "serveradmin",
Password: "",
},
Server: Server{
Port: 9987,
},
}
}

View file

@ -7,7 +7,7 @@ type Service interface {
type Channel struct {
ID int `json:"id"`
Subchannels []Channel `json:"subchannel"`
Subchannels []Channel `json:"subchannels,omitempty"`
Name string `json:"name"`
TotalClients int `json:"totalClients"`
NeededSubscribePower int `json:"neededSubscribePower"`

15
features/client/client.go Normal file
View file

@ -0,0 +1,15 @@
package client
type Service interface {
Client(id int) (*Client, error)
Clients() ([]*Client, error)
}
type Client struct {
ID int `json:"id"`
DatabaseID int `json:"databaseId"`
Nickname string `json:"nickname"`
Type int `json:"type"`
Away bool `json:"away"`
AwayMessage string `json:"awayMessage"`
}

View file

@ -0,0 +1,40 @@
package client
import (
"net/http"
"strconv"
"git.cliffbreak.de/haveachin/go-tsviewer/response"
"github.com/go-chi/chi"
)
func ClientHandler(s Service) http.HandlerFunc {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
response.Handler(w, response.HandlerFunc(func() (int, error) {
id, err := strconv.ParseUint(chi.URLParam(r, "id"), 10, 64)
if err != nil {
return http.StatusBadRequest, err
}
c, err := s.Client(int(id))
if err != nil {
return http.StatusNotFound, err
}
return response.New(c, r).Send(w, http.StatusOK)
}))
})
}
func ClientsHandler(s Service) http.HandlerFunc {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
response.Handler(w, response.HandlerFunc(func() (int, error) {
cc, err := s.Clients()
if err != nil {
return http.StatusBadRequest, err
}
return response.New(cc, r).Send(w, http.StatusOK)
}))
})
}

14
features/client/routes.go Normal file
View file

@ -0,0 +1,14 @@
package client
import (
"github.com/go-chi/chi"
)
func Routes(s Service) *chi.Mux {
router := chi.NewRouter()
router.Get("/{id}", ClientHandler(s))
router.Get("/", ClientsHandler(s))
return router
}

View file

@ -7,6 +7,7 @@ import (
"git.cliffbreak.de/haveachin/go-tsviewer/config"
"git.cliffbreak.de/haveachin/go-tsviewer/features/channel"
"git.cliffbreak.de/haveachin/go-tsviewer/features/client"
"git.cliffbreak.de/haveachin/go-tsviewer/service"
"github.com/go-chi/chi"
"github.com/go-chi/chi/middleware"
@ -24,6 +25,7 @@ func Routes(s service.Service) *chi.Mux {
router.Route("/v1", func(r chi.Router) {
r.Mount("/channels", channel.Routes(s))
r.Mount("/clients", client.Routes(s))
})
return router
@ -39,7 +41,7 @@ func main() {
if err != nil {
log.Fatal(err)
}
defer service.Client.Close()
defer service.TSClient.Close()
router := Routes(*service)

View file

@ -1,24 +1,64 @@
package service
import (
"log"
"errors"
"git.cliffbreak.de/haveachin/go-tsviewer/features/channel"
"github.com/multiplay/go-ts3"
)
func (s Service) Channel(id int) (*channel.Channel, error) {
return nil, nil
}
func (s Service) Channels() ([]*channel.Channel, error) {
cc, err := s.Client.Server.ClientList()
channels, err := s.TSClient.Server.ChannelList()
if err != nil {
return nil, err
}
for _, c := range cc {
log.Println(*c)
var c *channel.Channel
for _, channel := range channels {
if channel.ID == id {
c = convertChannel(channel)
break
}
}
return nil, nil
if c == nil {
return nil, errors.New("channel does not exist")
}
return c, nil
}
func (s Service) Channels() ([]*channel.Channel, error) {
channels, err := s.TSClient.Server.ChannelList()
if err != nil {
return nil, err
}
var cc []*channel.Channel
for _, channel := range channels {
if channel.ParentID == 0 {
cc = append(cc, convertChannel(channel))
continue
}
for _, c := range cc {
if c.ID == channel.ParentID {
c.Subchannels = append(c.Subchannels, *convertChannel(channel))
}
}
}
return cc, nil
}
func convertChannel(c *ts3.Channel) *channel.Channel {
return &channel.Channel{
ID: c.ID,
Subchannels: []channel.Channel{},
Name: c.ChannelName,
TotalClients: c.TotalClients,
NeededSubscribePower: c.NeededSubscribePower,
}
}

56
service/client.go Normal file
View file

@ -0,0 +1,56 @@
package service
import (
"errors"
"git.cliffbreak.de/haveachin/go-tsviewer/features/client"
"github.com/multiplay/go-ts3"
)
func (s Service) Client(id int) (*client.Client, error) {
clients, err := s.TSClient.Server.ClientList()
if err != nil {
return nil, err
}
var c *client.Client
for _, client := range clients {
if client.ID == id {
c = convertClient(client)
break
}
}
if c == nil {
return nil, errors.New("client does not exist")
}
return c, nil
}
func (s Service) Clients() ([]*client.Client, error) {
clients, err := s.TSClient.Server.ClientList()
if err != nil {
return nil, err
}
var cc []*client.Client
for _, client := range clients {
cc = append(cc, convertClient(client))
}
return cc, nil
}
func convertClient(c *ts3.OnlineClient) *client.Client {
return &client.Client{
ID: c.ID,
DatabaseID: c.DatabaseID,
Nickname: c.Nickname,
Type: c.Type,
Away: c.Away,
AwayMessage: c.AwayMessage,
}
}

View file

@ -9,7 +9,7 @@ import (
)
type Service struct {
Client *ts3.Client
TSClient *ts3.Client
}
func New(config config.Config) (*Service, error) {
@ -27,7 +27,11 @@ func New(config config.Config) (*Service, error) {
return nil, err
}
if err := client.UsePort(int(config.Server.Port)); err != nil {
return nil, err
}
return &Service{
Client: client,
TSClient: client,
}, nil
}