From 34e7586a7a555117504d20381feb8e8c0e6cd6d8 Mon Sep 17 00:00:00 2001 From: Olivier Le Thanh Duong Date: Thu, 8 Jan 2009 19:41:17 +0100 Subject: [PATCH] Initial commit --- connection_watcher.py | 110 +++++++++++++++++++++++++++++++++++++ dtube-test.py | 147 ++++++++++++++++++++++++++++++++++++++++++++++++++ setup.py | 87 ++++++++++++++++++++++++++++++ 3 files changed, 344 insertions(+) create mode 100644 connection_watcher.py create mode 100755 dtube-test.py create mode 100755 setup.py diff --git a/connection_watcher.py b/connection_watcher.py new file mode 100644 index 0000000..4a4c6e0 --- /dev/null +++ b/connection_watcher.py @@ -0,0 +1,110 @@ +# This should eventually land in telepathy-python, so has the same license: +# Copyright (C) 2008 Collabora Ltd. +# +# 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 2.1 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, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +# FIXME: this sould go upstream, in telepathy-python + +import logging + +import dbus +import dbus.mainloop.glib +import gobject + +from telepathy.client import Connection +from telepathy.interfaces import CONN_INTERFACE +from telepathy.constants import CONNECTION_STATUS_CONNECTED, \ + CONNECTION_STATUS_DISCONNECTED + +class ConnectionWatcher(gobject.GObject): + __gsignals__ = { + 'connection-added': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE, + ([gobject.TYPE_PYOBJECT])), + 'connection-removed': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE, + ([gobject.TYPE_PYOBJECT])) + } + + def __init__(self, bus=None): + gobject.GObject.__init__(self) + + if bus is None: + self.bus = dbus.Bus() + else: + self.bus = bus + + # D-Bus path -> Connection + self._connections = {} + + self.bus.add_signal_receiver(self._status_changed_cb, + dbus_interface=CONN_INTERFACE, signal_name='StatusChanged', + path_keyword='path') + + for conn in Connection.get_connections(bus): + conn.call_when_ready(self._conn_ready_cb) + + def _status_changed_cb(self, *args, **kwargs): + path = kwargs['path'] + if not path.startswith('/org/freedesktop/Telepathy/Connection/'): + return + + status, reason_ = args + service_name = path.replace('/', '.')[1:] + + if status == CONNECTION_STATUS_CONNECTED: + self._add_connection(service_name, path) + elif status == CONNECTION_STATUS_DISCONNECTED: + self._remove_connection(service_name, path) + + def _conn_ready_cb(self, conn): + if conn.object_path in self._connections: + return + + self._connections[conn.object_path] = conn + self.emit('connection-added', conn) + + def _add_connection(self, service_name, path): + if path in self._connections: + return + + try: + Connection(service_name, path, ready_handler=self._conn_ready_cb) + except dbus.exceptions.DBusException: + logging.debug('%s is propably already gone.', service_name) + + def _remove_connection(self, service_name, path): + conn = self._connections.pop(path, None) + if conn is None: + return + + self.emit('connection-removed', conn) + + def get_connections(self): + return self._connections.values() + +if __name__ == '__main__': + dbus.mainloop.glib.DBusGMainLoop(set_as_default=True) + + def connection_added_cb(conn_watcher, conn): + print "new connection", conn.service_name + + def connection_removed_cb(conn_watcher, conn): + print "removed connection", conn.service_name + + watcher = ConnectionWatcher() + watcher.connect('connection-added', connection_added_cb) + watcher.connect('connection-removed', connection_removed_cb) + + loop = gobject.MainLoop() + loop.run() diff --git a/dtube-test.py b/dtube-test.py new file mode 100755 index 0000000..3825cfa --- /dev/null +++ b/dtube-test.py @@ -0,0 +1,147 @@ +#!/usr/bin/python +# -*- coding:Utf-8 -*- + + # Dtube test + # Copyright (C) 2009 Olivier Le Thanh Duong + + # This program is free software: you can redistribute it and/or modify + # it under the terms of the GNU General Public License as published by + # the Free Software Foundation, either version 2 of the License, or + # (at your option) any later version. + + # This program is distributed in the hope that it will be useful, + # but WITHOUT ANY WARRANTY; without even the implied warranty of + # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + # GNU General Public License for more details. + + # You should have received a copy of the GNU General Public License + # along with this program. If not, see . + + +import sys +import gobject + +import dbus +from dbus.service import method, signal, Object + +from connection_watcher import ConnectionWatcher + +from telepathy.interfaces import CHANNEL_TYPE_CONTACT_LIST, CONNECTION_INTERFACE_REQUESTS,\ + CONNECTION_INTERFACE_SIMPLE_PRESENCE, CHANNEL_INTERFACE_GROUP, CHANNEL_TYPE_TUBES +from telepathy.constants import HANDLE_TYPE_LIST, HANDLE_TYPE_CONTACT, CONNECTION_PRESENCE_TYPE_AVAILABLE,\ + CONNECTION_PRESENCE_TYPE_AWAY, CONNECTION_PRESENCE_TYPE_EXTENDED_AWAY, CONNECTION_PRESENCE_TYPE_BUSY,\ + TUBE_STATE_OPEN +from telepathy.client.channel import Channel +from telepathy.client.conn import Connection + +TUBE_SERVICE = "org.pygame.Pyhalebarde" + + +def tp_search_contact_from_id(contact, conn): + """Return the handle that match the id in given connexion""" + + if CONNECTION_INTERFACE_REQUESTS not in conn: + print "CONNECTION_INTERFACE_REQUESTS not implemented in %s" % (conn.service_name) + return None + + # get contacts list + yours, path, props = conn[CONNECTION_INTERFACE_REQUESTS].EnsureChannel({ + 'org.freedesktop.Telepathy.Channel.ChannelType': CHANNEL_TYPE_CONTACT_LIST, + 'org.freedesktop.Telepathy.Channel.TargetHandleType': HANDLE_TYPE_LIST, + 'org.freedesktop.Telepathy.Channel.TargetID': 'subscribe'}) + + chan = Channel(conn.service_name, path) + contacts = chan[CHANNEL_INTERFACE_GROUP].GetMembers() + + ids = conn.InspectHandles(HANDLE_TYPE_CONTACT, contacts) + + for handle, id in zip(contacts, ids): + if id == contact: + return handle + +def tp_contact_is_online(handle, conn): + presences = conn[CONNECTION_INTERFACE_SIMPLE_PRESENCE].GetPresences([handle]) + + type, status, msg = presences[handle] + return type in [CONNECTION_PRESENCE_TYPE_AVAILABLE, CONNECTION_PRESENCE_TYPE_AWAY, + CONNECTION_PRESENCE_TYPE_EXTENDED_AWAY, CONNECTION_PRESENCE_TYPE_BUSY] + +def offer_tube(conn, handle): + # FIXME: check if contact supports our tube + # offering tube + # FIXME: use new tube API + yours, path, props = conn[CONNECTION_INTERFACE_REQUESTS].EnsureChannel({ + 'org.freedesktop.Telepathy.Channel.ChannelType': CHANNEL_TYPE_TUBES, + 'org.freedesktop.Telepathy.Channel.TargetHandleType': HANDLE_TYPE_CONTACT, + 'org.freedesktop.Telepathy.Channel.TargetHandle': handle}) + + def tube_state_changed_cb(id, state): + print "tube state changed", state + if state == TUBE_STATE_OPEN: + print "tube open!" + + address = chan[CHANNEL_TYPE_TUBES].GetDBusTubeAddress(id) + tube_conn = dbus.connection.Connection(address) + #p = RemotePlayer(tube_conn, "/Player", UI.game, "White") + + def tube_closed_cb(id): + print "tube closed" + + chan = Channel(conn.service_name, path) + chan[CHANNEL_TYPE_TUBES].connect_to_signal('TubeStateChanged', tube_state_changed_cb) + chan[CHANNEL_TYPE_TUBES].connect_to_signal('TubeClosed', tube_closed_cb) + chan[CHANNEL_TYPE_TUBES].OfferDBusTube(TUBE_SERVICE, {}) + +def offer_tube_to_contact_cb(watcher, conn, contact): + #TODO : Remove itself when contact is found. + handle = tp_search_contact_from_id(contact, conn) + if handle: + print "Contact %s found in %s" % (contact, conn.service_name) + if tp_contact_is_online(handle, conn): + print "contact online" + offer_tube(conn, handle) + + else: + print "Contact %s not found in %s" % (contact, conn.service_name) + +if __name__ == "__main__": + + if sys.argv[1] == '--handler': + contact = None + + # create D-Bus handler service + class Handler(Object): + @dbus.service.method("org.gnome.Empathy.TubeHandler", + in_signature='soouuu', out_signature='') + def HandleTube(self, bus_name, connection, channel, handle_type, handle, tube_id): + print "handling tube!" + # TODO: ask to the user if he wants to accept or decline the + # tube + + conn = Connection(bus_name, connection) + chan = Channel(bus_name, channel) + + print "accept tube" + address = chan[CHANNEL_TYPE_TUBES].AcceptDBusTube(tube_id) + tube_conn = dbus.connection.Connection(address) + p = RemotePlayer(tube_conn, "/Player", UI.game, "Black") + + bus = dbus.SessionBus() + #dbus.service.BusName("org.gnome.Empathy.DTubeHandler.%s" % TUBE_SERVICE, bus) + name = dbus.service.BusName("org.gnome.Empathy.DTubeHandler.org_2epygame_2ePyhalebarde", bus) + print "create handle service" + #handler = Handler(bus, "/org/gnome/Empathy/DTubeHandler/%s" % TUBE_SERVICE) + handler = Handler(bus, "/org/gnome/Empathy/DTubeHandler/org_2epygame_2ePyhalebarde") + + else: + contact = sys.argv[1] + + if contact is not None: + watcher = ConnectionWatcher() + watcher.connect('connection-added', offer_tube_to_contact_cb, contact) + + loop = gobject.MainLoop() + gobject.timeout_add(10, UI.runIteration) + loop.run() + +# vim:set shiftwidth=4 tabstop=4 expandtab textwidth=79: diff --git a/setup.py b/setup.py new file mode 100755 index 0000000..ce10c70 --- /dev/null +++ b/setup.py @@ -0,0 +1,87 @@ +#!/usr/bin/env python +# Installation script for pyhalebarde + + # PyHalebarde, a turn per turn strategy game + # Copyright (C) 2008 Laurent P & Olivier Le Thanh Duong + + # This program is free software: you can redistribute it and/or modify + # it under the terms of the GNU General Public License as published by + # the Free Software Foundation, either version 2 of the License, or + # (at your option) any later version. + + # This program is distributed in the hope that it will be useful, + # but WITHOUT ANY WARRANTY; without even the implied warranty of + # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + # GNU General Public License for more details. + + # You should have received a copy of the GNU General Public License + # along with this program. If not, see . + +from distutils.core import setup + +from distutils.command.build_py import build_py as _build_py +from distutils.command.install_data import install_data as _install_data + +import distutils.file_util + +import glob +import os + + +# create .mo files from .po locales if needed + +class build_py(_build_py): + def run(self): + for item in os.listdir("po"): + if item.endswith(".po"): + lang = item[:-3] + dest = "%s.mo" % (lang) + print "compiling '%s' translation '%s'" % (lang, dest) + os.system("msgfmt po/%s -o po/%s" % (item, dest)) + _build_py.run(self) + +class install_data(_install_data): +# Add the translation (mo files) in the right directory + def run(self): + _install_data.run(self) + for item in os.listdir("po"): + if item.endswith(".mo"): + lang = item[:-3] + source = "po/%s" % (item) + dest = "%s/share/locale/%s/LC_MESSAGES/pyhalebarde.mo" % (self.install_dir,lang) + print "Installing translation '%s' to '%s'" % (source, dest) + distutils.file_util.copy_file(source, dest) + + + + + +INCLUDED_THEME = ['wesnoth', 'retro'] +DATA_FILES = [] +for theme in INCLUDED_THEME: + theme_dir = "share/games/pyhalebarde/themes/%s" % (theme) + theme_files = glob.glob('themes/%s/*' % (theme)) + DATA_FILES.append((theme_dir, theme_files)) + +DATA_FILES.append(("share/games/pyhalebarde", ["pyhalebarde.png"])) +DATA_FILES.append(("share/pixmaps", ["pyhalebarde.png"])) +DATA_FILES.append(("share/applications", ["pyhalebarde.desktop"])) + +#install the script as a data file so it can be placed in /usr/game +DATA_FILES.append(("games", ["pyhalebarde"])) + +# install the mo file in the right directory +# TODO + +setup(name='pyHalebarde', + version='0.1.1', + description='pyHalebarde game', + author='Olivier Le Thanh Duong', + author_email='olethanh@gmail.com', + url='https://launchpad.net/pyhalebarde', + cmdclass={'build_py': build_py, 'install_data' : install_data}, + packages=['halebarde'], + #scripts=['pyhalebarde'], + data_files = DATA_FILES + ) + -- 2.11.4.GIT