Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
U
uva
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Taddeüs Kroes
uva
Commits
4e94aa8d
Commit
4e94aa8d
authored
Feb 13, 2011
by
Sander Mathijs van Veen
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Improved CLI and client connection.
parent
ef23cef8
Changes
5
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
180 additions
and
69 deletions
+180
-69
telematica/ass1/async.py
telematica/ass1/async.py
+21
-12
telematica/ass1/chat_window.py
telematica/ass1/chat_window.py
+1
-27
telematica/ass1/cli.py
telematica/ass1/cli.py
+140
-10
telematica/ass1/command_bar.py
telematica/ass1/command_bar.py
+17
-20
telematica/ass1/main.py
telematica/ass1/main.py
+1
-0
No files found.
telematica/ass1/async.py
View file @
4e94aa8d
...
...
@@ -2,23 +2,31 @@ import asyncore, socket
from
Queue
import
Queue
import
re
class
C
hatClient
(
asyncore
.
dispatcher
):
class
C
lientConnection
(
object
,
asyncore
.
dispatcher
):
def
__init__
(
self
,
host
,
port
,
nickname
=
'Foo'
):
def
__init__
(
self
):
asyncore
.
dispatcher
.
__init__
(
self
)
self
.
create_socket
(
socket
.
AF_INET
,
socket
.
SOCK_STREAM
)
self
.
connect
((
host
,
port
))
self
.
verified
=
False
self
.
authenticated
=
False
self
.
authentification_sent
=
False
self
.
nickname
=
nickname
self
.
nickname
=
'Anonymous'
self
.
send_queue
=
Queue
()
self
.
send_buffer
=
''
def
connect
(
self
,
addr
):
self
.
host
=
addr
[
0
]
self
.
port
=
addr
[
1
]
super
(
ClientConnection
,
self
).
connect
(
addr
)
def
handle_connect
(
self
):
"""
Called when a connection is established. This method will/should be
overwritten by the Command Line Interface or an other implementation.
"""
pass
def
handle_close
(
self
):
...
...
@@ -53,6 +61,13 @@ class ChatClient(asyncore.dispatcher):
else
:
self
.
parse_notification
(
buf
)
def
handle_write
(
self
):
if
not
self
.
send_buffer
:
self
.
send_buffer
=
self
.
send_queue
.
get
()
+
'
\
r
\
n
'
print
'> %s'
%
self
.
send_buffer
[:
-
1
]
sent
=
self
.
send
(
self
.
send_buffer
)
self
.
send_buffer
=
self
.
send_buffer
[
sent
:]
def
verify_server
(
self
,
buf
):
match
=
re
.
match
(
'^CHAT/(
\
d
\
.
\
d)/([^
\
x00-
\
x1F
/:]+)$'
,
buf
)
...
...
@@ -76,13 +91,7 @@ class ChatClient(asyncore.dispatcher):
def
writable
(
self
):
return
not
self
.
send_queue
.
empty
()
or
len
(
self
.
send_buffer
)
def
handle_write
(
self
):
if
not
self
.
send_buffer
:
self
.
send_buffer
=
self
.
send_queue
.
get
()
+
'
\
r
\
n
'
print
'> %s'
%
self
.
send_buffer
[:
-
1
]
sent
=
self
.
send
(
self
.
send_buffer
)
self
.
send_buffer
=
self
.
send_buffer
[
sent
:]
if
__name__
==
'__main__'
:
client
=
ChatClient
(
'ow150.science.uva.nl'
,
16897
)
client
=
ClientConnection
()
client
.
connect
((
'ow150.science.uva.nl'
,
16897
))
asyncore
.
loop
()
telematica/ass1/chat_window.py
View file @
4e94aa8d
...
...
@@ -17,33 +17,7 @@ class ChatWindow:
# True, if help screen is currently displayed.
self
.
displayed_help
=
False
def
handle_close
(
self
):
# If the help screen is currently displayed, hide it.
if
self
.
displayed_help
:
self
.
displayed_help
=
False
self
.
window
.
clear
()
self
.
window
.
refresh
()
else
:
# Stop user input handler (which will exit the application).
self
.
main
.
quit
()
def
display_help
(
self
):
if
self
.
displayed_help
:
return
self
.
displayed_help
=
True
def
clear
(
self
):
self
.
window
.
clear
()
help_text
=
'Help screen
\
n
'
\
+
'
\
n
'
\
+
'All commands listed below should be preceded by a slash:
\
n
'
\
+
'
\
n
'
\
+
' Command
\
t
Description
\
n
'
\
+
' close
\
t
\
t
Close visible chat window (or this help screen).
\
n
'
\
+
' help
\
t
\
t
This help page.
\
n
'
\
+
' quit
\
t
\
t
Quit this chat application (shortcut: ^c).
\
n
'
\
for
i
,
line
in
enumerate
(
help_text
.
split
(
'
\
n
'
)):
self
.
window
.
addstr
(
i
,
0
,
line
)
self
.
window
.
refresh
()
telematica/ass1/cli.py
View file @
4e94aa8d
import
curses
import
sys
from
async
import
ClientConnection
from
chat_window
import
ChatWindow
from
info_bar
import
InfoBar
from
command_bar
import
CommandBar
...
...
@@ -50,6 +51,12 @@ class CLI:
# Initialise color scheme.
curses
.
init_pair
(
1
,
curses
.
COLOR_WHITE
,
curses
.
COLOR_BLUE
)
# No default connection
self
.
connection
=
None
# Initialise command handler
self
.
init_command_handler
()
# Window composition.
self
.
init_windows
()
...
...
@@ -67,7 +74,7 @@ class CLI:
self
.
max_y
,
self
.
max_x
=
self
.
stdscr
.
getmaxyx
()
self
.
stdscr
.
refresh
()
# Initalise chat window.
# Init
i
alise chat window.
self
.
chat_window
=
ChatWindow
(
self
,
0
,
0
,
self
.
max_y
-
2
,
self
.
max_x
)
# Info bar between chat window and command bar
...
...
@@ -88,21 +95,144 @@ class CLI:
try
:
c
=
self
.
stdscr
.
getch
()
except
KeyboardInterrupt
:
self
.
quit
(
)
self
.
execute
(
'quit'
)
if
c
!=
curses
.
ERR
and
self
.
command_bar
.
handle_input
(
c
):
break
def
quit
(
self
):
# Reverse the curses-friendly terminal settings.
curses
.
nocbreak
();
self
.
stdscr
.
keypad
(
0
);
curses
.
echo
()
def
init_command_handler
(
self
):
# Restore the terminal to its original operating mode.
curses
.
endwin
()
def
close
(
main
):
# If the help screen is currently displayed, hide it.
if
main
.
chat_window
.
displayed_help
:
main
.
chat_window
.
displayed_help
=
False
main
.
chat_window
.
clear
()
else
:
# Stop user input handler (which will exit the application).
main
.
execute
(
'quit'
)
def
connect
(
main
,
host
,
port
=
16897
):
if
getattr
(
port
,
'__class__'
)
!=
'<type
\
'
int
\
'
>'
:
port
=
int
(
port
)
if
main
.
connection
:
main
.
execute
(
'disconnect'
)
main
.
display_info
(
'Connecting to %s:%d...'
%
(
host
,
port
))
def
handle_connect
(
conn
):
"""Called when a connection is established."""
conn
.
main
.
display_info
(
'Connected to %s'
%
conn
.
host
)
main
.
connection
=
ClientConnection
()
main
.
connection
.
main
=
main
main
.
connection
.
handle_connect
=
handle_connect
main
.
connection
.
connect
((
host
,
port
))
def
disconnect
(
main
):
"""
Disconnect from chat server. When there is no active connection,
this operating will only set the 'Offline' message in the
information bar. Otherwise, the active connection is set to None
and the 'Offline' message is set to the info bar.
"""
self
.
connection
=
None
self
.
display_info
(
'Offline. Type "/connect HOST" to connect'
\
+
' to another chat server.'
)
def
help
(
main
):
if
main
.
chat_window
.
displayed_help
:
return
main
.
chat_window
.
displayed_help
=
True
main
.
chat_window
.
clear
()
help_text
=
"""Help screen
All commands listed below should be preceded by a slash:
Command Description
close Close visible chat window (or this help screen).
connect Connect to a chat server using HOSTNAME and optionally a PORT.
If no PORT is specified, the default port 16897 is used.
Synopsis: /connect HOSTNAME [PORT]
For example, "/connect ow150" will connect to the provided test
server of this assignment (when you're using the UvA network).
disconnect Disconnect from the currently connected chat server.
exec Execute python code. For example. to list all variables and
function of the CLI, type: "/exec print dir(main)".
help This help page.
quit Quit this chat application (shortcut: ^c).
"""
for
i
,
line
in
enumerate
(
help_text
.
split
(
'
\
n
'
)):
main
.
chat_window
.
window
.
addstr
(
i
,
0
,
line
)
main
.
chat_window
.
window
.
refresh
()
def
quit
(
main
):
# Reverse the curses-friendly terminal settings.
curses
.
nocbreak
();
self
.
stdscr
.
keypad
(
0
);
curses
.
echo
()
# Restore the terminal to its original operating mode.
curses
.
endwin
()
sys
.
exit
(
0
)
def
_exec
(
main
,
cmd
):
# Skip the leading "/exec " of the command
exec
cmd
[
6
:]
# List of builtin command
self
.
cmd_list
=
{
'close'
:
close
,
'connect'
:
connect
,
'disconnect'
:
disconnect
,
'exec'
:
_exec
,
'help'
:
help
,
'quit'
:
quit
}
def
display_info
(
self
,
msg
):
"""
Display a message on the information bar (info_bar). This will erase the
existing message on the info bar.
"""
sys
.
exit
(
0
)
self
.
info_bar
.
display
(
msg
)
def
execute
(
self
,
cmd
,
args
=
[],
raw_command
=
''
):
if
not
raw_command
:
raw_command
=
cmd
# Select command from command list.
try
:
cmd_fn
=
self
.
cmd_list
[
cmd
]
except
KeyError
:
self
.
display_info
(
'Unknown command "/%s".'
%
cmd
)
return
# Call command handler.
try
:
if
cmd
==
'exec'
:
cmd_fn
(
self
,
raw_command
)
else
:
cmd_fn
(
self
,
*
args
)
except
Exception
,
e
:
self
.
display_info
(
str
(
e
))
return
def
__del__
(
self
):
import
curses
...
...
telematica/ass1/command_bar.py
View file @
4e94aa8d
import
curses
from
curses.textpad
import
Textbox
import
re
class
CommandBar
:
"""
Command bar is part of the Command Line Interface (CLI) of the chat
application. The command bar is responsible for handling the user input.
This inclues executing commands and (re)drawing the command line.
"""
def
__init__
(
self
,
main
,
top
,
left
,
height
,
width
):
# Reference to the main window
self
.
main
=
main
...
...
@@ -17,18 +24,10 @@ class CommandBar:
self
.
textbox
=
Textbox
(
self
.
window
)
def
handle_input
(
self
,
c
):
#if c == ord('Q'):
# return True
#if c == ord('q'):
# return self.handle_quit()
#if c == ord('h'):
# self.display_help()
#elif c == curses.KEY_HOME:
#if c == curses.KEY_HOME:
# self.x = self.y = 0
#if 32 <= c <= 127:
#
el
if 32 <= c <= 127:
# self.append_command(c)
#elif c == 10: # Enter key
# return self.execute_command()
self
.
append_command
(
c
)
def
append_command
(
self
,
c
):
...
...
@@ -42,21 +41,19 @@ class CommandBar:
command
=
self
.
textbox
.
gather
()
self
.
window
.
deleteln
()
self
.
window
.
move
(
0
,
0
)
# Handle the given/typed command.
self
.
handle_command
(
command
)
def
handle_command
(
self
,
command
):
command
=
command
.
strip
()
if
not
command
:
return
if
command
[
0
]
==
'/'
:
cmd
=
command
.
split
(
' '
,
1
)[
0
][
1
:]
if
cmd
==
'help'
:
self
.
main
.
chat_window
.
display_help
()
elif
cmd
==
'quit'
:
self
.
main
.
quit
()
elif
cmd
==
'close'
:
self
.
main
.
chat_window
.
handle_close
()
# Split command line into command identifier and arguments.
parts
=
re
.
split
(
'
\
s+
'
, command)
cmd = parts[0][1:]
args = parts[1:]
self.main.execute(cmd, args, command)
else:
pass
telematica/ass1/main.py
View file @
4e94aa8d
#!/usr/bin/env python
from
cli
import
CLI
import
curses
try
:
cli
=
CLI
()
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment