Compare commits

..

10 Commits

Author SHA1 Message Date
9dc9b7e1b5 rework to base template 2025-07-15 11:43:28 +01:00
8df6af5edf rework 2025-07-15 11:38:50 +01:00
e3cce698a0 Bump version: 1.2.6 → 1.2.7
All checks were successful
Build and Publish Docker Image / build-and-push (push) Successful in 4m4s
2025-07-15 11:28:10 +01:00
318468fe53 fix: Align version to 1.2.6 2025-07-15 11:27:52 +01:00
41fef3cb15 feat: Use .bumpversion.toml for configuration 2025-07-15 11:25:59 +01:00
cc576e3c91 Bump version: 1.2.6 → 1.2.7 2025-07-15 11:23:28 +01:00
1455e45554 fix: Set current version to 1.2.6 2025-07-15 11:23:23 +01:00
a442460338 fix: Align version with latest tag 2025-07-15 11:22:32 +01:00
f3b37d6ac2 feat: Configure bump-my-version 2025-07-15 11:22:14 +01:00
c174f1dbc9 reduced dockerfile 2025-07-15 11:19:44 +01:00
15 changed files with 283 additions and 472 deletions

9
.bumpversion.toml Normal file
View File

@ -0,0 +1,9 @@
[bumpversion]
current_version = "0.1.0"
commit = true
tag = true
[[bumpversion::file]]
filename = "VERSION"
search = "{current_version}"
replace = "{new_version}"

View File

@ -1 +1 @@
1.2.6
1.2.7

2
app.py
View File

@ -4,7 +4,7 @@ from flask_caching import Cache
import requests.auth
import os
from lib.datetime import filter_accounts_next_30_days, filter_accounts_expired
from lib.reqs import get_urls, get_user_accounts, add_user_account, delete_user_account, get_user_accounts_count, get_stream_names
from lib.reqs import get_urls, get_user_accounts, add_user_account, delete_user_account, get_stream_names
from flask import send_from_directory
import requests
import base64

View File

@ -1,19 +0,0 @@
from flask import Flask, jsonify
from config import DevelopmentConfig
from lib.mysql import execute_query
app = Flask(__name__)
app.config.from_object(DevelopmentConfig)
@app.route('/getUserAccounts', methods=['GET'])
def get_user_accounts():
# Use the execute_query function to get user accounts
data = execute_query("SELECT COUNT(*) AS account_count FROM userAccounts WHERE userID = %s;", (1,))
if data is None:
return jsonify({"error": "Database query failed"}), 500
return jsonify(data), 200
# Run the app
if __name__ == '__main__':
app.run(debug=app.config["DEBUG"], port=app.config["PORT"])

View File

@ -1,37 +0,0 @@
import mysql.connector
from flask import current_app
def execute_query(query, params=None, fetch_one=False):
"""Execute a SQL query and optionally fetch results."""
try:
# Get database configuration from the current app context
db_config = {
"host": current_app.config['DBHOST'],
"user": current_app.config['DBUSER'],
"password": current_app.config['DBPASS'],
"database": current_app.config['DATABASE'],
}
# Establish database connection
connection = mysql.connector.connect(**db_config)
cursor = connection.cursor(dictionary=True)
# Execute the query with optional parameters
cursor.execute(query, params)
# Fetch results if it's a SELECT query
if query.strip().upper().startswith("SELECT"):
result = cursor.fetchone() if fetch_one else cursor.fetchall()
else:
# Commit changes for INSERT, UPDATE, DELETE
connection.commit()
result = cursor.rowcount # Number of affected rows
# Close the database connection
cursor.close()
connection.close()
return result
except mysql.connector.Error as err:
print("Error: ", err)
return None

View File

@ -3,6 +3,10 @@
class Config:
DEBUG = False
BASE_URL = '' # Set your base URL here
HOST = '0.0.0.0'
PORT = 5000
OCR_ENABLED = False
TEXT_INPUT_ENABLED = False
class DevelopmentConfig(Config):
DEBUG = True

View File

