예제 #1
0
def xml_unicode_to_pns (e):
        "XML/PNS - serialize a UNICODEd XML element as 8-bit byte strings"
        if e.xml_attributes:
                yield netstring.encode ((
                        netstring.encode ((
                                key.encode ('utf-8'), val.encode ('utf-8')
                                ))
                        for key, val in e.xml_attributes.items ()
                        ))
        
        else:
                yield ''
                        
        yield e.xml_first.encode ('utf-8')

        if e.xml_children:
                yield netstring.encode ((
                        netstring.encode ((
                                child.pns_name, 
                                child.xml_name.encode ('utf-8')
                                ))
                        for child in e.xml_children
                        ))
        
        else:
                yield ''
                   
        if e.xml_follow:
                yield e.xml_follow.encode ('utf-8')
        
        else:
                yield ''
예제 #2
0
def articulate_re(text, articulate, articulators, depth=0):
    "Articulate text using a simple regular expression lexer"
    bottom = len(articulators)
    # move down the stack until a pattern is matched ...
    while True:
        texts = [t for t in articulators[depth].split(text) if t]
        depth += 1
        if len(texts) > 1:
            break

        if depth == bottom:
            # no match found, bottom of the stack reached.
            return text

    field = set()
    if depth == bottom:
        # bottom of the stack reached, simply split
        name = pns_model.pns_name(netstring.encode(texts), field)
    else:
        # not yet at the bottom of the stack, recurse ...
        name = pns_model.pns_name(
            netstring.encode((articulate_re(t, articulate, articulators, depth) for t in texts)), field
        )
    # validate the articulated name(s) as a Public Names
    if len(field) > 1:
        articulate((len(field), field, name, text))
    return name
예제 #3
0
def xml_unicode_to_pns(e):
    "XML/PNS - serialize a UNICODEd XML element as 8-bit byte strings"
    if e.xml_attributes:
        yield netstring.encode((netstring.encode(
            (key.encode('utf-8'), val.encode('utf-8')))
                                for key, val in e.xml_attributes.items()))

    else:
        yield ''

    yield e.xml_first.encode('utf-8')

    if e.xml_children:
        yield netstring.encode((netstring.encode(
            (child.pns_name, child.xml_name.encode('utf-8')))
                                for child in e.xml_children))

    else:
        yield ''

    if e.xml_follow:
        yield e.xml_follow.encode('utf-8')

    else:
        yield ''
예제 #4
0
def compact_traceback (ctb):
	"encode a compact traceback tuple as netstrings"
 	return netstring.encode ((
                ctb[0], 
 		netstring.encode ([' | '.join (x) for x in ctb[2]]),
                ctb[1]
 		)), 'traceback'
예제 #5
0
def log_statement(model):
    "Log valid statement to STDOUT, errors to STDERR"
    model, error = pns_model.pns_triple(model)
    if error:
        loginfo.log(netstring.encode(model), error)
        return False

    loginfo.log(netstring.encode(model))
    return True
예제 #6
0
def log_statement (model):
        "Log valid statement to STDOUT, errors to STDERR"
        model, error = pns_model.pns_triple (model)
        if error:
                loginfo.log (netstring.encode (model), error)
                return False
        
        loginfo.log (netstring.encode (model))
        return True
예제 #7
0
def classic_traceback (ctb=None):
        return netstring.encode ((
                netstring.encode ([
                        'File "%s", line %s, in %s' % (
                                tb[0] or '<string>', tb[2], tb[1]
                                )
                        for tb in ctb[2]
                        ]), '%s: %s' % ctb[:2]
                )), 'Traceback (most recent call last):'
예제 #8
0
def resolved (request):
        model = list (request.dns_question)
        if request.dns_resources == None:
                model.append ('')
        elif len (request.dns_resources) > 1:
                model.append (netstring.encode (
                        request.dns_resources
                        ))
        elif request.dns_resources:
                model.append (request.dns_resources[0])
        else:
                model.append ('')
        model.append (request.dns_peer[0])
        loginfo.log (netstring.encode (model))
예제 #9
0
 def __repr__(self):
     "return a safe netstring representation of the deque"
     r = []
     try:
         self.cv.acquire()
         l = len(self.deque)
         for item in self.deque:
             try:
                 r.append('%r' % (item, ))
             except:
                 r.append('item id="%x"' % id(item))
     finally:
         self.cv.release()
     return netstring.encode(
         ('protected_deque queued="%d"' % l, netstring.encode(r)))
