diff --git a/bcnsGDSAPI/__init__.py b/bcnsGDSAPI/__init__.py new file mode 100644 index 0000000..a1290a2 --- /dev/null +++ b/bcnsGDSAPI/__init__.py @@ -0,0 +1,52 @@ +from flask import request, jsonify, Flask +import json +from datetime import date +import tomllib +import sys +import os + + +class MyJSONEncoder(json.JSONEncoder): + def default(self, o): + if isinstance(o, date): + return o.isoformat() + + return super().default(o) + + +def create_app(test_config=None): + app = Flask(__name__, instance_relative_config=True) + app.config['JSON_AS_ASCII'] = False + + if test_config is None: + app.config.from_file('bcnsgdsapi-config.toml', + load=tomllib.load, text=False) + else: + app.config.from_mapping(test_config) + + try: + os.makedirs(app.instance_path) + except OSError: + pass + + import bcnsGDSAPI.modules.db_connect + bcnsGDSAPI.modules.db_connect.init(app.config) + from bcnsGDSAPI.modules.gamelist import gamelist + from bcnsGDSAPI.modules.game import game + app.register_blueprint(gamelist) + app.register_blueprint(game) + + # Just a simple homepage, nothing fancy + @app.route('/', methods=['GET']) + def home(): + if 'id' not in request.args: + return "

BCNS Game Distribution System

API-endpoint

" + else: + return jsonify("I see you're a man of culture as well") + + return app + + +if __name__ == "__main__": + app = create_app() + app.run(host="0.0.0.0", port=8001, debug=True) diff --git a/bcnsGDSAPI/modules/db_connect.py b/bcnsGDSAPI/modules/db_connect.py index ce7847d..bbd1be1 100644 --- a/bcnsGDSAPI/modules/db_connect.py +++ b/bcnsGDSAPI/modules/db_connect.py @@ -1,37 +1,19 @@ -import argparse -import configparser -import os -import inspect +main = {} +database = {} -def init(): - global config +def init(config=None): + global main + global database + main = config["MAIN"] + database = config["DATABASE"] - # Decide what config-file to use - parser = argparse.ArgumentParser() - parser.add_argument('-e', '--environment', choices=['dev', 'prod', 'test'], - default='prod', - help='choose what environment type to run.' - ' Defaults to prod') - args = parser.parse_args() + return True - if args.environment == 'dev': - print("Using devapi.conf") - configfile = '/../devapi.conf' - elif args.environment == 'test': - print("Using testapi.conf") - configfile = '/../testapi.conf' - else: - print("Using api.conf") - configfile = '/../api.conf' - - config = configparser.RawConfigParser() - config.read(os.path.dirname( - os.path.abspath(inspect.getfile( - inspect.currentframe()))) + configfile) def contentpath(): - return(config.get('Database','contentpath')) + return database["contentpath"] + def nfosuffix(): - return(config.get('Database','nfo_suffix')) + return database["nfo_suffix"] diff --git a/bcnsGDSAPI/modules/functions.py b/bcnsGDSAPI/modules/functions.py index 058cb6f..1d3f652 100644 --- a/bcnsGDSAPI/modules/functions.py +++ b/bcnsGDSAPI/modules/functions.py @@ -4,7 +4,6 @@ from io import BytesIO import zipfile import pathlib -global gamelist gamelist = [] diff --git a/bcnsGDSAPI/modules/game.py b/bcnsGDSAPI/modules/game.py index a1432e4..b3d3847 100644 --- a/bcnsGDSAPI/modules/game.py +++ b/bcnsGDSAPI/modules/game.py @@ -1,17 +1,17 @@ -from __main__ import app -from flask import jsonify, request, send_from_directory, send_file +from flask import jsonify, request, send_from_directory, send_file, Blueprint import base64 import json -import modules.db_connect -from modules.functions import reduceartcv2, make_archive +import bcnsGDSAPI.modules.db_connect +from bcnsGDSAPI.modules.functions import reduceartcv2, make_archive import os -contentpath = modules.db_connect.contentpath() +contentpath = bcnsGDSAPI.modules.db_connect.contentpath() +game = Blueprint('game', __name__, template_folder='templates') # Fetch and present all information from one _index.nfo-file -@app.route('/game', methods=['POST']) -def game( +@game.route('/game', methods=['POST']) +def showgame( predefinednfo=False, return_dict=False, skip_artwork=False, @@ -59,8 +59,8 @@ def game( # Fetch all artwork from a given _index.nfo-file -@app.route('/game/artwork/size/', methods=['POST']) -@app.route('/game/artwork', methods=['POST']) +@game.route('/game/artwork/size/', methods=['POST']) +@game.route('/game/artwork', methods=['POST']) def artwork(size='max'): f = open(request.json['nfo'], 'r') nfo = json.load(f) @@ -89,7 +89,7 @@ def artwork(size='max'): # Serve a file. Takes the following object parameters: # nfopath base64-encoded full path to specific game nfo-file # filepath base64-encoded path to file starting from game dir -@app.route('/getfile', methods=["GET"]) +@game.route('/getfile', methods=["GET"]) def getfile(): nfopath = os.path.dirname( base64.b64decode(request.json['nfopath']).decode()) @@ -98,7 +98,7 @@ def getfile(): # Game folder as ZIP-file (kinda slow) -@app.route('/getzipfile', methods=["GET"]) +@game.route('/getzipfile', methods=["GET"]) def getzipfile(): nfopath = base64.b64decode(request.json).decode() nfo = json.load(open(nfopath, 'r')) diff --git a/bcnsGDSAPI/modules/gamelist.py b/bcnsGDSAPI/modules/gamelist.py index 4cdc779..3f58872 100644 --- a/bcnsGDSAPI/modules/gamelist.py +++ b/bcnsGDSAPI/modules/gamelist.py @@ -1,20 +1,20 @@ -from __main__ import app -from flask import jsonify, make_response -import modules.db_connect -from modules.functions import get_gamelist, set_gamelist -import modules.game -from modules.gamelist_functions import ( +from flask import jsonify, make_response, Blueprint +import bcnsGDSAPI.modules.db_connect +from bcnsGDSAPI.modules.functions import get_gamelist, set_gamelist +import bcnsGDSAPI.modules.game +from bcnsGDSAPI.modules.gamelist_functions import ( get_threaded_thumbnails, update_threaded_thumbnails) import glob -contentpath = modules.db_connect.contentpath() -nfosuffix = modules.db_connect.nfosuffix() +contentpath = bcnsGDSAPI.modules.db_connect.contentpath() +nfosuffix = bcnsGDSAPI.modules.db_connect.nfosuffix() +gamelist = Blueprint('gamelist', __name__, template_folder='templates') # Collects all _index.nfo-files present and crunches them into a list of # games. -@app.route('/gamelist', methods=['GET']) +@gamelist.route('/gamelist', methods=['GET']) def show_gamelist(): if get_gamelist(): return jsonify(get_gamelist()) @@ -23,7 +23,7 @@ def show_gamelist(): # Updates the gamelist by searching for new nfo's -@app.route('/gamelist/update', methods=['GET']) +@gamelist.route('/gamelist/update', methods=['GET']) def update_gamelist(): nfolist = list(dict.fromkeys(glob.glob( str(contentpath)+'/**/**/*'+nfosuffix, recursive=True))) @@ -31,7 +31,7 @@ def update_gamelist(): glist = [] for nfo in nfolist: try: - game = modules.game.game(nfo, True, True, True) + game = bcnsGDSAPI.modules.game.showgame(nfo, True, True, True) glist.append(game) except Exception as e: print(nfo, e) @@ -41,7 +41,7 @@ def update_gamelist(): # Fetch displayimage for all nfo-files -@app.route('/gamelist/displayimage') +@gamelist.route('/gamelist/displayimage') def get_displayimages(update=False): thumbnails = get_threaded_thumbnails() if (len(thumbnails) == 0) or update: @@ -50,7 +50,7 @@ def get_displayimages(update=False): # Update displayimages -@app.route('/gamelist/displayimage/update') +@gamelist.route('/gamelist/displayimage/update') def update_displayimages(): update_threaded_thumbnails() return make_response("

