#!/usr/bin/env python

# MobLRC Server - Mobile Linux Remote Control Server
# Copyright (C) 2006 PoisoneR
# Author: PoisoneR
# License: GPL

# This program 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.

# This program 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 this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.

# Todo
# smenq proramata edin put i podawa komanda
# return song name and artist
# login password
# volume repeat command some times, w dict-a da ima list i da se izpulnqwat wsi4ki elementi
# start program if it is not
# proper quit
# choose better port than 7777

__author__ = "PoisoneR"
__version__ = "0.1.1"
__copyright__ = "(c) 2006 PoisoneR <poisonerbg@gmail.com>"
__projecthome__ = "http://moblrc.sourceforge.net"

from select import select
from socket import socket, AF_INET, SOCK_STREAM
from threading import Thread
from commands import getoutput
from os import popen

HOSTNAME = ''
PORT = 7777

class amarok:
	"""Amarok plugin for MobLRC"""
	def __init__(self):
		self.commands = {
			'aV' : 'dcop amarok player prev',
			'aA' : 'dcop amarok player pause',
			'aP' : 'dcop amarok player play',
			'aS' : 'dcop amarok player stop',
			'aN' : 'dcop amarok player next',
			'aM' : 'dcop amarok player mute',
			'aU' : 'dcop amarok player volumeUp',
			'aD' : 'dcop amarok player volumeDown',
			'aQ' : 'dcop amarok MainApplication-Interface quit'
			}
	def execCmd(self, cmd):
		"""Execute received command"""
		print cmd
		self.isAmarokRunning()
		if cmd in self.commands:
			return getoutput(self.commands[cmd])
		else:
			return 'Unknown command.'
	def isAmarokRunning(self):
		"""Check is Amarok running, if not start it"""
		notRunning = "No such application: 'amarok'"
		check = getoutput('dcop amarok')
		if (check == notRunning):
			print 'Startting Amarok'
			popen('amarok')

class kaffeine:
	"""Kaffeine plugin for MobLRC"""
	def __init__(self):
		self.commands = {
			'kV' : 'dcop kaffeine KaffeineIface prev',
			'kA' : 'dcop kaffeine KaffeineIface pause',
			'kP' : 'dcop kaffeine KaffeineIface play',
			'kS' : 'dcop kaffeine KaffeineIface stop',
			'kN' : 'dcop kaffeine KaffeineIface stop',
			'kM' : 'dcop kaffeine KaffeineIface stop',
			'kU' : 'dcop kaffeine KaffeineIface volUp',
			'kD' : 'dcop kaffeine KaffeineIface volDown',
			'kQ' : 'dcop kaffeine KaffeineIface quit'
			}
	def execCmd(self, cmd):
		print cmd
		self.isKaffeineRunning()
		if cmd in self.commands:
			return getoutput(self.commands[cmd])
		else:
			return 'Unknown command.'
	def isKaffeineRunning(self):
		notRunning = "No such application: 'kaffeine'"
		check = getoutput('dcop kaffeine')
		if (check == notRunning):
			print 'Starting Kaffeine'
			popen('kaffeine')

class server(Thread):
	"""MobLRC server"""
	def __init__(self):
		Thread.__init__(self)
		self.portsock = socket(AF_INET, SOCK_STREAM)
		self.portsock.bind((HOSTNAME, PORT))
		self.portsock.listen(5)
		self.mainsocks = [self.portsock]
		self.readsocks = [self.portsock]
		self.writesocks = [self.portsock]
		self.amarokPlugin = amarok()
		self.kaffeinePlugin = kaffeine()
	def loop(self):
		try:
			done = False
			while not done:
				self.run()
		except KeyboardInterrupt:
				self.disconnect()

	def run(self):
		readables, writeables, exceptions = select(self.readsocks, self.writesocks, [])
		for sockobj in readables:
			if sockobj in self.mainsocks:
				# Accept new client
				newsock, address = sockobj.accept()
				print 'Connect new client: ', id(sockobj)
				self.readsocks.append(newsock)
			else:
				try:
					data = (sockobj.recv(1024))
					print 'Received data: ', data, id(sockobj)
					if not data:
						print 'Closing connection: ', id(sockobj)
						sockobj.close()
						self.readsocks.remove(sockobj)
					elif data == 'quit':
						print 'Quit'
						#self.disconnect()
					else:
						print 'Executing command: ', data
						# get data and return result
						output = ''
						if data in self.amarokPlugin.commands:
							output = self.amarokPlugin.execCmd(data)
						elif data in self.kaffeinePlugin.commands:
							output = self.kaffeinePlugin.execCmd(data)
						else:
							ouptut = 'Unknown command'
						sockobj.send(output + '\n')
				except:
						print 'Exception'
	
	def disconnect(self):
		for sock in self.mainsocks:
			sock.close()

	def __del__(self):
		self.disconnect()

if __name__ == '__main__':
	test = server()
	test.loop()