Skip to content

Commit

Permalink
UP3 Part 1
Browse files Browse the repository at this point in the history
  • Loading branch information
lffg512 committed Apr 11, 2018
1 parent 87870e2 commit e723e93
Show file tree
Hide file tree
Showing 19 changed files with 790 additions and 0 deletions.
Binary file added AllSonnets.txt.idx
Binary file not shown.
Binary file added NYU-SH Chat System Spec.docx.pdf
Binary file not shown.
110 changes: 110 additions & 0 deletions chat_client_class.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
import time
import socket
import select
import sys
import json
from chat_utils import *
import client_state_machine_student as csm

import threading

class Client:
def __init__(self, args):
self.peer = ''
self.console_input = []
self.state = S_OFFLINE
self.system_msg = ''
self.local_msg = ''
self.peer_msg = ''
self.args = args

def quit(self):
self.socket.shutdown(socket.SHUT_RDWR)
self.socket.close()

def get_name(self):
return self.name

def init_chat(self):
self.socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM )
svr = SERVER if self.args.d == None else (self.args.d, CHAT_PORT)
self.socket.connect(svr)
self.sm = csm.ClientSM(self.socket)
reading_thread = threading.Thread(target=self.read_input)
reading_thread.daemon = True
reading_thread.start()

def shutdown_chat(self):
return

def send(self, msg):
mysend(self.socket, msg)

def recv(self):
return myrecv(self.socket)

def get_msgs(self):
read, write, error = select.select([self.socket], [], [], 0)
my_msg = ''
peer_msg = []
#peer_code = M_UNDEF for json data, peer_code is redundant
if len(self.console_input) > 0:
my_msg = self.console_input.pop(0)
if self.socket in read:
peer_msg = self.recv()
return my_msg, peer_msg

def output(self):
if len(self.system_msg) > 0:
print(self.system_msg)
self.system_msg = ''

def login(self):
my_msg, peer_msg = self.get_msgs()
if len(my_msg) > 0:
self.name = my_msg
msg = json.dumps({"action":"login", "name":self.name})
self.send(msg)
response = json.loads(self.recv())
if response["status"] == 'ok':
self.state = S_LOGGEDIN
self.sm.set_state(S_LOGGEDIN)
self.sm.set_myname(self.name)
self.print_instructions()
return (True)
elif response["status"] == 'duplicate':
self.system_msg += 'Duplicate username, try again'
return False
else: # fix: dup is only one of the reasons
return(False)


def read_input(self):
while True:
text = sys.stdin.readline()[:-1]
self.console_input.append(text) # no need for lock, append is thread safe

def print_instructions(self):
self.system_msg += menu

def run_chat(self):
self.init_chat()
self.system_msg += 'Welcome to ICS chat\n'
self.system_msg += 'Please enter your name: '
self.output()
while self.login() != True:
self.output()
self.system_msg += 'Welcome, ' + self.get_name() + '!'
self.output()
while self.sm.get_state() != S_OFFLINE:
self.proc()
self.output()
time.sleep(CHAT_WAIT)
self.quit()

#==============================================================================
# main processing loop
#==============================================================================
def proc(self):
my_msg, peer_msg = self.get_msgs()
self.system_msg += self.sm.proc(my_msg, peer_msg)
13 changes: 13 additions & 0 deletions chat_cmdl_client.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@

from chat_client_class import *

def main():
import argparse
parser = argparse.ArgumentParser(description='chat client argument')
parser.add_argument('-d', type=str, default=None, help='server IP addr')
args = parser.parse_args()

client = Client(args)
client.run_chat()

main()
116 changes: 116 additions & 0 deletions chat_group.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
# -*- coding: utf-8 -*-
"""
Created on Sun Apr 5 09:58:31 2015
@author: zhengzhang
"""
S_ALONE = 0
S_TALKING = 1

#==============================================================================
# Group class:
# member fields:
# - An array of items, each a Member class
# - A dictionary that keeps who is a chat group
# member functions:
# - join: first time in
# - leave: leave the system, and the group
# - list_my_peers: who is in chatting with me?
# - list_all: who is in the system, and the chat groups
# - connect: connect to a peer in a chat group, and become part of the group
# - disconnect: leave the chat group but stay in the system
#==============================================================================

class Group:

def __init__(self):
self.members = {}
self.chat_grps = {}
self.grp_ever = 0

def join(self, name):
self.members[name] = S_ALONE
return

def is_member(self, name):
return name in self.members.keys()

