Browse Source

clean up and started adding python backend

Karl Hudgell 4 weeks ago
parent
commit
d718b89035
6 changed files with 128 additions and 42 deletions
  1. 4 4
      app.py
  2. 19 0
      backend/app.py
  3. 37 0
      backend/lib/mysql.py
  4. 61 33
      lib/reqs.py
  5. 1 1
      templates/home.html
  6. 6 4
      templates/user_accounts.html

+ 4 - 4
app.py

@@ -4,17 +4,17 @@ from flask_caching import Cache
 import requests.auth
 import os
 from lib.datetime import filter_accounts_current_month
-from lib.reqs import get_urls, get_user_accounts, add_user_account, delete_user_account
+from lib.reqs import get_urls, get_user_accounts, add_user_account, delete_user_account, get_user_accounts_count
 from flask import send_from_directory
 import requests
 import base64
 from flask import Flask
-from config import DevelopmentConfig  # or ProductionConfig
+from config import DevelopmentConfig 
 
 app = Flask(__name__)
 app.config.from_object(
     DevelopmentConfig
-)  # Use DevelopmentConfig or ProductionConfig as needed
+) 
 cache = Cache(app, config={"CACHE_TYPE": "SimpleCache"})
 
 
@@ -44,7 +44,7 @@ def home():
     return render_template(
         "home.html",
         username=session["username"],
-        accounts=get_user_accounts(base_url, session["auth_credentials"]),
+        accounts=get_user_accounts_count(base_url, session["auth_credentials"]),
         current_month_accounts=current_month_accounts,
     )
 

+ 19 - 0
backend/app.py

@@ -0,0 +1,19 @@
+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"])

+ 37 - 0
backend/lib/mysql.py

@@ -0,0 +1,37 @@
+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

+ 61 - 33
lib/reqs.py

@@ -1,11 +1,20 @@
 import requests
 import json
 from datetime import datetime
+from typing import List, Dict, Any
 
 
-def get_urls(base_url, auth: str) -> list:
-    url = f"{base_url}/getUserAccounts/streams"
+def get_urls(base_url: str, auth: str) -> List[Dict[str, Any]]:
+    """Retrieve user account streams 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:
+        List[Dict[str, Any]]: A list of user account streams.
+    """
+    url = f"{base_url}/getUserAccounts/streams"
     payload = {}
     headers = {"Authorization": f"Basic {auth}"}
 
@@ -13,67 +22,86 @@ def get_urls(base_url, auth: str) -> list:
     return json.loads(response.text)
 
 
-def get_user_accounts(base_url, auth: str) -> list:
-    url = f"{base_url}/getUserAccounts"
+def get_user_accounts(base_url: str, auth: str) -> List[Dict[str, Any]]:
+    """Retrieve 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:
+        List[Dict[str, Any]]: A list of user accounts with their expiration dates rendered.
+    """
+    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
 
 
-def delete_user_account(base_url: str, auth: str, stream:str, username:str) -> bool:
-    """_summary_
+def delete_user_account(base_url: str, auth: str, stream: str, username: str) -> bool:
+    """Delete a user account from the specified base URL.
 
     Args:
-        base_url (str): _description_
-        auth (str): _description_
-        stream (str): _description_
-        username (str): _description_
+        base_url (str): The base URL of the API.
+        auth (str): The authorization token for accessing the API.
+        stream (str): The name of the stream associated with the user account.
+        username (str): The username of the account to delete.
 
     Returns:
-        bool: _description_
-    """    
+        bool: True if the account was deleted successfully, False otherwise.
+    """
     url = f"{base_url}/deleteAccount"
-
     payload = {"stream": stream, "user": username}
-
     headers = {"Authorization": f"Basic {auth}"}
 
     response = requests.request("POST", url, headers=headers, data=payload)
-    if "Deleted" in response.text:
-        return True
-    else:
-        return False
+    return "Deleted" in response.text
 
 
-
-def add_user_account(base_url: str, auth: str, username:str, password:str, stream:str,) -> bool:
-    """_summary_
+def add_user_account(base_url: str, auth: str, username: str, password: str, stream: str) -> bool:
+    """Add a user account to the specified base URL.
 
     Args:
-        base_url (str): _description_
-        auth (str): _description_
-        stream (str): _description_
-        username (str): _description_
+        base_url (str): The base URL of the API.
+        auth (str): The authorization token for accessing the API.
+        username (str): The username of the account to add.
+        password (str): The password of the account to add.
+        stream (str): The name of the stream associated with the user account.
 
     Returns:
-        bool: _description_
-    """    
+        bool: True if the account was added successfully, False otherwise.
+    """
     url = f"{base_url}/addAccount"
-
     payload = {"username": username, "password": password, "stream": stream}
-
     headers = {"Authorization": f"Basic {auth}"}
 
     response = requests.request("POST", url, headers=headers, data=payload)
-    if "Added successfully" in response.text:
-        return True
-    else:
-        return False
+    return "Added successfully" in response.text
+
+
+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']

+ 1 - 1
templates/home.html

@@ -34,7 +34,7 @@
 <div class="container mt-5">
     <h1>Welcome {{ username }}!</h1>
     <br>
-    <h2>You have {{ accounts|length }} active accounts</h2>
+    <h2>You have {{ accounts }} active accounts</h2>
     <br>
     
     {% if current_month_accounts %}

+ 6 - 4
templates/user_accounts.html

@@ -45,7 +45,7 @@
             <table class="table table-striped" id="accountsTable">
                 <thead>
                     <tr>
-                        <th>#</th>
+                        <!-- <th>#</th> -->
                         <th>Username</th>
                         <th>Stream</th>
                         <th>Stream URL</th>
@@ -57,7 +57,7 @@
                 <tbody>
                     {% for account in user_accounts %}
                     <tr>
-                        <td>{{ loop.index }}</td>
+                        <!-- <td>{{ loop.index }}</td> -->
                         <td>{{ account.username }}</td>
                         <td>{{ account.stream }}</td>
                         <td><a href="{{ account.streamURL }}" target="_blank">{{ account.streamURL }}</a></td>
@@ -100,17 +100,19 @@
                 return data; // return as is if the format is unexpected
             };
     
-            // Initialize DataTable with custom sorting
+            // Initialize DataTable with custom sorting and default ordering by Expiry Date
             $('#accountsTable').DataTable({
                 "searching": true,
                 "ordering": true,
                 "responsive": true,
+                "order": [[3, 'asc']], // Default order by Expiry Date column in ascending order
                 "columnDefs": [
-                    { "type": "date-eu", "targets": 4 } // Use custom date-eu type for the date column
+                    { "type": "date-eu", "targets": 3 } // Use custom date-eu type for the date column
                 ]
             });
         });
     </script>
     
+    
 </body>
 </html>