[Tkabber-dev] r53 - in trunk/plugins: . now_playing now_playing/contrib

tkabber-svn at jabber.ru tkabber-svn at jabber.ru
Tue Sep 25 04:03:01 MSD 2007


Author: kostix
Date: 2007-09-25 04:03:01 +0400 (Tue, 25 Sep 2007)
New Revision: 53

Added:
   trunk/plugins/now_playing/contrib/README
   trunk/plugins/now_playing/mpd.tcl
Removed:
   trunk/plugins/np_registry/
   trunk/plugins/np_send/
Modified:
   trunk/plugins/now_playing/now_playing.tcl
Log:
np_registry, np_send: deleted, functionality is (or is planned to be) in now_playing.

now_playing/contrib/README: moved here from np_send, briefly describes tkamarok.

now_playing/mpd.tcl: sample code to get now-playing info from MPD.
  when complete, will be included to now_playing.

now_playing/now_playing.tcl: misc fix.


Copied: trunk/plugins/now_playing/contrib/README (from rev 50, trunk/plugins/np_send/README)
===================================================================
--- trunk/plugins/now_playing/contrib/README	                        (rev 0)
+++ trunk/plugins/now_playing/contrib/README	2007-09-25 00:03:01 UTC (rev 53)
@@ -0,0 +1,24 @@
+"Now Playing via Tk [send]" plugin for Tkabber.
+$Id$
+
+I. The idea.
+
+...
+
+
+II. Supported media players.
+
+Currently these media players are supported:
+
+* Amarok [1] via "TkAmarok" script.
+
+
+III. Installation of TkAmarok script.
+
+
+V. References:
+
+1. http://amarok.kde.org
+
+
+vim:et:ts=4:sw=4:tw=64