예제 #10
0
        def pns_signal (self, resolved, model):
                "the default resolution handler"
                assert None == self.log (netstring.encode (model))
                if model[4] == '_' or model[4].startswith ('.'):
                        return False

                return True
예제 #11
0
        def pns_command (self, model):
                # handle a command from a PNS/TCP session
                assert None == self.log (
                        netstring.encode (model), 'command'
                        )
                if model[1]:
                        if model[2]:
                                # walk subject down to contexts, let the user
                                # agent walk the graph up and down at once to
                                # test and weight a subject against a set of
                                # contexts (and not implement that common walk
                                # into the client, but rather articulate it).
                                #
                                contexts = set (netunicode.decode (
                                        unicode (model[2], 'UTF-8')
                                        ))
                                self.thread_loop_queue ((
                                        self.pns_walk_simplest,
                                        (model, contexts)
                                        ))
                                return

                        # walk down the contexts once, in all contexts
                        self.thread_loop_queue ((
                                self.pns_command_predicate, (model,)
                                ))
                        return

                # walk up the names once, for in contexts
                self.thread_loop_queue ((
                        self.pns_command_object, (model,)
                        ))
예제 #12
0
def articulate_chunk(text, articulate, articulators, CHUNK, depth=0):
    "Articulate in chunks, usefull for larger text articulations"
    bottom = len(articulators)
    # move down the stack until a pattern is matched ...
    while True:
        texts = [t for t in articulators[depth].split(text) if t]
        depth += 1
        if len(texts) > 1:
            break

        if depth == bottom:
            # no match found, bottom of the stack reached, this
            # is supposed to chunk, not articulate, do not name
            # because it is inarticulated junk ...
            return ""

    if depth == bottom:
        # bottom of the stack reached, simply split do not articulate
        # any further, there is nothing to chunk and it is a flat
        # articulation ...
        return pns_model.pns_name(netstring.encode((t for t in texts if len(t) <= CHUNK)), set())

    # not yet at the bottom of the stack, recurse
    for t in texts:
        if len(t) > CHUNK:
            articulate_chunk(t, articulate, articulators, CHUNK, depth)
        else:
            articulate_re(t, articulate, articulators, depth)
    return None
예제 #13
0
 def pns_join(self, context, ip, handler):
     "join a context at ip and subscribe the handler to its log"
     if self.pns_subscribed.has_key(context):
         self.pns_subscribed[context].append(handler)
     else:
         self.pns_subscribed[context] = [handler]
     self.pns_send(netstring.encode((context, '', ip, context)))
예제 #14
0
 def pns_subscribe(self, context, handler):
     "subscribe to a context and log its statements"
     if self.pns_subscribed.has_key(context):
         self.pns_subscribed[context].append(handler)
     else:
         self.pns_subscribed[context] = [handler]
         self.pns_send(netstring.encode((context, '', '', context)))
예제 #15
0
 def pns_quit(self, context, handler):
     "quit a context, unsubscribe to its log"
     if self.pns_subscribed.has_key(context):
         self.pns_subscribed[context].remove(handler)
         if len(self.pns_subscribed[context]) == 0:
             del self.pns_subscribed[context]
             self.pns_send(netstring.encode(('', '', '', context)))
예제 #16
0
    def pns_signal(self, resolved, model):
        "the default resolution handler"
        assert None == self.log(netstring.encode(model))
        if model[4] == '_' or model[4].startswith('.'):
            return False

        return True
예제 #17
0
    def pns_walk_simple(self, model, contexts, walked, routes, names):
        assert None == self.select_trigger_log(
            '<walk-simple horizon="%d" walked="%d"/>'
            '<![CDATA[%s]]!>' %
            (len(names), len(walked), netstring.encode(model)), 'debug')
        for name in names:
            if name in walked:
                continue

            walked.add(name)
            if name in contexts:
                routes.setdefault(name, set()).add(name)
            paths = self.pns_walk_down(name, contexts)
            if paths:
                routes.setdefault(name, set()).update(paths)
            if len(walked) >= self.pns_horizon:
                # horizon reached, walk out
                self.pns_walk_out(model, routes)
                return

        names = self.pns_walk_up(names, walked)
        if len(names) == 0:
            # no more index to walk, walk out
            self.pns_walk_out(model, routes)
            return

        names = [r[1] for r in pns_weight_names(names)]
        self.thread_loop_queue(
            (self.pns_walk_simple, (model, contexts, walked, routes,
                                    names)))  # >>> do another simple step
