clean up and started adding python backend
This commit is contained in:
parent
f5369c05ac
commit
d718b89035
8
app.py
8
app.py
@ -4,17 +4,17 @@ from flask_caching import Cache
|
|||||||
import requests.auth
|
import requests.auth
|
||||||
import os
|
import os
|
||||||
from lib.datetime import filter_accounts_current_month
|
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
|
from flask import send_from_directory
|
||||||
import requests
|
import requests
|
||||||
import base64
|
import base64
|
||||||
from flask import Flask
|
from flask import Flask
|
||||||
from config import DevelopmentConfig # or ProductionConfig
|
from config import DevelopmentConfig
|
||||||
|
|
||||||
app = Flask(__name__)
|
app = Flask(__name__)
|
||||||
app.config.from_object(
|
app.config.from_object(
|
||||||
DevelopmentConfig
|
DevelopmentConfig
|
||||||
) # Use DevelopmentConfig or ProductionConfig as needed
|
)
|
||||||
cache = Cache(app, config={"CACHE_TYPE": "SimpleCache"})
|
cache = Cache(app, config={"CACHE_TYPE": "SimpleCache"})
|
||||||
|
|
||||||
|
|
||||||
@ -44,7 +44,7 @@ def home():
|
|||||||
return render_template(
|
return render_template(
|
||||||
"home.html",
|
"home.html",
|
||||||
username=session["username"],
|
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,
|
current_month_accounts=current_month_accounts,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
19
backend/app.py
Normal file
19
backend/app.py
Normal file
@ -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
backend/lib/mysql.py
Normal file
37
backend/lib/mysql.py
Normal file
@ -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
|
94
lib/reqs.py
94
lib/reqs.py
@ -1,11 +1,20 @@
|
|||||||
import requests
|
import requests
|
||||||
import json
|
import json
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
|
from typing import List, Dict, Any
|
||||||
|
|
||||||
|
|
||||||
def get_urls(base_url, auth: str) -> list:
|
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"
|
url = f"{base_url}/getUserAccounts/streams"
|
||||||
|
|
||||||
payload = {}
|
payload = {}
|
||||||
headers = {"Authorization": f"Basic {auth}"}
|
headers = {"Authorization": f"Basic {auth}"}
|
||||||
|
|
||||||
@ -13,67 +22,86 @@ def get_urls(base_url, auth: str) -> list:
|
|||||||
return json.loads(response.text)
|
return json.loads(response.text)
|
||||||
|
|
||||||
|
|
||||||
def get_user_accounts(base_url, auth: str) -> list:
|
def get_user_accounts(base_url: str, auth: str) -> List[Dict[str, Any]]:
|
||||||
url = f"{base_url}/getUserAccounts"
|
"""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 = {}
|
payload = {}
|
||||||
headers = {"Authorization": f"Basic {auth}"}
|
headers = {"Authorization": f"Basic {auth}"}
|
||||||
|
|
||||||
response = requests.request("GET", url, headers=headers, data=payload)
|
response = requests.request("GET", url, headers=headers, data=payload)
|
||||||
res_json = json.loads(response.text)
|
res_json = json.loads(response.text)
|
||||||
|
|
||||||
for account in res_json:
|
for account in res_json:
|
||||||
account["expiaryDate_rendered"] = datetime.utcfromtimestamp(
|
account["expiaryDate_rendered"] = datetime.utcfromtimestamp(
|
||||||
account["expiaryDate"]
|
account["expiaryDate"]
|
||||||
).strftime("%d/%m/%Y")
|
).strftime("%d/%m/%Y")
|
||||||
|
|
||||||
return res_json
|
return res_json
|
||||||
|
|
||||||
|
|
||||||
def delete_user_account(base_url: str, auth: str, stream:str, username:str) -> bool:
|
def delete_user_account(base_url: str, auth: str, stream: str, username: str) -> bool:
|
||||||
"""_summary_
|
"""Delete a user account from the specified base URL.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
base_url (str): _description_
|
base_url (str): The base URL of the API.
|
||||||
auth (str): _description_
|
auth (str): The authorization token for accessing the API.
|
||||||
stream (str): _description_
|
stream (str): The name of the stream associated with the user account.
|
||||||
username (str): _description_
|
username (str): The username of the account to delete.
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
bool: _description_
|
bool: True if the account was deleted successfully, False otherwise.
|
||||||
"""
|
"""
|
||||||
url = f"{base_url}/deleteAccount"
|
url = f"{base_url}/deleteAccount"
|
||||||
|
|
||||||
payload = {"stream": stream, "user": username}
|
payload = {"stream": stream, "user": username}
|
||||||
|
|
||||||
headers = {"Authorization": f"Basic {auth}"}
|
headers = {"Authorization": f"Basic {auth}"}
|
||||||
|
|
||||||
response = requests.request("POST", url, headers=headers, data=payload)
|
response = requests.request("POST", url, headers=headers, data=payload)
|
||||||
if "Deleted" in response.text:
|
return "Deleted" in response.text
|
||||||
return True
|
|
||||||
else:
|
|
||||||
return False
|
|
||||||
|
|
||||||
|
|
||||||
|
def add_user_account(base_url: str, auth: str, username: str, password: str, stream: str) -> bool:
|
||||||
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.
|
||||||
"""_summary_
|
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
base_url (str): _description_
|
base_url (str): The base URL of the API.
|
||||||
auth (str): _description_
|
auth (str): The authorization token for accessing the API.
|
||||||
stream (str): _description_
|
username (str): The username of the account to add.
|
||||||
username (str): _description_
|
password (str): The password of the account to add.
|
||||||
|
stream (str): The name of the stream associated with the user account.
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
bool: _description_
|
bool: True if the account was added successfully, False otherwise.
|
||||||
"""
|
"""
|
||||||
url = f"{base_url}/addAccount"
|
url = f"{base_url}/addAccount"
|
||||||
|
|
||||||
payload = {"username": username, "password": password, "stream": stream}
|
payload = {"username": username, "password": password, "stream": stream}
|
||||||
|
|
||||||
headers = {"Authorization": f"Basic {auth}"}
|
headers = {"Authorization": f"Basic {auth}"}
|
||||||
|
|
||||||
response = requests.request("POST", url, headers=headers, data=payload)
|
response = requests.request("POST", url, headers=headers, data=payload)
|
||||||
if "Added successfully" in response.text:
|
return "Added successfully" in response.text
|
||||||
return True
|
|
||||||
else:
|
|
||||||
return False
|
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']
|
||||||
|
@ -34,7 +34,7 @@
|
|||||||
<div class="container mt-5">
|
<div class="container mt-5">
|
||||||
<h1>Welcome {{ username }}!</h1>
|
<h1>Welcome {{ username }}!</h1>
|
||||||
<br>
|
<br>
|
||||||
<h2>You have {{ accounts|length }} active accounts</h2>
|
<h2>You have {{ accounts }} active accounts</h2>
|
||||||
<br>
|
<br>
|
||||||
|
|
||||||
{% if current_month_accounts %}
|
{% if current_month_accounts %}
|
||||||
|
@ -45,7 +45,7 @@
|
|||||||
<table class="table table-striped" id="accountsTable">
|
<table class="table table-striped" id="accountsTable">
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
<th>#</th>
|
<!-- <th>#</th> -->
|
||||||
<th>Username</th>
|
<th>Username</th>
|
||||||
<th>Stream</th>
|
<th>Stream</th>
|
||||||
<th>Stream URL</th>
|
<th>Stream URL</th>
|
||||||
@ -57,7 +57,7 @@
|
|||||||
<tbody>
|
<tbody>
|
||||||
{% for account in user_accounts %}
|
{% for account in user_accounts %}
|
||||||
<tr>
|
<tr>
|
||||||
<td>{{ loop.index }}</td>
|
<!-- <td>{{ loop.index }}</td> -->
|
||||||
<td>{{ account.username }}</td>
|
<td>{{ account.username }}</td>
|
||||||
<td>{{ account.stream }}</td>
|
<td>{{ account.stream }}</td>
|
||||||
<td><a href="{{ account.streamURL }}" target="_blank">{{ account.streamURL }}</a></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
|
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({
|
$('#accountsTable').DataTable({
|
||||||
"searching": true,
|
"searching": true,
|
||||||
"ordering": true,
|
"ordering": true,
|
||||||
"responsive": true,
|
"responsive": true,
|
||||||
|
"order": [[3, 'asc']], // Default order by Expiry Date column in ascending order
|
||||||
"columnDefs": [
|
"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>
|
</script>
|
||||||
|
|
||||||
|
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user