# This file is part of emesene.
#
# Emesene is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# emesene is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with emesene; if not, write to the Free Software
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
#
# This plugin uses some code of http://dev.jmoiron.net/projects/browser/xchat/mp3.py?rev=27&format=txt
#
VERSION = '0.3'
import os
import struct
import socket
if os.name == 'posix':
import pwd
import CurrentSong
ERROR = ''
#Commands for sockets
CMD_GET_VERSION = 0 #
CMD_PLAYLIST_ADD = 1 #
CMD_PLAY = 2 #
CMD_PAUSE = 3 #
CMD_STOP = 4 #
CMD_IS_PLAYING = 5 #
CMD_IS_PAUSED = 6 #
CMD_GET_PLAYLIST_POS = 7 #
CMD_SET_PLAYLIST_POS = 8 #
CMD_GET_PLAYLIST_LENGTH = 9 #
CMD_PLAYLIST_CLEAR = 10 #
CMD_GET_OUTPUT_TIME = 11 #
CMD_JUMP_TO_TIME = 12 #
CMD_GET_VOLUME = 13 #
CMD_SET_VOLUME = 14 #
CMD_GET_SKIN = 15 #
CMD_SET_SKIN = 16
CMD_GET_PLAYLIST_FILE = 17 #
CMD_GET_PLAYLIST_TITLE = 18 #
CMD_GET_PLAYLIST_TIME = 19 #
CMD_GET_INFO = 20 #
CMD_GET_EQ_DATA = 21 # these two aren't implemented in
CMD_SET_EQ_DATA = 22 # xmms 1.0.1, and that's all I have
CMD_PL_WIN_TOGGLE = 23 #
CMD_EQ_WIN_TOGGLE = 24 #
CMD_SHOW_PREFS_BOX = 25 #
CMD_TOGGLE_AOT = 26 #
CMD_SHOW_ABOUT_BOX = 27 # doesn't seem to work :-(
CMD_EJECT = 28 #
CMD_PLAYLIST_PREV = 29 #
CMD_PLAYLIST_NEXT = 30 #
CMD_PING = 31
CMD_GET_BALANCE = 32 #
CMD_TOGGLE_REPEAT = 33 #
CMD_TOGGLE_SHUFFLE = 34 #
CMD_MAIN_WIN_TOGGLE = 35 #
CMD_PLAYLIST_ADD_URL_STRING = 36
CMD_IS_EQ_WIN = 37 #
CMD_IS_PL_WIN = 38 #
CMD_IS_MAIN_WIN = 39 #
class ClientPacketHeader:
def __init__(self):
self.version,self.cmd,self.length = 0,0,0
def __repr__(self):
return "<< %s : version: %s cmd: %s length: %s >>"\
%(self.__class__.__name__,self.version,self.cmd,self.length)
def encode(self):
return struct.pack("=hhl",self.version,self.cmd,self.length)
class XmmsSocket:
def __init__(self,session=0):
self.status = True
self.sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
if os.path.exists( "/tmp/xmms_%s.%d"%(pwd.getpwuid(os.geteuid())[0],session) ):
sockFile = "/tmp/xmms_%s.%d"%(pwd.getpwuid(os.geteuid())[0],session)
#elif os.path.exists( "/tmp/audacious_%s.%d"%(pwd.getpwuid(os.geteuid())[0],session) ):
# sockFile = "/tmp/audacious_%s.%d"%(pwd.getpwuid(os.geteuid())[0],session)
else:
self.status = False
return
if sockFile == None: return
try:
self.sock.connect( sockFile )
except:
self.status = False
def send(self,cmd,data=""):
if type(data) == type(1):
data = struct.pack("=l",data)
packet = struct.pack("=hhl",1,cmd,len(data))+data
self.sock.send(packet)
def sendf(self,cmd,fmt,args):
data = apply(struct.pack,(fmt,)+args)
self.send(cmd,data)
def read_header(self, sock):
head = ClientPacketHeader()
head.version, head.cmd, head.length = \
struct.unpack("=hhl",sock.recv(struct.calcsize( "=hhl" )))
#struct.unpack("hhl",sock.recv(8))
return head
def get_reply(self):
self.reply_header = self.read_header(self.sock)
return self.sock.recv(self.reply_header.length)\
.decode('utf-8', 'replace').encode('utf-8')
def get_replyf(self,fmt):
return struct.unpack(fmt,self.get_reply())
def read_ack(self):
self.get_reply()
def isXmmsOpen(self):
return self.status
class XmmsCommands:
def __init__(self):
pass
def send_requestf(self, cmd, fmt, data=""):
xmmsSocket = XmmsSocket()
if xmmsSocket.isXmmsOpen():
xmmsSocket.send(cmd, data)
return xmmsSocket.get_replyf(fmt)
return False
def send_command(self, cmd, data=""):
xmmsSocket = XmmsSocket()
if xmmsSocket.isXmmsOpen():
xmmsSocket.send(cmd,data)
#xmmsSocket.read_ack()
return False
def send_request_args(self, cmd, fmt, *args):
xmmsSocket = XmmsSocket()
if xmmsSocket.isXmmsOpen():
xmmsSocket.sendf(cmd, fmt, args)
return xmmsSocket.get_reply()
return False
def playlist_pos(self):
return self.send_requestf(CMD_GET_PLAYLIST_POS,'=l')[0]
def playlist_file(self , pos):
return self.send_request_args(CMD_GET_PLAYLIST_FILE,'=l',pos)[:-1]
def playlist_title(self, pos):
return self.send_request_args(CMD_GET_PLAYLIST_TITLE,'=l',pos)[:-1]
def playlist_time(self, pos):
return self.send_requestf_args(CMD_GET_PLAYLIST_TIME,'=l','=l',pos)[0]
def socket_info(self):
"""returns (bitrate, freq, nch)"""
return self.send_requestf(CMD_GET_INFO, '=lll')
def socket_playlist_length(self):
return self.send_requestf(CMD_GET_PLAYLIST_LENGTH,'=l')[0]
# in milliseconds
def socket_output_time(self):
return self.send_requestf(CMD_GET_OUTPUT_TIME,'=l')[0]
def currentSong(self):
return self.playlist_title(self.playlist_pos())
def nextSong( self ):
self.send_command(CMD_PLAYLIST_NEXT)
def isPlaying(self):
if XmmsSocket().isXmmsOpen():
return self.send_requestf(CMD_IS_PLAYING,'=l')[0]
return False
class Xmms(CurrentSong.CurrentSong):
def __init__( self ):
CurrentSong.CurrentSong.__init__( self )
self.currentSong = ''
self.xmms = XmmsCommands()
def getSongPlain( self ):
if not self.isPlaying():
return ''
return self.xmms.currentSong()
def getCurrentSong( self ):
if not self.isPlaying():
return ''
song = '\\0Music\\01\\0' + self.xmms.currentSong() + '\\0\\0'
return song
def nextSong( self ):
self.xmms.nextSong()
def isPlaying( self ):
if self.xmms.isPlaying():
return True
return False
def isRunning( self ):
if self.xmms.isPlaying():
return True
return False
def getStatus( self ):
if os.name != 'posix':
return ( False, 'This plugin only works in posix systems' )
if ERROR:
return ( False, ERROR )
return ( True, 'Ok' )
def check( self ):
if self.currentSong != self.getCurrentSong():
self.currentSong = self.getCurrentSong()
return True
return False
|