@ -1,5 +1,5 @@
# Builder stage
FROM python:3.11-slim-bookworm as builder
FROM python:3.11-slim-bookworm AS builder
WORKDIR /app
@ -7,15 +7,10 @@ COPY requirements.txt .
RUN pip install --no-cache-dir --prefix=/install -r requirements.txt
# Final stage
FROM python:3.11-slim-bookworm as final
FROM python:3.11-slim-bookworm AS final
RUN apt-get update && apt-get install -y --no-install-recommends \
libglib2.0-0 \
libsm6 \
libxrender1 \
libxext6 \
libgomp1 \
libgl1 \
&& apt-get clean \
&& rm -rf /var/lib/apt/lists/*
@ -43,5 +38,5 @@ USER appuser
EXPOSE 5000
ENV FLASK_ENV production
ENV FLASK_ENV=production
CMD ["./run.sh"]

View File

@ -88,25 +88,6 @@ def add_user_account(base_url: str, auth: str, username: str, password: str, str
return response.status_code == 200
def get_user_accounts_count(base_url: str, auth: str) -> int:
"""Get the count of user accounts from the specified base URL.
Args:
base_url (str): The base URL of the API.
auth (str): The authorization token for accessing the API.
Returns:
int: The count of user accounts.
"""
url = f"{base_url}/getUserAccounts/count"
payload = {}
headers = {"Authorization": f"Basic {auth}"}
response = requests.request("GET", url, headers=headers, data=payload)
res_json = json.loads(response.text)
return res_json['count']
def get_stream_names(base_url: str, auth: str) -> List[str]:
"""Get a list of stream names from the API.

Binary file not shown.

View File

@ -1,13 +1,8 @@
<!-- templates/add_account.html -->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Add Account - KTVManager</title>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css">
<link rel="stylesheet" href="{{ url_for('static', filename='styles.css') }}" />
<link rel="manifest" href="{{ url_for('static', filename='site.webmanifest') }}?v={{ version }}" />
{% extends "base.html" %}
{% block title %}Add Account - KTVManager{% endblock %}
{% block head_content %}
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/awesomplete/1.1.5/awesomplete.min.css" />
<style>
/* Hide the spinner by default */
@ -16,29 +11,9 @@
display: none;
}
</style>
</head>
<body>
<!-- Navbar -->
<nav class="navbar navbar-expand-lg navbar-dark bg-dark">
<a class="navbar-brand" href="/">KTVManager</a>
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarNav" aria-controls="navbarNav" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="navbarNav">
<ul class="navbar-nav ml-auto">
<li class="nav-item">
<a class="nav-link" href="/">Home</a>
</li>
<li class="nav-item">
<a class="nav-link" href="/accounts">Accounts</a>
</li>
<li class="nav-item">
<a class="nav-link" href="/urls">URLs</a>
</li>
</ul>
</div>
</nav>
{% endblock %}
{% block sub_nav %}
<!-- Sub-navigation for Accounts -->
<div class="bg-light py-2">
<div class="container">
@ -52,9 +27,9 @@
</ul>
</div>
</div>
{% endblock %}
<!-- Main Content -->
<main class="container mt-5">
{% block content %}
<h1>Add Account</h1>
<div>
<form action="/accounts/add" method="POST" onsubmit="showLoading()">
@ -97,12 +72,9 @@
<textarea class="form-control" id="accountDetails" rows="4"></textarea>
</div>
{% endif %}
{% endblock %}
</main>
<footer class="bg-dark text-white text-center py-3 mt-5">
<p></p>
</footer>
<script src="https://cdn.jsdelivr.net/npm/popper.js@1.16.1/dist/umd/popper.min.js"></script>
{% block scripts %}
<script src="https://cdnjs.cloudflare.com/ajax/libs/awesomplete/1.1.5/awesomplete.min.js"></script>
<script>
function showLoading() {
@ -175,5 +147,4 @@
}
});
</script>
</body>
</html>
{% endblock %}

57
templates/base.html Normal file
View File

@ -0,0 +1,57 @@
<!-- templates/base.html -->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>{% block title %}KTVManager{% endblock %}</title>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css">
<link rel="icon" type="image/png" href="{{ url_for('static', filename='favicon-96x96.png') }}" sizes="96x96" />
<link rel="icon" type="image/svg+xml" href="{{ url_for('static', filename='favicon.svg') }}" />
<link rel="shortcut icon" href="{{ url_for('static', filename='favicon.ico') }}" />
<link rel="apple-touch-icon" sizes="180x180" href="{{ url_for('static', filename='apple-touch-icon.png') }}" />
<meta name="apple-mobile-web-app-title" content="kTvManager" />
<link rel="manifest" href="{{ url_for('static', filename='site.webmanifest') }}?v={{ version }}" />
<link rel="stylesheet" href="{{ url_for('static', filename='styles.css') }}" />
{% block head_content %}{% endblock %}
</head>
<body>
<!-- Navbar -->
<nav class="navbar navbar-expand-lg navbar-dark bg-dark">
<a class="navbar-brand" href="/">KTVManager</a>
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarNav" aria-controls="navbarNav" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="navbarNav">
<ul class="navbar-nav ml-auto">
<li class="nav-item">
<a class="nav-link" href="/">Home</a>
</li>
<li class="nav-item">
<a class="nav-link" href="/accounts">Accounts</a>
</li>
<li class="nav-item">
<a class="nav-link" href="/urls">URLs</a>
</li>
</ul>
</div>
</nav>
{% block sub_nav %}{% endblock %}
<!-- Main Content -->
<main class="container mt-5">
{% block content %}{% endblock %}
</main>
<footer class="bg-dark text-white text-center py-3 mt-5">
<p>Version: {{ version }}</p>
</footer>
<script src="https://code.jquery.com/jquery-3.5.1.slim.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/popper.js@1.16.1/dist/umd/popper.min.js"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/js/bootstrap.min.js"></script>
{% block scripts %}{% endblock %}
</body>
</html>

