Compare commits
	
		
			10 Commits
		
	
	
		
			13368a0437
			...
			9dc9b7e1b5
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 9dc9b7e1b5 | |||
| 8df6af5edf | |||
| e3cce698a0 | |||
| 318468fe53 | |||
| 41fef3cb15 | |||
| cc576e3c91 | |||
| 1455e45554 | |||
| a442460338 | |||
| f3b37d6ac2 | |||
| c174f1dbc9 | 
							
								
								
									
										9
									
								
								.bumpversion.toml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								.bumpversion.toml
									
									
									
									
									
										Normal 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}"
 | 
			
		||||
							
								
								
									
										2
									
								
								app.py
									
									
									
									
									
								
							
							
						
						
									
										2
									
								
								app.py
									
									
									
									
									
								
							@ -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
 | 
			
		||||
 | 
			
		||||
@ -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"])
 | 
			
		||||
@ -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
 | 
			
		||||
@ -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
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										11
									
								
								dockerfile
									
									
									
									
									
								
							
							
						
						
									
										11
									
								
								dockerfile
									
									
									
									
									
								
							@ -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"]
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										19
									
								
								lib/reqs.py
									
									
									
									
									
								
							
							
						
						
									
										19
									
								
								lib/reqs.py
									
									
									
									
									
								
							@ -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.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										
											BIN
										
									
								
								requirements.txt
									
									
									
									
									
								
							
							
						
						
									
										
											BIN
										
									
								
								requirements.txt
									
									
									
									
									
								
							
										
											Binary file not shown.
										
									
								
							@ -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,57 +27,54 @@
 | 
			
		||||
            </ul>
 | 
			
		||||
        </div>
 | 
			
		||||
    </div>
 | 
			
		||||
{% endblock %}
 | 
			
		||||
 | 
			
		||||
    <!-- Main Content -->
 | 
			
		||||
    <main class="container mt-5">
 | 
			
		||||
        <h1>Add Account</h1>
 | 
			
		||||
        <div>
 | 
			
		||||
        <form action="/accounts/add" method="POST" onsubmit="showLoading()">
 | 
			
		||||
{% block content %}
 | 
			
		||||
    <h1>Add Account</h1>
 | 
			
		||||
    <div>
 | 
			
		||||
    <form action="/accounts/add" method="POST" onsubmit="showLoading()">
 | 
			
		||||
        <div class="form-group">
 | 
			
		||||
            <label for="username">Username</label>
 | 
			
		||||
            <input type="text" class="form-control" id="username" name="username" value="{{ username }}" required>
 | 
			
		||||
        </div>
 | 
			
		||||
        <div class="form-group">
 | 
			
		||||
            <label for="password">Password</label>
 | 
			
		||||
            <input type="text" class="form-control" id="password" name="password" value="{{ password }}"  required>
 | 
			
		||||
        </div>
 | 
			
		||||
        <div class="form-group">
 | 
			
		||||
            <label for="stream">Stream Name</label>
 | 
			
		||||
            <input type="text" class="form-control" id="stream" name="stream" required>
 | 
			
		||||
        </div>
 | 
			
		||||
        <button type="submit" class="btn btn-primary" id="submitButton">
 | 
			
		||||
            <span class="spinner-border spinner-border-sm" id="loadingSpinner" role="status" aria-hidden="true"></span>
 | 
			
		||||
            <span id="buttonText">Add Account</span>
 | 
			
		||||
        </button>
 | 
			
		||||
    </form>
 | 
			
		||||
    {% if ocr_enabled %}
 | 
			
		||||
    <hr>
 | 
			
		||||
    <h2>Load Details Via OCR</h2>
 | 
			
		||||
        <form action="/OCRupload" method="POST" enctype="multipart/form-data" onsubmit="showLoadingOCR()">
 | 
			
		||||
            <div class="form-group">
 | 
			
		||||
                <label for="username">Username</label>
 | 
			
		||||
                <input type="text" class="form-control" id="username" name="username" value="{{ username }}" required>
 | 
			
		||||
                <label for="image">Select Image</label>
 | 
			
		||||
                <input type="file" class="form-control-file" id="image" name="image" accept="image/*" required>
 | 
			
		||||
            </div>
 | 
			
		||||
            <div class="form-group">
 | 
			
		||||
                <label for="password">Password</label>
 | 
			
		||||
                <input type="text" class="form-control" id="password" name="password" value="{{ password }}"  required>
 | 
			
		||||
            </div>
 | 
			
		||||
            <div class="form-group">
 | 
			
		||||
                <label for="stream">Stream Name</label>
 | 
			
		||||
                <input type="text" class="form-control" id="stream" name="stream" required>
 | 
			
		||||
            </div>
 | 
			
		||||
            <button type="submit" class="btn btn-primary" id="submitButton">
 | 
			
		||||
                <span class="spinner-border spinner-border-sm" id="loadingSpinner" role="status" aria-hidden="true"></span>
 | 
			
		||||
                <span id="buttonText">Add Account</span>
 | 
			
		||||
            <button type="submit" class="btn btn-success" id="ocrButton">
 | 
			
		||||
                <span class="spinner-border spinner-border-sm" id="ocrLoadingSpinner" role="status" aria-hidden="true"></span>
 | 
			
		||||
                <span id="ocrButtonText">Load Details</span>
 | 
			
		||||
            </button>
 | 
			
		||||
        </form>
 | 
			
		||||
        {% if ocr_enabled %}
 | 
			
		||||
        <hr>
 | 
			
		||||
        <h2>Load Details Via OCR</h2>
 | 
			
		||||
            <form action="/OCRupload" method="POST" enctype="multipart/form-data" onsubmit="showLoadingOCR()">
 | 
			
		||||
                <div class="form-group">
 | 
			
		||||
                    <label for="image">Select Image</label>
 | 
			
		||||
                    <input type="file" class="form-control-file" id="image" name="image" accept="image/*" required>
 | 
			
		||||
                </div>
 | 
			
		||||
                <button type="submit" class="btn btn-success" id="ocrButton">
 | 
			
		||||
                    <span class="spinner-border spinner-border-sm" id="ocrLoadingSpinner" role="status" aria-hidden="true"></span>
 | 
			
		||||
                    <span id="ocrButtonText">Load Details</span>
 | 
			
		||||
                </button>
 | 
			
		||||
            </form>
 | 
			
		||||
        {% endif %}
 | 
			
		||||
        {% if text_input_enabled %}
 | 
			
		||||
        <hr>
 | 
			
		||||
        <h2>Load Details Via Text</h2>
 | 
			
		||||
        <div class="form-group">
 | 
			
		||||
            <label for="accountDetails">Paste Account Details</label>
 | 
			
		||||
            <textarea class="form-control" id="accountDetails" rows="4"></textarea>
 | 
			
		||||
        </div>
 | 
			
		||||
        {% endif %}
 | 
			
		||||
    {% endif %}
 | 
			
		||||
    {% if text_input_enabled %}
 | 
			
		||||
    <hr>
 | 
			
		||||
    <h2>Load Details Via Text</h2>
 | 
			
		||||
    <div class="form-group">
 | 
			
		||||
        <label for="accountDetails">Paste Account Details</label>
 | 
			
		||||
        <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
									
								
							
							
						
						
									
										57
									
								
								templates/base.html
									
									
									
									
									
										Normal 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>
 | 
			
		||||
