RXSM update server
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
This repo is archived. You can view files and clone it, but cannot push or open issues/pull-requests.

96 lines
3.7KB

  1. # Created 2019-09-10 by NGnius
  2. from flask import Flask, Blueprint, jsonify, request, send_file
  3. import sqlite3 as dblib
  4. from hashlib import sha512
  5. from os import getcwd
  6. from threading import get_ident
  7. from time import time
  8. database_path = 'rxsm-update.db'
  9. database_connections = dict()
  10. app = Flask('rxsm-update-server')
  11. def get_or_create_connection():
  12. global database_connections, database_path
  13. thread_id = get_ident()
  14. if thread_id not in database_connections:
  15. database_connections[thread_id] = dblib.connect(database_path)
  16. return database_connections[thread_id]
  17. @app.route('/release', methods=['POST'])
  18. def create_or_modify_release():
  19. try:
  20. req_json = request.get_json(force=True)
  21. token = req_json['token']
  22. version = req_json['version']
  23. platform = req_json['platform']
  24. url = req_json['url']
  25. except:
  26. return jsonify({'status':400, 'reason':'Invalid request; missing parameter or invalid JSON'}), 400
  27. with open('.token', 'r') as f:
  28. master_token = f.read()
  29. if sha512(token.encode()).hexdigest() != master_token:
  30. return jsonify({'status':403, 'reason':'Permission denied; invalid token'}), 403
  31. db_connection = get_or_create_connection()
  32. cursor = db_connection.cursor()
  33. cursor.execute('SELECT version FROM releases WHERE version=? AND platform=?', (version, platform))
  34. result = cursor.fetchone()
  35. operation = ''
  36. if result is None:
  37. cursor.execute('INSERT INTO releases (version, platform, url, created_date) VALUES (?,?,?,?)', (version, platform, url, int(time())))
  38. operation = 'create'
  39. else:
  40. cursor.execute('UPDATE releases SET url=?, created_date=? WHERE version=? and platform=?', (url, int(time()), version, platform))
  41. operation = 'update'
  42. db_connection.commit()
  43. return jsonify({'status':200, 'reason':'Version %s %sd successfully' % (version, operation)}), 200
  44. @app.route('/db', methods=['GET'])
  45. @app.route('/database', methods=['GET'])
  46. def download_database():
  47. return send_file(database_path, cache_timeout=1, as_attachment=True, attachment_filename='rxsm.sqlite')
  48. @app.route('/update', methods=['POST'])
  49. @app.route('/check-for-update', methods=['POST'])
  50. def check_for_update():
  51. start = time()
  52. collect_anonymous_stats = str(request.headers.get('DNT')).strip() != '1'
  53. # TODO: add hit counter
  54. try:
  55. req_json = request.get_json(force=True)
  56. current_version = req_json['version']
  57. platform = req_json['platform']
  58. except:
  59. return jsonify({'status':400, 'reason':'Invalid request; missing parameter or invalid JSON'}), 400
  60. db_connection = get_or_create_connection()
  61. cursor = db_connection.cursor()
  62. cursor.execute('SELECT version, url FROM releases WHERE platform=? ORDER BY created_date DESC', (platform,))
  63. result = cursor.fetchone()
  64. if result is None:
  65. return jsonify({'status':404, 'reason':'Platform not found (%ss)' % (time()-start), 'url':'', 'out-of-date':False}), 404
  66. elif result[0] != current_version:
  67. return jsonify({'status':200, 'reason':'Ok (%ss)' % (time()-start), 'url':result[1], 'out-of-date':True}), 200
  68. else:
  69. return jsonify({'status':200, 'reason':'Ok (%ss)' % (time()-start), 'url':result[1], 'out-of-date':False}), 200
  70. # always try to create db table(s)
  71. conn = get_or_create_connection()
  72. cursor = conn.cursor()
  73. cursor.execute(\
  74. '''CREATE TABLE IF NOT EXISTS releases (
  75. id INTEGER PRIMARY KEY,
  76. version TEXT UNIQUE NOT NULL,
  77. url TEXT NOT NULL,
  78. platform TEXT NOT NULL,
  79. created_date INTEGER NOT NULL
  80. )''' )
  81. conn.commit()
  82. if __name__ == '__main__':
  83. print('Working directory: ' + getcwd())
  84. app.run(host='0.0.0.0', port=9080, threaded=True)