View File

@ -1,42 +1,8 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>KTVManager</title>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css">
<link rel="stylesheet" href="{{ url_for('static', filename='styles.css') }}" />
<link rel="manifest" href="{{ url_for('static', filename='site.webmanifest') }}?v={{ version }}" />
</head>
<body>
<script>
if ('serviceWorker' in navigator) {
navigator.serviceWorker.register('{{ url_for("static", filename="service-worker.js") }}')
}
</script>
<!-- Navbar -->
<nav class="navbar navbar-expand-lg navbar-dark bg-dark">
<a class="navbar-brand" href="/">KTVManager</a>
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarNav" aria-controls="navbarNav" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="navbarNav">
<ul class="navbar-nav ml-auto">
<li class="nav-item">
<a class="nav-link" href="/">Home</a>
</li>
<li class="nav-item">
<a class="nav-link" href="/accounts">Accounts</a>
</li>
<li class="nav-item">
<a class="nav-link" href="/urls">URLs</a>
</li>
</ul>
</div>
</nav>
{% extends "base.html" %}
<!-- Main Content -->
<main class="container mt-5">
{% block title %}KTVManager{% endblock %}
{% block content %}
<h1>Welcome {{ username }}!</h1>
<br>
<h2>You have {{ accounts }} active accounts</h2>
@ -84,15 +50,12 @@
</tbody>
</table>
{% endif %}
</main>
{% endblock %}
<!-- Footer -->
<footer class="bg-dark text-white text-center py-3 mt-5">
<p>Version: {{ version }}</p>
</footer>
<script src="https://code.jquery.com/jquery-3.5.1.slim.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/popper.js@1.16.1/dist/umd/popper.min.js"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/js/bootstrap.min.js"></script>
</body>
</html>
{% block scripts %}
<script>
if ('serviceWorker' in navigator) {
navigator.serviceWorker.register('{{ url_for("static", filename="service-worker.js") }}')
}
</script>
{% endblock %}

View File

@ -1,44 +1,8 @@
<!-- templates/index.html -->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>KTVManager</title>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css">
<link rel="icon" type="image/png" href="{{ url_for('static', filename='favicon-96x96.png') }}" sizes="96x96" />
<link rel="icon" type="image/svg+xml" href="{{ url_for('static', filename='favicon.svg') }}" />
<link rel="shortcut icon" href="{{ url_for('static', filename='favicon.ico') }}" />
<link rel="apple-touch-icon" sizes="180x180" href="{{ url_for('static', filename='apple-touch-icon.png') }}" />
<meta name="apple-mobile-web-app-title" content="kTvManager" />
<link rel="manifest" href="{{ url_for('static', filename='site.webmanifest') }}?v={{ version }}" />
<link rel="stylesheet" href="{{ url_for('static', filename='styles.css') }}" />
</head>
<body>
{% extends "base.html" %}
<!-- Navbar -->
<nav class="navbar navbar-expand-lg navbar-dark bg-dark">
<a class="navbar-brand" href="/">KTVManager</a>
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarNav" aria-controls="navbarNav" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="navbarNav">
<ul class="navbar-nav ml-auto">
<li class="nav-item">
<a class="nav-link" href="/">Home</a>
</li>
<li class="nav-item">
<a class="nav-link" href="/accounts">Accounts</a>
</li>
<li class="nav-item">
<a class="nav-link" href="/urls">URLs</a>
</li>
</ul>
</div>
</nav>
{% block title %}KTVManager{% endblock %}
<!-- Main Content -->
<main div class="container mt-5">
{% block content %}
<h1>Welcome to KTV Manager</h1>
<!-- Login Form -->
@ -56,17 +20,10 @@
<div class="alert alert-danger mt-3">{{ error }}</div>
{% endif %}
</form>
</div>
</main>
{% endblock %}
<footer class="bg-dark text-white text-center py-3 mt-5">
<p></p>
</footer>
<script src="https://code.jquery.com/jquery-3.5.1.slim.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/popper.js@1.16.1/dist/umd/popper.min.js"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/js/bootstrap.min.js"></script>
<script>
{% block scripts %}
<script>
if ('serviceWorker' in navigator) {
navigator.serviceWorker.register('{{ url_for("static", filename="service-worker.js") }}')
// .then(reg => {
@ -75,6 +32,5 @@
// console.log('Service worker:', err);
// });
}
</script>
</body>
</html>
</script>
{% endblock %}