@ -1,98 +1,61 @@
 | 
			
		||||
<!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">
 | 
			
		||||
        <h1>Welcome {{ username }}!</h1>
 | 
			
		||||
        <br>
 | 
			
		||||
        <h2>You have {{ accounts }} active accounts</h2>
 | 
			
		||||
        <br>
 | 
			
		||||
{% block title %}KTVManager{% endblock %}
 | 
			
		||||
 | 
			
		||||
        {% if current_month_accounts %}
 | 
			
		||||
            <h3>Accounts Expiring Within 30 Days</h3>
 | 
			
		||||
            <table class="table table-bordered table-striped">
 | 
			
		||||
                <thead class="thead-dark">
 | 
			
		||||
{% block content %}
 | 
			
		||||
    <h1>Welcome {{ username }}!</h1>
 | 
			
		||||
    <br>
 | 
			
		||||
    <h2>You have {{ accounts }} active accounts</h2>
 | 
			
		||||
    <br>
 | 
			
		||||
    
 | 
			
		||||
    {% if current_month_accounts %}
 | 
			
		||||
        <h3>Accounts Expiring Within 30 Days</h3>
 | 
			
		||||
        <table class="table table-bordered table-striped">
 | 
			
		||||
            <thead class="thead-dark">
 | 
			
		||||
                <tr>
 | 
			
		||||
                    <th>Stream Name</th>
 | 
			
		||||
                    <th>Username</th>
 | 
			
		||||
                    <th>Expiry Date</th>
 | 
			
		||||
                </tr>
 | 
			
		||||
            </thead>
 | 
			
		||||
            <tbody>
 | 
			
		||||
                {% for account in current_month_accounts %}
 | 
			
		||||
                    <tr>
 | 
			
		||||
                        <th>Stream Name</th>
 | 
			
		||||
                        <th>Username</th>
 | 
			
		||||
                        <th>Expiry Date</th>
 | 
			
		||||
                        <td>{{ account.stream }}</td>
 | 
			
		||||
                        <td>{{ account.username }}</td>
 | 
			
		||||
                        <td>{{ account.expiaryDate_rendered }}</td>
 | 
			
		||||
                    </tr>
 | 
			
		||||
                </thead>
 | 
			
		||||
                <tbody>
 | 
			
		||||
                    {% for account in current_month_accounts %}
 | 
			
		||||
                        <tr>
 | 
			
		||||
                            <td>{{ account.stream }}</td>
 | 
			
		||||
                            <td>{{ account.username }}</td>
 | 
			
		||||
                            <td>{{ account.expiaryDate_rendered }}</td>
 | 
			
		||||
                        </tr>
 | 
			
		||||
                    {% endfor %}
 | 
			
		||||
                </tbody>
 | 
			
		||||
            </table>
 | 
			
		||||
        {% endif %}
 | 
			
		||||
        {% if expired_accounts %}
 | 
			
		||||
            <h3>Expired Accounts</h3>
 | 
			
		||||
            <table class="table table-bordered table-striped">
 | 
			
		||||
                <thead class="thead-dark">
 | 
			
		||||
                {% endfor %}
 | 
			
		||||
            </tbody>
 | 
			
		||||
        </table>
 | 
			
		||||
    {% endif %}
 | 
			
		||||
    {% if expired_accounts %}
 | 
			
		||||
        <h3>Expired Accounts</h3>
 | 
			
		||||
        <table class="table table-bordered table-striped">
 | 
			
		||||
            <thead class="thead-dark">
 | 
			
		||||
                <tr>
 | 
			
		||||
                    <th>Stream Name</th>
 | 
			
		||||
                    <th>Username</th>
 | 
			
		||||
                    <th>Expiry Date</th>
 | 
			
		||||
                </tr>
 | 
			
		||||
            </thead>
 | 
			
		||||
            <tbody>
 | 
			
		||||
                {% for account in expired_accounts %}
 | 
			
		||||
                    <tr>
 | 
			
		||||
                        <th>Stream Name</th>
 | 
			
		||||
                        <th>Username</th>
 | 
			
		||||
                        <th>Expiry Date</th>
 | 
			
		||||
                        <td>{{ account.stream }}</td>
 | 
			
		||||
                        <td>{{ account.username }}</td>
 | 
			
		||||
                        <td>{{ account.expiaryDate_rendered }}</td>
 | 
			
		||||
                    </tr>
 | 
			
		||||
                </thead>
 | 
			
		||||
                <tbody>
 | 
			
		||||
                    {% for account in expired_accounts %}
 | 
			
		||||
                        <tr>
 | 
			
		||||
                            <td>{{ account.stream }}</td>
 | 
			
		||||
                            <td>{{ account.username }}</td>
 | 
			
		||||
                            <td>{{ account.expiaryDate_rendered }}</td>
 | 
			
		||||
                        </tr>
 | 
			
		||||
                    {% endfor %}
 | 
			
		||||
                </tbody>
 | 
			
		||||
            </table>
 | 
			
		||||
        {% endif %}
 | 
			
		||||
    </main>
 | 
			
		||||
                {% endfor %}
 | 
			
		||||
            </tbody>
 | 
			
		||||
        </table>
 | 
			
		||||
    {% endif %}
 | 
			
		||||
{% 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 %}
 | 
			
		||||
 | 
			
		||||
