qrzlogger now queries CALL if CALL/SUFFIX could not be found

better exception handling for ctrl+c and ctrl+d
implemented gracefull exit handling
qrzlogger no longer asks the user to continue if no call data was found
This commit is contained in:
Michael Clemens 2021-06-04 00:47:49 +02:00
parent f704297c14
commit b2665aaf42
2 changed files with 109 additions and 97 deletions

View File

@ -1,6 +1,6 @@
[metadata] [metadata]
name = qrzlogger name = qrzlogger
version = 0.6.5 version = 0.6.6
author = Michael Clemens author = Michael Clemens
author_email = qrzlogger@qrz.is author_email = qrzlogger@qrz.is
description = A python application to log QSOs directly to QRZ.com from the command line description = A python application to log QSOs directly to QRZ.com from the command line

View File

@ -32,6 +32,8 @@ from datetime import date
from datetime import timezone from datetime import timezone
import configparser import configparser
from colored import fore, back, style from colored import fore, back, style
import signal
import atexit
class QRZLogger(): class QRZLogger():
@ -39,7 +41,7 @@ class QRZLogger():
# initialize things # initialize things
def __init__(self): def __init__(self):
self.version = "0.6.5" self.version = "0.6.6"
# Define the configuration object # Define the configuration object
self.config = configparser.ConfigParser() self.config = configparser.ConfigParser()
@ -152,6 +154,25 @@ class QRZLogger():
return config return config
# returns the actual call sign without any indicators
# (e.g, "/p" or "F/")
def removeIndicators(self, call):
cleaned_call = call
if call.endswith(("/P","/M","/QRP")):
cleaned_call = re.sub(r'/\w$', "", call)
if "/" in cleaned_call:
cleaned_call = re.sub(r'^\w+/', "", cleaned_call)
return cleaned_call
# Print the table object to stdout
def printTable(self, tab):
print(self.tablecol)
print(tab)
print(style.RESET)
##################################################### #####################################################
# QRZ.com API Functions # # QRZ.com API Functions #
##################################################### #####################################################
@ -452,18 +473,13 @@ class QRZLogger():
return questions return questions
# ask a user a simple y/n question def handler(signum, frame):
# returns True if "y" return None
# returns False in "n"
def askUser(self, question):
while True: # Prints a message when the application is terminated
inp = input("\n" + self.inputcol + question + " [" + self.defvalcol + "y/n/quit" + self.inputcol + "]: " + style.RESET) def quit_gracefully():
if inp == "y": print("\n73!\n")
return True
elif inp == "n":
return False
elif inp == "quit":
sys.exit()
@ -471,9 +487,11 @@ class QRZLogger():
# Main Routine # # Main Routine #
##################################################### #####################################################
def main(): def main():
signal.signal(signal.SIGINT, handler)
atexit.register(quit_gracefully)
q = QRZLogger() q = QRZLogger()
q.printBanner() q.printBanner()
@ -482,95 +500,89 @@ def main():
# Begin the main loop # Begin the main loop
while keeponlogging: while keeponlogging:
try: # get a session after logging into QRZ with user/pass
# get a session after logging into QRZ with user/pass session_key = q.get_session()
session_key = q.get_session() # query a call sign from the user
# query a call sign from the user call = input("\n\n%sEnter Callsign:%s " % (q.inputcol, style.RESET))
resume = True if call == "quit":
call = input("\n\n%sEnter Callsign:%s " % (q.inputcol, style.RESET)) sys.exit()
if call == "quit": # check if it has the format of a valid call sign
sys.exit() # (at least 3 characters, only alphanumeric and slashes)
# check if it has the format of a valid call sign if not (len(call) > 2 and call.replace("/", "").isalnum()):
# (at least 3 characters, only alphanumeric and slashes) print(q.errorcol + "\nPlease enter a callsign with\n * at least 3 characters\n * only letters, numbers and slashes" + style.RESET)
if not (len(call) > 2 and call.replace("/", "").isalnum()): continue
print(q.errorcol + "\nPlease enter a callsign with\n * at least 3 characters\n * only letters, numbers and slashes" + style.RESET) # make the call sign all upper case
resume = False call = call.upper()
if resume: # query call sign data from QRZ
# make the call sign all upper case result = q.getCallData(call, session_key)
call = call.upper() # the query was successful
if result:
print ('\n%s%sQRZ.com results for %s%s' % (style.UNDERLINED, q.hlcol, call, style.RESET))
# generate a nice ascii table with the result
q.printTable(q.getXMLQueryTable(result))
# the query was unsuccessful
else:
print ('\n%s%s has no record on QRZ.com ¯\_(ツ)_/¯%s' % (q.errorcol, call, style.RESET))
cleaned_call = q.removeIndicators(call)
if call != cleaned_call:
# query call sign data from QRZ # query call sign data from QRZ
result = q.getCallData(call, session_key) result = q.getCallData(cleaned_call, session_key)
# the query was successful # the query was successful
if result: if result:
print ('\n%s%sQRZ.com results for %s%s' % (style.UNDERLINED, q.hlcol, call, style.RESET)) print ('\n%s%sShowing results for %s instead%s' % (style.UNDERLINED, q.hlcol, cleaned_call, style.RESET))
# generate a nice ascii table with the result # generate a nice ascii table with the result
tab = q.getXMLQueryTable(result) q.printTable(q.getXMLQueryTable(result))
# print the table print("")
print(q.tablecol) # pull all previous QSOs from tzhe QRZ logbook
print(tab) result = q.getQSOs("CALL:"+ call)
print(style.RESET) # ignore this part if there were no previous QSOs
# the query was unsuccessful if result and result[0]:
else: print ('%s%sPrevious QSOs with %s%s' % (style.UNDERLINED, q.hlcol, call, style.RESET))
print ('\n%s%s has no record on QRZ.com ¯\_(ツ)_/¯%s' % (q.errorcol, call, style.RESET)) q.printTable(q.getQSOTable(result))
# ask the user if he/she likes to continue anyway
if not q.askUser("Continue logging this call sign?"):
# restart from the beginning
resume = False
print("")
if resume:
# pull all previous QSOs from tzhe QRZ logbook
result = q.getQSOs("CALL:"+ call)
# ignore this part if there were no previous QSOs
if result and result[0]:
print ('%s%sPrevious QSOs with %s%s' % (style.UNDERLINED, q.hlcol, call, style.RESET))
# generate a nice ascii table with the result
tab = q.getQSOTable(result)
# print the table
print(q.tablecol)
print(tab)
print(style.RESET)
print ('%s%sEnter new QSO details below%s%s (enter \'c\' to cancel)%s\n' % (style.UNDERLINED, q.hlcol, style.RESET, q.hlcol, style.RESET,)) print ('%s%sEnter new QSO details below%s%s (enter \'c\' to cancel)%s\n' % (style.UNDERLINED, q.hlcol, style.RESET, q.hlcol, style.RESET,))
qso_ok = False done = False
qso = None qso = None
# we now ask the user for QSO details until he/she is happy with the result # we now ask the user for QSO details until he/she is happy with the result
while not qso_ok and resume: resume = True
# query QSO details from the user while not done:
qso = q.queryQSOData(qso) # query QSO details from the user
# the user has answered all questions qso = q.queryQSOData(qso)
if qso: # the user has answered all questions
print ('\n%s%sPlease review your choices%s' % (style.UNDERLINED, q.hlcol, style.RESET)) if qso:
# generate a pretty table print ('\n%s%sPlease review your choices%s' % (style.UNDERLINED, q.hlcol, style.RESET))
tab = q.getQSODetailTable(qso) q.printTable(q.getQSODetailTable(qso))
# print the table # ask user if everything is ok. If not, start over.
print(q.tablecol) while True:
print(tab) answer = input("\n" + q.inputcol + "Is this correct? [" + q.defvalcol + "y/n/c/quit" + q.inputcol + "]: " + style.RESET)
print(style.RESET) answer = answer.upper()
# ask user if everything is ok. If not, start over. if answer == "Y":
if q.askUser("Is this correct?"): logid = q.sendQSO(qso, call)
logid = q.sendQSO(qso, call) if logid and logid != "null":
if logid and logid != "null": # pull the uploaded QSO from QRZ
# pull the uploaded QSO from QRZ result = q.getQSOs("LOGIDS:"+ logid)
result = q.getQSOs("LOGIDS:"+ logid) if result and result[0]:
if result and result[0]: q.printTable(q.getQSOTable(result))
#print ('%sQSO uploaded to QRZ.com:%s' % (hlcol, style.RESET)) done = True
# generate a nice ascii table with the result break
tab = q.getQSOTable(result) elif answer == "C":
# print the table done = True
print(q.tablecol) break
print(tab) elif answer == "N":
print(style.RESET) break
qso_ok = True elif answer == "QUIT":
# the user has entered 'c' during the QSO detail entering process sys.exit()
else: # the user has entered 'c' during the QSO detail entering process
resume = False else:
except: done = True
print("\n\n73!\n") continue
sys.exit()
if __name__ == "__main__": if __name__ == "__main__":
sys.exit(main()) try:
sys.exit(main())
except EOFError:
pass