예제 #18
0
        def pns_statement(model):
            model, error = pns_model.pns_triple(model)
            if error:
                loginfo.log(netstring.encode(model), error)
                return False

            channel.pns_statement(tuple(model[:3]), model[3])
            return True
예제 #19
0
	def pns_anonymous (self, model):
		# anonymous question, resolve in all contexts.
                sp = netstring.encode (model[:2])
                stored = self.pns_statements.get (sp)
                if stored != None:
	          	bounce = model[:5]
	          	bounce[2] = netstring.encode ([
				netstring.encode (i) 
				for i in cPickle.loads (stored).items ()
				])
			self.select_trigger ((
				self.pns_peer.pns_tcp_continue,
				(bounce, '_')
				))
		self.select_trigger ((
			self.pns_peer.pns_tcp_continue, (model, '.')
			))
예제 #20
0
def xml_utf8_name (element, dom):
        # articulate a context's name one from its children's name(s)
        field = set ()
        return pns_model.pns_name (netstring.encode ((
                child.pns_name 
                for child in element.xml_children 
                if child.pns_name
                )), field)
예제 #21
0
def xml_utf8_to_pns(e):
    "XML/PNS - articulate an UTF-8 XML element as 8-bit byte strings"
    if e.xml_attributes:
        yield netstring.encode(
            (netstring.encode(item) for item in e.xml_attributes.items()))
    else:
        yield ''

    yield e.xml_first

    if e.xml_children:
        yield netstring.encode((netstring.encode(
            (child.pns_name, child.xml_name)) for child in e.xml_children))

    else:
        yield ''

    yield e.xml_follow or ''
예제 #22
0
 def xml_to_pns_continue(self, resolved, model):
     # handle all XML to PNS responses,
     assert None == loginfo.log(netstring.encode(model))
     if self.pns_resolved == resolved:
         pass
         # this is the end, at least if the PNS peer does
         # handle each of the statement in sequence, not
         # answering the last one before the others.
     return False
예제 #23
0
 def xml_to_pns_continue (self, resolved, model):
         # handle all XML to PNS responses, 
         assert None == loginfo.log (netstring.encode (model))
         if self.pns_resolved == resolved:
                 pass 
                 # this is the end, at least if the PNS peer does
                 # handle each of the statement in sequence, not
                 # answering the last one before the others.
         return False
예제 #24
0
 def pns_walk_out(self, model, routes):
     # continue the commands, drop the statements
     routes = pns_weight_routes(routes)
     assert None == self.select_trigger_log(
         '<walk-out routes="%d"/>'
         '<![CDATA[%s]]!><![CDATA[%s]]!>' %
         (len(routes), netstring.encode(model),
          encode(netunicode.encode([r[1] for r in routes]), 'UTF-8')), '')
     self.select_trigger((self.pns_walk_continue, (model, routes)))
예제 #25
0
 def pns_quit (self, context, handler):
         "quit a context, unsubscribe to its log"
         if self.pns_subscribed.has_key (context):
                 self.pns_subscribed[context].remove (handler)
                 if len (self.pns_subscribed[context]) == 0:
                         del self.pns_subscribed[context]
                         self.pns_send (netstring.encode ((
                                 '', '', '', context
                                 )))
예제 #26
0
 def pns_join (self, context, ip, handler):
         "join a context at ip and subscribe the handler to its log"
         if self.pns_subscribed.has_key (context):
                 self.pns_subscribed[context].append (handler)
         else:
                 self.pns_subscribed[context] = [handler]
         self.pns_send (netstring.encode ((
                 context, '', ip, context
                 )))
예제 #27
0
 def pns_subscribe (self, context, handler):
         "subscribe to a context and log its statements"
         if self.pns_subscribed.has_key (context):
                 self.pns_subscribed[context].append (handler)
         else:
                 self.pns_subscribed[context] = [handler]
                 self.pns_send (netstring.encode ((
                         context, '', '', context
                         )))
