mirror of
				https://github.com/craigerl/aprsd.git
				synced 2025-10-30 20:30:31 -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() | ||||||
|  | |||||||
							
								
								
									
										399
									
								
								aprsd/main.py
									
									
									
									
									
								
							
							
						
						
									
										399
									
								
								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,52 +136,154 @@ 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) | ||||||
|  |                 continue | ||||||
| 
 | 
 | ||||||
|           charset = part.get_content_charset() |             charset = part.get_content_charset() | ||||||
| 
 | 
 | ||||||
|           if part.get_content_type() == 'text/plain': |             if part.get_content_type() == 'text/plain': | ||||||
|               text = unicode(part.get_payload(decode=True), str(charset), "ignore").encode('utf8', 'replace') |                 text = six.text_type( | ||||||
|  |                     part.get_payload(decode=True), str(charset), | ||||||
|  |                     "ignore").encode('utf8', 'replace') | ||||||
| 
 | 
 | ||||||
|           if part.get_content_type() == 'text/html': |             if part.get_content_type() == 'text/html': | ||||||
|               html = unicode(part.get_payload(decode=True), str(charset), "ignore").encode('utf8', 'replace') |                 html = six.text_type( | ||||||
|  |                     part.get_payload(decode=True), | ||||||
|  |                     str(charset), | ||||||
|  |                     "ignore").encode('utf8', 'replace') | ||||||
| 
 | 
 | ||||||
|           if text is not None: |             if text is not None: | ||||||
|              body = text.strip()  # strip removes white space fore and aft of string |                 # strip removes white space fore and aft of string | ||||||
|           else: |                 body = text.strip() | ||||||
|              body = html.strip() |             else: | ||||||
|  |                 body = html.strip() | ||||||
|     else: |     else: | ||||||
|          if msg.get_content_charset() == None:   # email.uscc.net sends no charset, blows up unicode function below |         # email.uscc.net sends no charset, blows up unicode function below | ||||||
|             text = unicode(msg.get_payload(decode=True), 'US-ASCII', 'ignore').encode('utf8', 'replace') |         if msg.get_content_charset() is None: | ||||||
|          else: |             text = six.text_type( | ||||||
|             text = unicode(msg.get_payload(decode=True), msg.get_content_charset(), 'ignore').encode('utf8', 'replace') |                 msg.get_payload(decode=True), | ||||||
|          body = text.strip() |                 '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() | ||||||
| 
 | 
 | ||||||
|     body = re.sub('<[^<]+?>', '', body)                  # strip all html tags |     # strip all html tags | ||||||
|     body = body.replace("\n", " ").replace("\r", " ")    # strip CR/LF, make it one line, .rstrip fails at this |     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) |     return(body, from_addr) | ||||||
| ## end parse_email | # 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): | ||||||
|     date = datetime.datetime.now() |     date = datetime.datetime.now() | ||||||
| @ -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,6 +345,7 @@ 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) | ||||||
| 
 | 
 | ||||||
| @ -255,28 +359,23 @@ def check_email_thread(check_email_delay): | |||||||
|         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) | ||||||
| @ -288,7 +387,7 @@ def check_email_thread(check_email_delay): | |||||||
|                 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