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):
...
@@ -14,9 +14,18 @@ class ClientConnection(object, asyncore.dispatcher):
self
.
user
=
'Anonymous'
self
.
user
=
'Anonymous'
# Connection/chat event callbacks
self
.
event_list
=
{
}
self
.
send_queue
=
Queue
()
self
.
send_queue
=
Queue
()
self
.
send_buffer
=
''
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
):
def
connect
(
self
,
addr
):
self
.
host
=
addr
[
0
]
self
.
host
=
addr
[
0
]
self
.
port
=
addr
[
1
]
self
.
port
=
addr
[
1
]
...
@@ -28,10 +37,7 @@ class ClientConnection(object, asyncore.dispatcher):
...
@@ -28,10 +37,7 @@ class ClientConnection(object, asyncore.dispatcher):
self
.
user
=
name
self
.
user
=
name
def
handle_connect
(
self
):
def
handle_connect
(
self
):
"""
"""Called when a connection is established."""
Called when a connection is established. This method will/should be
overwritten by the Command Line Interface or an other implementation.
"""
pass
pass
def
handle_close
(
self
):
def
handle_close
(
self
):
...
@@ -57,7 +63,7 @@ class ClientConnection(object, asyncore.dispatcher):
...
@@ -57,7 +63,7 @@ class ClientConnection(object, asyncore.dispatcher):
buf
+=
chunk
buf
+=
chunk
buf
=
buf
[:
-
1
]
buf
=
buf
[:
-
1
]
print
'< %s'
%
buf
self
.
debug_log
(
'< %s'
%
buf
)
if
not
self
.
verified
:
if
not
self
.
verified
:
self
.
verify_server
(
buf
)
self
.
verify_server
(
buf
)
...
@@ -69,7 +75,7 @@ class ClientConnection(object, asyncore.dispatcher):
...
@@ -69,7 +75,7 @@ class ClientConnection(object, asyncore.dispatcher):
def
handle_write
(
self
):
def
handle_write
(
self
):
if
not
self
.
send_buffer
:
if
not
self
.
send_buffer
:
self
.
send_buffer
=
self
.
send_queue
.
get
()
+
'
\
r
\
n
'
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
)
sent
=
self
.
send
(
self
.
send_buffer
)
self
.
send_buffer
=
self
.
send_buffer
[
sent
:]
self
.
send_buffer
=
self
.
send_buffer
[
sent
:]
...
@@ -77,10 +83,14 @@ class ClientConnection(object, asyncore.dispatcher):
...
@@ -77,10 +83,14 @@ class ClientConnection(object, asyncore.dispatcher):
match
=
re
.
match
(
'^CHAT/(
\
d
\
.
\
d)/([^
\
x00-
\
x1F
/:]+)$'
,
buf
)
match
=
re
.
match
(
'^CHAT/(
\
d
\
.
\
d)/([^
\
x00-
\
x1F
/:]+)$'
,
buf
)
if
not
match
:
if
not
match
:
print
'Failed to verify connection'
self
.
debug_log
(
'Failed to verify connection'
)
sys
.
exit
(
-
1
)
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
.
verified
=
True
self
.
send_queue
.
put
(
'CHAT'
)
self
.
send_queue
.
put
(
'CHAT'
)
...
@@ -91,7 +101,8 @@ class ClientConnection(object, asyncore.dispatcher):
...
@@ -91,7 +101,8 @@ class ClientConnection(object, asyncore.dispatcher):
self
.
authentification_sent
=
True
self
.
authentification_sent
=
True
def
parse_notification
(
self
,
buf
):
def
parse_notification
(
self
,
buf
):
pass
if
'notify'
in
self
.
event_list
:
self
.
event_list
[
'notify'
](
msg
)
def
writable
(
self
):
def
writable
(
self
):
return
not
self
.
send_queue
.
empty
()
or
len
(
self
.
send_buffer
)
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
import
curses
from
base_window
import
BaseWindow
class
ChatWindow
:
class
ChatWindow
(
BaseWindow
)
:
def
__init__
(
self
,
main
,
top
,
left
,
height
,
width
):
def
__init__
(
self
,
main
,
top
,
left
,
height
,
width
):
# Reference to the main window
super
(
ChatWindow
,
self
).
__init__
(
main
,
top
,
left
,
height
,
width
)
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
)
# True, if help screen is currently displayed.
# True, if help screen is currently displayed.
self
.
displayed_help
=
False
self
.
displayed_help
=
False
def
clear
(
self
):
self
.
window
.
clear
()
self
.
window
.
refresh
()
telematica/ass1/cli.py
View file @
5fafb3dc
import
curses
import
curses
import
sys
import
sys
import
threading
from
async
import
ClientConnection
from
async
import
ClientConnection
from
chat_window
import
ChatWindow
from
chat_window
import
ChatWindow
from
debug_window
import
DebugWindow
from
info_bar
import
InfoBar
from
info_bar
import
InfoBar
from
command_bar
import
CommandBar
from
command_bar
import
CommandBar
...
@@ -67,37 +69,41 @@ class CLI:
...
@@ -67,37 +69,41 @@ class CLI:
"""
"""
Initialise the window of this command line interface. The user interface
Initialise the window of this command line interface. The user interface
of this chat application consists of a main chat window, an optional
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
user list window, an optional debug window, an info bar and at the
help screen, when the help screen is requested by the user.
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
.
max_y
,
self
.
max_x
=
self
.
stdscr
.
getmaxyx
()
self
.
stdscr
.
refresh
()
self
.
stdscr
.
refresh
()
# Initialise chat window.
# 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
# Debug bar between chat window and info bar
self
.
info_bar
=
InfoBar
(
self
,
self
.
max_y
-
2
,
0
,
1
,
self
.
max_x
)
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.
# 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.
# set cursor position to bottom of screen.
self
.
stdscr
.
move
(
self
.
max_y
-
1
,
0
)
self
.
stdscr
.
move
(
self
.
max_y
-
1
,
0
)
self
.
stdscr
.
refresh
()
self
.
stdscr
.
refresh
()
def
init_input_handler
(
self
):
def
init_input_handler
(
self
):
while
True
:
# KeyboardInterrupt is raised when an user presses ^C. This
# KeyboardInterrupt is raised when an user presses ^C. This
# try/except block will catch the exception and shutdown the
# try/except block will catch the exception and shutdown the
# application gracefully.
# application gracefully.
try
:
try
:
while
True
:
c
=
self
.
stdscr
.
getch
()
c
=
self
.
stdscr
.
getch
()
if
c
!=
curses
.
ERR
and
self
.
command_bar
.
handle_input
(
c
):
if
c
!=
curses
.
ERR
and
self
.
command_bar
.
handle_input
(
c
):
break
break
except
KeyboardInterrupt
:
except
KeyboardInterrupt
:
self
.
execute
(
'quit'
)
self
.
execute
(
'quit'
)
def
init_command_handler
(
self
):
def
init_command_handler
(
self
):
...
@@ -115,20 +121,24 @@ class CLI:
...
@@ -115,20 +121,24 @@ class CLI:
if
getattr
(
port
,
'__class__'
)
!=
'<type
\
'
int
\
'
>'
:
if
getattr
(
port
,
'__class__'
)
!=
'<type
\
'
int
\
'
>'
:
port
=
int
(
port
)
port
=
int
(
port
)
# Disconnect an active connection.
if
main
.
connection
:
if
main
.
connection
:
main
.
execute
(
'disconnect'
)
main
.
execute
(
'disconnect'
)
main
.
display_info
(
'Connecting to %s:%d...'
%
(
host
,
port
))
main
.
display_info
(
'Connecting to %s:%d...'
%
(
host
,
port
))
def
handle_connect
(
conn
):
# Initialise the connection and bind event handlers.
"""Called when a connection is established."""
conn
.
main
.
display_info
(
'Connected to %s'
%
conn
.
host
)
main
.
connection
=
ClientConnection
()
main
.
connection
=
ClientConnection
()
main
.
connection
.
main
=
main
main
.
connection
.
main
=
main
main
.
connection
.
handle_connect
=
handle_connect
main
.
connection
.
event_list
[
'debug'
]
=
main
.
debug_log
main
.
connection
.
connect
((
host
,
port
))
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
):
def
disconnect
(
main
):
"""
"""
Disconnect from chat server. When there is no active connection,
Disconnect from chat server. When there is no active connection,
...
@@ -140,6 +150,7 @@ class CLI:
...
@@ -140,6 +150,7 @@ class CLI:
self
.
connection
=
None
self
.
connection
=
None
self
.
display_info
(
'Offline. Type "/connect HOST" to connect'
\
self
.
display_info
(
'Offline. Type "/connect HOST" to connect'
\
+
' to another chat server.'
)
+
' to another chat server.'
)
self
.
debug_window
.
clear
()
def
help
(
main
):
def
help
(
main
):
if
main
.
chat_window
.
displayed_help
:
if
main
.
chat_window
.
displayed_help
:
...
@@ -179,6 +190,9 @@ All commands listed below should be preceded by a slash:
...
@@ -179,6 +190,9 @@ All commands listed below should be preceded by a slash:
main
.
chat_window
.
window
.
refresh
()
main
.
chat_window
.
window
.
refresh
()
def
quit
(
main
):
def
quit
(
main
):
# Disconnect the connection
del
self
.
connection
# Reverse the curses-friendly terminal settings.
# Reverse the curses-friendly terminal settings.
curses
.
nocbreak
();
curses
.
nocbreak
();
self
.
stdscr
.
keypad
(
0
);
self
.
stdscr
.
keypad
(
0
);
...
@@ -203,6 +217,9 @@ All commands listed below should be preceded by a slash:
...
@@ -203,6 +217,9 @@ All commands listed below should be preceded by a slash:
'quit'
:
quit
'quit'
:
quit
}
}
def
debug_log
(
self
,
msg
):
self
.
debug_window
.
append
(
msg
)
def
display_info
(
self
,
msg
):
def
display_info
(
self
,
msg
):
"""
"""
Display a message on the information bar (info_bar). This will erase the
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
...
@@ -2,26 +2,19 @@ import curses
from
curses.textpad
import
Textbox
from
curses.textpad
import
Textbox
import
re
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
Command bar is part of the Command Line Interface (CLI) of the chat
application. The command bar is responsible for handling the user input.
application. The command bar is responsible for handling the user input.
This inclues executing commands and (re)drawing the command line.
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
):
# Initialise textbox
# Reference to the main window
self
.
textbox
=
Textbox
(
self
.
bar
)
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
)
def
handle_input
(
self
,
c
):
def
handle_input
(
self
,
c
):
#if c == curses.KEY_HOME:
#if c == curses.KEY_HOME:
...
@@ -33,14 +26,14 @@ class CommandBar:
...
@@ -33,14 +26,14 @@ class CommandBar:
def
append_command
(
self
,
c
):
def
append_command
(
self
,
c
):
if
not
self
.
textbox
.
do_command
(
c
):
if
not
self
.
textbox
.
do_command
(
c
):
self
.
execute_command
()
self
.
execute_command
()
self
.
window
.
refresh
()
self
.
bar
.
refresh
()
def
execute_command
(
self
,
command
=
''
):
def
execute_command
(
self
,
command
=
''
):
if
not
command
:
if
not
command
:
# Clear command bar, reset cursor and redraw the command bar.
# Clear command bar, reset cursor and redraw the command bar.
command
=
self
.
textbox
.
gather
()
command
=
self
.
textbox
.
gather
()
self
.
window
.
deleteln
()
self
.
bar
.
deleteln
()
self
.
window
.
move
(
0
,
0
)
self
.
bar
.
move
(
0
,
0
)
command
=
command
.
strip
()
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
:
import
curses
def
__init__
(
self
,
main
,
top
,
left
,
height
,
width
):
# Reference to the main window
self
.
main
=
main
# Command bar position
from
base_bar
import
BaseBar
self
.
top
=
top
self
.
left
=
left
self
.
height
=
height
self
.
width
=
width
# Initialise window
class
InfoBar
(
BaseBar
):
self
.
window
=
curses
.
newwin
(
height
,
width
,
top
,
left
)
def
__init__
(
self
,
main
,
top
,
left
,
width
):
super
(
InfoBar
,
self
).
__init__
(
main
,
top
,
left
,
width
)
# Display start message
# Display start message
self
.
color_pair
=
curses
.
color_pair
(
1
)
start_message
=
'Type "/connect HOST" to connect to a chat server'
\
start_message
=
'Type "/connect HOST" to connect to a chat server'
\
+
' or "/help" for help.'
+
' or "/help" for help.'
self
.
display
(
start_message
)
self
.
display
(
start_message
)
def
display
(
self
,
msg
):
def
display
(
self
,
msg
):
color_pair
=
curses
.
color_pair
(
1
)
try
:
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
:
except
curses
.
error
:
pass
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