예제 #28
0
 def pns_statement (model):
         model, error = pns_model.pns_triple (model)
         if error:
                 loginfo.log (netstring.encode (model), error)
                 return False
         
         channel.pns_statement (
                 tuple (model[:3]), model[3]
                 )
         return True
예제 #29
0
def xml_utf8_root (element, dom):
        xml_utf8_context (element, dom)
        dom.pns_statement ((
                element.pns_name or dom.pns_name,
                element.xml_name,
                netstring.encode (
                        xml_utf8_to_pns (element)
                        ),
                dom.pns_name
                ))
예제 #30
0
 def __repr__ (self):
         "return a safe netstring representation of the deque"
         r = []
         try:
                 self.cv.acquire ()
                 l = len (self.deque)
                 for item in self.deque:
                         try:
                                 r.append ('%r' % (item,))
                         except:
                                 r.append (
                                         'item id="%x"' % id (item)
                                         )
         finally:
                 self.cv.release ()
         return netstring.encode ((
                 'protected_deque queued="%d"' % l,
                 netstring.encode (r)
                 ))
예제 #31
0
 def loginfo_netlines(self, data, info=None):
     "log netoutlines to STDOUT, a category handler or STDERR"
     assert type(data) == str
     if info == None:
         self.loginfo_stdout(netstring.netlines(data))
     elif self.loginfo_categories.has_key(info):
         self.loginfo_categories[info](netstring.netlines(data))
     else:
         assert type(info) == str
         self.loginfo_stderr(
             netstring.netlines(netstring.encode((info, data))))
예제 #32
0
 def loginfo_netstrings(self, data, info=None):
     "log netstrings to STDOUT, a category handler or STDERR"
     assert type(data) == str
     if info == None:
         self.loginfo_stdout('%d:%s,' % (len(data), data))
     elif self.loginfo_categories.has_key(info):
         self.loginfo_categories[info]('%d:%s,' % (len(data), data))
     else:
         assert type(info) == str
         encoded = netstring.encode((info, data))
         self.loginfo_stderr('%d:%s,' % (len(encoded), encoded))
예제 #33
0
 def pns_signal (self, resolved, model):
         # dump a netstring to STDOUT
         loginfo.log (netstring.encode (model))
         # waits for the echo to finalize and articulate the
         # next statement, nicely as the peer sends its echo
         if model[4].startswith ('.'):
                 self.pns_articulate ()
                 return False
 
         # _, ! or ? are simply dropped unless they occur
         # before ., ...
         return True
예제 #34
0
    def pns_signal(self, resolved, model):
        # dump a netstring to STDOUT
        loginfo.log(netstring.encode(model))
        # waits for the echo to finalize and articulate the
        # next statement, nicely as the peer sends its echo
        if model[4].startswith('.'):
            self.pns_articulate()
            return False

        # _, ! or ? are simply dropped unless they occur
        # before ., ...
        return True
예제 #35
0
	def pns_resolve (self, model):
		# store, retrieve and update, but also filter statements,
		# returns a tuple (persistent, stored), indicating wether
		# the statement is to be blocked and the object stored
		# previously if any.
		#
                sp = netstring.encode (model[:2])
                stored = self.pns_statements.get (sp)
                if stored == None:
                	# new (subject, predicate): log, store and pass
                	assert None == self.select_trigger_log (
                		netstring.encode (model), 'new'
                		)
                	self.pns_log (model)
			self.pns_statements [sp] = cPickle.dumps (
				{model[3]: model[2]}
				)
			return True, None

		# load the {(object, context)} hash from the store
		persistents = cPickle.loads (stored)
		o = persistents.get (model[3])
		if o == model[2]:
			# redundant contextual statement: block
                	assert None == self.select_trigger_log (
                		netstring.encode (model), 'block'
                		)
			return False, None
			
		if model[2] != '':
			# dissent: log, update answer and pass
                	assert None == self.select_trigger_log (
                		netstring.encode (model), 'update'
                		)
                	self.pns_log (model)
			persistents[model[3]] = model[2]
			self.pns_statements[sp] = cPickle.dumps (persistents)
		return True, o
