First commit

master
Pitriss 7 years ago
parent a984f43458
commit 3c4071b245

1
.gitignore vendored

@ -0,0 +1 @@
*~

@ -1,2 +1,28 @@
# MPD_Jabber_bot # MPD Jabber bot
Jabber/XMPP bot that controls streaming MPD instance.
This software is written in Ruby and allows you to control mpd server with simple commands written in MUC chat.
It can skip to prev/next song, play/pause/stop playback, control outputs, return info about current song and song which will be played next.
This software is still in alpha stage. It works for me so I can't promise updates in near future. Feel free to send me a patch if you want. I'll consider merging them.
TODO:
* Create persistent config file
* Code cleanup
* Possibly add some more features
* Make it work in all versions of private messages
Do:
<botnick>: help
to get basic usage help.
This bot depends on following ruby modules:
* rubygems
* jabbot
* ruby-mpd

@ -0,0 +1,294 @@
#!/usr/bin/ruby
$VERBOSE = nil
$BOTVERSION = "beta 0.0.1"
scriptname = "botik.rb" # When its changed, bot will switch to dev mode
botnick = "StreamCtl"
require 'rubygems'
require 'jabbot'
require 'ruby-mpd'
mpd = MPD.new 'localhost', 6600
mpd.connect
class MPD
def outputs
send_command 'outputs'
end
def pause
send_command 'pause'
end
def outputstatus(list)
outputs = outputrefresh()
if list.kind_of?(Array) then
conout = Hash.new
list.each {
|out|
conout[out.to_i] = outputs[out]
}
return conout
else
return outputs
end
end
def outputtoggle(out)
out = out.to_i
outputs = outputrefresh()
if outputs[out].status == 0 then
send_command "enableoutput #{out}"
else
send_command "disableoutput #{out}"
end
end
def outputrefresh
outarray = send_command 'outputs'
i = 0
outputs = Hash.new
Struct.new("Output", :name, :status)
until(outarray.length < 1)
line = outarray[0]
outid = line[:outputid].to_i
outname = line[:outputname]
outstatus = (line[:outputenabled] ? 1 : 0) # Conversion to int
outputs[outid] = Struct::Output.new(outname, outstatus)
outarray.shift
end
return outputs
end
def outputstatus(list)
outputs = outputrefresh()
if list.kind_of?(Array) then
conout = Hash.new
list.each {
|out|
conout[out.to_i] = outputs[out]
}
return conout
else
return outputs
end
end
def outputtoggle(out)
out = out.to_i
outputs = outputrefresh()
if outputs[out].status == 0 then
send_command "enableoutput #{out}"
else
send_command "disableoutput #{out}"
end
end
def nextsong
stat = send_command "status"
nsid = stat[:nextsongid]
return send_command "playlistid #{nsid}"
end
end
def mpdcontrol(mpd,request, mess, type)
arr = mess.text.split(/\W+/)
if arr[2].nil? == false then
if arr[2].chomp.strip != "" then
param = arr[2].chomp.strip
end
end
def outputsctl (outputs,sitelink)
reply = ""
def site_state_translate (input)
if input == 0 then
return "off"
else
return "on"
end
end
outputs.each {
|key,var|
outfile = var[:name].split.last
weblink = ""
case outfile
when "HQ"
file = "hi.ogg"
when "LQ"
file = "lo.ogg"
when "MP3"
file = "stream.mp3"
end
reply = reply+"#{key} - #{sitelink}/#{file} - #{site_state_translate(var.status)}\n"
}
return reply
end
status = mpd.status[:state].to_s.downcase
case request
when "status"
if status == "stop" then
sticon = ""
else
status == "play" ? sticon = "" : sticon = "▮▮"
end
song = mpd.current_song
if song.name != nil then
answer = "Stream: #{song.name} .:. #{song.title} @ #{song.file}"
else
answer = "#{song.artist} - #{song.title} [album #{song.album}]"
end
song = mpd.current_song
if song.name != nil then
# do nothing
else
ns = mpd.nextsong
answer = "#{answer}\nNext song in queue: #{ns[:artist]} - #{ns[:title]} [album #{ns[:album]}]"
end
if type == "0" then
post "#{sticon} #{answer}"
else
post "#{sticon} #{answer}" => mess.user
end
when "play"
mpd.play
when "pause"
mpd.pause
when "stop"
mpd.stop
when "prev"
mpd.previous
when "next"
mpd.next
when "nextsong"
song = mpd.current_song
if song.name != nil then
answer = "MPD is playing external stream. I can't get next song info."
else
ns = mpd.nextsong
answer = "Next song in queue: #{ns[:artist]} - #{ns[:title]} [album #{ns[:album]}]"
end
if type == "0" then
post answer
else
post answer => mess.user
end
when "toggle"
if param.nil? == false then
if param.to_i >= 0 and param.to_i <= 2 then
mpd.outputtoggle param.to_i
end
end
when "info"
if status == "stop" then
sticon = ""
else
status == "play" ? sticon = "" : sticon = "▮▮"
end
song = mpd.current_song
if song.name != nil then
answer = "Stream: #{song.name} .:. #{song.title} @ #{song.file}"
else
answer = "#{song.artist} - #{song.title} [album #{song.album}]"
end
if song.name != nil then
nsanswer = "MPD is playing external stream. I can't get next song info."
else
ns = mpd.nextsong
nsanswer = "Next song in queue: #{ns[:artist]} - #{ns[:title]} [album #{ns[:album]}]"
end
sitelink = "https://stream.example.com"
outputs = mpd.outputstatus([0, 1, 2])
outs = outputsctl(outputs,sitelink)
if type == "0" then
post "#{sticon} #{answer}\n#{nsanswer}\nOutputs:\n#{outs}"
else
post "#{sticon} #{answer}\n#{nsanswer}\nOutputs:\n#{outs}" => mess.user
end
when "outputs"
sitelink = "https://stream.example.com"
outputs = mpd.outputstatus([0, 1, 2])
if type == "0" then
post outputsctl(outputs,sitelink)
else
post outputsctl(outputs,sitelink) => mess.user
end
when "version"
if type == "0" then
post "Pitriss MPD stream control bot, version #{$BOTVERSION}"
else
post "Pitriss MPD stream control bot, version #{$BOTVERSION}" => mess.user
end
when "help"
answer = "Stream is located at https://stream.example.com/xyz.ext (see outputs)\n
Commands:\n
status - Info about played track
nestsong - Info about next song in queue
info - Verbose info about most relevant aspects
outputs - list all outputs available and its status
toggle <output number> - toggle state of output
play - start MPD
pause - pause MPD
stop - stops MPD
next - next song
prev - previous song\n\n
For more info ask in room. (eg howto access playlist control)"
if type == "0" then
post answer
else
post answer => mess.user
end
else
if type == "0" then
post "Are you kiddin' me? That's complete bullshit! I don't believe single word you told me! Maybe you can try again with \"help\"?"
else
post "Are you kiddin' me? That's complete bullshit! I don't believe single word you told me! Maybe you can try again with \"help\"?" => mess.user
end
end
end
configure do |conf|
conf.login = "bot@example.com"
conf.password = "ChangeMe"
# conf.nick = "StreamCtl"
conf.nick = botnick
conf.resource = "StreamCtl"
if scriptname == File.basename($0) then
conf.channel = "some-room"
else
conf.channel = "botdev"
end
conf.server = "conf.example.com"
end
message(/^#{botnick}[,|:| ].*$/i) do |message, params|
arr = message.text.split(/\W+/)
if arr[1].nil? == false then
if arr[1].chomp.strip != "" then
mpdcontrol(mpd,arr[1].chomp.strip,message,"0")
else
mpdcontrol(mpd,"status",message,"0")
end
else
mpdcontrol(mpd,"status",message,"0")
end
end
query do |message, params|
arr = message.text.split(/\W+/)
if arr[0].nil? == false then
if arr[0].chomp.strip != "" then
mpdcontrol(mpd,arr[0].chomp.strip,message, "1")
else
mpdcontrol(mpd,"status",message,"1")
end
else
mpdcontrol(mpd,"status",message,"1")
end
end
Loading…
Cancel
Save