webdist/app/webdist.py

132 lines
4.1 KiB
Python
Raw Normal View History

"""
Webdist Flask backend
"""
import json
2022-10-02 18:29:41 +02:00
import logging
import subprocess
import sqlite3
from datetime import datetime
from flask import Flask, render_template, request
2022-10-02 18:29:41 +02:00
# Enable logging
logging.basicConfig(format='%(asctime)s - %(name)s - %(levelname)s - %(message)s',
level=logging.INFO)
logger = logging.getLogger(__name__)
def create_app(config):
""" creates and returns the Flask app """
_app = Flask(__name__)
_app.config.from_file(config, load=json.load)
2022-10-02 18:29:41 +02:00
# initialize moment on the app within create_app()
return _app
2022-10-02 18:29:41 +02:00
app = create_app("/etc/webdist/main.json")
logger.info(app.config)
2022-10-02 18:29:41 +02:00
def cursor_row_to_dict(cursor, row):
""" Converts a sqlite3 cursor row into a dict """
2022-10-02 18:29:41 +02:00
items = {}
for idx, key in enumerate(cursor.description):
if key[0] in ['buildtime']:
items[key[0]] = datetime.fromtimestamp(row[idx]).isoformat()
2022-10-02 18:29:41 +02:00
else:
items[key[0]] = row[idx]
return items
def latest():
""" Returns a dict of latest packages """
2022-10-02 18:29:41 +02:00
response = {}
for repo in app.config['WEBDIST_CONFIG']['repos']:
2022-10-02 18:29:41 +02:00
response[repo] = []
repo_sources_db = "file:" + app.config['WEBDIST_CONFIG']['repos'][repo]['path'] + \
f"{app.config['WEBDIST_CONFIG']['repos'][repo]['dbname']}-sources.db?mode=ro"
conn = sqlite3.connect(repo_sources_db, uri=True)
2022-10-02 18:29:41 +02:00
cursor = conn.cursor()
cursor.execute(
'SELECT * FROM sources ORDER BY buildtime DESC limit 100')
2022-10-02 18:29:41 +02:00
for row in cursor:
response[repo].append(cursor_row_to_dict(cursor, row))
2022-10-02 18:29:41 +02:00
return response
def query(querystring):
""" Performs a query of a package """
logger.info("Query of %s", querystring)
2022-10-02 18:29:41 +02:00
response = {}
for repo in app.config['WEBDIST_CONFIG']['repos']:
2022-10-02 18:29:41 +02:00
response[repo] = []
repo_sources_db = "file:" + app.config['WEBDIST_CONFIG']['repos'][repo]['path'] + \
f"{app.config['WEBDIST_CONFIG']['repos'][repo]['dbname']}-sources.db?mode=ro"
conn = sqlite3.connect(repo_sources_db, uri=True)
2022-10-02 18:29:41 +02:00
cursor = conn.cursor()
cursor.execute(
f'SELECT * FROM sources where name like "%%{querystring}%%" '
'or summary like "%%{querystring}%%" '
'ORDER BY name="{querystring}" DESC, name like "{qs}%%" DESC, '
'name like "%%{querystring}%%" DESC limit 10')
2022-10-02 18:29:41 +02:00
for row in cursor:
response[repo].append(cursor_row_to_dict(cursor, row))
2022-10-02 18:29:41 +02:00
return response
@app.route("/")
def _search():
return render_template("index.html")
@app.route("/latest")
def _latest():
data = latest()
return render_template("latest.html", data=data)
@app.route("/button/<name>")
def _button(name):
script = app.config['WEBDIST_CONFIG']['buttons'][name]['script']
output = subprocess.check_output([script])
return render_template("button.html",output=output.decode())
@app.route("/query/<querystring>")
def _query(querystring):
data = query(querystring)
2022-10-02 18:29:41 +02:00
return render_template("query.html", data=data)
@app.route("/api/v1/config")
def api_config():
""" GET config API call """
logger.info("Origin: %s", request.headers['Origin'])
return {'result': app.config['WEBDIST_CONFIG'] }
@app.route("/api/v1/latest")
def api_latest():
""" Get latest packages API call """
data = latest()
return {'result': data }
@app.route("/api/v1/button/<name>")
def api_button(name):
""" Call a button associated script """
script = app.config['WEBDIST_CONFIG']['buttons'][name]['script']
output = subprocess.check_output([script])
return {'result': output.decode() }
@app.after_request
def after_request(response):
""" Allow API request origins specified in configuration file """
white_origin = app.config['WEBDIST_CONFIG']['white_origins']
if request.headers['Origin'] in white_origin:
response.headers['Access-Control-Allow-Origin'] = request.headers['Origin']
response.headers['Access-Control-Allow-Methods'] = 'PUT,GET,POST,DELETE'
response.headers['Access-Control-Allow-Headers'] = 'Content-Type,Authorization'
return response