mirror of
https://github.com/craigerl/aprsd.git
synced 2025-06-25 13:35:20 -04:00
commit
26ca8563f9
294
aprsd.py
294
aprsd.py
@ -323,165 +323,167 @@ def send_email(to_addr, content):
|
|||||||
|
|
||||||
|
|
||||||
### main() ###
|
### main() ###
|
||||||
try:
|
def main():
|
||||||
tn = telnetlib.Telnet(HOST, 14580)
|
|
||||||
except Exception, e:
|
|
||||||
print "Telnet session failed.\n"
|
|
||||||
sys.exit(-1)
|
|
||||||
|
|
||||||
time.sleep(2)
|
|
||||||
|
|
||||||
tn.write("user " + USER + " pass " + PASS + " vers aprsd 0.99\n" )
|
|
||||||
|
|
||||||
time.sleep(2)
|
|
||||||
|
|
||||||
check_email_thread() # start email reader thread
|
|
||||||
|
|
||||||
while True:
|
|
||||||
line = ""
|
|
||||||
try:
|
try:
|
||||||
for char in tn.read_until("\n",100):
|
tn = telnetlib.Telnet(HOST, 14580)
|
||||||
line = line + char
|
except Exception, e:
|
||||||
line = line.replace('\n', '')
|
print "Telnet session failed.\n"
|
||||||
print line
|
sys.exit(-1)
|
||||||
searchstring = '::' + USER
|
|
||||||
if re.search(searchstring, line): # is aprs message to us, not beacon, status, etc
|
|
||||||
(fromcall, message, ack) = process_message(line)
|
|
||||||
else:
|
|
||||||
message = "noise"
|
|
||||||
continue
|
|
||||||
|
|
||||||
# ACK (ack##)
|
time.sleep(2)
|
||||||
if re.search('^ack[0-9]+', message):
|
|
||||||
a = re.search('^ack([0-9]+)', message) # put message_number:1 in dict to record the ack
|
|
||||||
ack_dict.update({int(a.group(1)):1})
|
|
||||||
continue
|
|
||||||
|
|
||||||
# EMAIL (-)
|
tn.write("user " + USER + " pass " + PASS + " vers aprsd 0.99\n" )
|
||||||
elif re.search('^-.*', message): # is email command
|
|
||||||
searchstring = '^' + BASECALLSIGN + '.*'
|
|
||||||
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:
|
|
||||||
resend_email(r.group(1))
|
|
||||||
elif re.search('^-([A-Za-z0-9_\-\.@]+) (.*)', message): # -user@address.com body of email
|
|
||||||
a = re.search('^-([A-Za-z0-9_\-\.@]+) (.*)', message) # (same search again)
|
|
||||||
if a is not None:
|
|
||||||
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
|
|
||||||
too_soon = 0
|
|
||||||
now = time.time()
|
|
||||||
if ack in email_sent_dict: # see if we sent this msg number recently
|
|
||||||
timedelta = now - email_sent_dict[ack]
|
|
||||||
if ( timedelta < 300 ): # five minutes
|
|
||||||
too_soon = 1
|
|
||||||
if not too_soon or ack == 0:
|
|
||||||
send_result = send_email(to_addr, content)
|
|
||||||
if send_result != 0:
|
|
||||||
send_message(fromcall, "-" + to_addr + " failed")
|
|
||||||
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."
|
|
||||||
email_sent_dict.clear()
|
|
||||||
email_sent_dict[ack] = now
|
|
||||||
else:
|
|
||||||
print "\nEmail for message number " + ack + " recently sent, not sending again.\n"
|
|
||||||
else:
|
|
||||||
send_message(fromcall, "Bad email address")
|
|
||||||
|
|
||||||
# TIME (t)
|
time.sleep(2)
|
||||||
elif re.search('^t', message):
|
|
||||||
stm = time.localtime()
|
|
||||||
h = stm.tm_hour
|
|
||||||
m = stm.tm_min
|
|
||||||
cur_time = fuzzy(h, m, 1)
|
|
||||||
reply = cur_time + " (" + str(h) + ":" + str(m).rjust(2, '0') + "PDT)" + " (" + message.rstrip() + ")"
|
|
||||||
thread = threading.Thread(target = send_message, args = (fromcall, reply))
|
|
||||||
thread.start()
|
|
||||||
|
|
||||||
# FORTUNE (f)
|
check_email_thread() # start email reader thread
|
||||||
elif re.search('^f', message):
|
|
||||||
process = subprocess.Popen(['/usr/games/fortune', '-s', '-n 60'], stdout=subprocess.PIPE)
|
|
||||||
reply = process.communicate()[0]
|
|
||||||
send_message(fromcall, reply.rstrip())
|
|
||||||
|
|
||||||
# PING (p)
|
while True:
|
||||||
elif re.search('^p', message):
|
line = ""
|
||||||
stm = time.localtime()
|
try:
|
||||||
h = stm.tm_hour
|
for char in tn.read_until("\n",100):
|
||||||
m = stm.tm_min
|
line = line + char
|
||||||
s = stm.tm_sec
|
line = line.replace('\n', '')
|
||||||
reply = "Pong! " + str(h).zfill(2) + ":" + str(m).zfill(2) + ":" + str(s).zfill(2)
|
print line
|
||||||
send_message(fromcall, reply.rstrip())
|
searchstring = '::' + USER
|
||||||
|
if re.search(searchstring, line): # is aprs message to us, not beacon, status, etc
|
||||||
|
(fromcall, message, ack) = process_message(line)
|
||||||
|
else:
|
||||||
|
message = "noise"
|
||||||
|
continue
|
||||||
|
|
||||||
# LOCATION (l) "8 Miles E Auburn CA 1771' 38.91547,-120.99500 0.1h ago"
|
# ACK (ack##)
|
||||||
elif re.search('^l', message):
|
if re.search('^ack[0-9]+', message):
|
||||||
# get my last location, get descriptive name from weather service
|
a = re.search('^ack([0-9]+)', message) # put message_number:1 in dict to record the ack
|
||||||
try:
|
ack_dict.update({int(a.group(1)):1})
|
||||||
url = "http://api.aprs.fi/api/get?name=" + fromcall + "&what=loc&apikey=104070.f9lE8qg34L8MZF&format=json"
|
continue
|
||||||
response = urllib.urlopen(url)
|
|
||||||
aprs_data = json.loads(response.read())
|
# EMAIL (-)
|
||||||
lat = aprs_data['entries'][0]['lat']
|
elif re.search('^-.*', message): # is email command
|
||||||
lon = aprs_data['entries'][0]['lng']
|
searchstring = '^' + BASECALLSIGN + '.*'
|
||||||
try: # altitude not always provided
|
if re.search(searchstring, fromcall): # only I can do email
|
||||||
alt = aprs_data['entries'][0]['altitude']
|
r = re.search('^-([0-9])[0-9]*$', message) # digits only, first one is number of emails to resend
|
||||||
except:
|
if r is not None:
|
||||||
alt = 0
|
resend_email(r.group(1))
|
||||||
altfeet = int(alt * 3.28084)
|
elif re.search('^-([A-Za-z0-9_\-\.@]+) (.*)', message): # -user@address.com body of email
|
||||||
aprs_lasttime_seconds = aprs_data['entries'][0]['lasttime']
|
a = re.search('^-([A-Za-z0-9_\-\.@]+) (.*)', message) # (same search again)
|
||||||
aprs_lasttime_seconds = aprs_lasttime_seconds.encode('ascii',errors='ignore') #unicode to ascii
|
if a is not None:
|
||||||
delta_seconds = time.time() - int(aprs_lasttime_seconds)
|
to_addr = a.group(1)
|
||||||
delta_hours = delta_seconds / 60 / 60
|
content = a.group(2)
|
||||||
url2 = "https://forecast.weather.gov/MapClick.php?lat=" + str(lat) + "&lon=" + str(lon) + "&FcstType=json"
|
if content == 'mapme': # send recipient link to aprs.fi map
|
||||||
response2 = urllib.urlopen(url2)
|
content = "Click for my location: http://aprs.fi/" + BASECALLSIGN
|
||||||
wx_data = json.loads(response2.read())
|
too_soon = 0
|
||||||
reply = wx_data['location']['areaDescription'] + " " + str(altfeet) + "' " + str(lat) + "," + str(lon) + " " + str("%.1f" % round(delta_hours,1)) + "h ago"
|
now = time.time()
|
||||||
reply = reply.encode('ascii',errors='ignore') # unicode to ascii
|
if ack in email_sent_dict: # see if we sent this msg number recently
|
||||||
send_message(fromcall, reply.rstrip())
|
timedelta = now - email_sent_dict[ack]
|
||||||
except:
|
if ( timedelta < 300 ): # five minutes
|
||||||
reply = "Unable to find you (send beacon?)"
|
too_soon = 1
|
||||||
|
if not too_soon or ack == 0:
|
||||||
|
send_result = send_email(to_addr, content)
|
||||||
|
if send_result != 0:
|
||||||
|
send_message(fromcall, "-" + to_addr + " failed")
|
||||||
|
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."
|
||||||
|
email_sent_dict.clear()
|
||||||
|
email_sent_dict[ack] = now
|
||||||
|
else:
|
||||||
|
print "\nEmail for message number " + ack + " recently sent, not sending again.\n"
|
||||||
|
else:
|
||||||
|
send_message(fromcall, "Bad email address")
|
||||||
|
|
||||||
|
# TIME (t)
|
||||||
|
elif re.search('^t', message):
|
||||||
|
stm = time.localtime()
|
||||||
|
h = stm.tm_hour
|
||||||
|
m = stm.tm_min
|
||||||
|
cur_time = fuzzy(h, m, 1)
|
||||||
|
reply = cur_time + " (" + str(h) + ":" + str(m).rjust(2, '0') + "PDT)" + " (" + message.rstrip() + ")"
|
||||||
|
thread = threading.Thread(target = send_message, args = (fromcall, reply))
|
||||||
|
thread.start()
|
||||||
|
|
||||||
|
# FORTUNE (f)
|
||||||
|
elif re.search('^f', message):
|
||||||
|
process = subprocess.Popen(['/usr/games/fortune', '-s', '-n 60'], stdout=subprocess.PIPE)
|
||||||
|
reply = process.communicate()[0]
|
||||||
send_message(fromcall, reply.rstrip())
|
send_message(fromcall, reply.rstrip())
|
||||||
|
|
||||||
# WEATHER (w) "42F(68F/48F) Haze. Tonight, Haze then Chance Rain."
|
# PING (p)
|
||||||
elif re.search('^w', message):
|
elif re.search('^p', message):
|
||||||
# get my last location from aprsis then get weather from weather service
|
stm = time.localtime()
|
||||||
try:
|
h = stm.tm_hour
|
||||||
url = "http://api.aprs.fi/api/get?name=" + fromcall + "&what=loc&apikey=104070.f9lE8qg34L8MZF&format=json"
|
m = stm.tm_min
|
||||||
response = urllib.urlopen(url)
|
s = stm.tm_sec
|
||||||
aprs_data = json.loads(response.read())
|
reply = "Pong! " + str(h).zfill(2) + ":" + str(m).zfill(2) + ":" + str(s).zfill(2)
|
||||||
lat = aprs_data['entries'][0]['lat']
|
|
||||||
lon = aprs_data['entries'][0]['lng']
|
|
||||||
url2 = "https://forecast.weather.gov/MapClick.php?lat=" + str(lat) + "&lon=" + str(lon) + "&FcstType=json"
|
|
||||||
response2 = urllib.urlopen(url2)
|
|
||||||
wx_data = json.loads(response2.read())
|
|
||||||
reply = wx_data['currentobservation']['Temp'] + "F(" + wx_data['data']['temperature'][0] + "F/" + wx_data['data']['temperature'][1] + "F) " + wx_data['data']['weather'][0] + ". " + wx_data['time']['startPeriodName'][1] + ", " + wx_data['data']['weather'][1] + "."
|
|
||||||
reply = reply.encode('ascii',errors='ignore') # unicode to ascii
|
|
||||||
send_message(fromcall, reply.rstrip())
|
send_message(fromcall, reply.rstrip())
|
||||||
except:
|
|
||||||
reply = "Unable to find you (send beacon?)"
|
# LOCATION (l) "8 Miles E Auburn CA 1771' 38.91547,-120.99500 0.1h ago"
|
||||||
|
elif re.search('^l', message):
|
||||||
|
# get my last location, get descriptive name from weather service
|
||||||
|
try:
|
||||||
|
url = "http://api.aprs.fi/api/get?name=" + fromcall + "&what=loc&apikey=104070.f9lE8qg34L8MZF&format=json"
|
||||||
|
response = urllib.urlopen(url)
|
||||||
|
aprs_data = json.loads(response.read())
|
||||||
|
lat = aprs_data['entries'][0]['lat']
|
||||||
|
lon = aprs_data['entries'][0]['lng']
|
||||||
|
try: # altitude not always provided
|
||||||
|
alt = aprs_data['entries'][0]['altitude']
|
||||||
|
except:
|
||||||
|
alt = 0
|
||||||
|
altfeet = int(alt * 3.28084)
|
||||||
|
aprs_lasttime_seconds = aprs_data['entries'][0]['lasttime']
|
||||||
|
aprs_lasttime_seconds = aprs_lasttime_seconds.encode('ascii',errors='ignore') #unicode to ascii
|
||||||
|
delta_seconds = time.time() - int(aprs_lasttime_seconds)
|
||||||
|
delta_hours = delta_seconds / 60 / 60
|
||||||
|
url2 = "https://forecast.weather.gov/MapClick.php?lat=" + str(lat) + "&lon=" + str(lon) + "&FcstType=json"
|
||||||
|
response2 = urllib.urlopen(url2)
|
||||||
|
wx_data = json.loads(response2.read())
|
||||||
|
reply = 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
|
||||||
|
send_message(fromcall, reply.rstrip())
|
||||||
|
except:
|
||||||
|
reply = "Unable to find you (send beacon?)"
|
||||||
|
send_message(fromcall, reply.rstrip())
|
||||||
|
|
||||||
|
# WEATHER (w) "42F(68F/48F) Haze. Tonight, Haze then Chance Rain."
|
||||||
|
elif re.search('^w', message):
|
||||||
|
# get my last location from aprsis then get weather from weather service
|
||||||
|
try:
|
||||||
|
url = "http://api.aprs.fi/api/get?name=" + fromcall + "&what=loc&apikey=104070.f9lE8qg34L8MZF&format=json"
|
||||||
|
response = urllib.urlopen(url)
|
||||||
|
aprs_data = json.loads(response.read())
|
||||||
|
lat = aprs_data['entries'][0]['lat']
|
||||||
|
lon = aprs_data['entries'][0]['lng']
|
||||||
|
url2 = "https://forecast.weather.gov/MapClick.php?lat=" + str(lat) + "&lon=" + str(lon) + "&FcstType=json"
|
||||||
|
response2 = urllib.urlopen(url2)
|
||||||
|
wx_data = json.loads(response2.read())
|
||||||
|
reply = wx_data['currentobservation']['Temp'] + "F(" + wx_data['data']['temperature'][0] + "F/" + wx_data['data']['temperature'][1] + "F) " + wx_data['data']['weather'][0] + ". " + wx_data['time']['startPeriodName'][1] + ", " + wx_data['data']['weather'][1] + "."
|
||||||
|
reply = reply.encode('ascii',errors='ignore') # unicode to ascii
|
||||||
|
send_message(fromcall, reply.rstrip())
|
||||||
|
except:
|
||||||
|
reply = "Unable to find you (send beacon?)"
|
||||||
|
send_message(fromcall, reply)
|
||||||
|
|
||||||
|
# USAGE
|
||||||
|
else:
|
||||||
|
reply = "usage: time, fortune, loc, weath, -emailaddr emailbody, -#(resend)"
|
||||||
send_message(fromcall, reply)
|
send_message(fromcall, reply)
|
||||||
|
|
||||||
|
time.sleep(1) # let any threads do their thing, then ack
|
||||||
|
send_ack(fromcall, ack) # send an ack last
|
||||||
|
|
||||||
# USAGE
|
except Exception, e:
|
||||||
else:
|
print "Error in mainline loop:"
|
||||||
reply = "usage: time, fortune, loc, weath, -emailaddr emailbody, -#(resend)"
|
print "%s" % str(e)
|
||||||
send_message(fromcall, reply)
|
print "Exiting."
|
||||||
|
#sys.exit(1) # merely a suggestion
|
||||||
|
os._exit(1)
|
||||||
|
|
||||||
time.sleep(1) # let any threads do their thing, then ack
|
# end while True
|
||||||
send_ack(fromcall, ack) # send an ack last
|
tn.close()
|
||||||
|
exit()
|
||||||
|
|
||||||
except Exception, e:
|
|
||||||
print "Error in mainline loop:"
|
|
||||||
print "%s" % str(e)
|
|
||||||
print "Exiting."
|
|
||||||
#sys.exit(1) # merely a suggestion
|
|
||||||
os._exit(1)
|
|
||||||
|
|
||||||
# end while True
|
if __name__ == "__main__":
|
||||||
|
main()
|
||||||
tn.close()
|
|
||||||
|
|
||||||
exit()
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user