Many Changes

This commit is contained in:
sebastian.serfling
2025-03-05 10:33:58 +00:00
parent 8d5e367d23
commit bf95494ab3
17 changed files with 445 additions and 97 deletions
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
+43 -15
View File
@@ -8,7 +8,7 @@ from dotenv import load_dotenv
load_dotenv()
def get_filtered_server(customer_id, service_id, service_status):
def get_filtered_server(customer_ids, service_id, service_status, os_type, reporting):
mydb = mysql.connector.connect(
host=os.getenv("MYSQL_HOST"),
user=os.getenv("MYSQL_USER"),
@@ -18,23 +18,30 @@ def get_filtered_server(customer_id, service_id, service_status):
# Prepare the base query
query = f"""
select s.hostname,s.privat_ipaddress,s.public_ipaddress, s.ram, s.createdate, s.disabledate,s.customer_ID,s.server_ID,hc.name,hc.core
select s.hostname, s.privat_ipaddress, s.public_ipaddress, s.ram, s.createdate, s.disabledate, s.os, s.customer_ID, s.server_ID, hc.name, hc.core
from Kunden.server s
join Kunden.`hardware.cpu` hc ON hc.cpu_ID = s.cpu_ID
WHERE 1=1
"""
if customer_id:
query += f"AND s.customer_ID = {customer_id}"
# If multiple customers are selected, use the IN clause
if customer_ids:
customer_ids_str = ', '.join([str(id) for id in customer_ids])
query += f" AND s.customer_ID IN ({customer_ids_str})"
if service_id:
query += f" AND s.service_ID = {service_id}"
if service_status:
query += f" AND s.status = {service_status}"
if os_type:
query += f" AND s.os = '{os_type}'"
if reporting == "True":
query += f" AND licensekey IS NOT NULL"
users = pd.read_sql_query(query, mydb)
mydb.close()
return users
def get_initial_data():
mydb = mysql.connector.connect(
host=os.getenv("MYSQL_HOST"),
@@ -60,7 +67,6 @@ def get_initial_data():
mydb.close()
return service_ids, customers
def server_filter():
st.title("Server Filter :mag_right:")
# Get initial data for widgets
@@ -68,15 +74,17 @@ def server_filter():
# Combine service_ID and name for display
service_options = initial_service_ids.apply(lambda row: f"{row['service_ID']} - {row['name']}", axis=1)
# Add selection widget for customer ID
selected_customer = st.selectbox(
'Select Customer',
["All"] + customers.apply(lambda row: f"{row['customer_ID']} - {row['companyname']} - {row['customer']}",
axis=1).tolist()
# Create a dictionary for customer selection
customer_dict = {f"{row['companyname']} - {row['customer']}": row['customer_ID'] for _, row in customers.iterrows()}
# Use multiselect for multiple customer selection
selected_customers = st.multiselect(
'Select Customer(s)',
list(customer_dict.keys()) # Display only companyname and customer
)
# Extract customer_ID from selected option
selected_customer_id = None if selected_customer == "All" else int(selected_customer.split(' - ')[0])
# Get the corresponding customer IDs
selected_customer_ids = [customer_dict[customer] for customer in selected_customers]
# Add selection widget for service ID
selected_service = st.selectbox(
@@ -96,13 +104,33 @@ def server_filter():
# Extract status from selected option
service_status = None if selected_status == "All" else int(selected_status.split(' - ')[0])
# Add SPLA server selection
reporting_box = st.selectbox(
'Select SPLA Server',
["Nein", "Ja"]
)
# Extract reporting status
reporting = None if reporting_box == "Nein" else "True"
# Add OS type selection
os_box = st.selectbox(
'Select OS Type',
["All", "Linux", "Windows"]
)
# Extract OS type
os_type = None if os_box == "All" else os_box
# Add a button to apply filters
if st.button('Apply Filters'):
# Fetch filtered data from the database
filtered_data = get_filtered_server(selected_customer_id, selected_service_id, service_status)
filtered_data = get_filtered_server(selected_customer_ids, selected_service_id, service_status, os_type, reporting)
# Display the filtered data
if not filtered_data.empty:
st.dataframe(filtered_data)
st.text(f"CPU SUMME = {sum(filtered_data['core'])}" )
st.text(f"Berechung der Core-Pakete: Anzahl der Cores({filtered_data['core'].count()}) * Core-Pakete aus SPLA (8) / 2")
st.text(f"Reporting Core-Pakete = {(filtered_data['core'].count())*8/2}".split('.')[0])
else:
st.write("No data available for the selected filters.")
+229 -32
View File
@@ -4,11 +4,14 @@ import mysql.connector
from datetime import datetime, date
import os
from dotenv import load_dotenv
import altair as alt
load_dotenv()
def get_filtered_data(customer_id, service_id, start_date, end_date):
"""
Fetches the user count data grouped by month within the specified date range.
"""
mydb = mysql.connector.connect(
host=os.getenv("MYSQL_HOST"),
user=os.getenv("MYSQL_USER"),
@@ -16,9 +19,8 @@ def get_filtered_data(customer_id, service_id, start_date, end_date):
database=os.getenv("MYSQL_DATABASE")
)
# Prepare the query
query = f"""
SELECT DATE_FORMAT(sr.reportingdate, '%Y-%m') AS month,
SELECT DATE_FORMAT(sr.reportingdate, '%Y-%m') AS day,
COUNT(DISTINCT sr.username) as count
FROM Kunden.`services.reporting` sr
JOIN Kunden.services s ON sr.service_ID = s.service_ID
@@ -36,6 +38,163 @@ def get_filtered_data(customer_id, service_id, start_date, end_date):
return service_reporting
def get_user_online(customer_id,service_id,start_date,end_date):
mydb = mysql.connector.connect(
host=os.getenv("MYSQL_HOST"),
user=os.getenv("MYSQL_USER"),
password=os.getenv("MYSQL_PASSWORD"),
database=os.getenv("MYSQL_DATABASE")
)
if service_id == 100:
user_info = "u.primarymail as username"
else:
user_info = "u.username"
query = f"""
SELECT DATE_FORMAT(sr.reportingdate, '%Y-%m') AS day,
sr.username
FROM Kunden.`services.reporting` sr
JOIN Kunden.services s ON sr.service_ID = s.service_ID
WHERE sr.customer_ID = {customer_id}
AND sr.service_ID = {service_id}
AND sr.username NOT LIKE '%admin%'
AND sr.username NOT LIKE '%test%'
AND sr.reportingdate BETWEEN '{start_date}' AND '{end_date}'
GROUP BY day, sr.username
ORDER BY sr.username;
"""
user_online = pd.read_sql_query(query, mydb)
user_online_count= user_online.shape[0]
mydb.close()
return user_online, user_online_count
def get_max_user_count(customer_id, service_id, start_date, end_date):
"""
Fetches the maximum user count within the specified date range.
"""
mydb = mysql.connector.connect(
host=os.getenv("MYSQL_HOST"),
user=os.getenv("MYSQL_USER"),
password=os.getenv("MYSQL_PASSWORD"),
database=os.getenv("MYSQL_DATABASE")
)
query = f"""
SELECT MAX(user_counts.count) as max_count
FROM (
SELECT DATE_FORMAT(sr.reportingdate, '%Y-%m') AS day,
COUNT(DISTINCT sr.username) as count
FROM Kunden.`services.reporting` sr
JOIN Kunden.services s ON sr.service_ID = s.service_ID
WHERE sr.customer_ID = {customer_id}
AND sr.service_ID = {service_id}
AND sr.username NOT LIKE '%admin%'
AND sr.username NOT LIKE '%test%'
AND sr.reportingdate BETWEEN '{start_date}' AND '{end_date}'
GROUP BY DATE_FORMAT(sr.reportingdate, '%Y-%m')
) as user_counts;
"""
max_user_count = pd.read_sql_query(query, mydb)
mydb.close()
return max_user_count.iloc[0]['max_count'] if not max_user_count.empty else 0
def get_active_users(customer_id, service_id, start_date, end_date):
"""
Fetch all active users for the given customer, service, and date range
based on the most recent activity and status.
"""
mydb = mysql.connector.connect(
host=os.getenv("MYSQL_HOST"),
user=os.getenv("MYSQL_USER"),
password=os.getenv("MYSQL_PASSWORD"),
database=os.getenv("MYSQL_DATABASE")
)
if service_id == 100:
user_info = "u.primarymail as username"
else:
user_info = "u.username"
query = f"""
SELECT
{user_info}
FROM Kunden.`users` u
JOIN (
SELECT
us.user_id,
us.`timestamp` AS last_active_timestamp,
us.status
FROM Kunden.`users.services` us
JOIN (
SELECT
user_id,
MAX(`timestamp`) AS last_active_timestamp
FROM Kunden.`users.services`
WHERE `timestamp` <= '{end_date}'
AND customer_id = {customer_id}
AND service_ID = {service_id}
AND user_id NOT IN (
SELECT user_id
FROM Kunden.`users.status`
WHERE status = 0
AND `timestamp` < '{start_date}'
AND customer_id = {customer_id}
)
GROUP BY user_id
) max_timestamps ON us.user_id = max_timestamps.user_id
AND us.`timestamp` = max_timestamps.last_active_timestamp
WHERE us.customer_id = {customer_id}
AND us.service_ID = {service_id}
AND us.status = 1
) active_users ON u.user_id = active_users.user_id
GROUP BY u.user_id, u.username, active_users.last_active_timestamp, active_users.status ORDER by u.username ASC;
"""
active_users = pd.read_sql_query(query, mydb)
user_active_count = active_users.shape[0]
mydb.close()
return active_users, user_active_count
def get_user_not_online(customer_id,service_id,start_date,end_date):
mydb = mysql.connector.connect(
host=os.getenv("MYSQL_HOST"),
user=os.getenv("MYSQL_USER"),
password=os.getenv("MYSQL_PASSWORD"),
database=os.getenv("MYSQL_DATABASE")
)
query = f"""
SELECT u.username, ss.service_ID
FROM Kunden.users u
JOIN Kunden.`users.services` ss ON ss.user_ID = u.user_ID
JOIN (
SELECT user_id,
MAX(CASE WHEN status = 1 THEN timestamp END) AS latest_active_timestamp,
MAX(CASE WHEN status = 0 THEN timestamp END) AS latest_inactive_timestamp
FROM Kunden.`users.status`
GROUP BY user_id
) us ON u.user_ID = us.user_id
WHERE ss.service_ID = {service_id}
AND (
(us.latest_active_timestamp IS NOT NULL AND
(us.latest_inactive_timestamp IS NULL OR us.latest_active_timestamp > us.latest_inactive_timestamp))
OR us.latest_inactive_timestamp IS NULL
)
AND u.username NOT IN (
SELECT sr.username
FROM Kunden.`services.reporting` sr
WHERE sr.service_ID = {service_id}
AND sr.reportingdate BETWEEN '{start_date}' AND '{end_date}'
)
AND u.user_ID != 95
AND u.user_ID != 102
AND u.customer_ID = {customer_id}
AND u.username NOT LIKE "%ad-test-user%"
"""
not_active_users = pd.read_sql_query(query, mydb)
user_not_online_count = not_active_users.shape[0]
mydb.close()
return not_active_users, user_not_online_count
def get_initial_data():
mydb = mysql.connector.connect(
host=os.getenv("MYSQL_HOST"),
@@ -43,6 +202,7 @@ def get_initial_data():
password=os.getenv("MYSQL_PASSWORD"),
database=os.getenv("MYSQL_DATABASE")
)
# Fetch unique service IDs and names
service_id_query = """
SELECT DISTINCT s.service_ID, s.name
@@ -71,61 +231,98 @@ def get_initial_data():
return service_ids, customers, date_range
def generate_month_range(min_date, max_date):
months = pd.date_range(start=min_date, end=max_date, freq='MS').strftime("%Y-%m").tolist()
return months
def services_reporting():
st.title("Reporting :mag_right:")
# Get initial data for widgets
initial_service_ids, customers, initial_date_range = get_initial_data()
# Combine service_ID and name for display
service_options = initial_service_ids.apply(lambda row: f"{row['service_ID']} - {row['name']}", axis=1)
# Add selection widget for customer ID
# Selection widget for customer ID
customer_dict = {f"{row['companyname']} - {row['customer']}": row['customer_ID'] for _, row in customers.iterrows()}
# Selectbox with only the customer name and company displayed
selected_customer = st.selectbox(
'Select Customer',
customers.apply(lambda row: f"{row['customer_ID']} - {row['companyname']} - {row['customer']}", axis=1).tolist()
list(customer_dict.keys()) # Display only companyname and customer
)
# Extract customer_ID from selected option
selected_customer_id = int(selected_customer.split(' - ')[0])
# Get the corresponding customer ID
selected_customer_id = customer_dict[selected_customer]
# Add selection widget for service ID
# Selection widget for service ID
selected_service = st.selectbox(
'Select Service',
service_options.tolist()
)
# Extract service_ID from selected option
selected_service_id = int(selected_service.split(' - ')[0])
# Convert date range to datetime objects
min_date = initial_date_range['min_date'][0]
max_date = initial_date_range['max_date'][0]
# Generate month options for dropdown
month_options = generate_month_range(min_date, max_date)
# Date input for start and end date
start_date = st.date_input('Start Date', min_date)
end_date = st.date_input('End Date', max_date)
# Add dropdown for start and end months
start_month = st.selectbox('Start Month', month_options)
end_month = st.selectbox('End Month', month_options, index=len(month_options) - 1)
# Convert 'YYYY-MM' to 'YYYY-MM-DD' format for SQL query
start_date = datetime.strptime(start_month, '%Y-%m').date().replace(day=1)
end_date = datetime.strptime(end_month, '%Y-%m').date().replace(day=1)
end_date = (end_date.replace(day=28) + pd.DateOffset(days=4)).replace(day=1) - pd.DateOffset(days=1) # last day of the month
# Add a button to apply filters
if st.button('Apply Filters'):
# Fetch filtered data from the database
filtered_data = get_filtered_data(selected_customer_id, selected_service_id, start_date, end_date)
# Sort the data by month
filtered_data = filtered_data.sort_values('month')
# Fetch max user count in the selected range
max_count = get_max_user_count(selected_customer_id, selected_service_id, start_date, end_date)
# Sort the data by day
filtered_data = filtered_data.sort_values('day')
# Create a bar chart with the filtered data
if not filtered_data.empty:
st.bar_chart(filtered_data.set_index('month')['count'])
# Highlight the max value in the chart
filtered_data['color'] = filtered_data['count'].apply(lambda x: 'red' if x == max_count else 'steelblue')
# Create an Altair bar chart
bars = alt.Chart(filtered_data).mark_bar().encode(
x='day:O',
y='count:Q',
color=alt.Color('color:N', scale=None, legend=None)
)
# Add text labels to bars
text = bars.mark_text(
align='center',
baseline='middle',
dy=-10
).encode(
text='count:Q'
)
# Combine bars and text into a single chart
chart = (bars + text).properties(
title='Daily Service Usage with Highlighted Maximum'
)
# Fetch the data for users not online, online, and active users
not_user_online, max_count_user_not_online = get_user_not_online(selected_customer_id, selected_service_id, start_date, end_date)
user_online, user_online_count = get_user_online(selected_customer_id, selected_service_id, start_date, end_date)
active_users_data, user_active_count = get_active_users(selected_customer_id, selected_service_id, start_date, end_date)
# Create three columns for each DataFrame
col1, col2, col3, col4, col5 = st.columns([2,2,2,2,2])
# Display each DataFrame in a separate column
with col4:
st.subheader(f"{selected_service.split(' - ')[1]} - User not Online")
st.metric(label="1",label_visibility="hidden", value=max_count_user_not_online)
st.data_editor(not_user_online['username'],use_container_width=True, hide_index=True)
with col2:
st.subheader(f"{selected_service.split(' - ')[1]} - User Online")
st.metric(label="1",label_visibility="hidden", value=user_online_count)
st.data_editor(user_online['username'],use_container_width=True, hide_index=True)
with col3:
st.subheader(f"{selected_service.split(' - ')[1]} - Active Users")
st.metric(label="1",label_visibility="hidden", value=user_active_count)
st.data_editor(active_users_data['username'],key=active_users_data,use_container_width=True, hide_index=True)
st.altair_chart(chart, use_container_width=True)
else:
st.write("No data available for the selected filters.")
st.write("No data available for the selected filters.")
+2 -2
View File
@@ -20,7 +20,7 @@ def get_filtered_users(customer_id, start_date, end_date):
# Prepare the base query with date filter
query = f"""
SELECT number, title, createdate, time FROM Kunden.tickets
WHERE createdate BETWEEN '{start_date}' AND '{end_date}'
WHERE closedate BETWEEN '{start_date}' AND '{end_date}'
"""
if customer_id:
query += f" AND customer_ID = {customer_id}"
@@ -149,4 +149,4 @@ def ticket_filter():
st.write("No data available for the selected filters.")
if __name__ == "__main__":
ticket_filter()
ticket_filter()