Allow referring to peers by nick
This commit is contained in:
parent
76704d4a11
commit
a140fde1c1
127
ethermess.py
127
ethermess.py
|
@ -54,12 +54,14 @@ def writeall(f, b):
|
|||
while written < len(b):
|
||||
written += f.write(b[written:])
|
||||
|
||||
class ReadallError(Exception): pass
|
||||
|
||||
def readall(f, length):
|
||||
read = bytearray()
|
||||
while len(read) < length:
|
||||
data = f.read(length - len(read))
|
||||
if data == b'':
|
||||
raise ConnectionError('Could not satisfy read of %i bytes' % length)
|
||||
raise ReadallError('Could not satisfy read of %i bytes' % length)
|
||||
read.extend(data)
|
||||
return bytes(read)
|
||||
|
||||
|
@ -67,18 +69,47 @@ def readall_u16(f):
|
|||
u16_bytes = readall(f, 2)
|
||||
return (u16_bytes[0] << 8) | u16_bytes[1]
|
||||
|
||||
class MACParseError(Exception): pass
|
||||
|
||||
def parse_mac(text):
|
||||
parts = text.split(':')
|
||||
if len(parts) != 6:
|
||||
raise ValueError('Invalid MAC format: %s' % text)
|
||||
raise MACParseError('Invalid MAC format: %s' % text)
|
||||
|
||||
try:
|
||||
parsed = bytes(int(field, 16) for field in parts)
|
||||
except ValueError:
|
||||
raise ValueError('Invalid MAC format %s' % text)
|
||||
raise MACParseError('Invalid MAC format %s' % text)
|
||||
|
||||
return parsed
|
||||
|
||||
class NoMatchesError(Exception): pass
|
||||
class TooManyMatchesError(Exception): pass
|
||||
|
||||
def mac_from_name(text):
|
||||
global peers
|
||||
|
||||
# Try to parse as a MAC address
|
||||
try:
|
||||
mac = parse_mac(text)
|
||||
return mac
|
||||
except MACParseError as err:
|
||||
pass
|
||||
|
||||
# It was not, try to find a matching nick
|
||||
hits = 0
|
||||
for peer_mac, peer in peers.items():
|
||||
if text == peer.nick or text == '~' + peer.nick:
|
||||
hits += 1
|
||||
mac = peer_mac
|
||||
|
||||
if hits == 0:
|
||||
raise NoMatchesError(text)
|
||||
elif hits > 1:
|
||||
raise TooManyMatchesError(text)
|
||||
|
||||
return mac
|
||||
|
||||
def format_mac(mac):
|
||||
return ':'.join(mac[i:i+1].hex() for i in range(len(mac)))
|
||||
|
||||
|
@ -129,45 +160,63 @@ def handle_user_command(backend, line):
|
|||
|
||||
if len(line) > 0 and line[0] == '/':
|
||||
command, _, rest = line.partition(' ')
|
||||
if command == '/':
|
||||
# Send quoted message
|
||||
if default_target_mac is None:
|
||||
print('--- Default target not set, set with /target')
|
||||
|
||||
try:
|
||||
if command == '/':
|
||||
# Send quoted message
|
||||
# TODO: Validate message
|
||||
if default_target_mac is None:
|
||||
print('--- Default target not set, set with /target')
|
||||
else:
|
||||
queue_message(backend, default_target_mac, rest)
|
||||
|
||||
elif command == '/msg':
|
||||
# Send message to target
|
||||
target, _, message = rest.partition(' ')
|
||||
mac = mac_from_name(target)
|
||||
queue_message(backend, mac, message)
|
||||
|
||||
elif command == '/status':
|
||||
# Request status
|
||||
mac = mac_from_name(rest)
|
||||
if mac in peers:
|
||||
print('=== ~%s (%s) [%s]' % (peers[mac].nick, peers[mac].status.name, format_mac(mac)))
|
||||
else:
|
||||
send_status_request(backend, mac)
|
||||
|
||||
elif command == '/available' and rest == '':
|
||||
# Set status to available
|
||||
own_status = statuses.available
|
||||
set_status_nick(backend, own_status, own_nick)
|
||||
|
||||
elif command == '/unavailable' and rest == '':
|
||||
# Set status to unavailable
|
||||
own_status = statuses.unavailable
|
||||
set_status_nick(backend, own_status, own_nick)
|
||||
|
||||
elif command == '/nick':
|
||||
# Change nick
|
||||
# TODO: Validate nick
|
||||
own_nick = rest
|
||||
set_status_nick(backend, own_status, own_nick)
|
||||
|
||||
elif command == '/target':
|
||||
# Set default target of messages
|
||||
default_target_mac = mac_from_name(rest)
|
||||
|
||||
elif command == '/quit':
|
||||
# Quit
|
||||
return 'quit'
|
||||
|
||||
else:
|
||||
queue_message(backend, default_target_mac, rest)
|
||||
# Display usage
|
||||
print('--- / <message>; /msg <target> <message>; /status <target>; /available; /unavailable; /nick <nick>; /target <target>; /quit')
|
||||
|
||||
elif command == '/msg':
|
||||
# Send message to target
|
||||
mac_str, _, message = rest.partition(' ')
|
||||
mac = parse_mac(mac_str)
|
||||
queue_message(backend, mac, message)
|
||||
except NoMatchesError as err:
|
||||
print('--- name %s matches no peers' % err.args[0])
|
||||
|
||||
elif command == '/status':
|
||||
# Request status
|
||||
mac = parse_mac(rest)
|
||||
send_status_request(backend, mac)
|
||||
|
||||
elif command == '/available' and rest == '':
|
||||
own_status = statuses.available
|
||||
set_status_nick(backend, own_status, own_nick)
|
||||
|
||||
elif command == '/unavailable' and rest == '':
|
||||
own_status = statuses.unavailable
|
||||
set_status_nick(backend, own_status, own_nick)
|
||||
|
||||
elif command == '/nick':
|
||||
own_nick = rest
|
||||
set_status_nick(backend, own_status, own_nick)
|
||||
|
||||
elif command == '/target':
|
||||
default_target_mac = parse_mac(rest)
|
||||
|
||||
elif command == '/quit':
|
||||
return 'quit'
|
||||
|
||||
else:
|
||||
# Display usage
|
||||
print('--- / <message>; /msg <MAC> <message>; /status <MAC>; /available; /unavailable; /nick <nick>; /target <MAC>; /quit')
|
||||
except TooManyMatchesError as err:
|
||||
print('--- name %s matches several peers' % err.args[0])
|
||||
|
||||
else:
|
||||
# Send message
|
||||
|
|
Loading…
Reference in New Issue