예제 #36
0
 def pns_resolve (self, model, context, handler, handlers):
         "resolve a command or statement"
         handlers.append (handler or self.pns_signal)
         if len (handlers) == 1:
                 # send the statement if it is not redundant
                 encoded = netstring.encode (model)
                 if context:
                         encoded += '%d:%s,' % (len (context), context)
                 else:
                         encoded += '0:,'
                 self.pns_send (encoded)
                 return True
                 
         return False
예제 #37
0
        def http_continue (self, http):
                uri = http.request[1]
                try:
                        uri = list (HTTP_URI.match (uri).groups ())
                except:
                        uri = ['http://', http.collector_headers.get (
                                'host', self.presto_path
                                ), uri, '', '']
                else:
                        uri[0] = uri[0] or 'http://'
                        uri[1] = uri[1] or http.collector_headers.get (
                                'host', self.presto_path
                                )
                http.uri = uri
                about = uri[2].split ('/', 2)
                about[0] = uri[1]
                about = http.uri_about = tuple ((
                        unicode (urldecode (n), 'UTF-8') for n in about
                        ))
                try:
                        # context, subject and maybe predicate 
                        # || http://host/folder || http://host/folder/file
                        controller = self.presto_cached[about] 
                except:
                        if len (about) > 2:
                                about = (about[0], about[1])
                        else:
                                about = (about[0],)
                        try:
                                # context and subject || http://host/folder
                                controller = self.presto_cached[about] 
                        except:
                                controller = http_404_close

                try:
                        stalled = controller (http, about)
                except:
                        self.loginfo_traceback ()
                        http (500)
                        stalled = False
                try:
                        digest = http.irtd2[4]
                except:
                        digest = '%x' % id (http)
                loginfo.log (str (netstring.encode ((
                        ' '.join (http.request),
                        ''.join (uri[:3]),
                        digest
                        ))), '%d' % http.response)
                return stalled
예제 #38
0
	def loginfo_netlines (self, data, info=None):
		"log netoutlines to STDOUT, a category handler or STDERR"
                assert type (data) == str
		if info == None:
			self.loginfo_stdout (netstring.netlines (data))
		elif self.loginfo_categories.has_key (info):
			self.loginfo_categories[info] (
				netstring.netlines (data)
				)
		else:
			assert type (info) == str
			self.loginfo_stderr (netstring.netlines (
				netstring.encode ((info, data))
				))
예제 #39
0
    def pns_resolve(self, model, context, handler, handlers):
        "resolve a command or statement"
        handlers.append(handler or self.pns_signal)
        if len(handlers) == 1:
            # send the statement if it is not redundant
            encoded = netstring.encode(model)
            if context:
                encoded += '%d:%s,' % (len(context), context)
            else:
                encoded += '0:,'
            self.pns_send(encoded)
            return True

        return False
예제 #40
0
    def http_continue(self, http):
        uri = http.request[1]
        try:
            uri = list(HTTP_URI.match(uri).groups())
        except:
            uri = [
                'http://',
                http.collector_headers.get('host', self.presto_path), uri, '',
                ''
            ]
        else:
            uri[0] = uri[0] or 'http://'
            uri[1] = uri[1] or http.collector_headers.get(
                'host', self.presto_path)
        http.uri = uri
        about = uri[2].split('/', 2)
        about[0] = uri[1]
        about = http.uri_about = tuple(
            (unicode(urldecode(n), 'UTF-8') for n in about))
        try:
            # context, subject and maybe predicate
            # || http://host/folder || http://host/folder/file
            controller = self.presto_cached[about]
        except:
            if len(about) > 2:
                about = (about[0], about[1])
            else:
                about = (about[0], )
            try:
                # context and subject || http://host/folder
                controller = self.presto_cached[about]
            except:
                controller = http_404_close

        try:
            stalled = controller(http, about)
        except:
            self.loginfo_traceback()
            http(500)
            stalled = False
        try:
            digest = http.irtd2[4]
        except:
            digest = '%x' % id(http)
        loginfo.log(
            str(
                netstring.encode(
                    (' '.join(http.request), ''.join(uri[:3]), digest))),
            '%d' % http.response)
        return stalled
