diff --git a/server/api.py b/server/api.py index 71d226ba..2ed27e37 100755 --- a/server/api.py +++ b/server/api.py @@ -18,9 +18,9 @@ from const import ( sql_language_strings, sql_notifications_all, sql_online_history, - sql_devices_tiles, sql_devices_filters, ) +from db.db_helper import get_sql_devices_tiles from logger import mylog from helper import write_file, get_setting_value from utils.datetime_utils import timeNowUTC @@ -67,7 +67,7 @@ def update_api( ["plugins_language_strings", sql_language_strings], ["notifications", sql_notifications_all], ["online_history", sql_online_history], - ["devices_tiles", sql_devices_tiles], + ["devices_tiles", get_sql_devices_tiles()], ["devices_filters", sql_devices_filters], ["custom_endpoint", conf.API_CUSTOM_SQL], ] diff --git a/server/const.py b/server/const.py index 135102ec..e07eda06 100755 --- a/server/const.py +++ b/server/const.py @@ -68,41 +68,6 @@ sql_devices_all = """ """ sql_appevents = """select * from AppEvents order by dateTimeCreated desc""" -# The below query calculates counts of devices in various categories: -# (connected/online, offline, down, new, archived), -# as well as a combined count for devices that match any status listed in the UI_MY_DEVICES setting -sql_devices_tiles = """ - WITH Statuses AS ( - SELECT setValue - FROM Settings - WHERE setKey = 'UI_MY_DEVICES' - ), - MyDevicesFilter AS ( - SELECT - -- Build a dynamic filter for devices matching any status in UI_MY_DEVICES - devPresentLastScan, devAlertDown, devIsNew, devIsArchived - FROM Devices - WHERE - (instr((SELECT setValue FROM Statuses), 'online') > 0 AND devPresentLastScan = 1) OR - (instr((SELECT setValue FROM Statuses), 'offline') > 0 AND devPresentLastScan = 0 AND devIsArchived = 0) OR - (instr((SELECT setValue FROM Statuses), 'down') > 0 AND devPresentLastScan = 0 AND devAlertDown = 1) OR - (instr((SELECT setValue FROM Statuses), 'new') > 0 AND devIsNew = 1) OR - (instr((SELECT setValue FROM Statuses), 'archived') > 0 AND devIsArchived = 1) - ) - SELECT - -- Counts for each individual status - (SELECT COUNT(*) FROM Devices WHERE devPresentLastScan = 1) AS connected, - (SELECT COUNT(*) FROM Devices WHERE devPresentLastScan = 0) AS offline, - (SELECT COUNT(*) FROM Devices WHERE devPresentLastScan = 0 AND devAlertDown = 1) AS down, - (SELECT COUNT(*) FROM Devices WHERE devIsNew = 1) AS new, - (SELECT COUNT(*) FROM Devices WHERE devIsArchived = 1) AS archived, - (SELECT COUNT(*) FROM Devices WHERE devFavorite = 1) AS favorites, - (SELECT COUNT(*) FROM Devices) AS "all", - (SELECT COUNT(*) FROM Devices) AS "all_devices", - -- My Devices count - (SELECT COUNT(*) FROM MyDevicesFilter) AS my_devices - FROM Statuses; - """ sql_devices_filters = """ SELECT DISTINCT 'devSite' AS columnName, devSite AS columnValue FROM Devices WHERE devSite NOT IN ('', 'null') AND devSite IS NOT NULL diff --git a/server/db/db_helper.py b/server/db/db_helper.py index a962ef2d..c828de00 100755 --- a/server/db/db_helper.py +++ b/server/db/db_helper.py @@ -66,6 +66,55 @@ def get_device_condition_by_status(device_status): return get_device_conditions().get(device_status, "WHERE 1=0") +# ------------------------------------------------------------------------------- +def get_sql_devices_tiles(): + """Build the device tiles count SQL using get_device_conditions() to avoid duplicating filter logic.""" + conds = get_device_conditions() + + def f(key): + """Strip 'WHERE ' prefix for use inside SELECT subqueries.""" + return conds[key][len("WHERE "):] + + # UI_MY_DEVICES setting values mapped to their device_conditions keys + my_devices_setting_map = [ + ("online", "connected"), + ("offline", "offline"), + ("down", "down"), + ("new", "new"), + ("archived", "archived"), + ] + + my_devices_clauses = "\n OR ".join( + f"(instr((SELECT setValue FROM Statuses), '{sk}') > 0 AND {f(ck)})" + for sk, ck in my_devices_setting_map + ) + + return f""" + WITH Statuses AS ( + SELECT setValue + FROM Settings + WHERE setKey = 'UI_MY_DEVICES' + ), + MyDevicesFilter AS ( + SELECT devMac + FROM Devices + WHERE + {my_devices_clauses} + ) + SELECT + (SELECT COUNT(*) FROM Devices WHERE {f('connected')}) AS connected, + (SELECT COUNT(*) FROM Devices WHERE {f('offline')}) AS offline, + (SELECT COUNT(*) FROM Devices WHERE {f('down')}) AS down, + (SELECT COUNT(*) FROM Devices WHERE {f('new')}) AS new, + (SELECT COUNT(*) FROM Devices WHERE {f('archived')}) AS archived, + (SELECT COUNT(*) FROM Devices WHERE {f('favorites')}) AS favorites, + (SELECT COUNT(*) FROM Devices WHERE {f('all')}) AS "all", + (SELECT COUNT(*) FROM Devices) AS "all_devices", + (SELECT COUNT(*) FROM MyDevicesFilter) AS my_devices + FROM Statuses; + """ + + # ------------------------------------------------------------------------------- # Creates a JSON-like dictionary from a database row def row_to_json(names, row):