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
5fafb3dc
Commit
5fafb3dc
authored
Feb 13, 2011
by
Taddeus Kroes
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Created base classes (for windows and bars) and improved CLI.
parent
4835e157
Changes
8
Hide whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
138 additions
and
75 deletions
+138
-75
telematica/ass1/async.py
telematica/ass1/async.py
+20
-9
telematica/ass1/base_bar.py
telematica/ass1/base_bar.py
+16
-0
telematica/ass1/base_window.py
telematica/ass1/base_window.py
+40
-0
telematica/ass1/chat_window.py
telematica/ass1/chat_window.py
+3
-16
telematica/ass1/cli.py
telematica/ass1/cli.py
+35
-18
telematica/ass1/command_bar.py
telematica/ass1/command_bar.py
+10
-17
telematica/ass1/debug_window.py
telematica/ass1/debug_window.py
+6
-0
telematica/ass1/info_bar.py
telematica/ass1/info_bar.py
+8
-15
No files found.
telematica/ass1/async.py
View file @
5fafb3dc
...
...
@@ -14,9 +14,18 @@ class ClientConnection(object, asyncore.dispatcher):
self
.
user
=
'Anonymous'
# Connection/chat event callbacks
self
.
event_list
=
{
}
self
.
send_queue
=
Queue
()
self
.
send_buffer
=
''
def
debug_log
(
self
,
msg
):
if
'debug'
in
self
.
event_list
:
self
.
event_list
[
'debug'
](
msg
)
else
:
print
msg
def
connect
(
self
,
addr
):
self
.
host
=
addr
[
0
]
self
.
port
=
addr
[
1
]
...
...
@@ -28,10 +37,7 @@ class ClientConnection(object, asyncore.dispatcher):
self
.
user
=
name
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.
"""
"""Called when a connection is established."""
pass
def
handle_close
(
self
):
...
...
@@ -57,7 +63,7 @@ class ClientConnection(object, asyncore.dispatcher):
buf
+=
chunk
buf
=
buf
[:
-
1
]
print
'< %s'
%
buf
self
.
debug_log
(
'< %s'
%
buf
)
if
not
self
.
verified
:
self
.
verify_server
(
buf
)
...
...
@@ -69,7 +75,7 @@ class ClientConnection(object, asyncore.dispatcher):
def
handle_write
(
self
):
if
not
self
.
send_buffer
:
self
.
send_buffer
=
self
.
send_queue
.
get
()
+
'
\
r
\
n
'
print
'> %s'
%
self
.
send_buffer
[:
-
1
]
self
.
debug_log
(
'> %s'
%
self
.
send_buffer
[:
-
2
])
sent
=
self
.
send
(
self
.
send_buffer
)
self
.
send_buffer
=
self
.
send_buffer
[
sent
:]
...
...
@@ -77,10 +83,14 @@ class ClientConnection(object, asyncore.dispatcher):
match
=
re
.
match
(
'^CHAT/(
\
d
\
.
\
d)/([^
\
x00-
\
x1F
/:]+)$'
,
buf
)
if
not
match
:
print
'Failed to verify connection'
self
.
debug_log
(
'Failed to verify connection'
)
sys
.
exit
(
-
1
)
print
'Connected to server, server version is'
,
match
.
group
(
1
)
if
'verify'
in
self
.
event_list
:
self
.
event_list
[
'verify'
](
buf
,
match
.
group
(
1
))
else
:
self
.
debug_log
(
'Server version is %s'
%
match
.
group
(
1
))
self
.
verified
=
True
self
.
send_queue
.
put
(
'CHAT'
)
...
...
@@ -91,7 +101,8 @@ class ClientConnection(object, asyncore.dispatcher):
self
.
authentification_sent
=
True
def
parse_notification
(
self
,
buf
):
pass
if
'notify'
in
self
.
event_list
:
self
.
event_list
[
'notify'
](
msg
)
def
writable
(
self
):
return
not
self
.
send_queue
.
empty
()
or
len
(
self
.
send_buffer
)
...
...
telematica/ass1/base_bar.py
0 → 100644
View file @
5fafb3dc
import
curses
class
BaseBar
(
object
):
def
__init__
(
self
,
main
,
top
,
left
,
width
):
# Reference to the main window
self
.
main
=
main
# Bar position
self
.
top
=
top
self
.
left
=
left
self
.
width
=
width
# Initialise bar
self
.
bar
=
curses
.
newwin
(
1
,
width
,
top
,
left
)
telematica/ass1/base_window.py
0 → 100644
View file @
5fafb3dc
import
curses
class
BaseWindow
(
object
):
def
__init__
(
self
,
main
,
top
,
left
,
height
,
width
):
# Reference to the main window
self
.
main
=
main
# Window position
self
.
top
=
top
self
.
left
=
left
self
.
height
=
height
self
.
width
=
width
self
.
lines
=
[]
# Initialise window
self
.
window
=
curses
.
newwin
(
height
,
width
,
top
,
left
)
def
clear
(
self
):
self
.
lines
=
[]
self
.
window
.
clear
()
self
.
window
.
refresh
()
def
redraw
(
self
):
for
y
in
range
(
self
.
height
):
self
.
window
.
move
(
y
,
0
)
for
y
,
line
in
enumerate
(
self
.
lines
[
-
self
.
height
:]):
try
:
self
.
window
.
addstr
(
y
,
0
,
line
.
ljust
(
self
.
width
))
except
curses
.
error
:
pass
self
.
window
.
refresh
()
def
append
(
self
,
msg
):
while
msg
:
self
.
lines
+=
[
msg
[:
self
.
width
]]
msg
=
msg
[
self
.
width
:]
self
.
redraw
()
telematica/ass1/chat_window.py
View file @
5fafb3dc
import
curses
from
base_window
import
BaseWindow
class
ChatWindow
:
class
ChatWindow
(
BaseWindow
)
:
def
__init__
(
self
,
main
,
top
,
left
,
height
,
width
):
# Reference to the main window
self
.
main
=
main
# Command bar position
self
.
top
=
top
self
.
left
=
left
self
.
height
=
height
self
.
width
=
width
# Initialise window
self
.
window
=
curses
.
newwin
(
height
,
width
,
top
,
left
)
super
(
ChatWindow
,
self
).
__init__
(
main
,
top
,
left
,
height
,
width
)
# True, if help screen is currently displayed.
self
.
displayed_help
=
False
def
clear
(
self
):
self
.
window
.
clear
()
self
.
window
.
refresh
()
telematica/ass1/cli.py
View file @
5fafb3dc
import
curses
import
sys
import
threading
from
async
import
ClientConnection
from
chat_window
import
ChatWindow
from
debug_window
import
DebugWindow
from
info_bar
import
InfoBar
from
command_bar
import
CommandBar
...
...
@@ -67,37 +69,41 @@ class CLI:
"""
Initialise the window of this command line interface. The user interface
of this chat application consists of a main chat window, an optional
user list window and a command bar. The chat window does also view the
help screen, when the help screen is requested by the user.
user list window, an optional debug window, an info bar and at the
bottom a command bar. The chat window does also view the help screen,
when the help screen is requested by the user.
"""
self
.
max_y
,
self
.
max_x
=
self
.
stdscr
.
getmaxyx
()
self
.
stdscr
.
refresh
()
# Initialise chat window.
self
.
chat_window
=
ChatWindow
(
self
,
0
,
0
,
self
.
max_y
-
2
,
self
.
max_x
)
self
.
chat_window
=
ChatWindow
(
self
,
0
,
0
,
self
.
max_y
-
8
,
self
.
max_x
)
# Info bar between chat window and command bar
self
.
info_bar
=
InfoBar
(
self
,
self
.
max_y
-
2
,
0
,
1
,
self
.
max_x
)
# Debug bar between chat window and info bar
self
.
debug_window
=
DebugWindow
(
self
,
self
.
max_y
-
5
,
0
,
3
,
self
.
max_x
)
# Info bar between debug window and command bar
self
.
info_bar
=
InfoBar
(
self
,
self
.
max_y
-
2
,
0
,
self
.
max_x
)
# Command bar at the bottom of the screen.
self
.
command_bar
=
CommandBar
(
self
,
self
.
max_y
-
1
,
0
,
1
,
self
.
max_x
)
self
.
command_bar
=
CommandBar
(
self
,
self
.
max_y
-
1
,
0
,
self
.
max_x
)
# set cursor position to bottom of screen.
self
.
stdscr
.
move
(
self
.
max_y
-
1
,
0
)
self
.
stdscr
.
refresh
()
def
init_input_handler
(
self
):
while
True
:
# KeyboardInterrupt is raised when an user presses ^C. This
# try/except block will catch the exception and shutdown the
# application gracefully.
try
:
# KeyboardInterrupt is raised when an user presses ^C. This
# try/except block will catch the exception and shutdown the
# application gracefully.
try
:
while
True
:
c
=
self
.
stdscr
.
getch
()
if
c
!=
curses
.
ERR
and
self
.
command_bar
.
handle_input
(
c
):
break
except
KeyboardInterrupt
:
self
.
execute
(
'quit'
)
except
KeyboardInterrupt
:
self
.
execute
(
'quit'
)
def
init_command_handler
(
self
):
...
...
@@ -115,20 +121,24 @@ class CLI:
if
getattr
(
port
,
'__class__'
)
!=
'<type
\
'
int
\
'
>'
:
port
=
int
(
port
)
# Disconnect an active connection.
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
)
# Initialise the connection and bind event handlers.
main
.
connection
=
ClientConnection
()
main
.
connection
.
main
=
main
main
.
connection
.
handle_connect
=
handle_connect
main
.
connection
.
event_list
[
'debug'
]
=
main
.
debug_log
main
.
connection
.
connect
((
host
,
port
))
# The chat connection is ran in a separate thread.
import
asyncore
self
.
connection_thread
=
threading
.
Thread
()
self
.
connection_thread
.
run
=
asyncore
.
loop
self
.
connection_thread
.
start
()
def
disconnect
(
main
):
"""
Disconnect from chat server. When there is no active connection,
...
...
@@ -140,6 +150,7 @@ class CLI:
self
.
connection
=
None
self
.
display_info
(
'Offline. Type "/connect HOST" to connect'
\
+
' to another chat server.'
)
self
.
debug_window
.
clear
()
def
help
(
main
):
if
main
.
chat_window
.
displayed_help
:
...
...
@@ -179,6 +190,9 @@ All commands listed below should be preceded by a slash:
main
.
chat_window
.
window
.
refresh
()
def
quit
(
main
):
# Disconnect the connection
del
self
.
connection
# Reverse the curses-friendly terminal settings.
curses
.
nocbreak
();
self
.
stdscr
.
keypad
(
0
);
...
...
@@ -203,6 +217,9 @@ All commands listed below should be preceded by a slash:
'quit'
:
quit
}
def
debug_log
(
self
,
msg
):
self
.
debug_window
.
append
(
msg
)
def
display_info
(
self
,
msg
):
"""
Display a message on the information bar (info_bar). This will erase the
...
...
telematica/ass1/command_bar.py
View file @
5fafb3dc
...
...
@@ -2,26 +2,19 @@ import curses
from
curses.textpad
import
Textbox
import
re
class
CommandBar
:
from
base_bar
import
BaseBar
class
CommandBar
(
BaseBar
):
"""
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
,
width
):
super
(
CommandBar
,
self
).
__init__
(
main
,
top
,
left
,
width
)
def
__init__
(
self
,
main
,
top
,
left
,
height
,
width
):
# Reference to the main window
self
.
main
=
main
# Command bar position
self
.
top
=
top
self
.
left
=
left
self
.
height
=
height
self
.
width
=
width
# Initialise window and textbox
self
.
window
=
curses
.
newwin
(
height
,
width
,
top
,
left
)
self
.
textbox
=
Textbox
(
self
.
window
)
# Initialise textbox
self
.
textbox
=
Textbox
(
self
.
bar
)
def
handle_input
(
self
,
c
):
#if c == curses.KEY_HOME:
...
...
@@ -33,14 +26,14 @@ class CommandBar:
def
append_command
(
self
,
c
):
if
not
self
.
textbox
.
do_command
(
c
):
self
.
execute_command
()
self
.
window
.
refresh
()
self
.
bar
.
refresh
()
def
execute_command
(
self
,
command
=
''
):
if
not
command
:
# Clear command bar, reset cursor and redraw the command bar.
command
=
self
.
textbox
.
gather
()
self
.
window
.
deleteln
()
self
.
window
.
move
(
0
,
0
)
self
.
bar
.
deleteln
()
self
.
bar
.
move
(
0
,
0
)
command
=
command
.
strip
()
...
...
telematica/ass1/debug_window.py
0 → 100644
View file @
5fafb3dc
import
curses
from
base_window
import
BaseWindow
class
DebugWindow
(
BaseWindow
):
pass
telematica/ass1/info_bar.py
View file @
5fafb3dc
import
curses
class
InfoBar
:
def
__init__
(
self
,
main
,
top
,
left
,
height
,
width
):
# Reference to the main window
self
.
main
=
main
import
curses
# Command bar position
self
.
top
=
top
self
.
left
=
left
self
.
height
=
height
self
.
width
=
width
from
base_bar
import
BaseBar
# Initialise window
self
.
window
=
curses
.
newwin
(
height
,
width
,
top
,
left
)
class
InfoBar
(
BaseBar
):
def
__init__
(
self
,
main
,
top
,
left
,
width
):
super
(
InfoBar
,
self
).
__init__
(
main
,
top
,
left
,
width
)
# Display start message
self
.
color_pair
=
curses
.
color_pair
(
1
)
start_message
=
'Type "/connect HOST" to connect to a chat server'
\
+
' or "/help" for help.'
self
.
display
(
start_message
)
def
display
(
self
,
msg
):
color_pair
=
curses
.
color_pair
(
1
)
try
:
self
.
window
.
addstr
(
0
,
0
,
msg
.
ljust
(
self
.
width
),
color_pair
)
self
.
bar
.
addstr
(
0
,
0
,
msg
.
ljust
(
self
.
width
),
self
.
color_pair
)
except
curses
.
error
:
pass
self
.
window
.
refresh
()
self
.
bar
.
refresh
()
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