Browse Source

initial working version

Karl Hudgell 4 months ago
parent
commit
44a7cd0b82

+ 2 - 0
.gitignore

@@ -0,0 +1,2 @@
+venv/
+config.py

+ 17 - 0
.vscode/launch.json

@@ -0,0 +1,17 @@
+{
+    // Use IntelliSense to learn about possible attributes.
+    // Hover to view descriptions of existing attributes.
+    // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
+    "version": "0.2.0",
+    "configurations": [
+        {
+            "name": "Python Debugger: Current File",
+            "type": "debugpy",
+            "request": "launch",
+            "program": "${file}",
+            "console": "integratedTerminal",
+            "justMyCode": false,
+            "args": ["--host=0.0.0.0"]
+        }
+    ]
+}

BIN
__pycache__/config.cpython-310.pyc


+ 73 - 0
app.py

@@ -0,0 +1,73 @@
+# app.py
+from flask import Flask, render_template, request, redirect, url_for, session, flash
+import requests.auth
+from lib.datetime import filter_accounts_current_month
+from lib.reqs import (get_urls, get_user_accounts)
+import requests
+import base64
+from flask import Flask
+from config import DevelopmentConfig  # or ProductionConfig
+
+app = Flask(__name__)
+app.config.from_object(DevelopmentConfig)  # Use DevelopmentConfig or ProductionConfig as needed
+
+@app.route('/')
+def home():
+    # If the user is logged in, redirect to a protected page like /accounts
+    if session.get('logged_in'):
+        base_url = app.config['BASE_URL']  # Access base_url from the config
+        all_accounts = get_user_accounts(base_url, session['auth_credentials'])
+        current_month_accounts = filter_accounts_current_month(all_accounts)
+        return render_template('home.html',  username=session['username'], accounts=get_user_accounts(base_url, session['auth_credentials']), current_month_accounts=current_month_accounts)
+    return render_template('index.html')
+
+@app.route('/login', methods=['POST'])
+def login():
+    username = request.form['username']
+    password = request.form['password']
+    
+    # Encode the username and password in Base64
+    credentials = f"{username}:{password}"
+    encoded_credentials = base64.b64encode(credentials.encode()).decode()
+    
+    base_url = app.config['BASE_URL']  # Access base_url from the config
+    login_url = f"{base_url}/Login"  # Construct the full URL
+
+    # Send GET request to the external login API with Basic Auth
+    response = requests.get(
+        login_url,
+        auth=requests.auth.HTTPBasicAuth(username, password)
+    )
+
+    # Check if login was successful
+    if response.status_code == 200 and response.json().get("auth") == "Success":
+        # Set session variable to indicate the user is logged in
+        session['logged_in'] = True
+        session['username'] = username
+        session['auth_credentials'] = encoded_credentials
+        return redirect(url_for('home'))  # Redirect to the Accounts page
+    else:
+        # Show error on the login page
+        error = "Invalid username or password. Please try again."
+        return render_template('index.html', error=error)
+
+@app.route('/urls', methods=['GET'])
+def urls():
+    # Check if the user is logged in
+    if not session.get('logged_in'):
+        return redirect(url_for('home'))
+    # Placeholder content for Accounts page
+    base_url = app.config['BASE_URL']  # Access base_url from the config
+    return render_template('urls.html', urls=get_urls(base_url, session['auth_credentials']))
+
+@app.route('/accounts', methods=['GET'])
+def user_accounts():
+    # Check if the user is logged in
+    if not session.get('logged_in'):
+        return redirect(url_for('home'))
+    # Placeholder content for Accounts page
+    base_url = app.config['BASE_URL']  # Access base_url from the config    
+    return render_template('user_accounts.html', username=session['username'], user_accounts=get_user_accounts(base_url, session['auth_credentials']))
+
+if __name__ == '__main__':
+    app.run(debug=app.config['DEBUG'], host=app.config['HOST'], port=app.config['PORT'])

+ 11 - 0
config.py.sample

@@ -0,0 +1,11 @@
+# config.py
+
+class Config:
+    DEBUG = False
+    BASE_URL = ''  # Set your base URL here
+
+class DevelopmentConfig(Config):
+    DEBUG = True
+
+class ProductionConfig(Config):
+    BASE_URL = ''  # Production base URL

BIN
lib/__pycache__/datetime.cpython-310.pyc


BIN
lib/__pycache__/reqs.cpython-310.pyc


+ 25 - 0
lib/datetime.py

@@ -0,0 +1,25 @@
+from datetime import datetime
+from flask import render_template
+
+def filter_accounts_current_month(accounts):
+    # Get the start and end of the current month
+    now = datetime.now()
+    start_of_month = datetime(now.year, now.month, 1)
+    if now.month == 12:
+        # If current month is December, next month is January of the next year
+        start_of_next_month = datetime(now.year + 1, 1, 1)
+    else:
+        # Otherwise, next month is just the next month of the same year
+        start_of_next_month = datetime(now.year, now.month + 1, 1)
+    
+    # Convert start and end of the month to epoch timestamps
+    start_of_month_timestamp = int(start_of_month.timestamp())
+    start_of_next_month_timestamp = int(start_of_next_month.timestamp())
+
+    # Filter accounts with expiryDate in the current month
+    accounts_in_current_month = [
+        account for account in accounts
+        if start_of_month_timestamp <= account['expiaryDate'] < start_of_next_month_timestamp
+    ]
+
+    return accounts_in_current_month

+ 26 - 0
lib/reqs.py