예제 #41
0
	def loginfo_netstrings (self, data, info=None):
		"log netstrings to STDOUT, a category handler or STDERR"
                assert type (data) == str
		if info == None:
			self.loginfo_stdout ('%d:%s,' % (len (data), data))
		elif self.loginfo_categories.has_key (info):
			self.loginfo_categories[info] (
				'%d:%s,' % (len (data), data)
				)
		else:
                        assert type (info) == str
			encoded = netstring.encode ((info, data))
			self.loginfo_stderr (
				'%d:%s,' % (len (encoded), encoded)
				)
예제 #42
0
def xml_utf8_to_pns (e):
        "XML/PNS - articulate an UTF-8 XML element as 8-bit byte strings"
        if e.xml_attributes:
                yield netstring.encode ((
                        netstring.encode (item) 
                        for item in e.xml_attributes.items ()
                        ))
        else:
                yield ''
                        
        yield e.xml_first

        if e.xml_children:
                yield netstring.encode ((
                        netstring.encode ((
                                child.pns_name, child.xml_name
                                ))
                        for child in e.xml_children
                        ))
        
        else:
                yield ''
                        
        yield e.xml_follow or ''
예제 #43
0
 def xml_unicode_to_pns(self, element, context):
     try:
         pns = element.xml_attributes.pop(u'pns')
     except:
         element.pns_name = ''
         subject = context
     else:
         element.pns_name = subject = pns.encode('utf-8')
     if element.xml_children:
         for child in element.xml_children:
             self.xml_unicode_to_pns(child, subject)
     self.pns_statement((subject, element.xml_name.encode('utf-8'),
                         netstring.encode(xml_unicode_to_pns(element))),
                        context, self.xml_to_pns_continue)
     if subject != context:
         element.xml_attributes[u'pns'] = pns
예제 #44
0
 def pns_walk_out (self, model, routes):
         # continue the commands, drop the statements
         routes = pns_weight_routes (routes)
         assert None == self.select_trigger_log (
                 '<walk-out routes="%d"/>'
                 '<![CDATA[%s]]!><![CDATA[%s]]!>' % (
                         len (routes),
                         netstring.encode (model),
                         encode (netunicode.encode (
                                 [r[1] for r in routes]
                                 ), 'UTF-8')
                         ), ''
                 )
         self.select_trigger ((
                 self.pns_walk_continue, (model, routes)
                 ))
예제 #45
0
 def xml_utf8_to_pns (self, element, context):
         try:
                 element.pns_name = subject = \
                         element.xml_attributes.pop ('pns')
         except:
                 element.pns_name = ''
                 subject = context
         if element.xml_children:
                 for child in element.xml_children:
                         self.xml_utf8_to_pns (child, subject)
         self.pns_statement ((
                 subject, element.xml_name,
                 netstring.encode (xml_utf8_to_pns (element)),
                 ), context, self.xml_to_pns_continue)
         if subject != context:
                 element.xml_attributes['pns'] = subject
예제 #46
0
 def xml_utf8_to_pns(self, element, context):
     try:
         element.pns_name = subject = \
                 element.xml_attributes.pop ('pns')
     except:
         element.pns_name = ''
         subject = context
     if element.xml_children:
         for child in element.xml_children:
             self.xml_utf8_to_pns(child, subject)
     self.pns_statement((
         subject,
         element.xml_name,
         netstring.encode(xml_utf8_to_pns(element)),
     ), context, self.xml_to_pns_continue)
     if subject != context:
         element.xml_attributes['pns'] = subject
예제 #47
0
 def xml_unicode_to_pns (self, element, context):
         try:
                 pns = element.xml_attributes.pop (u'pns')
         except:
                 element.pns_name = ''
                 subject = context
         else:
                 element.pns_name = subject = pns.encode ('utf-8')
         if element.xml_children:
                 for child in element.xml_children:
                         self.xml_unicode_to_pns (child, subject)
         self.pns_statement ((
                 subject, element.xml_name.encode ('utf-8'),
                 netstring.encode (xml_unicode_to_pns (element))
                 ), context, self.xml_to_pns_continue)
         if subject != context:
                 element.xml_attributes[u'pns'] = pns
