"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]