Success

", 200) diff --git a/bcnsGDSAPI/modules/gamelist_functions.py b/bcnsGDSAPI/modules/gamelist_functions.py index d068e31..2af1359 100644 --- a/bcnsGDSAPI/modules/gamelist_functions.py +++ b/bcnsGDSAPI/modules/gamelist_functions.py @@ -1,14 +1,14 @@ -import modules.db_connect +import bcnsGDSAPI.modules.db_connect import glob import os import json -from modules.functions import reduceartcv2 +from bcnsGDSAPI.modules.functions import reduceartcv2 import threading from queue import Queue import time -contentpath = modules.db_connect.contentpath() -nfosuffix = modules.db_connect.nfosuffix() +contentpath = bcnsGDSAPI.modules.db_connect.contentpath() +nfosuffix = bcnsGDSAPI.modules.db_connect.nfosuffix() global nfofiles nfofiles = [] diff --git a/bcnsGDSSite/__init__.py b/bcnsGDSSite/__init__.py index 952e2f3..1c63b57 100644 --- a/bcnsGDSSite/__init__.py +++ b/bcnsGDSSite/__init__.py @@ -1,8 +1,6 @@ from datetime import date from flask import render_template, Flask, request from json import JSONEncoder -from bcnsGDSSite.modules.gamelist import gamelist -from bcnsGDSSite.modules.game import game import bcnsGDSSite.modules.init import os import inspect @@ -21,9 +19,6 @@ class MyJSONEncoder(JSONEncoder): def create_app(test_config=None): app = Flask(__name__, instance_relative_config=True) - app.register_blueprint(gamelist) - app.register_blueprint(game) - print(app.url_map) app.config.from_mapping( SECRET_KEY='dev', DATABASE=os.path.join(app.instance_path, 'bcns_gds.sqlite'), @@ -44,14 +39,13 @@ def create_app(test_config=None): except OSError: pass + bcnsGDSSite.modules.init.init(app.config) -# import bcnsGDSSite.modules.gamelist # noqa: E402 - bcnsGDSSite.modules.init.set_apihost("http://" + - app.config['API']['host'] + - ':' + app.config['API']['port']) + from bcnsGDSSite.modules.gamelist import gamelist + from bcnsGDSSite.modules.game import game + app.register_blueprint(gamelist) + app.register_blueprint(game) - bcnsGDSSite.modules.init.set_applanguage( - app.config['MAIN']['app_language']) languages = bcnsGDSSite.modules.init.get_languages() if not languages: languages_path = os.path.dirname( diff --git a/bcnsGDSSite/modules/game.py b/bcnsGDSSite/modules/game.py index 91b5228..5da5ef7 100644 --- a/bcnsGDSSite/modules/game.py +++ b/bcnsGDSSite/modules/game.py @@ -4,7 +4,7 @@ import base64 from flask import render_template, request, Response, Blueprint import bcnsGDSSite.modules.init -host_endpoint = bcnsGDSSite.modules.init.get_apihost() +apihost = bcnsGDSSite.modules.init.apihost() languages = bcnsGDSSite.modules.init.get_languages() app_language = bcnsGDSSite.modules.init.app_language @@ -27,7 +27,7 @@ def showgame(lang_code): gamepath = request.args.get("gamepath") game = json.loads((requests.post( - host_endpoint + '/game', json=gamepath).content).decode()) + apihost + '/game', json=gamepath).content).decode()) game['game']['plot'] = game['game']['plot'].split('\\n') if 'linuxinstructions' in game['game']: @@ -54,7 +54,7 @@ def download(lang_code): gametitle = request.args.get("gametitle") targettype = request.args.get("targettype") if "zip" in targettype: - gamezip = requests.get(host_endpoint + '/getzipfile', json=gamepath) + gamezip = requests.get(apihost + '/getzipfile', json=gamepath) return Response(gamezip, mimetype="application/zip", headers={ "Content-Disposition": @@ -77,7 +77,7 @@ def getfile(lang_code): filepath_enc = base64.b64encode(filepath.encode('utf-8')).decode() jsonbody = {'nfopath': gamepath, 'filepath': filepath_enc} print(gamepath, filepath) - file = requests.get(host_endpoint + '/getfile', json=jsonbody) + file = requests.get(apihost + '/getfile', json=jsonbody) return Response(file, mimetype="application/pdf", headers={ "Content-Disposition": diff --git a/bcnsGDSSite/modules/gamelist.py b/bcnsGDSSite/modules/gamelist.py index 61a5dbc..2028aae 100644 --- a/bcnsGDSSite/modules/gamelist.py +++ b/bcnsGDSSite/modules/gamelist.py @@ -4,7 +4,7 @@ from flask import render_template, redirect, url_for, request, Blueprint import bcnsGDSSite.modules.init import base64 -host_endpoint = bcnsGDSSite.modules.init.get_apihost() +apihost = bcnsGDSSite.modules.init.apihost() languages = bcnsGDSSite.modules.init.get_languages() app_language = bcnsGDSSite.modules.init.app_language @@ -26,7 +26,7 @@ def showgamelist(lang_code): glist = None try: glist = json.loads((requests.get( - host_endpoint + '/gamelist').content).decode()) + apihost + '/gamelist').content).decode()) # Sorting list alphabetically glist = sorted(glist, key=lambda d: d['game']['title']) @@ -48,7 +48,7 @@ def showgamelist(lang_code): if thumbnails == "get": try: thumbnailslist = json.loads((requests.get( - host_endpoint + '/gamelist/displayimage').content).decode()) + apihost + '/gamelist/displayimage').content).decode()) except request.exceptions.ConnectionError as e: print(e) @@ -70,6 +70,6 @@ def showgamelist(lang_code): def gamelist_update(lang_code): lang_code = lang(lang_code) response = requests.get( - host_endpoint + '/gamelist/update') + apihost + '/gamelist/update') if response.status_code == 200: - return redirect(url_for('gamelist', lang_code=lang_code)) + return redirect(url_for('gamelist.showgamelist', lang_code=lang_code)) diff --git a/bcnsGDSSite/modules/init.py b/bcnsGDSSite/modules/init.py index ece5a0e..53c6b89 100644 --- a/bcnsGDSSite/modules/init.py +++ b/bcnsGDSSite/modules/init.py @@ -1,14 +1,23 @@ -import os -import inspect - -global languages languages = {} - -global apihost -apihost = "http://media.odecif.net:5501" - -global app_language app_language = "" +main = {} +api = {} + + +def init(config=None): + global main + global api + main = config["MAIN"] + api = config["API"] + + +def apihost(): + return ( + api["protocol"] + "://" + + api["host"] + ":" + + api["port"] + ) + def set_languages(languages_dict): global languages @@ -36,7 +45,3 @@ def set_applanguage(new_applanguage): global app_language app_language = new_applanguage return app_language - -def init(): - global apihost - apihost = ""