Added: trunk/plugins/now_playing/mpd.tcl
===================================================================
--- trunk/plugins/now_playing/mpd.tcl	                        (rev 0)
+++ trunk/plugins/now_playing/mpd.tcl	2007-09-25 00:03:01 UTC (rev 53)
@@ -0,0 +1,325 @@
+# $Id$
+# Sample code to get "now playing" info from MPD.
+
+namespace eval plugins::tune {
+	proc publish args   { puts [info level 0] }
+	proc unpublish args { puts [info level 0] }
+}
+
+namespace eval now_playing {
+	variable connections [list 1]
+	variable lasttime 0
+	variable options
+	array set options {
+		media_player     mpd
+		check_timeout    3
+		update_threshold 5
+	}
+
+	proc my what {
+		return [uplevel 1 namespace current]::$what
+	}
+
+	proc mycmd args {
+		lset args 0 [uplevel 1 namespace current]::[lindex $args 0]
+	}
+
+	proc debugmsg {topic msg} {
+		puts "$topic: $msg"
+	}
+
+	proc warn {topic msg} {
+		puts $msg
+	}
+}
+
+#### Polling:
+
+proc now_playing::poll {op {script ""}} {
+	variable repollid
+
+	switch -- $op {
+		using {
+			[mycmd poller] $script
+		}
+		cancel {
+			if {[info exists repollid]} {
+				after cancel $repollid
+				unset repollid
+			}
+		}
+		default {
+			return -code error "Bad operation \"$op\":\
+				must be one of using or cancel"
+		}
+	}
+
+}
+
+proc now_playing::poller script {
+	variable options
+	variable repollid
+
+	debugmsg tune [info level 0]
+
+	namespace eval :: $script
+
+	if {$options(check_timeout) > 0} {
+		set repollid [after \
+			[expr {$options(check_timeout) * 1000}] [info level 0]]
+	}
+}
+
+#### Socket:
+
+proc now_playing::sock_connect {host port {timeout ""}} {
+	set sock [socket -async $host $port]
+	variable $sock
+	upvar 0 $sock state
+
+	if {$timeout != ""} {
+		set state(on_timeout) [after [expr {$timeout * 1000}] \
+			[mycmd OnSockTimeout $sock]]
+	}
+
+	fileevent $sock readable [mycmd OnSockConnected $sock]
+
+	vwait [my $sock](result)
+
+	lassign $state(result) status msg
+	unset state
+
+	switch -- $status {
+		OK {
+			return $sock
+		}
+		ERROR {
+			return -code error $msg
+		}
+	}
+}
+
+proc now_playing::OnSockConnected sock {
+	variable $sock
+	upvar 0 $sock state
+
+	fileevent $sock readable {}
+	if {[info exists state(on_timeout)]} {
+		after cancel $state(on_timeout)
+	}
+
+	set err [fconfigure $sock -error]
+	if {$err == ""} {
+		set state(result) [list OK ""]
+	} else {
+		set state(result) [list ERROR $err]
+	}
+}
+
+proc now_playing::OnSockTimeout sock {
+	variable $sock
+	upvar 0 $sock state
+
+	set state(result) [list ERROR "Connection timed out"]
+}
+
+#### MPD:
+
+proc now_playing::laststate {op {val ""}} {
+	variable mpd
+
+	switch -- $op {
+		get {
+			set mpd(laststate)
+		}
+		is {
+			string equal $mpd(laststate) $val
+		}
+		set {
+			set mpd(laststate) $val
+		}
+		default {
+			return -code error "Bad operation \"$op\":\
+				must be one of get, is or set"
+		}
+	}
+}
+
+proc now_playing::mpd_init {} {
+	variable mpd
+	upvar 0 mpd(sock) sock
+
+	# TODO make host and port tunable:
+	set sock [sock_connect localhost 6600 5]
+	gets $sock ;# read hello string from mpd
+
+	# TODO provide for login, if needed...
+
+	fconfigure $sock -buffering line -translation lf -encoding utf-8
+
+	laststate set unknown
+
+	poll using [mycmd mpd_yield $sock]
+}
+
+proc now_playing::mpd_cleanup {} {
+	variable mpd
+
+	if {[array exists mpd]} {
+		close $mpd(sock)
+		unset mpd
+	}
+}
+
+proc now_playing::mpd_yield sock {
+	variable mpd
+	variable options
+	variable lasttime
+
+	debugmsg tune [info level 0]
+
+	puts $sock status
+
+	set state    unknown
+	set playlist -1
+	set songid   -1
+
+	while 1 {
+		if {[gets $sock line] < 0} {
+			# EOF => mpd closed
+			# TODO ideally, we should schedule connection retries here
+			# instead of just giving up
+			monitoring off
+			return
+		}
+		switch -glob -- $line {
+			state:*    {
+				set state    [mpd_getval $line state]
+			}
+			playlist:* {
+				set playlist [mpd_getval $line playlist]
+			}
+			songid:*   {
+				set songid   [mpd_getval $line songid]
+			}
+			OK         break
+		}
+	}
+
+	debugmsg tune "state: $state\n\
+		playlist: $playlist\n\
+		songid: $songid"
+
+	switch -- $state {
+		stop  -
+		pause {
+			set newstate inactive
+		}
+		play {
+			set newstate active
+		}
+		default {
+			warn parsing "unknown player state \"$state\", ignored"
+			return
+		}
+	}
+
+	if {[laststate is $newstate]} return
+
+	if {[clock seconds] - $lasttime < $options(update_threshold)} return
+
+	switch -- $newstate {
+		inactive {
+			variable connections
+			foreach connid $connections {
+				::plugins::tune::unpublish $connid
+			}
+		}
+		active {
+			set unseen no
+			if {![info exists mpd(playlist)]} {
+				set mpd(playlist) $playlist
+				set unseen yes
+			}
+			if {![info exists mpd(songid)]} {
+				set mpd(songid) $songid
+				set unseen yes
+			}
+
+			if {$unseen
+			|| $mpd(playlist) != $playlist
+			|| $mpd(songid) != $songid} {
+				set mpd(playlist) $playlist
+				set mpd(songid)   $songid
+
+				mpd_get_songinfo $sock info
+				mpd_publish_songinfo info
+			}
+		}
+	}
+
+	laststate set $newstate
+	set lasttime [clock seconds]
+	return
+}
+
+proc now_playing::mpd_get_songinfo {sock vinfo} {
+	upvar 1 $vinfo info
+
+	puts $sock currentsong
+
+	while 1 {
+		if {[gets $sock line] < 0} {
+			# EOF => mpd closed
+			# TODO ideally, we should schedule connection retries here
+			# instead of just giving up
+			monitoring off
+			return
+		}
+		switch -glob -- $line {
+			Artist:* {
+				set info(artist) [mpd_getval $line Artist]
+			}
+			Title:*  {
+				set info(title)  [mpd_getval $line Title]
+			}
+			Track:*  {
+				set info(track)  [mpd_getval $line Track]
+			}
+			Time:*   {
+				set info(length) [mpd_getval $line Time]
+			}
+			Album:*  {
+				set info(source) [mpd_getval $line Album]
+			}
+			OK       break
+		}
+	}
+}
+
+proc now_playing::mpd_getval {s key} {
+	set val [string trim [string range $s [string length $key:] end]]
+	puts "[info level 0] -> $val"
+	set val
+}
+
+proc now_playing::mpd_publish_songinfo vinfo {
+	variable connections
+	upvar 1 $vinfo info
+
+	set opts [list]
+	foreach {key val} [array get info] {
+		lappend opts -$key $val
+	}
+
+	foreach connid $connections {
+		eval [list ::plugins::tune::publish $connid] $opts
+	}
+}
+
+#### Action:
+
+now_playing::mpd_init
+
+vwait forever
+


Property changes on: trunk/plugins/now_playing/mpd.tcl
___________________________________________________________________
Name: svn:keywords
   + Id
Name: svn:eol-style
   + native

Modified: trunk/plugins/now_playing/now_playing.tcl
===================================================================
--- trunk/plugins/now_playing/now_playing.tcl	2007-09-23 00:55:47 UTC (rev 52)
+++ trunk/plugins/now_playing/now_playing.tcl	2007-09-25 00:03:01 UTC (rev 53)
@@ -724,7 +724,6 @@
 
 	set now [clock seconds]
 	if {$now - $lasttime < $options(update_threshold)} return
-	set lasttime $now
 
 	puts $sock currentsong
 
@@ -758,6 +757,8 @@
 		}
 	}
 
+	set lasttime $now
+
 	foreach connid $connections {
 		eval [list ::plugins::tune::publish $connid] $opts
 	}



More information about the Tkabber-dev mailing list