@ -1,80 +1,36 @@
 | 
			
		||||
<!-- 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>
 | 
			
		||||
{% block title %}KTVManager{% endblock %}
 | 
			
		||||
 | 
			
		||||
{% block content %}
 | 
			
		||||
    <h1>Welcome to KTV Manager</h1>
 | 
			
		||||
 | 
			
		||||
    <!-- Login Form -->
 | 
			
		||||
    <form action="/login" method="post" class="mt-3">
 | 
			
		||||
        <div class="form-group">
 | 
			
		||||
            <label for="username">Username:</label>
 | 
			
		||||
            <input type="text" class="form-control" id="username" name="username" required>
 | 
			
		||||
        </div>
 | 
			
		||||
    </nav>
 | 
			
		||||
        <div class="form-group">
 | 
			
		||||
            <label for="password">Password:</label>
 | 
			
		||||
            <input type="password" class="form-control" id="password" name="password" required>
 | 
			
		||||
        </div>
 | 
			
		||||
        <button type="submit" class="btn btn-primary">Login</button>
 | 
			
		||||
        {% if error %}
 | 
			
		||||
            <div class="alert alert-danger mt-3">{{ error }}</div>
 | 
			
		||||
        {% endif %}
 | 
			
		||||
    </form>
 | 
			
		||||
{% endblock %}
 | 
			
		||||
 | 
			
		||||
    <!-- Main Content -->
 | 
			
		||||
    <main div class="container mt-5">
 | 
			
		||||
        <h1>Welcome to KTV Manager</h1>
 | 
			
		||||
 | 
			
		||||
        <!-- Login Form -->
 | 
			
		||||
        <form action="/login" method="post" class="mt-3">
 | 
			
		||||
            <div class="form-group">
 | 
			
		||||
                <label for="username">Username:</label>
 | 
			
		||||
                <input type="text" class="form-control" id="username" name="username" required>
 | 
			
		||||
            </div>
 | 
			
		||||
            <div class="form-group">
 | 
			
		||||
                <label for="password">Password:</label>
 | 
			
		||||
                <input type="password" class="form-control" id="password" name="password" required>
 | 
			
		||||
            </div>
 | 
			
		||||
            <button type="submit" class="btn btn-primary">Login</button>
 | 
			
		||||
            {% if error %}
 | 
			
		||||
                <div class="alert alert-danger mt-3">{{ error }}</div>
 | 
			
		||||
            {% endif %}
 | 
			
		||||
        </form>
 | 
			
		||||
    </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>
 | 
			
		||||
    <script>
 | 
			
		||||
        if ('serviceWorker' in navigator) {
 | 
			
		||||
            navigator.serviceWorker.register('{{ url_for("static", filename="service-worker.js") }}')
 | 
			
		||||
            // .then(reg => {
 | 
			
		||||
            // 		console.log('Service worker:', reg);
 | 
			
		||||
            // .catch(err => {
 | 
			
		||||
            // 	console.log('Service worker:', err);
 | 
			
		||||
            // });
 | 
			
		||||
        }
 | 
			
		||||
    </script>
 | 
			
		||||
