From: Jônatas Isvi Date: Thu, 4 Jun 2009 06:44:51 +0000 (-0400) Subject: commit do server X-Git-Url: http://vcs.maemo.org/git/?p=remotepc;a=commitdiff_plain;h=ecd25c96cdb83f2db85490589c761a3253f40681 commit do server --- diff --git a/pcremote-server/connection/__init__.py b/pcremote-server/connection/__init__.py new file mode 100755 index 0000000..e69de29 diff --git a/pcremote-server/connection/bluetoothconnectionmanager.py b/pcremote-server/connection/bluetoothconnectionmanager.py new file mode 100755 index 0000000..581b0f8 --- /dev/null +++ b/pcremote-server/connection/bluetoothconnectionmanager.py @@ -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 . +# +# ============================================================================ +# 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 index 0000000..30a2894 --- /dev/null +++ b/pcremote-server/connection/genericconnectionmanager.py @@ -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 . +# +# ============================================================================ +# 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 index 0000000..310d175 --- /dev/null +++ b/pcremote-server/connection/iconnection.py @@ -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 . +# +# ============================================================================ +# 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 index 0000000..e92ec3d --- /dev/null +++ b/pcremote-server/connection/wirelessconnectionmanager.py @@ -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 . +# +# ============================================================================ +# 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 index 0000000..e69de29 diff --git a/pcremote-server/exceptions/exception.py b/pcremote-server/exceptions/exception.py new file mode 100755 index 0000000..697535b --- /dev/null +++ b/pcremote-server/exceptions/exception.py @@ -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 . +# +# ============================================================================ +# 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 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 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 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 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 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 index 0000000..195af3e --- /dev/null +++ b/pcremote-server/pcremote-server.py @@ -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 index 0000000..e69de29 diff --git a/pcremote-server/players/amarok.py b/pcremote-server/players/amarok.py new file mode 100755 index 0000000..2d54fb0 --- /dev/null +++ b/pcremote-server/players/amarok.py @@ -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 . +# +# ============================================================================ +# 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 index 0000000..31a3a61 --- /dev/null +++ b/pcremote-server/players/playlist.py @@ -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 . +# +# ============================================================================ +# 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 index 0000000..faaa0ac --- /dev/null +++ b/pcremote-server/players/plistparser.py @@ -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 . +# +# ============================================================================ +# 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 index 0000000..2d8e9bf --- /dev/null +++ b/pcremote-server/players/run-amarok.py @@ -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 index 0000000..b91efd2 --- /dev/null +++ b/pcremote-server/runserver.py @@ -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 . +# +# ============================================================================ +# 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 index 0000000..dfbe76c --- /dev/null +++ b/pcremote-server/services/ObjectServers.py @@ -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 . +# +# ============================================================================ +# 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 index 0000000..4b16012 --- /dev/null +++ b/pcremote-server/services/ServerHandlers.py @@ -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 . +# +# ============================================================================ +# 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 index 0000000..e69de29 diff --git a/pcremote-server/services/service.py b/pcremote-server/services/service.py new file mode 100755 index 0000000..778745b --- /dev/null +++ b/pcremote-server/services/service.py @@ -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 . +# +# ============================================================================ +# 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 index 0000000..e69de29 diff --git a/pcremote-server/utils/labels.py b/pcremote-server/utils/labels.py new file mode 100755 index 0000000..044609c --- /dev/null +++ b/pcremote-server/utils/labels.py @@ -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 . + +# ============================================================================ +# 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 index 0000000..b35cd58 --- /dev/null +++ b/pcremote-server/utils/messages.py @@ -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 index 0000000..faaa0ac --- /dev/null +++ b/pcremote-server/utils/plistparser.py @@ -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 . +# +# ============================================================================ +# 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 + + + + + + + +