View File

@ -1,39 +1,8 @@
<!-- templates/urls.html -->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>KTVManager</title>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css">
<link rel="stylesheet" href="{{ url_for('static', filename='styles.css') }}" />
</head>
<body>
{% extends "base.html" %}
<!-- Navbar (same as index.html) -->
<nav class="navbar navbar-expand-lg navbar-dark bg-dark">
<a class="navbar-brand" href="/">KTVManager</a>
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarNav" aria-controls="navbarNav" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="navbarNav">
<ul class="navbar-nav ml-auto">
<li class="nav-item">
<a class="nav-link" href="/">Home</a>
</li>
<li class="nav-item">
<a class="nav-link" href="/accounts">Accounts</a> <!-- Link to the URLs page -->
</li>
<li class="nav-item">
<a class="nav-link" href="/urls">URLs</a> <!-- Link to the URLs page -->
</li>
</ul>
</div>
</nav>
{% block title %}URLs - KTVManager{% endblock %}
<!-- Main Content -->
<main div class="container mt-5">
{% block content %}
<h2>URLs</h2>
<table class="table table-striped">
<thead>
@ -51,15 +20,4 @@
{% endfor %}
</tbody>
</table>
</div>
</main>
<footer class="bg-dark text-white text-center py-3 mt-5">
<p></p>
</footer>
<script src="https://code.jquery.com/jquery-3.5.1.slim.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/popper.js@1.16.1/dist/umd/popper.min.js"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/js/bootstrap.min.js"></script>
</body>
</html>
{% endblock %}

View File

@ -1,30 +1,13 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>KTVManager</title>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css">
{% extends "base.html" %}
{% block title %}Accounts - KTVManager{% endblock %}
{% block head_content %}
<link rel="stylesheet" href="https://cdn.datatables.net/1.10.24/css/jquery.dataTables.min.css">
<link rel="stylesheet" href="https://cdn.datatables.net/responsive/2.2.9/css/responsive.dataTables.min.css">
<link rel="stylesheet" href="{{ url_for('static', filename='styles.css') }}" />
</head>
<body>
<!-- Navbar -->
<nav class="navbar navbar-expand-lg navbar-dark bg-dark">
<a class="navbar-brand" href="/">KTVManager</a>
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarNav" aria-controls="navbarNav" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="navbarNav">
<ul class="navbar-nav ml-auto">
<li class="nav-item"><a class="nav-link" href="/">Home</a></li>
<li class="nav-item"><a class="nav-link" href="/accounts">Accounts</a></li>
<li class="nav-item"><a class="nav-link" href="/urls">URLs</a></li>
</ul>
</div>
</nav>
{% endblock %}
{% block sub_nav %}
<!-- Sub-navigation for Accounts -->
<div class="bg-light py-2">
<div class="container">
@ -38,9 +21,9 @@
</ul>
</div>
</div>
{% endblock %}
<!-- Main Content -->
<main div class="container mt-5">
{% block content %}
<h2>{{ username }}'s Accounts</h2>
<div class="table-responsive">
<table class="table table-striped" id="accountsTable">
@ -78,16 +61,9 @@
</tbody>
</table>
</div>
</div>
</main>
{% endblock %}
<footer class="bg-dark text-white text-center py-3 mt-5">
<p></p>
</footer>
<script src="https://code.jquery.com/jquery-3.5.1.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/popper.js@1.16.1/dist/umd/popper.min.js"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/js/bootstrap.min.js"></script>
{% block scripts %}
<script src="https://cdn.datatables.net/1.10.24/js/jquery.dataTables.min.js"></script>
<script src="https://cdn.datatables.net/responsive/2.2.9/js/dataTables.responsive.min.js"></script>
<script>
@ -114,7 +90,4 @@
});
});
</script>
</body>
</html>
{% endblock %}