Last active
December 21, 2015 05:49
-
-
Save maxdeliso/6259538 to your computer and use it in GitHub Desktop.
PyPu
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#! /usr/bin/env python3.3 | |
# PyPu: Simple UDP chat. | |
import logging | |
import curses | |
import curses.ascii | |
from socketserver import UDPServer | |
from socketserver import BaseRequestHandler | |
class PuChat(UDPServer): | |
# module constants | |
PU_MAJOR_VER = 0 | |
PU_MINOR_VER = 1 | |
PU_HOST = "" | |
PU_PORT = 1337 | |
PU_POLL = 0.1 | |
def __init__(self): | |
# chain call UDPServer constructor with nested class for handler | |
super(PuChat, self).__init__((self.PU_HOST, self.PU_PORT), self.PuHandler) | |
# configure logger output to file | |
logging.basicConfig(filename='pupu.log',level=logging.DEBUG) | |
# print version info | |
logging.info(sys.version + '\nPU_VER: {}.{}'.format( | |
self.PU_MAJOR_VER, self.PU_MINOR_VER)) | |
# only wait for this many seconds | |
self.timeout = self.PU_POLL | |
# log | |
logging.info("starting UDP server on port: {}". | |
format(self.PU_PORT)) | |
# initialize terminal and make it non-blocking | |
self.win = curses.initscr() | |
self.win.nodelay(1) | |
TERM_HEIGHT, TERM_WIDTH = self.win.getmaxyx() | |
logging.info("initialized terminal with dimensions {} by {}". | |
format(TERM_WIDTH, TERM_HEIGHT)) | |
assert TERM_HEIGHT > 4 | |
self.netWin = self.win.subwin(TERM_HEIGHT - 3, TERM_WIDTH - 2, 1, 1) | |
self.netWin.idlok(True) | |
self.netWin.scrollok(True) | |
self.localWin = self.win.subwin(1, TERM_WIDTH - 2, TERM_HEIGHT - 2, 1) | |
curses.noecho() | |
curses.nonl() | |
def __loop(self): | |
""" main i/o loop """ | |
while True: | |
self.handle_request() | |
userCh = self.win.getch() | |
if(userCh != -1 and curses.ascii.isalnum(userCh)): | |
self.localWin.addch(userCh) | |
self.localWin.refresh() | |
# TODO: handle sending and clearing localWin | |
def start(self): | |
""" initiate i/o loop and clean-up gracefully afterwards """ | |
logging.info("entering main loop") | |
try: | |
self.__loop() | |
except KeyboardInterrupt: | |
self.win.addstr('shutting down...') | |
finally: | |
curses.endwin() | |
logging.info("exiting main loop") | |
class PuHandler(BaseRequestHandler): | |
""" class to deal with UDP messages. poll driven """ | |
def handle(self): | |
# alias into locals | |
msgData = self.request[0] | |
peerSocket = self.request[1] | |
peerAddress = self.client_address[0] | |
win = self.server.netWin | |
logging.info("received {} bytes from sender: {}".format( | |
len(msgData), peerAddress)) | |
# print out the received message and its origin | |
win.addstr("{} >> {}\n".format(peerAddress, msgData)) | |
win.refresh() | |
# echo received message back to sender over UDP | |
peerSocket.sendto(msgData, self.client_address) | |
if __name__ == "__main__": | |
import sys | |
chat = PuChat() | |
chat.start() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment