/
fldigi2habboy.py
184 lines (157 loc) · 4.33 KB
/
fldigi2habboy.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
#!/bin/env python
# dl-fldigi.exe --hab --arq-server-address 127.0.0.1 --arq-server-port 7777
# fldigi.exe --arq-server-address 127.0.0.1 --arq-server-port 7777
from __future__ import print_function
import string
import socket
import select
import time
import re
import traceback
import threading
import queue
import urllib3
def crc(i_str):
def _hex(n): return hex(int(n))[2:]
i_str = str(i_str)
CRC = 0xffff
for i in xrange(len(i_str)):
CRC ^= ord(i_str[i]) << 8
for j in xrange(8):
if (CRC & 0x8000):
CRC = (CRC << 1) ^ 0x1021
else:
CRC <<= 1
result = ''
result += _hex((CRC >> 12) & 15)
result += _hex((CRC >> 8) & 15)
result += _hex((CRC >> 4) & 15)
result += _hex(CRC & 15)
return result.lower()
def make_connection(host='localhost', port='7777'):
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
try:
port = int(port)
sock.connect(( host, port ))
sock.setblocking(0)
except:
print("fldigi2habboy: make_connection failed.")
print(traceback.format_exc())
return sock
def read_from_fldigi(sock, callback = None):
timeout_in_seconds = 10
while 1:
try:
ready = select.select([sock], [], [], timeout_in_seconds)
if ready[0]:
chunk = sock.recv(4096)
if callback:
callback(chunk)
else:
print("Waiting for some fldigi data ...")
except KeyboardInterrupt:
return
except:
print(traceback.format_exc())
class UkhasSentenceScanner(object):
'''
1. push() some characters into internal buffer
2. if a valid sentence is found, run callback(sentence)
'''
def __init__(self):
self.__buff__ = ''
self.__rex__ = re.compile( r'''(.*?)\$+(.+)(\*)(\w{4})(.*)''' )
self.__sentence_callback__ = print
def set_callback(self, cb):
self.__sentence_callback__ = cb
def push(self, chars):
# print(chars, end='')
if len(self.__buff__) > 5000:
self.__buff__ = ''
self.__buff__ += chars
sentences = self.__scan__()
for s in sentences:
self.__sentence_callback__(s)
def __scan__(self):
sentences = []
for line in string.split(self.__buff__, '\n'):
mo = self.__rex__.match( string.strip(line), re.I )
if not mo:
self.__buff__ = line
continue
if len(mo.groups()) != 5:
self.__buff__ = line #sentence might be not complete yet
continue
self.__buff__ = ''
sentence_no_crc = mo.group(2)
_crc = mo.group(4)
if crc(sentence_no_crc).lower() == _crc.lower():
sentences.append( (sentence_no_crc, _crc) )
else:
print('CRC not valid', sentence_no_crc, _crc, crc(sentence_no_crc) )
return sentences
class HabBoyBridge(object):
'''
Sends sentences to HabBoy server.
usage:
hbb = HabBoyBridge(host,port)
hbb.run() # run sending thread
hbb.push(sentence) # adds sentence to internal que
'''
def __init__(self, host = 'localhost', port = 8888):
self.__host__ = str(host)
self.__port__ = int(port)
self.__sentence_que__ = queue.Queue()
self.__run__ = False #que sending thread
self.__http__ = urllib3.PoolManager()
def push(self, sentence):
self.__sentence_que__.put(sentence)
def run(self):
self.__thread__ = threading.Thread(target = self.__send_loop__)
try:
self.__run__ = True
self.__thread__.start()
except KeyboardInterrupt:
self.stop()
def stop(self):
self.__run__ = False
if self.__thread__:
self.__thread__.join()
self.__thread__ = None
def __send_loop__(self):
while self.__run__:
try:
s = self.__sentence_que__.get(block=True, timeout=.5)
is_success = self.send(s)
print("send result OK ?", is_success)
except queue.Empty:
pass
except KeyboardInterrupt:
self.stop()
return
def send(self, sentence):
_url = 'http://{}:{}'.format(self.__host__, self.__port__)
_url += "/habboy/api/v1/sentence/fldigi/" + sentence
print("Sending sentence ", sentence, ' to ', _url)
try:
r = self.__http__.request('PUT', _url, timeout=2.0)
except:
print("Failed sending to habboy")
print(traceback.format_exc())
return False
return True
def main():
print("HabBoy connection...")
hbb = HabBoyBridge('habboy', 8888)
hbb.run()
print("Scanner")
scanner = UkhasSentenceScanner()
scanner.set_callback( lambda sent_and_crc:
hbb.send( sent_and_crc[0] + '*' + sent_and_crc[1] ) )
print("fldigi connection")
con = make_connection()
print("Connected to fldigi")
print("Go !")
read_from_fldigi( con, lambda chars: scanner.push(chars) )
if __name__ == "__main__":
main()