|
- # Created 2019-09-10 by NGnius
- from flask import Flask, Blueprint, jsonify, request, send_file
- import sqlite3 as dblib
- from hashlib import sha512
- from os import getcwd
- from threading import get_ident
- from time import time
- from datetime import datetime
-
- database_path = 'rxsm-update.db'
-
- database_connections = dict()
- app = Flask('rxsm-update-server')
-
- def get_or_create_connection():
- global database_connections, database_path
- thread_id = get_ident()
- if thread_id not in database_connections:
- database_connections[thread_id] = dblib.connect(database_path)
- return database_connections[thread_id]
-
- def close_connection():
- thread_id = get_ident()
- if thread_id in database_connections:
- database_connections[thread_id].close()
- del(database_connections[thread_id])
-
- @app.route('/release', methods=['POST'])
- def create_or_modify_release():
- try:
- req_json = request.get_json(force=True)
- token = req_json['token']
- version = req_json['version']
- platform = req_json['platform']
- url = req_json['url']
- except:
- return jsonify({'status':400, 'reason':'Invalid request; missing parameter or invalid JSON'}), 400
-
- with open('.token', 'r') as f:
- master_token = f.read()
- if sha512(token.encode()).hexdigest() != master_token:
- return jsonify({'status':403, 'reason':'Permission denied; invalid token'}), 403
-
- db_connection = get_or_create_connection()
- cursor = db_connection.cursor()
- cursor.execute('SELECT version FROM releases WHERE version=? AND platform=?', (version, platform))
- result = cursor.fetchone()
- operation = ''
- if result is None:
- cursor.execute('INSERT INTO releases (version, platform, url, created_date) VALUES (?,?,?,?)', (version, platform, url, int(time())))
- operation = 'create'
- else:
- cursor.execute('UPDATE releases SET url=?, created_date=? WHERE version=? and platform=?', (url, int(time()), version, platform))
- operation = 'update'
- db_connection.commit()
- close_connection()
-
- return jsonify({'status':200, 'reason':'Version %s %sd successfully' % (version, operation)}), 200
-
- @app.route('/db', methods=['GET'])
- @app.route('/database', methods=['GET'])
- def download_database():
- return send_file(database_path, cache_timeout=1, as_attachment=True, attachment_filename='rxsm.sqlite')
-
- @app.route('/update', methods=['POST'])
- @app.route('/check-for-update', methods=['POST'])
- def check_for_update():
- start = time()
- db_connection = get_or_create_connection()
- cursor = db_connection.cursor()
- collect_anonymous_stats = str(request.headers.get('DNT')).strip() != '1'
- # hit counter
- if collect_anonymous_stats:
- today = datetime.today().date().isoformat()
- cursor.execute('SELECT count FROM hits WHERE date=?', (today,))
- result = cursor.fetchone()
- if result is not None:
- cursor.execute('UPDATE hits SET count=count+1 WHERE date=?', (today,))
- else:
- cursor.execute('INSERT INTO hits (date, count) VALUES (?,?)', (today, 1))
- db_connection.commit()
- # update lookup
- try:
- req_json = request.get_json(force=True)
- current_version = req_json['version']
- platform = req_json['platform']
- except:
- close_connection()
- return jsonify({'status':400, 'reason':'Invalid request; missing parameter or invalid JSON'}), 400
- cursor.execute('SELECT version, url FROM releases WHERE platform=? ORDER BY created_date DESC', (platform,))
- result = cursor.fetchone()
- close_connection()
- if result is None:
- return jsonify({'status':404, 'reason':'Platform not found (%ss)' % (time()-start), 'url':'', 'out-of-date':False}), 404
- elif result[0] != current_version:
- return jsonify({'status':200, 'reason':'Ok (%ss)' % (time()-start), 'url':result[1], 'out-of-date':True}), 200
- else:
- return jsonify({'status':200, 'reason':'Ok (%ss)' % (time()-start), 'url':result[1], 'out-of-date':False}), 200
-
- # always try to create db table(s)
- conn = get_or_create_connection()
- cursor = conn.cursor()
- cursor.execute(\
- '''CREATE TABLE IF NOT EXISTS releases (
- id INTEGER PRIMARY KEY,
- version TEXT NOT NULL,
- url TEXT NOT NULL,
- platform TEXT NOT NULL,
- created_date INTEGER NOT NULL
- )''' )
- cursor.execute(\
- '''CREATE TABLE IF NOT EXISTS hits (
- date TEXT UNIQUE NOT NULL,
- count INTEGER NOT NULL
- )''' )
- conn.commit()
-
- if __name__ == '__main__':
- print('Working directory: ' + getcwd())
- app.run(host='0.0.0.0', port=9080, threaded=True)
|