commit do server
authorJônatas Isvi <jonatas@nona-desktop.(none)>
Thu, 4 Jun 2009 06:44:51 +0000 (02:44 -0400)
committerJônatas Isvi <jonatas@nona-desktop.(none)>
Thu, 4 Jun 2009 06:44:51 +0000 (02:44 -0400)
27 files changed:
pcremote-server/connection/__init__.py [new file with mode: 0755]
pcremote-server/connection/bluetoothconnectionmanager.py [new file with mode: 0755]
pcremote-server/connection/genericconnectionmanager.py [new file with mode: 0755]
pcremote-server/connection/iconnection.py [new file with mode: 0755]
pcremote-server/connection/wirelessconnectionmanager.py [new file with mode: 0755]
pcremote-server/exceptions/__init__.py [new file with mode: 0755]
pcremote-server/exceptions/exception.py [new file with mode: 0755]
pcremote-server/images/28x.png [new file with mode: 0755]
pcremote-server/images/64x.png [new file with mode: 0755]
pcremote-server/images/PCR_off.bmp [new file with mode: 0755]
pcremote-server/images/PCR_on.bmp [new file with mode: 0755]
pcremote-server/images/remote48x.png [new file with mode: 0755]
pcremote-server/pcremote-server.py [new file with mode: 0755]
pcremote-server/players/__init__.py [new file with mode: 0755]
pcremote-server/players/amarok.py [new file with mode: 0755]
pcremote-server/players/playlist.py [new file with mode: 0755]
pcremote-server/players/plistparser.py [new file with mode: 0755]
pcremote-server/players/run-amarok.py [new file with mode: 0755]
pcremote-server/runserver.py [new file with mode: 0644]
pcremote-server/services/ObjectServers.py [new file with mode: 0755]
pcremote-server/services/ServerHandlers.py [new file with mode: 0755]
pcremote-server/services/__init__.py [new file with mode: 0755]
pcremote-server/services/service.py [new file with mode: 0755]
pcremote-server/utils/__init__.py [new file with mode: 0755]
pcremote-server/utils/labels.py [new file with mode: 0755]
pcremote-server/utils/messages.py [new file with mode: 0755]
pcremote-server/utils/plistparser.py [new file with mode: 0755]

