mirror of
https://github.com/craigerl/aprsd.git
synced 2025-06-25 05:25:21 -04:00
Merge pull request #11 from hemna/py3
Fixed all pep8 errors and some py3 errors
This commit is contained in:
commit
901b17a94c
@ -1,18 +1,10 @@
|
|||||||
#!/bin/python
|
|
||||||
|
|
||||||
import argparse
|
import argparse
|
||||||
import logging
|
import logging
|
||||||
import os
|
|
||||||
import select
|
|
||||||
import signal
|
|
||||||
import socket
|
|
||||||
import sys
|
import sys
|
||||||
import time
|
import time
|
||||||
import threading
|
import socketserver
|
||||||
import Queue
|
|
||||||
|
|
||||||
from logging.handlers import RotatingFileHandler
|
from logging.handlers import RotatingFileHandler
|
||||||
from telnetsrv.green import TelnetHandler, command
|
|
||||||
|
|
||||||
from aprsd import utils
|
from aprsd import utils
|
||||||
|
|
||||||
@ -34,34 +26,9 @@ parser.add_argument("--ip",
|
|||||||
default='127.0.0.1',
|
default='127.0.0.1',
|
||||||
help="The IP to listen on ")
|
help="The IP to listen on ")
|
||||||
|
|
||||||
args = parser.parse_args()
|
|
||||||
|
|
||||||
CONFIG = None
|
CONFIG = None
|
||||||
LOG = logging.getLogger('ARPSSERVER')
|
LOG = logging.getLogger('ARPSSERVER')
|
||||||
|
|
||||||
class MyAPRSServer(TelnetHandler):
|
|
||||||
|
|
||||||
@command('echo')
|
|
||||||
def command_echo(self, params):
|
|
||||||
LOG.debug("ECHO %s" % params)
|
|
||||||
self.writeresponse(' '.join(params))
|
|
||||||
|
|
||||||
@command('user')
|
|
||||||
def command_user(self, params):
|
|
||||||
LOG.debug("User auth command")
|
|
||||||
self.writeresponse('')
|
|
||||||
|
|
||||||
@command('quit')
|
|
||||||
def command_quit(self, params):
|
|
||||||
LOG.debug("quit called")
|
|
||||||
self.writeresponse('quitting')
|
|
||||||
os.kill(os.getpid(), signal.SIGINT)
|
|
||||||
|
|
||||||
|
|
||||||
def signal_handler(signal, frame):
|
|
||||||
LOG.info("Ctrl+C, exiting.")
|
|
||||||
#sys.exit(0) # thread ignores this
|
|
||||||
os._exit(0)
|
|
||||||
|
|
||||||
# Setup the logging faciility
|
# Setup the logging faciility
|
||||||
# to disable logging to stdout, but still log to file
|
# to disable logging to stdout, but still log to file
|
||||||
@ -83,7 +50,7 @@ def setup_logging(args):
|
|||||||
log_formatter = logging.Formatter(fmt=log_format,
|
log_formatter = logging.Formatter(fmt=log_format,
|
||||||
datefmt=date_format)
|
datefmt=date_format)
|
||||||
fh = RotatingFileHandler('aprs-server.log',
|
fh = RotatingFileHandler('aprs-server.log',
|
||||||
maxBytes=(10248576*5),
|
maxBytes=(10248576 * 5),
|
||||||
backupCount=4)
|
backupCount=4)
|
||||||
fh.setFormatter(log_formatter)
|
fh.setFormatter(log_formatter)
|
||||||
LOG.addHandler(fh)
|
LOG.addHandler(fh)
|
||||||
@ -94,98 +61,33 @@ def setup_logging(args):
|
|||||||
LOG.addHandler(sh)
|
LOG.addHandler(sh)
|
||||||
|
|
||||||
|
|
||||||
class ClientThread(threading.Thread):
|
class MyAPRSTCPHandler(socketserver.BaseRequestHandler):
|
||||||
def __init__(self, msg_q, ip, port, conn, *args, **kwargs):
|
|
||||||
super(ClientThread, self).__init__()
|
|
||||||
self.msg_q = msg_q
|
|
||||||
self.ip = ip
|
|
||||||
self.port = port
|
|
||||||
self.conn = conn
|
|
||||||
LOG.info("[+] New thread started for %s:%s" % (ip, port))
|
|
||||||
|
|
||||||
def send_command(self, msg):
|
def handle(self):
|
||||||
LOG.info("Sending command '%s'" % msg)
|
# self.request is the TCP socket connected to the client
|
||||||
self.conn.send(msg)
|
self.data = self.request.recv(1024).strip()
|
||||||
|
LOG.debug("{} wrote:".format(self.client_address[0]))
|
||||||
def run(self):
|
LOG.debug(self.data)
|
||||||
while True:
|
# just send back the same data, but upper-cased
|
||||||
LOG.debug("Wait for data")
|
self.request.sendall(self.data.upper())
|
||||||
readable, writeable, exceptional = select.select([self.conn],
|
|
||||||
[], [],
|
|
||||||
1)
|
|
||||||
LOG.debug("select returned %s" % readable)
|
|
||||||
if readable:
|
|
||||||
data = self.conn.recv(2048)
|
|
||||||
LOG.info("got data '%s'" % data)
|
|
||||||
else:
|
|
||||||
try:
|
|
||||||
msg = self.msg_q.get(True, 0.05)
|
|
||||||
if msg:
|
|
||||||
LOG.info("Sending message '%s'" % msg)
|
|
||||||
self.conn.send(msg+"\n")
|
|
||||||
except Queue.Empty:
|
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
class InputThread(threading.Thread):
|
def main():
|
||||||
def __init__(self, msg_q):
|
global CONFIG
|
||||||
super(InputThread, self).__init__()
|
args = parser.parse_args()
|
||||||
self.msg_q = msg_q
|
|
||||||
LOG.info("User input thread started")
|
|
||||||
|
|
||||||
def run(self):
|
|
||||||
while True:
|
|
||||||
text = raw_input("Prompt> ")
|
|
||||||
LOG.debug("Got input '%s'" % text)
|
|
||||||
if text == 'quit':
|
|
||||||
LOG.info("Quitting Input Thread")
|
|
||||||
sys.exit(0)
|
|
||||||
else:
|
|
||||||
LOG.info("add '%s' to message Q" % text)
|
|
||||||
self.msg_q.put(text)
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
threads = []
|
|
||||||
|
|
||||||
|
|
||||||
def main(args):
|
|
||||||
global CONFIG, threads
|
|
||||||
setup_logging(args)
|
setup_logging(args)
|
||||||
LOG.info("Test APRS server starting.")
|
LOG.info("Test APRS server starting.")
|
||||||
time.sleep(1)
|
time.sleep(1)
|
||||||
signal.signal(signal.SIGINT, signal_handler)
|
|
||||||
|
|
||||||
CONFIG = utils.parse_config(args)
|
CONFIG = utils.parse_config(args)
|
||||||
|
|
||||||
msg_q = Queue.Queue()
|
|
||||||
|
|
||||||
tcpsock = socket.socket(socket.AF_INET,
|
|
||||||
socket.SOCK_STREAM)
|
|
||||||
tcpsock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
|
|
||||||
ip = CONFIG['aprs']['host']
|
ip = CONFIG['aprs']['host']
|
||||||
port = CONFIG['aprs']['port']
|
port = CONFIG['aprs']['port']
|
||||||
LOG.info("Start server listening on %s:%s" % (args.ip, args.port))
|
LOG.info("Start server listening on %s:%s" % (args.ip, args.port))
|
||||||
tcpsock.bind((ip,port))
|
|
||||||
|
|
||||||
in_t = None
|
with socketserver.TCPServer((ip, port), MyAPRSTCPHandler) as server:
|
||||||
while True:
|
server.serve_forever()
|
||||||
tcpsock.listen(4)
|
|
||||||
LOG.info("Waiting for incomming connections....")
|
|
||||||
(conn, (ip, port)) = tcpsock.accept()
|
|
||||||
newthread = ClientThread(msg_q, ip, port, conn)
|
|
||||||
newthread.start()
|
|
||||||
threads.append(newthread)
|
|
||||||
if not in_t:
|
|
||||||
in_t = InputThread(msg_q)
|
|
||||||
in_t.daemon = True
|
|
||||||
in_t.start()
|
|
||||||
in_t.join()
|
|
||||||
|
|
||||||
|
|
||||||
for t in threads:
|
|
||||||
t.join()
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
main(args)
|
main()
|
||||||
|
@ -61,10 +61,10 @@ def fuzzy(hour, minute, degree=1):
|
|||||||
if dmin == 0:
|
if dmin == 0:
|
||||||
s1 = f1
|
s1 = f1
|
||||||
pos = pos - 1
|
pos = pos - 1
|
||||||
elif dmin <= base/2:
|
elif dmin <= base / 2:
|
||||||
s1 = f2
|
s1 = f2
|
||||||
if minute < 30:
|
if minute < 30:
|
||||||
pos = pos-1
|
pos = pos - 1
|
||||||
else:
|
else:
|
||||||
s1 = f0
|
s1 = f0
|
||||||
if minute > 30:
|
if minute > 30:
|
||||||
@ -118,4 +118,6 @@ def main():
|
|||||||
print(fuzzy(h, m, deg))
|
print(fuzzy(h, m, deg))
|
||||||
return
|
return
|
||||||
|
|
||||||
main()
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
||||||
|
425
aprsd/main.py
425
aprsd/main.py
@ -31,21 +31,22 @@ import socket
|
|||||||
import pprint
|
import pprint
|
||||||
import re
|
import re
|
||||||
import signal
|
import signal
|
||||||
|
import six
|
||||||
import smtplib
|
import smtplib
|
||||||
import subprocess
|
import subprocess
|
||||||
import sys
|
import sys
|
||||||
#import telnetlib
|
# import telnetlib
|
||||||
import threading
|
import threading
|
||||||
import time
|
import time
|
||||||
import urllib
|
import urllib
|
||||||
|
|
||||||
from email.mime.text import MIMEText
|
from email.mime.text import MIMEText
|
||||||
|
import imapclient
|
||||||
|
import imaplib
|
||||||
from logging.handlers import RotatingFileHandler
|
from logging.handlers import RotatingFileHandler
|
||||||
|
|
||||||
# external lib imports
|
|
||||||
from imapclient import IMAPClient, SEEN
|
|
||||||
|
|
||||||
# local imports here
|
# local imports here
|
||||||
|
import aprsd
|
||||||
from aprsd.fuzzyclock import fuzzy
|
from aprsd.fuzzyclock import fuzzy
|
||||||
from aprsd import utils
|
from aprsd import utils
|
||||||
|
|
||||||
@ -96,7 +97,7 @@ parser.add_argument("--quiet",
|
|||||||
args = parser.parse_args()
|
args = parser.parse_args()
|
||||||
|
|
||||||
|
|
||||||
#def setup_connection():
|
# def setup_connection():
|
||||||
# global tn
|
# global tn
|
||||||
# host = CONFIG['aprs']['host']
|
# host = CONFIG['aprs']['host']
|
||||||
# port = CONFIG['aprs']['port']
|
# port = CONFIG['aprs']['port']
|
||||||
@ -115,15 +116,16 @@ def setup_connection():
|
|||||||
try:
|
try:
|
||||||
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
||||||
sock.connect((CONFIG['aprs']['host'], 14580))
|
sock.connect((CONFIG['aprs']['host'], 14580))
|
||||||
sock.settimeout(300)
|
|
||||||
|
sock.settimeout(300)
|
||||||
connected = True
|
connected = True
|
||||||
except Exception, e:
|
except Exception as e:
|
||||||
print "Unable to connect to APRS-IS server.\n"
|
print("Unable to connect to APRS-IS server.\n")
|
||||||
print str(e)
|
print(str(e))
|
||||||
time.sleep(5)
|
time.sleep(5)
|
||||||
continue
|
continue
|
||||||
#os._exit(1)
|
# os._exit(1)
|
||||||
sock_file = sock.makefile(mode='r', bufsize=0 )
|
sock_file = sock.makefile(mode='r')
|
||||||
sock.setsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY, 1) # disable nagle algorithm
|
sock.setsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY, 1) # disable nagle algorithm
|
||||||
sock.setsockopt(socket.SOL_SOCKET, socket.SO_SNDBUF, 512) # buffer size
|
sock.setsockopt(socket.SOL_SOCKET, socket.SO_SNDBUF, 512) # buffer size
|
||||||
|
|
||||||
@ -134,51 +136,153 @@ def signal_handler(signal, frame):
|
|||||||
# sys.exit(0) # thread ignores this
|
# sys.exit(0) # thread ignores this
|
||||||
os._exit(0)
|
os._exit(0)
|
||||||
|
|
||||||
# end signal_handler
|
|
||||||
|
|
||||||
|
# end signal_handler
|
||||||
def parse_email(msgid, data, server):
|
def parse_email(msgid, data, server):
|
||||||
envelope = data[b'ENVELOPE']
|
envelope = data[b'ENVELOPE']
|
||||||
f = re.search('([\.\w_-]+@[\.\w_-]+)', str(envelope.from_[0]) ) # email address match
|
# email address match
|
||||||
|
# use raw string to avoid invalid escape secquence errors r"string here"
|
||||||
|
f = re.search(r"([\.\w_-]+@[\.\w_-]+)", str(envelope.from_[0]))
|
||||||
if f is not None:
|
if f is not None:
|
||||||
from_addr = f.group(1)
|
from_addr = f.group(1)
|
||||||
else:
|
else:
|
||||||
from_addr = "noaddr"
|
from_addr = "noaddr"
|
||||||
|
LOG.debug("Got a message from '{}'".format(from_addr))
|
||||||
m = server.fetch([msgid], ['RFC822'])
|
m = server.fetch([msgid], ['RFC822'])
|
||||||
msg = email.message_from_string(m[msgid]['RFC822'])
|
msg = email.message_from_string(m[msgid][b'RFC822'].decode())
|
||||||
if msg.is_multipart():
|
if msg.is_multipart():
|
||||||
text = ""
|
text = ""
|
||||||
html = None
|
html = None
|
||||||
body = "* unreadable msg received" # default in case body somehow isn't set below - happened once
|
# default in case body somehow isn't set below - happened once
|
||||||
for part in msg.get_payload():
|
body = "* unreadable msg received"
|
||||||
if part.get_content_charset() is None:
|
for part in msg.get_payload():
|
||||||
# We cannot know the character set, so return decoded "something"
|
if part.get_content_charset() is None:
|
||||||
text = part.get_payload(decode=True)
|
# We cannot know the character set,
|
||||||
continue
|
# so return decoded "something"
|
||||||
|
text = part.get_payload(decode=True)
|
||||||
charset = part.get_content_charset()
|
continue
|
||||||
|
|
||||||
if part.get_content_type() == 'text/plain':
|
|
||||||
text = unicode(part.get_payload(decode=True), str(charset), "ignore").encode('utf8', 'replace')
|
|
||||||
|
|
||||||
if part.get_content_type() == 'text/html':
|
|
||||||
html = unicode(part.get_payload(decode=True), str(charset), "ignore").encode('utf8', 'replace')
|
|
||||||
|
|
||||||
if text is not None:
|
|
||||||
body = text.strip() # strip removes white space fore and aft of string
|
|
||||||
else:
|
|
||||||
body = html.strip()
|
|
||||||
else:
|
|
||||||
if msg.get_content_charset() == None: # email.uscc.net sends no charset, blows up unicode function below
|
|
||||||
text = unicode(msg.get_payload(decode=True), 'US-ASCII', 'ignore').encode('utf8', 'replace')
|
|
||||||
else:
|
|
||||||
text = unicode(msg.get_payload(decode=True), msg.get_content_charset(), 'ignore').encode('utf8', 'replace')
|
|
||||||
body = text.strip()
|
|
||||||
|
|
||||||
body = re.sub('<[^<]+?>', '', body) # strip all html tags
|
|
||||||
body = body.replace("\n", " ").replace("\r", " ") # strip CR/LF, make it one line, .rstrip fails at this
|
|
||||||
return(body, from_addr)
|
|
||||||
## end parse_email
|
|
||||||
|
|
||||||
|
charset = part.get_content_charset()
|
||||||
|
|
||||||
|
if part.get_content_type() == 'text/plain':
|
||||||
|
text = six.text_type(
|
||||||
|
part.get_payload(decode=True), str(charset),
|
||||||
|
"ignore").encode('utf8', 'replace')
|
||||||
|
|
||||||
|
if part.get_content_type() == 'text/html':
|
||||||
|
html = six.text_type(
|
||||||
|
part.get_payload(decode=True),
|
||||||
|
str(charset),
|
||||||
|
"ignore").encode('utf8', 'replace')
|
||||||
|
|
||||||
|
if text is not None:
|
||||||
|
# strip removes white space fore and aft of string
|
||||||
|
body = text.strip()
|
||||||
|
else:
|
||||||
|
body = html.strip()
|
||||||
|
else:
|
||||||
|
# email.uscc.net sends no charset, blows up unicode function below
|
||||||
|
if msg.get_content_charset() is None:
|
||||||
|
text = six.text_type(
|
||||||
|
msg.get_payload(decode=True),
|
||||||
|
'US-ASCII',
|
||||||
|
'ignore').encode('utf8', 'replace')
|
||||||
|
else:
|
||||||
|
text = six.text_type(
|
||||||
|
msg.get_payload(decode=True),
|
||||||
|
msg.get_content_charset(),
|
||||||
|
'ignore').encode('utf8', 'replace')
|
||||||
|
body = text.strip()
|
||||||
|
|
||||||
|
# strip all html tags
|
||||||
|
body = body.decode()
|
||||||
|
body = re.sub('<[^<]+?>', '', body)
|
||||||
|
# strip CR/LF, make it one line, .rstrip fails at this
|
||||||
|
body = body.replace("\n", " ").replace("\r", " ")
|
||||||
|
return(body, from_addr)
|
||||||
|
# end parse_email
|
||||||
|
|
||||||
|
|
||||||
|
def _imap_connect():
|
||||||
|
imap_port = CONFIG['imap'].get('port', 143)
|
||||||
|
use_ssl = CONFIG['imap'].get('use_ssl', False)
|
||||||
|
host = CONFIG['imap']['host']
|
||||||
|
msg = ("{}{}:{}".format(
|
||||||
|
'TLS ' if use_ssl else '',
|
||||||
|
host,
|
||||||
|
imap_port
|
||||||
|
))
|
||||||
|
LOG.debug("Connect to IMAP host {} with user '{}'".
|
||||||
|
format(msg, CONFIG['imap']['login']))
|
||||||
|
|
||||||
|
try:
|
||||||
|
server = imapclient.IMAPClient(CONFIG['imap']['host'], port=imap_port,
|
||||||
|
use_uid=True, ssl=use_ssl)
|
||||||
|
except Exception:
|
||||||
|
LOG.error("Failed to connect IMAP server")
|
||||||
|
return
|
||||||
|
|
||||||
|
LOG.debug("Connected to IMAP host {}".format(msg))
|
||||||
|
|
||||||
|
try:
|
||||||
|
server.login(CONFIG['imap']['login'], CONFIG['imap']['password'])
|
||||||
|
except (imaplib.IMAP4.error, Exception) as e:
|
||||||
|
msg = getattr(e, 'message', repr(e))
|
||||||
|
LOG.error("Failed to login {}".format(msg))
|
||||||
|
return
|
||||||
|
|
||||||
|
LOG.debug("Logged in to IMAP, selecting INBOX")
|
||||||
|
server.select_folder('INBOX')
|
||||||
|
return server
|
||||||
|
|
||||||
|
|
||||||
|
def _smtp_connect():
|
||||||
|
host = CONFIG['smtp']['host']
|
||||||
|
smtp_port = CONFIG['smtp']['port']
|
||||||
|
use_ssl = CONFIG['smtp'].get('use_ssl', False)
|
||||||
|
msg = ("{}{}:{}".format(
|
||||||
|
'SSL ' if use_ssl else '',
|
||||||
|
host,
|
||||||
|
smtp_port
|
||||||
|
))
|
||||||
|
LOG.debug("Connect to SMTP host {} with user '{}'".
|
||||||
|
format(msg, CONFIG['imap']['login']))
|
||||||
|
|
||||||
|
try:
|
||||||
|
if use_ssl:
|
||||||
|
server = smtplib.SMTP_SSL(host=host, port=smtp_port)
|
||||||
|
else:
|
||||||
|
server = smtplib.SMTP(host=host, port=smtp_port)
|
||||||
|
except Exception:
|
||||||
|
LOG.error("Couldn't connect to SMTP Server")
|
||||||
|
return
|
||||||
|
|
||||||
|
LOG.debug("Connected to smtp host {}".format(msg))
|
||||||
|
|
||||||
|
try:
|
||||||
|
server.login(CONFIG['smtp']['login'], CONFIG['smtp']['password'])
|
||||||
|
except Exception:
|
||||||
|
LOG.error("Couldn't connect to SMTP Server")
|
||||||
|
return
|
||||||
|
|
||||||
|
LOG.debug("Logged into SMTP server {}".format(msg))
|
||||||
|
return server
|
||||||
|
|
||||||
|
|
||||||
|
def validate_email():
|
||||||
|
"""function to simply ensure we can connect to email services.
|
||||||
|
|
||||||
|
This helps with failing early during startup.
|
||||||
|
"""
|
||||||
|
LOG.info("Checking IMAP configuration")
|
||||||
|
imap_server = _imap_connect()
|
||||||
|
LOG.info("Checking SMTP configuration")
|
||||||
|
smtp_server = _smtp_connect()
|
||||||
|
|
||||||
|
if imap_server and smtp_server:
|
||||||
|
return True
|
||||||
|
else:
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
def resend_email(count, fromcall):
|
def resend_email(count, fromcall):
|
||||||
@ -192,12 +296,11 @@ def resend_email(count, fromcall):
|
|||||||
# swap key/value
|
# swap key/value
|
||||||
shortcuts_inverted = dict([[v, k] for k, v in shortcuts.items()])
|
shortcuts_inverted = dict([[v, k] for k, v in shortcuts.items()])
|
||||||
|
|
||||||
LOG.debug("resend_email: Connect to IMAP host '%s' with user '%s'" %
|
try:
|
||||||
(CONFIG['imap']['host'],
|
server = _imap_connect()
|
||||||
CONFIG['imap']['login']))
|
except Exception as e:
|
||||||
server = IMAPClient(CONFIG['imap']['host'], use_uid=True)
|
LOG.exception("Failed to Connect to IMAP. Cannot resend email ", e)
|
||||||
server.login(CONFIG['imap']['login'], CONFIG['imap']['password'])
|
return
|
||||||
select_info = server.select_folder('INBOX')
|
|
||||||
|
|
||||||
messages = server.search(['SINCE', today])
|
messages = server.search(['SINCE', today])
|
||||||
LOG.debug("%d messages received today" % len(messages))
|
LOG.debug("%d messages received today" % len(messages))
|
||||||
@ -211,7 +314,7 @@ def resend_email(count, fromcall):
|
|||||||
# one at a time, otherwise order is random
|
# one at a time, otherwise order is random
|
||||||
(body, from_addr) = parse_email(msgid, data, server)
|
(body, from_addr) = parse_email(msgid, data, server)
|
||||||
# unset seen flag, will stay bold in email client
|
# unset seen flag, will stay bold in email client
|
||||||
server.remove_flags(msgid, [SEEN])
|
server.remove_flags(msgid, [imapclient.SEEN])
|
||||||
if from_addr in shortcuts_inverted:
|
if from_addr in shortcuts_inverted:
|
||||||
# reverse lookup of a shortcut
|
# reverse lookup of a shortcut
|
||||||
from_addr = shortcuts_inverted[from_addr]
|
from_addr = shortcuts_inverted[from_addr]
|
||||||
@ -242,53 +345,49 @@ def check_email_thread(check_email_delay):
|
|||||||
|
|
||||||
while True:
|
while True:
|
||||||
# threading.Timer(55, check_email_thread).start()
|
# threading.Timer(55, check_email_thread).start()
|
||||||
|
LOG.debug("Top of check_email_thread.")
|
||||||
|
|
||||||
time.sleep(check_email_delay)
|
time.sleep(check_email_delay)
|
||||||
|
|
||||||
shortcuts = CONFIG['shortcuts']
|
shortcuts = CONFIG['shortcuts']
|
||||||
# swap key/value
|
# swap key/value
|
||||||
shortcuts_inverted = dict([[v, k] for k, v in shortcuts.items()])
|
shortcuts_inverted = dict([[v, k] for k, v in shortcuts.items()])
|
||||||
|
|
||||||
date = datetime.datetime.now()
|
date = datetime.datetime.now()
|
||||||
month = date.strftime("%B")[:3] # Nov, Mar, Apr
|
month = date.strftime("%B")[:3] # Nov, Mar, Apr
|
||||||
day = date.day
|
day = date.day
|
||||||
year = date.year
|
year = date.year
|
||||||
today = "%s-%s-%s" % (day, month, year)
|
today = "%s-%s-%s" % (day, month, year)
|
||||||
|
|
||||||
LOG.debug("Connect to IMAP host '%s' with user '%s'" %
|
server = None
|
||||||
(CONFIG['imap']['host'],
|
|
||||||
CONFIG['imap']['login']))
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
server = IMAPClient(CONFIG['imap']['host'], use_uid=True, timeout=5)
|
server = _imap_connect()
|
||||||
server.login(CONFIG['imap']['login'], CONFIG['imap']['password'])
|
except Exception as e:
|
||||||
except Exception:
|
LOG.exception("Failed to get IMAP server Can't check email.", e)
|
||||||
LOG.exception("Failed to login with IMAP server")
|
|
||||||
#return
|
if not server:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
server.select_folder('INBOX')
|
|
||||||
|
|
||||||
messages = server.search(['SINCE', today])
|
messages = server.search(['SINCE', today])
|
||||||
LOG.debug("%d messages received today" % len(messages))
|
LOG.debug("{} messages received today".format(len(messages)))
|
||||||
|
|
||||||
for msgid, data in server.fetch(messages, ['ENVELOPE']).items():
|
for msgid, data in server.fetch(messages, ['ENVELOPE']).items():
|
||||||
envelope = data[b'ENVELOPE']
|
envelope = data[b'ENVELOPE']
|
||||||
LOG.debug('ID:%d "%s" (%s)' %
|
LOG.debug('ID:%d "%s" (%s)' %
|
||||||
(msgid, envelope.subject.decode(), envelope.date))
|
(msgid, envelope.subject.decode(), envelope.date))
|
||||||
f = re.search('([[A-a][0-9]_-]+@[[A-a][0-9]_-\.]+)',
|
f = re.search(r"'([[A-a][0-9]_-]+@[[A-a][0-9]_-\.]+)",
|
||||||
str(envelope.from_[0]))
|
str(envelope.from_[0]))
|
||||||
if f is not None:
|
if f is not None:
|
||||||
from_addr = f.group(1)
|
from_addr = f.group(1)
|
||||||
else:
|
else:
|
||||||
from_addr = "noaddr"
|
from_addr = "noaddr"
|
||||||
|
|
||||||
if "APRS" not in server.get_flags(msgid)[msgid]:
|
if "APRS" not in server.get_flags(msgid)[msgid]:
|
||||||
# if msg not flagged as sent via aprs
|
# if msg not flagged as sent via aprs
|
||||||
server.fetch([msgid], ['RFC822'])
|
server.fetch([msgid], ['RFC822'])
|
||||||
(body, from_addr) = parse_email(msgid, data, server)
|
(body, from_addr) = parse_email(msgid, data, server)
|
||||||
# unset seen flag, will stay bold in email client
|
# unset seen flag, will stay bold in email client
|
||||||
server.remove_flags(msgid, [SEEN])
|
server.remove_flags(msgid, [imapclient.SEEN])
|
||||||
|
|
||||||
if from_addr in shortcuts_inverted:
|
if from_addr in shortcuts_inverted:
|
||||||
# reverse lookup of a shortcut
|
# reverse lookup of a shortcut
|
||||||
@ -301,7 +400,7 @@ def check_email_thread(check_email_delay):
|
|||||||
# flag message as sent via aprs
|
# flag message as sent via aprs
|
||||||
server.add_flags(msgid, ['APRS'])
|
server.add_flags(msgid, ['APRS'])
|
||||||
# unset seen flag, will stay bold in email client
|
# unset seen flag, will stay bold in email client
|
||||||
server.remove_flags(msgid, [SEEN])
|
server.remove_flags(msgid, [imapclient.SEEN])
|
||||||
|
|
||||||
server.logout()
|
server.logout()
|
||||||
|
|
||||||
@ -310,14 +409,15 @@ def check_email_thread(check_email_delay):
|
|||||||
|
|
||||||
def send_ack_thread(tocall, ack, retry_count):
|
def send_ack_thread(tocall, ack, retry_count):
|
||||||
tocall = tocall.ljust(9) # pad to nine chars
|
tocall = tocall.ljust(9) # pad to nine chars
|
||||||
line = "%s>APRS::%s:ack%s\n" % (CONFIG['aprs']['login'], tocall, ack)
|
line = ("{}>APRS::{}:ack{}\n".format(
|
||||||
|
CONFIG['aprs']['login'], tocall, ack))
|
||||||
for i in range(retry_count, 0, -1):
|
for i in range(retry_count, 0, -1):
|
||||||
LOG.info("Sending ack __________________ Tx(%s)" % i)
|
LOG.info("Sending ack __________________ Tx({})".format(i))
|
||||||
LOG.info("Raw : %s" % line)
|
LOG.info("Raw : {}".format(line))
|
||||||
LOG.info("To : %s" % tocall)
|
LOG.info("To : {}".format(tocall))
|
||||||
LOG.info("Ack number : %s" % ack)
|
LOG.info("Ack number : {}".format(ack))
|
||||||
#tn.write(line)
|
# tn.write(line)
|
||||||
sock.send(line)
|
sock.send(line.encode())
|
||||||
# aprs duplicate detection is 30 secs?
|
# aprs duplicate detection is 30 secs?
|
||||||
# (21 only sends first, 28 skips middle)
|
# (21 only sends first, 28 skips middle)
|
||||||
time.sleep(31)
|
time.sleep(31)
|
||||||
@ -328,6 +428,7 @@ def send_ack_thread(tocall, ack, retry_count):
|
|||||||
def send_ack(tocall, ack):
|
def send_ack(tocall, ack):
|
||||||
retry_count = 3
|
retry_count = 3
|
||||||
thread = threading.Thread(target=send_ack_thread,
|
thread = threading.Thread(target=send_ack_thread,
|
||||||
|
name="send_ack",
|
||||||
args=(tocall, ack, retry_count))
|
args=(tocall, ack, retry_count))
|
||||||
thread.start()
|
thread.start()
|
||||||
return()
|
return()
|
||||||
@ -336,19 +437,27 @@ def send_ack(tocall, ack):
|
|||||||
|
|
||||||
def send_message_thread(tocall, message, this_message_number, retry_count):
|
def send_message_thread(tocall, message, this_message_number, retry_count):
|
||||||
global ack_dict
|
global ack_dict
|
||||||
line = (CONFIG['aprs']['login'] + ">APRS::" + tocall + ":" + message +
|
# line = (CONFIG['aprs']['login'] + ">APRS::" + tocall + ":" + message
|
||||||
"{" + str(this_message_number) + "\n")
|
# + "{" + str(this_message_number) + "\n")
|
||||||
|
line = ("{}>APRS::{}:{}{{{}\n".format(
|
||||||
|
CONFIG['aprs']['login'],
|
||||||
|
tocall, message,
|
||||||
|
str(this_message_number),
|
||||||
|
))
|
||||||
for i in range(retry_count, 0, -1):
|
for i in range(retry_count, 0, -1):
|
||||||
LOG.debug("DEBUG: send_message_thread msg:ack combos are: ")
|
LOG.debug("DEBUG: send_message_thread msg:ack combos are: ")
|
||||||
LOG.debug(pprint.pformat(ack_dict))
|
LOG.debug(pprint.pformat(ack_dict))
|
||||||
if ack_dict[this_message_number] != 1:
|
if ack_dict[this_message_number] != 1:
|
||||||
LOG.info("Sending message_______________ " +
|
LOG.info("Sending message_______________ {}(Tx{})"
|
||||||
str(this_message_number) + "(Tx" + str(i) + ")")
|
.format(
|
||||||
LOG.info("Raw : " + line)
|
str(this_message_number),
|
||||||
LOG.info("To : " + tocall)
|
str(i)
|
||||||
LOG.info("Message : " + message)
|
))
|
||||||
#tn.write(line)
|
LOG.info("Raw : {}".format(line))
|
||||||
sock.send(line)
|
LOG.info("To : {}".format(tocall))
|
||||||
|
LOG.info("Message : {}".format(message))
|
||||||
|
# tn.write(line)
|
||||||
|
sock.send(line.encode())
|
||||||
# decaying repeats, 31 to 93 second intervals
|
# decaying repeats, 31 to 93 second intervals
|
||||||
sleeptime = (retry_count - i + 1) * 31
|
sleeptime = (retry_count - i + 1) * 31
|
||||||
time.sleep(sleeptime)
|
time.sleep(sleeptime)
|
||||||
@ -383,6 +492,7 @@ def send_message(tocall, message):
|
|||||||
message = message[:67]
|
message = message[:67]
|
||||||
thread = threading.Thread(
|
thread = threading.Thread(
|
||||||
target=send_message_thread,
|
target=send_message_thread,
|
||||||
|
name="send_message",
|
||||||
args=(tocall, message, message_number, retry_count))
|
args=(tocall, message, message_number, retry_count))
|
||||||
thread.start()
|
thread.start()
|
||||||
return()
|
return()
|
||||||
@ -436,18 +546,17 @@ def send_email(to_addr, content):
|
|||||||
msg['Subject'] = subject
|
msg['Subject'] = subject
|
||||||
msg['From'] = CONFIG['smtp']['login']
|
msg['From'] = CONFIG['smtp']['login']
|
||||||
msg['To'] = to_addr
|
msg['To'] = to_addr
|
||||||
s = smtplib.SMTP_SSL(CONFIG['smtp']['host'],
|
server = _smtp_connect()
|
||||||
CONFIG['smtp']['port'])
|
if server:
|
||||||
s.login(CONFIG['smtp']['login'],
|
try:
|
||||||
CONFIG['smtp']['password'])
|
server.sendmail(CONFIG['smtp']['login'], [to_addr], msg.as_string())
|
||||||
try:
|
except Exception as e:
|
||||||
s.sendmail(CONFIG['smtp']['login'], [to_addr], msg.as_string())
|
msg = getattr(e, 'message', repr(e))
|
||||||
except Exception:
|
LOG.error("Sendmail Error!!!! '{}'", msg)
|
||||||
LOG.exception("Sendmail Error!!!!!!!!!")
|
server.quit()
|
||||||
s.quit()
|
return(-1)
|
||||||
return(-1)
|
server.quit()
|
||||||
s.quit()
|
return(0)
|
||||||
return(0)
|
|
||||||
# end send_email
|
# end send_email
|
||||||
|
|
||||||
|
|
||||||
@ -465,13 +574,13 @@ def setup_logging(args):
|
|||||||
log_level = levels[args.loglevel]
|
log_level = levels[args.loglevel]
|
||||||
|
|
||||||
LOG.setLevel(log_level)
|
LOG.setLevel(log_level)
|
||||||
log_format = ("%(asctime)s [%(threadName)-12.12s] [%(levelname)-5.5s]"
|
log_format = ("%(asctime)s [%(threadName)-12s] [%(levelname)-5.5s]"
|
||||||
" %(message)s")
|
" %(message)s")
|
||||||
date_format = '%m/%d/%Y %I:%M:%S %p'
|
date_format = '%m/%d/%Y %I:%M:%S %p'
|
||||||
log_formatter = logging.Formatter(fmt=log_format,
|
log_formatter = logging.Formatter(fmt=log_format,
|
||||||
datefmt=date_format)
|
datefmt=date_format)
|
||||||
fh = RotatingFileHandler(CONFIG['aprs']['logfile'],
|
fh = RotatingFileHandler(CONFIG['aprs']['logfile'],
|
||||||
maxBytes=(10248576*5),
|
maxBytes=(10248576 * 5),
|
||||||
backupCount=4)
|
backupCount=4)
|
||||||
fh.setFormatter(log_formatter)
|
fh.setFormatter(log_formatter)
|
||||||
LOG.addHandler(fh)
|
LOG.addHandler(fh)
|
||||||
@ -488,23 +597,31 @@ def main(args=args):
|
|||||||
|
|
||||||
CONFIG = utils.parse_config(args)
|
CONFIG = utils.parse_config(args)
|
||||||
signal.signal(signal.SIGINT, signal_handler)
|
signal.signal(signal.SIGINT, signal_handler)
|
||||||
LOG.info("APRSD Started")
|
|
||||||
LOG.debug(CONFIG)
|
|
||||||
setup_logging(args)
|
setup_logging(args)
|
||||||
|
LOG.info("APRSD Started version: {}".format(aprsd.__version__))
|
||||||
|
|
||||||
time.sleep(2)
|
time.sleep(2)
|
||||||
setup_connection()
|
setup_connection()
|
||||||
|
valid = validate_email()
|
||||||
|
if not valid:
|
||||||
|
LOG.error("Failed to validate email config options")
|
||||||
|
sys.exit(-1)
|
||||||
|
|
||||||
user = CONFIG['aprs']['login']
|
user = CONFIG['aprs']['login']
|
||||||
password = CONFIG['aprs']['password']
|
password = CONFIG['aprs']['password']
|
||||||
LOG.info("LOGIN to APRSD with user '%s'" % user)
|
|
||||||
#tn.write("user %s pass %s vers aprsd 0.99\n" % (user, password))
|
LOG.debug("LOGIN to APRSD with user '%s'" % user)
|
||||||
sock.send("user %s pass %s vers https://github.com/craigerl/aprsd 2.00\n" % (user, password))
|
msg = ("user {} pass {} vers aprsd {}\n".format(user, password,
|
||||||
|
aprsd.__version__))
|
||||||
|
sock.send(msg.encode())
|
||||||
|
|
||||||
|
|
||||||
time.sleep(2)
|
time.sleep(2)
|
||||||
|
|
||||||
check_email_delay = 60 # initial email check interval
|
check_email_delay = 60 # initial email check interval
|
||||||
checkemailthread = threading.Thread(target=check_email_thread, args=(check_email_delay, )) # args must be tuple
|
checkemailthread = threading.Thread(target=check_email_thread,
|
||||||
|
name="check_email",
|
||||||
|
args=(check_email_delay, )) # args must be tuple
|
||||||
checkemailthread.start()
|
checkemailthread.start()
|
||||||
|
|
||||||
LOG.info("Start main loop")
|
LOG.info("Start main loop")
|
||||||
@ -512,7 +629,8 @@ def main(args=args):
|
|||||||
line = ""
|
line = ""
|
||||||
try:
|
try:
|
||||||
line = sock_file.readline().strip()
|
line = sock_file.readline().strip()
|
||||||
LOG.info(line)
|
if line:
|
||||||
|
LOG.info(line)
|
||||||
searchstring = '::%s' % user
|
searchstring = '::%s' % user
|
||||||
# is aprs message to us, not beacon, status, etc
|
# is aprs message to us, not beacon, status, etc
|
||||||
if re.search(searchstring, line):
|
if re.search(searchstring, line):
|
||||||
@ -529,31 +647,40 @@ def main(args=args):
|
|||||||
continue
|
continue
|
||||||
|
|
||||||
# EMAIL (-)
|
# EMAIL (-)
|
||||||
elif re.search('^-.*', message): # is email command
|
# is email command
|
||||||
|
elif re.search('^-.*', message):
|
||||||
searchstring = '^' + CONFIG['ham']['callsign'] + '.*'
|
searchstring = '^' + CONFIG['ham']['callsign'] + '.*'
|
||||||
if re.search(searchstring, fromcall): # only I can do email
|
# only I can do email
|
||||||
r = re.search('^-([0-9])[0-9]*$', message) # digits only, first one is number of emails to resend
|
if re.search(searchstring, fromcall):
|
||||||
|
# digits only, first one is number of emails to resend
|
||||||
|
r = re.search('^-([0-9])[0-9]*$', message)
|
||||||
if r is not None:
|
if r is not None:
|
||||||
resend_email(r.group(1), fromcall)
|
resend_email(r.group(1), fromcall)
|
||||||
elif re.search('^-([A-Za-z0-9_\-\.@]+) (.*)', message): # -user@address.com body of email
|
# -user@address.com body of email
|
||||||
a = re.search('^-([A-Za-z0-9_\-\.@]+) (.*)', message) # (same search again)
|
elif re.search(r"^-([A-Za-z0-9_\-\.@]+) (.*)", message):
|
||||||
|
# (same search again)
|
||||||
|
a = re.search(r"^-([A-Za-z0-9_\-\.@]+) (.*)", message)
|
||||||
if a is not None:
|
if a is not None:
|
||||||
to_addr = a.group(1)
|
to_addr = a.group(1)
|
||||||
content = a.group(2)
|
content = a.group(2)
|
||||||
if content == 'mapme': # send recipient link to aprs.fi map
|
# send recipient link to aprs.fi map
|
||||||
content = "Click for my location: http://aprs.fi/" + CONFIG['ham']['callsign']
|
if content == 'mapme':
|
||||||
|
content = (
|
||||||
|
"Click for my location: http://aprs.fi/{}".
|
||||||
|
format(CONFIG['ham']['callsign']))
|
||||||
too_soon = 0
|
too_soon = 0
|
||||||
now = time.time()
|
now = time.time()
|
||||||
if ack in email_sent_dict: # see if we sent this msg number recently
|
# see if we sent this msg number recently
|
||||||
|
if ack in email_sent_dict:
|
||||||
timedelta = now - email_sent_dict[ack]
|
timedelta = now - email_sent_dict[ack]
|
||||||
if ( timedelta < 300 ): # five minutes
|
if (timedelta < 300): # five minutes
|
||||||
too_soon = 1
|
too_soon = 1
|
||||||
if not too_soon or ack == 0:
|
if not too_soon or ack == 0:
|
||||||
send_result = send_email(to_addr, content)
|
send_result = send_email(to_addr, content)
|
||||||
if send_result != 0:
|
if send_result != 0:
|
||||||
send_message(fromcall, "-" + to_addr + " failed")
|
send_message(fromcall, "-" + to_addr + " failed")
|
||||||
else:
|
else:
|
||||||
#send_message(fromcall, "-" + to_addr + " sent")
|
# send_message(fromcall, "-" + to_addr + " sent")
|
||||||
if len(email_sent_dict) > 98: # clear email sent dictionary if somehow goes over 100
|
if len(email_sent_dict) > 98: # clear email sent dictionary if somehow goes over 100
|
||||||
LOG.debug("DEBUG: email_sent_dict is big (" + str(len(email_sent_dict)) + ") clearing out.")
|
LOG.debug("DEBUG: email_sent_dict is big (" + str(len(email_sent_dict)) + ") clearing out.")
|
||||||
email_sent_dict.clear()
|
email_sent_dict.clear()
|
||||||
@ -570,7 +697,9 @@ def main(args=args):
|
|||||||
m = stm.tm_min
|
m = stm.tm_min
|
||||||
cur_time = fuzzy(h, m, 1)
|
cur_time = fuzzy(h, m, 1)
|
||||||
reply = cur_time + " (" + str(h) + ":" + str(m).rjust(2, '0') + "PDT)" + " (" + message.rstrip() + ")"
|
reply = cur_time + " (" + str(h) + ":" + str(m).rjust(2, '0') + "PDT)" + " (" + message.rstrip() + ")"
|
||||||
thread = threading.Thread(target = send_message, args = (fromcall, reply))
|
thread = threading.Thread(target=send_message,
|
||||||
|
name="send_message",
|
||||||
|
args=(fromcall, reply))
|
||||||
thread.start()
|
thread.start()
|
||||||
|
|
||||||
# FORTUNE (f)
|
# FORTUNE (f)
|
||||||
@ -592,33 +721,33 @@ def main(args=args):
|
|||||||
elif re.search('^[lL]', message):
|
elif re.search('^[lL]', message):
|
||||||
# get last location of a callsign, get descriptive name from weather service
|
# get last location of a callsign, get descriptive name from weather service
|
||||||
try:
|
try:
|
||||||
a = re.search('^.*\s+(.*)', message) # optional second argument is a callsign to search
|
a = re.search(r"'^.*\s+(.*)", message) # optional second argument is a callsign to search
|
||||||
if a is not None:
|
if a is not None:
|
||||||
searchcall = a.group(1)
|
searchcall = a.group(1)
|
||||||
searchcall = searchcall.upper()
|
searchcall = searchcall.upper()
|
||||||
else:
|
else:
|
||||||
searchcall = fromcall # if no second argument, search for calling station
|
searchcall = fromcall # if no second argument, search for calling station
|
||||||
url = "http://api.aprs.fi/api/get?name=" + searchcall + "&what=loc&apikey=104070.f9lE8qg34L8MZF&format=json"
|
url = "http://api.aprs.fi/api/get?name=" + searchcall + "&what=loc&apikey=104070.f9lE8qg34L8MZF&format=json"
|
||||||
response = urllib.urlopen(url)
|
response = urllib.urlopen(url)
|
||||||
aprs_data = json.loads(response.read())
|
aprs_data = json.loads(response.read())
|
||||||
lat = aprs_data['entries'][0]['lat']
|
lat = aprs_data['entries'][0]['lat']
|
||||||
lon = aprs_data['entries'][0]['lng']
|
lon = aprs_data['entries'][0]['lng']
|
||||||
try: # altitude not always provided
|
try: # altitude not always provided
|
||||||
alt = aprs_data['entries'][0]['altitude']
|
alt = aprs_data['entries'][0]['altitude']
|
||||||
except:
|
except Exception:
|
||||||
alt = 0
|
alt = 0
|
||||||
altfeet = int(alt * 3.28084)
|
altfeet = int(alt * 3.28084)
|
||||||
aprs_lasttime_seconds = aprs_data['entries'][0]['lasttime']
|
aprs_lasttime_seconds = aprs_data['entries'][0]['lasttime']
|
||||||
aprs_lasttime_seconds = aprs_lasttime_seconds.encode('ascii',errors='ignore') #unicode to ascii
|
aprs_lasttime_seconds = aprs_lasttime_seconds.encode('ascii', errors='ignore') # unicode to ascii
|
||||||
delta_seconds = time.time() - int(aprs_lasttime_seconds)
|
delta_seconds = time.time() - int(aprs_lasttime_seconds)
|
||||||
delta_hours = delta_seconds / 60 / 60
|
delta_hours = delta_seconds / 60 / 60
|
||||||
url2 = "https://forecast.weather.gov/MapClick.php?lat=" + str(lat) + "&lon=" + str(lon) + "&FcstType=json"
|
url2 = "https://forecast.weather.gov/MapClick.php?lat=" + str(lat) + "&lon=" + str(lon) + "&FcstType=json"
|
||||||
response2 = urllib.urlopen(url2)
|
response2 = urllib.urlopen(url2)
|
||||||
wx_data = json.loads(response2.read())
|
wx_data = json.loads(response2.read())
|
||||||
reply = searchcall + ": " + wx_data['location']['areaDescription'] + " " + str(altfeet) + "' " + str(lat) + "," + str(lon) + " " + str("%.1f" % round(delta_hours,1)) + "h ago"
|
reply = searchcall + ": " + wx_data['location']['areaDescription'] + " " + str(altfeet) + "' " + str(lat) + "," + str(lon) + " " + str("%.1f" % round(delta_hours, 1)) + "h ago"
|
||||||
reply = reply.encode('ascii',errors='ignore') # unicode to ascii
|
reply = reply.encode('ascii', errors='ignore') # unicode to ascii
|
||||||
send_message(fromcall, reply.rstrip())
|
send_message(fromcall, reply.rstrip())
|
||||||
except:
|
except Exception:
|
||||||
reply = "Unable to find station " + searchcall + ". Sending beacons?"
|
reply = "Unable to find station " + searchcall + ". Sending beacons?"
|
||||||
send_message(fromcall, reply.rstrip())
|
send_message(fromcall, reply.rstrip())
|
||||||
|
|
||||||
@ -666,20 +795,22 @@ def main(args=args):
|
|||||||
except Exception as e:
|
except Exception as e:
|
||||||
LOG.error("Error in mainline loop:")
|
LOG.error("Error in mainline loop:")
|
||||||
LOG.error("%s" % str(e))
|
LOG.error("%s" % str(e))
|
||||||
if str(e) == "timed out" or str(e) == "Temporary failure in name resolution" or str(e) == "Network is unreachable":
|
|
||||||
LOG.error("Attempting to reconnect.")
|
if (str(e) == "timed out" or str(e) == "Temporary failure in name resolution" or str(e) == "Network is unreachable"):
|
||||||
sock.shutdown(0)
|
LOG.error("Attempting to reconnect.")
|
||||||
sock.close()
|
sock.shutdown(0)
|
||||||
setup_connection()
|
sock.close()
|
||||||
sock.send("user %s pass %s vers https://github.com/craigerl/aprsd 2.00\n" % (user, password))
|
setup_connection()
|
||||||
continue
|
sock.send("user %s pass %s vers https://github.com/craigerl/aprsd 2.00\n" % (user, password))
|
||||||
#LOG.error("Exiting.")
|
continue
|
||||||
#os._exit(1)
|
# LOG.error("Exiting.")
|
||||||
|
# os._exit(1)
|
||||||
|
|
||||||
time.sleep(5)
|
time.sleep(5)
|
||||||
continue # don't know what failed, so wait and then continue main loop again
|
continue # don't know what failed, so wait and then continue main loop again
|
||||||
|
|
||||||
# end while True
|
# end while True
|
||||||
#tn.close()
|
# tn.close()
|
||||||
sock.shutdown(0)
|
sock.shutdown(0)
|
||||||
sock.close()
|
sock.close()
|
||||||
|
|
||||||
|
@ -53,7 +53,7 @@ def get_config():
|
|||||||
config_file = os.path.expanduser("~/.aprsd/config.yml")
|
config_file = os.path.expanduser("~/.aprsd/config.yml")
|
||||||
if os.path.exists(config_file):
|
if os.path.exists(config_file):
|
||||||
with open(config_file, "r") as stream:
|
with open(config_file, "r") as stream:
|
||||||
config = yaml.load(stream)
|
config = yaml.load(stream, Loader=yaml.FullLoader)
|
||||||
return config
|
return config
|
||||||
else:
|
else:
|
||||||
log.critical("%s is missing, please create config file" % config_file)
|
log.critical("%s is missing, please create config file" % config_file)
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
pbr
|
pbr
|
||||||
imapclient
|
imapclient
|
||||||
pyyaml
|
pyyaml
|
||||||
|
six
|
||||||
|
@ -21,6 +21,7 @@ packages =
|
|||||||
[entry_points]
|
[entry_points]
|
||||||
console_scripts =
|
console_scripts =
|
||||||
aprsd = aprsd.main:main
|
aprsd = aprsd.main:main
|
||||||
|
fake_aprs = aprsd.fake_aprs:main
|
||||||
|
|
||||||
[build_sphinx]
|
[build_sphinx]
|
||||||
source-dir = doc/source
|
source-dir = doc/source
|
||||||
|
4
tox.ini
4
tox.ini
@ -23,7 +23,7 @@ commands = sphinx-build -b html docs/source docs/html
|
|||||||
|
|
||||||
[testenv:pep8]
|
[testenv:pep8]
|
||||||
commands =
|
commands =
|
||||||
flake8 {posargs} aprsd test
|
flake8 {posargs} aprsd
|
||||||
|
|
||||||
[testenv:fast8]
|
[testenv:fast8]
|
||||||
basepython = python3
|
basepython = python3
|
||||||
@ -35,5 +35,5 @@ passenv = FAST8_NUM_COMMITS
|
|||||||
|
|
||||||
[flake8]
|
[flake8]
|
||||||
show-source = True
|
show-source = True
|
||||||
ignore = E713
|
ignore = E713,E501
|
||||||
exclude = .venv,.git,.tox,dist,doc,.ropeproject
|
exclude = .venv,.git,.tox,dist,doc,.ropeproject
|
||||||
|
Loading…
x
Reference in New Issue
Block a user