daily pastebin goal
31%
SHARE
TWEET

Untitled

a guest Jan 14th, 2018 53 Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. #!/usr/bin/env python
  2. #-*- coding: utf-8 -*-
  3.  
  4. import socket
  5. import threading
  6.  
  7. class BadWordsServer:
  8.     """Represent a server which is designed to filter "bad words"
  9.        from data which is send to the network, and then resend
  10.        the cleaned data to the client."""
  11.  
  12.     def __init__(self, bad_words, host='127.0.0.1', port=8000):
  13.         """bad_words: words to ban
  14.            host: host to use for the server
  15.            port: port to use for the server"""
  16.  
  17.         self.bad_words = bad_words
  18.         self.bad_replace = ['*' * len(x) for x in bad_words]
  19.  
  20.         self.s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
  21.         self.s.bind((host, port))
  22.         self.s.listen(1)
  23.  
  24.     def serve(self, buf_size=1024, encoding='UTF-8'):
  25.         """Run the server. It can handle multiple connection concurrently.
  26.  
  27.            buf_size: size of the buffer to use for recieving data
  28.            encoding: encoding of input/output data"""
  29.  
  30.         while True:
  31.             conn, _ = self.s.accept()
  32.             threading.Thread(None, self.serve_one, None,\
  33.                              (conn, buf_size, encoding)).start()
  34.  
  35.     def serve_one(self, conn, buf_size=1024, encoding='UTF-8'):
  36.         """Serve only one connection. Close it recieve an empty data."""
  37.  
  38.         while True:
  39.             data = conn.recv(buf_size).decode(encoding)
  40.  
  41.             if not data:
  42.                 break
  43.  
  44.             print('Raw data:', data)
  45.             data = self.filter_bad_words(data)
  46.             print('Cleaned data:', data)
  47.             conn.send(bytes(data, encoding))
  48.  
  49.         conn.close()
  50.  
  51.     def filter_bad_words(self, data):
  52.         """Remove the "bad words" from data, and return the cleaned data."""
  53.  
  54.         for w, r in zip(self.bad_words, self.bad_replace):
  55.             data = data.replace(w, r)
  56.  
  57.         return data
  58.  
  59. class BadWordsClient:
  60.     """Represent a client which ask user for input, and which send that
  61.        data to a BadWordsServer for cleaning it. Once the client recieve
  62.        the cleaned data it prints it."""
  63.  
  64.     def __init__(self, host='127.0.0.1', port=8000):
  65.         """host: host of the server
  66.            port: port of the server"""
  67.  
  68.         self.s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
  69.         self.s.connect((host, port))
  70.  
  71.     def run(self, buf_size=1024, encoding='UTF-8'):
  72.         """Ask the user for data, clean it through the BadWordsServer,
  73.            and then print the result.
  74.  
  75.            buf_size: size of the buffer to use for recieving data
  76.            encoding: encoding of input/output data"""
  77.  
  78.         while True:
  79.             data = input('Data to filter? ')
  80.  
  81.             if not data:
  82.                 break
  83.  
  84.             self.s.send(bytes(data, encoding))
  85.  
  86.             data = self.s.recv(buf_size).decode(encoding)
  87.             print('Cleaned data:', data)
  88.  
  89.         self.s.close()
  90.  
  91. if __name__ == '__main__':
  92.     import sys
  93.  
  94.     def yes_no(prompt, default_yes=True):
  95.         """Ask the user for a yes/no question.
  96.  
  97.            prompt: the question to ask
  98.            default_yes: the default choice is yes if True no otherwise
  99.  
  100.            Return True for yes, False for no"""
  101.  
  102.         y, n = 'y', 'n'
  103.  
  104.         if default_yes:
  105.             y = y.upper()
  106.         else:
  107.             n = n.upper()
  108.  
  109.         i = None
  110.  
  111.         while i not in ['', 'y', 'n']:
  112.             i = input('%s (%c/%c)? ' % (prompt, y, n)).lower()
  113.  
  114.         if i == '':
  115.             return default_yes
  116.         elif i == 'y':
  117.             return True
  118.         else:
  119.             return False
  120.  
  121.     def get_host_port():
  122.         """Ask the user for an host and a port, and return them."""
  123.  
  124.         host = input('host? ')
  125.         port = None
  126.  
  127.         while port == None:
  128.             try:
  129.                 port = int(input('port? '))
  130.             except ValueError:
  131.                 print('port should be an integer.', file=sys.stderr)
  132.  
  133.         return host, port
  134.  
  135.     arg_error = 'This program takes exactly one argument serve or client.'
  136.  
  137.     if len(sys.argv) != 2:
  138.         print(arg_error, file=sys.stderr)
  139.     elif sys.argv[1] == 'serve':
  140.         bad_words = ['fuck', 'shit', 'dumb']
  141.  
  142.         if yes_no('Would you like to serve on localhost:8000'):
  143.             host, port = 'localhost', 8000
  144.         else:
  145.             host, port = get_host_port()
  146.  
  147.         try:
  148.             BadWordsServer(bad_words, host, port).serve()
  149.         except socket.error as e:
  150.             print('Error occured:', e, file=sys.stderr)
  151.     elif sys.argv[1] == 'client':
  152.         if yes_no('Would you like to use localhost:8000 as server'):
  153.             host, port = 'localhost', 8000
  154.         else:
  155.             host, port = get_host_port()
  156.  
  157.         try:
  158.             BadWordsClient(host, port).run()
  159.         except socket.error as e:
  160.             print('Error occured:', e, file=sys.stderr)
  161.     else:
  162.         print(arg_error, file=sys.stderr)
  163.  
  164. # Q4:
  165.  
  166. # One way of passing more information in a message, like encoding, language
  167. # or degree of cleaning would be to use "headers" in the message, the first
  168. # one would be the encoding, followed by (for instance) a semicolon, then
  169. # the language followed by a semicolon, then the degree of cleaning followed
  170. # by a semicolon and finally the message.
  171.  
  172. # e.g.
  173. # UTF-8;french;moderate;<the actual message>
  174.  
  175. # the encoding and first semicolon should be in UTF-8 to be sure that it
  176. # will be well undestand by the server, all the following data in the
  177. # message (including the two remaining semicolons) should be encoded
  178. # with the "new" encoding.
RAW Paste Data
We use cookies for various purposes including analytics. By continuing to use Pastebin, you agree to our use of cookies as described in the Cookies Policy. OK, I Understand
 
Top