root/trunk/RBJabber/RBJabber/JabberObserver.py

Revision 528, 5.6 kB (checked in by sholloway, 5 years ago)

Depreciating WeakBind?, LazyProperty?
General cleanup tasks
Demo cleanups

Line 
1 #!/usr/bin/env python
2 ##~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
3 ##~ License
4 ##~
5 ##- The RuneBlade Foundation library is intended to ease some
6 ##- aspects of writing intricate Jabber, XML, and User Interface (wxPython, etc.)
7 ##- applications, while providing the flexibility to modularly change the
8 ##- architecture. Enjoy.
9 ##~
10 ##~ Copyright (C) 2002  TechGame Networks, LLC.
11 ##~
12 ##~ This library is free software; you can redistribute it and/or
13 ##~ modify it under the terms of the BSD style License as found in the
14 ##~ LICENSE file included with this distribution.
15 ##~
16 ##~ TechGame Networks, LLC can be reached at:
17 ##~ 3578 E. Hartsel Drive #211
18 ##~ Colorado Springs, Colorado, USA, 80920
19 ##~
20 ##~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
21
22 #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
23 #~ Imports
24 #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
25
26 from RBFoundation.BindCallable import BoundCallable, BindCallable
27 import JID
28
29 #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
30 #~ Definitions
31 #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
32
33 class _MatchBase(object):
34     Negate = 0
35     def __call__(self, value):
36         if self.Negate:
37             return not self.MatchValue(value)
38         else: return self.MatchValue(value)
39
40 class MatchAnd(list, _MatchBase):
41     def MatchValue(self, value):
42         for each in self:
43             if not each(value): return 0
44         else: return len(self) and 1 or 0
45 MatchAll = MatchAnd
46    
47 class MatchOr(list, _MatchBase):
48     def MatchValue(self, value):
49         for each in self:
50             if each(value): return 1
51         else: return 0
52 MatchOne = MatchOr
53
54 class MatchNone(list, _MatchBase):
55     def MatchValue(self, value):
56         for each in self:
57             if each(value): return 0
58         else: return 1
59    
60 class MatchAttributesRE(_MatchBase):
61     def __init__(self, **attributes):
62         import re
63         self._MatchInfo = {}
64         for key, value in attributes.iteritems():
65             self._MatchInfo[key] = re.compile(value).match
66
67     def MatchValue(self, value):
68         for key, match in self._MatchInfo.iteritems():
69             value = getattr(value, key, None)
70             if value is None:
71                 return 0
72             elif not match(value):
73                 return 0
74         else: return 1
75
76 class MatchAttributes(_MatchBase):
77     def __init__(self, **attributes):
78         self._MatchInfo = attributes
79
80     def MatchValue(self, value):
81         for key, compareto in self._MatchInfo.iteritems():
82             if isinstance(compareto, JID.JID):
83                 if getattr(value, key, None) not in compareto:
84                     return 0
85             elif compareto != getattr(value, key, None):
86                 return 0
87         else: return 1
88
89 class MatchHasAttribute(_MatchBase):
90     def __init__(self, name):
91         self._MatchInfo = name
92        
93     def MatchValue(self, value):
94         return hasattr(value, self._MatchInfo)
95
96 class MatchHasNode(_MatchBase):
97     def __init__(self, namespace, node):
98         self._MatchInfo = (namespace, node)
99        
100     def MatchValue(self, value):
101         for each in value._elements:
102             if each[0] == self._MatchInfo: return 1
103         else: return 0
104
105 class MatchHasChildNode(_MatchBase):
106     def __init__(self, node):
107         self._MatchInfo = node
108        
109     def MatchValue(self, value):
110         for each in value._elements:
111             if each[0][-1] == self._MatchInfo: return 1
112         else: return 0
113
114 class MatchHasChildNamespace(_MatchBase):
115     def __init__(self, namespace):
116         self._MatchInfo = namespace
117        
118     def MatchValue(self, value):
119         for each in value._elements:
120             if each[0][0] == self._MatchInfo: return 1
121         else: return 0
122
123 #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
124
125 class JabberObserver(BoundCallable):
126     _debug = 0
127     def __init__(self, callback=None, Match=None, BidValue=1):
128         super(JabberObserver, self).__init__(callback)
129         self.BidValue = BidValue
130         self.Match = Match or MatchAnd()
131
132     def AddRule(self, rule, Negate=0):
133         rule.Negate = Negate
134         self.Match.append(rule)
135
136     def Bid(self, subject, **UpdateDict):
137         for value in UpdateDict.itervalues():
138             if self.Match(value):
139                 return self.BidValue
140             elif self._debug:
141                 print "!!! No Match !!!"
142                 for each in self.Match:
143                     print each(value), '==', each.__class__.__name__
144
145
146 #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
147 #~ Testing
148 #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
149
150 def _Test_():
151     from RBFoundation.XMLObjectify import Objectify
152     from SubjectObserver.BidableSubject import BidableSubject
153     def TestTrue(subject, obj): assert obj.__namespace__ == 'testing' and (obj.__node__ == 'tag' or (obj.myattr.find('haps') >= 0))
154     def TestFalse(subject, obj): assert 0
155     obj = Objectify('''<test xmlns='testing' myattr='perhaps'><tag attr='1' /> <tag /></test>''')
156     subject = BidableSubject()
157     observer = JabberObserver(TestTrue, MatchHasNode('testing', 'tag'))
158     subject.AddObserver(observer)
159     observer = JabberObserver(TestFalse, MatchHasNode('testing', 'tango'))
160     subject.AddObserver(observer)
161     observer = JabberObserver(TestTrue, MatchAttributes(myattr = '.*haps.*'))
162     subject.AddObserver(observer)
163     observer = JabberObserver(TestTrue)
164     observer.Match.append(MatchHasNode('testing', 'tag'))
165     observer.Match.append(MatchAttributes(myattr='.*haps.*'))
166     subject.AddObserver(observer)
167
168     subject.UpdateObservers(obj=obj)
169
170 #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
171
172 if __name__=='__main__':
173     print "Testing..."
174     _Test_()
175     print "Test complete."
176
177
Note: See TracBrowser for help on using the browser.