mirror of
https://github.com/craigerl/aprsd.git
synced 2025-06-24 21:15:18 -04:00
Require ~/.aprsd/config.yml
This patch completes the migration to using a config.yml file. ~/.aprsd/config.yml is now required and all options for callsign, imap, aprs user, passwords are in the config. If there is no existing ~/.aprsd/config.yml file, then the app will output a sample config and exit. This patch also adds a global logging facility that allows logging all commands to aprsd.log as well as stdout. You can disable logging to stdout by adding --quiet on the command line. You can specify the log level with --loglevel INFO. By default the log level is DEBUG. This patch also updates some formatting issues and small refactoring to ensure that the logging facility and config is read prior to starting any network connections and/or services.
This commit is contained in:
parent
4c8d9c3b2c
commit
ce7a30aa78
336
aprsd/main.py
336
aprsd/main.py
@ -1,9 +1,10 @@
|
||||
#!/usr/bin/python -u
|
||||
#
|
||||
# Listen on amateur radio aprs-is network for messages and respond to them.
|
||||
# You must have an amateur radio callsign to use this software. Put your
|
||||
# callsign in the "USER" variable and update your aprs-is password in "PASS".
|
||||
# You must also have an imap email account available for polling.
|
||||
# You must have an amateur radio callsign to use this software. You must
|
||||
# create an ~/.aprsd/config.yml file with all of the required settings. To
|
||||
# generate an example config.yml, just run aprsd, then copy the sample config
|
||||
# to ~/.aprsd/config.yml and edit the settings.
|
||||
#
|
||||
# APRS messages:
|
||||
# l(ocation) = descriptive location of calling station
|
||||
@ -21,23 +22,24 @@
|
||||
|
||||
# python included libs
|
||||
import argparse
|
||||
import json
|
||||
import urllib
|
||||
import sys
|
||||
import os
|
||||
import telnetlib
|
||||
import time
|
||||
import re
|
||||
from random import randint
|
||||
import smtplib
|
||||
from email.mime.text import MIMEText
|
||||
import subprocess
|
||||
import datetime
|
||||
import calendar
|
||||
import email
|
||||
import threading
|
||||
import signal
|
||||
import json
|
||||
import logging
|
||||
import os
|
||||
import pprint
|
||||
import re
|
||||
import signal
|
||||
import smtplib
|
||||
import subprocess
|
||||
import sys
|
||||
import telnetlib
|
||||
import threading
|
||||
import time
|
||||
import urllib
|
||||
|
||||
from email.mime.text import MIMEText
|
||||
from logging.handlers import RotatingFileHandler
|
||||
|
||||
# external lib imports
|
||||
from imapclient import IMAPClient, SEEN
|
||||
@ -46,87 +48,60 @@ from imapclient import IMAPClient, SEEN
|
||||
from aprsd.fuzzyclock import fuzzy
|
||||
import utils
|
||||
|
||||
# setup the global logger
|
||||
LOG = logging.getLogger('APRSD')
|
||||
|
||||
# global for the config yaml
|
||||
CONFIG = None
|
||||
|
||||
# localization, please edit:
|
||||
HOST = "noam.aprs2.net" # north america tier2 servers round robin
|
||||
USER = "KM6XXX-9" # callsign of this aprs client with SSID
|
||||
PASS = "99999" # google how to generate this
|
||||
BASECALLSIGN = "KM6XXX" # callsign of radio in the field to which we send email
|
||||
shortcuts = {
|
||||
"aa" : "5551239999@vtext.com",
|
||||
"cl" : "craiglamparter@somedomain.org",
|
||||
"wb" : "5553909472@vtext.com"
|
||||
}
|
||||
# HOST = "noam.aprs2.net" # north america tier2 servers round robin
|
||||
# USER = "KM6XXX-9" # callsign of this aprs client with SSID
|
||||
# PASS = "99999" # google how to generate this
|
||||
# BASECALLSIGN = "KM6XXX" # callsign of radio in the field to which we send email
|
||||
# shortcuts = {
|
||||
# "aa" : "5551239999@vtext.com",
|
||||
# "cl" : "craiglamparter@somedomain.org",
|
||||
# "wb" : "5553909472@vtext.com"
|
||||
# }
|
||||
|
||||
# globals - tell me a better way to update data being used by threads
|
||||
email_sent_dict = {} # message_number:time combos so we don't resend the same email in five mins {int:int}
|
||||
ack_dict = {} # message_nubmer:ack combos so we stop sending a message after an ack from radio {int:int}
|
||||
message_number = 0 # current aprs radio message number, increments for each message we send over rf {int}
|
||||
|
||||
# global telnet connection object
|
||||
tn = None
|
||||
|
||||
# command line args
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument("--user",
|
||||
metavar="<user>",
|
||||
default=utils.env("APRS_USER"),
|
||||
help="The callsign of this ARPS client with SSID"
|
||||
" Default=env[APRS_USER]")
|
||||
|
||||
parser.add_argument("--host",
|
||||
metavar="<host>",
|
||||
default=utils.env("APRS_HOST"),
|
||||
help="The aprs host to use Default=env[APRS_HOST]")
|
||||
parser.add_argument("--password",
|
||||
metavar="<password>",
|
||||
default=utils.env("APRS_PASSWORD"),
|
||||
help="The aprs password Default=env[APRS_PASSWORD]")
|
||||
parser.add_argument("--callsign",
|
||||
metavar="<callsign>",
|
||||
default=utils.env("APRS_CALLSIGN"),
|
||||
help="The callsign of radio in the field to which we send "
|
||||
"email Default=env[APRS_CALLSIGN]")
|
||||
parser.add_argument("--loglevel",
|
||||
default='DEBUG',
|
||||
choices=['CRITICAL', 'ERROR', 'WARNING', 'INFO', 'DEBUG'],
|
||||
help="The log level to use for aprsd.log")
|
||||
parser.add_argument("--quiet",
|
||||
action='store_true',
|
||||
help="Don't log to stdout")
|
||||
|
||||
args = parser.parse_args()
|
||||
if not args.user:
|
||||
print("Missing the aprs user (env[APRS_USER])")
|
||||
parser.print_help()
|
||||
parser.exit()
|
||||
else:
|
||||
USER = args.user
|
||||
|
||||
if not args.password:
|
||||
print("Missing the aprs password (env[APRS_PASSWORD])")
|
||||
parser.print_help()
|
||||
parser.exit()
|
||||
else:
|
||||
PASS = args.password
|
||||
|
||||
if not args.callsign:
|
||||
print("Missing the aprs callsign (env[APRS_CALLSIGN])")
|
||||
parser.print_help()
|
||||
parser.exit()
|
||||
else:
|
||||
BASECALLSIGN = args.callsign
|
||||
|
||||
|
||||
# Now read the ~/.aprds/config.yml
|
||||
config = utils.get_config()
|
||||
if 'shortcuts' in config:
|
||||
shortcuts = config['shortcuts']
|
||||
else:
|
||||
print("missing 'shortcuts' section of config.yml")
|
||||
sys.exit(-1)
|
||||
|
||||
def setup_connection():
|
||||
global tn
|
||||
host = CONFIG['aprs']['host']
|
||||
LOG.debug("Setting up telnet connection to '%s'" % host)
|
||||
try:
|
||||
tn = telnetlib.Telnet(HOST, 14580)
|
||||
tn = telnetlib.Telnet(host, 14580)
|
||||
except Exception, e:
|
||||
print "Telnet session failed.\n"
|
||||
LOG.critical("Telnet session failed.\n", e)
|
||||
sys.exit(-1)
|
||||
|
||||
|
||||
def signal_handler(signal, frame):
|
||||
print("Ctrl+C, exiting.")
|
||||
LOG.info("Ctrl+C, exiting.")
|
||||
#sys.exit(0) # thread ignores this
|
||||
os._exit(0)
|
||||
signal.signal(signal.SIGINT, signal_handler)
|
||||
|
||||
### end signal_handler
|
||||
|
||||
def parse_email(msgid, data, server):
|
||||
@ -178,15 +153,18 @@ def resend_email(count):
|
||||
year = date.year
|
||||
today = str(day) + "-" + month + "-" + str(year)
|
||||
|
||||
global shortcuts
|
||||
shortcuts = CONFIG['shortcuts']
|
||||
shortcuts_inverted = dict([[v,k] for k,v in shortcuts.items()]) # swap key/value
|
||||
|
||||
server = IMAPClient('imap.yourdomain.com', use_uid=True)
|
||||
server.login('KM6XXX@yourdomain.org', 'yourpassword')
|
||||
select_info = server.select_folder('INBOX')
|
||||
LOG.debug("resend_email: Connect to IMAP host '%s' with user '%s'" %
|
||||
(CONFIG['imap']['host'],
|
||||
CONFIG['imap']['login']))
|
||||
server = IMAPClient(CONFIG['imap']['host'], use_uid=True)
|
||||
server.login(CONFIG['imap']['login'], CONFIG['imap']['password'])
|
||||
# select_info = server.select_folder('INBOX')
|
||||
|
||||
messages = server.search(['SINCE', today])
|
||||
#print("%d messages received today" % len(messages))
|
||||
LOG.debug("%d messages received today" % len(messages))
|
||||
|
||||
msgexists = False
|
||||
|
||||
@ -216,13 +194,13 @@ def resend_email(count):
|
||||
### end resend_email()
|
||||
|
||||
def check_email_thread():
|
||||
|
||||
# print "Email thread disabled."
|
||||
# return
|
||||
|
||||
LOG.debug("Starting Email thread")
|
||||
threading.Timer(55, check_email_thread).start() # how do we skip first run?
|
||||
|
||||
global shortcuts
|
||||
shortcuts = CONFIG['shortcuts']
|
||||
shortcuts_inverted = dict([[v,k] for k,v in shortcuts.items()]) # swap key/value
|
||||
|
||||
date = datetime.datetime.now()
|
||||
@ -231,17 +209,23 @@ def check_email_thread():
|
||||
year = date.year
|
||||
today = str(day) + "-" + month + "-" + str(year)
|
||||
|
||||
server = IMAPClient('imap.yourdomain.com', use_uid=True)
|
||||
server.login('KM6XXX@yourdomain.org', 'yourpassword')
|
||||
select_info = server.select_folder('INBOX')
|
||||
LOG.debug("Connect to IMAP host '%s' with user '%s'" %
|
||||
(CONFIG['imap']['host'],
|
||||
CONFIG['imap']['login']))
|
||||
|
||||
server = IMAPClient(CONFIG['imap']['host'], use_uid=True)
|
||||
server.login(CONFIG['imap']['login'], CONFIG['imap']['password'])
|
||||
# select_info = server.select_folder('INBOX')
|
||||
|
||||
messages = server.search(['SINCE', today])
|
||||
#print("%d messages received today" % len(messages))
|
||||
LOG.debug("%d messages received today" % len(messages))
|
||||
|
||||
for msgid, data in server.fetch(messages, ['ENVELOPE']).items():
|
||||
envelope = data[b'ENVELOPE']
|
||||
#print('ID:%d "%s" (%s)' % (msgid, envelope.subject.decode(), envelope.date ))
|
||||
f = re.search('([[A-a][0-9]_-]+@[[A-a][0-9]_-\.]+)', str(envelope.from_[0]) )
|
||||
LOG.debug('ID:%d "%s" (%s)' %
|
||||
(msgid, envelope.subject.decode(), envelope.date))
|
||||
f = re.search('([[A-a][0-9]_-]+@[[A-a][0-9]_-\.]+)',
|
||||
str(envelope.from_[0]) )
|
||||
if f is not None:
|
||||
from_addr = f.group(1)
|
||||
else:
|
||||
@ -257,7 +241,7 @@ def check_email_thread():
|
||||
|
||||
reply = "-" + from_addr + " " + body
|
||||
#print "Sending message via aprs: " + reply
|
||||
send_message(BASECALLSIGN, reply) #radio
|
||||
send_message(CONFIG['ham']['callsign'], reply) #radio
|
||||
server.add_flags(msgid, ['APRS']) #flag message as sent via aprs
|
||||
server.remove_flags(msgid, [SEEN]) #unset seen flag, will stay bold in email client
|
||||
|
||||
@ -267,12 +251,12 @@ def check_email_thread():
|
||||
|
||||
def send_ack_thread(tocall, ack, retry_count):
|
||||
tocall = tocall.ljust(9) # pad to nine chars
|
||||
line = USER + ">APRS::" + tocall + ":ack" + str(ack) + "\n"
|
||||
line = CONFIG['aprs']['login'] + ">APRS::" + tocall + ":ack" + str(ack) + "\n"
|
||||
for i in range(retry_count, 0, -1):
|
||||
print "Sending ack __________________ Tx(" + str(i) + ")"
|
||||
print "Raw : " + line,
|
||||
print "To : " + tocall
|
||||
print "Ack number : " + str(ack)
|
||||
LOG.info("Sending ack __________________ Tx(" + str(i) + ")")
|
||||
LOG.info("Raw : " + line)
|
||||
LOG.info("To : " + tocall)
|
||||
LOG.info("Ack number : " + str(ack))
|
||||
tn.write(line)
|
||||
time.sleep(31) # aprs duplicate detection is 30 secs? (21 only sends first, 28 skips middle)
|
||||
return()
|
||||
@ -289,15 +273,17 @@ def send_ack(tocall, ack):
|
||||
|
||||
def send_message_thread(tocall, message, this_message_number, retry_count):
|
||||
global ack_dict
|
||||
line = USER + ">APRS::" + tocall + ":" + message + "{" + str(this_message_number) + "\n"
|
||||
line = (CONFIG['aprs']['login'] + ">APRS::" + tocall + ":" + message +
|
||||
"{" + str(this_message_number) + "\n")
|
||||
for i in range(retry_count, 0, -1):
|
||||
print "DEBUG: send_message_thread msg:ack combos are: "
|
||||
pprint.pprint(ack_dict)
|
||||
LOG.debug("DEBUG: send_message_thread msg:ack combos are: ")
|
||||
LOG.debug(pprint.pformat(ack_dict))
|
||||
if ack_dict[this_message_number] != 1:
|
||||
print "Sending message_______________ " + str(this_message_number) + "(Tx" + str(i) + ")"
|
||||
print "Raw : " + line,
|
||||
print "To : " + tocall
|
||||
print "Message : " + message
|
||||
LOG.info("Sending message_______________ " +
|
||||
str(this_message_number) + "(Tx" + str(i) + ")")
|
||||
LOG.info("Raw : " + line)
|
||||
LOG.info("To : " + tocall)
|
||||
LOG.info("Message : " + message)
|
||||
tn.write(line)
|
||||
sleeptime = (retry_count - i + 1) * 31 # decaying repeats, 31 to 93 second intervals
|
||||
time.sleep(sleeptime)
|
||||
@ -315,17 +301,19 @@ def send_message(tocall, message):
|
||||
message_number = 0
|
||||
message_number += 1
|
||||
if len(ack_dict) > 90: # empty ack dict if it's really big, could result in key error later
|
||||
print "DEBUG: Length of ack dictionary is big at " + str(len(ack_dict)) + " clearing."
|
||||
LOG.debug("DEBUG: Length of ack dictionary is big at " + str(len(ack_dict)) + " clearing.")
|
||||
ack_dict.clear()
|
||||
pprint.pprint(ack_dict)
|
||||
print "DEBUG: Cleared ack dictionary, ack_dict length is now " + str(len(ack_dict)) + "."
|
||||
LOG.debug(pprint.pformat(ack_dict))
|
||||
LOG.debug("DEBUG: Cleared ack dictionary, ack_dict length is now " + str(len(ack_dict)) + ".")
|
||||
ack_dict[message_number] = 0 # clear ack for this message number
|
||||
tocall = tocall.ljust(9) # pad to nine chars
|
||||
message = message[:67] # max? ftm400 displays 64, raw msg shows 74
|
||||
# and ftm400-send is max 64. setting this to
|
||||
# 67 displays 64 on the ftm400. (+3 {01 suffix)
|
||||
# feature req: break long ones into two msgs
|
||||
thread = threading.Thread(target = send_message_thread, args = (tocall, message, message_number, retry_count))
|
||||
thread = threading.Thread(
|
||||
target = send_message_thread,
|
||||
args = (tocall, message, message_number, retry_count))
|
||||
thread.start()
|
||||
return()
|
||||
### end send_message()
|
||||
@ -334,7 +322,7 @@ def send_message(tocall, message):
|
||||
def process_message(line):
|
||||
f = re.search('^(.*)>', line)
|
||||
fromcall = f.group(1)
|
||||
searchstring = '::' + USER + '[ ]*:(.*)' # verify this, callsign is padded out with spaces to colon
|
||||
searchstring = '::' + CONFIG['aprs']['login'] + '[ ]*:(.*)' # verify this, callsign is padded out with spaces to colon
|
||||
m = re.search(searchstring, line)
|
||||
fullmessage = m.group(1)
|
||||
|
||||
@ -346,27 +334,27 @@ def process_message(line):
|
||||
message = fullmessage
|
||||
ack_num = "0" # ack not requested, but lets send one as 0
|
||||
|
||||
print "Received message______________"
|
||||
print "Raw : " + line
|
||||
print "From : " + fromcall
|
||||
print "Message : " + message
|
||||
print "Msg number : " + str(ack_num)
|
||||
LOG.info("Received message______________")
|
||||
LOG.info("Raw : " + line)
|
||||
LOG.info("From : " + fromcall)
|
||||
LOG.info("Message : " + message)
|
||||
LOG.info("Msg number : " + str(ack_num))
|
||||
|
||||
return (fromcall, message, ack_num)
|
||||
### end process_message()
|
||||
|
||||
|
||||
def send_email(to_addr, content):
|
||||
print "Sending Email_________________"
|
||||
global shortcuts
|
||||
LOG.info("Sending Email_________________")
|
||||
shortcuts = CONFIG['shortcuts']
|
||||
if to_addr in shortcuts:
|
||||
print "To : " + to_addr ,
|
||||
LOG.info("To : " + to_addr)
|
||||
to_addr = shortcuts[to_addr]
|
||||
print " (" + to_addr + ")"
|
||||
subject = BASECALLSIGN
|
||||
LOG.info(" (" + to_addr + ")")
|
||||
subject = CONFIG['ham']['callsign']
|
||||
# content = content + "\n\n(NOTE: reply with one line)"
|
||||
print "Subject : " + subject
|
||||
print "Body : " + content
|
||||
LOG.info("Subject : " + subject)
|
||||
LOG.info("Body : " + content)
|
||||
|
||||
msg = MIMEText(content)
|
||||
msg['Subject'] = subject
|
||||
@ -376,8 +364,8 @@ def send_email(to_addr, content):
|
||||
s.login("KM6XXX@yourdomain.org", "yourpassword")
|
||||
try:
|
||||
s.sendmail("KM6XXX@yourdomain.org", [to_addr], msg.as_string())
|
||||
except Exception, e:
|
||||
print "Sendmail Error!!!!!!!!!"
|
||||
except Exception:
|
||||
LOG.exception("Sendmail Error!!!!!!!!!")
|
||||
s.quit()
|
||||
return(-1)
|
||||
s.quit()
|
||||
@ -385,15 +373,87 @@ def send_email(to_addr, content):
|
||||
### end send_email
|
||||
|
||||
|
||||
# Setup the logging faciility
|
||||
# to disable logging to stdout, but still log to file
|
||||
# use the --quiet option on the cmdln
|
||||
def setup_logging(args):
|
||||
global LOG
|
||||
levels = {
|
||||
'CRITICAL': logging.CRITICAL,
|
||||
'ERROR': logging.ERROR,
|
||||
'WARNING': logging.WARNING,
|
||||
'INFO': logging.INFO,
|
||||
'DEBUG': logging.DEBUG}
|
||||
log_level = levels[args.loglevel]
|
||||
|
||||
LOG.setLevel(log_level)
|
||||
log_format = ("%(asctime)s [%(threadName)-12.12s] [%(levelname)-5.5s]"
|
||||
" %(message)s")
|
||||
date_format = '%m/%d/%Y %I:%M:%S %p'
|
||||
log_formatter = logging.Formatter(fmt=log_format,
|
||||
datefmt=date_format)
|
||||
fh = RotatingFileHandler('aprsd.log',
|
||||
maxBytes=(10248576*5),
|
||||
backupCount=4)
|
||||
fh.setFormatter(log_formatter)
|
||||
LOG.addHandler(fh)
|
||||
|
||||
if not args.quiet:
|
||||
sh = logging.StreamHandler(sys.stdout)
|
||||
sh.setFormatter(log_formatter)
|
||||
LOG.addHandler(sh)
|
||||
|
||||
# This method tries to parse the config yaml file
|
||||
# and consume the settings.
|
||||
# If the required params don't exist,
|
||||
# it will look in the environment
|
||||
def parse_config(args):
|
||||
# for now we still use globals....ugh
|
||||
global CONFIG, LOG
|
||||
|
||||
def fail(msg):
|
||||
LOG.critical(msg)
|
||||
sys.exit(-1)
|
||||
|
||||
def check_option(config, section, name=None):
|
||||
if section in config:
|
||||
if name and name not in config[section]:
|
||||
fail("'%s' was not in '%s' section of config file" %
|
||||
(name, section))
|
||||
else:
|
||||
fail("'%s' section wasn't in config file" % section)
|
||||
|
||||
# Now read the ~/.aprds/config.yml
|
||||
config = utils.get_config()
|
||||
check_option(config, 'shortcuts')
|
||||
check_option(config, 'ham', 'callsign')
|
||||
check_option(config, 'aprs', 'login')
|
||||
check_option(config, 'aprs', 'password')
|
||||
check_option(config, 'aprs', 'host')
|
||||
check_option(config, 'imap', 'host')
|
||||
check_option(config, 'imap', 'login')
|
||||
check_option(config, 'imap', 'password')
|
||||
|
||||
CONFIG = config
|
||||
LOG.info("aprsd config loaded")
|
||||
|
||||
|
||||
### main() ###
|
||||
def main():
|
||||
def main(args=args):
|
||||
setup_logging(args)
|
||||
|
||||
LOG.info("APRSD Started")
|
||||
parse_config(args)
|
||||
LOG.debug("Signal handler setup")
|
||||
signal.signal(signal.SIGINT, signal_handler)
|
||||
|
||||
time.sleep(2)
|
||||
setup_connection()
|
||||
|
||||
tn.write("user " + USER + " pass " + PASS + " vers aprsd 0.99\n" )
|
||||
|
||||
user = CONFIG['aprs']['login']
|
||||
password = CONFIG['aprs']['password']
|
||||
LOG.info("LOGIN to APRSD with user '%s'" % user)
|
||||
tn.write("user " + user + " pass " + password + " vers aprsd 0.99\n" )
|
||||
time.sleep(2)
|
||||
|
||||
check_email_thread() # start email reader thread
|
||||
@ -404,9 +464,10 @@ def main():
|
||||
for char in tn.read_until("\n",100):
|
||||
line = line + char
|
||||
line = line.replace('\n', '')
|
||||
print line
|
||||
searchstring = '::' + USER
|
||||
if re.search(searchstring, line): # is aprs message to us, not beacon, status, etc
|
||||
LOG.info(line)
|
||||
searchstring = '::' + user
|
||||
# is aprs message to us, not beacon, status, etc
|
||||
if re.search(searchstring, line):
|
||||
(fromcall, message, ack) = process_message(line)
|
||||
else:
|
||||
message = "noise"
|
||||
@ -414,13 +475,14 @@ def main():
|
||||
|
||||
# ACK (ack##)
|
||||
if re.search('^ack[0-9]+', message):
|
||||
a = re.search('^ack([0-9]+)', message) # put message_number:1 in dict to record the ack
|
||||
# put message_number:1 in dict to record the ack
|
||||
a = re.search('^ack([0-9]+)', message)
|
||||
ack_dict.update({int(a.group(1)):1})
|
||||
continue
|
||||
|
||||
# EMAIL (-)
|
||||
elif re.search('^-.*', message): # is email command
|
||||
searchstring = '^' + BASECALLSIGN + '.*'
|
||||
searchstring = '^' + CONFIG['ham']['callsign'] + '.*'
|
||||
if re.search(searchstring, fromcall): # only I can do email
|
||||
r = re.search('^-([0-9])[0-9]*$', message) # digits only, first one is number of emails to resend
|
||||
if r is not None:
|
||||
@ -431,7 +493,7 @@ def main():
|
||||
to_addr = a.group(1)
|
||||
content = a.group(2)
|
||||
if content == 'mapme': # send recipient link to aprs.fi map
|
||||
content = "Click for my location: http://aprs.fi/" + BASECALLSIGN
|
||||
content = "Click for my location: http://aprs.fi/" + CONFIG['ham']['callsign']
|
||||
too_soon = 0
|
||||
now = time.time()
|
||||
if ack in email_sent_dict: # see if we sent this msg number recently
|
||||
@ -445,11 +507,11 @@ def main():
|
||||
else:
|
||||
#send_message(fromcall, "-" + to_addr + " sent")
|
||||
if len(email_sent_dict) > 98: # clear email sent dictionary if somehow goes over 100
|
||||
print "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[ack] = now
|
||||
else:
|
||||
print "\nEmail for message number " + ack + " recently sent, not sending again.\n"
|
||||
LOG.info("Email for message number " + ack + " recently sent, not sending again.")
|
||||
else:
|
||||
send_message(fromcall, "Bad email address")
|
||||
|
||||
@ -534,9 +596,9 @@ def main():
|
||||
send_ack(fromcall, ack) # send an ack last
|
||||
|
||||
except Exception, e:
|
||||
print "Error in mainline loop:"
|
||||
print "%s" % str(e)
|
||||
print "Exiting."
|
||||
LOG.error("Error in mainline loop:")
|
||||
LOG.error("%s" % str(e))
|
||||
LOG.error("Exiting.")
|
||||
#sys.exit(1) # merely a suggestion
|
||||
os._exit(1)
|
||||
|
||||
@ -546,4 +608,4 @@ def main():
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
main(args)
|
||||
|
@ -1,12 +1,20 @@
|
||||
"""Utilities and helper functions."""
|
||||
|
||||
import logging
|
||||
import os
|
||||
import pprint
|
||||
import sys
|
||||
import yaml
|
||||
|
||||
# an example of what should be in the ~/.aprsd/config.yml
|
||||
example_config = '''
|
||||
ham:
|
||||
callsign: KFART
|
||||
|
||||
aprs:
|
||||
login: someusername
|
||||
password: password
|
||||
host: noam.aprs2.net
|
||||
|
||||
shortcuts:
|
||||
'aa': '5551239999@vtext.com'
|
||||
'cl': 'craiglamparter@somedomain.org'
|
||||
@ -19,12 +27,10 @@ smtp:
|
||||
imap:
|
||||
login: imapuser
|
||||
password: something dumb
|
||||
|
||||
ham:
|
||||
callsign: something
|
||||
basename: somebasename
|
||||
'''
|
||||
|
||||
log = logging.getLogger('APRSD')
|
||||
|
||||
def env(*vars, **kwargs):
|
||||
"""This returns the first environment variable set.
|
||||
if none are non-empty, defaults to '' or keyword arg default
|
||||
@ -44,6 +50,6 @@ def get_config():
|
||||
config = yaml.load(stream)
|
||||
return config
|
||||
else:
|
||||
print("%s is missing, please create a config file" % config_file)
|
||||
print("example config is\n %s" % example_config)
|
||||
log.critical("%s is missing, please create a config file" % config_file)
|
||||
print("\nCopy to ~/.aprsd/config.yml and edit\n\nSample config:\n %s" % example_config)
|
||||
sys.exit(-1)
|
||||
|
Loading…
x
Reference in New Issue
Block a user