From 1a25fa6d58a53d81b60f4a23c0a0ac91a1b19b16 Mon Sep 17 00:00:00 2001 From: Haveachin Date: Mon, 14 Jan 2019 17:41:21 +0100 Subject: [PATCH 1/6] purge --- .gitignore | 14 +- README.md | 3 +- app.js | 43 --- package-lock.json | 552 ---------------------------------- package.json | 17 -- views/home.handlebars | 1 - views/layouts/main.handlebars | 12 - 7 files changed, 14 insertions(+), 628 deletions(-) delete mode 100644 app.js delete mode 100644 package-lock.json delete mode 100644 package.json delete mode 100644 views/home.handlebars delete mode 100644 views/layouts/main.handlebars diff --git a/.gitignore b/.gitignore index c2658d7..4d9a5c2 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,13 @@ -node_modules/ +# Binaries for programs and plugins +*.exe +*.exe~ +*.dll +*.so +*.dylib +*.bat + +# Test binary, build with `go test -c` +*.test + +# Output of the go coverage tool, specifically when used with LiteIDE +*.out \ No newline at end of file diff --git a/README.md b/README.md index 41a401f..a2ddf14 100644 --- a/README.md +++ b/README.md @@ -1,2 +1 @@ -# tsviewer - +# go-tsviewer diff --git a/app.js b/app.js deleted file mode 100644 index 73b5026..0000000 --- a/app.js +++ /dev/null @@ -1,43 +0,0 @@ -var express = require('express'); -var exphbs = require('express-handlebars'); - -var app = express(); - -app.engine('handlebars', exphbs({defaultLayout: 'main'})); -app.set('view engine', 'handlebars'); - -app.get('/', function (req, res) { - res.render('home', {foo: 'bar'}); -}); - -app.listen(3000); - -const TeamSpeak3 = require("ts3-nodejs-library") - -var ts3conn = new TeamSpeak3({ - host: "localhost", - queryport: 10011, - serverport: 9987, - username: "serveradmin", - password: "R0cHL6tb", - nickname: "NodeJS Query Framework", -}) - - ts3conn.on("ready", () => { - ts3conn.clientList({client_type:0}).then(clients => { - clients.forEach(client => { - console.log("Online: ", client.getCache().client_nickname) - }) - }).catch(e => console.log("CATCHED", e.message)) - - ts3conn.channelList({}).then(channel => { - channel.forEach(channel => { - console.log("Channel: ", channel.getCache().channel_name) - }) - }).catch(e => console.log("CATCHED", e.message)) - }) - - - - ts3conn.on("error", e => console.log("Error", e.message)) - ts3conn.on("close", e => console.log("Connection has been closed!", e)) diff --git a/package-lock.json b/package-lock.json deleted file mode 100644 index 781ac2c..0000000 --- a/package-lock.json +++ /dev/null @@ -1,552 +0,0 @@ -{ - "name": "TSViewer", - "version": "0.0.1", - "lockfileVersion": 1, - "requires": true, - "dependencies": { - "accepts": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.5.tgz", - "integrity": "sha1-63d99gEXI6OxTopywIBcjoZ0a9I=", - "requires": { - "mime-types": "2.1.21", - "negotiator": "0.6.1" - } - }, - "array-flatten": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", - "integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=" - }, - "asap": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz", - "integrity": "sha1-5QNHYR1+aQlDIIu9r+vLwvuGbUY=" - }, - "async": { - "version": "2.6.1", - "resolved": "https://registry.npmjs.org/async/-/async-2.6.1.tgz", - "integrity": "sha512-fNEiL2+AZt6AlAw/29Cr0UDe4sRAHCpEHh54WMz+Bb7QfNcFw4h3loofyJpLeQs4Yx7yuqu/2dLgM5hKOs6HlQ==", - "requires": { - "lodash": "4.17.11" - } - }, - "balanced-match": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", - "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=" - }, - "body-parser": { - "version": "1.18.3", - "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.18.3.tgz", - "integrity": "sha1-WykhmP/dVTs6DyDe0FkrlWlVyLQ=", - "requires": { - "bytes": "3.0.0", - "content-type": "1.0.4", - "debug": "2.6.9", - "depd": "1.1.2", - "http-errors": "1.6.3", - "iconv-lite": "0.4.23", - "on-finished": "2.3.0", - "qs": "6.5.2", - "raw-body": "2.3.3", - "type-is": "1.6.16" - } - }, - "brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "requires": { - "balanced-match": "1.0.0", - "concat-map": "0.0.1" - } - }, - "bytes": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz", - "integrity": "sha1-0ygVQE1olpn4Wk6k+odV3ROpYEg=" - }, - "commander": { - "version": "2.17.1", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.17.1.tgz", - "integrity": "sha512-wPMUt6FnH2yzG95SA6mzjQOEKUU3aLaDEmzs1ti+1E9h+CsrZghRlqEM/EJ4KscsQVG8uNN4uVreUeT8+drlgg==", - "optional": true - }, - "concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" - }, - "content-disposition": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.2.tgz", - "integrity": "sha1-DPaLud318r55YcOoUXjLhdunjLQ=" - }, - "content-type": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz", - "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==" - }, - "cookie": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.3.1.tgz", - "integrity": "sha1-5+Ch+e9DtMi6klxcWpboBtFoc7s=" - }, - "cookie-signature": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", - "integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw=" - }, - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "requires": { - "ms": "2.0.0" - } - }, - "define-properties": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz", - "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==", - "requires": { - "object-keys": "1.0.12" - } - }, - "depd": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", - "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=" - }, - "destroy": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz", - "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA=" - }, - "ee-first": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", - "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=" - }, - "encodeurl": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", - "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=" - }, - "escape-html": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", - "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=" - }, - "etag": { - "version": "1.8.1", - "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", - "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=" - }, - "express": { - "version": "4.16.4", - "resolved": "https://registry.npmjs.org/express/-/express-4.16.4.tgz", - "integrity": "sha512-j12Uuyb4FMrd/qQAm6uCHAkPtO8FDTRJZBDd5D2KOL2eLaz1yUNdUB/NOIyq0iU4q4cFarsUCrnFDPBcnksuOg==", - "requires": { - "accepts": "1.3.5", - "array-flatten": "1.1.1", - "body-parser": "1.18.3", - "content-disposition": "0.5.2", - "content-type": "1.0.4", - "cookie": "0.3.1", - "cookie-signature": "1.0.6", - "debug": "2.6.9", - "depd": "1.1.2", - "encodeurl": "1.0.2", - "escape-html": "1.0.3", - "etag": "1.8.1", - "finalhandler": "1.1.1", - "fresh": "0.5.2", - "merge-descriptors": "1.0.1", - "methods": "1.1.2", - "on-finished": "2.3.0", - "parseurl": "1.3.2", - "path-to-regexp": "0.1.7", - "proxy-addr": "2.0.4", - "qs": "6.5.2", - "range-parser": "1.2.0", - "safe-buffer": "5.1.2", - "send": "0.16.2", - "serve-static": "1.13.2", - "setprototypeof": "1.1.0", - "statuses": "1.4.0", - "type-is": "1.6.16", - "utils-merge": "1.0.1", - "vary": "1.1.2" - } - }, - "express-handlebars": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/express-handlebars/-/express-handlebars-3.0.0.tgz", - "integrity": "sha1-gKBwu4GbCeSvLKbQeA91zgXnXC8=", - "requires": { - "glob": "6.0.4", - "graceful-fs": "4.1.15", - "handlebars": "4.0.12", - "object.assign": "4.1.0", - "promise": "7.3.1" - } - }, - "finalhandler": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.1.tgz", - "integrity": "sha512-Y1GUDo39ez4aHAw7MysnUD5JzYX+WaIj8I57kO3aEPT1fFRL4sr7mjei97FgnwhAyyzRYmQZaTHb2+9uZ1dPtg==", - "requires": { - "debug": "2.6.9", - "encodeurl": "1.0.2", - "escape-html": "1.0.3", - "on-finished": "2.3.0", - "parseurl": "1.3.2", - "statuses": "1.4.0", - "unpipe": "1.0.0" - } - }, - "forwarded": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.1.2.tgz", - "integrity": "sha1-mMI9qxF1ZXuMBXPozszZGw/xjIQ=" - }, - "fresh": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", - "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=" - }, - "function-bind": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", - "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" - }, - "glob": { - "version": "6.0.4", - "resolved": "https://registry.npmjs.org/glob/-/glob-6.0.4.tgz", - "integrity": "sha1-DwiGD2oVUSey+t1PnOJLGqtuTSI=", - "requires": { - "inflight": "1.0.6", - "inherits": "2.0.3", - "minimatch": "3.0.4", - "once": "1.4.0", - "path-is-absolute": "1.0.1" - } - }, - "graceful-fs": { - "version": "4.1.15", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.15.tgz", - "integrity": "sha512-6uHUhOPEBgQ24HM+r6b/QwWfZq+yiFcipKFrOFiBEnWdy5sdzYoi+pJeQaPI5qOLRFqWmAXUPQNsielzdLoecA==" - }, - "handlebars": { - "version": "4.0.12", - "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.0.12.tgz", - "integrity": "sha512-RhmTekP+FZL+XNhwS1Wf+bTTZpdLougwt5pcgA1tuz6Jcx0fpH/7z0qd71RKnZHBCxIRBHfBOnio4gViPemNzA==", - "requires": { - "async": "2.6.1", - "optimist": "0.6.1", - "source-map": "0.6.1", - "uglify-js": "3.4.9" - } - }, - "has-symbols": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.0.tgz", - "integrity": "sha1-uhqPGvKg/DllD1yFA2dwQSIGO0Q=" - }, - "http-errors": { - "version": "1.6.3", - "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.3.tgz", - "integrity": "sha1-i1VoC7S+KDoLW/TqLjhYC+HZMg0=", - "requires": { - "depd": "1.1.2", - "inherits": "2.0.3", - "setprototypeof": "1.1.0", - "statuses": "1.4.0" - } - }, - "iconv-lite": { - "version": "0.4.23", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.23.tgz", - "integrity": "sha512-neyTUVFtahjf0mB3dZT77u+8O0QB89jFdnBkd5P1JgYPbPaia3gXXOVL2fq8VyU2gMMD7SaN7QukTB/pmXYvDA==", - "requires": { - "safer-buffer": "2.1.2" - } - }, - "inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", - "requires": { - "once": "1.4.0", - "wrappy": "1.0.2" - } - }, - "inherits": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", - "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=" - }, - "ipaddr.js": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.8.0.tgz", - "integrity": "sha1-6qM9bd16zo9/b+DJygRA5wZzix4=" - }, - "lodash": { - "version": "4.17.11", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.11.tgz", - "integrity": "sha512-cQKh8igo5QUhZ7lg38DYWAxMvjSAKG0A8wGSVimP07SIUEK2UO+arSRKbRZWtelMtN5V0Hkwh5ryOto/SshYIg==" - }, - "media-typer": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", - "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=" - }, - "merge-descriptors": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", - "integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E=" - }, - "methods": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", - "integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4=" - }, - "mime": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/mime/-/mime-1.4.1.tgz", - "integrity": "sha512-KI1+qOZu5DcW6wayYHSzR/tXKCDC5Om4s1z2QJjDULzLcmf3DvzS7oluY4HCTrc+9FiKmWUgeNLg7W3uIQvxtQ==" - }, - "mime-db": { - "version": "1.37.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.37.0.tgz", - "integrity": "sha512-R3C4db6bgQhlIhPU48fUtdVmKnflq+hRdad7IyKhtFj06VPNVdk2RhiYL3UjQIlso8L+YxAtFkobT0VK+S/ybg==" - }, - "mime-types": { - "version": "2.1.21", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.21.tgz", - "integrity": "sha512-3iL6DbwpyLzjR3xHSFNFeb9Nz/M8WDkX33t1GFQnFOllWk8pOrh/LSrB5OXlnlW5P9LH73X6loW/eogc+F5lJg==", - "requires": { - "mime-db": "1.37.0" - } - }, - "minimatch": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", - "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", - "requires": { - "brace-expansion": "1.1.11" - } - }, - "minimist": { - "version": "0.0.10", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.10.tgz", - "integrity": "sha1-3j+YVD2/lggr5IrRoMfNqDYwHc8=" - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" - }, - "negotiator": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.1.tgz", - "integrity": "sha1-KzJxhOiZIQEXeyhWP7XnECrNDKk=" - }, - "object-keys": { - "version": "1.0.12", - "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.0.12.tgz", - "integrity": "sha512-FTMyFUm2wBcGHnH2eXmz7tC6IwlqQZ6mVZ+6dm6vZ4IQIHjs6FdNsQBuKGPuUUUY6NfJw2PshC08Tn6LzLDOag==" - }, - "object.assign": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.0.tgz", - "integrity": "sha512-exHJeq6kBKj58mqGyTQ9DFvrZC/eR6OwxzoM9YRoGBqrXYonaFyGiFMuc9VZrXf7DarreEwMpurG3dd+CNyW5w==", - "requires": { - "define-properties": "1.1.3", - "function-bind": "1.1.1", - "has-symbols": "1.0.0", - "object-keys": "1.0.12" - } - }, - "on-finished": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", - "integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=", - "requires": { - "ee-first": "1.1.1" - } - }, - "once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", - "requires": { - "wrappy": "1.0.2" - } - }, - "optimist": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/optimist/-/optimist-0.6.1.tgz", - "integrity": "sha1-2j6nRob6IaGaERwybpDrFaAZZoY=", - "requires": { - "minimist": "0.0.10", - "wordwrap": "0.0.3" - } - }, - "parseurl": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.2.tgz", - "integrity": "sha1-/CidTtiZMRlGDBViUyYs3I3mW/M=" - }, - "path-is-absolute": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=" - }, - "path-to-regexp": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", - "integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w=" - }, - "promise": { - "version": "7.3.1", - "resolved": "https://registry.npmjs.org/promise/-/promise-7.3.1.tgz", - "integrity": "sha512-nolQXZ/4L+bP/UGlkfaIujX9BKxGwmQ9OT4mOt5yvy8iK1h3wqTEJCijzGANTCCl9nWjY41juyAn2K3Q1hLLTg==", - "requires": { - "asap": "2.0.6" - } - }, - "proxy-addr": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.4.tgz", - "integrity": "sha512-5erio2h9jp5CHGwcybmxmVqHmnCBZeewlfJ0pex+UW7Qny7OOZXTtH56TGNyBizkgiOwhJtMKrVzDTeKcySZwA==", - "requires": { - "forwarded": "0.1.2", - "ipaddr.js": "1.8.0" - } - }, - "qs": { - "version": "6.5.2", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz", - "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==" - }, - "range-parser": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.0.tgz", - "integrity": "sha1-9JvmtIeJTdxA3MlKMi9hEJLgDV4=" - }, - "raw-body": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.3.3.tgz", - "integrity": "sha512-9esiElv1BrZoI3rCDuOuKCBRbuApGGaDPQfjSflGxdy4oyzqghxu6klEkkVIvBje+FF0BX9coEv8KqW6X/7njw==", - "requires": { - "bytes": "3.0.0", - "http-errors": "1.6.3", - "iconv-lite": "0.4.23", - "unpipe": "1.0.0" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" - }, - "safer-buffer": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" - }, - "send": { - "version": "0.16.2", - "resolved": "https://registry.npmjs.org/send/-/send-0.16.2.tgz", - "integrity": "sha512-E64YFPUssFHEFBvpbbjr44NCLtI1AohxQ8ZSiJjQLskAdKuriYEP6VyGEsRDH8ScozGpkaX1BGvhanqCwkcEZw==", - "requires": { - "debug": "2.6.9", - "depd": "1.1.2", - "destroy": "1.0.4", - "encodeurl": "1.0.2", - "escape-html": "1.0.3", - "etag": "1.8.1", - "fresh": "0.5.2", - "http-errors": "1.6.3", - "mime": "1.4.1", - "ms": "2.0.0", - "on-finished": "2.3.0", - "range-parser": "1.2.0", - "statuses": "1.4.0" - } - }, - "serve-static": { - "version": "1.13.2", - "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.13.2.tgz", - "integrity": "sha512-p/tdJrO4U387R9oMjb1oj7qSMaMfmOyd4j9hOFoxZe2baQszgHcSWjuya/CiT5kgZZKRudHNOA0pYXOl8rQ5nw==", - "requires": { - "encodeurl": "1.0.2", - "escape-html": "1.0.3", - "parseurl": "1.3.2", - "send": "0.16.2" - } - }, - "setprototypeof": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.0.tgz", - "integrity": "sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ==" - }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" - }, - "statuses": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.4.0.tgz", - "integrity": "sha512-zhSCtt8v2NDrRlPQpCNtw/heZLtfUDqxBM1udqikb/Hbk52LK4nQSwr10u77iopCW5LsyHpuXS0GnEc48mLeew==" - }, - "type-is": { - "version": "1.6.16", - "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.16.tgz", - "integrity": "sha512-HRkVv/5qY2G6I8iab9cI7v1bOIdhm94dVjQCPFElW9W+3GeDOSHmy2EBYe4VTApuzolPcmgFTN3ftVJRKR2J9Q==", - "requires": { - "media-typer": "0.3.0", - "mime-types": "2.1.21" - } - }, - "uglify-js": { - "version": "3.4.9", - "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.4.9.tgz", - "integrity": "sha512-8CJsbKOtEbnJsTyv6LE6m6ZKniqMiFWmm9sRbopbkGs3gMPPfd3Fh8iIA4Ykv5MgaTbqHr4BaoGLJLZNhsrW1Q==", - "optional": true, - "requires": { - "commander": "2.17.1", - "source-map": "0.6.1" - } - }, - "unpipe": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", - "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=" - }, - "utils-merge": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", - "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=" - }, - "vary": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", - "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=" - }, - "wordwrap": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.3.tgz", - "integrity": "sha1-o9XabNXAvAAI03I0u68b7WMFkQc=" - }, - "wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" - } - } -} diff --git a/package.json b/package.json deleted file mode 100644 index fa42f7e..0000000 --- a/package.json +++ /dev/null @@ -1,17 +0,0 @@ -{ - "name": "TSViewer", - "version": "0.0.0", - "description": "", - "private": true, - "main": "app.js", - "scripts": { - "test": "echo \"Error: no test specified\" && exit 1", - "start": "node app.js" - }, - "author": "Marc Kemper", - "license": "", - "dependencies": { - "express": "^4.16.4", - "express-handlebars": "^3.0.0" - } -} diff --git a/views/home.handlebars b/views/home.handlebars deleted file mode 100644 index 8ba16d1..0000000 --- a/views/home.handlebars +++ /dev/null @@ -1 +0,0 @@ -

