Changeset 677

Show
Ignore:
Timestamp:
06/15/08 15:36:36 (5 months ago)
Author:
sylvain
Message:

Updated several components and support for XMPP core and extensions

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • oss/headstock/headstock/api/contact.py

    r668 r677  
    2323 
    2424    def __repr__(self): 
    25         return '<Presence %s (%s) at %s>' % (str(self.from_jid), self.subscription, hex(id(self))) 
     25        return '<Presence %s (%s) at %s>' % (str(self.from_jid), self.type, hex(id(self))) 
    2626 
    2727    @staticmethod 
  • oss/headstock/headstock/api/discovery.py

    r668 r677  
    1414 
    1515__all__ = ['FeaturesDiscovery', 'ItemsDiscovery', 
    16            'SubscriptionsDiscovery'
     16           'SubscriptionsDiscovery', 'AffiliationsDiscovery'
    1717 
    1818class Identity(object): 
     
    5151        return '<Subscription %s [%s:%s] at %s>' % (str(self.jid), self.node,  
    5252                                                    self.state, hex(id(self))) 
     53 
     54class Affiliation(object): 
     55    def __init__(self, node, affiliation): 
     56        self.node = node 
     57        self.affiliation = affiliation 
     58 
     59    def __repr__(self): 
     60        return '<Affiliation %s (%s) at %s>' % (self.node, self.affiliation, hex(id(self))) 
    5361 
    5462class FeaturesDiscovery(Entity): 
     
    172180                                       type=e.get_attribute_value('type'), 
    173181                                       stanza_id=e.get_attribute_value('id')) 
    174  
    175         for c in e.xml_children: 
    176             if not isinstance(c, E): 
    177                 continue 
    178  
    179             if c.xml_ns == XMPP_PUBSUB_NS: 
    180                 if c.xml_name == 'subscriptions': 
    181                     for i in c.xml_children: 
    182                         if i.xml_name == 'subscription' and i.xml_ns == XMPP_DISCO_ITEMS_NS: 
    183                             jid = JID.parse(unicode(i.get_attribute_value('jid'))) 
    184                             item = Subscription(i.get_attribute_value('node'), 
    185                                                 jid, i.get_attribute_value('subscription')) 
    186                             disco.subscriptions.append(item) 
     182        for c in e.xml_children: 
     183            if not isinstance(c, E): 
     184                continue 
     185 
     186            if c.xml_ns == XMPP_PUBSUB_NS and c.xml_name == 'pubsub': 
     187                for p in c.xml_children:                     
     188                    if not isinstance(p, E): 
     189                        continue 
     190                    if p.xml_ns == XMPP_PUBSUB_NS and p.xml_name == 'subscriptions':    
     191                        for s in p.xml_children:                     
     192                            if not isinstance(s, E): 
     193                                continue 
     194                            jid = s.get_attribute_value('jid', None) 
     195                            if jid: 
     196                                JID.parse(jid) 
     197                            sub = Subscription(s.get_attribute_value('node'), jid, 
     198                                               s.get_attribute_value('subscription')) 
     199                            disco.subscriptions.append(sub) 
    187200            elif c.xml_ns == XMPP_CLIENT_NS and c.xml_name == 'error': 
    188201                disco.error = Error.from_element(c) 
    189202 
    190203        return disco 
     204 
     205class AffiliationsDiscovery(Entity): 
     206    def __init__(self, from_jid, to_jid, type=u'get', stanza_id=None): 
     207        Entity.__init__(self, from_jid, to_jid, type, stanza_id) 
     208        self.affiliations  = [] 
     209     
     210    @staticmethod 
     211    def to_element(e): 
     212        iq = Entity.to_element(e) 
     213        query = E(u'query', namespace=XMPP_PUBSUB_NS, parent=iq) 
     214        E('affiliations', namespace=XMPP_PUBSUB_NS, parent=query) 
     215 
     216        return iq 
     217 
     218    @staticmethod 
     219    def from_element(e): 
     220        disco = AffiliationsDiscovery(JID.parse(e.get_attribute_value('from')), 
     221                                       JID.parse(e.get_attribute_value('to')), 
     222                                       type=e.get_attribute_value('type'), 
     223                                       stanza_id=e.get_attribute_value('id')) 
     224        for c in e.xml_children: 
     225            if not isinstance(c, E): 
     226                continue 
     227 
     228            if c.xml_ns == XMPP_PUBSUB_NS and c.xml_name == 'pubsub': 
     229                for p in c.xml_children:                     
     230                    if not isinstance(p, E): 
     231                        continue 
     232                    if p.xml_ns == XMPP_PUBSUB_NS and p.xml_name == 'affiliations':    
     233                        for s in p.xml_children:                     
     234                            if not isinstance(s, E): 
     235                                continue 
     236                            aff = Affiliation(s.get_attribute_value('node'), 
     237                                              s.get_attribute_value('affiliation')) 
     238                            disco.affiliations.append(aff) 
     239            elif c.xml_ns == XMPP_CLIENT_NS and c.xml_name == 'error': 
     240                disco.error = Error.from_element(c) 
     241 
     242        return disco 
  • oss/headstock/headstock/api/error.py

    r667 r677  
    2424    @staticmethod 
    2525    def from_element(e): 
    26         error_type = e.get_attribute('type') 
    27         code = e.get_attribute('code') 
     26        error_type = e.get_attribute_value('type') 
     27        code = e.get_attribute_value('code') 
    2828        condition = text = lang = foreign = None 
    2929        for child in e.xml_children: 
     
    3131                if child.xml_name == u'text': 
    3232                    text = child.xml_text 
    33                     lang = child.get_attribute('lang') 
     33                    lang = child.get_attribute_value('lang') 
    3434                else: 
    3535                    condition = child.xml_name 
  • oss/headstock/headstock/api/im.py

    r668 r677  
    1414from bridge import Attribute as A 
    1515from bridge.common import XML_NS, XML_PREFIX, XMPP_CLIENT_NS, \ 
    16      XMPP_EVENT_NS, XMPP_XOOB_NS 
     16     XMPP_EVENT_NS, XMPP_XOOB_NS, XMPP_XHTML_IM_NS, XHTML1_NS 
    1717 
    1818class Body(object): 
     
    2626    def __str__(self): 
    2727        return str(self.plain_body) 
     28 
     29class XHTMLBody(object): 
     30    def __init__(self, inner): 
     31        self.inner = inner 
     32         
     33    def __repr__(self): 
     34        return '<XHTMLBody at %s>' % (hex(id(self)),) 
    2835 
    2936class Subject(object): 
     
    5057class Message(Entity): 
    5158    def __init__(self, from_jid, to_jid, type=u'normal', stanza_id=None, lang=None): 
    52         Entity.__init__(self, from_jid, to_jid) 
    53         self.type = type 
     59        Entity.__init__(self, from_jid, to_jid, type, stanza_id) 
    5460        self.lang = lang 
    55         self.stanza_id = stanza_id  
    5661 
    5762        self.bodies = [] 
     
    100105                elif child.xml_name == 'thread': 
    101106                    message.thread = child.xml_text 
     107                if child.xml_name == 'html' and child.xml_ns == XMPP_XHTML_IM_N: 
     108                    b = XHTMLBody(child.xml_children.clone()) 
     109                    message.bodies.append(b) 
    102110                else: 
    103111                    message.foreign.append(Foreign(child)) 
     
    132140 
    133141        for body in m.bodies: 
    134             b = E(u'body', content=body.plain_body, 
    135                   namespace=XMPP_CLIENT_NS, parent=e) 
    136             if body.lang: 
    137                 A(u'lang', value=body.lang, 
    138                   prefix=XML_PREFIX, namespace=XML_NS, parent=b) 
     142            if isinstance(body, Body): 
     143                b = E(u'body', content=body.plain_body, 
     144                      namespace=XMPP_CLIENT_NS, parent=e) 
     145                if body.lang: 
     146                    A(u'lang', value=body.lang, 
     147                      prefix=XML_PREFIX, namespace=XML_NS, parent=b) 
     148            elif isinstance(body, XHTMLBody): 
     149                h = E(u'html', namespace=XMPP_XHTML_IM_NS, parent=e) 
     150                b = E(u'body', namespace=XHTML1_NS, parent=h) 
     151                body.inner.xml_parent = b 
     152                b.xml_children.append(body.inner) 
    139153 
    140154        if m.thread: 
  • oss/headstock/headstock/api/pubsub.py

    r668 r677  
    88from headstock.api.error import Error 
    99from headstock.api.jid import JID 
     10from headstock.api.dataform import Data, Field 
    1011from bridge import Element as E 
    1112from bridge import Attribute as A 
     
    1516 
    1617class Configure(object): 
    17     def __init__(self, data=None): 
    18         self.data = data 
     18    def __init__(self, x=None): 
     19        self.x = x 
     20 
     21    @staticmethod 
     22    def to_element(e, parent=None): 
     23        c = E(u'configure', namespace=XMPP_PUBSUB_NS, parent=parent) 
     24        Data.to_element(e.x, parent=c) 
     25        return c 
     26 
     27    @staticmethod 
     28    def make_collection_node(): 
     29        d = Data(u'submit') 
     30        d.fields.append(Field(field_type=u'hidden', var=u'FORM_TYPE',  
     31                               values=[u'http://jabber.org/protocol/pubsub#node_config'])) 
     32        d.fields.append(Field(field_type=None, var=u'pubsub#node_type',  
     33                              values=[u'collection'])) 
     34        return Configure(x=d) 
    1935 
    2036    def create_leaf_node_whitelist(cls): 
     
    4460        Entity.__init__(self, from_jid, to_jid, type, stanza_id)  
    4561        self.node_name = node_name 
     62        self.configure = None 
    4663        if kwargs: 
    4764            self.__dict__.update(kwargs) 
     
    5067        return '<Node "%s" at %s>' % (self.node_name, hex(id(self))) 
    5168 
     69    def set_default_collection_conf(self): 
     70        self.configure = Configure.make_collection_node() 
     71 
    5272    @staticmethod 
    5373    def to_creation_element(e): 
     
    5676        attrs = {u'node': e.node_name} 
    5777        E(u'create', attributes=attrs, namespace=XMPP_PUBSUB_NS, parent=pubsub) 
    58         E(u'configure', namespace=XMPP_PUBSUB_NS, parent=pubsub) 
     78        if not e.configure: 
     79            E(u'configure', namespace=XMPP_PUBSUB_NS, parent=pubsub) 
     80        else: 
     81            Configure.to_element(e.configure, parent=pubsub) 
    5982        return iq 
    6083 
     
    7295                        if p.xml_name == 'create': 
    7396                            node.node_name = p.get_attribute('node') 
    74             elif i.xml_ns == XMPP_STREAM_NS and i.xml_name == 'error': 
     97            elif i.xml_ns == XMPP_CLIENT_NS and i.xml_name == 'error': 
    7598                node.error = Error.from_element(i) 
    7699 
     
    98121                        if p.xml_name == 'create': 
    99122                            node.node_name = p.get_attribute('node') 
    100             elif i.xml_ns == XMPP_STREAM_NS and i.xml_name == 'error': 
     123            elif i.xml_ns == XMPP_CLIENT_NS and i.xml_name == 'error': 
     124                node.error = Error.from_element(i) 
     125 
     126        return node 
     127 
     128    @staticmethod 
     129    def to_purge_element(e): 
     130        iq = Entity.to_element(e) 
     131        pubsub = E(u'pubsub', namespace=XMPP_PUBSUB_OWNER_NS, parent=iq) 
     132        attrs = {u'node': e.node_name} 
     133        E(u'purge', attributes=attrs, namespace=XMPP_PUBSUB_OWNER_NS, parent=pubsub) 
     134        return iq 
     135 
     136    @staticmethod 
     137    def from_purge_element(e): 
     138        node = Node(JID.parse(e.get_attribute_value('from')), 
     139                    JID.parse(e.get_attribute_value('to')), 
     140                    type=e.get_attribute_value('type'), 
     141                    stanza_id=e.get_attribute_value('id')) 
     142 
     143        for i in e.xml_children: 
     144            if i.xml_ns in [XMPP_PUBSUB_NS]: 
     145                for p in i.xml_children: 
     146                    if p.xml_ns in [XMPP_PUBSUB_NS]: 
     147                        if p.xml_name == 'create': 
     148                            node.node_name = p.get_attribute('node') 
     149            elif i.xml_ns == XMPP_CLIENT_NS and i.xml_name == 'error': 
    101150                node.error = Error.from_element(i) 
    102151 
     
    107156        iq = Entity.to_element(e) 
    108157        pubsub = E(u'pubsub', namespace=XMPP_PUBSUB_NS, parent=iq) 
    109         sub_jid = e.sub_jid 
    110158        attrs = {u'node': e.node_name, u'jid': e.sub_jid} 
    111159        E(u'subscribe', attributes=attrs, namespace=XMPP_PUBSUB_NS, parent=pubsub) 
     
    126174                            sub.node_name = p.get_attribute('node') 
    127175                            sub.sub_jid = p.get_attribute('jid') 
    128             elif i.xml_ns == XMPP_STREAM_NS and i.xml_name == 'error': 
     176            elif i.xml_ns == XMPP_CLIENT_NS and i.xml_name == 'error': 
    129177                sub.error = Error.from_element(i) 
    130178 
     
    154202                            sub.node_name = p.get_attribute('node') 
    155203                            sub.sub_jid = p.get_attribute('jid') 
    156             elif i.xml_ns == XMPP_STREAM_NS and i.xml_name == 'error': 
     204            elif i.xml_ns == XMPP_CLIENT_NS and i.xml_name == 'error': 
    157205                sub.error = Error.from_element(i) 
    158206 
     
    192240                                        payload = q.xml_children[0].clone() 
    193241                                    node.item = Item(q.get_attribute('id'), payload)                                     
    194             elif i.xml_ns == XMPP_STREAM_NS and i.xml_name == 'error': 
     242            elif i.xml_ns == XMPP_CLIENT_NS and i.xml_name == 'error': 
    195243                node.error = Error.from_element(i) 
    196244 
     
    224272                                if q.xml_name == 'item': 
    225273                                    node.item = Item(q.get_attribute('id'))                                     
    226             elif i.xml_ns == XMPP_STREAM_NS and i.xml_name == 'error': 
     274            elif i.xml_ns == XMPP_CLIENT_NS and i.xml_name == 'error': 
    227275                node.error = Error.from_element(i) 
    228276 
  • oss/headstock/headstock/api/registration.py

    r668 r677  
    6565 
    6666        if e.x: 
    67             Data.to_element(x, parent=query) 
     67            Data.to_element(e.x, parent=query) 
    6868 
    6969        return iq 
  • oss/headstock/headstock/lib/logger.py

    r652 r677  
    77 
    88import logging 
     9from logging import handlers 
    910 
    1011class Logger(component): 
     
    1415                "signal" : "UNUSED",} 
    1516    
    16     def __init__(self, path=None, stdout=False): 
     17    def __init__(self, path=None, stdout=False, name=None): 
    1718        super(Logger, self).__init__() 
    1819 
    1920        self.path = path 
    2021        self.with_stdout = stdout 
     22        self.name = name 
    2123 
    2224    def main(self): 
    23         logger = logging.getLogger("kamaelia.logger"
     25        logger = logging.getLogger("kamaelia.logger.%s" % self.name or ''
    2426        logger.setLevel(logging.DEBUG) 
    2527         
     
    2729 
    2830        if self.path: 
    29             h = logging.FileHandler(self.path
     31            h = handlers.RotatingFileHandler(self.path, maxBytes=1048576, backupCount=5
    3032            h.setLevel(logging.DEBUG) 
    3133            h.setFormatter(logfmt) 
  • oss/headstock/headstock/lib/utils.py

    r667 r677  
    1 #!/usr/bin/env python 
    21# -*- coding: utf-8 -*- 
    3  
     2import codecs 
    43import sha 
    54from time import time 
    65from random import random 
    76 
    8 __all__ = ['generate_unique'] 
     7 
     8__all__ = ['generate_unique', 'remove_BOM'] 
    99 
    1010def generate_unique(seed=None): 
     
    1212        seed = str(time() * random()) 
    1313    return unicode(abs(hash(sha.new(seed).hexdigest()))) 
     14 
     15def remove_BOM(text): 
     16    if text[0] == codecs.BOM_UTF8.decode("utf-8"): 
     17        return text.replace(codecs.BOM_UTF8.decode("utf-8"), '') 
     18    if text[0] == codecs.BOM.decode("utf-16"): 
     19        return text.replace(codecs.BOM.decode("utf-16"), '') 
     20    if text[0] == codecs.BOM_BE.decode("utf-16-be"): 
     21        return text.replace(codecs.BOM_BE.decode("utf-16-be"), '') 
     22    if text[0] == codecs.BOM_LE.decode("utf-16-le"): 
     23        return text.replace(codecs.BOM_LE.decode("utf-16-le"), '') 
     24 
     25    return text 
  • oss/headstock/headstock/protocol/extension/discovery.py

    r660 r677  
    22 
    33from headstock.api.discovery import FeaturesDiscovery, ItemsDiscovery,\ 
    4     SubscriptionsDiscovery 
     4    SubscriptionsDiscovery, AffiliationsDiscovery 
    55from bridge import Element as E 
    66from bridge import Attribute as A 
     
    1212 
    1313__all__ = ['FeaturesDiscoveryDispatcher', 'ItemsDiscoveryDispatcher', 
    14            'SubscriptionsDiscoveryDispatcher', 'DiscoveryDispatcher'] 
     14           'SubscriptionsDiscoveryDispatcher', 'AffiliationsDiscoveryDispatcher', 
     15           'DiscoveryDispatcher'] 
    1516 
    1617class FeaturesDiscoveryDispatcher(component): 
     
    157158            if self.dataReady("inbox"): 
    158159                handled = False 
    159                 e = self.recv("inbox") 
    160                 e = e.xml_parent.xml_parent 
    161                 print e.xml() 
     160                s = self.recv("inbox") 
     161                e = s.xml_parent.xml_parent 
    162162                self.send(('INCOMING', e), "log") 
    163163                 
     
    177177            yield 1 
    178178 
     179class AffiliationsDiscoveryDispatcher(component): 
     180     
     181    Inboxes = {"inbox"              : "bridge.Element instance", 
     182               "control"            : "Shutdown the client stream", 
     183               "forward"            : "headstock.api.contact.Message instance to be sent back to the client. Transforms the instance to a bridge.Element instance and puts it into the 'outbox'", 
     184               } 
     185     
     186    Outboxes = {"outbox"       : "bridge.Element instance", 
     187                "signal"       : "Shutdown signal", 
     188                "log"          : "log", 
     189                "unknown"      : "Unknown element that could not be dispatched properly", 
     190                "xmpp.get"     : "Activity requests", 
     191                "xmpp.set"     : "Activity requests", 
     192                "xmpp.result"  : "Activity responses", 
     193                "xmpp.error"   : "Activity response error", 
     194                } 
     195     
     196    def __init__(self): 
     197       super(AffiliationsDiscoveryDispatcher, self).__init__()  
     198 
     199    def main(self): 
     200        while 1: 
     201            if self.dataReady("control"): 
     202                mes = self.recv("control") 
     203                 
     204                if isinstance(mes, shutdownMicroprocess) or isinstance(mes, producerFinished): 
     205                    self.send(producerFinished(), "signal") 
     206                    break 
     207 
     208            if self.dataReady("forward"): 
     209                m = self.recv("forward") 
     210                self.send(AffiliationsDiscovery.to_element(m), "outbox") 
     211 
     212            if self.dataReady("inbox"): 
     213                handled = False 
     214                s = self.recv("inbox") 
     215                e = s.xml_parent.xml_parent 
     216                self.send(('INCOMING', e), "log") 
     217                 
     218                msg_type = e.get_attribute_value(u'type') or u'get' 
     219                key = 'xmpp.%s' % unicode(msg_type) 
     220 
     221                if key in self.outboxes: 
     222                    self.send(AffiliationsDiscovery.from_element(e), key) 
     223                    handled = True 
     224 
     225                if not handled: 
     226                    self.send(e, "unknown") 
     227 
     228            if not self.anyReady(): 
     229                self.pause() 
     230   
     231            yield 1 
     232 
    179233class DiscoveryDispatcher(component): 
    180234    Inboxes = {"inbox"              : "bridge.Element instance", 
     
    182236               "features.inbox": "", 
    183237               "subscription.inbox": "", 
     238               "affiliation.inbox": "", 
    184239               "items.inbox": "", 
    185240               "features.forward": "", 
    186241               "subscription.forward": "", 
     242               "affiliation.forward": "", 
    187243               "items.forward": "", 
    188244               "in.features.get"     : "Activity requests", 
     
    197253               "in.subscription.set"     : "Activity requests", 
    198254               "in.subscription.result"  : "Activity responses", 
    199                "in.subscription.error"   : "Activity response error",} 
     255               "in.subscription.error"   : "Activity response error", 
     256               "in.affiliation.get"     : "Activity requests", 
     257               "in.affiliation.set"     : "Activity requests", 
     258               "in.affiliation.result"  : "Activity responses", 
     259               "in.affiliation.error"   : "Activity response error",} 
    200260     
    201261    Outboxes = {"outbox"       : "bridge.Element instance", 
     
    205265                "features.outbox": "", 
    206266                "subscription.outbox": "", 
     267                "affiliation.outbox": "", 
    207268                "items.outbox": "", 
    208269                "out.features.get"     : "Activity requests", 
     
    218279                "out.subscription.result"  : "Activity responses", 
    219280                "out.subscription.error"   : "Activity response error", 
     281                "out.affiliation.get"     : "Activity requests", 
     282                "out.affiliation.set"     : "Activity requests", 
     283                "out.affiliation.result"  : "Activity responses", 
     284                "out.affiliation.error"   : "Activity response error", 
    220285                } 
    221286     
     
    239304        self.link((subdisp, 'log'), (self, 'log'), passthrough=2) 
    240305        self.addChildren(subdisp) 
    241         subdisp.activate() 
     306        subdisp.activate()       
     307 
     308        affdisp = AffiliationsDiscoveryDispatcher() 
     309        self.link((self, 'affiliation.inbox'), (affdisp, 'inbox'), passthrough=1) 
     310        self.link((self, 'affiliation.forward'), (affdisp, 'forward'), passthrough=1) 
     311        self.link((self, 'in.affiliation.get'), (affdisp, 'forward'), passthrough=1) 
     312        self.link((self, 'in.affiliation.set'), (affdisp, 'forward'), passthrough=1) 
     313        self.link((self, 'in.affiliation.result'), (affdisp, 'forward'), passthrough=1) 
     314        self.link((self, 'in.affiliation.error'), (affdisp, 'forward'), passthrough=1) 
     315        self.link((affdisp, 'outbox'), (self, 'affiliation.outbox'), passthrough=2) 
     316        self.link((affdisp, 'xmpp.get'), (self, 'out.affiliation.get'), passthrough=2) 
     317        self.link((affdisp, 'xmpp.set'), (self, 'out.affiliation.set'), passthrough=2) 
     318        self.link((affdisp, 'xmpp.result'), (self, 'out.affiliation.result'), passthrough=2) 
     319        self.link((affdisp, 'xmpp.error'), (self, 'out.affiliation.error'), passthrough=2) 
     320        self.link((affdisp, 'unknown'), (self, 'unknown'), passthrough=2) 
     321        self.link((affdisp, 'log'), (self, 'log'), passthrough=2) 
     322        self.addChildren(affdisp) 
     323        affdisp.activate() 
    242324     
    243325        featdisp = FeaturesDiscoveryDispatcher() 
  • oss/headstock/headstock/protocol/extension/pubsub.py

    r654 r677  
    1212           'NodeDeletionDispatcher', 'UnsubscriptionDispatcher',  
    1313           'ItemPublicationDispatcher', 'ItemDeletionDispatcher', 
    14            'MessageEventDispatcher', 'PubSubDispatcher'] 
     14           'MessageEventDispatcher', 'NodePurgeDispatcher', 
     15           'PubSubDispatcher'] 
    1516 
    1617class SubscriptionDispatcher(component): 
     
    246247        yield 1 
    247248 
    248 class ItemPublicationDispatcher(component): 
     249class NodePurgeDispatcher(component): 
    249250     
    250251    Inboxes = {"inbox"              : "bridge.Element instance", 
     
    264265     
    265266    def __init__(self): 
    266        super(ItemPublicationDispatcher, self).__init__()  
     267       super(NodePurgeDispatcher, self).__init__()  
    267268 
    268269    def main(self): 
     
    279280            if self.dataReady("forward"): 
    280281                s = self.recv("forward") 
    281                 self.send(Node.to_publication_element(s), "outbox") 
     282                self.send(Node.to_purge_element(s), "outbox") 
    282283 
    283284            if self.dataReady("inbox"): 
     
    291292 
    292293                if key in self.outboxes: 
    293                     self.send(Node.from_publication_element(e), key) 
     294                    self.send(Node.from_purge_element(e), key) 
    294295                    handled = True 
    295296 
     
    304305        yield 1 
    305306 
    306 class ItemDeletionDispatcher(component): 
     307class ItemPublicationDispatcher(component): 
    307308     
    308309    Inboxes = {"inbox"              : "bridge.Element instance", 
     
    322323     
    323324    def __init__(self): 
     325       super(ItemPublicationDispatcher, self).__init__()  
     326 
     327    def main(self): 
     328        yield 1 
     329 
     330        while 1: 
     331            if self.dataReady("control"): 
     332                mes = self.recv("control") 
     333                 
     334                if isinstance(mes, shutdownMicroprocess) or isinstance(mes, producerFinished): 
     335                    self.send(producerFinished(), "signal") 
     336                    break 
     337 
     338            if self.dataReady("forward"): 
     339                s = self.recv("forward") 
     340                self.send(Node.to_publication_element(s), "outbox") 
     341 
     342            if self.dataReady("inbox"): 
     343                handled = False 
     344                a = self.recv("inbox") 
     345                e = a.xml_parent.xml_parent 
     346                self.send(('INCOMING', e), "log") 
     347                 
     348                msg_type = e.get_attribute_value(u'type') or 'get' 
     349                key = 'xmpp.%s' % unicode(msg_type) 
     350 
     351                if key in self.outboxes: 
     352                    self.send(Node.from_publication_element(e), key) 
     353                    handled = True 
     354 
     355                if not handled: 
     356                    self.send(e, "unknown") 
     357                     
     358            if not self.anyReady(): 
     359                self.pause() 
     360   
     361            yield 1 
     362 
     363        yield 1 
     364 
     365class ItemDeletionDispatcher(component): 
     366     
     367    Inboxes = {"inbox"              : "bridge.Element instance", 
     368               "control"            : "Shutdown the client stream", 
     369               "forward"            : "headstock.api.contact.Message instance to be sent back to the client. Transforms the instance to a bridge.Element instance and puts it into the 'outbox'", 
     370               } 
     371     
     372    Outboxes = {"outbox"       : "bridge.Element instance", 
     373                "signal"       : "Shutdown signal", 
     374                "log"          : "log", 
     375                "unknown"      : "Unknown element that could not be dispatched properly", 
     376                "xmpp.get"     : "Activity requests", 
     377                "xmpp.set"     : "Activity responses", 
     378                "xmpp.result"  : "Activity responses", 
     379                "xmpp.error"   : "Activity response error", 
     380                } 
     381     
     382    def __init__(self): 
    324383       super(ItemDeletionDispatcher, self).__init__()  
    325384 
     
    407466               "create.inbox"        : "", 
    408467               "create.forward"      : "", 
     468               "purge.inbox"        : "", 
     469               "purge.forward"      : "", 
    409470               "delete.inbox"        : "", 
    410471               "delete.forward"      : "", 
     
    418479               "retract.forward"     : "", 
    419480               "message.inbox"       : "", 
     481               "in.create.error"        : "Publish items response error", 
    420482               "in.create.get"          : "Publish items requests", 
    421483               "in.create.set"          : "Publish items responses", 
    422484               "in.create.result"       : "Publish items responses", 
     485               "in.purge.error"        : "Publish items response error", 
     486               "in.purge.get"          : "Publish items requests", 
     487               "in.purge.set"          : "Publish items responses", 
     488               "in.purge.result"       : "Publish items responses", 
    423489               "in.delete.error"        : "Publish items response error", 
    424490               "in.delete.get"          : "Publish items requests", 
    425491               "in.delete.set"          : "Publish items responses", 
    426492               "in.delete.result"       : "Publish items responses", 
    427                "in.create.error"        : "Publish items response error", 
    428493               "in.subscribe.get"       : "Publish items requests", 
    429494               "in.subscribe.set"       : "Publish items responses", 
     
    448513                "log"                     : "log", 
    449514                "create.outbox"           : "", 
     515                "purge.outbox"            : "", 
    450516                "delete.outbox"           : "", 
    451517                "subscribe.outbox"        : "", 
     
    457523                "out.create.set"          : "Publish items responses", 
    458524                "out.create.result"       : "Publish items responses", 
     525                "out.purge.error"        : "Publish items response error", 
     526                "out.purge.get"          : "Publish items requests", 
     527                "out.purge.set"          : "Publish items responses", 
     528                "out.purge.result"       : "Publish items responses", 
    459529                "out.delete.error"        : "Publish items response error", 
    460530                "out.delete.get"          : "Publish items requests", 
     
    535605        nodecreatedisp.activate() 
    536606 
     607        nodepurgedisp = NodePurgeDispatcher() 
     608        self.link((self, 'purge.inbox'), (nodepurgedisp, 'inbox'), passthrough=1) 
     609        self.link((self, 'purge.forward'), (nodepurgedisp, 'forward'), passthrough=1) 
     610        self.link((self, 'in.purge.get'), (nodepurgedisp, 'forward'), passthrough=1) 
     611        self.link((self, 'in.purge.set'), (nodepurgedisp, 'forward'), passthrough=1) 
     612        self.link((self, 'in.purge.result'), (nodepurgedisp, 'forward'), passthrough=1) 
     613        self.link((self, 'in.purge.error'), (nodepurgedisp, 'forward'), passthrough=1) 
     614        self.link((nodepurgedisp, 'outbox'), (self, 'purge.outbox'), passthrough=2) 
     615        self.link((nodepurgedisp, 'xmpp.get'), (self, 'out.purge.get'), passthrough=2) 
     616        self.link((nodepurgedisp, 'xmpp.set'), (self, 'out.purge.set'), passthrough=2) 
     617        self.link((nodepurgedisp, 'xmpp.result'), (self, 'out.purge.result'), passthrough=2) 
     618        self.link((nodepurgedisp, 'xmpp.error'), (self, 'out.purge.error'), passthrough=2) 
     619        self.link((nodepurgedisp, 'unknown'), (self, 'unknown'), passthrough=2) 
     620        self.link((nodepurgedisp, 'log'), (self, 'log'), passthrough=2) 
     621        self.addChildren(nodepurgedisp) 
     622        nodepurgedisp.activate() 
     623 
    537624        nodedeletedisp = NodeDeletionDispatcher() 
    538625        self.link((self, 'delete.inbox'), (nodedeletedisp, 'inbox'), passthrough=1)