second iteration of morse code plugin, provided by braph

This commit is contained in:
Thorsten
2016-08-13 02:32:08 +02:00
parent cde081dad2
commit e0385a7db3
+176
View File
@@ -0,0 +1,176 @@
# -*- coding: utf-8 -*-
import logging
import re
from plugin_system import pluginfunction, ptypes
from rate_limit import RATE_FUN, RATE_GLOBAL
log = logging.getLogger(__name__)
# copy from https://de.wikipedia.org/wiki/Morsezeichen
raw_wiki_copy = """
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− − · ·
1· − − − −
2· · − − −
3· · · − −
4· · · · −
5· · · · ·
6− · · · ·
7− − · · ·
8− − − · ·
9− − − − ·
0− − − − −
"""
# machen dictionary aus wikipaste
def wiki_paste_to_morse_dict(wikicopy):
wikicopy = wikicopy.replace(' ', '')
morse_dict = {l[0]: l[1:] for l in wikicopy.splitlines() if l}
return morse_dict
ascii_morse = wiki_paste_to_morse_dict(raw_wiki_copy)
morse_ascii = {v: k for k, v in ascii_morse.items()}
# return a dictionary of possible morse-chars as key
# and their count as value
def possible_morse_chars(string):
"""
returns dit,dah or None
"""
stats = {}
for c in re.sub("[\w\d ]", '', string):
try:
stats[c] += 1
except KeyError:
stats[c] = 1
return stats
# return morse-encoded string
def morse_encode(string, dot='·', dash='−', sep=' ', ignore_unknown=False):
morse_codes = []
for char in string.upper():
try:
morse_codes.append(ascii_morse[char].replace('·', dot).replace('−', dash))
except KeyError:
if not ignore_unknown:
morse_codes.append(char)
return sep.join(morse_codes)
# return morse-decoded string with number of errors as tuple
# -> (decoded string, num errors)
def morse_decode(string, dot=None, dash=None):
"""
decode a "morse string" to ascii text
uses \s{2,} as word separator
"""
# dot and dash given, just decode
if dot and dash:
errors = 0
words = []
# drawback: does not allow single characters.
for match in re.finditer('([{dit}{dah}]+((?:\\s)[{dit}{dah}]+)+|\w+)'.format(dit=dot, dah=dash), string):
word = match.group()
log.debug("morse word: ", word)
if any([dot in word, dash in word]):
w = []
for morse_character in word.split():
try:
character = morse_ascii[morse_character.replace(dot, '·').replace(dash, '−')]
print("Converted \t{} \tto {}".format(morse_character, character))
except KeyError:
character = morse_character
errors += 1
w.append(character)
words.append(''.join(w))
# words.append(''.join([morse_ascii[x.replace(dot, '·').replace(dash, '−')] for x in word.split()]))
else:
words.append(word)
return ' '.join(words), errors
# dot/dash given, search for dash/dot
else:
if not dash:
dash_stats = {x: string.count(x) for x in '-−_'}
dash = max(dash_stats, key=dash_stats.get)
if not dot:
dot_stats = {x: string.count(x) for x in '.·*'}
dot = max(dot_stats, key=dot_stats.get)
return morse_decode(string, dot=dot, dash=dash)
@pluginfunction('morse-encode', 'encode string to morse', ptypes.COMMAND, ratelimit_class=RATE_FUN | RATE_GLOBAL)
def command_morse_encode(argv, **args):
if not argv:
return {
'msg': args['reply_user'] + "usage: morse-encode <string>"
}
if len(argv) == 1 and argv[0] == 'that':
message_stack = args['stack']
if not message_stack[-1]:
return
message = message_stack[-1]['body']
else:
message = ' '.join(argv)
return {
'msg': args['reply_user'] + ': %s' % morse_encode(message)
}
@pluginfunction('morse-decode', 'decode morse encoded string', ptypes.COMMAND, ratelimit_class=RATE_FUN | RATE_GLOBAL)
def command_morse_decode(argv, **args):
if not argv:
return {
'msg': args['reply_user'] + "usage: morse-decode <string>"
}
if len(argv) == 1 and argv[0] == 'that':
message_stack = args['stack']
if not message_stack[-1]:
return
message = message_stack[-1]['body']
else:
message = ' '.join(argv)
decoded, errors = morse_decode(message, dot='·', dash='-')
return {
'msg': args['reply_user'] + ': %s (%d errors)' % (decoded, errors)
}