Skip to content

Commit

Permalink
Some fixes and changes, hopefully non-breaking.
Browse files Browse the repository at this point in the history
  • Loading branch information
sp9wpn committed Sep 20, 2024
1 parent 3b55368 commit 84281e9
Show file tree
Hide file tree
Showing 3 changed files with 135 additions and 22 deletions.
71 changes: 52 additions & 19 deletions mopp.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,20 @@
class Mopp:
serial = 1

morse = {
"0" : "-----", "1" : ".----", "2" : "..---", "3" : "...--", "4" : "....-", "5" : ".....",
"6" : "-....", "7" : "--...", "8" : "---..", "9" : "----.",
"a" : ".-", "b" : "-...", "c" : "-.-.", "d" : "-..", "e" : ".", "f" : "..-.", "g" : "--.",
"h" : "....", "i" : "..", "j" : ".---", "k" : "-.-", "l" : ".-..", "m" : "--", "n" : "-.",
"o" : "---", "p" : ".--.", "q" : "--.-", "r" : ".-.", "s" : "...", "t" : "-", "u" : "..-",
"v" : "...-", "w" : ".--", "x" : "-..-", "y" : "-.--", "z" : "--..", "=" : "-...-",
"/" : "-..-.", "+" : ".-.-.", "-" : "-....-", "." : ".-.-.-", "," : "--..--", "?" : "..--..",
":" : "---...", "!" : "-.-.--", "'" : ".----."
}

morse_inv = {v: k for k, v in morse.items()}


def __init__(self, speed = 20):
self.speed = speed
return
Expand All @@ -17,36 +31,34 @@ def _str2bin(self, bytes):
bincode = "".join("{:08b}".format(c) for c in bytes)
return bincode

def mopp(self, speed, msg):
logging.debug("Encoding message with "+str(speed)+" wpm :"+str(msg))

morse = {
"0" : "-----", "1" : ".----", "2" : "..---", "3" : "...--", "4" : "....-", "5" : ".....",
"6" : "-....", "7" : "--...", "8" : "---..", "9" : "----.",
"a" : ".-", "b" : "-...", "c" : "-.-.", "d" : "-..", "e" : ".", "f" : "..-.", "g" : "--.",
"h" : "....", "i" : "..", "j" : ".---", "k" : "-.-", "l" : ".-..", "m" : "--", "n" : "-.",
"o" : "---", "p" : ".--.", "q" : "--.-", "r" : ".-.", "s" : "...", "t" : "-", "u" : "..-",
"v" : "...-", "w" : ".--", "x" : "-..-", "y" : "-.--", "z" : "--..", "=" : "-...-",
"/" : "-..-.", "+" : ".-.-.", "-" : "-....-", "." : ".-.-.-", "," : "--..--", "?" : "..--..",
":" : "---...", "!" : "-.-.--", "'" : ".----."
}
def mopp(self, speed, msg, for_transmission = True):

m = '01' # protocol version
m += bin(self.serial)[2:].zfill(6)
m += bin(speed)[2:].zfill(6)

_txt = ''

for c in msg:
if c == " ":
continue # spaces not supported by morserino!

for b in morse[c.lower()]:
if c.lower() not in self.morse:
continue # unknown character

_txt += c.lower()
for b in self.morse[c.lower()]:
if b == '.':
m += '01'
else:
m += '10'

m += '00' # EOC

if len(m) <= 14: # empty message
return bytes('','latin_1')


m = m[0:-2] + '11' # final EOW
m = m.ljust(int(8*ceil(len(m)/8.0)),'0')

Expand All @@ -57,15 +69,20 @@ def mopp(self, speed, msg):
#print (m[i:i+8], bytes(chr(int(m[i:i+8],2)),"latin_1"), i, " ENCODER")
res += chr(int(m[i:i+8],2))

self.serial += 1
if for_transmission:
logging.debug("Encoding message with "+str(speed)+" wpm: "+str(_txt))
self.serial += 1
if self.serial >= 64:
self.serial = 0

return bytes(res,'latin_1') # WATCH OUT: UNICODE MAKES MULTI-BYTES

