"Fossies" - the Fresh Open Source Software Archive 
Member "pyzor-1.0.0/pyzor/message.py" (10 Dec 2014, 4023 Bytes) of package /linux/privat/pyzor-1.0.0.tar.gz:
As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) Python source code syntax highlighting (style:
standard) with prefixed line numbers.
Alternatively you can here
view or
download the uninterpreted source code file.
For more information about "message.py" see the
Fossies "Dox" file reference documentation.
1 """This modules contains the various messages used in the pyzor client server
2 communication.
3 """
4
5 import random
6 import email.message
7
8 import pyzor
9
10
11 class Message(email.message.Message):
12 def __init__(self):
13 email.message.Message.__init__(self)
14 self.setup()
15
16 def setup(self):
17 pass
18
19 def init_for_sending(self):
20 self.ensure_complete()
21
22 def __str__(self):
23 # The parent class adds the unix From header.
24 return self.as_string()
25
26 def ensure_complete(self):
27 pass
28
29
30 class ThreadedMessage(Message):
31 def init_for_sending(self):
32 if 'Thread' not in self:
33 self.set_thread(ThreadId.generate())
34 assert 'Thread' in self
35 self["PV"] = str(pyzor.proto_version)
36 Message.init_for_sending(self)
37
38 def ensure_complete(self):
39 if 'PV' not in self or 'Thread' not in self:
40 raise pyzor.IncompleteMessageError("Doesn't have fields for a "
41 "ThreadedMessage.")
42 Message.ensure_complete(self)
43
44 def get_protocol_version(self):
45 return float(self['PV'])
46
47 def get_thread(self):
48 return ThreadId(self['Thread'])
49
50 def set_thread(self, i):
51 self['Thread'] = str(i)
52
53
54 class Response(ThreadedMessage):
55 ok_code = 200
56
57 def ensure_complete(self):
58 if 'Code' not in self or 'Diag' not in self:
59 raise pyzor.IncompleteMessageError("doesn't have fields for a "
60 "Response")
61 ThreadedMessage.ensure_complete(self)
62
63 def is_ok(self):
64 return self.get_code() == self.ok_code
65
66 def get_code(self):
67 return int(self['Code'])
68
69 def get_diag(self):
70 return self['Diag']
71
72 def head_tuple(self):
73 return self.get_code(), self.get_diag()
74
75
76 class Request(ThreadedMessage):
77 """This is the class that should be used to read in Requests of any type.
78 Subclasses are responsible for setting 'Op' if they are generating a
79 message,"""
80
81 def get_op(self):
82 return self['Op']
83
84 def ensure_complete(self):
85 if 'Op' not in self:
86 raise pyzor.IncompleteMessageError("doesn't have fields for a "
87 "Request")
88 ThreadedMessage.ensure_complete(self)
89
90
91 class ClientSideRequest(Request):
92 op = None
93
94 def setup(self):
95 Request.setup(self)
96 self["Op"] = self.op
97
98
99 class SimpleDigestBasedRequest(ClientSideRequest):
100 def __init__(self, digest=None):
101 ClientSideRequest.__init__(self)
102 self.digest_count = 0
103 if digest:
104 self.add_digest(digest)
105
106 def add_digest(self, digest):
107 self.add_header("Op-Digest", digest)
108 self.digest_count += 1
109
110
111 class SimpleDigestSpecBasedRequest(SimpleDigestBasedRequest):
112 def __init__(self, digest=None, spec=None):
113 SimpleDigestBasedRequest.__init__(self, digest)
114 if spec:
115 flat_spec = [item for sublist in spec for item in sublist]
116 self["Op-Spec"] = ",".join(str(part) for part in flat_spec)
117
118
119 class PingRequest(ClientSideRequest):
120 op = "ping"
121
122
123 class PongRequest(SimpleDigestBasedRequest):
124 op = "pong"
125
126
127 class CheckRequest(SimpleDigestBasedRequest):
128 op = "check"
129
130
131 class InfoRequest(SimpleDigestBasedRequest):
132 op = "info"
133
134
135 class ReportRequest(SimpleDigestSpecBasedRequest):
136 op = "report"
137
138
139 class WhitelistRequest(SimpleDigestSpecBasedRequest):
140 op = "whitelist"
141
142
143 class ThreadId(int):
144 # (0, 1024) is reserved
145 full_range = (0, 2 ** 16)
146 ok_range = (1024, full_range[1])
147 error_value = 0
148
149 def __new__(cls, i):
150 self = int.__new__(cls, i)
151 if not (cls.full_range[0] <= self < cls.full_range[1]):
152 raise ValueError("value outside of range")
153 return self
154
155 @classmethod
156 def generate(cls):
157 return cls(random.randrange(*cls.ok_range))
158
159 def in_ok_range(self):
160 return self.ok_range[0] <= self < self.ok_range[1]