examples/tune.lua
author Myhailo Danylenko <isbear@ukrpost.net>
Wed, 28 Nov 2012 20:17:53 +0200
changeset 146 04d19c9c1196
parent 71 eb6edac301ac
permissions -rw-r--r--
Fix module loading problem


local mpd    = require 'mpd'
local lm     = require 'lm'
local pubsub = require 'lm.pubsub'
local tune   = require 'lm.tune'

local tune_enabled = false
local mpd_pub_song = { }

pubsub.handler ( 'http://jabber.org/protocol/tune',
	function ( from, node, data )
		local self = false
		if from == lm.connection.bless ( main.connection () ):jid():gsub ( '/.*', '' ) then -- o_O
			self         = true
			mpd_pub_song = { }
		end
		local item = data:child ()
		local text = ''
		while item do
			local name  = item:name ()
			local value = item:value ()
			if self then
				mpd_pub_song[name] = value or ''
			end
			text = ("%s\n- %s: %s"):format ( text, item:name (), item:value () or '' )
			item = item:next ()
		end
		if main.yesno ( main.option ( 'lua_pep_notification' ) ) then
			if text ~= '' then
				text = 'Now listening to:' .. text
			else
				text = 'Now not listening to anything'
			end
		end
		main.print_info ( from, text )
		return true
	end )

local function mpd_getstatus ()
	local status = mpd.call_command { 'status' }
	if not tune_enabled or ( status.state ~= 'play' and status.state ~= 'pause' ) then
		for k, v in pairs ( mpd_pub_song ) do -- if there is anything published, publish nothing
			return { }
		end
		return nil
	end
	
	local song      = mpd.call_command { 'currentsong' }
	local dir, file = song.file:match ( '(.+)/(.-)' )
	-- populate according to currentsong fields: artist - artist, length - time, source - album, title - title, track - id, rating - ?, uri - ?
	local ret = {
		artist = song.artist or 'Unknown',
		length = song.time,
		source = song.album  or dir,
		title  = song.title  or file,
		track  = song.id,
	}

	if not song.time or song.time == '0' then -- XXX
		ret.length = nil
	end

	local modified = false
	for k, v in pairs ( ret ) do
		if mpd_pub_song[k] ~= v then
			modified = true
			break
		end
	end
	if not modified then
		for k, v in pairs ( mpd_pub_song ) do
			if ret[k] ~= v then
				modified = true
				break
			end
		end
	end

	if modified then
		return ret
	else
		return nil
	end
end

local function mpd_callback ()
	local sdata = mpd_getstatus ()
	if sdata then
		tune.publish ( lm.connection.bless ( main.connection () ),
			function ()
			end,
			function ( mesg )
				print ( 'Error publishing tune: ' .. mesg )
			end, sdata )
	end
	if tune_enabled then
		return true
	else
		return false
	end
end

-- do not call it too fast, or you end up with many daemons at once
local function enable_tune ( yn )
	if yn == nil then
		yn = true
	end
	if yn then
		if not tune_enabled then
			main.timer ( 15, mpd_callback )
			tune_enabled = true
			-- update status
		end
	else
		if tune_enabled then
			tune_enabled = false
			-- update status
		end
	end
end

main.command ( 'tune',
	function ( args )
		local enable = main.yesno ( args )
		if enable == nil then
			if tune_enabled then
				print ( "Tune notifications enabled" )
			else
				print ( "Tune notifications disabled" )
			end
		else
			enable_tune ( enable )
		end
	end, false, 'yesno' )

commands_help['tune'] = "[enable|disable|on|off|yes|no|true|false]\n\nEnables or disables publishing of notifications about playing music in your player (currently only mpd is supported)."

hooks_d['hook-post-connect'].tune =
	function ( args )
		if tune_enabled then
			mpd_callback ()
		end
	end

main.add_feature ( 'http://jabber.org/protocol/tune+notify' )
main.add_feature ( 'http://jabber.org/protocol/tune' )

mpd.server ( "localhost", 6600, nil )

-- vim: se ts=4: --