</body>
 | 
			
		||||
</html>
 | 
			
		||||
{% block scripts %}
 | 
			
		||||
<script>
 | 
			
		||||
    if ('serviceWorker' in navigator) {
 | 
			
		||||
        navigator.serviceWorker.register('{{ url_for("static", filename="service-worker.js") }}')
 | 
			
		||||
        // .then(reg => {
 | 
			
		||||
        // 		console.log('Service worker:', reg);
 | 
			
		||||
        // .catch(err => {
 | 
			
		||||
        // 	console.log('Service worker:', err);
 | 
			
		||||
        // });
 | 
			
		||||
    }
 | 
			
		||||
</script>
 | 
			
		||||
{% endblock %}
 | 
			
		||||
 | 
			
		||||
@ -1,65 +1,23 @@
 | 
			
		||||
<!-- 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">
 | 
			
		||||
        <h2>URLs</h2>
 | 
			
		||||
        <table class="table table-striped">
 | 
			
		||||
            <thead>
 | 
			
		||||
                <tr>
 | 
			
		||||
                    <th>#</th>
 | 
			
		||||
                    <th>URL</th>
 | 
			
		||||
                </tr>
 | 
			
		||||
            </thead>
 | 
			
		||||
            <tbody>
 | 
			
		||||
                {% for url in urls %}
 | 
			
		||||
                <tr>
 | 
			
		||||
                    <td>{{ loop.index }}</td>
 | 
			
		||||
                    <td><a href="{{ url }}" target="_blank">{{ url }}</a></td>
 | 
			
		||||
                </tr>
 | 
			
		||||
                {% 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>
 | 
			
		||||
{% block content %}
 | 
			
		||||
    <h2>URLs</h2>
 | 
			
		||||
    <table class="table table-striped">
 | 
			
		||||
        <thead>
 | 
			
		||||
            <tr>
 | 
			
		||||
                <th>#</th>
 | 
			
		||||
                <th>URL</th>
 | 
			
		||||
            </tr>
 | 
			
		||||
        </thead>
 | 
			
		||||
        <tbody>
 | 
			
		||||
            {% for url in urls %}
 | 
			
		||||
            <tr>
 | 
			
		||||
                <td>{{ loop.index }}</td>
 | 
			
		||||
                <td><a href="{{ url }}" target="_blank">{{ url }}</a></td>
 | 
			
		||||
            </tr>
 | 
			
		||||
            {% endfor %}
 | 
			
		||||
        </tbody>
 | 
			
		||||
    </table>
 | 
			
		||||
{% endblock %}
 | 
			
		||||
 | 
			
		||||
@ -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,56 +21,49 @@
 | 
			
		||||
            </ul>
 | 
			
		||||
        </div>
 | 
			
		||||
    </div>
 | 
			
		||||
{% endblock %}
 | 
			
		||||
 | 
			
		||||
    <!-- Main Content -->
 | 
			
		||||
    <main div class="container mt-5">
 | 
			
		||||
        <h2>{{ username }}'s Accounts</h2>
 | 
			
		||||
        <div class="table-responsive">
 | 
			
		||||
            <table class="table table-striped" id="accountsTable">
 | 
			
		||||
                <thead>
 | 
			
		||||
                    <tr>
 | 
			
		||||
                        <!-- <th>#</th> -->
 | 
			
		||||
                        <th>Username</th>
 | 
			
		||||
                        <th>Stream</th>
 | 
			
		||||
                        <th>Stream URL</th>
 | 
			
		||||
                        <th>Expiry Date</th>
 | 
			
		||||
                        <th>Password</th>
 | 
			
		||||
                        <th>Actions</th>
 | 
			
		||||
                    </tr>
 | 
			
		||||
                </thead>
 | 
			
		||||
                <tbody>
 | 
			
		||||
                    {% for account in user_accounts %}
 | 
			
		||||
                    <tr>
 | 
			
		||||
                        <!-- <td>{{ loop.index }}</td> -->
 | 
			
		||||
                        <td>{{ account.username }}</td>
 | 
			
		||||
                        <td>{{ account.stream }}</td>
 | 
			
		||||
                        <td><a href="{{ account.streamURL }}" target="_blank">{{ account.streamURL }}</a></td>
 | 
			
		||||
                        <td>{{ account.expiaryDate_rendered }}</td>
 | 
			
		||||
                        <td>{{ account.password }}</td>
 | 
			
		||||
                        <td>
 | 
			
		||||
                            <form action="/accounts/delete" method="POST" style="display:inline;">
 | 
			
		||||
                                <input type="hidden" name="stream" value="{{ account.stream }}">
 | 
			
		||||
                                <input type="hidden" name="username" value="{{ account.username }}">
 | 
			
		||||
                                <button type="submit" class="btn btn-danger" onclick="return confirm('Are you sure you want to delete this account?');">
 | 
			
		||||
                                    Delete
 | 
			
		||||
                                </button>
 | 
			
		||||
                            </form>
 | 
			
		||||
                        </td>
 | 
			
		||||
                    </tr>
 | 
			
		||||
                    {% endfor %}
 | 
			
		||||
                </tbody>
 | 
			
		||||
            </table>
 | 
			
		||||
        </div>
 | 
			
		||||
{% block content %}
 | 
			
		||||
    <h2>{{ username }}'s Accounts</h2>
 | 
			
		||||
    <div class="table-responsive">
 | 
			
		||||
        <table class="table table-striped" id="accountsTable">
 | 
			
		||||
            <thead>
 | 
			
		||||
                <tr>
 | 
			
		||||
                    <!-- <th>#</th> -->
 | 
			
		||||
                    <th>Username</th>
 | 
			
		||||
                    <th>Stream</th>
 | 
			
		||||
                    <th>Stream URL</th>
 | 
			
		||||
                    <th>Expiry Date</th>
 | 
			
		||||
                    <th>Password</th>
 | 
			
		||||
                    <th>Actions</th>
 | 
			
		||||
                </tr>
 | 
			
		||||
            </thead>
 | 
			
		||||
            <tbody>
 | 
			
		||||
                {% for account in user_accounts %}
 | 
			
		||||
                <tr>
 | 
			
		||||
                    <!-- <td>{{ loop.index }}</td> -->
 | 
			
		||||
                    <td>{{ account.username }}</td>
 | 
			
		||||
                    <td>{{ account.stream }}</td>
 | 
			
		||||
                    <td><a href="{{ account.streamURL }}" target="_blank">{{ account.streamURL }}</a></td>
 | 
			
		||||
                    <td>{{ account.expiaryDate_rendered }}</td>
 | 
			
		||||
                    <td>{{ account.password }}</td>
 | 
			
		||||
                    <td>
 | 
			
		||||
                        <form action="/accounts/delete" method="POST" style="display:inline;">
 | 
			
		||||
                            <input type="hidden" name="stream" value="{{ account.stream }}">
 | 
			
		||||
                            <input type="hidden" name="username" value="{{ account.username }}">
 | 
			
		||||
                            <button type="submit" class="btn btn-danger" onclick="return confirm('Are you sure you want to delete this account?');">
 | 
			
		||||
                                Delete
 | 
			
		||||
                            </button>
 | 
			
		||||
                        </form>
 | 
			
		||||
                    </td>
 | 
			
		||||
                </tr>
 | 
			
		||||
                {% endfor %}
 | 
			
		||||
            </tbody>
 | 
			
		||||
        </table>
 | 
			
		||||
    </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 %}
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user