diff --git a/pcremote-server/connection/__init__.py b/pcremote-server/connection/__init__.py
new file mode 100755 (executable)
index 0000000..e69de29
diff --git a/pcremote-server/connection/bluetoothconnectionmanager.py b/pcremote-server/connection/bluetoothconnectionmanager.py
new file mode 100755 (executable)
index 0000000..581b0f8
--- /dev/null
@@ -0,0 +1,215 @@
+# -*- coding: utf-8 -*-
+
+#  ****************************************************************************
+#  Copyright (c) 2008 INdT/Fucapi.
+#  This program is free software: you can redistribute it and/or modify
+#  it under the terms of the GNU Lesser General Public License as published by
+#  the Free Software Foundation, either version 3 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 Lesser General Public License for more details.
+#
+#  You should have received a copy of the GNU Lesser General Public License
+#  along with this program.  If not, see <http://www.gnu.org/licenses/>.
+#
+#  ============================================================================
+#  Project Name : PC Remote
+#  Author       : Jônatas Isvi
+#  Email        : jonatas.nona@gmail.com
+#  Reviewer     : 
+#  Email        :
+#  Version      : 1.0
+#  Package      : connection
+#  Description  : BluetoothConnectionManager
+#  ============================================================================
+
+import bluetooth
+from exceptions import *
+from genericconnectionmanager import *
+
+class BluetoothConnectionManager(GenericConnectionManager):
+
+    """ BluetoothConnectionManager
+
+    manages objects and operations for bluetooth connection.
+    Subclass of GerericConnectionManager.
+    """
+
+    def __init__(self):        
+               GenericConnectionManager.__init__(self)
+       self.sock           =    None
+       self.port           =    None
+       self.address        =    None
+       self.client_sock    =    None
+       self.client_address =    None           
+
+    # fast way to create a simple server
+    def create_server(self, protocol, port):
+       self.create_socket(protocol)
+       self.set_port(port)
+       self.bind()
+       self.listen()
+       self.accept()
+
+    # fast way to create a simple client       
+    def create_client(self, protocol, address, port):
+       self.create_socket(protocol)
+       self.set_address(address)
+       self.set_port(port)
+       self.connect()
+
+    # search for all devices
+    def find_devices(self, time=8):
+       list_devices = bluetooth.discover_devices(lookup_names = True, duration=time)
+       if list_devices:
+           print list_devices
+           return list_devices
+       else:
+           raise BluetoothConnectionError, "Device were not found." 
+       
+    # search the device port
+    def find_port(self, addr):
+       port = None
+       aux = addr.split(":")
+       if len(aux) == 6:
+           services = bluetooth.find_service(address=addr)
+           for i in range(len(services)):
+               port = services[i]['port']
+                
+           if port != None:        
+               return port
+           else:
+               raise BluetoothConnectionError, "Port not found."
+                               
+       else:
+           raise BluetoothConnectionError, "Invalid address."
+        
+    # search device services
+    def find_services(self, service=None, addr=None):
+       if service == None and addr == None:
+           list = bluetooth.find_service()
+           return list
+       elif service != None and addr == None:
+           list = bluetooth.find_service(name=service)
+           if list != []:
+               return list
+           else:
+               raise BluetoothConnectionError, "Name of the service does not exist."
+       elif service == None and addr != None:
+           number = addr.split(":")
+           if(len(number) == 6):
+               list = bluetooth.find_service(address=addr)
+               if list != []:
+                   return list
+               else:
+                   raise BluetoothConnectionError, "Services not found."
+           else:
+               raise BluetoothConnectionError, "Invalid address."
+       elif service != None and addr != None:
+           number = addr.split(":")
+           if(len(number) == 6):
+               list = bluetooth.find_service(name=service, address=addr)
+               if list != []:
+                   return list
+               else:
+                   raise BluetoothConnectionError, "Services not found."
+           else:
+               raise BluetoothConnectionError, "Invalid address."
+       
+
+    # search the device indicated by name
+    def find_device_address_by_name(self, device_name):        
+               list = bluetooth.discover_devices()
+       addr = None
+               
+       for address in list:
+           if device_name == bluetooth.lookup_name(address):
+               addr = address
+               break
+       if addr:
+           return addr
+       else:
+            raise BluetoothConnectionError, "Device name not found."
+       
+    # search only device names
+    def find_devices_only_names(self):
+       list = self.find_devices()
+       list_names = []
+       for address, names in list:
+           list_names += [names]
+       
+       if list_names:
+           return list_names
+       else:
+           raise BluetoothConnectionError, "Devices were not found."
+
+    # get the client address
+    def get_client_address(self):
+        return self.client_address     
+
+    # set the port to communicate
+    def set_port(self, port):
+       self.port = port
+
+    # get the port to communicate
+    def get_port(self):
+       return self.port
+
+    # set the device address
+    def set_address(self, address):
+       aux = address.split(":")
+       if len(aux) == 6:
+           self.address = address
+       else:
+           raise BluetoothConnectionError, "Invalid address."
+
+    # get the device address
+    def get_address(self):
+       return self.address
+
+    # create a socket with a determinated protocol
+    def create_socket(self, protocol=None):
+       if protocol == 'rfcomm' or protocol == 'RFCOMM':
+           self.sock = bluetooth.BluetoothSocket(bluetooth.RFCOMM)
+       elif protocol == 'l2cap' or protocol == 'L2CAP':
+           self.sock = bluetooth.BluetoothSocket(bluetooth.L2CAP)
+       else:   
+           raise BluetoothConnectionError, "Undefined Protocol."
+
+    # bind the communication
+    def bind(self):
+       self.sock.bind(("", self.get_port()))
+
+    # just listen the tube, only to server
+    def listen(self):
+       self.sock.listen(1)
+
+    # accept the client communication 
+    def accept(self):
+       self.client_sock, self.client_address = self.sock.accept()
+               
+    # connect devices
+    def connect(self):
+       self.sock.connect((self.get_address(), self.get_port()))
+
+    # send string message              
+    def send_message(self, msg=None):
+       self.sock.send(msg)
+
+    # receive string message
+    def received_message(self):
+       return self.client_sock.recv(1024)
+
+    # close connection
+    def close(self):
+       if self.sock != None and self.client_sock != None:
+           self.client_sock.close()
+           self.sock.close()   
+       elif self.sock != None and self.client_sock == None:
+           self.sock.close()
+       else:
+           self.client_sock.close()
+
diff --git a/pcremote-server/connection/genericconnectionmanager.py b/pcremote-server/connection/genericconnectionmanager.py
new file mode 100755 (executable)
index 0000000..30a2894
--- /dev/null
@@ -0,0 +1,42 @@
+# -*- coding: utf-8 -*-
+
+#  ****************************************************************************
+#  Copyright (c) 2008 INdT/Fucapi.
+#  This program is free software: you can redistribute it and/or modify
+#  it under the terms of the GNU Lesser General Public License as published by
+#  the Free Software Foundation, either version 3 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 Lesser General Public License for more details.
+#
+#  You should have received a copy of the GNU Lesser General Public License
+#  along with this program.  If not, see <http://www.gnu.org/licenses/>.
+#
+#  ============================================================================
+#  Project Name : PC Remote
+#  Author       : André Portela
+#  Email        : andre_portela@hotmail.com
+#  Reviewer     : Jônatas Isvi
+#  Email        : jonatas.nona@gmail.com
+#  Version      : 1.0
+#  Package      : connection
+#  Description  : GenericConnectionManager
+#  ============================================================================
+
+
+class GenericConnectionManager:
+
+    """ GenericConnectionManager
+    Superclass of connections
+    """
+       
+    def __init__(self):
+               print "GenericConnectionManager iniciado."
+       self.tipo = "generico"
+
+    # current service running
+    def identify_app(self):
+       print "identify_app"
diff --git a/pcremote-server/connection/iconnection.py b/pcremote-server/connection/iconnection.py
new file mode 100755 (executable)
index 0000000..310d175
--- /dev/null
@@ -0,0 +1,167 @@
+# -*- coding: utf-8 -*-
+
+#  ****************************************************************************
+#  Copyright (c) 2008 INdT/Fucapi.
+#  This program is free software: you can redistribute it and/or modify
+#  it under the terms of the GNU Lesser General Public License as published by
+#  the Free Software Foundation, either version 3 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 Lesser General Public License for more details.
+#
+#  You should have received a copy of the GNU Lesser General Public License
+#  along with this program.  If not, see <http://www.gnu.org/licenses/>.
+#
+#  ============================================================================
+#  Project Name : PC Remote
+#  Author       : André Portela
+#  Email        : andre_portela_@hotmail.com
+#  Reviewer     : Jônatas Isvi
+#  Email        : jonatas.nona@gmail.com
+#  Version      : 1.0
+#  Package      : connection
+#  Description  : Iconnection Interface Class
+#  ============================================================================
+
+from wirelessconnectionmanager import *
+from bluetoothconnectionmanager import *
+from exceptions import *
+
+# connections aliases
+_btconst   = ['bluetooth', 'BLUETOOTH', 'blue']
+_wificonst = ['wireless', 'WIRELESS', 'wifi']
+
+class Iconnection:
+    
+    """ Iconnection
+    Interface for wireless and bluetooth connections.
+    Manages all commonalities operations between entities.
+    """
+    def __init__(self, string):
+       self.string = string
+       if(self.string in _btconst):
+           self.obj = BluetoothConnectionManager()
+       elif(self.string in _wificonst):
+           self.obj = WirelessConnectionManager()
+       else:
+           raise IconnectionError, "Undefined type."
+       
+       
+    # +---------------------------------------------+ 
+    # | Generic methods -> Wireless and Bluetooth   |
+    # +---------------------------------------------+
+
+    # create a socket with defined protocol
+    def create_socket(self, protocol=None):
+       self.obj.create_socket(protocol)
+
+    # connect device
+    def connect(self):
+       self.obj.connect()
+
+    # accept the connection
+    def accept(self):
+       return self.obj.accept()
+
+    # send a message to device
+    def send_message(self, msg=None):
+       self.obj.send_message(msg)
+       
+    # received a message 
+    def received_message(self):
+       return self.obj.received_message()
+       
+    # bind the connection
+    def bind(self):
+       self.obj.bind()
+
+    # listen the connection
+    def listen(self):
+       self.obj.listen()
+
+    # close connection
+    def close(self):
+       self.obj.close()
+
+    # set the port to communicate
+    def set_port(self, port):
+       self.obj.set_port(port)
+
+    # get the port to communicate
+    def get_port(self):
+       return self.obj.get_port()
+
+    # set the device address
+    def set_address(self, address):
+       self.obj.set_address(address)
+
+    # get the device address
+    def get_address(self):
+       return self.obj.get_address()
+
+    # get the client address
+    def get_client_address(self):
+       return self.obj.get_client_address()
+
+    # +------------------------------------------+
+    # | Bluetooth: particular behaviors          |
+    # +------------------------------------------+
+       
+    # fast way to create a simple server
+    def bluetooth_create_server(self, protocol, port):
+       if self.string in _btconst:
+           return self.obj.create_server(protocol, port)
+       else:
+           raise IconnectionError, "Only method used by Bluetooth connections."
+
+    # fast way to create a simple client
+    def bluetooth_create_client(self, protocol, address, port):
+       if self.string in _btconst:
+           return self.obj.create_client(protocol, address, port)
+       else:
+           raise IconnectionError, "Only method used by Bluetooth connections."
+
+    # search for all devices
+    def bluetooth_find_devices(self, time=8):
+               if self.string in _btconst:
+           return self.obj.find_devices(time)
+       else:
+           raise IconnectionError, "Only method used by Bluetooth connections."
+
+    # search only devices names
+    def bluetooth_find_devices_only_names(self):
+       if self.string in _btconst:
+           return self.obj.find_devices_only_names()
+       else:   
+                   raise IconnectionError, "Only method used by Bluetooth connections."
+
+    # search the device port
+    def bluetooth_find_port(self, addr):
+       if self.string in _btconst:
+           return self.obj.find_port(addr)
+       else:   
+           raise IconnectionError, "Only method used by Bluetooth connections."
+
+    # search device services
+    def bluetooth_find_services(self, service=None, addr=None):
+       if self.string in _btconst:
+           return self.obj.find_services(service, addr)
+       else:
+           raise IconnectionError, "Only method used by Bluetooth connections."
+
+
+    # search the device indicated by name
+    def bluetooth_find_device_address_by_name(self, device_name=None):
+       if self.string in _btconst:
+           return self.obj.find_device_address_by_name(device_name)
+       else:
+           raise IconnectionError, "Only method used by Bluetooth connections."
+
+
+
+    # +---------------------------------+
+    # | Wireless: particular behaviors  | 
+    # +---------------------------------+
diff --git a/pcremote-server/connection/wirelessconnectionmanager.py b/pcremote-server/connection/wirelessconnectionmanager.py
new file mode 100755 (executable)
index 0000000..e92ec3d
--- /dev/null
@@ -0,0 +1,43 @@
+# -*- coding: utf-8 -*-
+
+#  ****************************************************************************
+#  Copyright (c) 2008 INdT/Fucapi.
+#  This program is free software: you can redistribute it and/or modify
+#  it under the terms of the GNU Lesser General Public License as published by
+#  the Free Software Foundation, either version 3 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 Lesser General Public License for more details.
+#
+#  You should have received a copy of the GNU Lesser General Public License
+#  along with this program.  If not, see <http://www.gnu.org/licenses/>.
+#
+#  ============================================================================
+#  Project Name : PC Remote
+#  Author       : André Portela
+#  Email        : andre_portela_@hotmail.com
+#  Reviewer     : Jônatas Isvi
+#  Email        : jonatas.nona@gmail.com
+#  Version      : 0.1
+#  Package      : connection
+#  Description  : Wireless Connection Manager Class
+#  ============================================================================
+
+from genericconnectionmanager import * 
+
+class WirelessConnectionManager(GenericConnectionManager):
+
+    """ WirelessConnectionManager
+    Manages objects and operations for wireless connection.
+    Subclass of GenericConnectionManager.
+    """    
+
+    def __init__(self):
+       GenericConnectionManager.__init__(self)
+       self.tipo = "wireless"
+
+    
+
diff --git a/pcremote-server/exceptions/__init__.py b/pcremote-server/exceptions/__init__.py
new file mode 100755 (executable)
index 0000000..e69de29
diff --git a/pcremote-server/exceptions/exception.py b/pcremote-server/exceptions/exception.py
new file mode 100755 (executable)
index 0000000..697535b
--- /dev/null
@@ -0,0 +1,52 @@
+# -*- coding: utf-8 -*-
+
+#  ****************************************************************************
+#  Copyright (c) 2008 INdT/Fucapi.
+#  This program is free software: you can redistribute it and/or modify
+#  it under the terms of the GNU Lesser General Public License as published by
+#  the Free Software Foundation, either version 3 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 Lesser General Public License for more details.
+#
+#  You should have received a copy of the GNU Lesser General Public License
+#  along with this program.  If not, see <http://www.gnu.org/licenses/>.
+#
+#  ============================================================================
+#  Project Name : PC Remote
+#  Author       : Jônatas Isvi
+#  Email        : jonatas.nona@gmail.com
+#  Reviewer     : 
+#  Email        :
+#  Version      : 1.0
+#  package      : exceptions
+#  Description  : Exceptions
+#  ============================================================================
+
+class BluetoothConnectionError(Exception):
+       ''' Treatment of errors bluetooth connections '''
+       pass
+
+class WirelessConnectionError(Exception):
+       ''' Treatment of errors wireless connections '''
+       pass
+
+class IconnectionError(Exception):
+       ''' Treatment of errors Iconnection class '''
+       pass
+
+
+       
+
+
+
+
+
+
+
+
+       
+
diff --git a/pcremote-server/images/28x.png b/pcremote-server/images/28x.png
new file mode 100755 (executable)
index 0000000..9c918db
Binary files /dev/null and b/pcremote-server/images/28x.png differ
diff --git a/pcremote-server/images/64x.png b/pcremote-server/images/64x.png
new file mode 100755 (executable)
index 0000000..2e13bd7
Binary files /dev/null and b/pcremote-server/images/64x.png differ
diff --git a/pcremote-server/images/PCR_off.bmp b/pcremote-server/images/PCR_off.bmp
new file mode 100755 (executable)
index 0000000..c686d43
Binary files /dev/null and b/pcremote-server/images/PCR_off.bmp differ
diff --git a/pcremote-server/images/PCR_on.bmp b/pcremote-server/images/PCR_on.bmp
new file mode 100755 (executable)
index 0000000..84f4109
Binary files /dev/null and b/pcremote-server/images/PCR_on.bmp differ
diff --git a/pcremote-server/images/remote48x.png b/pcremote-server/images/remote48x.png
new file mode 100755 (executable)
index 0000000..22b5640
Binary files /dev/null and b/pcremote-server/images/remote48x.png differ
diff --git a/pcremote-server/pcremote-server.py b/pcremote-server/pcremote-server.py
new file mode 100755 (executable)
index 0000000..195af3e
--- /dev/null
@@ -0,0 +1,95 @@
+#!/usr/bin/env python
+
+from runserver import Server
+import gtk
+import thread
+import sys
+
+class Service:
+
+    def start_server(self, widget):
+
+        if self.connected == False:    
+            imagepath = self.images.replace('pcremote-server.py','images/PCR_on.bmp')
+            self.staticon.set_from_file(imagepath)
+            self.staticon.set_tooltip("PC Remote Server - Online")
+
+            img = gtk.Image()
+            img.set_from_stock(gtk.STOCK_DISCONNECT, gtk.ICON_SIZE_MENU)
+            self.menuItemCon.set_image(img)
+
+            self.srv = Server("PC Remote")
+            thread.start_new_thread(Server.start,(self.srv,"server"))
+
+        else:          
+            imagepath = self.images.replace('pcremote-server.py','images/PCR_off.bmp')
+            self.staticon.set_from_file(imagepath)
+            self.staticon.set_tooltip("PC Remote Server - Offline")
+
+            img = gtk.Image()
+            img.set_from_stock(gtk.STOCK_EXECUTE, gtk.ICON_SIZE_MENU)
+
+            self.menuItemCon.set_image(img)
+
+            thread.exit_thread()
+
+        self.connected = not self.connected
+
+    def  destroyer(self, widget,response_id, data= None):
+        if response_id == gtk.RESPONSE_OK:
+            gtk.main_quit()
+        else:
+            widget.hide()
+
+    def popup(self, widget):
+        dialog = gtk.MessageDialog(
+        parent         = None,
+        flags          = gtk.DIALOG_DESTROY_WITH_PARENT,
+        type           = gtk.MESSAGE_INFO,
+        buttons        = gtk.BUTTONS_OK_CANCEL,
+        message_format = "Do you want to shut down the server?")
+        dialog.set_title('PC Remote Server')
+        dialog.connect('response', self.destroyer)
+        dialog.show()
+     
+    def popup_menu_cb(self, widget, button, time, data = None):
+        if button == 3:
+            if data:
+                data.show_all()
+                data.popup(None, None, None, 3, time)
+       
+
+    def __init__(self):
+
+        self.images = sys.argv[0]
+        self.connected = False
+
+        self.staticon = gtk.StatusIcon()
+        imagepath = self.images.replace('pcremote-server.py','images/PCR_off.bmp')
+        self.staticon.set_from_file(imagepath)
+        self.staticon.set_tooltip("PC Remote Server(offline)")
+
+        self.menu = gtk.Menu()
+
+        self.menuItemCon = gtk.ImageMenuItem(gtk.STOCK_EXECUTE)
+        self.menuItemCon.connect('activate', self.start_server)
+
+        self.menuItemExit = gtk.ImageMenuItem(gtk.STOCK_QUIT)
+        self.menuItemExit.connect('activate', self.popup)
+
+        self.menu.append(self.menuItemCon)
+        self.menu.append(self.menuItemExit)
+
+        self.staticon.connect('popup-menu', self.popup_menu_cb, self.menu)
+
+        self.staticon.set_visible(True)
+
+        gtk.gdk.threads_init()
+        gtk.gdk.threads_enter()
+
+        gtk.main()
+
+        gtk.gdk.threads_leave()
+
+print sys.argv
+Srv = Service()
diff --git a/pcremote-server/players/__init__.py b/pcremote-server/players/__init__.py
new file mode 100755 (executable)
index 0000000..e69de29
diff --git a/pcremote-server/players/amarok.py b/pcremote-server/players/amarok.py
new file mode 100755 (executable)
index 0000000..2d54fb0
--- /dev/null
@@ -0,0 +1,242 @@
+# -*- coding: utf-8 -*-
+
+#  ****************************************************************************
+#  Copyright (c) 2008 INdT/Fucapi.
+#  This program is free software: you can redistribute it and/or modify
+#  it under the terms of the GNU Lesser General Public License as published by
+#  the Free Software Foundation, either version 3 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 Lesser General Public License for more details.
+#
+#  You should have received a copy of the GNU Lesser General Public License
+#  along with this program.  If not, see <http://www.gnu.org/licenses/>.
+#
+#  ============================================================================
+#  Project Name : PC Remote
+#  Author       : Jonatas Isvi
+#  Email        : jonatas.nona@gmail.com
+#  Reviewer     :
+#  Email        : 
+#  Version      : 1.0
+#  Packge       : players
+#  Description  : Amarok Player
+#  ============================================================================
+
+import os
+import commands
+import random
+from playlist import Playlist
+import pydcop
+
+# command line
+def shell(command):
+    return commands.getoutput(command)
+
+
+# starts the amarok player application
+def start():
+    os.popen('amarok')
+
+
+# close the amarok player application
+def shutdown():
+    shell('dcop amarok player stop')
+    pid = shell('pidof amarokapp')
+    shell('kill -9 %s' % pid)
+
+
+# verifies if the amarok is running 
+def isRunning():
+    pid = shell('pidof amarokapp')
+    if pid > 0:
+        return True
+    else:
+        return False
+
+def send_file(addr, path):
+    shell("bluetooth-sendto --dest=%s %s" + (addr, path))
+
+class AmarokPlayer():
+
+    """ Amarok
+    Define all states and functions of amarok player.
+    This class will build to support PCRemote Player,
+    receiving messages from any devices with a bluetooth 
+    connection.
+    """
+       
+    # some importants variables 
+    def __init__(self):
+               self.amarok = pydcop.anyAppCalled("amarok")
+        self.playlist = Playlist(self.amarok.playlist.saveCurrentPlaylist())
+        self.isPlaying()
+
+    # refresh playlist, accessing the Playlist class instance
+    def refresh_playlist(self):
+        self.playlist = Playlist(self.amarok.playlist.saveCurrentPlaylist())
+       self.isPlaying()
+
+    # get all songs of playlist
+    def song_list(self):
+        self.playlist.show()
+
+    # show current song, acessing the Playlist class instance
+    def current_song(self):
+       self.isPlaying()
+
+    # verifies if this amarok app is running
+    def isRunning(self):
+       aux = pydcop.anyAppCalled("amarok")
+        if aux:
+           return aux
+       else:
+           return None
+
+    # verifies if this amarok app is playing and update the 
+    # Playlist with current song
+    def isPlaying(self):
+               if not self.amarok.player.isPlaying() == 'true':
+           self.playlist.update(self.amarok.playlist.getActiveIndex(),\
+                                self.amarok.player.title(),               \
+                                self.amarok.player.artist(),              \
+                                self.amarok.player.path(),                \
+                                "." + self.amarok.player.type(),          \
+                               )
+            return True
+       else:
+           return False        
+
+    # get the players name
+    def getName(self):
+       return "Amarok"
+
+    # send audio files to the N810 device
+    def file_properties(self, index=None):
+        track = self.amarok.playlist.getActiveIndex()
+        audiofile = self.playlist.song_properties(index=track, path=True)
+       #audiofile = (self.playlist.song_filename(index),\
+       #             self.playlist.song_size(index))
+       return audiofile
+
+    # next button and sets current song
+    def next(self):
+       self.amarok.player.next()
+       self.playlist.update(self.amarok.playlist.getActiveIndex(),\
+                            self.amarok.player.title(),               \
+                            self.amarok.player.artist(),              \
+                            self.amarok.player.path(),                \
+                            "." + self.amarok.player.type(),          \
+                            )
+       
+    # prev button and sets current song
+    def prev(self):
+       self.amarok.player.prev()               
+       self.playlist.update(self.amarok.playlist.getActiveIndex(),\
+                            self.amarok.player.title(),               \
+                            self.amarok.player.artist(),              \
+                            self.amarok.player.path(),                \
+                            "." + self.amarok.player.type(),          \
+                            )
+       
+    # play button and sets current song
+    #def play(self):
+       #self.amarok.player.play()
+       #self.playlist.update(self.amarok.playlist.getActiveIndex() + 1,\
+       #                    self.amarok.player.title(),               \
+       #                    self.amarok.player.artist(),              \
+       #                    self.amarok.player.path(),                \
+       #                    "." + self.amarok.player.type(),          \
+       #                    )
+
+    # play button and sets current song
+    # receive track or random form
+    # the argument track has intended to manipulate
+    # the playlist form when the user indicate a song track
+    # in client application
+    def play(self, track=-1, rdm=False):
+        if rdm:
+            index = random.randint(0, self.playlist.length() - 1)
+            self.amarok.playlist.playByIndex(index)
+            self.playlist.update(index + 1,                      \
+                                 self.amarok.player.title(),     \
+                                 self.amarok.player.artist(),    \
+                                 self.amarok.player.path(),      \
+                                 "." + self.amarok.player.type(),\
+                                )
+        elif track != -1:
+            self.amarok.playlist.playByIndex(track)
+            self.playlist.update(track-1,                               \
+                                 self.amarok.player.title(),     \
+                                 self.amarok.player.artist(),    \
+                                 self.amarok.player.path(),      \
+                                 "." + self.amarok.player.type(),\
+                                 ) 
+        else:
+            self.amarok.player.play()
+            self.playlist.update(self.amarok.playlist.getActiveIndex() + 1,\
+                                 self.amarok.player.title(),               \
+                                 self.amarok.player.artist(),              \
+                                 self.amarok.player.path(),               \
+                                 "." + self.amarok.player.type(),         \
+                                 )
+       
+    # play button with index song and sets current song
+    #def play_track(self, index):
+    #  self.amarok.playlist.playByIndex(index-1)       
+    #  self.playlist.update(index,                          \
+    #                       self.amarok.player.title(),     \
+    #                       self.amarok.player.artist(),    \
+    #                       self.amarok.player.path(),      \
+    #                       "." + self.amarok.player.type(),\
+    #                       )
+
+    # random play songs
+    #def play_random(self):
+    #  index = random.randint(0, self.playlist.length() - 1)
+    #  self.amarok.playlist.playByIndex(index)
+    #  self.playlist.update(index+1,                        \
+    #                       self.amarok.player.title(),     \
+    #                       self.amarok.player.artist(),    \
+    #                       self.amarok.player.path(),      \
+    #                       "." + self.amarok.player.type(),\
+    #                       )
+               
+    # pause button
+    def pause(self):
+       self.amarok.player.pause()
+
+    # mute button
+    def mute(self):
+       self.amarok.player.mute()
+
+    # stop button
+    def stop(self):
+       self.amarok.player.stop()
+
+    # get the current volume value
+    def get_volume(self):
+       return self.amarok.player.getVolume()
+
+    # set up volume
+    def volume_up(self, increase=1):
+       if (self.get_volume() + increase) <= 100:
+           up = self.get_volume() + increase
+           self.amarok.player.setVolume(up)
+       else:
+           print "erro!"
+
+    # set down volume
+    def volume_down(self, decrement=1):
+        if (self.get_volume() - decrement) >= 0:
+           down = self.get_volume() - decrement
+           self.amarok.player.setVolume(down)
+       else:
+           print "erro!"
+       
+    # set seek value 
+    def seek(self, value):
+               self.amarok.player.seek(value)
diff --git a/pcremote-server/players/playlist.py b/pcremote-server/players/playlist.py
new file mode 100755 (executable)
index 0000000..31a3a61
--- /dev/null
@@ -0,0 +1,161 @@
+# -*- coding: utf-8 -*-
+
+#  ****************************************************************************
+#  Copyright (c) 2008 INdT/Fucapi.
+#  This program is free software: you can redistribute it and/or modify
+#  it under the terms of the GNU Lesser General Public License as published by
+#  the Free Software Foundation, either version 3 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 Lesser General Public License for more details.
+#
+#  You should have received a copy of the GNU Lesser General Public License
+#  along with this program.  If not, see <http://www.gnu.org/licenses/>.
+#
+#  ============================================================================
+#  Project Name : PC Remote
+#  Author       : Jonatas Isvi 
+#  Email        : jonatas.nona@gmail.com
+#  Reviewer     :
+#  Email        :
+#  Version      : 1.0
+#  Package      : players
+#  Description  : Playlist
+#  ============================================================================
+
+import plistparser
+import pydcop
+
+class Playlist():
+
+    """ Playlist
+    make the interpreter and manipulation
+    of the player playlist, creates a composite
+    with any player class. 
+    """
+
+    # some importants variables
+    # analyze if file is a playlist
+    def __init__(self, file):
+               if self.isPlaylist(file):
+           self.file = file
+           self.songs = self.load()
+           self.currentSong = 0
+           self.fix()
+       else:
+           raise("Argument is not a playlist file")
+
+    # analyzes the file
+    def isPlaylist(self, file):
+       if not file:
+           return False
+       else:
+           return True
+
+    # make a list of dicts songs
+    def load(self):
+       self.songs = plistparser._request(self.file)    
+       return self.songs
+
+    # get the length of the current playlist
+    def length(self):
+       return len(self.songs)
+
+    # update the current song in songs list and return a song dict
+    def update(self, track, title, artist, path, ext):
+               self.currentSong = track
+       if self.songs[self.currentSong]['title'] == 'Unknown Title':
+           self.songs[self.currentSong]['title'] = title
+       if self.songs[self.currentSong]['artist'] == 'Unknown Artist':
+           self.songs[self.currentSong]['artist'] = artist
+       self.songs[self.currentSong]['path'] = path
+       self.songs[self.currentSong]['extension'] = ext
+       print self.songs[self.currentSong]
+
+
+    # show the current song
+    def show_playing_now(self):
+               return ('TITLE: %s' % self.songs[self.currentSong]['title'],  \
+               'ARTIST: %s' % self.songs[self.currentSong]['artist'],\
+               'TRACK: %s' % self.songs[self.currentSong]['track']
+               )
+
+    # get the current song filename if index is None
+    def song_filename(self, index=None):
+       if index == None:
+           return self.songs[self.currentSong]['title'] +" - "+\
+                  self.songs[self.currentSong]['artist'] +     \
+                  self.songs[self.currentSong]['extension']
+
+       else:
+           return self.songs[index]['title'] +" - "+\
+                  self.songs[index]['artist'] +     \
+                  self.songs[index]['extension']
+       
+    # get thr current song filesize if index is None
+    def song_size(self, index=None):
+       if index == None:
+                   return int(self.songs[self.currentSong]['filesize'])
+       else:
+           return int(self.songs[index]['filesize'])
+
+    # show all songs of the playlist
+    def show(self):
+       for i in range(self.length()):
+           print self.songs[i]['track'], " - ", \
+                 self.songs[i]['title'], " | ", \
+                 self.songs[i]['artist'],       \
+                 "\n"
+
+    # fix some problems of musics tags
+    def fix(self):
+       for i in range(self.length()):
+           if self.songs[i]['title'] == None:
+              self.songs[i]['title'] = 'Unknown Title'
+           elif self.songs[i]['artist'] == None:
+               self.songs[i]['artist'] = 'Unknown Artist'
+               
+
+    # get the porperties of any song of ther playlist  
+    def song_properties(self, index=None, track=False, title=False,\
+                        artist=False, ext=False, filesize=False, \
+                       duration=False, path=False):
+       props = {}
+       if index == None:
+           if track:
+               props['track'] = self.songs[self.currentSong]['track']
+           if title:
+               props['title'] = self.songs[self.currentSong]['title']
+           if artist:
+               props['artist'] = self.songs[self.currentSong]['artist']
+           if ext:
+               props['ext'] = self.songs[self.currentSong]['extension']
+           if filesize:
+               props['filesize'] = self.songs[self.currentSong]['filesize']
+           if duration:
+               props['duration'] = self.songs[self.currentSong]['duration']
+           if path:
+               props['path'] = self.songs[self.currentSong]['path']
+                       
+           return props
+       else:
+           if track:
+               props['track'] = self.songs[index]['track']
+           if title:
+               props['title'] = self.songs[index]['title']
+           if artist:
+               props['artist'] = self.songs[index]['artist']
+           if ext:
+               props['ext'] = self.songs[index]['extension']
+           if filesize:
+               props['filesize'] = self.songs[index]['filesize']
+           if duration:
+               props['duration'] = self.songs[index]['duration']
+           if path:
+               props['path'] = self.songs[index]['path']
+
+            return props
+
diff --git a/pcremote-server/players/plistparser.py b/pcremote-server/players/plistparser.py
new file mode 100755 (executable)
index 0000000..faaa0ac
--- /dev/null
@@ -0,0 +1,72 @@
+# -*- coding: utf-8 -*-
+
+#  ****************************************************************************
+#  Copyright (c) 2008 INdT/Fucapi.
+#  This program is free software: you can redistribute it and/or modify
+#  it under the terms of the GNU Lesser General Public License as published by
+#  the Free Software Foundation, either version 3 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 Lesser General Public License for more details.
+#
+#  You should have received a copy of the GNU Lesser General Public License
+#  along with this program.  If not, see <http://www.gnu.org/licenses/>.
+#
+#  ============================================================================
+#  Project Name : PC Remote
+#  Author       : Jonatas Isvi
+#  Email        : jonatas.nona@gmail.com
+#  Reviewer     :
+#  Email        :
+#  Version      : 1.0
+#  Package      : utils
+#  Description  : plisparser
+#  ============================================================================
+
+from xml.etree import cElementTree as ElementTree
+
+# get the file
+def _request(url):
+    xml = url
+    return parse_playlist_file(xml)
+
+# parser the file
+def parse_playlist_file(xml):
+    tree = ElementTree.parse(xml)
+    listsongs = []
+    dictsongs = {}
+    count = duration = filesize = 0
+    title = artist = path = ''
+
+    for child in tree.getiterator():
+        if child.tag == 'Title':
+           title = child.text
+       elif child.tag == 'Artist':
+           artist = child.text
+       elif child.tag == 'Length':
+           duration = child.text
+       elif child.tag == 'Filesize':
+           filesize = child.text
+           count = count + 1
+           dictsongs = {'track' : count, 
+                        'title' : title, 
+                        'artist' : artist, 
+                        'duration' : duration, 
+                        'filesize' : filesize, 
+                        'path' : None,
+                        'extension' : None,
+                       }
+           listsongs.append(dictsongs)
+
+    return listsongs
+
+
+
+                       
+
+
+
+
diff --git a/pcremote-server/players/run-amarok.py b/pcremote-server/players/run-amarok.py
new file mode 100755 (executable)
index 0000000..2d8e9bf
--- /dev/null
@@ -0,0 +1,43 @@
+import amarok
+
+if not amarok.isRunning():
+    player = amarok.AmarokPlayer()
+else:
+    print "entrou aqui"
+    amarok.start()
+    player = amarok.AmarokPlayer()
+
+while(1):
+    data = raw_input(">>> ")
+    if data == '#exit' or data == '#quit' or data == '#close':
+        print "Application closed."
+        amarok.shutdown()
+       break
+    elif data == 'next':
+        player.next()
+    elif data == 'prev':
+        player.prev()
+    elif data == 'play':
+        player.play()
+    elif data == 'pause':
+        player.pause()
+    elif data == 'stop':
+        player.stop()
+    elif data == 'mute':
+        player.mute()
+    elif data == 'volume-up':
+        player.volume_up()
+    elif data == 'volume-down':
+        player.volume_down()
+    elif data == 'current_song':
+       print player.current_song()
+    elif data == 'random':
+        player.play_random()
+    elif data == 'play-track':
+        index = input('track: ')
+        player.play_track(index)
+    elif data == 'refresh':
+        player.refresh_playlist()
+    elif data == 'show':
+        player.song_list()
+  
diff --git a/pcremote-server/runserver.py b/pcremote-server/runserver.py
new file mode 100644 (file)
index 0000000..b91efd2
--- /dev/null
@@ -0,0 +1,108 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+
+# ****************************************************************************
+# Copyright (c) 2008 INdT/Fucapi.
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License as published by
+# the Free Software Foundation, either version 3 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 Lesser General Public License for more details.
+#
+#  You should have received a copy of the GNU Lesser General Public License
+#   along with this program.  If not, see <http://www.gnu.org/licenses/>.
+#
+# ============================================================================
+# Project Name : PC Remote
+# Author       : Nilson ; Jonatas Izvi; Andre Portela
+# Email        : fergus.mao@gmail.com ; nona@gmail.com ; 
+#                andre_portela_@hotmail.com;
+# Version      : 1.0
+# Class        : Server File - This is the main script of the server
+# ============================================================================
+
+from connection.iconnection import *
+from services.service import *
+from utils import *
+from utils.messages import *
+
+class Server():
+
+    def __init__(self, AppName):
+        self.msgbox = Message(AppName)
+       self.msgbox.show_message("Server Initialized...")
+
+    def start(self, servername):
+
+        label = Labels()
+        iconn = Iconnection('blue')
+        iconn.bluetooth_create_server('l2cap', 0x1001)
+
+        address = iconn.get_client_address()
+
+        self.msgbox.show_message("Accepted connection from " + address[0])
+
+        while (1):
+
+            data = iconn.received_message()
+
+            if data == 'Tablet:#start':
+
+                self.msgbox.show_message('Service Tablet initialized...')
+
+                service = Service()
+                service.set_service('Tablet')
+
+                while(1):
+                    data = iconn.received_message()
+                    if data == 'Tablet:#stop':
+                        service.clean_all()
+                        self.msgbox.show_message('Service Tablet stoped')
+                        break
+                    service.execute(data)
+
+            elif data == 'Slideshow:#start':
+
+                self.msgbox.show_message('Service Slideshow initialized...')
+
+                service = Service()
+                service.set_service('Slideshow')
+
+                while(1):
+                    data = iconn.received_message()
+                    if data == 'Slideshow:#stop':
+                        service.clean_all()
+                        self.msgbox.show_message('Service Slideshow stoped')
+                        break
+                    print data, "\n"
+                    service.execute(data)
+    
+            elif data == 'Player:#start':
+
+                self.msgbox.show_message('Service Player initialized...')
+
+                service = Service()
+                service.set_service('Player')
+
+                while(1):
+                    data = iconn.received_message()
+                    if data == 'Player:#stop':
+                        self.msgbox.show_message('Service Player stoped')
+                        break
+                    elif data == 'Player:#download':
+                        service.set_address_to_download(address[0])
+                    elif data == 'Player:#load_playlist':
+                        # e preciso criar um metodo de transferencia
+                        # no caso de carregar uma playlist para o cliente
+                        service.execute_transfer(data)
+                
+                       service.execute(data)
+
+            else:      
+                iconn.close()
+                self.msgbox.show_message('Desconected from ' + address[0])
+               break
diff --git a/pcremote-server/services/ObjectServers.py b/pcremote-server/services/ObjectServers.py
new file mode 100755 (executable)
index 0000000..dfbe76c
--- /dev/null
@@ -0,0 +1,294 @@
+# -*- coding: utf-8 -*-
+
+# ****************************************************************************
+# Copyright (c) 2008 INdT/Fucapi.
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License as published by
+# the Free Software Foundation, either version 3 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 Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+#
+# ============================================================================
+# Project Name : PC Remote
+# Author       : Nilson Silva, Jonatas Isvi, Andre Portela
+# Email        : fergus.mao@gmail.com, jonatas.nona@gmail.com,
+#               andre_portela_@hotmail.com
+# Reviewer     : Jônatas Isvi
+# Email        : 
+# Version      : 1.0
+# Package      : services
+# Description  : Mouse Server, Keyboard Server
+# ============================================================================
+
+import time
+from utils.labels import *
+from ServerHandlers import *
+from players import amarok
+
+class Mouse_Server:
+
+    """ Mouse Server
+    Defines all mouse behaviors.
+    Clicks and coordinates.
+    """
+
+    #Initialize the class
+    def __init__(self, service):
+        self._service_name = service
+        self.mouse  = Mouse()
+        self.labels = Labels()
+       self.timer  = time
+        self.timerclick = 0
+        
+        self.fg_dbclick = False
+        self.fg_move = True
+        self.x = 0      
+        self.y = 0
+
+    #Executes the action requested by the Service Manager
+    def execute(self, command):
+
+        self.mouse_counter_lclick()
+
+        if (command == self.labels.CLICK):
+            self.mouse_click()
+        elif (command == self.labels.DOUBLE_CLICK):
+            self.mouse_press_dbclick()
+        elif (command == self.labels.TRIPLE_CLICK):
+            self.mouse_release_dbclick()
+        elif (command == self.labels.LEFT_CLICK):
+            self.mouse_lclick()
+        elif (command == self.labels.MIDDLE_CLICK):
+            self.mouse_mclick()
+        elif (command == self.labels.RIGHT_CLICK):
+            self.mouse_rclick()
+        elif (command[0] == "#"):
+            self.mouse_fator(command)
+        else:
+            self.mouse_move(command)
+
+    #Gets the time the mouse pointer is pressed. If It is greater than (or equal to) 2s, The Mouse Left Click is activated.
+    def mouse_counter_lclick(self):
+                 
+        if ((not self.fg_move) and ((int(self.timer.time()) - self.timerclick) >= 2)):
+            self.mouse.right_click(True)
+            self.mouse.right_click(False)
+            self.timerclick = 0
+            self.fg_move = True
+
+    #Mouse Pointer - Single Click
+    def mouse_click(self):
+        self.timerclick = int(self.timer.time())
+        self.fg_move = False
+
+    #Mouse Pointer - Double Click
+    def mouse_press_dbclick(self):
+        self.mouse.left_click(True)
+        self.fg_dbclick = True
+
+    #Mouse Pointer - Released after a Double Click
+    def mouse_release_dbclick(self):
+        if self.fg_dbclick:
+            self.mouse.left_click(False)
+            self.fg_dbclick = False
+
+    #Mouse Left Click
+    def mouse_lclick(self):
+        self.mouse.left_click()
+
+    #Mouse Middle Click
+    def mouse_mclick(self):
+        self.mouse.middle_click()
+
+    #Mouse Right Click
+    def mouse_rclick(self):
+        self.mouse.right_click()
+
+    #Sets the factor of the Mouse Pointer Move
+    def mouse_fator(self, command):
+        num = ""
+        for i in range(1, len(command)):
+            num = num + command(i)
+
+        self.mouse.set_fator(int(num))
+
+    #Moves the Mouse Pointer
+    def mouse_move(self, command):
+        coord = command.split(",")
+
+        i = int(coord[0]) - self.x
+        if ((abs(i) == 1) or (abs(i) >= 20)):
+            i = 0
+
+        j = int(coord[1]) - self.y
+        if ((abs(j) == 1) or (abs(j) >= 20)):
+            j = 0
+
+        if not ((i == 0) and (j == 0)):            
+            if ((i >= 4) or (j >= 4)):
+                self.fg_move = True
+            if self._service_name == "Tablet":
+                self.mouse.position(i, j)
+            else:
+                self.mouse.position(-j, i)
+
+        self.x = int(coord[0])
+        self.y = int(coord[1])
+
+    def clean_up(self):
+       self.mouse.clean_up()
+
+class KeyBoard_Server:
+
+    """ Keyboard Server
+    Defines all keyboard behaviors.
+    Map keys and events.
+    """    
+
+    def __init__(self, service):
+       self.keyboard = Keyboard()
+       self.shift_flag = False
+       self.control_flag = False
+       self.alt_flag = False
+        self._service_name = service
+
+    # execute key command
+    def execute(self, command):
+       
+       print "\n", command
+
+       if(command == 'F8'):
+           self.keyboard.reproduce_key_press('Control_L')
+           self.keyboard.reproduce_key_press('z')
+           self.keyboard.reproduce_key_release('z')
+           self.keyboard.reproduce_key_release('Control_L')
+        elif(self._service_name == 'Slideshow' and command == 'F6'):
+            self.keyboard.reproduce_key_press('F5')
+            self.keyboard.reproduce_key_release('F5')
+       elif(command == 'Control_R'):
+           self.control_flag = True
+           self.keyboard.reproduce_key_press('Control_R')
+           #self.keys.append(command)
+       elif(command == 'Shift_L'):
+           self.shift_flag = True
+           self.keyboard.reproduce_key_press('Shift_L')
+           #self.keys.append(command)
+       elif(command == 'Alt_L'):
+           self.alt_flag = True
+           self.keyboard.reproduce_key_press('Alt_L')
+       elif(command == 'F7'):
+           self.keyboard.reproduce_key_press('Control_L')
+           self.keyboard.reproduce_key_press('y')
+           self.keyboard.reproduce_key_release('y')
+           self.keyboard.reproduce_key_release('Control_L')
+       elif(command == 'Alt+F1'):
+           self.keyboard.reproduce_key_press('Alt_L')
+           self.keyboard.reproduce_key_press('F1')
+           self.keyboard.reproduce_key_release('F1')
+           self.keyboard.reproduce_key_release('Alt_L')
+        elif(command == 'Alt+F2'):
+           self.keyboard.reproduce_key_press('Alt_L')
+           self.keyboard.reproduce_key_press('F2')
+           self.keyboard.reproduce_key_release('F2')
+           self.keyboard.reproduce_key_release('Alt_L')
+       elif(command == 'Alt+F4'):
+           self.keyboard.reproduce_key_press('Alt_L')
+           self.keyboard.reproduce_key_press('F4')
+           self.keyboard.reproduce_key_release('F4')
+           self.keyboard.reproduce_key_release('Alt_L')
+       elif(command == 'Alt+F9'):
+           self.keyboard.reproduce_key_press('Alt_L')
+           self.keyboard.reproduce_key_press('F9')
+           self.keyboard.reproduce_key_release('F9')
+           self.keyboard.reproduce_key_release('Alt_L')
+       elif(command == 'Alt+F0'):
+           self.keyboard.reproduce_key_press('Alt_L')
+           self.keyboard.reproduce_key_press('F10')
+           self.keyboard.reproduce_key_release('F10')
+           self.keyboard.reproduce_key_release('Alt_L')
+       elif(command == 'Alt+Space'):
+           self.keyboard.reproduce_key_press('Alt_L')
+           self.keyboard.reproduce_key_press('space')
+           self.keyboard.reproduce_key_release('space')
+           self.keyboard.reproduce_key_release('Alt_L')
+       elif(command == 'Tab'):
+           self.keyboard.reproduce_key_press('Tab')
+           self.keyboard.reproduce_key_release('Tab')
+       else:
+           self.keyboard.reproduce_key_press(command)
+           self.keyboard.reproduce_key_release(command)
+                       
+           if self.shift_flag:
+               self.keyboard.reproduce_key_release('Shift_L')
+               #self.keys.remove('Shift_L')
+               self.shift_flag = False
+           elif self.control_flag:
+               self.keyboard.reproduce_key_release('Control_R')
+               #self.keys.remove('Control_R')
+               self.control_flag = False
+           elif self.alt_flag:
+               self.keyboard.reproduce_key_release('Alt_L')
+               self.alt_flag = False
+       
+    # clean all keys pressed                   
+    def clean_up(self):
+       self.keyboard.clean_up()
+
+class Player_Server():
+
+    def __init__(self):
+        if not amarok.isRunning():
+            self.player = amarok.AmarokPlayer()
+        else:
+            amarok.start()
+            self.player = amarok.AmarokPlayer()
+        self.labels = Labels()
+
+    def execute(self, command):
+        if len(command) > 2:
+            if command[1] == self.labels.PLAY:
+                if command[2] and command[3]:
+                    self.player.play(track=int(command[2]), rmd=bool(command[3]))      
+                elif command[2]:
+                    arg = int(command[2])
+                    if isinstance(arg, int):
+                        self.player.play(track=arg)
+                    else:
+                        arg = bool(command[2])
+                        self.player.play(rmd=arg)
+                else:
+                    pass
+        else:
+            if command[1] == self.labels.STOP:
+                self.player.stop()
+            elif command[1] == self.labels.PLAY:
+                self.player.play()
+            elif command[1] == self.labels.PAUSE:
+                self.player.pause()
+            elif command[1] == self.labels.NEXT:
+                self.player.next()
+            elif command[1] == self.labels.PREVIOUS:
+                self.player.prev()
+            elif command[1] == self.labels.VOL_UP:
+                self.player.volume_up()
+            elif command[1] == self.labels.VOL_DOWN:
+                self.player.volume_down()
+            elif command[1] == self.labels.SEEK:
+                self.player.seek(int(command[2]))
+            elif command[1] == self.labels.DOWNLOAD:
+                path = self.player.file_properties()
+                addr = command[2]
+                amarok.send_file(addr, path)
+                pass
+            elif command[1] == self.labels.LOAD_PLAYLIST:
+                # falta o metodo de trasnferencia
+                pass
+            else:
+                pass
diff --git a/pcremote-server/services/ServerHandlers.py b/pcremote-server/services/ServerHandlers.py
new file mode 100755 (executable)
index 0000000..4b16012
--- /dev/null
@@ -0,0 +1,201 @@
+# -*- coding: utf-8 -*-
+
+# ****************************************************************************
+# Copyright (c) 2008 INdT/Fucapi.
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License as published by
+# the Free Software Foundation, either version 3 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 Lesser General Public License for more details.
+#
+#  You should have received a copy of the GNU Lesser General Public License
+#   along with this program.  If not, see <http://www.gnu.org/licenses/>.
+#
+# ============================================================================
+# Project Name : PC Remote
+# Author       : Nilson Silva
+# Email        : fergus.mao@gmail.com
+# Reviewer     : Jônatas Isvi
+# Email        : jonatas.nona@gmail.com
+# Version      : 1.0
+# Package      : service
+# Description  : Singleton, Mouse and Keyboard
+# ============================================================================
+
+import Xlib
+from Xlib import display, X, XK
+
+class Singleton_Xlib():
+
+    """ Singleton
+    defines a singleton. 
+    """
+    def __init__(self):
+       self.display = display.Display()
+       self.screen = self.display.screen()
+
+xlib_srv = Singleton_Xlib()
+
+class Mouse(object):
+
+    """ Mouse
+    pass mouse information to Xorg
+    """
+
+    #Initialize the class
+    def __init__(self):
+        self.disp = xlib_srv.display
+        self.screen = xlib_srv.screen
+        self.fator = 10
+        self.lbutton = False
+        self.mbutton = False
+        self.rbutton = False
+       self.buttons = []
+
+    #Set the mouse pointer position
+    def position(self,x=None,y=None):            
+        
+        if (x == None):
+            x = self.fator
+            
+        if (y == None):
+            y = self.fator
+
+        #Get the current mouse pointer position
+        current_x = self.screen.root.query_pointer()._data["root_x"]
+        current_y = self.screen.root.query_pointer()._data["root_y"]
+        
+        def absolute(ax = None, ay = None):
+            if (ax == None):
+                ax = x
+            if (ay == None):
+                ay = y
+
+            self.screen.root.warp_pointer(ax, ay)
+            self.disp.sync()
+
+        def relative():
+            rX = current_x + x
+            rY = current_y + y
+            absolute(rX,rY)
+
+        relative()
+
+    #Returns the current X position
+    def get_x(self):
+        return self.screen.root.query_pointer()._data["root_x"]
+
+    #Returns the current Y position
+    def get_y(self):
+        return self.screen.root.query_pointer()._data["root_y"]
+
+    #Defines the factor(px) of the mouse pointer move
+    def set_fator(self,fator):
+        self.fator = fator
+
+    #Returns the factor
+    def get_fator(self):
+        return self.fator
+        
+    #Mouse Left Click 
+    def left_click(self, fg_lbutton = None):
+
+        if (fg_lbutton != None):
+            self.lbutton = not fg_lbutton
+
+        if not self.lbutton:
+            self.disp.xtest_fake_input(X.ButtonPress, 1, 0)
+           self.buttons.append('left_button')
+            self.lbutton = True
+        else:
+            self.disp.xtest_fake_input(X.ButtonRelease, 1, 5)
+           self.buttons.remove('left_button')
+            self.lbutton = False
+
+        self.disp.flush()
+        
+    #Mouse Middle Click 
+    def middle_click(self):
+        if not self.mbutton:    
+            self.disp.xtest_fake_input(X.ButtonPress, 2, 0)
+           self.buttons.append('middle_button')
+            self.mbutton = True
+        else:
+            self.disp.xtest_fake_input(X.ButtonRelease, 2, 5)
+           self.buttons.remove('middle_button')
+            self.mbutton = False
+
+        self.disp.flush()
+
+    #Mouse Right Click 
+    def right_click(self, fg_rbutton = None):
+
+        if (fg_rbutton != None):
+            self.rbutton = not fg_rbutton
+
+        if not self.rbutton:
+            self.disp.xtest_fake_input(X.ButtonPress, 3, 0)
+           self.buttons.append('right_button')
+            self.rbutton = True
+        else:
+            self.disp.xtest_fake_input(X.ButtonRelease, 3, 5)
+           self.buttons.remove('right_button')
+            self.rbutton = False
+
+        self.disp.flush()
+
+    def clean_up(self):
+        if self.buttons:
+            while self.buttons:
+               button = self.buttons.pop()
+              if button == 'left_button':
+                  self.disp.xtest_fake_input(X.ButtonRelease, 1, 5)
+                  self.disp.xtest_fake_input(X.ButtonPress, 3, 5)
+                  self.disp.xtest_fake_input(X.ButtonRelease, 3, 5)
+              elif button == 'middle_button':
+                  self.disp.xtest_fake_input(X.ButtonRelease, 2, 5)
+              elif button == 'right_button':
+                  self.disp.xtest_fake_input(X.ButtonRelease, 3, 5)
+
+       print self.buttons
+
+class Keyboard():
+
+    """ Keyboard
+    pass keyboard information to Xorg 
+    """
+
+    def __init__(self):
+       self.display = xlib_srv.display
+       self.screen = xlib_srv.screen
+        self.keys = []
+
+    # encode key 
+    def __key_to_code(self,key):
+       new_key = getattr(XK, "XK_" + key)
+       code = self.display.keysym_to_keycode(new_key)
+       return code
+
+    # reproduce key pressed
+    def reproduce_key_press(self, key):
+       Xlib.ext.xtest.fake_input(self.display, Xlib.X.KeyPress, self.__key_to_code(key))
+       self.display.sync()
+        self.keys.append(key)
+
+    # reproduce key release
+    def reproduce_key_release(self, key):
+       Xlib.ext.xtest.fake_input(self.display, Xlib.X.KeyRelease, self.__key_to_code(key))
+       self.display.sync()
+        self.keys.remove(key)
+
+    # clean all pressed keys
+    def clean_up(self):
+        if self.keys:
+            while self.keys:
+                key = self.keys.pop()
+                self.reproduce_key_release(key)
+           
diff --git a/pcremote-server/services/__init__.py b/pcremote-server/services/__init__.py
new file mode 100755 (executable)
index 0000000..e69de29
diff --git a/pcremote-server/services/service.py b/pcremote-server/services/service.py
new file mode 100755 (executable)
index 0000000..778745b
--- /dev/null
@@ -0,0 +1,90 @@
+# -*- coding: utf-8 -*-
+
+# ****************************************************************************
+# Copyright (c) 2008 INdT/Fucapi.
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License as published by
+# the Free Software Foundation, either version 3 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 Lesser General Public License for more details.
+#
+#  You should have received a copy of the GNU Lesser General Public License
+#   along with this program.  If not, see <http://www.gnu.org/licenses/>.
+#
+# ============================================================================
+# Project Name : PC Remote
+# Author       : Nilson Silva, Jonatas Isvi
+# Email        : fergus.mao@gmail.com, jonatas.nona@gmail.com
+# Reviewer     : Jônatas Isvi
+# Email        :
+# Version      : 1.0
+# Package      : Main Application
+# Description  : Service Application
+# ============================================================================
+
+from ObjectServers import *
+
+class Service:
+    
+    """ Service
+    supports all services applications
+    """    
+
+    def __init__(self):
+        self.mouse_srv = None
+        self.keyboard_srv = None
+        self.player = None
+        self.service = ""
+        self.addr = None
+
+    #Set the Service requested by the Service Manager
+    def set_service(self, command):
+
+        self.service = command
+
+        if self.service == 'Tablet':
+            self.mouse_srv    = Mouse_Server(self.service)
+            self.keyboard_srv = KeyBoard_Server(self.service)
+        elif self.service == 'Slideshow':
+            self.mouse_srv     = Mouse_Server(self.service)
+           self.keyboard_srv = KeyBoard_Server(self.service)   
+        elif self.service == 'Player':
+            self.player_srv = Player_Server()
+        elif self.service == 'Torrent':
+            print "torrent service."
+
+    #Returns the Service which is being executed
+    def get_service(self):
+        return self.service
+
+    #Executes the action requested by the Service Manager
+    def execute(self, command):
+        
+        cmd = command.split(":")
+
+        if cmd[0] == "Mouse":
+            self.mouse_srv.execute(cmd[1])
+        elif cmd[0] == "Keyboard":
+            self.keyboard_srv.execute(cmd[1])
+        elif cmd[0] == "Player":
+            if self.addr:
+                cmd += self.addr
+                self.player_srv.execute(cmd)
+            else:
+                self.player_srv.execute(cmd)
+
+    def set_address_to_download(self, addr):
+        self.addr = addr
+   
+    # clean all button and keys pressed
+    def clean_all(self):
+       self.mouse_srv.clean_up()
+       self.keyboard_srv.clean_up()
+
+#teste unitario
+if __name__ == '__main__':
+    import utils.plistparser
diff --git a/pcremote-server/utils/__init__.py b/pcremote-server/utils/__init__.py
new file mode 100755 (executable)
index 0000000..e69de29
diff --git a/pcremote-server/utils/labels.py b/pcremote-server/utils/labels.py
new file mode 100755 (executable)
index 0000000..044609c
--- /dev/null
@@ -0,0 +1,75 @@
+# -*- coding: utf-8 -*-
+
+#  ****************************************************************************
+#  Copyright (c) 2008 INdT/Fucapi.
+#  This program is free software: you can redistribute it and/or modify
+#  it under the terms of the GNU Lesser General Public License as published by
+#  the Free Software Foundation, either version 3 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 Lesser General Public License for more details.
+
+#  You should have received a copy of the GNU Lesser General Public License
+#  along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+#  ============================================================================
+#  Project Name : PC Remote
+#  Author       : Jônatas Isvi
+#  Email        : jonatas.nona@gmail.com
+#  Version      : 1.0
+#  Description  : Labels
+#  ============================================================================
+
+class Labels():
+
+       def __init__(self):
+               pass
+
+        # SERVICES SUPPORTED
+        TABLET    = "Tablet"
+        SLIDESHOW = "Slideshow"
+        PLAYER    = "Player"
+        TORRENT          = "Torrent"
+
+       # GENERIC LABELS FOR MULTIMEDIA APPLICATIONS
+
+       PLAY          = "#play"
+       STOP          = "#stop"
+       PAUSE         = "#pause"
+       NEXT          = "#next"
+       PREVIOUS      = "#previous"
+       VOL_UP        = "#vol_up"
+       VOL_DOWN      = "#vol_down"
+       TLINE_LEFT    = "#tline_left"
+       TLINE_RIGHT   = "#tline_right"
+       RECORD        = "#record"
+        SEEK          = "#seek"
+        LOAD_PLAYLIST = "#load_playlist"
+        PLAYLIST      = "#playlist"
+       #------------------------------------------>
+
+       # GENERIC LABELS FOR APPLICATIONS
+
+       START        = "#start"
+       CLOSE        = "#close"
+       FULL_SRC     = "#fullscreen"
+       UPLOAD       = "#upload"
+       DOWNLOAD     = "#download"
+       SAVE         = "#save"
+       DELETE       = "#delete"
+       #-------------------------------->
+
+       # GENERAL MOUSE LABELS
+
+       CLICK         = "#click"
+       DOUBLE_CLICK  = "#double_click"
+       TRIPLE_CLICK  = "#triple_click"
+       LEFT_CLICK    = "#left_click"
+       RIGHT_CLICK   = "#right_click"
+       MIDDLE_CLICK  = "#middle_click"
+       #-------------------------------->
+
+
diff --git a/pcremote-server/utils/messages.py b/pcremote-server/utils/messages.py
new file mode 100755 (executable)
index 0000000..b35cd58
--- /dev/null
@@ -0,0 +1,37 @@
+import pynotify
+import Image
+import StringIO
+import gtk
+
+class Message():
+    def __init__(self, AppName):
+        pynotify.init(AppName)
+        self.AppName = AppName
+        self.msgbox = pynotify.Notification(self.AppName, self.AppName, "PCR_on.bmp")
+        self.msgbox.set_urgency(pynotify.URGENCY_CRITICAL)
+        self.msgbox.set_timeout(5000)
+
+    def show_message(self, message):
+        self.msgbox = pynotify.Notification(self.AppName, message)
+        self.msgbox.show()
+
+    def set_image(self, img):
+#        image = Image.open(img)
+#        image = gtk.gdk.pixbuf_new_from_file(img)
+#        self.msgbox.set_icon_from_pixbuf(self.image2pixbuf(image))
+       pass
+
+    def image2pixbuf(self, img):
+       file1 = StringIO.StringIO()
+
+       img.save(file1, "ppm")
+       contents = file1.getvalue()
+       file1.close()
+
+       loader = gtk.gdk.PixbufLoader("pnm")
+       loader.write(contents, len(contents))
+
+       pixbuf = loader.get_pixbuf()
+       loader.close()
+       
+       return pixbuf
diff --git a/pcremote-server/utils/plistparser.py b/pcremote-server/utils/plistparser.py
new file mode 100755 (executable)
index 0000000..faaa0ac
--- /dev/null
@@ -0,0 +1,72 @@
+# -*- coding: utf-8 -*-
+
+#  ****************************************************************************
+#  Copyright (c) 2008 INdT/Fucapi.
+#  This program is free software: you can redistribute it and/or modify
+#  it under the terms of the GNU Lesser General Public License as published by
+#  the Free Software Foundation, either version 3 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 Lesser General Public License for more details.
+#
+#  You should have received a copy of the GNU Lesser General Public License
+#  along with this program.  If not, see <http://www.gnu.org/licenses/>.
+#
+#  ============================================================================
+#  Project Name : PC Remote
+#  Author       : Jonatas Isvi
+#  Email        : jonatas.nona@gmail.com
+#  Reviewer     :
+#  Email        :
+#  Version      : 1.0
+#  Package      : utils
+#  Description  : plisparser
+#  ============================================================================
+
+from xml.etree import cElementTree as ElementTree
+
+# get the file
+def _request(url):
+    xml = url
+    return parse_playlist_file(xml)
+
+# parser the file
+def parse_playlist_file(xml):
+    tree = ElementTree.parse(xml)
+    listsongs = []
+    dictsongs = {}
+    count = duration = filesize = 0
+    title = artist = path = ''
+
+    for child in tree.getiterator():
+        if child.tag == 'Title':
+           title = child.text
+       elif child.tag == 'Artist':
+           artist = child.text
+       elif child.tag == 'Length':
+           duration = child.text
+       elif child.tag == 'Filesize':
+           filesize = child.text
+           count = count + 1
+           dictsongs = {'track' : count, 
+                        'title' : title, 
+                        'artist' : artist, 
+                        'duration' : duration, 
+                        'filesize' : filesize, 
+                        'path' : None,
+                        'extension' : None,
+                       }
+           listsongs.append(dictsongs)
+
+    return listsongs
+
+
+
+                       
+
+
+
+