initial commit
This commit is contained in:
parent
b9497fe386
commit
ba8910cb87
|
@ -0,0 +1,165 @@
|
|||
import urllib
|
||||
import re
|
||||
import os
|
||||
import sys
|
||||
import configparser
|
||||
from pathlib import Path
|
||||
from flask import Flask, jsonify, request, Response
|
||||
from flask_restful import Resource, Api
|
||||
import requests
|
||||
from requests.structures import CaseInsensitiveDict
|
||||
|
||||
|
||||
app = Flask(__name__)
|
||||
api = Api(app)
|
||||
|
||||
class QRZ():
|
||||
#class QRZ():
|
||||
"""QRZ class"""
|
||||
|
||||
def __init__(self):
|
||||
"""initialize things"""
|
||||
|
||||
self.config = configparser.ConfigParser()
|
||||
self.home_dir = str(Path.home())
|
||||
self.config_dir = self.home_dir + "/.config/CloudlogOffline2QRZ/"
|
||||
# Check if config directory exists and else create it
|
||||
Path(self.config_dir).mkdir(parents=True, exist_ok=True)
|
||||
self.config_file = os.path.expanduser(self.config_dir + 'CloudlogOffline2QRZ.ini')
|
||||
self.read_config(self.config, self.config_file)
|
||||
|
||||
# headers for all POST requests
|
||||
self.headers = CaseInsensitiveDict()
|
||||
self.headers["Content-Type"] = "application/x-www-form-urlencoded"
|
||||
|
||||
|
||||
@staticmethod
|
||||
def read_config(config, file_name):
|
||||
"""reads the configuration from the config file or
|
||||
creates a default config file if none could be found"""
|
||||
if os.path.isfile(file_name):
|
||||
config.read(file_name)
|
||||
else:
|
||||
config = configparser.ConfigParser()
|
||||
config['qrz.com'] = {
|
||||
'station_call': 'MYCALL',
|
||||
'api_key': '1234-ABCD-1234-A1B2',
|
||||
'url': 'https://logbook.qrz.com/api'}
|
||||
config['general'] = {
|
||||
'api_key': 'API_KEY_FOR_THIS_API'
|
||||
}
|
||||
|
||||
with open(file_name, 'w') as configfile:
|
||||
config.write(configfile)
|
||||
print("\nNo configuration file found. A new configuration file has been created.")
|
||||
print("\nPlease edit the file " + file_name + " and restart the application.\n" )
|
||||
sys.exit()
|
||||
return config
|
||||
|
||||
|
||||
def send_request(self, post_data):
|
||||
"""Sends a POST request to QRZ.com, checks for errors
|
||||
and returns the response"""
|
||||
try:
|
||||
resp = requests.post(qrz.config['qrz.com']['url'], headers=self.headers, data=post_data)
|
||||
if resp.status_code == 200:
|
||||
str_resp = resp.content.decode("utf-8")
|
||||
response = urllib.parse.unquote(str_resp)
|
||||
resp_list = response.splitlines()
|
||||
if resp_list[0]:
|
||||
if "invalid api key" in resp_list[0]:
|
||||
print("\nThe API key configured \
|
||||
in config.ini is not correct.\n")
|
||||
else:
|
||||
return response
|
||||
elif resp.status_code == 404:
|
||||
print("\nThe API URL could not be found. \
|
||||
Please check the URL in config.ini\n")
|
||||
except requests.exceptions.ConnectionError as e_conn:
|
||||
print("\nUnable to connect to xmldata.qrz.com:")
|
||||
print(e_conn)
|
||||
print("\nPlease check if you are connected to the internet")
|
||||
except: # pylint: disable=bare-except
|
||||
print("\nsomething unexpected has happened:\n")
|
||||
print(e_conn)
|
||||
return None
|
||||
|
||||
|
||||
def send_qso(self, adif):
|
||||
"""Sends the previously collected QSO information as a new
|
||||
QRZ.com logbook entry via the API"""
|
||||
|
||||
logid = "null"
|
||||
|
||||
# construct POST data
|
||||
post_data = { 'KEY' : self.config['qrz.com']['api_key'], \
|
||||
'ACTION' : 'INSERT', 'ADIF' : adif }
|
||||
|
||||
# URL encode the payload
|
||||
data = urllib.parse.urlencode(post_data)
|
||||
# send the POST request to QRZ.com
|
||||
response = self.send_request(data)
|
||||
|
||||
# Check if the upload failed and print out
|
||||
# the reason plus some additional info
|
||||
if response:
|
||||
if "STATUS=FAIL" in response:
|
||||
print("QSO upload failed. QRZ.com has send the following reason:\n")
|
||||
resp_list = response.split("&")
|
||||
for item in resp_list:
|
||||
print(item)
|
||||
print("\nPlease review the following request that led to this error:\n")
|
||||
print(post_data)
|
||||
else:
|
||||
try:
|
||||
logid = re.search('LOGID=(\d+)', response).group(1)
|
||||
print("QSO successfully uploaded to QRZ.com (LOGID "+ logid + ")")
|
||||
log_status = "SUCCESS: "
|
||||
except: # pylint: disable=bare-except
|
||||
logid = "null"
|
||||
print("\nQSO upload to QRZ.com failed!\n")
|
||||
return logid
|
||||
|
||||
|
||||
class ApiTest(Resource):
|
||||
|
||||
def get(self, key):
|
||||
if key and key == qrz.config['general']['api_key']:
|
||||
print("API Key is valid!")
|
||||
return Response("{'status':'ok'}", status=200, mimetype='application/json')
|
||||
print("Wrong API key configured in CloudlogOffline")
|
||||
return Response("{'status':'not ok'}", status=403, mimetype='application/json')
|
||||
|
||||
|
||||
class UploadQso(Resource):
|
||||
|
||||
def post(self):
|
||||
data = request.json
|
||||
key = data['key']
|
||||
adif = data['string']
|
||||
|
||||
if key == qrz.config['general']['api_key']:
|
||||
print("\n Sending the following QSO: " + adif)
|
||||
logid = qrz.send_qso(adif)
|
||||
if logid != "null":
|
||||
return jsonify(
|
||||
status='created',
|
||||
)
|
||||
return jsonify(
|
||||
status='failed',
|
||||
)
|
||||
print("Wrong API key configured in CloudlogOffline")
|
||||
return jsonify(
|
||||
status='wrong api key',
|
||||
)
|
||||
|
||||
|
||||
# adding the defined resources along with their corresponding urls
|
||||
api.add_resource(ApiTest, '/index.php/api/auth/<string:key>' )
|
||||
api.add_resource(UploadQso, '/index.php/api/qso')
|
||||
|
||||
|
||||
# driver function
|
||||
if __name__ == '__main__':
|
||||
qrz = QRZ()
|
||||
app.run(debug=True, host='0.0.0.0')
|
Loading…
Reference in New Issue