TSViewer: Home

diff --git a/views/layouts/main.handlebars b/views/layouts/main.handlebars deleted file mode 100644 index c104d6f..0000000 --- a/views/layouts/main.handlebars +++ /dev/null @@ -1,12 +0,0 @@ - - - - - TSViewer - - - - Test 123 - - - From 5c2d4d06ed155d2ba9063d9066fa4b77df7bce9d Mon Sep 17 00:00:00 2001 From: Hendrik Schlehlein Date: Mon, 14 Jan 2019 21:07:11 +0100 Subject: [PATCH 2/6] initial commit --- .gitignore | 5 ++- config/config.go | 63 +++++++++++++++++++++++++++ features/channel/channel.go | 14 ++++++ features/channel/handler.go | 40 +++++++++++++++++ features/channel/routes.go | 14 ++++++ main.go | 47 ++++++++++++++++++++ request/meta/meta.go | 36 +++++++++++++++ request/routes.go | 10 +++++ response/error.go | 21 +++++++++ response/response.go | 87 +++++++++++++++++++++++++++++++++++++ service/channel.go | 24 ++++++++++ service/service.go | 33 ++++++++++++++ stringer/stringer.go | 49 +++++++++++++++++++++ 13 files changed, 442 insertions(+), 1 deletion(-) create mode 100644 config/config.go create mode 100644 features/channel/channel.go create mode 100644 features/channel/handler.go create mode 100644 features/channel/routes.go create mode 100644 main.go create mode 100644 request/meta/meta.go create mode 100644 request/routes.go create mode 100644 response/error.go create mode 100644 response/response.go create mode 100644 service/channel.go create mode 100644 service/service.go create mode 100644 stringer/stringer.go diff --git a/.gitignore b/.gitignore index 4d9a5c2..7a42440 100644 --- a/.gitignore +++ b/.gitignore @@ -10,4 +10,7 @@ *.test # Output of the go coverage tool, specifically when used with LiteIDE -*.out \ No newline at end of file +*.out + +# Custom Blacklist +config.json \ No newline at end of file diff --git a/config/config.go b/config/config.go new file mode 100644 index 0000000..93e22b7 --- /dev/null +++ b/config/config.go @@ -0,0 +1,63 @@ +package config + +import ( + "encoding/json" + "io/ioutil" + "log" + "os" +) + +type Config struct { + IP string `json:"ip"` + Port uint16 `json:"port"` + User User `json:"user"` +} + +type User struct { + Name string `json:"name"` + Password string `json:"password"` +} + +const FileName = "config.json" + +func New() (*Config, error) { + config := defaults() + + configFile, err := os.Open(FileName) + if err != nil { + log.Println("Made it") + if err := config.createFile(); err != nil { + log.Println("WUT?") + return nil, err + } + + log.Println(config) + return &config, nil + } + defer configFile.Close() + + jsonParser := json.NewDecoder(configFile) + jsonParser.Decode(&config) + + return &config, nil +} + +func (config Config) createFile() error { + configJSON, err := json.MarshalIndent(config, "", " ") + if err != nil { + return err + } + + return ioutil.WriteFile(FileName, configJSON, 0644) +} + +func defaults() Config { + return Config{ + IP: "127.0.0.1", + Port: 10011, + User: User{ + Name: "serveradmin", + Password: "", + }, + } +} diff --git a/features/channel/channel.go b/features/channel/channel.go new file mode 100644 index 0000000..daea83c --- /dev/null +++ b/features/channel/channel.go @@ -0,0 +1,14 @@ +package channel + +type Service interface { + Channel(id int) (*Channel, error) + Channels() ([]*Channel, error) +} + +type Channel struct { + ID int `json:"id"` + Subchannels []Channel `json:"subchannel"` + Name string `json:"name"` + TotalClients int `json:"totalClients"` + NeededSubscribePower int `json:"neededSubscribePower"` +} diff --git a/features/channel/handler.go b/features/channel/handler.go new file mode 100644 index 0000000..a05ff77 --- /dev/null +++ b/features/channel/handler.go @@ -0,0 +1,40 @@ +package channel + +import ( + "net/http" + "strconv" + + "git.cliffbreak.de/haveachin/go-tsviewer/response" + "github.com/go-chi/chi" +) + +func ChannelHandler(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.Channel(int(id)) + if err != nil { + return http.StatusNotFound, err + } + + return response.New(c, r).Send(w, http.StatusOK) + })) + }) +} + +func ChannelsHandler(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.Channels() + if err != nil { + return http.StatusBadRequest, err + } + + return response.New(cc, r).Send(w, http.StatusOK) + })) + }) +} diff --git a/features/channel/routes.go b/features/channel/routes.go new file mode 100644 index 0000000..ddf6ba0 --- /dev/null +++ b/features/channel/routes.go @@ -0,0 +1,14 @@ +package channel + +import ( + "github.com/go-chi/chi" +) + +func Routes(s Service) *chi.Mux { + router := chi.NewRouter() + + router.Get("/{id}", ChannelHandler(s)) + router.Get("/", ChannelsHandler(s)) + + return router +} diff --git a/main.go b/main.go new file mode 100644 index 0000000..538a51a --- /dev/null +++ b/main.go @@ -0,0 +1,47 @@ +package main + +import ( + "log" + "net/http" + "time" + + "git.cliffbreak.de/haveachin/go-tsviewer/config" + "git.cliffbreak.de/haveachin/go-tsviewer/features/channel" + "git.cliffbreak.de/haveachin/go-tsviewer/service" + "github.com/go-chi/chi" + "github.com/go-chi/chi/middleware" +) + +func Routes(s service.Service) *chi.Mux { + router := chi.NewRouter() + router.Use( + middleware.Logger, + middleware.Timeout(5*time.Second), + middleware.DefaultCompress, + middleware.RedirectSlashes, + middleware.Recoverer, + ) + + router.Route("/v1", func(r chi.Router) { + r.Mount("/channels", channel.Routes(s)) + }) + + return router +} + +func main() { + config, err := config.New() + if err != nil { + log.Fatal(err) + } + + service, err := service.New(*config) + if err != nil { + log.Fatal(err) + } + defer service.Client.Close() + + router := Routes(*service) + + log.Fatal("Handler: ", http.ListenAndServe(":8080", router)) +} diff --git a/request/meta/meta.go b/request/meta/meta.go new file mode 100644 index 0000000..9b7544a --- /dev/null +++ b/request/meta/meta.go @@ -0,0 +1,36 @@ +package meta + +import ( + "net/http" + "strconv" +) + +type Meta struct { + Pretty bool `json:"pretty"` + Envelope bool `json:"envelope"` +} + +func NewFromRequest(r *http.Request) *Meta { + meta := Meta{ + Pretty: false, + Envelope: false, + } + + pretty, ok := r.URL.Query()["pretty"] + if ok && len(pretty) > 0 { + prettyBool, err := strconv.ParseBool(pretty[0]) + if err == nil { + meta.Pretty = prettyBool + } + } + + envelope, ok := r.URL.Query()["envelope"] + if ok && len(envelope) > 0 { + envelopeBool, err := strconv.ParseBool(envelope[0]) + if err == nil { + meta.Envelope = envelopeBool + } + } + + return &meta +} diff --git a/request/routes.go b/request/routes.go new file mode 100644 index 0000000..2923553 --- /dev/null +++ b/request/routes.go @@ -0,0 +1,10 @@ +package request + +const ( + GET = "GET" + PUT = "PUT" + POST = "POST" + DELETE = "DELETE" + LINK = "LINK" + UNLINK = "UNLINK" +) diff --git a/response/error.go b/response/error.go new file mode 100644 index 0000000..ce1c42d --- /dev/null +++ b/response/error.go @@ -0,0 +1,21 @@ +package response + +import "time" + +// Error data type +type Error struct { + Status int `json:"status"` + Error string `json:"error"` + Timestamp string `json:"timestamp"` +} + +// NewError creates a new Response fill with an error +func NewError(status int, err error) *Response { + return &Response{ + Content: Error{ + Status: status, + Error: err.Error(), + Timestamp: time.Now().Format("2006-01-02T15:04:05Z"), //.Format("02 Jan 2006, 15:04:05 MST"), + }, + } +} diff --git a/response/response.go b/response/response.go new file mode 100644 index 0000000..82f65e4 --- /dev/null +++ b/response/response.go @@ -0,0 +1,87 @@ +package response + +import ( + "encoding/json" + "log" + "net/http" + + "git.cliffbreak.de/haveachin/go-tsviewer/request/meta" +) + +type HandlerFunc func() (int, error) + +// Responder is a service for responses +type Responder interface { + Send(http.ResponseWriter, int) +} + +// Response data type +type Response struct { + Content interface{} + Pretty bool +} + +type Envelope struct { + Data interface{} `json:"data,omitempty"` +} + +// New creates a new Response +func New(content interface{}, r *http.Request) *Response { + var resp Response + + meta := meta.NewFromRequest(r) + + if meta.Envelope { + resp = Response{ + Content: Envelope{ + Data: content, + }, + } + } else { + resp = Response{ + Content: content, + } + } + + resp.Pretty = meta.Pretty + + return &resp +} + +// Send sends the response +func (resp Response) Send(w http.ResponseWriter, status int) (int, error) { + var ( + rawJSON []byte + err error + ) + + if resp.Pretty { + rawJSON, err = json.MarshalIndent(resp.Content, "", " ") + } else { + rawJSON, err = json.Marshal(resp.Content) + } + + if err != nil { + return http.StatusInternalServerError, err + } else if string(rawJSON) == "null" { + rawJSON = make([]byte, 0) + } + + w.Header().Set("Content-Type", "application/json") + w.WriteHeader(status) + w.Write(rawJSON) + + return status, nil +} + +func Handler(w http.ResponseWriter, hf HandlerFunc) { + status, err := hf() + if err == nil { + return + } + + log.Printf("HTTP %d: %q", status, err) + if status, err = NewError(status, err).Send(w, status); err != nil { + http.Error(w, http.StatusText(status), status) + } +} diff --git a/service/channel.go b/service/channel.go new file mode 100644 index 0000000..2bc4e7a --- /dev/null +++ b/service/channel.go @@ -0,0 +1,24 @@ +package service + +import ( + "log" + + "git.cliffbreak.de/haveachin/go-tsviewer/features/channel" +) + +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() + if err != nil { + return nil, err + } + + for _, c := range cc { + log.Println(*c) + } + + return nil, nil +} diff --git a/service/service.go b/service/service.go new file mode 100644 index 0000000..8c34632 --- /dev/null +++ b/service/service.go @@ -0,0 +1,33 @@ +package service + +import ( + "strconv" + + "git.cliffbreak.de/haveachin/go-tsviewer/config" + "git.cliffbreak.de/haveachin/go-tsviewer/stringer" + ts3 "github.com/multiplay/go-ts3" +) + +type Service struct { + Client *ts3.Client +} + +func New(config config.Config) (*Service, error) { + addr, err := stringer.Build(config.IP, ":", strconv.Itoa(int(config.Port))) + if err != nil { + return nil, err + } + + client, err := ts3.NewClient(addr) + if err != nil { + return nil, err + } + + if err := client.Login(config.User.Name, config.User.Password); err != nil { + return nil, err + } + + return &Service{ + Client: client, + }, nil +} diff --git a/stringer/stringer.go b/stringer/stringer.go new file mode 100644 index 0000000..c77ccf6 --- /dev/null +++ b/stringer/stringer.go @@ -0,0 +1,49 @@ +package stringer + +import ( + "fmt" + "strings" + "unicode" +) + +func Build(ss ...string) (string, error) { + var builder strings.Builder + + for _, s := range ss { + if _, err := builder.WriteString(s); err != nil { + return "", err + } + } + + return builder.String(), nil +} + +func ToCamel(str string) string { + if len(str) < 1 { + return str + } + + for i, c := range str[1:] { + if c >= 'A' && c <= 'Z' { + str = fmt.Sprintf("%s_%c%s", str[:i+1], unicode.ToLower(c), str[i+2:]) + return ToCamel(str) + } + } + + return str +} + +func ToSnake(str string) string { + if len(str) < 1 { + return str + } + + for i, c := range str[1:] { + if c == '_' { + str = fmt.Sprintf("%s%c%s", str[:i+1], unicode.ToUpper(rune(str[i+2])), str[i+3:]) + return ToSnake(str) + } + } + + return str +} From 5bbae9f4f738b1f4eb5fe6e6b8c315d11ab302ff Mon Sep 17 00:00:00 2001 From: Hendrik Schlehlein Date: Tue, 15 Jan 2019 01:46:39 +0100 Subject: [PATCH 3/6] added features --- README.md | 56 ++++++++++++++++++++++++++++++++++- config/config.go | 16 ++++++---- features/channel/channel.go | 2 +- features/client/client.go | 15 ++++++++++ features/client/handler.go | 40 +++++++++++++++++++++++++ features/client/routes.go | 14 +++++++++ main.go | 4 ++- service/channel.go | 58 +++++++++++++++++++++++++++++++------ service/client.go | 56 +++++++++++++++++++++++++++++++++++ service/service.go | 8 +++-- 10 files changed, 250 insertions(+), 19 deletions(-) create mode 100644 features/client/client.go create mode 100644 features/client/handler.go create mode 100644 features/client/routes.go create mode 100644 service/client.go diff --git a/README.md b/README.md index a2ddf14..8d75b70 100644 --- a/README.md +++ b/README.md @@ -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 +}, +``` diff --git a/config/config.go b/config/config.go index 93e22b7..ea0acb5 100644 --- a/config/config.go +++ b/config/config.go @@ -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, + }, } } diff --git a/features/channel/channel.go b/features/channel/channel.go index daea83c..cad648b 100644 --- a/features/channel/channel.go +++ b/features/channel/channel.go @@ -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"` diff --git a/features/client/client.go b/features/client/client.go new file mode 100644 index 0000000..14f557a --- /dev/null +++ b/features/client/client.go @@ -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"` +} diff --git a/features/client/handler.go b/features/client/handler.go new file mode 100644 index 0000000..3578061 --- /dev/null +++ b/features/client/handler.go @@ -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) + })) + }) +} diff --git a/features/client/routes.go b/features/client/routes.go new file mode 100644 index 0000000..a34c596 --- /dev/null +++ b/features/client/routes.go @@ -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 +} diff --git a/main.go b/main.go index 538a51a..836267f 100644 --- a/main.go +++ b/main.go @@ -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) diff --git a/service/channel.go b/service/channel.go index 2bc4e7a..51cf321 100644 --- a/service/channel.go +++ b/service/channel.go @@ -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, + } } diff --git a/service/client.go b/service/client.go new file mode 100644 index 0000000..79de5b9 --- /dev/null +++ b/service/client.go @@ -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, + } +} diff --git a/service/service.go b/service/service.go index 8c34632..86d4187 100644 --- a/service/service.go +++ b/service/service.go @@ -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 } From e99d11dfbc3c5c2e0670934ce8207ce1db506e60 Mon Sep 17 00:00:00 2001 From: Hendrik Schlehlein Date: Tue, 15 Jan 2019 01:47:54 +0100 Subject: [PATCH 4/6] README hotfix --- README.md | 2 -- 1 file changed, 2 deletions(-) diff --git a/README.md b/README.md index 8d75b70..2057cae 100644 --- a/README.md +++ b/README.md @@ -28,7 +28,6 @@ The config file is generated automatically on first startup. - **`GET`** `/v1/channels/:id` - **`GET`** `/v1/channels` ```json -A channel object in JSON { "id": 1, "databaseId": 1, @@ -42,7 +41,6 @@ A channel object in JSON - **`GET`** `/v1/clients/:id` - **`GET`** `/v1/clients/` ```json -A client object in JSON { "id": 1, "subchannels": [ From 171e8128a409771c4a555da87b19885d6ef424e7 Mon Sep 17 00:00:00 2001 From: Hendrik Schlehlein Date: Wed, 16 Jan 2019 22:01:48 +0100 Subject: [PATCH 5/6] added server info --- README.md | 2 +- features/channel/handler.go | 4 ++-- features/channel/routes.go | 6 +++--- features/client/handler.go | 4 ++-- features/client/routes.go | 6 +++--- features/server/handler.go | 20 ++++++++++++++++++++ features/server/routes.go | 13 +++++++++++++ features/server/server.go | 22 ++++++++++++++++++++++ main.go | 6 ++++-- service/server.go | 29 +++++++++++++++++++++++++++++ 10 files changed, 99 insertions(+), 13 deletions(-) create mode 100644 features/server/handler.go create mode 100644 features/server/routes.go create mode 100644 features/server/server.go create mode 100644 service/server.go diff --git a/README.md b/README.md index 2057cae..746faff 100644 --- a/README.md +++ b/README.md @@ -49,5 +49,5 @@ The config file is generated automatically on first startup. "name": "main1", "totalClients": 0, "neededSubscribePower": 0 -}, +} ``` diff --git a/features/channel/handler.go b/features/channel/handler.go index a05ff77..d0e3be8 100644 --- a/features/channel/handler.go +++ b/features/channel/handler.go @@ -8,7 +8,7 @@ import ( "github.com/go-chi/chi" ) -func ChannelHandler(s Service) http.HandlerFunc { +func ChannelAPIHandler(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) @@ -26,7 +26,7 @@ func ChannelHandler(s Service) http.HandlerFunc { }) } -func ChannelsHandler(s Service) http.HandlerFunc { +func ChannelsAPIHandler(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.Channels() diff --git a/features/channel/routes.go b/features/channel/routes.go index ddf6ba0..02532d8 100644 --- a/features/channel/routes.go +++ b/features/channel/routes.go @@ -4,11 +4,11 @@ import ( "github.com/go-chi/chi" ) -func Routes(s Service) *chi.Mux { +func APIRoutes(s Service) *chi.Mux { router := chi.NewRouter() - router.Get("/{id}", ChannelHandler(s)) - router.Get("/", ChannelsHandler(s)) + router.Get("/{id}", ChannelAPIHandler(s)) + router.Get("/", ChannelsAPIHandler(s)) return router } diff --git a/features/client/handler.go b/features/client/handler.go index 3578061..56b036a 100644 --- a/features/client/handler.go +++ b/features/client/handler.go @@ -8,7 +8,7 @@ import ( "github.com/go-chi/chi" ) -func ClientHandler(s Service) http.HandlerFunc { +func ClientAPIHandler(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) @@ -26,7 +26,7 @@ func ClientHandler(s Service) http.HandlerFunc { }) } -func ClientsHandler(s Service) http.HandlerFunc { +func ClientsAPIHandler(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() diff --git a/features/client/routes.go b/features/client/routes.go index a34c596..9e20d55 100644 --- a/features/client/routes.go +++ b/features/client/routes.go @@ -4,11 +4,11 @@ import ( "github.com/go-chi/chi" ) -func Routes(s Service) *chi.Mux { +func APIRoutes(s Service) *chi.Mux { router := chi.NewRouter() - router.Get("/{id}", ClientHandler(s)) - router.Get("/", ClientsHandler(s)) + router.Get("/{id}", ClientAPIHandler(s)) + router.Get("/", ClientsAPIHandler(s)) return router } diff --git a/features/server/handler.go b/features/server/handler.go new file mode 100644 index 0000000..6ed9303 --- /dev/null +++ b/features/server/handler.go @@ -0,0 +1,20 @@ +package server + +import ( + "net/http" + + "git.cliffbreak.de/haveachin/go-tsviewer/response" +) + +func InfoAPIHandler(s Service) http.HandlerFunc { + return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + response.Handler(w, response.HandlerFunc(func() (int, error) { + s, err := s.Info() + if err != nil { + return http.StatusNotFound, err + } + + return response.New(s, r).Send(w, http.StatusOK) + })) + }) +} diff --git a/features/server/routes.go b/features/server/routes.go new file mode 100644 index 0000000..22342f3 --- /dev/null +++ b/features/server/routes.go @@ -0,0 +1,13 @@ +package server + +import ( + "github.com/go-chi/chi" +) + +func APIRoutes(s Service) *chi.Mux { + router := chi.NewRouter() + + router.Get("/info", InfoAPIHandler(s)) + + return router +} diff --git a/features/server/server.go b/features/server/server.go new file mode 100644 index 0000000..401614f --- /dev/null +++ b/features/server/server.go @@ -0,0 +1,22 @@ +package server + +import "time" + +type Service interface { + Info() (*Server, error) +} + +type Server struct { + Name string `json:"name"` + Status string `json:"status"` + Version string `json:"version"` + WelcomeMessage string `json:"welcomeMessage"` + MaxClients int `json:"maxClients"` + ClientsOnline int `json:"clientsOnline"` + ReservedSlots int `json:"reservedSlots"` + Uptime time.Duration `json:"uptime"` + TotalPing float32 `json:"totalPing"` + MinAndroidVersion int `json:"minAndroidVersion"` + MinClientVersion int `json:"minClientVersion"` + MiniOSVersion int `json:"miniOSVersion"` +} diff --git a/main.go b/main.go index 836267f..c8e02de 100644 --- a/main.go +++ b/main.go @@ -8,6 +8,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/features/server" "git.cliffbreak.de/haveachin/go-tsviewer/service" "github.com/go-chi/chi" "github.com/go-chi/chi/middleware" @@ -24,8 +25,9 @@ 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)) + r.Mount("/channels", channel.APIRoutes(s)) + r.Mount("/clients", client.APIRoutes(s)) + r.Mount("/server", server.APIRoutes(s)) }) return router diff --git a/service/server.go b/service/server.go new file mode 100644 index 0000000..d5f2d4a --- /dev/null +++ b/service/server.go @@ -0,0 +1,29 @@ +package service + +import ( + "time" + + "git.cliffbreak.de/haveachin/go-tsviewer/features/server" +) + +func (s Service) Info() (*server.Server, error) { + serverInfo, err := s.TSClient.Server.Info() + if err != nil { + return nil, err + } + + return &server.Server{ + Name: serverInfo.Name, + Status: serverInfo.Status, + Version: serverInfo.Version, + WelcomeMessage: serverInfo.WelcomeMessage, + MaxClients: serverInfo.MaxClients, + ClientsOnline: serverInfo.ClientsOnline, + ReservedSlots: serverInfo.ReservedSlots, + Uptime: time.Duration(serverInfo.Uptime) * time.Nanosecond, + TotalPing: serverInfo.TotalPing, + MinAndroidVersion: serverInfo.MinAndroidVersion, + MinClientVersion: serverInfo.MinClientVersion, + MiniOSVersion: serverInfo.MiniOSVersion, + }, nil +} From 99f99ab23559bd856700e6049fe350b2aae03fb2 Mon Sep 17 00:00:00 2001 From: Hendrik Schlehlein Date: Wed, 16 Jan 2019 23:07:38 +0100 Subject: [PATCH 6/6] fixed client channelId --- README.md | 20 +++++++++++++++++++- features/client/client.go | 2 +- service/client.go | 8 ++++++-- 3 files changed, 26 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 746faff..7f05e39 100644 --- a/README.md +++ b/README.md @@ -29,8 +29,8 @@ The config file is generated automatically on first startup. - **`GET`** `/v1/channels` ```json { - "id": 1, "databaseId": 1, + "channelId": 1, "nickname": "serveradmin from 127.0.0.1:58359", "type": 1, "away": false, @@ -51,3 +51,21 @@ The config file is generated automatically on first startup. "neededSubscribePower": 0 } ``` +## Server +- **`GET`** `/v1/server/info` +```json +{ + "name": "TeamSpeak ]I[ Server", + "status": "online", + "version": "3.5.1 [Build: 1545076855]", + "welcomeMessage": "Welcome to TeamSpeak, check [URL]www.teamspeak.com[/URL] for latest information", + "maxClients": 32, + "clientsOnline": 2, + "reservedSlots": 0, + "uptime": 5976, + "totalPing": 0, + "minAndroidVersion": 1502275280, + "minClientVersion": 1513163251, + "miniOSVersion": 1502275280 +} +``` diff --git a/features/client/client.go b/features/client/client.go index 14f557a..e6ef949 100644 --- a/features/client/client.go +++ b/features/client/client.go @@ -6,8 +6,8 @@ type Service interface { } type Client struct { - ID int `json:"id"` DatabaseID int `json:"databaseId"` + ChannelID int `json:"channelId"` Nickname string `json:"nickname"` Type int `json:"type"` Away bool `json:"away"` diff --git a/service/client.go b/service/client.go index 79de5b9..f806807 100644 --- a/service/client.go +++ b/service/client.go @@ -16,7 +16,7 @@ func (s Service) Client(id int) (*client.Client, error) { var c *client.Client for _, client := range clients { - if client.ID == id { + if client.DatabaseID == id { c = convertClient(client) break } @@ -26,6 +26,10 @@ func (s Service) Client(id int) (*client.Client, error) { return nil, errors.New("client does not exist") } + /* if _, err := s.TSClient.Server.ExecCmd(ts3.NewCmd(fmt.Sprintf("clientinfo clid=%d", c.ID)).WithResponse(&c)); err != nil { + return nil, err + } */ + return c, nil } @@ -46,8 +50,8 @@ func (s Service) Clients() ([]*client.Client, error) { func convertClient(c *ts3.OnlineClient) *client.Client { return &client.Client{ - ID: c.ID, DatabaseID: c.DatabaseID, + ChannelID: c.ID, Nickname: c.Nickname, Type: c.Type, Away: c.Away,