184 lines
8.9 KiB
Python
184 lines
8.9 KiB
Python
# Copyright (C) 2006, Red Hat, Inc.
|
|
#
|
|
# This library 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 of the License, or (at your option) any later version.
|
|
#
|
|
# This library 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 library; if not, write to the
|
|
# Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
|
# Boston, MA 02111-1307, USA.
|
|
|
|
import random
|
|
import copy
|
|
|
|
import gobject
|
|
import dbus
|
|
|
|
from sugar.presence import PresenceService
|
|
from sugar.graphics.iconcolor import IconColor
|
|
from sugar.p2p import Stream
|
|
from sugar import util
|
|
|
|
_nick_names = ['Aba', 'Abebe', 'Abebi', 'Abena', 'Abeni', 'Abeo', 'Abiba', 'Ada', 'Adah', 'Adana', 'Adanna', 'Adanya', 'Aissa', 'Akili', 'Alika', 'Ama', 'Amadi', 'Ameena', 'Ameenah', 'Ami', 'Amina', 'Aminah', 'Arziki', 'Asha', 'Ashia', 'Aziza', 'Baako', 'Binah', 'Binta', 'Bisa', 'Bolanle', 'Bunme', 'Caimile', 'Cataval', 'Chika', 'Chipo', 'Dalia', 'Dalila', 'Dayo', 'Deka', 'Delu', 'Denisha', 'Dore', 'Ebere', 'Fadhila', 'Faizah', 'Falala', 'Fayola', 'Feechi', 'Femi', 'Fisseha', 'Fola', 'Gamada', 'Ghalyela', 'Habika', 'Hada', 'Hadiya', 'Haiba', 'Halima', 'Hanzila', 'Hasina', 'Hija', 'Ilori', 'Iman', 'Imena', 'Iniko', 'Isabis', 'Isoke', 'Jahia', 'Jamelia', 'Jamila', 'Jamilah', 'Jamilia', 'Jamilla', 'Jamille', 'Jemila', 'Jendayi', 'Jina', 'Kabira', 'Kadija', 'Kafi', 'Kainda', 'Kali', 'Kalifa', 'Kanene', 'Kapera', 'Karimah', 'Kasinda', 'Keisha', 'Kesia', 'Lakeesha', 'Lateefah', 'Latrice', 'Latricia', 'Leal', 'Lehana', 'Limber', 'Lulu', 'Maha', 'Maizah', 'Malika', 'Mandisa', 'Mardea', 'Marjani', 'Marka', 'Nabelung', 'Nailah', 'Naima', 'Naja', 'Nakeisha', 'Narkeasha', 'Neda', 'Neema', 'Nichelle', 'Oba', 'Okoth', 'Ontibile', 'Orma', 'Pemba', 'Rabia', 'Rafiya', 'Ramla', 'Rashida', 'Raziya', 'Reta', 'Ridhaa', 'Saada', 'Sabra', 'Safara', 'Saidah', 'Salihah', 'Shasa', 'Shasmecka', 'Sibongile', 'Sika', 'Simbra', 'Sitembile', 'Siyanda', 'Sukutai', 'Tabita', 'Taifa', 'Taja', 'Takiyah', 'Tamala', 'Tamasha', 'Tanesha', 'Tanginika', 'Tanishia', 'Tapanga', 'Tarisai', 'Tayla', 'Tendai', 'Thandiwe', 'Tiesha', 'TinekaJawana', 'Tiombe', 'Wafa', 'Wangari', 'Waseme', 'Xhosa', 'Zabia', 'Zahara', 'Zahra', 'Zalika', 'Zanta', 'Zarina', 'Zina', 'Aba', 'Abebe', 'Abebi', 'Abena', 'Abeni', 'Abeo', 'Abiba', 'Ada', 'Adah', 'Adana', 'Adanna', 'Adanya', 'Aissa', 'Akili', 'Alika', 'Ama', 'Amadi', 'Ameena', 'Ameenah', 'Ami', 'Amina', 'Aminah', 'Amineh', 'Arziki', 'Asha', 'Ashia', 'Aziza', 'Baako', 'Binah', 'Binta', 'Bisa', 'Bolanle', 'Bunme', 'Caimile', 'Cataval', 'Chika', 'Chipo', 'Dalila', 'Dayo', 'Deka', 'Delu', 'Denisha', 'Dore', 'Ebere', 'Fadhila', 'Faizah', 'Falala', 'Fayola', 'Feechi', 'Femi', 'Fisseha', 'Fola', 'Gamada', 'Ghalyela', 'Habika', 'Hada', 'Hadiya', 'Haiba', 'Halima', 'Hanzila', 'Hasina', 'Hija', 'Ilori', 'Iman', 'Imena', 'Iniko', 'Isabis', 'Isoke', 'Jahia', 'Jamelia', 'Jamila', 'Jamilah', 'Jamilia', 'Jamilla', 'Jamille', 'Jemila', 'Jendayi', 'Jina', 'Kabira', 'Kadija', 'Kafi', 'Kainda', 'Kali', 'Kalifa', 'Kanene', 'Kapera', 'Karimah', 'Kasinda', 'Keisha', 'Kesia', 'Lakeesha', 'Lateefah', 'Latrice', 'Leal', 'Lehana', 'Limber', 'Lulu', 'Maha', 'Maizah', 'Malika', 'Mandisa', 'Mandisa', 'Mardea', 'Marjani', 'Marka', 'Nabelung', 'Nailah', 'Naima', 'Naja', 'Nakeisha', 'Narkeasha', 'Neda', 'Neema', 'Nichelle', 'Oba', 'Okoth', 'Ontibile', 'Orma', 'Pemba', 'Rabia', 'Rafiya', 'Ramla', 'Rashida', 'Raziya', 'Reta', 'Ridhaa', 'Saada', 'Sabra', 'Safara', 'Saidah', 'Salihah', 'Shasa', 'Shasmecka', 'Sibongile', 'Sika', 'Simbra', 'Sitembile', 'Siyanda', 'Sukutai', 'Tabita', 'Taifa', 'Taja', 'Takiyah', 'Tale', 'Tale green', 'Tamala', 'Tamasha', 'Tanesha', 'Tanginika', 'Tanishia', 'Tapanga', 'Tarisai', 'Tayla', 'Tendai', 'Thandiwe', 'Tiesha', 'TinekaJawana', 'Tiombe', 'Wafa', 'Wangari', 'Waseme', 'Xhosa', 'Zabia', 'Zahara', 'Zahra', 'Zalika', 'Zanta']
|
|
|
|
_PRESENCE_SERVICE_TYPE = "_presence_olpc._tcp"
|
|
|
|
_activity_refs = {}
|
|
|
|
class _NameCollection(object):
|
|
def __init__(self):
|
|
self._names = copy.copy(_nick_names)
|
|
|
|
def get_name(self):
|
|
i = random.randint(0, len(self._names))
|
|
return self._names.pop(i)
|
|
|
|
class _BotService(object):
|
|
def __init__(self, bot):
|
|
self._bot = bot
|
|
|
|
def announce(self):
|
|
props = { 'color': self._bot.color.to_string() }
|
|
pservice = PresenceService.get_instance()
|
|
self._service = pservice.register_service(self._bot.name,
|
|
_PRESENCE_SERVICE_TYPE, properties=props)
|
|
|
|
self._stream = Stream.Stream.new_from_service(self._service)
|
|
self._stream.register_reader_handler(
|
|
self._handle_buddy_icon_request, "get_buddy_icon")
|
|
self._stream.register_reader_handler(
|
|
self._handle_invite, "invite")
|
|
|
|
def _handle_buddy_icon_request(self):
|
|
if self._bot.icon:
|
|
fd = open(self._bot.icon, "r")
|
|
icon_data = fd.read()
|
|
fd.close()
|
|
if icon_data:
|
|
return base64.b64encode(self._icon)
|
|
return ''
|
|
|
|
def _handle_invite(self, issuer, bundle_id, activity_id):
|
|
return ''
|
|
|
|
def set_current_activity(self, activity_id):
|
|
self._service.set_published_value('curact', dbus.String(activity_id))
|
|
|
|
class _JoinActivityAction(object):
|
|
def __init__(self, bot, named_ref):
|
|
self._bot = bot
|
|
self._named_ref = named_ref
|
|
|
|
def execute(self):
|
|
activity_id = _activity_refs[self._named_ref]
|
|
|
|
pservice = PresenceService.get_instance()
|
|
activity = pservice.get_activity(activity_id)
|
|
service = activity.get_services()[0]
|
|
|
|
name = "%s [%s]" % (self._bot.name, activity_id)
|
|
properties = { 'title' : service.get_published_value('title'),
|
|
'color' : service.get_published_value('color') }
|
|
|
|
pservice.register_service(name, service.get_type(),
|
|
properties, service.get_address(),
|
|
service.get_port())
|
|
|
|
self._bot._service.set_current_activity(activity_id)
|
|
|
|
class _ChangeActivityAction(object):
|
|
def __init__(self, bot, named_ref):
|
|
self._bot = bot
|
|
self._named_ref = named_ref
|
|
|
|
def execute(self):
|
|
activity_id = _activity_refs[self._named_ref]
|
|
self._bot._service.set_current_activity(activity_id)
|
|
|
|
class _ShareChatAction(object):
|
|
def __init__(self, bot, named_ref, title):
|
|
self._bot = bot
|
|
self._title = title
|
|
self._id = util.unique_id()
|
|
|
|
_activity_refs[named_ref] = self._id
|
|
|
|
def execute(self):
|
|
name = "%s [%s]" % (self._bot.name, self._id)
|
|
stype = '_GroupChatActivity_Sugar_redhat_com._udp'
|
|
properties = { 'title' : self._title,
|
|
'color' : self._bot.color.to_string() }
|
|
address = u"232.%d.%d.%d" % (random.randint(0, 254),
|
|
random.randint(1, 254),
|
|
random.randint(1, 254))
|
|
|
|
pservice = PresenceService.get_instance()
|
|
pservice.register_service(name, stype, properties, address)
|
|
|
|
class _WaitAction(object):
|
|
def __init__(self, bot, seconds):
|
|
self._bot = bot
|
|
self._seconds = seconds
|
|
|
|
def execute(self):
|
|
self._bot._pause_queue(self._seconds)
|
|
|
|
class Bot(object):
|
|
_name_collection = _NameCollection()
|
|
|
|
def __init__(self):
|
|
self.name = Bot._name_collection.get_name()
|
|
self.color = IconColor()
|
|
self.icon = None
|
|
|
|
self._queue = []
|
|
|
|
def wait(self, seconds):
|
|
action = _WaitAction(self, seconds)
|
|
self._queue.append(action)
|
|
|
|
def share_chat(self, activity_id, title):
|
|
action = _ShareChatAction(self, activity_id, title)
|
|
self._queue.append(action)
|
|
|
|
def change_activity(self, activity_id):
|
|
action = _ChangeActivityAction(self, activity_id)
|
|
self._queue.append(action)
|
|
|
|
def join_activity(self, activity_id):
|
|
action = _JoinActivityAction(self, activity_id)
|
|
self._queue.append(action)
|
|
|
|
def start(self):
|
|
self._service = _BotService(self)
|
|
self._service.announce()
|
|
|
|
self._start_queue()
|
|
|
|
def _idle_cb(self):
|
|
self._next_action()
|
|
return True
|
|
|
|
def _pause_done_cb(self):
|
|
self._start_queue()
|
|
return False
|
|
|
|
def _start_queue(self):
|
|
self._queue_sid = gobject.idle_add(self._idle_cb)
|
|
|
|
def _pause_queue(self, seconds):
|
|
gobject.source_remove(self._queue_sid)
|
|
gobject.timeout_add(int(seconds * 1000), self._pause_done_cb)
|
|
|
|
def _next_action(self):
|
|
if len(self._queue) > 0:
|
|
action = self._queue.pop(0)
|
|
action.execute()
|