def _stripheader(self, msg):
res = bytes(0x00) + bytes(msg[1] & 3) + msg[2:]
return res

def msg_strcmp (self, data_bytes, speed, msg):
if self._stripheader(data_bytes) == self._stripheader(self.mopp(speed, msg)):
if self._stripheader(data_bytes) == self._stripheader(self.mopp(speed, msg, False)):
return True
else:
return False
Expand Down Expand Up @@ -104,7 +121,9 @@ def decode_message (self, data_bytes):
s = n[i:i+2]
msg += self._mopp2morse(s)

return {"Protocol": protocol, "Serial": serial, "Speed": speed, "Message": msg}
txt = self._morse2txt(msg)

return {"Protocol": protocol, "Serial": serial, "Speed": speed, "Message": msg, "Text": txt}


def _mopp2morse(self, sym):
Expand All @@ -121,5 +140,19 @@ def _mopp2morse(self, sym):
logging.debug ("This should not happen: symbol ", s)
return s

def _morse2txt(self, morse):
return
def _morse2txt(self, ditcode):
s = ""
for word in ditcode.split("EOW"):
if word == '':
continue
for letter in word.split("EOC"):
if letter == '':
continue
if letter in self.morse_inv:
s += self.morse_inv[letter]
else:
s += "<" + letter + ">"

s += " "

return s.strip()
5 changes: 2 additions & 3 deletions udp_chat_server.py
Original file line number Diff line number Diff line change
Expand Up @@ -82,12 +82,11 @@ def reject(client, speed):
pass

# clean clients list
for c in receivers.items():
# FIXME: RuntimeError: dictionary changed size during iteration
for c in list(receivers.items()):
if c[1] + config.CLIENT_TIMEOUT < time.time():
ip,port = c[0].split(':')
bye_msg = ':bye'
transmit(mopp.mopp(config.CHAT_WPM, bye_msg), ip, int(port))
del receivers[c[0]]
logging.debug ("Removing expired client %s" % c[0])


81 changes: 81 additions & 0 deletions udp_client_console.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
#!/usr/local/bin/python3
# The MOPP Chat Client (UDP)

import socket
import time
import logging
from mopp import *
import config
import argparse
import sys
import select

logging.basicConfig(level=logging.DEBUG, format='%(message)s', )

argparser = argparse.ArgumentParser(description='MOPP - IP/UDP console client')
argparser.add_argument('ip', help='Server IP address')
argparser.add_argument('port', help='Server UDP port (default: 7373)', nargs='?', type=int, default=7373)

args=argparser.parse_args()

sock = socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
sock.settimeout(0.2)

speed = 20

mopp = Mopp()

def transmit (data):
if len(data) > 0:
sock.sendto(data, (args.ip, args.port))

print("### MOPP - IP/UDP console client")
print("### Speed is set to %d wpm. To change, type: #<wpm>" % speed)
print("")

# Login with hi
transmit(mopp.mopp(speed, 'hi'))


while KeyboardInterrupt:
try:
data_bytes, addr = sock.recvfrom(64)
try:
if len(data_bytes) > 0:
r = mopp.decode_message(data_bytes)
print ("Received (%d wpm): %s" % (mopp.received_speed(data_bytes), r['Text']))
except:
raise
pass

except (KeyboardInterrupt, SystemExit):
sock.close()
break
pass

except socket.timeout:
# time.sleep(0.2) # anti flood
pass

_i, _o, _e = select.select([sys.stdin], [], [], 1)
if (_i):
input = sys.stdin.readline().strip()

if input[0:1] == '#':
try:
_speed = int(input[1:])
if (_speed >= 5 and _speed <= 60):
speed = _speed
print("Speed set to %d wpm." % speed)
else:
print("Allowed speeds from 5 to 60 wpm.")

except:
pass

continue

for word in input.split(' '):
if word != '':
# print("Transmitting (%d wpm): %s" % (speed,word))
transmit(mopp.mopp(speed, word))

0 comments on commit 84281e9

Please sign in to comment.