예제 #48
0
def xml_utf8_context(element, dom):
    if not element.xml_children:
        return

    context = element.pns_name or dom.pns_name
    for child in element.xml_children:
        # A PNS/XML statement with the same context and subject is a
        # leaf. All other are branches, that have their parent's name
        # has contexts but not as subject.
        #
        dom.pns_statement((child.pns_name or context, child.xml_name,
                           netstring.encode(xml_utf8_to_pns(child)), context))
        child.xml_children = None  # drop articulated children now!
        # articulate the child SATs in this element's context
        for articulated in child.pns_sat_articulated:
            if not dom.pns_statement(
                (articulated[2], 'sat', articulated[3], context)):
                break
예제 #49
0
	def run (self):
                """The Thread Loop
                
                If thread_loop_init() is True call queued instance until
                None is popped or and exception is raised and not catched
                by thread_loop_throw. Finally, if thread_loop_delete() is
                True, trunk the thread loop queue.
                """
		if self.thread_loop_init ():
                        next = self.thread_loop_queue.popleft # ? maybe safer
			while True:
				queued = next () # ... sure faster
				if queued == None:
					break

				try:
				        queued[0] (*queued[1])
				except:
					if self.thread_loop_throw ():
                                                del queued
                                                break
                                        
                                else:
                                        del queued
                        #
                        # note that I make sure to delete the tuple which
                        # would otherwise hold a reference to the method and
                        # arguments of the call threaded, preventing garbage
                        # collection hence finalization and was the source
                        # of subtle bugs ...
                        #
		if self.thread_loop_delete ():
                        trunked = self.thread_loop_queue.trunk ()
                        if trunked:
                                assert None == self.select_trigger_log (
                                        netstring.encode ([
                                                '%r' % (i,) for i in trunked
                                                ]), 'debug'
                                        )
예제 #50
0
    def pns_command(self, model):
        # handle a command from a PNS/TCP session
        assert None == self.log(netstring.encode(model), 'command')
        if model[1]:
            if model[2]:
                # walk subject down to contexts, let the user
                # agent walk the graph up and down at once to
                # test and weight a subject against a set of
                # contexts (and not implement that common walk
                # into the client, but rather articulate it).
                #
                contexts = set(netunicode.decode(unicode(model[2], 'UTF-8')))
                self.thread_loop_queue(
                    (self.pns_walk_simplest, (model, contexts)))
                return

            # walk down the contexts once, in all contexts
            self.thread_loop_queue((self.pns_command_predicate, (model, )))
            return

        # walk up the names once, for in contexts
        self.thread_loop_queue((self.pns_command_object, (model, )))
예제 #51
0
def xml_utf8_context (element, dom):
        if not element.xml_children:
                return
        
        context = element.pns_name or dom.pns_name
        for child in element.xml_children:
                # A PNS/XML statement with the same context and subject is a
                # leaf. All other are branches, that have their parent's name
                # has contexts but not as subject.
                #
                dom.pns_statement ((
                        child.pns_name or context,
                        child.xml_name,
                        netstring.encode (xml_utf8_to_pns (child)),
                        context
                        ))
                child.xml_children = None # drop articulated children now!
                # articulate the child SATs in this element's context
                for articulated in child.pns_sat_articulated:
                        if not dom.pns_statement ((
                                articulated[2], 'sat', articulated[3], context
                                )):
                                break
예제 #52
0
def pns_name(encoded, horizon, HORIZON=126):
    # Recursively validate a Public Name, returns the empty string if
    # the name encoded is invalid or inside the horizon. This function
    # does more than just assert that the encoded 8-bit byte string is
    # a valid public name: it transform it to a valid public name.
    #
    # try to decode the articulated public names
    names = [n for n in netstring.decode(encoded) if n]
    if not names:
        if encoded not in horizon and pns_name_clean(encoded):
            # clean name new in this horizon
            horizon.add(encoded)
            return encoded

        # unsafe 8-bit byte string or Public Name in the in horizon
        return ''

    # articulated Public Names
    valid = []
    for name in names:
        # recursively validate each articulated name in this horizon
        name = pns_name(name, horizon, HORIZON)
        if name:
            valid.append(name)
            if len(horizon) >= HORIZON:
                break  # but only under this HORIZON

    if len(valid) > 1:
        # sort Public Names and encode
        valid.sort()
        return netstring.encode(valid)

    if len(valid) > 0:
        # return a "singleton"
        return valid[0]

    return ''  # nothing valid to articulate in this horizon