@@ -0,0 +1,26 @@
+import requests
+import json
+from datetime import datetime
+
+
+def get_urls(base_url, auth: str) -> list:
+    url = f"{base_url}/getUserAccounts/streams"
+
+    payload = {}
+    headers = {"Authorization": f"Basic {auth}"}
+
+    response = requests.request("GET", url, headers=headers, data=payload)
+    return json.loads(response.text)
+
+
+def get_user_accounts(base_url, auth: str) -> list:
+    url = f"{base_url}/getUserAccounts"
+
+    payload = {}
+    headers = {"Authorization": f"Basic {auth}"}
+
+    response = requests.request("GET", url, headers=headers, data=payload)
+    res_json = json.loads(response.text)
+    for account in res_json:
+        account['expiaryDate_rendered'] = datetime.utcfromtimestamp(account['expiaryDate']).strftime('%d/%m/%Y')  
+    return res_json

+ 66 - 0
templates/home.html

@@ -0,0 +1,66 @@
+<!-- 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>KTV Manager</title>
+    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css">
+</head>
+<body>
+
+    <!-- Navbar -->
+    <nav class="navbar navbar-expand-lg navbar-dark bg-dark">
+        <a class="navbar-brand" href="#">KTV Manager</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>
+
+    <!-- Main Content -->
+    <div class="container mt-5">
+        <h1>Welcome to KTV Manager {{ username }}</h1>
+        <span>You have {{accounts|length}} accounts</span>
+        <h3>Accounts Expiring This Month</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>
+                        <td>{{ account.stream }}</td>
+                        <td>{{ account.username }}</td>
+                        <td>{{ account.expiaryDate_rendered }}</td>
+                    </tr>
+                {% endfor %}
+            </tbody>
+        </table>
+    </div>
+
+    <footer class="bg-dark text-white text-center py-3 mt-5">
+        <p>&copy; 2024 KTV Manager | All rights reserved</p>
+    </footer>
+
+    <script src="https://code.jquery.com/jquery-3.5.1.slim.min.js"></script>
+    <script src="https://cdn.jsdelivr.net/npm/@popperjs/core@2.0.7/dist/umd/popper.min.js"></script>
+    <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/js/bootstrap.min.js"></script>
+</body>
+</html>

+ 18 - 3
templates/index.html

@@ -21,10 +21,10 @@
                     <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 -->
+                    <a class="nav-link" href="/accounts">Accounts</a>
                 </li>
                 <li class="nav-item">
-                    <a class="nav-link" href="/urls">URLs</a> <!-- Link to the URLs page -->
+                    <a class="nav-link" href="/urls">URLs</a>
                 </li>
             </ul>
         </div>
@@ -33,7 +33,22 @@
     <!-- Main Content -->
     <div class="container mt-5">
         <h1>Welcome to KTV Manager</h1>
-        <!-- <p>This website is built using Flask and Bootstrap. It’s designed to look great on any screen size!</p> -->
+
+        <!-- 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>
 
     <footer class="bg-dark text-white text-center py-3 mt-5">

+ 2 - 2
templates/urls.html

@@ -4,7 +4,7 @@
 <head>
     <meta charset="UTF-8">
     <meta name="viewport" content="width=device-width, initial-scale=1.0">
-    <title>URLs List</title>
+    <title>KTVManager</title>
     <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css">
 </head>
 <body>
@@ -53,7 +53,7 @@
     </div>
 
     <footer class="bg-dark text-white text-center py-3 mt-5">
-        <p>&copy; 2024 My Site | All rights reserved</p>
+        <p>&copy; 2024 KTVManager | All rights reserved</p>
     </footer>
 
     <script src="https://code.jquery.com/jquery-3.5.1.slim.min.js"></script>

+ 5 - 5
templates/user_accounts.html

@@ -4,7 +4,7 @@
 <head>
     <meta charset="UTF-8">
     <meta name="viewport" content="width=device-width, initial-scale=1.0">
-    <title>User Accounts</title>
+    <title>KTVManager</title>
     <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css">
     <link rel="stylesheet" href="https://cdn.datatables.net/1.10.24/css/jquery.dataTables.min.css">
     <style>
@@ -19,7 +19,7 @@
 
     <!-- Navbar (same as index.html) -->
     <nav class="navbar navbar-expand-lg navbar-dark bg-dark">
-        <a class="navbar-brand" href="#">KTV Manager</a>
+        <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>
@@ -40,7 +40,7 @@
 
     <!-- Main Content -->
     <div class="container mt-5">
-        <h2>User Accounts</h2>
+        <h2>{{ username }}'s Accounts</h2>
         <table class="table table-striped" id="accountsTable">
             <thead>
                 <tr>
@@ -59,7 +59,7 @@
                     <td>{{ account.username }}</td>
                     <td>{{ account.stream }}</td>
                     <td><a href="{{ account.streamURL }}" target="_blank">{{ account.streamURL }}</a></td>
-                    <td>{{ account.expiaryDate }}</td> <!-- Ensure this is in d/m/Y format -->
+                    <td>{{ account.expiaryDate_rendered }}</td>
                     <td class="password-cell" data-password="{{ account.password }}">
                         <span class="password-blur">********</span>
                     </td>
@@ -70,7 +70,7 @@
     </div>
 
     <footer class="bg-dark text-white text-center py-3 mt-5">
-        <p>&copy; 2024 My Site | All rights reserved</p>
+        <p>&copy; 2024 KTVManager | All rights reserved</p>
     </footer>
 
     <script src="https://code.jquery.com/jquery-3.5.1.min.js"></script>