def leave(self, name):
self.disconnect(name)
del self.members[name]
return

def find_group(self, name):
found = False
group_key = 0
for k in self.chat_grps.keys():
if name in self.chat_grps[k]:
found = True
group_key = k
break
return found, group_key

def connect(self, me, peer):
peer_in_group = False
#if peer is in a group, join it
peer_in_group, group_key = self.find_group(peer)
if peer_in_group == True:
print(peer, "is talking already, connect!")
self.chat_grps[group_key].append(me)
self.members[me] = S_TALKING
else:
# otherwise, create a new group
print(peer, "is idle as well")
self.grp_ever += 1
group_key = self.grp_ever
self.chat_grps[group_key] = []
self.chat_grps[group_key].append(me)
self.chat_grps[group_key].append(peer)
self.members[me] = S_TALKING
self.members[peer] = S_TALKING
print(self.list_me(me))
return

def disconnect(self, me):
# find myself in the group, quit
in_group, group_key = self.find_group(me)
if in_group == True:
self.chat_grps[group_key].remove(me)
self.members[me] = S_ALONE
# peer may be the only one left as well...
if len(self.chat_grps[group_key]) == 1:
peer = self.chat_grps[group_key].pop()
self.members[peer] = S_ALONE
del self.chat_grps[group_key]
return

def list_all(self, me):
# a simple minded implementation
full_list = "Users: ------------" + "\n"
full_list += str(self.members) + "\n"
full_list += "Groups: -----------" + "\n"
full_list += str(self.chat_grps) + "\n"
return full_list

def list_all2(self, me):
print("Users: ------------")
print(self.members)
print("Groups: -----------")
print(self.chat_grps, "\n")
member_list = str(self.members)
grp_list = str(self.chat_grps)
return member_list, grp_list

def list_me(self, me):
# return a list, "me" followed by other peers in my group
if me in self.members.keys():
my_list = []
my_list.append(me)
in_group, group_key = self.find_group(me)
if in_group == True:
for member in self.chat_grps[group_key]:
if member != me:
my_list.append(member)
return my_list

g = Group()
Binary file added chat_server.cpython-35.pyc
Binary file not shown.
Binary file added chat_server.cpython-35_win.pyc
Binary file not shown.
Binary file added chat_server.cpython-36.pyc
Binary file not shown.
76 changes: 76 additions & 0 deletions chat_utils.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
import socket
import time

# use local loop back address by default
#CHAT_IP = '127.0.0.1'
CHAT_IP = socket.gethostbyname(socket.gethostname())
CHAT_PORT = 1112
SERVER = (CHAT_IP, CHAT_PORT)

menu = "\n++++ Choose one of the following commands\n \
time: calendar time in the system\n \
who: to find out who else are there\n \
c _peer_: to connect to the _peer_ and chat\n \
? _term_: to search your chat logs where _term_ appears\n \
p _#_: to get number <#> sonnet\n \
q: to leave the chat system\n\n"

S_OFFLINE = 0
S_CONNECTED = 1
S_LOGGEDIN = 2
S_CHATTING = 3

SIZE_SPEC = 5

CHAT_WAIT = 0.2

def print_state(state):
print('**** State *****::::: ')
if state == S_OFFLINE:
print('Offline')
elif state == S_CONNECTED:
print('Connected')
elif state == S_LOGGEDIN:
print('Logged in')
elif state == S_CHATTING:
print('Chatting')
else:
print('Error: wrong state')

def mysend(s, msg):
#append size to message and send it
msg = ('0' * SIZE_SPEC + str(len(msg)))[-SIZE_SPEC:] + str(msg)
msg = msg.encode()
total_sent = 0
while total_sent < len(msg) :
sent = s.send(msg[total_sent:])
if sent==0:
print('server disconnected')
break
total_sent += sent

def myrecv(s):
#receive size first
size = ''
while len(size) < SIZE_SPEC:
text = s.recv(SIZE_SPEC - len(size)).decode()
if not text:
print('disconnected')
return('')
size += text
size = int(size)
#now receive message
msg = ''
while len(msg) < size:
text = s.recv(size-len(msg)).decode()
if text == b'':
print('disconnected')
break
msg += text
#print ('received '+message)
return (msg)

def text_proc(text, user):
ctime = time.strftime('%d.%m.%y,%H:%M', time.localtime())
return('(' + ctime + ') ' + user + ' : ' + text) # message goes directly to screen

Loading

0 comments on commit e723e93

Please sign in to comment.