def send(self, packet): released_lock = None if self.locked: if packet.locked == self.locked: tmp_debug("IO", "O => %s: %s" % (self.uid, deprotect(packet.packet))) try: self.socket.sendall(str(packet.packet)) except: self.disconnect() return None released_lock = self.locked if not self.keep_flow: self.locked = 0 else: # just discard, may be too old pass else: # on let events go if not packet.locked: tmp_debug("IO", "O => %s %s" % (self.uid, deprotect(packet.packet))) try: self.socket.sendall(str(packet.packet)) except: self.disconnect() else: # humm, why we get that ?? pass return released_lock
def handle_line(self): if self.socket: bytes = '' try: bytes = self.socket.recv(4096) except: pass if len(bytes) == 0: self.disconnect() self.buffer += bytes in_lines = self.buffer.split('\n') self.lines.extend([l + '\n' for l in in_lines[:-1]]) self.buffer = in_lines[-1] for line in self.lines: tmp_debug("IO", "%s => O: %s" % (self.uid, deprotect(line))) line = line.strip() # if locked, we are waiting for a result if not self.locked: if line.lower().startswith('action:'): self.action = \ Action(line[line.find(':') + 1:].strip()) elif line == '': if self.action: self.locked = bigtime() self.push(self.action) self.action = None else: if ':' in line: k = line.split(':')[0] v = line[line.find(':') + 1:].strip() if self.action: self.action.add_parameters({k: v}) self.lines = []
def push(self, packet): if packet.name.lower() in STARTING_EVENTS_KEYWORDS: self.keep_flow = True p = dict(emiter=self.id, locked=self.locked, timestamp=time(), packet=packet) tmp_debug("PACKET", "%s (L:%s, KF:%s) >> %s" % (self.uid, self.locked, self.keep_flow, deprotect(str(p)))) self.octopasty.in_queue.put(Packet(p))
def sendall(self): if not self.out_queue.empty(): outgoing = list(self.out_queue.queue) self.out_queue.queue.clear() for packet in outgoing: tmp_debug("PACKET", "%s << %s" % (packet.dest, deprotect(packet))) if packet.dest == '__internal__': handle_action(self, packet) else: dest = self.get_peer(packet.dest) if dest: # here is another place to check # and requeue if necessary if packet.locked != dest.locked and \ not dest.available: self.out_queue.put(packet) tmp_debug("SQUIRM", "Requeueing on output: %s" % \ deprotect(packet)) continue if not packet.locked and not dest.available: self.out_queue.put(packet) tmp_debug("SQUIRM", "Requeueing on output: %s" % \ deprotect(packet)) continue sent = dest.send(packet) if sent: if str(sent) in self.flow: keep_flow = dest.keep_flow if packet.packet.name.lower() in \ STOPPING_EVENTS_KEYWORDS: keep_flow = False dest.keep_flow = False dest.locked = 0 # then it was an answer if not keep_flow: self.flow.pop("%s" % sent) else: # then it was a query self.flow["%s" % sent] = packet.emiter else: # Then it was an event pass
def handle_line(self): if self.socket: bytes = '' try: bytes = self.socket.recv(4096) except: pass if len(bytes) == 0: self.disconnect() self.buffer += bytes in_lines = self.buffer.split('\n') self.lines.extend([l + '\n' for l in in_lines[:-1]]) self.buffer = in_lines[-1] for line in self.lines: tmp_debug("IO", "%s => O: L: %s D: %s" % ( self.uid, self.locked, deprotect(line))) line = line.strip() if line.startswith('Asterisk Call Manager'): self.login() self.lines = [] return if self.locked and line.lower().startswith('response:'): self.response = \ Response(line[line.find(':') + 1:].strip()) self.event = None elif line.lower().startswith('event:'): name = line[line.find(':') + 1:].strip() self.event = Event(name) self.response = None elif line == '': if self.response: self.push(self.response) self.response = None elif self.event: if self.keep_flow: self.push(self.event) else: self.push(self.event, locked=0) self.event = None else: if ':' in line: sc = line.find(':') k = line[:sc].strip() v = line[sc + 1:].strip() else: k = line v = None if self.response: self.response.add_parameters({k: v}) if self.event: self.event.add_parameters({k: v}) self.lines = []
def send(self, packet): if not self.locked: tmp_debug("IO", "O => %s: L: %s D: %s" % ( self.uid, packet.locked, deprotect(packet.packet))) self.socket.sendall(str(packet.packet)) if packet.packet.name.lower() in STARTING_EVENTS_KEYWORDS: self.keep_flow = True tmp_debug("PACKET", "%s Starting flow (L:%s)" % (self.uid, self.locked)) self.locked = packet.locked return self.locked else: return None
def push(self, packet, emiter=None, dest=None, locked=-1): p = dict(emiter=emiter or self.server, locked=locked == -1 and self.locked or locked, timestamp=time(), packet=packet) if dest: p['dest'] = dest tmp_debug("PACKET", "%s (L:%s, KF:%s) >> %s" % (self.uid, self.locked, self.keep_flow, deprotect(p))) self.octopasty.in_queue.put(Packet(p)) if packet.name.lower() in STOPPING_EVENTS_KEYWORDS: self.keep_flow = False tmp_debug("PACKET", "%s Stopping flow (L:%s)" % (self.uid, self.locked))
def squirm(self): apocalypse = time() - 10 if not self.in_queue.empty(): incoming = list(self.in_queue.queue) self.in_queue.queue.clear() for packet in incoming: tmp_debug("SQUIRM", "Processing packet %s" % deprotect(packet)) if packet.timestamp < apocalypse: # not puting in the queue and just continuing # makes the packet go nowhere # TODO: figure what to do here, i was thinking about something # if packet.locked: # dest = self.flow.get("%s" % packet.locked) # if dest != '__internal__': # peer = self.get_peer(dest) tmp_debug("SQUIRM", "Removing very old packet: %s" % packet) continue if packet.emiter == '__internal__': peer = self.get_peer(packet.dest) if peer and peer.available: self.out_queue.put(packet) else: self.in_queue.put(packet) else: if packet.locked: if packet.emiter in self.connected_servers: tmp_debug("SQUIRM", "Emiter is server %s" % \ packet.emiter) emiter = self.get_peer(packet.emiter) if emiter.locked and not emiter.keep_flow: emiter.locked = 0 tmp_debug("SQUIRM", "Unlocking emiter %s" % \ emiter.uid) dest = self.flow.get("%s" % packet.locked) if dest: if dest == '__internal__': handle_action(self, packet) else: peer = self.get_peer(dest) if peer and peer.logged: if peer.locked: if peer.locked == packet.locked: packet.dest = dest self.out_queue.put(packet) else: tmp_debug("SQUIRM", "Requeueing packet " \ "from server: %s" % \ deprotect(packet)) self.in_queue.put(packet) else: # just forgot it, and stop flow if any if emiter.keep_flow: emiter.keep_flow = 0 emiter.locked = 0 else: if emiter.keep_flow: emiter.keep_flow = 0 emiter.locked = 0 if packet.emiter in self.connected_clients: tmp_debug("SQUIRM", "Emiter is client %s" % \ packet.emiter) if packet.packet.name.lower() in KEEP_INTERNAL: handle_action(self, packet) continue client = self.get_peer(packet.emiter) if client.logged: cid = client.id.split('_')[0] cu = self.config['users'].get(cid) if cu: cs = client.binded_server if cs: peer = self.get_peer(cs) if peer and peer.logged: if peer.available: # server seems already available # but may be busy just after, # then we need to verify that # in outgoing packets too packet.dest = cs self.out_queue.put(packet) tmp_debug("SQUIRM", "Packet from client " \ "pushed to queue %s" % \ deprotect(packet)) else: # server seems busy self.in_queue.put(packet) tmp_debug("SQUIRM", "Requeueing packet from " " client: %s" % \ deprotect(packet)) else: response = Error( parameters=dict( Message='Server unavailable')) p = dict(emiter=cs, locked=packet.locked, timestamp=time(), packet=response, dest=client.id) self.out_queue.put(Packet(p)) else: if len(client.multiple_servers): response = Error( parameters=dict( Message='Cannot send command ' 'to multiple servers')) p = dict(emiter='__internal__', locked=packet.locked, timestamp=time(), packet=response, dest=client.id) self.out_queue.put(Packet(p)) else: packet.dest = '__internal__' self.out_queue.put(packet) else: # packet not locked if packet.emiter in self.connected_servers: # broadcast events ami = self.get_peer(packet.emiter) if ami.logged: for client in self.connected_clients: peer = self.get_peer(client) if peer.binded_server == packet.emiter or \ packet.emiter in peer.multiple_servers and \ peer.wants_events: p = copy(packet) p.dest = client self.out_queue.put(p) else: # Do not remove that comment and that case # it might be logged one day # ami not logged, and no command before # i wonder what can it be pass