예제 #53
0
def pns_name (encoded, horizon, HORIZON=126):
        # Recursively validate a Public Name, returns the empty string if
        # the name encoded is invalid or inside the horizon. This function
        # does more than just assert that the encoded 8-bit byte string is
        # a valid public name: it transform it to a valid public name.
        #
        # try to decode the articulated public names
        names = [n for n in netstring.decode (encoded) if n]
        if not names:
                if encoded not in horizon and pns_name_clean (encoded):
                        # clean name new in this horizon
                        horizon.add (encoded)
                        return encoded
                        
                # unsafe 8-bit byte string or Public Name in the in horizon
                return ''

        # articulated Public Names
        valid = []
        for name in names:
                # recursively validate each articulated name in this horizon
                name = pns_name (name, horizon, HORIZON)
                if name:
                        valid.append (name)
                        if len (horizon) >= HORIZON:
                                break # but only under this HORIZON
                                
        if len (valid) > 1:
                # sort Public Names and encode
                valid.sort ()
                return netstring.encode (valid)
                
        if len (valid) > 0:
                # return a "singleton"
                return valid[0]
                
        return '' # nothing valid to articulate in this horizon
예제 #54
0
    def run(self):
        """The Thread Loop
                
                If thread_loop_init() is True call queued instance until
                None is popped or and exception is raised and not catched
                by thread_loop_throw. Finally, if thread_loop_delete() is
                True, trunk the thread loop queue.
                """
        if self.thread_loop_init():
            next = self.thread_loop_queue.popleft  # ? maybe safer
            while True:
                queued = next()  # ... sure faster
                if queued == None:
                    break

                try:
                    queued[0](*queued[1])
                except:
                    if self.thread_loop_throw():
                        del queued
                        break

                else:
                    del queued
            #
            # note that I make sure to delete the tuple which
            # would otherwise hold a reference to the method and
            # arguments of the call threaded, preventing garbage
            # collection hence finalization and was the source
            # of subtle bugs ...
            #
        if self.thread_loop_delete():
            trunked = self.thread_loop_queue.trunk()
            if trunked:
                assert None == self.select_trigger_log(
                    netstring.encode(['%r' % (i, ) for i in trunked]), 'debug')
예제 #55
0
	def pns_statement (self, model):
		# handle PNS/TCP statements either directly from persistence
		# or not-relayed original statements
		sp = netstring.encode (model[:2])
		o = self.pns_buffer.get (sp)
		if o != None:
			# buffered statement, TODO: drop or buffer?
			model[2] = o
			return
			
		# not buffered, echo to all subscribers, set timeout and buffer
		self.pns_tcp_continue (model[:4], '.')
		self.pns_peer.pns_udp.timeouts_push (
			(self.pns_right or self.pns_name, sp)
			)
		self.pns_buffer[sp] = model[2]
		if self.pns_left and self.pns_right:
			# joined: record as stated, index and relay
			self.pns_peer.pns_inference.pns_map (model)
			self.pns_statements[sp] = model[2]
			if model[2]:
				# answer right
				self.pns_sendto_right ('%s%d:%s,' % (
					sp, len (model[2]), model[2]
					), self.pns_right)
				return
					
			# question left
			self.sendto (sp, (self.pns_left, 3534))
			return
				
		# not relayed
		if model[3] == self.pns_name:
			# route named statements that cannot be relayed
			self.pns_peer.pns_inference.pns_statement (model[:4])
			return
예제 #56
0
def classic_traceback(ctb=None):
    return netstring.encode((netstring.encode([
        'File "%s", line %s, in %s' % (tb[0] or '<string>', tb[2], tb[1])
        for tb in ctb[2]
    ]), '%s: %s' % ctb[:2])), 'Traceback (most recent call last):'
예제 #57
0
def compact_traceback(ctb):
    "encode a compact traceback tuple as netstrings"
    return netstring.encode(
        (ctb[0], netstring.encode([' | '.join(x)
                                   for x in ctb[2]]), ctb[1])), 'traceback'
예제 #58
0
    def loginfo_log(self, data, info=None):
        """log a message with this instance's __repr__ and an 
		optional category"""
        self.loginfo_logger.log(netstring.encode(('%r' % self, '%s' % data)),
                                info)