diff --git a/app.iced b/app.iced index ec9f0a5..6f25ac5 100644 --- a/app.iced +++ b/app.iced @@ -8,6 +8,8 @@ request = require "request" fs = require("fs") path = require("path") qs = require "querystring" +youtubedl = require "youtube-dl" +isValidUrl = (require "valid-url").isWebUri log = getLogger "Main" @@ -44,6 +46,14 @@ await services.find("pulseaudio").start defer err if err log.warn "PulseAudio could not start up, audio may not act as expected!" +# VLC HTTP API +await services.find("vlc").start defer err +if err + log.warn "VLC could not start up!" + await module.exports.shutdown defer() + process.exit 1 +vlc = services.find("vlc").instance + # TeamSpeak3 ts3clientService = services.find("ts3client") @@ -113,7 +123,7 @@ ts3clientService.on "started", (ts3proc) => ts3query.on "message.notifytextmessage", (args) => await ts3query.use args.schandlerid, defer(err, data) - + msg = args.msg invoker = { name: args.invokername, uid: args.invokeruid, id: args.invokerid } targetmode = args.targetmode # 1 = private, 2 = channel @@ -135,39 +145,58 @@ ts3clientService.on "started", (ts3proc) => switch name.toLowerCase() when "play" - q = - uid: invoker.uid - input: removeBB paramline - await request "http://127.0.0.1:16444/play?#{qs.stringify q}", defer(err, response) - switch response.statusCode - when 200 then ts3query.sendtextmessage args.targetmode, invoker.id, "Now playing #{paramline}." - when 400 then ts3query.sendtextmessage args.targetmode, invoker.id, "Something seems to be wrong with what you wrote. Maybe check the URL/sound name you provided?" - when 403 then ts3query.sendtextmessage args.targetmode, invoker.id, "Sorry, you're not allowed to play #{q.input} via the bot." - else - log.warn "API reported error", response.statusCode, err - ts3query.sendtextmessage args.targetmode, invoker.id, "Sorry, an error occurred. Try again later." + inputBB = paramline + input = removeBB paramline + + # only allow playback from file if it's a preconfigured alias + if isValidUrl input + log.debug "Got input URL:", input + else + input = config.get "aliases:#{input}" + if not(isValidUrl input) and not(fs.existsSync input) + log.debug "Got neither valid URL nor valid alias:", input + ts3query.sendtextmessage args.targetmode, invoker.id, "Sorry, you're not allowed to play #{inputBB} via the bot." + return + + # TODO: permission system to check if uid is allowed to play this url or alias + + await vlc.status.empty defer(err) + if err + log.warn "Couldn't empty VLC playlist", err + ts3query.sendtextmessage args.targetmode, invoker.id, "Sorry, an error occurred. Try again later." + return + + # let's give youtube-dl a shot! + await youtubedl.getInfo input, [ + "--format=bestaudio" + ], defer(err, info) + if err or not info? + log.debug "There is no audio-only download for #{inputBB}, downloading full video instead." + await youtubedl.getInfo input, [ + "--format=best" + ], defer(err, info) + if err or not info? + info = + url: input + if not info.url? + info.url = input + info.title = input # URL as title + + await vlc.status.play info.url, defer(err) + if err + vlc.status.empty() + log.warn "VLC API returned an error when trying to play", err + ts3query.sendtextmessage args.targetmode, invoker.id, "Something seems to be wrong with that media. Maybe check the URL/sound name you provided?" + return + + ts3query.sendtextmessage args.targetmode, invoker.id, "Now playing [URL=#{input}]#{info.title}[/URL]." when "stop" - q = - uid: invoker.uid - await request "http://127.0.0.1:16444/stop?#{qs.stringify q}", defer(err, response) - switch response.statusCode - when 200 then ts3query.sendtextmessage args.targetmode, invoker.id, "Stopped playback." - when 403 then ts3query.sendtextmessage args.targetmode, invoker.id, "Sorry, you're not allowed to do that." - else - log.warn "API reported error", response.statusCode, err - ts3query.sendtextmessage args.targetmode, invoker.id, "Sorry, an error occurred. Try again later." + vlc.status.stop() + vlc.status.empty() + + ts3query.sendtextmessage args.targetmode, invoker.id, "Stopped playback." when "setvolume" - q = - uid: invoker.uid - volume: parseFloat paramline - await request "http://127.0.0.1:16444/setvolume?#{qs.stringify q}", defer(err, response) - switch response.statusCode - when 200 then ts3query.sendtextmessage args.targetmode, invoker.id, "Set volume to #{q.volume}" - when 400 then ts3query.sendtextmessage args.targetmode, invoker.id, "Something seems to be wrong with what you wrote. Maybe check the volume? It's supposed to be a floating-point number between 0 and 2." - when 403 then ts3query.sendtextmessage args.targetmode, invoker.id, "Sorry, you're not allowed to do that." - else - log.warn "API reported error", response.statusCode, err - ts3query.sendtextmessage args.targetmode, invoker.id, "Sorry, an error occurred. Try again later." + ts3query.sendtextmessage args.targetmode, invoker.id, "Sorry, that's not implemented yet." when "changenick" nick = if paramline.length > params[0].length then paramline else params[0] if nick.length < 1 or nick.length > 32 @@ -185,10 +214,3 @@ if err log.error "TeamSpeak3 could not start, shutting down." await module.exports.shutdown defer() process.exit 1 - -# HTTP API -await services.find("api").start defer err -if err - log.error "API could not start up, shutting down!" - await module.exports.shutdown defer() - process.exit 1 \ No newline at end of file diff --git a/services.iced b/services.iced index 917021b..2d6168a 100644 --- a/services.iced +++ b/services.iced @@ -56,7 +56,6 @@ module.exports.Service = require "./service_template" # register services services = [ - new(require "./services/api") new(require "./services/pulseaudio") new(require "./services/ts3client") new(require "./services/vlc") diff --git a/services/api.iced b/services/api.iced deleted file mode 100644 index 3d18085..0000000 --- a/services/api.iced +++ /dev/null @@ -1,111 +0,0 @@ -express = require "express" -url = require "url" -path = require "path" -spawn = require("child_process").spawn -net = require "net" -Socket = net.Socket -getLogger = require "../logger" -config = require "../config" -log = getLogger "API" -youtubedl = require "youtube-dl" -#PulseAudio = require "pulseaudio" -isValidUrl = (require "valid-url").isWebUri - -services = require "../services" - -module.exports = class APIService extends services.Service - dependencies: [ - "pulseaudio" - "vlc" - "ts3client" - ] - constructor: () -> super "API", - start: (cb) -> - if @httpServer - cb? null - return - - vlc = services.find("vlc").instance - ts3query = services.find("ts3client").query - - # set up HTTP server - log.debug "Starting up HTTP API..." - app = express() - app.get "/play", (req, res) => - if not req.query.uid - log.debug "Didn't get a UID, sending forbidden" - res.status(400).send("Forbidden") - return - if not req.query.input - log.debug "Didn't get an input URI/alias, sending bad request" - res.status(400).send("Bad request") - return - - input = null - # only allow playback from file if it's a preconfigured alias - if isValidUrl req.query.input - log.debug "Got input URL:", req.query.input - input = req.query.input - else - input = config.get("aliases:#{req.query.input}") - if not(isValidUrl input) and not(fs.existsSync input) - log.debug "Got neither valid URL nor valid alias:", req.query.input - res.status(403).send("Forbidden") - return - - # TODO: permission system to check if uid is allowed to play this url or alias - - await vlc.status.empty defer(err) - if err - res.status(503).send("Something went wrong") - log.warn "VLC API returned an error when trying to empty", err - return - - # let's give youtube-dl a shot! - await youtubedl.getInfo input, [ - "--format=bestaudio" - ], defer(err, info) - if err or not info? - await youtubedl.getInfo input, [ - "--format=best" - ], defer(err, info) - if err or not info? - info = - url: input - if not info.url? - info.url = input - info.title = input # URL as title - - await vlc.status.play info.url, defer(err) - if err - vlc.status.empty() - res.status(503).send("Something went wrong") - log.warn "VLC API returned an error when trying to play", err - return - - res.send JSON.stringify info - - app.get "/stop", (req, res) => - if not req.query.uid - log.debug "Didn't get a UID, sending forbidden" - res.status(403).send("Forbidden - missing UID") - return - - # TODO: permission system to check if uid is allowed to stop playback - - vlc.status.stop() - vlc.status.empty() - - res.send("OK") - - app.get "/setvolume", (req, res) => - throw new "Not implemented yet" # FIXME below, still need to implement audio - - @httpServer = app.listen 16444 - - cb? null - - stop: (cb) -> - @httpServer.close() - - cb?() \ No newline at end of file