-
-
Notifications
You must be signed in to change notification settings - Fork 365
Next release #1271
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Next release #1271
Conversation
Signed-off-by: jokob-sk <jokob.sk@gmail.com>
Signed-off-by: jokob-sk <jokob.sk@gmail.com>
|
Important Review skippedMore than 25% of the files skipped due to max files limit. The review is being skipped to prevent a low-quality review. 69 files out of 239 files are above the max files limit of 100. Please upgrade to Pro plan to get higher limits. You can disable this status message by setting the WalkthroughThis PR centralizes datetime utilities into Changes
Sequence Diagram(s)sequenceDiagram
participant App as Application
participant Utils as utils.datetime_utils
participant Plugin as Plugin
participant DB as Database
App->>Utils: timeNowDB()
Utils-->>App: DB-safe timestamp (string)
Plugin->>Utils: timeNowDB() for secondaryId/state
Utils-->>Plugin: timestamp
Plugin->>DB: persist entries with timestamp
DB-->>Plugin: ack
sequenceDiagram
participant Client as API Client
participant Server as API Server
participant Endpoint as logs_endpoint.py
participant Queue as UserEventsQueue
participant File as execution_queue.log
participant Utils as utils.datetime_utils
Client->>Server: POST /logs/add-to-execution-queue {action}
Server->>Endpoint: api_add_to_execution_queue()
Endpoint->>Queue: add_event(action)
Queue->>Utils: timeNowDB()
Utils-->>Queue: timestamp
Queue->>Queue: generate uuid
Queue->>File: write "[timestamp]|[uuid]|[action]\n"
File-->>Queue: success
Queue-->>Endpoint: (True, msg)
Endpoint-->>Client: 200 {success: true, message: msg}
sequenceDiagram
participant Client as GraphQL Client
participant Server as GraphQL Server
participant Res as graphql_endpoint.py
participant Cache as In-Memory Cache
participant FS as File System
Client->>Server: Query langStrings(langCode?, langStringKey?)
Server->>Res: resolve_langStrings(...)
Res->>Cache: check core/plugin cache
alt cache hit
Cache-->>Res: return cached
else
Res->>FS: read core lang JSONs
FS-->>Res: core data
Res->>FS: read plugin lang JSON
FS-->>Res: plugin data
Res->>Cache: store merged results
end
Res->>Res: apply filters + fallback
Res-->>Server: LangStringResult {langStrings, count}
Server-->>Client: response
Estimated code review effort🎯 4 (Complex) | ⏱️ ~50 minutes Areas requiring extra attention:
Possibly related PRs
Poem
Pre-merge checks and finishing touches❌ Failed checks (1 warning, 1 inconclusive)
✅ Passed checks (1 passed)
Comment |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 3
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (9)
front/plugins/arp_scan/script.py(0 hunks)front/plugins/dhcp_servers/script.py(1 hunks)front/plugins/nmap_scan/script.py(0 hunks)front/plugins/plugin_helper.py(1 hunks)server/api_server/device_endpoint.py(4 hunks)server/app_state.py(2 hunks)server/helper.py(0 hunks)server/plugin.py(5 hunks)server/scan/device_handling.py(4 hunks)
💤 Files with no reviewable changes (3)
- front/plugins/arp_scan/script.py
- server/helper.py
- front/plugins/nmap_scan/script.py
🧰 Additional context used
📓 Path-based instructions (4)
front/plugins/plugin_helper.py
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
Use 'Plugin_Objects' from 'front/plugins/plugin_helper.py' to sanitize text and normalize MAC addresses before writing results.
Files:
front/plugins/plugin_helper.py
**/*.py
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
Use 'logger.mylog' for logging at levels: none, minimal, verbose, debug, or trace.
Files:
front/plugins/plugin_helper.pyserver/scan/device_handling.pyserver/api_server/device_endpoint.pyserver/app_state.pyfront/plugins/dhcp_servers/script.pyserver/plugin.py
server/api_server/*.py
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
When introducing new server functionality, add endpoints only within 'server/api_server/*' and keep authorization checks consistent.
Files:
server/api_server/device_endpoint.py
front/plugins/*/script.py
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
front/plugins/*/script.py: Run plugin scripts as standalone executables with 'sys.path' configured for '/app/front/plugins' and '/app/server', following the provided template.
During plugin processing, collect results with 'Plugin_Objects.add_object(...)' and call 'plugin_objects.write_result_file()' exactly once at the end of the script.
Do not write ad-hoc files for plugin results; only generate 'last_result..log' using 'Plugin_Objects'.
Log a concise summary (such as the total number of objects added) at info level before writing the plugin result file; use verbose/debug for extra context.
Files:
front/plugins/dhcp_servers/script.py
🧠 Learnings (5)
📚 Learning: 2025-10-21T01:40:24.597Z
Learnt from: CR
Repo: jokob-sk/NetAlertX PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-10-21T01:40:24.597Z
Learning: Applies to front/plugins/plugin_helper.py : Use 'Plugin_Objects' from 'front/plugins/plugin_helper.py' to sanitize text and normalize MAC addresses before writing results.
Applied to files:
front/plugins/plugin_helper.py
📚 Learning: 2025-10-21T01:40:24.597Z
Learnt from: CR
Repo: jokob-sk/NetAlertX PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-10-21T01:40:24.597Z
Learning: Applies to server/helper.py : Use 'helper.py' ('timeNowTZ', 'normalize_mac', and sanitizers) for all time, MAC, and string operations; always validate MACs before database writes.
Applied to files:
server/api_server/device_endpoint.py
📚 Learning: 2025-11-02T02:22:10.949Z
Learnt from: jokob-sk
Repo: jokob-sk/NetAlertX PR: 1261
File: server/app_state.py:106-115
Timestamp: 2025-11-02T02:22:10.949Z
Learning: In server/app_state.py, the pluginsStates parameter always contains complete plugin state objects with the structure: {"PLUGIN_NAME": {"lastChanged": "...", "totalObjects": N, "newObjects": N, "changedObjects": N}}. Type validation before calling .update() is not needed as the maintainer guarantees well-formed objects are always supplied.
Applied to files:
server/app_state.pyserver/plugin.py
📚 Learning: 2025-10-19T15:29:46.423Z
Learnt from: adamoutler
Repo: jokob-sk/NetAlertX PR: 1230
File: front/plugins/dhcp_servers/script.py:44-44
Timestamp: 2025-10-19T15:29:46.423Z
Learning: In the NetAlertX dhcp_servers plugin (front/plugins/dhcp_servers/script.py), the nmap command uses both 'sudo' and '--privileged' flag to maintain cross-platform compatibility. While the hardened Docker image stubs sudo and uses capabilities, hardware installations (Debian 12, Ubuntu 24) and the Debian Dockerfile require sudo for raw socket access. This approach ensures the plugin works across all deployment targets.
Applied to files:
front/plugins/dhcp_servers/script.py
📚 Learning: 2025-10-21T01:40:24.597Z
Learnt from: CR
Repo: jokob-sk/NetAlertX PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-10-21T01:40:24.597Z
Learning: Applies to front/plugins/*/script.py : Log a concise summary (such as the total number of objects added) at info level before writing the plugin result file; use verbose/debug for extra context.
Applied to files:
server/plugin.py
🧬 Code graph analysis (4)
server/scan/device_handling.py (1)
server/helper.py (1)
timeNowTZ(35-45)
server/api_server/device_endpoint.py (1)
server/helper.py (5)
is_random_mac(632-647)is_random_mac(675-686)format_date(101-103)get_setting_value(326-379)timeNowTZ(35-45)
server/app_state.py (1)
server/helper.py (1)
timeNowTZ(35-45)
server/plugin.py (1)
server/helper.py (1)
timeNowTZ(35-45)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
- GitHub Check: docker_dev
🔇 Additional comments (2)
server/scan/device_handling.py (2)
6-6: LGTM!The
datetimeimport is needed for the type checking on line 544.
59-59: LGTM!The ISO 8601 timestamp format is appropriate for database storage and aligns with the PR's standardization goal.
server/scan/device_handling.py
Outdated
| sql.execute("SELECT CURRENT_TIMESTAMP") | ||
| row = sql.fetchone() | ||
| pm.name_plugins_checked = row[0] if row else None | ||
| pm.name_plugins_checked = timeNowTZ() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ensure timezone consistency for datetime comparisons.
Line 653 uses timeNowTZ() which returns a naive datetime when conf.tz is not set, but line 59 uses timeNowTZ().astimezone().isoformat() for database storage. For the comparison on line 552 to work correctly without TypeError, both last_checked and latest_state must be consistently either timezone-aware or naive.
Apply this diff to ensure timezone-aware datetime:
- pm.name_plugins_checked = timeNowTZ()
+ pm.name_plugins_checked = timeNowTZ().astimezone()This ensures last_checked is always timezone-aware, matching the behavior of parsed ISO timestamps from plugin states.
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| pm.name_plugins_checked = timeNowTZ() | |
| pm.name_plugins_checked = timeNowTZ().astimezone() |
🤖 Prompt for AI Agents
In server/scan/device_handling.py around line 653, pm.name_plugins_checked is
being set with timeNowTZ() which can return a naive datetime; update this
assignment to ensure the value is timezone-aware (e.g., call
timeNowTZ().astimezone()) so it matches the ISO-parsed plugin state timestamps
and avoids TypeError during comparisons.
Signed-off-by: jokob-sk <jokob.sk@gmail.com>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
🧹 Nitpick comments (1)
server/api_server/device_endpoint.py (1)
190-191: Consider consolidating the timestamp computation.Both lines call
timeNowTZ().astimezone().isoformat()separately, which could result in slightly different timestamps. Consider computing once at the function start and reusing it.Apply this diff:
def set_device_data(mac, data): """Update or create a device.""" + now = timeNowTZ().astimezone().isoformat() if data.get("createNew", False): sql = """ INSERT INTO Devices ( @@ -187,8 +188,8 @@ data.get("devSkipRepeated", 0), data.get("devIsNew", 0), data.get("devIsArchived", 0), - data.get("devLastConnection", timeNowTZ().astimezone().isoformat()), - data.get("devFirstConnection", timeNowTZ().astimezone().isoformat()), + data.get("devLastConnection", now), + data.get("devFirstConnection", now), data.get("devLastIP", ""),
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (4)
server/api_server/device_endpoint.py(4 hunks)server/helper.py(1 hunks)server/scan/device_handling.py(4 hunks)test/test_dbquery_endpoints.py(1 hunks)
🧰 Additional context used
📓 Path-based instructions (4)
**/*.py
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
Use 'logger.mylog' for logging at levels: none, minimal, verbose, debug, or trace.
Files:
test/test_dbquery_endpoints.pyserver/api_server/device_endpoint.pyserver/helper.pyserver/scan/device_handling.py
test/**/*.py
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
Tests must reside under 'test/' and use pytest.
Files:
test/test_dbquery_endpoints.py
server/api_server/*.py
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
When introducing new server functionality, add endpoints only within 'server/api_server/*' and keep authorization checks consistent.
Files:
server/api_server/device_endpoint.py
server/helper.py
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
Use 'helper.py' ('timeNowTZ', 'normalize_mac', and sanitizers) for all time, MAC, and string operations; always validate MACs before database writes.
Files:
server/helper.py
🧠 Learnings (1)
📚 Learning: 2025-10-21T01:40:24.597Z
Learnt from: CR
Repo: jokob-sk/NetAlertX PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-10-21T01:40:24.597Z
Learning: Applies to server/helper.py : Use 'helper.py' ('timeNowTZ', 'normalize_mac', and sanitizers) for all time, MAC, and string operations; always validate MACs before database writes.
Applied to files:
server/api_server/device_endpoint.pyserver/helper.py
🧬 Code graph analysis (4)
test/test_dbquery_endpoints.py (1)
server/helper.py (1)
timeNowTZ(35-45)
server/api_server/device_endpoint.py (1)
server/helper.py (1)
timeNowTZ(35-45)
server/helper.py (1)
front/js/common.js (1)
tz(375-375)
server/scan/device_handling.py (2)
server/helper.py (1)
timeNowTZ(35-45)server/logger.py (2)
timeNowTZ(16-20)mylog(86-92)
🪛 Ruff (0.14.3)
server/helper.py
109-109: Do not catch blind exception: Exception
(BLE001)
server/scan/device_handling.py
550-550: Do not catch blind exception: Exception
(BLE001)
558-558: Do not catch blind exception: Exception
(BLE001)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
- GitHub Check: docker_dev
🔇 Additional comments (7)
server/api_server/device_endpoint.py (1)
31-31: LGTM! Past issue resolved.Hoisting
nowbefore the conditional ensures it's defined for all code paths, addressing theUnboundLocalErrorflagged in previous reviews.test/test_dbquery_endpoints.py (1)
43-48: LGTM! Consistent timestamp usage.Good practice to compute the timestamp once and reuse it for both
devFirstConnectionanddevLastConnectionfields, ensuring consistency.server/scan/device_handling.py (2)
545-561: Timestamp normalization logic is sound.The code properly normalizes plugin state timestamps to
datetimeobjects before comparison, addressing the type-mixing concerns from previous reviews. The broadExceptioncatches (flagged by static analysis) are acceptable here since they handle unpredictable external data formats and include proper logging for debugging.
59-59: LGTM! ISO 8601 standardization.The change to
timeNowTZ().astimezone().isoformat()aligns with the PR's goal of standardizing timestamps across the codebase.server/helper.py (3)
88-99: LGTM! Robust datetime parsing.The two-stage parsing (ISO8601 first, then RFC1123/HTTP) handles the most common timestamp formats gracefully, with appropriate fallback to
Noneon failure.
101-110: Function logic is correct.The timezone assignment for naive datetimes (lines 104-107) properly uses the application timezone from
conf.tz. The broadExceptioncatch (line 109, flagged by static analysis) is acceptable for a user-facing formatting function that needs to handle malformed input gracefully by returning"invalid".
112-153: All callers properly handle the dict return type — no breaking change issues found.The verification confirms all four usages of
format_date_diffinserver/api_server/sessions_endpoint.pyare already accessing the dict keys (["text"],["total_minutes"]) correctly. The breaking change has been fully accommodated across the codebase.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
🧹 Nitpick comments (1)
server/scan/device_handling.py (1)
536-543: Prefer specific exception types over bareException.The logic correctly normalizes
last_checkedto a datetime object. However, catching bareExceptionis overly broad. Theparser.parse()method primarily raisesValueErrorandTypeErroron failure.Apply this diff to catch specific exceptions:
# Normalize last_checked to datetime if it's a string if isinstance(last_checked, str): try: last_checked = parser.parse(last_checked) - except Exception as e: + except (ValueError, TypeError) as e: mylog('none', f'[Update Device Name] Could not parse last_checked timestamp: {last_checked!r} ({e})') last_checked = None elif not isinstance(last_checked, datetime.datetime): last_checked = None
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (1)
server/scan/device_handling.py(4 hunks)
🧰 Additional context used
📓 Path-based instructions (1)
**/*.py
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
Use 'logger.mylog' for logging at levels: none, minimal, verbose, debug, or trace.
Files:
server/scan/device_handling.py
🧬 Code graph analysis (1)
server/scan/device_handling.py (2)
server/helper.py (1)
timeNowTZ(35-45)server/logger.py (2)
timeNowTZ(16-20)mylog(86-92)
🪛 Ruff (0.14.3)
server/scan/device_handling.py
539-539: Do not catch blind exception: Exception
(BLE001)
560-560: Do not catch blind exception: Exception
(BLE001)
568-568: Do not catch blind exception: Exception
(BLE001)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
- GitHub Check: docker_dev
🔇 Additional comments (4)
server/scan/device_handling.py (4)
6-6: LGTM!The
datetimeimport is correctly added to support the type checking operations introduced in theupdate_devices_namesfunction.
59-59: LGTM!The change to ISO 8601 format with
.astimezone().isoformat()correctly standardizes timestamp representation and ensures timezone awareness.
574-574: LGTM!The comparison logic is correct, assuming both
last_checkedandlatest_stateare properly normalized datetime objects (which they will be once the indentation issue in lines 565-570 is resolved).
675-675: LGTM!The timestamp update correctly uses ISO 8601 format with timezone awareness, consistent with the standardization objectives and the change on line 59.
Signed-off-by: jokob-sk <jokob.sk@gmail.com>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 4
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (4)
front/plugins/nmap_dev_scan/nmap_dev.py (3)
50-51: Remove unused database connection.The database connection is opened but never used or closed, resulting in a resource leak.
Apply this diff:
- # Create a database connection - db = DB() # instance of class DB - db.open() -
68-80: Inconsistent and non-standard MAC address handling.The
primaryIduses lowercased MAC (line 72) whileforeignKeyuses the original case (line 79). More importantly,nmap_dev.pyshould follow the established pattern in the codebase: import and usenormalize_mac()fromplugin_helper.py, as done insnmp_discovery/script.py. The current.lower()approach is inconsistent with the codebase standard.Apply this fix:
- Import
normalize_macat the top ofnmap_dev.py:from plugin_helper import Plugin_Object, Plugin_Objects, decodeBase64, normalize_mac
- Update lines 72 and 79 to use
normalize_mac():for device in unique_devices: plugin_objects.add_object( # "MAC", "IP", "Name", "Vendor", "Interface" - primaryId = device['mac'].lower(), + primaryId = normalize_mac(device['mac']), secondaryId = device['ip'], watched1 = device['name'], watched2 = device['vendor'], watched3 = device['interface'], watched4 = '', extra = '', - foreignKey = device['mac']) + foreignKey = normalize_mac(device['mac']))
193-200: Usenormalize_macfromplugin_helper.pyto normalize generated MAC addresses before writing to Plugin_Objects.The generated MAC at line 173 is written directly to Plugin_Objects without normalization. According to project guidelines, all MAC addresses should be normalized before writing results. Apply normalization to the generated MAC:
if mac == '' and fakeMac: mac = normalize_mac(string_to_mac_hash(ip))Add the import if not present:
from plugin_helper import Plugin_Object, Plugin_Objects, decodeBase64, normalize_macfront/plugins/_publisher_mqtt/mqtt.py (1)
558-573: Fix type mismatch: timeNowDB() returns string, not datetime.The fallback path assigns
timeNowDB()toparsed_datetime, buttimeNowDB()returns a string (e.g., '2025-11-04 18:09:11'), while line 573 expects a datetime object to call.isoformat(). This will cause anAttributeError.Apply this diff to fix the type mismatch:
except ValueError: mylog('verbose', [f"[{pluginName}] Timestamp conversion failed of string '{datetime_str}'"]) # Use the current time if the input format is invalid - parsed_datetime = timeNowDB() + parsed_datetime = datetime.now(conf.tz)
🧹 Nitpick comments (5)
front/plugins/ddns_update/script.py (1)
14-14: Remove unused import for consistency.The
datetimeimport is not used anywhere in this file and should be removed, similar to thetimeNowTZcleanup.Apply this diff:
-from datetime import datetimefront/plugins/__test/test.py (1)
9-10: Consider removing unused standard library imports.The
datetimeandtimeimports don't appear to be used in the current code. While this is a development/test plugin where such imports might be kept available for ad-hoc testing, removing them would improve code clarity.Apply this diff if you'd like to clean up:
-from datetime import datetime -import timefront/plugins/nmap_dev_scan/nmap_dev.py (1)
16-16: Remove unused import.The
datetimeimport is not used anywhere in this file.Apply this diff:
-from datetime import datetimeserver/messaging/reporting.py (1)
126-128: Use "debug" log level for SQL query logging.The SQL query is logged at "none" level, meaning it will always appear in logs. This should use "debug" level instead.
Apply this diff:
- mylog("none", sqlQuery) + mylog("debug", sqlQuery)server/scan/device_handling.py (1)
553-560: Narrow the exception handler for better error diagnostics.Line 559 catches bare
Exception, which can mask unexpected errors. Since timestamp parsing typically raisesValueErrororTypeError, narrow the handler to those specific exceptions.Apply this diff:
elif isinstance(state_updated, str): try: state_times.append(parser.parse(state_updated)) - except Exception as e: + except (ValueError, TypeError) as e: mylog('none', f'[Update Device Name] Failed to parse timestamp for {p}: {state_updated!r} ({e})')
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (67)
front/plugins/__template/rename_me.py(1 hunks)front/plugins/__test/test.py(1 hunks)front/plugins/_publisher_apprise/apprise.py(2 hunks)front/plugins/_publisher_email/email_smtp.py(2 hunks)front/plugins/_publisher_mqtt/mqtt.py(2 hunks)front/plugins/_publisher_ntfy/ntfy.py(2 hunks)front/plugins/_publisher_pushover/pushover.py(2 hunks)front/plugins/_publisher_pushsafer/pushsafer.py(2 hunks)front/plugins/_publisher_telegram/tg.py(2 hunks)front/plugins/_publisher_webhook/webhook.py(2 hunks)front/plugins/arp_scan/script.py(1 hunks)front/plugins/csv_backup/script.py(1 hunks)front/plugins/db_cleanup/script.py(1 hunks)front/plugins/ddns_update/script.py(1 hunks)front/plugins/dhcp_leases/script.py(1 hunks)front/plugins/dhcp_servers/script.py(2 hunks)front/plugins/dig_scan/digscan.py(1 hunks)front/plugins/freebox/freebox.py(1 hunks)front/plugins/icmp_scan/icmp.py(1 hunks)front/plugins/internet_ip/script.py(2 hunks)front/plugins/internet_speedtest/script.py(2 hunks)front/plugins/ipneigh/ipneigh.py(1 hunks)front/plugins/luci_import/script.py(1 hunks)front/plugins/maintenance/maintenance.py(1 hunks)front/plugins/nbtscan_scan/nbtscan.py(1 hunks)front/plugins/nmap_dev_scan/nmap_dev.py(1 hunks)front/plugins/nmap_scan/script.py(2 hunks)front/plugins/nslookup_scan/nslookup.py(1 hunks)front/plugins/omada_sdn_imp/omada_sdn.py(1 hunks)front/plugins/plugin_helper.py(2 hunks)front/plugins/snmp_discovery/script.py(1 hunks)front/plugins/sync/sync.py(6 hunks)front/plugins/unifi_api_import/unifi_api_import.py(1 hunks)front/plugins/unifi_import/script.py(1 hunks)front/plugins/vendor_update/script.py(1 hunks)front/plugins/wake_on_lan/wake_on_lan.py(1 hunks)front/plugins/website_monitor/script.py(1 hunks)server/api_server/api_server_start.py(1 hunks)server/api_server/device_endpoint.py(4 hunks)server/api_server/events_endpoint.py(1 hunks)server/api_server/sessions_endpoint.py(1 hunks)server/api_server/sync_endpoint.py(3 hunks)server/app_state.py(3 hunks)server/helper.py(3 hunks)server/initialise.py(3 hunks)server/logger.py(1 hunks)server/messaging/in_app.py(2 hunks)server/messaging/reporting.py(2 hunks)server/models/notification_instance.py(5 hunks)server/plugin.py(10 hunks)server/plugin_utils.py(1 hunks)server/scan/device_handling.py(5 hunks)server/scan/device_heuristics.py(1 hunks)server/scan/session_events.py(3 hunks)server/workflows/actions.py(1 hunks)server/workflows/app_events.py(1 hunks)server/workflows/conditions.py(1 hunks)server/workflows/manager.py(1 hunks)server/workflows/triggers.py(1 hunks)test/test_dbquery_endpoints.py(2 hunks)test/test_device_endpoints.py(1 hunks)test/test_devices_endpoints.py(1 hunks)test/test_graphq_endpoints.py(1 hunks)test/test_history_endpoints.py(1 hunks)test/test_nettools_endpoints.py(1 hunks)test/test_sessions_endpoints.py(6 hunks)test/test_settings_endpoints.py(1 hunks)
✅ Files skipped from review due to trivial changes (7)
- front/plugins/ipneigh/ipneigh.py
- front/plugins/snmp_discovery/script.py
- front/plugins/db_cleanup/script.py
- test/test_devices_endpoints.py
- front/plugins/unifi_api_import/unifi_api_import.py
- server/plugin_utils.py
- front/plugins/website_monitor/script.py
🚧 Files skipped from review as they are similar to previous changes (1)
- front/plugins/dhcp_servers/script.py
🧰 Additional context used
📓 Path-based instructions (8)
front/plugins/*/script.py
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
front/plugins/*/script.py: Run plugin scripts as standalone executables with 'sys.path' configured for '/app/front/plugins' and '/app/server', following the provided template.
During plugin processing, collect results with 'Plugin_Objects.add_object(...)' and call 'plugin_objects.write_result_file()' exactly once at the end of the script.
Do not write ad-hoc files for plugin results; only generate 'last_result..log' using 'Plugin_Objects'.
Log a concise summary (such as the total number of objects added) at info level before writing the plugin result file; use verbose/debug for extra context.
Files:
front/plugins/vendor_update/script.pyfront/plugins/nmap_scan/script.pyfront/plugins/internet_ip/script.pyfront/plugins/dhcp_leases/script.pyfront/plugins/csv_backup/script.pyfront/plugins/internet_speedtest/script.pyfront/plugins/luci_import/script.pyfront/plugins/ddns_update/script.pyfront/plugins/unifi_import/script.pyfront/plugins/arp_scan/script.py
**/*.py
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
Use 'logger.mylog' for logging at levels: none, minimal, verbose, debug, or trace.
Files:
front/plugins/vendor_update/script.pytest/test_nettools_endpoints.pyserver/scan/device_heuristics.pyfront/plugins/icmp_scan/icmp.pyfront/plugins/sync/sync.pyfront/plugins/_publisher_ntfy/ntfy.pyfront/plugins/_publisher_webhook/webhook.pyfront/plugins/nmap_scan/script.pyfront/plugins/plugin_helper.pyserver/workflows/conditions.pyfront/plugins/internet_ip/script.pyserver/api_server/sync_endpoint.pyserver/api_server/events_endpoint.pyfront/plugins/__test/test.pyfront/plugins/_publisher_pushover/pushover.pyfront/plugins/nbtscan_scan/nbtscan.pyserver/plugin.pyfront/plugins/omada_sdn_imp/omada_sdn.pyserver/workflows/app_events.pytest/test_history_endpoints.pyserver/scan/session_events.pyfront/plugins/nmap_dev_scan/nmap_dev.pyserver/workflows/manager.pyfront/plugins/dhcp_leases/script.pyserver/messaging/reporting.pyserver/logger.pyfront/plugins/_publisher_apprise/apprise.pyfront/plugins/_publisher_pushsafer/pushsafer.pyfront/plugins/_publisher_mqtt/mqtt.pyfront/plugins/wake_on_lan/wake_on_lan.pytest/test_graphq_endpoints.pyfront/plugins/csv_backup/script.pyfront/plugins/_publisher_email/email_smtp.pyfront/plugins/freebox/freebox.pyserver/initialise.pyserver/api_server/api_server_start.pyfront/plugins/internet_speedtest/script.pyserver/helper.pytest/test_sessions_endpoints.pyfront/plugins/luci_import/script.pytest/test_dbquery_endpoints.pyserver/workflows/actions.pytest/test_device_endpoints.pyserver/workflows/triggers.pyserver/api_server/sessions_endpoint.pyserver/models/notification_instance.pyserver/api_server/device_endpoint.pyfront/plugins/dig_scan/digscan.pyserver/scan/device_handling.pyfront/plugins/_publisher_telegram/tg.pyfront/plugins/maintenance/maintenance.pyfront/plugins/ddns_update/script.pytest/test_settings_endpoints.pyfront/plugins/__template/rename_me.pyserver/app_state.pyserver/messaging/in_app.pyfront/plugins/nslookup_scan/nslookup.pyfront/plugins/unifi_import/script.pyfront/plugins/arp_scan/script.py
test/**/*.py
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
Tests must reside under 'test/' and use pytest.
Files:
test/test_nettools_endpoints.pytest/test_history_endpoints.pytest/test_graphq_endpoints.pytest/test_sessions_endpoints.pytest/test_dbquery_endpoints.pytest/test_device_endpoints.pytest/test_settings_endpoints.py
front/plugins/plugin_helper.py
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
Use 'Plugin_Objects' from 'front/plugins/plugin_helper.py' to sanitize text and normalize MAC addresses before writing results.
Files:
front/plugins/plugin_helper.py
server/api_server/*.py
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
When introducing new server functionality, add endpoints only within 'server/api_server/*' and keep authorization checks consistent.
Files:
server/api_server/sync_endpoint.pyserver/api_server/events_endpoint.pyserver/api_server/api_server_start.pyserver/api_server/sessions_endpoint.pyserver/api_server/device_endpoint.py
server/initialise.py
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
Add or modify settings centrally via 'ccd()' in 'server/initialise.py' or via plugin manifest; never hardcode ports or secrets—always use 'get_setting_value()'.
Files:
server/initialise.py
server/api_server/api_server_start.py
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
All API endpoints must enforce Authorization headers: 'Authorization: Bearer <API_TOKEN>' obtained via 'get_setting_value('API_TOKEN')'.
Files:
server/api_server/api_server_start.py
server/helper.py
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
Use 'helper.py' ('timeNowTZ', 'normalize_mac', and sanitizers) for all time, MAC, and string operations; always validate MACs before database writes.
Files:
server/helper.py
🧠 Learnings (10)
📓 Common learnings
Learnt from: CR
Repo: jokob-sk/NetAlertX PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-10-21T01:40:24.597Z
Learning: Applies to server/helper.py : Use 'helper.py' ('timeNowTZ', 'normalize_mac', and sanitizers) for all time, MAC, and string operations; always validate MACs before database writes.
📚 Learning: 2025-10-21T01:40:24.597Z
Learnt from: CR
Repo: jokob-sk/NetAlertX PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-10-21T01:40:24.597Z
Learning: Applies to front/plugins/plugin_helper.py : Use 'Plugin_Objects' from 'front/plugins/plugin_helper.py' to sanitize text and normalize MAC addresses before writing results.
Applied to files:
front/plugins/vendor_update/script.pyfront/plugins/icmp_scan/icmp.pyfront/plugins/internet_ip/script.pyfront/plugins/__test/test.pyfront/plugins/_publisher_pushover/pushover.pyfront/plugins/nmap_dev_scan/nmap_dev.pyfront/plugins/dhcp_leases/script.pyfront/plugins/_publisher_mqtt/mqtt.pyfront/plugins/csv_backup/script.pyfront/plugins/internet_speedtest/script.pyfront/plugins/luci_import/script.pyfront/plugins/maintenance/maintenance.pyfront/plugins/ddns_update/script.pyfront/plugins/nslookup_scan/nslookup.pyfront/plugins/unifi_import/script.py
📚 Learning: 2025-10-21T01:40:24.597Z
Learnt from: CR
Repo: jokob-sk/NetAlertX PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-10-21T01:40:24.597Z
Learning: Applies to server/helper.py : Use 'helper.py' ('timeNowTZ', 'normalize_mac', and sanitizers) for all time, MAC, and string operations; always validate MACs before database writes.
Applied to files:
front/plugins/vendor_update/script.pyserver/scan/device_heuristics.pyfront/plugins/icmp_scan/icmp.pyfront/plugins/_publisher_ntfy/ntfy.pyserver/plugin.pyserver/workflows/app_events.pyfront/plugins/nmap_dev_scan/nmap_dev.pyserver/helper.pyserver/api_server/sessions_endpoint.pyserver/models/notification_instance.pyserver/api_server/device_endpoint.pyserver/app_state.pyfront/plugins/unifi_import/script.py
📚 Learning: 2025-10-21T01:40:24.597Z
Learnt from: CR
Repo: jokob-sk/NetAlertX PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-10-21T01:40:24.597Z
Learning: Applies to front/plugins/*/script.py : Run plugin scripts as standalone executables with 'sys.path' configured for '/app/front/plugins' and '/app/server', following the provided template.
Applied to files:
test/test_nettools_endpoints.pyserver/api_server/events_endpoint.pytest/test_history_endpoints.pytest/test_graphq_endpoints.pytest/test_sessions_endpoints.pytest/test_dbquery_endpoints.pytest/test_device_endpoints.pyserver/api_server/sessions_endpoint.pytest/test_settings_endpoints.py
📚 Learning: 2025-10-21T01:40:24.597Z
Learnt from: CR
Repo: jokob-sk/NetAlertX PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-10-21T01:40:24.597Z
Learning: Applies to front/plugins/*/script.py : Log a concise summary (such as the total number of objects added) at info level before writing the plugin result file; use verbose/debug for extra context.
Applied to files:
front/plugins/sync/sync.py
📚 Learning: 2025-10-21T01:40:24.597Z
Learnt from: CR
Repo: jokob-sk/NetAlertX PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-10-21T01:40:24.597Z
Learning: Applies to front/plugins/*/script.py : During plugin processing, collect results with 'Plugin_Objects.add_object(...)' and call 'plugin_objects.write_result_file()' exactly once at the end of the script.
Applied to files:
front/plugins/_publisher_webhook/webhook.py
📚 Learning: 2025-09-15T19:45:46.725Z
Learnt from: ingoratsdorf
Repo: jokob-sk/NetAlertX PR: 1176
File: server/__main__.py:191-193
Timestamp: 2025-09-15T19:45:46.725Z
Learning: The method clearPluginObjects() in server/models/notification_instance.py should be renamed to clearPluginEvents() since it deletes from the Plugins_Events table, not a Plugins_Objects table. The method name should reflect the actual table being cleared.
Applied to files:
front/plugins/_publisher_pushover/pushover.py
📚 Learning: 2025-11-02T02:22:10.949Z
Learnt from: jokob-sk
Repo: jokob-sk/NetAlertX PR: 1261
File: server/app_state.py:106-115
Timestamp: 2025-11-02T02:22:10.949Z
Learning: In server/app_state.py, the pluginsStates parameter always contains complete plugin state objects with the structure: {"PLUGIN_NAME": {"lastChanged": "...", "totalObjects": N, "newObjects": N, "changedObjects": N}}. Type validation before calling .update() is not needed as the maintainer guarantees well-formed objects are always supplied.
Applied to files:
server/plugin.pyserver/app_state.py
📚 Learning: 2025-10-21T01:40:24.597Z
Learnt from: CR
Repo: jokob-sk/NetAlertX PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-10-21T01:40:24.597Z
Learning: Applies to server/database.py : Leverage helpers in 'server/database.py' and 'server/db/*' for persistent state with SQLite.
Applied to files:
server/api_server/api_server_start.py
📚 Learning: 2025-10-21T01:40:24.597Z
Learnt from: CR
Repo: jokob-sk/NetAlertX PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-10-21T01:40:24.597Z
Learning: Applies to server/db/*.py : Prefer using functions from 'server/db/db_helper.py' (like 'get_table_json' and device condition helpers) over raw SQL for new database code.
Applied to files:
server/helper.pyserver/api_server/device_endpoint.py
🧬 Code graph analysis (59)
front/plugins/vendor_update/script.py (1)
server/helper.py (1)
get_setting_value(343-396)
test/test_nettools_endpoints.py (1)
server/helper.py (1)
get_setting_value(343-396)
server/scan/device_heuristics.py (1)
server/helper.py (1)
get_setting_value(343-396)
front/plugins/icmp_scan/icmp.py (1)
server/helper.py (1)
get_setting_value(343-396)
front/plugins/sync/sync.py (2)
server/helper.py (2)
timeNowDB(49-64)get_setting_value(343-396)server/messaging/in_app.py (1)
write_notification(28-78)
front/plugins/_publisher_ntfy/ntfy.py (1)
server/helper.py (2)
timeNowDB(49-64)get_setting_value(343-396)
front/plugins/_publisher_webhook/webhook.py (1)
server/helper.py (1)
timeNowDB(49-64)
front/plugins/nmap_scan/script.py (1)
server/helper.py (2)
timeNowDB(49-64)get_setting_value(343-396)
front/plugins/plugin_helper.py (1)
server/logger.py (3)
mylog(103-109)Logger(72-113)timeNowDB(22-37)
server/workflows/conditions.py (1)
server/helper.py (1)
get_setting_value(343-396)
front/plugins/internet_ip/script.py (2)
server/helper.py (1)
timeNowDB(49-64)server/logger.py (2)
timeNowDB(22-37)append_line_to_file(167-175)
server/api_server/sync_endpoint.py (2)
server/helper.py (1)
timeNowDB(49-64)server/messaging/in_app.py (1)
write_notification(28-78)
server/api_server/events_endpoint.py (2)
server/helper.py (1)
ensure_datetime(90-95)server/logger.py (1)
mylog(103-109)
front/plugins/__test/test.py (1)
server/helper.py (3)
get_setting_value(343-396)bytes_to_string(588-592)sanitize_string(627-631)
front/plugins/_publisher_pushover/pushover.py (1)
server/helper.py (3)
timeNowDB(49-64)get_setting_value(343-396)hide_string(612-616)
front/plugins/nbtscan_scan/nbtscan.py (1)
server/helper.py (1)
get_setting_value(343-396)
server/plugin.py (2)
server/helper.py (1)
timeNowDB(49-64)server/messaging/in_app.py (1)
write_notification(28-78)
front/plugins/omada_sdn_imp/omada_sdn.py (1)
server/helper.py (1)
get_setting_value(343-396)
server/workflows/app_events.py (1)
server/helper.py (1)
get_setting_value(343-396)
test/test_history_endpoints.py (1)
server/helper.py (1)
get_setting_value(343-396)
server/scan/session_events.py (1)
server/helper.py (2)
timeNowDB(49-64)get_setting_value(343-396)
front/plugins/nmap_dev_scan/nmap_dev.py (1)
server/helper.py (4)
get_setting_value(343-396)extract_between_strings(578-584)extract_ip_addresses(685-688)extract_mac_addresses(679-682)
server/workflows/manager.py (1)
server/helper.py (1)
get_setting_value(343-396)
front/plugins/dhcp_leases/script.py (1)
server/helper.py (1)
get_setting_value(343-396)
server/messaging/reporting.py (2)
server/helper.py (4)
get_file_content(240-246)write_file(249-270)get_timezone_offset(43-47)get_setting_value(343-396)server/logger.py (1)
mylog(103-109)
server/logger.py (2)
server/helper.py (1)
timeNowDB(49-64)front/js/common.js (1)
tz(375-375)
front/plugins/_publisher_apprise/apprise.py (1)
server/helper.py (2)
timeNowDB(49-64)get_setting_value(343-396)
front/plugins/_publisher_pushsafer/pushsafer.py (1)
server/helper.py (3)
timeNowDB(49-64)get_setting_value(343-396)hide_string(612-616)
front/plugins/_publisher_mqtt/mqtt.py (1)
server/helper.py (3)
timeNowDB(49-64)get_setting_value(343-396)bytes_to_string(588-592)
front/plugins/wake_on_lan/wake_on_lan.py (1)
server/helper.py (1)
get_setting_value(343-396)
test/test_graphq_endpoints.py (1)
server/helper.py (1)
get_setting_value(343-396)
front/plugins/csv_backup/script.py (1)
server/helper.py (1)
get_setting_value(343-396)
front/plugins/_publisher_email/email_smtp.py (1)
server/helper.py (1)
timeNowDB(49-64)
front/plugins/freebox/freebox.py (1)
server/helper.py (1)
get_setting_value(343-396)
server/initialise.py (2)
server/helper.py (1)
timeNowDB(49-64)server/messaging/in_app.py (1)
write_notification(28-78)
server/api_server/api_server_start.py (1)
server/helper.py (1)
get_setting_value(343-396)
front/plugins/internet_speedtest/script.py (1)
server/helper.py (2)
timeNowDB(49-64)get_setting_value(343-396)
server/helper.py (2)
server/logger.py (1)
timeNowDB(22-37)front/js/common.js (1)
tz(375-375)
test/test_sessions_endpoints.py (1)
server/helper.py (2)
timeNowDB(49-64)get_setting_value(343-396)
front/plugins/luci_import/script.py (1)
server/helper.py (1)
get_setting_value(343-396)
test/test_dbquery_endpoints.py (1)
server/helper.py (1)
timeNowDB(49-64)
server/workflows/actions.py (1)
server/helper.py (1)
get_setting_value(343-396)
test/test_device_endpoints.py (1)
server/helper.py (1)
get_setting_value(343-396)
server/workflows/triggers.py (1)
server/helper.py (1)
get_setting_value(343-396)
server/api_server/sessions_endpoint.py (2)
server/helper.py (9)
is_random_mac(649-664)is_random_mac(692-703)format_date(111-120)get_setting_value(343-396)format_date_iso(72-77)format_event_date(80-87)format_date_diff(122-163)format_ip_long(714-725)parse_datetime(98-109)server/logger.py (1)
mylog(103-109)
server/models/notification_instance.py (1)
server/helper.py (1)
timeNowDB(49-64)
server/api_server/device_endpoint.py (1)
server/helper.py (3)
format_date(111-120)get_setting_value(343-396)timeNowDB(49-64)
front/plugins/dig_scan/digscan.py (1)
server/helper.py (1)
get_setting_value(343-396)
server/scan/device_handling.py (1)
server/helper.py (4)
timeNowDB(49-64)timeNowTZ(34-38)get_setting_value(343-396)check_IP_format(551-566)
front/plugins/_publisher_telegram/tg.py (1)
server/helper.py (2)
timeNowDB(49-64)get_setting_value(343-396)
front/plugins/maintenance/maintenance.py (1)
server/helper.py (1)
get_setting_value(343-396)
front/plugins/ddns_update/script.py (1)
server/helper.py (2)
get_setting_value(343-396)check_IP_format(551-566)
test/test_settings_endpoints.py (1)
server/helper.py (1)
get_setting_value(343-396)
front/plugins/__template/rename_me.py (1)
server/helper.py (1)
get_setting_value(343-396)
server/app_state.py (1)
server/helper.py (3)
timeNowDB(49-64)timeNow(40-41)checkNewVersion(797-833)
server/messaging/in_app.py (1)
server/helper.py (5)
timeNowDB(49-64)get_file_content(240-246)write_file(249-270)get_setting_value(343-396)get_timezone_offset(43-47)
front/plugins/nslookup_scan/nslookup.py (1)
server/helper.py (1)
get_setting_value(343-396)
front/plugins/unifi_import/script.py (1)
server/helper.py (2)
get_setting_value(343-396)normalize_string(636-642)
front/plugins/arp_scan/script.py (1)
server/helper.py (1)
get_setting_value(343-396)
🪛 Ruff (0.14.3)
front/plugins/_publisher_pushover/pushover.py
14-14: Unused noqa directive (non-enabled: E402)
Remove unused noqa directive
(RUF100)
server/logger.py
32-32: ZoneInfo may be undefined, or defined from star imports
(F405)
33-33: Do not catch blind exception: Exception
(BLE001)
server/initialise.py
395-395: f-string without any placeholders
Remove extraneous f prefix
(F541)
server/helper.py
59-59: ZoneInfo may be undefined, or defined from star imports
(F405)
60-60: Do not catch blind exception: Exception
(BLE001)
119-119: Do not catch blind exception: Exception
(BLE001)
server/scan/device_handling.py
559-559: Do not catch blind exception: Exception
(BLE001)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
- GitHub Check: docker_dev
🔇 Additional comments (57)
front/plugins/maintenance/maintenance.py (1)
20-20: LGTM! Unused import removed.The removal of
timeNowTZfrom the import statement is appropriate since it's not used anywhere in this file. This cleanup aligns with the PR's broader objective to centralize time handling.front/plugins/ddns_update/script.py (2)
22-22: LGTM! Correctly removes unused import.The removal of
timeNowTZis appropriate since it's not used anywhere in this file.
93-105: Clarify plugin result tracking requirements.The commented-out code suggests this plugin previously tracked results via
Plugin_Objects. Per the coding guidelines, plugin scripts should "collect results withPlugin_Objects.add_object(...)and callplugin_objects.write_result_file()exactly once at the end of the script."Should this DDNS plugin write result files, or is it intentionally exempt from this requirement since it performs operational tasks (DDNS updates) rather than device/object discovery?
As per coding guidelines.
front/plugins/__test/test.py (1)
26-26: LGTM! Correct removal of unused import.The removal of
timeNowTZfrom the import statement is appropriate since it's not used anywhere in this test file. This aligns with the PR's objective to migrate fromtimeNowTZtotimeNowDBacross the codebase.front/plugins/nmap_dev_scan/nmap_dev.py (1)
24-24: LGTM!The removal of
timeNowTZfrom the import is correct, as the file does not perform any timestamp operations.front/plugins/unifi_import/script.py (1)
24-24: LGTM! Import cleanup and normalization improvement.The removal of the unused
timeNowTZimport and the addition ofnormalize_stringaligns with the PR's migration totimeNowDBand improves string handling by using the helper utility at line 197. Based on learnings.front/plugins/wake_on_lan/wake_on_lan.py (1)
19-19: LGTM! Appropriate cleanup of unused import.The removal of the unused
timeNowTZimport is correct and aligns with the PR's migration strategy.front/plugins/freebox/freebox.py (1)
27-27: LGTM! Unused import removed.Correct removal of the unused
timeNowTZimport, consistent with the broader refactoring effort.front/plugins/nmap_scan/script.py (2)
17-17: LGTM! Correct import migration to timeNowDB.The import change from
timeNowTZtotimeNowDBis appropriate and aligns with the PR's objective to use ISO-formatted, DB-friendly timestamps. Based on learnings.
161-161: LGTM! Correct usage of timeNowDB.The replacement of
timeNowTZ()withtimeNowDB()for the timestamp field ensures DB-compatible ISO 8601 formatting, consistent with the broader migration pattern.front/plugins/luci_import/script.py (1)
12-12: LGTM! Unused import removed.Appropriate removal of the unused
timeNowTZimport.front/plugins/vendor_update/script.py (1)
20-20: LGTM! Unused import removed.Correct cleanup of the unused
timeNowTZimport.front/plugins/nbtscan_scan/nbtscan.py (1)
18-18: LGTM! Unused import removed.Appropriate removal of the unused
timeNowTZimport.server/scan/session_events.py (3)
9-9: LGTM! Correct import migration.The import change from
timeNowTZtotimeNowDBis appropriate for the timestamp operations in this module. Based on learnings.
131-131: LGTM! Correct usage of timeNowDB for event timestamps.The replacement of
timeNowTZ()withtimeNowDB()ensures thestartTimeused in event insertion (lines 138, 151, 168, 182) is in ISO 8601 format, which is DB-safe and consistent with the migration pattern.
194-194: LGTM! Correct usage of timeNowDB for history timestamps.The replacement of
timeNowTZ()withtimeNowDB()forscanTimestampensures the Online_History table receives properly formatted ISO 8601 timestamps, maintaining DB compatibility.front/plugins/omada_sdn_imp/omada_sdn.py (1)
47-47: LGTM: Unused import removed.The removal of
timeNowTZis appropriate as it's not used anywhere in this file.front/plugins/dhcp_leases/script.py (1)
18-18: LGTM: Unused import removed.The removal of
timeNowTZis appropriate as it's not used anywhere in this file.front/plugins/csv_backup/script.py (1)
19-19: LGTM: Unused import removed.The removal of
timeNowTZis appropriate as it's not used anywhere in this file.front/plugins/arp_scan/script.py (1)
19-19: LGTM: Unused imports removed.The removal of
timeNowTZandstrftimeis appropriate as they're not used anywhere in this file.server/api_server/sessions_endpoint.py (1)
19-19: LGTM: Unused import removed.The removal of
timeNowTZis appropriate as it's not used anywhere in this file. The file already imports other necessary date/time formatting functions likeformat_date,format_date_iso, andparse_datetime.server/workflows/app_events.py (1)
13-13: LGTM: Unused import removed.The removal of
timeNowTZis appropriate as it's not used anywhere in this file. Timestamps are handled by SQLite'sDATETIME('now')function.server/workflows/manager.py (1)
12-12: LGTM: Unused import removed.The removal of
timeNowTZis appropriate as it's not used anywhere in this file.front/plugins/icmp_scan/icmp.py (1)
23-23: LGTM: Unused import removed.The removal of
timeNowTZis appropriate as it's not used anywhere in this file.test/test_nettools_endpoints.py (1)
13-13: LGTM: Import cleanup is appropriate.The removal of
timeNowTZfrom imports is correct since the file only usesget_setting_valueand does not require timestamp functionality.front/plugins/_publisher_pushsafer/pushsafer.py (2)
22-22: LGTM: Import updated correctly.The replacement of
timeNowTZwithtimeNowDBin imports aligns with the PR's standardization effort.
71-71: LGTM: Timestamp function updated correctly.The change from
timeNowTZ()totimeNowDB()provides DB-friendly ISO 8601 timestamps for the notification log's secondaryId field, consistent with the PR's objective.front/plugins/nslookup_scan/nslookup.py (1)
23-23: LGTM: Unused import removed.The removal of
timeNowTZis appropriate since the file only requiresget_setting_valuefor configuration access and does not use timestamp functions.front/plugins/dig_scan/digscan.py (1)
18-18: LGTM: Unused import removed.The removal of
timeNowTZis correct as the file does not use timestamp functionality.front/plugins/_publisher_mqtt/mqtt.py (1)
26-26: LGTM: Import updated correctly.The replacement of
timeNowTZwithtimeNowDBaligns with the PR's standardization effort.front/plugins/__template/rename_me.py (1)
18-18: LGTM: Template import cleanup.The removal of
timeNowTZfrom the plugin template is appropriate since timestamp functionality is not needed in the template skeleton.server/api_server/events_endpoint.py (1)
17-17: LGTM: Unused import removed.The removal of
timeNowTZis correct since the file relies onensure_datetimefor timestamp handling, which internally usestimeNowDB()when needed.test/test_dbquery_endpoints.py (2)
9-9: LGTM: Import updated correctly.The replacement of
timeNowTZwithtimeNowDBaligns with the PR's standardization effort.
44-48: LGTM: Improved timestamp consistency.Caching the timestamp in the
nowvariable and using it for bothdevFirstConnectionanddevLastConnectionensures consistent timestamps for test device creation, which is appropriate for unit testing.server/app_state.py (1)
7-7: LGTM: Timestamp migration to timeNowDB.The import and usage changes correctly migrate from
timeNowTZ()totimeNowDB()for database-friendly timestamps. ThelastUpdatedfield now uses ISO 8601 format suitable for DB storage.Also applies to: 62-62
front/plugins/sync/sync.py (1)
21-21: LGTM: Consistent migration to timeNowDB.All timestamp generation for notifications and logging has been consistently migrated from
timeNowTZ()totimeNowDB(), ensuring DB-friendly ISO 8601 format throughout.Also applies to: 152-152, 258-258, 302-302, 311-311, 335-335, 343-343
server/helper.py (1)
90-95: LGTM: Updated ensure_datetime to use timeNowDB.The function now correctly delegates to
timeNowDB()whendtis None, maintaining consistency with the new timestamp standard.server/workflows/actions.py (1)
10-10: LGTM: Removed unused import.The
timeNowTZimport was not used in this file and has been correctly removed.server/scan/device_heuristics.py (1)
15-15: LGTM: Removed unused import.The
timeNowTZimport was not used in this file and has been correctly removed.front/plugins/_publisher_ntfy/ntfy.py (1)
22-22: LGTM: Plugin timestamp migrated to timeNowDB.The plugin object's
secondaryIdtimestamp now usestimeNowDB()for DB-friendly ISO 8601 format, consistent with the repository-wide migration.Also applies to: 71-71
server/workflows/conditions.py (1)
11-11: LGTM: Removed unused import.The
timeNowTZimport was not used in this file and has been correctly removed.server/workflows/triggers.py (1)
10-10: LGTM! Unused import removed.The removal of
timeNowTZis correct as it's not used anywhere in this file.front/plugins/internet_speedtest/script.py (1)
16-16: LGTM! Consistent migration to timeNowDB.The import and usage have been correctly updated to use
timeNowDB(), which provides DB-friendly ISO 8601 timestamps for the speedtest result'ssecondaryId.Also applies to: 43-43
server/models/notification_instance.py (1)
19-19: LGTM! Timestamp generation migrated to timeNowDB.All timestamp assignments (
DateTimeCreated, report date,DateTimePushed, and SQL updates) now correctly usetimeNowDB()for consistent DB-friendly formatting.Also applies to: 75-75, 116-116, 235-235, 286-286
server/scan/device_handling.py (2)
59-59: LGTM! Consistent DB timestamp generation.The
startTimeassignments in bothupdate_devices_data_from_scanandcreate_new_devicesnow correctly usetimeNowDB()for DB-friendly timestamps.Also applies to: 374-374
532-543: LGTM! Timestamp normalization handles string-to-datetime conversion.The code correctly normalizes
last_checkedfrom string (persisted from previous run viatimeNowDB()on line 676) todatetimeobject (lines 536-543), ensuring type consistency for comparison on line 575.Also applies to: 676-676
front/plugins/_publisher_webhook/webhook.py (1)
25-25: LGTM! Publisher timestamp migrated to timeNowDB.The import and usage correctly updated to use
timeNowDB()for the notification log'ssecondaryId, consistent with other publisher plugins in this PR.Also applies to: 74-74
test/test_device_endpoints.py (1)
12-12: LGTM! Unused import removed.The removal of
timeNowTZis correct as it's not used in this test file.front/plugins/plugin_helper.py (1)
14-14: LGTM! Centralized timestamp generation for plugin objects.The migration from inline
datetime.now().strftime()totimeNowDB()centralizes timestamp generation and ensures consistent timezone-aware formatting across all plugin objects.Also applies to: 207-207
test/test_history_endpoints.py (1)
12-12: LGTM! Unused import removed.The removal of
timeNowTZis correct as it's not used in this test file.front/plugins/internet_ip/script.py (1)
23-23: LGTM! Timestamp standardization to timeNowDB.The import and usage have been correctly updated to use
timeNowDB()for ISO 8601 DB-friendly timestamps.Also applies to: 83-83
server/api_server/api_server_start.py (1)
12-12: LGTM! Unused import removed.Correctly removes
timeNowTZfrom imports as it's not used in this file.test/test_settings_endpoints.py (1)
13-13: LGTM! Unused import removed.Correctly removes
timeNowTZfrom imports as it's not used in this test file.front/plugins/_publisher_apprise/apprise.py (1)
19-19: LGTM! Timestamp standardization to timeNowDB.The import and usage in
add_objecthave been correctly updated to usetimeNowDB()for consistent ISO 8601 timestamps.Also applies to: 68-68
server/messaging/in_app.py (1)
23-23: LGTM! Timestamp standardization to timeNowDB.The import and default timestamp in
write_notificationhave been correctly updated to usetimeNowDB().Also applies to: 42-42
front/plugins/_publisher_pushover/pushover.py (1)
14-14: LGTM! Timestamp standardization to timeNowDB.The import and usage have been correctly updated to use
timeNowDB()for consistent ISO 8601 timestamps.Also applies to: 66-66
test/test_graphq_endpoints.py (1)
13-13: LGTM! Unused import removed.Correctly removes
timeNowTZfrom imports as it's not used in this test file.
Signed-off-by: jokob-sk <jokob.sk@gmail.com>
Signed-off-by: jokob-sk <jokob.sk@gmail.com>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
♻️ Duplicate comments (2)
server/helper.py (1)
49-69: MissingZoneInfoimport causes NameError.The function uses
ZoneInfoat line 62, but it's not imported. Additionally,datetime.UTCat line 69 doesn't exist in Python 3.10 and earlier—usedatetime.timezone.utcinstead.Apply this diff to fix both issues:
import datetime +from zoneinfo import ZoneInfo import oselse: - return datetime.datetime.now(datetime.UTC).strftime('%Y-%m-%d %H:%M:%S') + return datetime.datetime.now(datetime.timezone.utc).strftime('%Y-%m-%d %H:%M:%S')server/logger.py (1)
22-42: MissingZoneInfoimport and incorrectdatetime.UTCusage.This function has the same issues as
server/helper.py:
ZoneInfois used at line 35 but not importeddatetime.UTCat line 42 doesn't exist in Python ≤3.10—usedatetime.timezone.utcinsteadApply this diff:
import logging +from zoneinfo import ZoneInfoelse: - return datetime.datetime.now(datetime.UTC).strftime('%Y-%m-%d %H:%M:%S') + return datetime.datetime.now(datetime.timezone.utc).strftime('%Y-%m-%d %H:%M:%S')
🧹 Nitpick comments (2)
server/helper.py (1)
116-125: Avoid bareExceptioncatch.Catching all exceptions can hide bugs. Consider catching specific exceptions like
(ValueError, AttributeError, TypeError)that you expect from date parsing.Apply this diff:
try: dt = parse_datetime(date_str) if dt.tzinfo is None: # Set timezone if missing — change to timezone.utc if you prefer UTC now = datetime.datetime.now(conf.tz) dt = dt.replace(tzinfo=now.astimezone().tzinfo) return dt.astimezone().isoformat() - except Exception: + except (ValueError, AttributeError, TypeError): return "invalid"server/logger.py (1)
22-42: Consider extracting to shared module to avoid duplication.
timeNowDBis duplicated here and inserver/helper.py. While the comment at line 14 notes this is intentional to avoid circular imports, maintaining two identical copies creates a maintenance burden. Consider extracting time utilities to a dedicated module (e.g.,time_utils.py) that bothhelper.pyandlogger.pycan import.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (3)
server/helper.py(3 hunks)server/logger.py(1 hunks)test/test_sessions_endpoints.py(6 hunks)
🧰 Additional context used
📓 Path-based instructions (3)
**/*.py
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
Use 'logger.mylog' for logging at levels: none, minimal, verbose, debug, or trace.
Files:
test/test_sessions_endpoints.pyserver/logger.pyserver/helper.py
test/**/*.py
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
Tests must reside under 'test/' and use pytest.
Files:
test/test_sessions_endpoints.py
server/helper.py
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
Use 'helper.py' ('timeNowTZ', 'normalize_mac', and sanitizers) for all time, MAC, and string operations; always validate MACs before database writes.
Files:
server/helper.py
🧠 Learnings (3)
📓 Common learnings
Learnt from: CR
Repo: jokob-sk/NetAlertX PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-10-21T01:40:24.597Z
Learning: Applies to server/helper.py : Use 'helper.py' ('timeNowTZ', 'normalize_mac', and sanitizers) for all time, MAC, and string operations; always validate MACs before database writes.
📚 Learning: 2025-10-21T01:40:24.597Z
Learnt from: CR
Repo: jokob-sk/NetAlertX PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-10-21T01:40:24.597Z
Learning: Applies to front/plugins/*/script.py : Run plugin scripts as standalone executables with 'sys.path' configured for '/app/front/plugins' and '/app/server', following the provided template.
Applied to files:
test/test_sessions_endpoints.py
📚 Learning: 2025-10-21T01:40:24.597Z
Learnt from: CR
Repo: jokob-sk/NetAlertX PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-10-21T01:40:24.597Z
Learning: Applies to server/helper.py : Use 'helper.py' ('timeNowTZ', 'normalize_mac', and sanitizers) for all time, MAC, and string operations; always validate MACs before database writes.
Applied to files:
server/helper.py
🧬 Code graph analysis (3)
test/test_sessions_endpoints.py (1)
server/helper.py (3)
timeNowDB(49-69)timeNowTZ(34-38)get_setting_value(348-401)
server/logger.py (2)
server/helper.py (1)
timeNowDB(49-69)front/js/common.js (1)
tz(375-375)
server/helper.py (2)
server/logger.py (1)
timeNowDB(22-42)front/js/common.js (1)
tz(375-375)
🪛 Ruff (0.14.3)
server/logger.py
35-35: ZoneInfo may be undefined, or defined from star imports
(F405)
38-38: Do not catch blind exception: Exception
(BLE001)
server/helper.py
62-62: ZoneInfo may be undefined, or defined from star imports
(F405)
65-65: Do not catch blind exception: Exception
(BLE001)
124-124: Do not catch blind exception: Exception
(BLE001)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
- GitHub Check: docker_dev
🔇 Additional comments (2)
test/test_sessions_endpoints.py (2)
13-13: LGTM! Import statement is now complete.Both
timeNowDBandtimeNowTZare correctly imported. The file usestimeNowDB()for database-friendly timestamps in test payloads andtimeNowTZ()for datetime arithmetic in the calendar test (line 191). This is the correct pattern.
51-51: Consistent migration totimeNowDB()for test payloads.The test payloads now use
timeNowDB()to generate database-friendly timestamp strings for thestart_timefield. This aligns with the PR's objective of centralizing DB-safe timestamp formatting across the codebase.Also applies to: 66-66, 83-83, 118-118, 166-166
Signed-off-by: jokob-sk <jokob.sk@gmail.com>
Signed-off-by: jokob-sk <jokob.sk@gmail.com>
Signed-off-by: jokob-sk <jokob.sk@gmail.com>
Signed-off-by: jokob-sk <jokob.sk@gmail.com>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 2
🧹 Nitpick comments (1)
server/helper.py (1)
117-126: Consider simplifying timezone application.The current approach creates a temporary
nowdatetime to extract timezone info (lines 122-123). This could be more direct:try: dt = parse_datetime(date_str) if dt.tzinfo is None: - # Set timezone if missing — change to timezone.utc if you prefer UTC - now = datetime.datetime.now(conf.tz) - dt = dt.replace(tzinfo=now.astimezone().tzinfo) + # Set timezone if missing + dt = dt.replace(tzinfo=conf.tz if isinstance(conf.tz, datetime.tzinfo) else ZoneInfo(conf.tz)) return dt.astimezone().isoformat() except Exception: return "invalid"Note: The current implementation is safe and handles edge cases. This is an optional refinement.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (4)
docs/NOTIFICATIONS.md(1 hunks)front/plugins/notification_processing/config.json(1 hunks)server/helper.py(5 hunks)server/scan/name_resolution.py(1 hunks)
✅ Files skipped from review due to trivial changes (1)
- front/plugins/notification_processing/config.json
🧰 Additional context used
📓 Path-based instructions (2)
**/*.py
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
Use 'logger.mylog' for logging at levels: none, minimal, verbose, debug, or trace.
Files:
server/scan/name_resolution.pyserver/helper.py
server/helper.py
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
Use 'helper.py' ('timeNowTZ', 'normalize_mac', and sanitizers) for all time, MAC, and string operations; always validate MACs before database writes.
Files:
server/helper.py
🧠 Learnings (1)
📚 Learning: 2025-10-21T01:40:24.597Z
Learnt from: CR
Repo: jokob-sk/NetAlertX PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-10-21T01:40:24.597Z
Learning: Applies to server/helper.py : Use 'helper.py' ('timeNowTZ', 'normalize_mac', and sanitizers) for all time, MAC, and string operations; always validate MACs before database writes.
Applied to files:
server/helper.py
🧬 Code graph analysis (2)
server/scan/name_resolution.py (1)
server/logger.py (1)
mylog(109-115)
server/helper.py (2)
server/logger.py (1)
timeNowDB(23-43)front/js/common.js (1)
tz(375-375)
🪛 LanguageTool
docs/NOTIFICATIONS.md
[style] ~54-~54: Consider using a different adverb to strengthen your wording.
Context: ...IFICATIONS/NEWDEV_ignores.png) You can completely ignore detected devices globally. This ...
(COMPLETELY_ENTIRELY)
[grammar] ~61-~61: Ensure spelling is correct
Context: ...to ignore new device notifications of a certian pattern. 1. Events Filter (`NTFPRCS_ev...
(QB_NEW_EN_ORTHOGRAPHY_ERROR_IDS_1)
🪛 Ruff (0.14.3)
server/helper.py
66-66: Do not catch blind exception: Exception
(BLE001)
125-125: Do not catch blind exception: Exception
(BLE001)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
- GitHub Check: docker_dev
🔇 Additional comments (6)
server/scan/name_resolution.py (1)
75-75: LGTM! Helpful debugging enhancement.The trace log appropriately shows the complete list of regex patterns before they're applied, making it easier to debug name cleanup issues. The logging level and format are consistent with the existing trace logs in this method.
docs/NOTIFICATIONS.md (2)
50-50: Verify the emoji swap is intentional.The heading emoji for "Ignoring devices" changes from 🔕 (bell) to 💻 (laptop), while the new section "Ignoring notifications" uses the bell emoji instead. This semantic shift is sensible—notifications logically map to the bell, devices to the laptop—but represents a significant heading reorganization. Confirm this aligns with your documentation structure intent.
59-64: Documentation structure for new notifications filtering looks good.The new "Ignoring notifications 🔕" section clearly documents the two global notification filters (
NTFPRCS_event_conditionandNTFPRCS_new_dev_condition). The placement after "Ignoring devices" and the distinction between filtering devices (preventing detection) versus filtering notifications (post-detection logs/alerts) is logical and helpful.server/helper.py (3)
15-15: LGTM! Import issue resolved.The missing ZoneInfo import has been properly added, resolving the NameError that would occur in
timeNowDB()whenlocal=True.
384-386: LGTM! Effective caching optimization.The addition of
SETTINGS_SECONDARYCACHEstorage at line 385 properly caches settings retrieved fromconf.mySettings, complementing the existing cache at line 402 for JSON-sourced settings. This reduces repeated lookups and improves performance.
472-473: LGTM! Ensures transformers run for array values.The addition ensures that transformers (e.g., base64 decoding) are consistently applied to array entries, aligning with how transformers are handled for other data types (strings, objects). This fixes a gap where select-type arrays might have skipped transformation.
server/helper.py
Outdated
| def timeNowDB(local=True): | ||
| """ | ||
| Return the current time (local or UTC) as ISO 8601 for DB storage. | ||
| Safe for SQLite, PostgreSQL, etc. | ||
|
|
||
| Example local: '2025-11-04 18:09:11' | ||
| Example UTC: '2025-11-04 07:09:11' | ||
| """ | ||
| if local: | ||
| try: | ||
| if isinstance(conf.tz, datetime.tzinfo): | ||
| tz = conf.tz | ||
| elif conf.tz: | ||
| tz = ZoneInfo(conf.tz) | ||
| else: | ||
| tz = None | ||
| except Exception: | ||
| tz = None | ||
| return datetime.datetime.now(tz).strftime('%Y-%m-%d %H:%M:%S') | ||
| else: | ||
| return datetime.datetime.now(datetime.UTC).strftime('%Y-%m-%d %H:%M:%S') | ||
|
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Critical: Remove duplicate implementation in logger.py.
The timeNowDB function is duplicated in both server/helper.py (lines 50-71) and server/logger.py (lines 22-42). This violates DRY principles and creates a maintenance burden where bug fixes must be applied in two places.
Since the coding guidelines specify that helper.py should be used for all time operations, remove the duplicate from logger.py and import it from here instead:
In server/logger.py, replace the duplicate function with an import:
from helper import timeNowDBBased on coding guidelines.
🧰 Tools
🪛 Ruff (0.14.3)
66-66: Do not catch blind exception: Exception
(BLE001)
🤖 Prompt for AI Agents
In server/logger.py around lines 22 to 42, remove the duplicate timeNowDB
implementation and replace it with a single import from server/helper.py; delete
the function body in logger.py and add an import (use a package-relative import,
e.g. from .helper import timeNowDB) at the top of logger.py so all code uses the
centralized helper.timeNowDB; ensure any local references/namespace usage remain
correct after the import.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is done on purpose to prevent circular references - should I create another module instead?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@jokob-sk, that's a valid concern! You're right that importing timeNowDB from helper.py into logger.py would create a circular dependency since helper.py already imports mylog and logResult from logger.py.
Your current approach (keeping the duplicate) is a pragmatic solution given the circular import constraint. However, if you'd like to eliminate the duplication while avoiding circular imports, creating a separate module would be a cleaner architectural solution.
You could create a new module like server/time_utils.py containing just the time-related utilities (timeNowDB, timeNowTZ, timeNow, etc.) that both helper.py and logger.py can import from without creating circular dependencies.
Options:
- Keep current approach - Duplicate remains, but it's simple and works
- Create
server/time_utils.py- Move time functions there, both modules import from it (eliminates duplication, cleaner separation of concerns)
Either approach is valid. The second option is more maintainable long-term if you anticipate changes to these time functions. What would you prefer?
✏️ Learnings added
Learnt from: jokob-sk
Repo: jokob-sk/NetAlertX PR: 1271
File: server/helper.py:50-71
Timestamp: 2025-11-05T04:34:52.319Z
Learning: In the NetAlertX codebase, `timeNowDB` function is intentionally duplicated in both `server/helper.py` and `server/logger.py` to prevent circular import issues, since `helper.py` imports from `logger.py` (`from logger import mylog, logResult`). This duplication is by design.
Note: Learnings are effective only in the context of similar code segments. To apply general coding guidelines, please configure review instructions. You can manage existing learnings in the app.
🧠 Learnings used
Learnt from: CR
Repo: jokob-sk/NetAlertX PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-10-21T01:40:24.597Z
Learning: Applies to server/helper.py : Use 'helper.py' ('timeNowTZ', 'normalize_mac', and sanitizers) for all time, MAC, and string operations; always validate MACs before database writes.
Learnt from: CR
Repo: jokob-sk/NetAlertX PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-10-21T01:40:24.597Z
Learning: Applies to server/db/*.py : Prefer using functions from 'server/db/db_helper.py' (like 'get_table_json' and device condition helpers) over raw SQL for new database code.
Signed-off-by: jokob-sk <jokob.sk@gmail.com>
Signed-off-by: jokob-sk <jokob.sk@gmail.com>
Signed-off-by: jokob-sk <jokob.sk@gmail.com>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 8
♻️ Duplicate comments (1)
server/initialise.py (1)
396-396: Remove unnecessary f-string prefix.The string literal on Line 396 uses an
fprefix without any placeholders, which is unnecessary.Apply this diff:
- write_notification(f'[Upgrade] : App upgraded 🚀 Please clear the cache: <ol> <li>Click OK below</li> <li>Clear the browser cache (shift + browser refresh button)</li> <li> Clear app cache with the <i class="fa-solid fa-rotate"></i> (reload) button in the header</li><li>Go to Settings and click Save</li> </ol> Check out new features and what has changed in the <a href="https://github.com/jokob-sk/NetAlertX/releases" target="_blank">📓 release notes</a>.', 'interrupt', timeNowDB()) + write_notification('[Upgrade] : App upgraded 🚀 Please clear the cache: <ol> <li>Click OK below</li> <li>Clear the browser cache (shift + browser refresh button)</li> <li> Clear app cache with the <i class="fa-solid fa-rotate"></i> (reload) button in the header</li><li>Go to Settings and click Save</li> </ol> Check out new features and what has changed in the <a href="https://github.com/jokob-sk/NetAlertX/releases" target="_blank">📓 release notes</a>.', 'interrupt', timeNowDB())
🧹 Nitpick comments (2)
front/plugins/_publisher_pushover/pushover.py (1)
14-14: Remove unused noqa directive.The
# noqa: E402comment on line 14 is no longer needed since E402 is not enabled.Apply this diff:
-from helper import get_setting_value, hide_string # noqa: E402 +from helper import get_setting_value, hide_stringserver/scan/device_handling.py (1)
560-561: Narrow exception handling to specific types.Line 560 catches broad
Exception. Per coding standards and static analysis, catch only the specific exceptions thatparser.parse()can raise.Apply this diff:
elif isinstance(state_updated, str): try: state_times.append(parser.parse(state_updated)) - except Exception as e: + except (ValueError, TypeError) as e: mylog('none', f'[Update Device Name] Failed to parse timestamp for {p}: {state_updated!r} ({e})')
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (38)
.github/copilot-instructions.md(1 hunks)docs/NOTIFICATIONS.md(1 hunks)front/php/components/logs.php(4 hunks)front/plugins/_publisher_apprise/apprise.py(2 hunks)front/plugins/_publisher_email/email_smtp.py(2 hunks)front/plugins/_publisher_mqtt/mqtt.py(2 hunks)front/plugins/_publisher_ntfy/ntfy.py(2 hunks)front/plugins/_publisher_pushover/pushover.py(2 hunks)front/plugins/_publisher_pushsafer/pushsafer.py(2 hunks)front/plugins/_publisher_telegram/tg.py(2 hunks)front/plugins/_publisher_webhook/webhook.py(2 hunks)front/plugins/internet_ip/script.py(2 hunks)front/plugins/internet_speedtest/script.py(2 hunks)front/plugins/nmap_scan/script.py(2 hunks)front/plugins/plugin_helper.py(2 hunks)front/plugins/sync/sync.py(6 hunks)server/__main__.py(1 hunks)server/api.py(1 hunks)server/api_server/device_endpoint.py(4 hunks)server/api_server/devices_endpoint.py(1 hunks)server/api_server/events_endpoint.py(1 hunks)server/api_server/history_endpoint.py(1 hunks)server/api_server/sessions_endpoint.py(1 hunks)server/api_server/sync_endpoint.py(3 hunks)server/app_state.py(3 hunks)server/helper.py(3 hunks)server/initialise.py(3 hunks)server/logger.py(1 hunks)server/messaging/in_app.py(2 hunks)server/messaging/reporting.py(2 hunks)server/models/notification_instance.py(5 hunks)server/plugin.py(10 hunks)server/scan/device_handling.py(5 hunks)server/scan/session_events.py(3 hunks)server/utils/datetime_utils.py(1 hunks)test/api_endpoints/test_dbquery_endpoints.py(2 hunks)test/api_endpoints/test_events_endpoints.py(1 hunks)test/api_endpoints/test_sessions_endpoints.py(6 hunks)
✅ Files skipped from review due to trivial changes (1)
- server/api_server/devices_endpoint.py
🚧 Files skipped from review as they are similar to previous changes (13)
- server/models/notification_instance.py
- front/plugins/_publisher_mqtt/mqtt.py
- server/api_server/device_endpoint.py
- server/messaging/reporting.py
- server/api_server/sessions_endpoint.py
- server/api_server/events_endpoint.py
- server/scan/session_events.py
- front/plugins/internet_ip/script.py
- test/api_endpoints/test_dbquery_endpoints.py
- front/plugins/_publisher_webhook/webhook.py
- front/plugins/_publisher_telegram/tg.py
- front/plugins/_publisher_ntfy/ntfy.py
- front/plugins/internet_speedtest/script.py
🧰 Additional context used
📓 Path-based instructions (7)
front/plugins/*/script.py
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
front/plugins/*/script.py: Run plugin scripts as standalone executables with 'sys.path' configured for '/app/front/plugins' and '/app/server', following the provided template.
During plugin processing, collect results with 'Plugin_Objects.add_object(...)' and call 'plugin_objects.write_result_file()' exactly once at the end of the script.
Do not write ad-hoc files for plugin results; only generate 'last_result..log' using 'Plugin_Objects'.
Log a concise summary (such as the total number of objects added) at info level before writing the plugin result file; use verbose/debug for extra context.
Files:
front/plugins/nmap_scan/script.py
**/*.py
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
Use 'logger.mylog' for logging at levels: none, minimal, verbose, debug, or trace.
Files:
front/plugins/nmap_scan/script.pyfront/plugins/_publisher_pushsafer/pushsafer.pyserver/api_server/history_endpoint.pyserver/api.pyfront/plugins/sync/sync.pyserver/api_server/sync_endpoint.pyfront/plugins/_publisher_apprise/apprise.pytest/api_endpoints/test_sessions_endpoints.pyserver/__main__.pyfront/plugins/plugin_helper.pyserver/logger.pyserver/utils/datetime_utils.pyserver/app_state.pyserver/plugin.pyserver/messaging/in_app.pytest/api_endpoints/test_events_endpoints.pyserver/helper.pyfront/plugins/_publisher_email/email_smtp.pyserver/scan/device_handling.pyfront/plugins/_publisher_pushover/pushover.pyserver/initialise.py
server/api_server/*.py
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
When introducing new server functionality, add endpoints only within 'server/api_server/*' and keep authorization checks consistent.
Files:
server/api_server/history_endpoint.pyserver/api_server/sync_endpoint.py
test/**/*.py
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
Tests must reside under 'test/' and use pytest.
Files:
test/api_endpoints/test_sessions_endpoints.pytest/api_endpoints/test_events_endpoints.py
front/plugins/plugin_helper.py
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
Use 'Plugin_Objects' from 'front/plugins/plugin_helper.py' to sanitize text and normalize MAC addresses before writing results.
Files:
front/plugins/plugin_helper.py
server/helper.py
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
Use 'helper.py' ('timeNowTZ', 'normalize_mac', and sanitizers) for all time, MAC, and string operations; always validate MACs before database writes.
Files:
server/helper.py
server/initialise.py
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
Add or modify settings centrally via 'ccd()' in 'server/initialise.py' or via plugin manifest; never hardcode ports or secrets—always use 'get_setting_value()'.
Files:
server/initialise.py
🧠 Learnings (12)
📓 Common learnings
Learnt from: CR
Repo: jokob-sk/NetAlertX PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-10-21T01:40:24.597Z
Learning: Applies to server/helper.py : Use 'helper.py' ('timeNowTZ', 'normalize_mac', and sanitizers) for all time, MAC, and string operations; always validate MACs before database writes.
Learnt from: jokob-sk
Repo: jokob-sk/NetAlertX PR: 1271
File: server/helper.py:50-71
Timestamp: 2025-11-05T04:34:52.319Z
Learning: In the NetAlertX codebase, `timeNowDB` function is intentionally duplicated in both `server/helper.py` and `server/logger.py` to prevent circular import issues, since `helper.py` imports from `logger.py` (`from logger import mylog, logResult`). This duplication is by design.
Learnt from: CR
Repo: jokob-sk/NetAlertX PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-10-21T01:40:24.597Z
Learning: Applies to server/db/*.py : Prefer using functions from 'server/db/db_helper.py' (like 'get_table_json' and device condition helpers) over raw SQL for new database code.
📚 Learning: 2025-11-05T04:34:52.319Z
Learnt from: jokob-sk
Repo: jokob-sk/NetAlertX PR: 1271
File: server/helper.py:50-71
Timestamp: 2025-11-05T04:34:52.319Z
Learning: In the NetAlertX codebase, `timeNowDB` function is intentionally duplicated in both `server/helper.py` and `server/logger.py` to prevent circular import issues, since `helper.py` imports from `logger.py` (`from logger import mylog, logResult`). This duplication is by design.
Applied to files:
front/plugins/nmap_scan/script.pyfront/plugins/_publisher_pushsafer/pushsafer.pyserver/api.pyfront/plugins/sync/sync.pyserver/api_server/sync_endpoint.pyfront/plugins/_publisher_apprise/apprise.pyserver/__main__.pyfront/plugins/plugin_helper.pyserver/logger.pyserver/utils/datetime_utils.pyserver/app_state.pyserver/plugin.pyserver/messaging/in_app.pytest/api_endpoints/test_events_endpoints.pyserver/helper.pyfront/plugins/_publisher_email/email_smtp.pyserver/scan/device_handling.pyfront/plugins/_publisher_pushover/pushover.pyserver/initialise.py
📚 Learning: 2025-10-21T01:40:24.597Z
Learnt from: CR
Repo: jokob-sk/NetAlertX PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-10-21T01:40:24.597Z
Learning: Applies to front/plugins/*/script.py : Run plugin scripts as standalone executables with 'sys.path' configured for '/app/front/plugins' and '/app/server', following the provided template.
Applied to files:
server/api_server/history_endpoint.pytest/api_endpoints/test_events_endpoints.py
📚 Learning: 2025-10-21T01:40:24.597Z
Learnt from: CR
Repo: jokob-sk/NetAlertX PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-10-21T01:40:24.597Z
Learning: Applies to server/helper.py : Use 'helper.py' ('timeNowTZ', 'normalize_mac', and sanitizers) for all time, MAC, and string operations; always validate MACs before database writes.
Applied to files:
server/api.pyserver/__main__.py.github/copilot-instructions.mdserver/helper.pyserver/initialise.py
📚 Learning: 2025-10-21T01:40:24.597Z
Learnt from: CR
Repo: jokob-sk/NetAlertX PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-10-21T01:40:24.597Z
Learning: Applies to front/plugins/*/script.py : Log a concise summary (such as the total number of objects added) at info level before writing the plugin result file; use verbose/debug for extra context.
Applied to files:
front/plugins/sync/sync.py
📚 Learning: 2025-10-21T01:40:24.597Z
Learnt from: CR
Repo: jokob-sk/NetAlertX PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-10-21T01:40:24.597Z
Learning: Applies to server/initialise.py : Add or modify settings centrally via 'ccd()' in 'server/initialise.py' or via plugin manifest; never hardcode ports or secrets—always use 'get_setting_value()'.
Applied to files:
.github/copilot-instructions.md
📚 Learning: 2025-10-21T01:40:24.597Z
Learnt from: CR
Repo: jokob-sk/NetAlertX PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-10-21T01:40:24.597Z
Learning: Applies to server/db/*.py : Prefer using functions from 'server/db/db_helper.py' (like 'get_table_json' and device condition helpers) over raw SQL for new database code.
Applied to files:
.github/copilot-instructions.mdserver/helper.py
📚 Learning: 2025-10-21T01:40:24.597Z
Learnt from: CR
Repo: jokob-sk/NetAlertX PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-10-21T01:40:24.597Z
Learning: When exposing new core config, define it once using central helpers (core 'ccd()' or plugin manifest) and read it via helper functions throughout the codebase.
Applied to files:
.github/copilot-instructions.md
📚 Learning: 2025-10-21T01:40:24.597Z
Learnt from: CR
Repo: jokob-sk/NetAlertX PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-10-21T01:40:24.597Z
Learning: Applies to front/plugins/*/config.json : Add or modify plugin-specific settings only via the plugin manifest and reference via helpers, never hardcoding sensitive information.
Applied to files:
.github/copilot-instructions.md
📚 Learning: 2025-11-02T02:22:10.949Z
Learnt from: jokob-sk
Repo: jokob-sk/NetAlertX PR: 1261
File: server/app_state.py:106-115
Timestamp: 2025-11-02T02:22:10.949Z
Learning: In server/app_state.py, the pluginsStates parameter always contains complete plugin state objects with the structure: {"PLUGIN_NAME": {"lastChanged": "...", "totalObjects": N, "newObjects": N, "changedObjects": N}}. Type validation before calling .update() is not needed as the maintainer guarantees well-formed objects are always supplied.
Applied to files:
server/app_state.pyserver/plugin.py
📚 Learning: 2025-09-20T14:09:29.159Z
Learnt from: adamoutler
Repo: jokob-sk/NetAlertX PR: 1184
File: .devcontainer/scripts/setup.sh:103-116
Timestamp: 2025-09-20T14:09:29.159Z
Learning: In NetAlertX devcontainer setup, the netalertx user has write permissions to /var/log/nginx/ directory as it's explicitly chowned to netalertx:www-data in the Dockerfile, so setup.sh can write to nginx log files without sudo.
Applied to files:
server/helper.py
📚 Learning: 2025-09-15T19:45:46.725Z
Learnt from: ingoratsdorf
Repo: jokob-sk/NetAlertX PR: 1176
File: server/__main__.py:191-193
Timestamp: 2025-09-15T19:45:46.725Z
Learning: The method clearPluginObjects() in server/models/notification_instance.py should be renamed to clearPluginEvents() since it deletes from the Plugins_Events table, not a Plugins_Objects table. The method name should reflect the actual table being cleared.
Applied to files:
front/plugins/_publisher_pushover/pushover.py
🧬 Code graph analysis (20)
front/plugins/nmap_scan/script.py (2)
server/helper.py (1)
get_setting_value(210-265)server/utils/datetime_utils.py (1)
timeNowDB(43-63)
front/plugins/_publisher_pushsafer/pushsafer.py (2)
server/helper.py (2)
get_setting_value(210-265)hide_string(481-485)server/utils/datetime_utils.py (1)
timeNowDB(43-63)
server/api_server/history_endpoint.py (2)
server/helper.py (3)
is_random_mac(518-533)is_random_mac(561-572)get_setting_value(210-265)server/utils/datetime_utils.py (1)
format_date(110-119)
server/api.py (2)
server/helper.py (2)
write_file(116-137)get_setting_value(210-265)server/utils/datetime_utils.py (1)
timeNowTZ(28-32)
front/plugins/sync/sync.py (3)
server/helper.py (1)
get_setting_value(210-265)server/utils/datetime_utils.py (1)
timeNowDB(43-63)server/messaging/in_app.py (1)
write_notification(29-79)
server/api_server/sync_endpoint.py (3)
server/helper.py (1)
get_setting_value(210-265)server/utils/datetime_utils.py (1)
timeNowDB(43-63)server/messaging/in_app.py (1)
write_notification(29-79)
front/plugins/_publisher_apprise/apprise.py (2)
server/helper.py (1)
get_setting_value(210-265)server/utils/datetime_utils.py (1)
timeNowDB(43-63)
test/api_endpoints/test_sessions_endpoints.py (2)
server/helper.py (1)
get_setting_value(210-265)server/utils/datetime_utils.py (2)
timeNowTZ(28-32)timeNowDB(43-63)
server/__main__.py (2)
server/helper.py (2)
filePermissions(88-100)get_setting_value(210-265)server/utils/datetime_utils.py (1)
timeNowTZ(28-32)
front/plugins/plugin_helper.py (1)
server/utils/datetime_utils.py (1)
timeNowDB(43-63)
server/logger.py (1)
server/utils/datetime_utils.py (1)
timeNowTZ(28-32)
server/utils/datetime_utils.py (2)
front/js/common.js (1)
tz(375-375)server/helper.py (1)
get_setting_value(210-265)
server/app_state.py (1)
server/utils/datetime_utils.py (2)
timeNowDB(43-63)timeNow(34-35)
server/plugin.py (3)
server/helper.py (4)
get_file_content(107-113)write_file(116-137)get_setting(149-206)get_setting_value(210-265)server/utils/datetime_utils.py (2)
timeNowTZ(28-32)timeNowDB(43-63)server/messaging/in_app.py (1)
write_notification(29-79)
server/messaging/in_app.py (1)
server/utils/datetime_utils.py (1)
timeNowDB(43-63)
test/api_endpoints/test_events_endpoints.py (2)
server/helper.py (1)
get_setting_value(210-265)server/utils/datetime_utils.py (1)
timeNowTZ(28-32)
front/plugins/_publisher_email/email_smtp.py (2)
server/helper.py (2)
get_setting_value(210-265)hide_email(472-478)server/utils/datetime_utils.py (1)
timeNowDB(43-63)
server/scan/device_handling.py (2)
server/helper.py (2)
get_setting_value(210-265)check_IP_format(420-435)server/utils/datetime_utils.py (1)
timeNowDB(43-63)
front/plugins/_publisher_pushover/pushover.py (2)
server/helper.py (2)
get_setting_value(210-265)hide_string(481-485)server/utils/datetime_utils.py (1)
timeNowDB(43-63)
server/initialise.py (2)
server/utils/datetime_utils.py (1)
timeNowDB(43-63)server/messaging/in_app.py (1)
write_notification(29-79)
🪛 LanguageTool
docs/NOTIFICATIONS.md
[style] ~54-~54: Consider using a different adverb to strengthen your wording.
Context: ...IFICATIONS/NEWDEV_ignores.png) You can completely ignore detected devices globally. This ...
(COMPLETELY_ENTIRELY)
🪛 Ruff (0.14.3)
server/logger.py
17-17: from const import * used; unable to detect undefined names
(F403)
server/utils/datetime_utils.py
1-1: Shebang is present but file is not executable
(EXE001)
9-9: Redefinition of unused datetime from line 6
(F811)
21-21: from const import * used; unable to detect undefined names
(F403)
56-56: ZoneInfo may be undefined, or defined from star imports
(F405)
59-59: Do not catch blind exception: Exception
(BLE001)
118-118: Do not catch blind exception: Exception
(BLE001)
128-128: get_setting_value may be undefined, or defined from star imports
(F405)
136-136: email may be undefined, or defined from star imports
(F405)
137-137: Do not catch blind exception: Exception
(BLE001)
server/scan/device_handling.py
560-560: Do not catch blind exception: Exception
(BLE001)
front/plugins/_publisher_pushover/pushover.py
14-14: Unused noqa directive (non-enabled: E402)
Remove unused noqa directive
(RUF100)
server/initialise.py
396-396: f-string without any placeholders
Remove extraneous f prefix
(F541)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
- GitHub Check: docker_dev
🔇 Additional comments (32)
server/api.py (1)
10-11: LGTM! Import source updated correctly.The migration of
timeNowTZfromhelpertoutils.datetime_utilsaligns with the PR's centralization of datetime utilities..github/copilot-instructions.md (1)
45-45: LGTM! Documentation updated to reflect new utility.The guidance now correctly references
timeNowDBas the preferred time utility fromhelper.py.front/plugins/nmap_scan/script.py (2)
17-18: LGTM! Import updated correctly.The migration to
timeNowDBfromutils.datetime_utilsis appropriate for database timestamp generation.
162-162: LGTM! Timestamp source updated appropriately.Using
timeNowDB()here ensures the timestamp is in the correct ISO 8601 format for database storage.front/plugins/_publisher_email/email_smtp.py (2)
28-29: LGTM! Import migration completed correctly.The switch to
timeNowDBfromutils.datetime_utilsaligns with the centralization effort.
90-90: LGTM! Timestamp format updated for database storage.Using
timeNowDB()forsecondaryIdensures consistent ISO 8601 formatting for plugin logging.front/php/components/logs.php (2)
18-27: LGTM! Defensive file handling added.The addition of file existence and readability checks prevents errors and provides user-friendly feedback when files are missing or inaccessible.
31-31: LGTM! Download button guarded appropriately.The additional
file_exists($filePath)check prevents broken download links for missing files.server/plugin.py (3)
15-16: LGTM! Import migration completed correctly.The dual import of
timeNowTZandtimeNowDBis appropriate since the module uses both:timeNowDBfor database timestamps andtimeNowTZfor datetime objects (e.g., schedule tracking at Line 107).
225-225: LGTM! Consistent timestamp captured at function start.Capturing
now_str = timeNowDB()at the function start ensures allstateUpdatedfields use the same timestamp, which is appropriate for consistency.
763-763: LGTM! Simplified timestamp generation.Replacing
timeNowTZ().strftime(...)withtimeNowDB()is cleaner and ensures consistent formatting for database storage.front/plugins/plugin_helper.py (2)
15-15: LGTM! Import added for centralized time utility.The import of
timeNowDBfromutils.datetime_utilsaligns with the PR's datetime centralization effort.
208-208: LGTM! Timestamp generation simplified.Replacing
datetime.now().strftime("%Y-%m-%d %H:%M:%S")withtimeNowDB()is cleaner and ensures consistent formatting across the codebase.front/plugins/_publisher_pushsafer/pushsafer.py (1)
22-23: LGTM: Clean migration to timeNowDB.The import and usage updates correctly standardize on
timeNowDB()for logging timestamps, aligning with the broader PR refactor.Also applies to: 72-72
front/plugins/sync/sync.py (1)
21-22: LGTM: Consistent notification timestamp migration.All
write_notificationcalls now correctly usetimeNowDB()instead oftimeNowTZ(), ensuring consistent ISO 8601 timestamps across notification logging.Also applies to: 153-153, 259-259, 303-303, 312-312, 336-336, 344-344
front/plugins/_publisher_pushover/pushover.py (1)
14-15: LGTM: Timestamp migration correct.The switch from
timeNowTZ()totimeNowDB()is consistent with the PR's standardization effort.Also applies to: 67-67
front/plugins/_publisher_apprise/apprise.py (1)
19-20: LGTM: Standard migration pattern.The migration from
timeNowTZ()totimeNowDB()follows the same clean pattern as other publisher plugins.Also applies to: 69-69
server/scan/device_handling.py (2)
6-6: LGTM: Successful migration to timeNowDB.The import updates and
timeNowDB()usage forstartTimeandname_plugins_checkedcorrectly standardize timestamp generation across the module.Also applies to: 13-14, 60-60, 375-375, 677-677
533-577: Approve refactored timestamp normalization with better type safety.The refactored
update_devices_namesfunction now properly normalizes timestamps from multiple sources (strings, datetime objects) before comparison, addressing the type mismatch issues flagged in previous reviews. The logic correctly:
- Normalizes
last_checkedto datetime or None (lines 536-544)- Collects and validates plugin state timestamps (lines 546-572)
- Safely computes
latest_statewith fallback handling (lines 565-572)- Compares normalized datetime objects (line 576)
This ensures type-safe comparisons and prevents
TypeErrorexceptions.server/messaging/in_app.py (1)
23-24: LGTM: Default timestamp correctly updated.The migration updates the default timestamp parameter from
timeNowTZ()totimeNowDB(), ensuring consistent ISO 8601 format for notification timestamps.Also applies to: 43-43
test/api_endpoints/test_events_endpoints.py (1)
13-14: LGTM: Import path correctly updated.The import of
timeNowTZhas been correctly moved fromhelpertoutils.datetime_utils, maintaining the same functionality while aligning with the new module structure.server/__main__.py (1)
29-30: LGTM: Import path migration correct.The import of
timeNowTZhas been properly relocated fromhelpertoutils.datetime_utils, maintaining the same functionality while supporting the new module structure.server/api_server/history_endpoint.py (1)
17-18: LGTM: Clean refactor to centralized datetime utilities.The import restructure correctly moves
format_dateto the newserver/utils/datetime_utilsmodule, aligning with the PR's objective to consolidate datetime handling.test/api_endpoints/test_sessions_endpoints.py (1)
13-14: LGTM: Correct migration to centralized datetime utilities.The imports correctly source
timeNowTZandtimeNowDBfromutils.datetime_utils, with appropriate usage throughout:timeNowDB()for database timestamp fields andtimeNowTZ()for datetime object calculations.server/initialise.py (1)
15-16: LGTM: Timestamp refactor correctly applied.The import and usage updates properly migrate to
timeNowDB()from the centralizedutils.datetime_utilsmodule for notification timestamps.server/app_state.py (1)
7-8: LGTM: Correct datetime utilities migration.The imports correctly source time functions from
utils.datetime_utils, with appropriate usage:timeNowDB()for ISO timestamp strings andtimeNow().timestamp()for numeric timestamps.docs/NOTIFICATIONS.md (1)
50-64: LGTM: Clear documentation improvements.The restructure separates "Ignoring devices" (preventing device detection) from "Ignoring notifications" (filtering notification output), improving clarity for users configuring the system.
server/logger.py (1)
8-18: LGTM: Proper migration to centralized datetime utilities.The updates correctly import
timeNowTZfrom the newutils.datetime_utilsmodule, eliminating the local duplicate definition. TheZoneInfoimport and sys.path setup properly support the datetime utilities infrastructure.server/api_server/sync_endpoint.py (1)
5-6: LGTM: Consistent timestamp refactor.The migration to
timeNowDB()fromutils.datetime_utilscorrectly provides ISO-formatted timestamp strings for notifications and API responses.server/helper.py (3)
245-247: LGTM: Improved caching for settings retrieval.Adding the secondary cache update when sourcing from
conf.mySettingsimproves performance by caching values from both retrieval paths (in-memory settings and JSON file).
250-250: LGTM: Typo correction.Fixed spelling error in comment: "retrive" → "retrieve".
333-334: LGTM: Enhanced array transformer handling.The unconditional transformer application to array entries (particularly base64 decoding) correctly handles encoded array values. The
reverseTransformersfunction properly maps the transformation over list items.
server/utils/datetime_utils.py
Outdated
| from datetime import datetime | ||
| import pytz | ||
| from pytz import timezone | ||
| import datetime |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Remove duplicate datetime import.
Line 6 imports datetime from the datetime module, and Line 9 imports the datetime module itself. The duplicate on Line 9 shadows the earlier import.
Apply this diff to remove the duplicate:
from datetime import datetime
import pytz
from pytz import timezone, all_timezones, UnknownTimeZoneError
-import datetime
from typing import UnionCommittable suggestion skipped: line range outside the PR's diff.
🧰 Tools
🪛 Ruff (0.14.3)
9-9: Redefinition of unused datetime from line 6
(F811)
🤖 Prompt for AI Agents
In server/utils/datetime_utils.py around lines 6 to 9, there's a duplicate
import: you already have "from datetime import datetime" on line 6 and later
"import datetime" on line 9 which shadows the earlier name; remove the redundant
"import datetime" line (or replace with explicit aliases only if you need both
module and class) so only the correct import(s) remain and adjust any code that
relied on the module import to use the imported class or an alias.
| INSTALL_PATH="/app" | ||
|
|
||
| import conf | ||
| from const import * |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion | 🟠 Major
Replace wildcard import with explicit imports.
The wildcard import from const import * makes it unclear what symbols are being used and can lead to naming conflicts.
Determine which symbols from const are actually needed (likely none based on the code) and import them explicitly. If no imports are needed, remove this line entirely:
-from const import *📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| from const import * |
🧰 Tools
🪛 Ruff (0.14.3)
21-21: from const import * used; unable to detect undefined names
(F403)
🤖 Prompt for AI Agents
In server/utils/datetime_utils.py around line 21, the file uses a wildcard
import "from const import *" which obscures used symbols and risks name
collisions; inspect the module to identify the specific constants or symbols
actually referenced (or determine that none are used) and replace the wildcard
with an explicit import of only those names, or remove the import line entirely
if nothing from const is required.
server/utils/datetime_utils.py
Outdated
| if local: | ||
| try: | ||
| if isinstance(conf.tz, datetime.tzinfo): | ||
| tz = conf.tz | ||
| elif conf.tz: | ||
| tz = ZoneInfo(conf.tz) | ||
| else: | ||
| tz = None | ||
| except Exception: | ||
| tz = None | ||
| return datetime.datetime.now(tz).strftime('%Y-%m-%d %H:%M:%S') | ||
| else: | ||
| return datetime.datetime.now(datetime.UTC).strftime('%Y-%m-%d %H:%M:%S') |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Add missing ZoneInfo import and handle exception more specifically.
Line 56 uses ZoneInfo without importing it. Also, the bare Exception catch on Line 59 is too broad.
Apply this diff to add the import and improve exception handling:
+from zoneinfo import ZoneInfo
+
import conf
-from const import *
#-------------------------------------------------------------------------------
# DateTime
#-------------------------------------------------------------------------------Then update the exception handling:
if local:
try:
if isinstance(conf.tz, datetime.tzinfo):
tz = conf.tz
elif conf.tz:
tz = ZoneInfo(conf.tz)
else:
tz = None
- except Exception:
+ except (KeyError, ValueError, TypeError):
tz = NoneCommittable suggestion skipped: line range outside the PR's diff.
🧰 Tools
🪛 Ruff (0.14.3)
56-56: ZoneInfo may be undefined, or defined from star imports
(F405)
59-59: Do not catch blind exception: Exception
(BLE001)
🤖 Prompt for AI Agents
In server/utils/datetime_utils.py around lines 51 to 63, add an import for
ZoneInfo from the zoneinfo module at the top of the file and replace the bare
"except Exception:" with a targeted exception handler (catch
zoneinfo.ZoneInfoNotFoundError and ValueError) when constructing
ZoneInfo(conf.tz); if those exceptions occur set tz = None. Ensure you import
ZoneInfo like "from zoneinfo import ZoneInfo" and only catch the specific errors
that can be raised by ZoneInfo creation rather than a broad Exception.
Signed-off-by: jokob-sk <jokob.sk@gmail.com>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
♻️ Duplicate comments (3)
server/utils/datetime_utils.py (3)
19-19: Replace wildcard import with explicit imports.The wildcard import obscures which symbols from
constare actually used and can cause naming conflicts.Based on learnings.
Inspect the code to determine which symbols from
constare needed, then replace with explicit imports:-from const import * +# Add explicit imports if needed, e.g.: +# from const import SYMBOL_NAMEIf no symbols from
constare used in this module, remove the import entirely.
49-58: Handle timezone exceptions more specifically.The bare
Exceptioncatch is too broad and may hide unexpected errors when constructingZoneInfo.Apply this diff to catch only the specific exceptions that
ZoneInfocan raise:try: if isinstance(conf.tz, datetime.tzinfo): tz = conf.tz elif conf.tz: tz = ZoneInfo(conf.tz) else: tz = None - except Exception: + except (KeyError, ValueError, TypeError): tz = None
6-7: Resolve conflictingdatetimeimports.Line 6 imports the
datetimeclass, and Line 7 imports thedatetimemodule, causing the module import to shadow the class. Since the code uses bothdatetime.datetime.now()(requiring the module) and potentially direct class references, you should import both explicitly with an alias to avoid ambiguity.Apply this diff:
-from datetime import datetime -import datetime +import datetime +from datetime import datetime as dt_classThen update code that uses the bare class name (e.g., Line 51's
datetime.tzinfo) to usedatetime.tzinfo, which is now unambiguous.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (2)
server/api_server/sessions_endpoint.py(4 hunks)server/utils/datetime_utils.py(1 hunks)
🧰 Additional context used
📓 Path-based instructions (2)
server/api_server/*.py
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
When introducing new server functionality, add endpoints only within 'server/api_server/*' and keep authorization checks consistent.
Files:
server/api_server/sessions_endpoint.py
**/*.py
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
Use 'logger.mylog' for logging at levels: none, minimal, verbose, debug, or trace.
Files:
server/api_server/sessions_endpoint.pyserver/utils/datetime_utils.py
🧠 Learnings (3)
📓 Common learnings
Learnt from: CR
Repo: jokob-sk/NetAlertX PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-10-21T01:40:24.597Z
Learning: Applies to server/helper.py : Use 'helper.py' ('timeNowTZ', 'normalize_mac', and sanitizers) for all time, MAC, and string operations; always validate MACs before database writes.
Learnt from: CR
Repo: jokob-sk/NetAlertX PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-10-21T01:40:24.597Z
Learning: Applies to server/db/*.py : Prefer using functions from 'server/db/db_helper.py' (like 'get_table_json' and device condition helpers) over raw SQL for new database code.
Learnt from: jokob-sk
Repo: jokob-sk/NetAlertX PR: 1271
File: server/helper.py:50-71
Timestamp: 2025-11-05T04:34:52.319Z
Learning: In the NetAlertX codebase, `timeNowDB` function is intentionally duplicated in both `server/helper.py` and `server/logger.py` to prevent circular import issues, since `helper.py` imports from `logger.py` (`from logger import mylog, logResult`). This duplication is by design.
Learnt from: CR
Repo: jokob-sk/NetAlertX PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-10-21T01:40:24.597Z
Learning: Applies to server/database.py : Leverage helpers in 'server/database.py' and 'server/db/*' for persistent state with SQLite.
📚 Learning: 2025-10-21T01:40:24.597Z
Learnt from: CR
Repo: jokob-sk/NetAlertX PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-10-21T01:40:24.597Z
Learning: Applies to front/plugins/*/script.py : Run plugin scripts as standalone executables with 'sys.path' configured for '/app/front/plugins' and '/app/server', following the provided template.
Applied to files:
server/api_server/sessions_endpoint.py
📚 Learning: 2025-11-05T04:34:52.319Z
Learnt from: jokob-sk
Repo: jokob-sk/NetAlertX PR: 1271
File: server/helper.py:50-71
Timestamp: 2025-11-05T04:34:52.319Z
Learning: In the NetAlertX codebase, `timeNowDB` function is intentionally duplicated in both `server/helper.py` and `server/logger.py` to prevent circular import issues, since `helper.py` imports from `logger.py` (`from logger import mylog, logResult`). This duplication is by design.
Applied to files:
server/utils/datetime_utils.py
🧬 Code graph analysis (2)
server/api_server/sessions_endpoint.py (4)
server/helper.py (4)
is_random_mac(518-533)is_random_mac(561-572)get_setting_value(210-265)format_ip_long(583-594)server/logger.py (1)
mylog(84-90)server/db/db_helper.py (2)
row_to_json(47-72)get_date_from_period(97-117)server/utils/datetime_utils.py (5)
format_date_iso(69-74)format_event_date(77-84)format_date_diff(119-159)parse_datetime(95-106)format_date(108-117)
server/utils/datetime_utils.py (1)
front/js/common.js (1)
tz(375-375)
🪛 Ruff (0.14.3)
server/api_server/sessions_endpoint.py
354-354: Undefined name tz_name
(F821)
358-358: Undefined name tz_name
(F821)
server/utils/datetime_utils.py
1-1: Shebang is present but file is not executable
(EXE001)
7-7: Redefinition of unused datetime from line 6
(F811)
19-19: from const import * used; unable to detect undefined names
(F403)
57-57: Do not catch blind exception: Exception
(BLE001)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
- GitHub Check: docker_dev
🔇 Additional comments (4)
server/utils/datetime_utils.py (2)
108-117: Good exception handling improvements.The specific exception types
(ValueError, AttributeError, TypeError)are appropriate for parsing errors and provide better error visibility than a bareexcept Exception.
128-143: Good timezone-aware parsing with specific exception handling.The fallback from RFC1123 to ISO format with specific exception handling (
ValueError, TypeError) and timezone normalization is well-implemented.server/api_server/sessions_endpoint.py (2)
19-21: Good refactoring to use centralized datetime utilities.The import changes properly consolidate datetime formatting helpers into the
utils.datetime_utilsmodule, aligning with the PR objective to centralize datetime handling.
211-211: Correct timezone-aware duration calculations inget_device_sessions.The
tz_nameretrieval from settings and its usage informat_date_diffcalls ensures timezone-aware duration formatting.Also applies to: 234-236
Signed-off-by: jokob-sk <jokob.sk@gmail.com>
Signed-off-by: jokob-sk <jokob.sk@gmail.com>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
♻️ Duplicate comments (3)
server/utils/datetime_utils.py (3)
57-57: Use specific exception types instead of bare Exception.Line 57 catches a bare
Exceptionwhich can hide unexpected errors. When constructingZoneInfo(conf.tz), the specific exceptions that can be raised should be caught.Apply this diff:
try: if isinstance(conf.tz, datetime.tzinfo): tz = conf.tz elif conf.tz: tz = ZoneInfo(conf.tz) else: tz = None - except Exception: + except (KeyError, ValueError, TypeError): tz = None
19-19: Replace wildcard import with explicit imports.The wildcard import
from const import *obscures which symbols are being used and can cause naming conflicts.Determine which symbols from
constare actually used in this file and import them explicitly:-from const import * +# Import specific symbols from const if needed, or remove if unusedBased on the code, it appears no symbols from
constare directly referenced in this file, so this import may be unnecessary and should be removed.
6-7: Remove duplicate datetime import.Line 7 imports the
datetimemodule, but line 6 already importsdatetimefrom thedatetimemodule. This creates a naming conflict where the module import shadows the class import.Apply this diff:
from datetime import datetime import datetime import pytzSince line 6 imports the
datetimeclass, either:
- Remove line 7 if only the
datetimeclass is needed, OR- Use
import datetime as dtif both module and class are neededBased on the code usage (e.g.,
datetime.datetime.now(),datetime.tzinfo,datetime.UTC), you need the module. Update to:-from datetime import datetime -import datetime +import datetime
🧹 Nitpick comments (2)
server/scan/device_handling.py (1)
563-563: Use idiomatic Python comparisons.Lines 563, 569, and 592 use non-idiomatic comparisons that should be updated per PEP 8:
- Lines 563, 569: Use
is Noneinstead of== None- Line 592: Use
not check_plugin_data_changed(...)instead of== FalseApply this diff:
- if last_changed_ts == None: + if last_changed_ts is None: mylog('none', f'[check_plugin_data_changed] Unexpected last_data_change timestamp for {plugin_name}: {last_data_change}') - if last_data_check_ts == None: + if last_data_check_ts is None: mylog('none', f'[check_plugin_data_changed] Unexpected last_data_check timestamp for {plugin_name}: {last_data_check}')- if check_plugin_data_changed(pm, ["DIGSCAN", "NSLOOKUP", "NBTSCAN", "AVAHISCAN"]) == False: + if not check_plugin_data_changed(pm, ["DIGSCAN", "NSLOOKUP", "NBTSCAN", "AVAHISCAN"]): mylog('debug', '[Update Device Name] No relevant plugin changes since last check.') returnAlso applies to: 569-569, 592-592
docs/PLUGINS_DEV_CONFIG.md (1)
17-19: Add language specification to fenced code block.The code block on line 17 should specify a language identifier for proper syntax highlighting and rendering.
Apply this diff:
-``` +```log ================ CurrentScan table content ================</blockquote></details> </blockquote></details> <details> <summary>📜 Review details</summary> **Configuration used**: CodeRabbit UI **Review profile**: CHILL **Plan**: Pro <details> <summary>📥 Commits</summary> Reviewing files that changed from the base of the PR and between cbe5a4a7327c0b96bfdd2ea9de9f678f96f59a2a and 552d2a82869b7f7c777d76c73e70b20b44a867d7. </details> <details> <summary>📒 Files selected for processing (4)</summary> * `docs/PLUGINS_DEV_CONFIG.md` (1 hunks) * `server/plugin.py` (11 hunks) * `server/scan/device_handling.py` (5 hunks) * `server/utils/datetime_utils.py` (1 hunks) </details> <details> <summary>🧰 Additional context used</summary> <details> <summary>📓 Path-based instructions (1)</summary> <details> <summary>**/*.py</summary> **📄 CodeRabbit inference engine (.github/copilot-instructions.md)** > Use 'logger.mylog' for logging at levels: none, minimal, verbose, debug, or trace. Files: - `server/scan/device_handling.py` - `server/plugin.py` - `server/utils/datetime_utils.py` </details> </details><details> <summary>🧠 Learnings (7)</summary> <details> <summary>📓 Common learnings</summary>Learnt from: CR
Repo: jokob-sk/NetAlertX PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-10-21T01:40:24.597Z
Learning: Applies to server/helper.py : Use 'helper.py' ('timeNowTZ', 'normalize_mac', and sanitizers) for all time, MAC, and string operations; always validate MACs before database writes.Learnt from: jokob-sk
Repo: jokob-sk/NetAlertX PR: 1271
File: server/helper.py:50-71
Timestamp: 2025-11-05T04:34:52.339Z
Learning: In the NetAlertX codebase,timeNowDBfunction is intentionally duplicated in bothserver/helper.pyandserver/logger.pyto prevent circular import issues, sincehelper.pyimports fromlogger.py(from logger import mylog, logResult). This duplication is by design.</details> <details> <summary>📚 Learning: 2025-11-05T04:34:52.339Z</summary>Learnt from: jokob-sk
Repo: jokob-sk/NetAlertX PR: 1271
File: server/helper.py:50-71
Timestamp: 2025-11-05T04:34:52.339Z
Learning: In the NetAlertX codebase,timeNowDBfunction is intentionally duplicated in bothserver/helper.pyandserver/logger.pyto prevent circular import issues, sincehelper.pyimports fromlogger.py(from logger import mylog, logResult). This duplication is by design.**Applied to files:** - `server/scan/device_handling.py` - `server/plugin.py` - `server/utils/datetime_utils.py` </details> <details> <summary>📚 Learning: 2025-10-21T01:40:24.597Z</summary>Learnt from: CR
Repo: jokob-sk/NetAlertX PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-10-21T01:40:24.597Z
Learning: Applies to front/plugins/*/config.json : Add or modify plugin-specific settings only via the plugin manifest and reference via helpers, never hardcoding sensitive information.**Applied to files:** - `docs/PLUGINS_DEV_CONFIG.md` </details> <details> <summary>📚 Learning: 2025-10-21T01:40:24.597Z</summary>Learnt from: CR
Repo: jokob-sk/NetAlertX PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-10-21T01:40:24.597Z
Learning: Applies to front/plugins/*/config.json : Ensure each plugin manifest resides at 'front/plugins/<code_name>/config.json', with '<code_name>' matching the folder, and settings filenames driven by 'unique_prefix'.**Applied to files:** - `docs/PLUGINS_DEV_CONFIG.md` </details> <details> <summary>📚 Learning: 2025-10-21T01:40:24.597Z</summary>Learnt from: CR
Repo: jokob-sk/NetAlertX PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-10-21T01:40:24.597Z
Learning: When adding a plugin, start from the provided template in 'front/plugins/__template', implement with 'plugin_helper', define all required manifest settings, and wire execution via '_RUN'.**Applied to files:** - `docs/PLUGINS_DEV_CONFIG.md` </details> <details> <summary>📚 Learning: 2025-11-02T02:22:10.968Z</summary>Learnt from: jokob-sk
Repo: jokob-sk/NetAlertX PR: 1261
File: server/app_state.py:106-115
Timestamp: 2025-11-02T02:22:10.968Z
Learning: In server/app_state.py, the pluginsStates parameter always contains complete plugin state objects with the structure: {"PLUGIN_NAME": {"lastChanged": "...", "totalObjects": N, "newObjects": N, "changedObjects": N}}. Type validation before calling .update() is not needed as the maintainer guarantees well-formed objects are always supplied.**Applied to files:** - `server/plugin.py` </details> <details> <summary>📚 Learning: 2025-10-21T01:40:24.597Z</summary>Learnt from: CR
Repo: jokob-sk/NetAlertX PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-10-21T01:40:24.597Z
Learning: Applies to server/helper.py : Use 'helper.py' ('timeNowTZ', 'normalize_mac', and sanitizers) for all time, MAC, and string operations; always validate MACs before database writes.**Applied to files:** - `server/utils/datetime_utils.py` </details> </details><details> <summary>🧬 Code graph analysis (3)</summary> <details> <summary>server/scan/device_handling.py (5)</summary><blockquote> <details> <summary>server/helper.py (2)</summary> * `get_setting_value` (210-265) * `check_IP_format` (420-435) </details> <details> <summary>server/utils/datetime_utils.py (2)</summary> * `timeNowDB` (41-61) * `normalizeTimeStamp` (68-105) </details> <details> <summary>server/logger.py (1)</summary> * `mylog` (84-90) </details> <details> <summary>server/scan/name_resolution.py (1)</summary> * `NameResolver` (24-84) </details> <details> <summary>server/models/device_instance.py (1)</summary> * `DeviceInstance` (12-84) </details> </blockquote></details> <details> <summary>server/plugin.py (2)</summary><blockquote> <details> <summary>server/utils/datetime_utils.py (2)</summary> * `timeNowTZ` (26-30) * `timeNowDB` (41-61) </details> <details> <summary>server/messaging/in_app.py (1)</summary> * `write_notification` (29-79) </details> </blockquote></details> <details> <summary>server/utils/datetime_utils.py (1)</summary><blockquote> <details> <summary>front/js/common.js (1)</summary> * `tz` (375-375) </details> </blockquote></details> </details><details> <summary>🪛 markdownlint-cli2 (0.18.1)</summary> <details> <summary>docs/PLUGINS_DEV_CONFIG.md</summary> 17-17: Fenced code blocks should have a language specified (MD040, fenced-code-language) --- 184-184: Emphasis used instead of a heading (MD036, no-emphasis-as-heading) </details> </details> <details> <summary>🪛 Ruff (0.14.3)</summary> <details> <summary>server/scan/device_handling.py</summary> 563-563: Comparison to `None` should be `cond is None` Replace with `cond is None` (E711) --- 569-569: Comparison to `None` should be `cond is None` Replace with `cond is None` (E711) --- 592-592: Avoid equality comparisons to `False`; use `not ...:` for false checks Replace comparison (E712) </details> <details> <summary>server/utils/datetime_utils.py</summary> 1-1: Shebang is present but file is not executable (EXE001) --- 7-7: Redefinition of unused `datetime` from line 6 (F811) --- 19-19: `from const import *` used; unable to detect undefined names (F403) --- 57-57: Do not catch blind exception: `Exception` (BLE001) --- 100-100: `parser` may be undefined, or defined from star imports (F405) --- 101-101: Do not catch blind exception: `Exception` (BLE001) </details> </details> </details> <details> <summary>⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)</summary> * GitHub Check: docker_dev </details> <details> <summary>🔇 Additional comments (7)</summary><blockquote> <details> <summary>server/scan/device_handling.py (2)</summary><blockquote> `6-6`: **LGTM! Consistent time source migration.** The migration from `timeNowTZ()` to `timeNowDB()` for database timestamps is well-executed and aligns with the PR's centralization of datetime utilities. The imports are clean and the usage is consistent. Also applies to: 14-14, 60-60, 375-375 --- `589-700`: **Well-structured plugin change detection and name resolution flow.** The integration of `check_plugin_data_changed` provides an efficient early-return optimization. The multi-strategy name resolution with structured logging and plugin timestamp tracking (line 699) is well-implemented. </blockquote></details> <details> <summary>docs/PLUGINS_DEV_CONFIG.md (1)</summary><blockquote> `1-191`: **Excellent documentation updates.** The restructured plugin lifecycle documentation with clear flow descriptions, updated terminology (lastDataChange, Plugin Interface Contract), and well-organized plugin categories significantly improves clarity for plugin developers. </blockquote></details> <details> <summary>server/utils/datetime_utils.py (1)</summary><blockquote> `26-62`: **Well-designed centralized datetime utilities.** The new `timeNowDB()`, `timeNowTZ()`, and `normalizeTimeStamp()` functions provide a clean, centralized approach to time handling with proper timezone support. The documentation is clear, and the fallback behavior for missing timezone configuration is appropriate. </blockquote></details> <details> <summary>server/plugin.py (3)</summary><blockquote> `15-16`: **Clean datetime utility migration and improved naming.** The import of `timeNowTZ` and `timeNowDB` from the centralized `utils.datetime_utils` module is well-executed. The rename from `name_plugins_checked` to `plugin_checks` (line 31) provides clearer semantics for general plugin check tracking. Also applies to: 31-31 --- `158-158`: **Consistent use of timeNowDB() for database operations.** All database timestamp operations now use `timeNowDB()` instead of `timeNowTZ()`, ensuring consistent ISO 8601 formatted timestamps suitable for database storage. This aligns with the PR's centralization objectives. Also applies to: 167-167, 181-181, 190-190, 225-225, 763-763 --- `216-216`: **Schema change: lastChanged → lastDataChange.** The rename from `lastChanged` to `lastDataChange` in the plugin state structure provides clearer semantics, distinguishing data change timestamps from other state changes. This is a beneficial API improvement. Also applies to: 241-241, 264-264 </blockquote></details> </blockquote></details> </details> <!-- This is an auto-generated comment by CodeRabbit for review status -->
Signed-off-by: jokob-sk <jokob.sk@gmail.com>
Signed-off-by: jokob-sk <jokob.sk@gmail.com>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 0
♻️ Duplicate comments (4)
server/utils/datetime_utils.py (4)
6-8: Remove unused datetime class import.Line 6 imports the
datetimeclass, but line 8 immediately shadows it by importing thedatetimemodule. Since the code exclusively usesdatetime.datetime.now(),datetime.datetime.fromisoformat(), etc. (requiring the module), line 6 serves no purpose.Apply this diff:
-from datetime import datetime from dateutil import parser import datetime
21-21: Remove unused wildcard import.The wildcard import
from const import *obscures which symbols are imported and can cause naming conflicts. A review of this file shows no usage of symbols fromconst.Apply this diff:
import conf -from const import *
47-68: Replace bare exception with specific exception types.Line 63 catches
Exceptiontoo broadly. When constructingZoneInfo(conf.tz), the specific exceptions that can occur areKeyError(includingZoneInfoNotFoundError) andTypeError.Apply this diff:
if local: try: if isinstance(conf.tz, datetime.tzinfo): tz = conf.tz elif conf.tz: tz = ZoneInfo(conf.tz) else: tz = None - except Exception: + except (KeyError, TypeError): tz = None
100-117: Replace bare exception with specific exception types.Line 113 catches
Exceptiontoo broadly. Theparser.parse()call can raiseValueError,TypeError, ordateutil.parser.ParserError. Catching specific exceptions makes error handling more precise and prevents masking unexpected errors.Apply this diff:
+from dateutil.parser import ParserError + try: # match the "2025-11-08 14:32:10" format pattern = DATETIME_REGEX if pattern.match(inputTimeStamp): return datetime.datetime.strptime(inputTimeStamp, DATETIME_PATTERN) else: # Handles SQLite and ISO8601 automatically return parser.parse(inputTimeStamp) - except Exception: + except (ValueError, TypeError, ParserError): return None
🧹 Nitpick comments (2)
server/scan/device_handling.py (2)
563-570: Useis Nonefor None comparisons.Lines 563 and 569 use
== Nonewhich is not idiomatic Python. Line 573 in the same function correctly usesis None, making this inconsistent. SinceNoneis a singleton, identity checks withisare preferred.Apply this diff:
- if last_changed_ts == None: + if last_changed_ts is None: mylog('none', f'[check_plugin_data_changed] Unexpected last_data_change timestamp for {plugin_name} (input|output): ({last_data_change}|{last_changed_ts})') # Normalize and validate last_data_check timestamp last_data_check_ts = normalizeTimeStamp(last_data_check) - if last_data_check_ts == None: + if last_data_check_ts is None: mylog('none', f'[check_plugin_data_changed] Unexpected last_data_check timestamp for {plugin_name} (input|output): ({last_data_check}|{last_data_check_ts})')
589-594: Usenotinstead of== Falsefor boolean checks.Line 592 compares a boolean return value with
== False, which is not idiomatic Python. The preferred approach is to use thenotoperator directly.Apply this diff:
def update_devices_names(pm): # --- Short-circuit if no name-resolution plugin has changed --- - if check_plugin_data_changed(pm, ["DIGSCAN", "NSLOOKUP", "NBTSCAN", "AVAHISCAN"]) == False: + if not check_plugin_data_changed(pm, ["DIGSCAN", "NSLOOKUP", "NBTSCAN", "AVAHISCAN"]): mylog('debug', '[Update Device Name] No relevant plugin changes since last check.') return
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (2)
server/scan/device_handling.py(5 hunks)server/utils/datetime_utils.py(1 hunks)
🧰 Additional context used
📓 Path-based instructions (1)
**/*.py
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
Use 'logger.mylog' for logging at levels: none, minimal, verbose, debug, or trace.
Files:
server/scan/device_handling.pyserver/utils/datetime_utils.py
🧠 Learnings (3)
📓 Common learnings
Learnt from: CR
Repo: jokob-sk/NetAlertX PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-10-21T01:40:24.597Z
Learning: Applies to server/helper.py : Use 'helper.py' ('timeNowTZ', 'normalize_mac', and sanitizers) for all time, MAC, and string operations; always validate MACs before database writes.
📚 Learning: 2025-11-05T04:34:52.339Z
Learnt from: jokob-sk
Repo: jokob-sk/NetAlertX PR: 1271
File: server/helper.py:50-71
Timestamp: 2025-11-05T04:34:52.339Z
Learning: In the NetAlertX codebase, `timeNowDB` function is intentionally duplicated in both `server/helper.py` and `server/logger.py` to prevent circular import issues, since `helper.py` imports from `logger.py` (`from logger import mylog, logResult`). This duplication is by design.
Applied to files:
server/scan/device_handling.pyserver/utils/datetime_utils.py
📚 Learning: 2025-10-21T01:40:24.597Z
Learnt from: CR
Repo: jokob-sk/NetAlertX PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-10-21T01:40:24.597Z
Learning: Applies to server/helper.py : Use 'helper.py' ('timeNowTZ', 'normalize_mac', and sanitizers) for all time, MAC, and string operations; always validate MACs before database writes.
Applied to files:
server/utils/datetime_utils.py
🧬 Code graph analysis (2)
server/scan/device_handling.py (5)
server/helper.py (2)
get_setting_value(210-265)check_IP_format(420-435)server/utils/datetime_utils.py (2)
timeNowDB(47-67)normalizeTimeStamp(74-117)server/logger.py (1)
mylog(84-90)server/scan/name_resolution.py (1)
NameResolver(24-84)server/models/device_instance.py (1)
DeviceInstance(12-84)
server/utils/datetime_utils.py (1)
front/js/common.js (2)
tz(375-375)match(390-390)
🪛 Ruff (0.14.3)
server/scan/device_handling.py
563-563: Comparison to None should be cond is None
Replace with cond is None
(E711)
569-569: Comparison to None should be cond is None
Replace with cond is None
(E711)
592-592: Avoid equality comparisons to False; use not ...: for false checks
Replace comparison
(E712)
server/utils/datetime_utils.py
1-1: Shebang is present but file is not executable
(EXE001)
8-8: Redefinition of unused datetime from line 6
(F811)
21-21: from const import * used; unable to detect undefined names
(F403)
63-63: Do not catch blind exception: Exception
(BLE001)
113-113: Do not catch blind exception: Exception
(BLE001)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
- GitHub Check: docker_dev
Signed-off-by: jokob-sk <jokob.sk@gmail.com>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 0
🧹 Nitpick comments (1)
front/plugins/nmap_dev_scan/nmap_dev.py (1)
11-12: Remove unused imports as part of this cleanup PR.The following imports are not used anywhere in the code and should be removed:
csv(line 11)sqlite3(line 12)datetime(line 16)DB(line 26)DeviceInstance(line 27)Since this PR focuses on refactoring and cleanup, removing these unused imports would improve code clarity.
Apply this diff to remove the unused imports:
-import csv -import sqlite3 import re import nmap from io import StringIO -from datetime import datetime # Register NetAlertX directories INSTALL_PATH="/app" sys.path.extend([f"{INSTALL_PATH}/front/plugins", f"{INSTALL_PATH}/server"]) from plugin_helper import Plugin_Object, Plugin_Objects, decodeBase64 from logger import mylog, Logger, append_line_to_file from helper import get_setting_value, extract_between_strings, extract_ip_addresses, extract_mac_addresses from const import logPath, applicationPath, fullDbPath -from database import DB -from models.device_instance import DeviceInstance import conf from pytz import timezoneAlso applies to: 16-16, 26-27
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (5)
.github/workflows/docker_dev.yml(3 hunks).github/workflows/docker_prod.yml(2 hunks).github/workflows/docker_rewrite.yml(1 hunks)front/plugins/_publisher_mqtt/mqtt.py(2 hunks)front/plugins/nmap_dev_scan/nmap_dev.py(1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
- front/plugins/_publisher_mqtt/mqtt.py
🧰 Additional context used
📓 Path-based instructions (1)
**/*.py
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
Use 'logger.mylog' for logging at levels: none, minimal, verbose, debug, or trace.
Files:
front/plugins/nmap_dev_scan/nmap_dev.py
🧠 Learnings (5)
📓 Common learnings
Learnt from: CR
Repo: jokob-sk/NetAlertX PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-10-21T01:40:24.597Z
Learning: Applies to server/helper.py : Use 'helper.py' ('timeNowTZ', 'normalize_mac', and sanitizers) for all time, MAC, and string operations; always validate MACs before database writes.
📚 Learning: 2025-11-05T04:34:52.339Z
Learnt from: jokob-sk
Repo: jokob-sk/NetAlertX PR: 1271
File: server/helper.py:50-71
Timestamp: 2025-11-05T04:34:52.339Z
Learning: In the NetAlertX codebase, `timeNowDB` function is intentionally duplicated in both `server/helper.py` and `server/logger.py` to prevent circular import issues, since `helper.py` imports from `logger.py` (`from logger import mylog, logResult`). This duplication is by design.
Applied to files:
front/plugins/nmap_dev_scan/nmap_dev.py
📚 Learning: 2025-10-21T01:40:24.597Z
Learnt from: CR
Repo: jokob-sk/NetAlertX PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-10-21T01:40:24.597Z
Learning: Applies to front/plugins/plugin_helper.py : Use 'Plugin_Objects' from 'front/plugins/plugin_helper.py' to sanitize text and normalize MAC addresses before writing results.
Applied to files:
front/plugins/nmap_dev_scan/nmap_dev.py
📚 Learning: 2025-09-20T03:01:19.912Z
Learnt from: adamoutler
Repo: jokob-sk/NetAlertX PR: 1184
File: .devcontainer/Dockerfile:18-19
Timestamp: 2025-09-20T03:01:19.912Z
Learning: In the NetAlertX repository, .devcontainer/Dockerfile is auto-generated and should not be reviewed directly. Review comments about dependencies and build steps should be directed at the root Dockerfile where the actual source commands are located.
Applied to files:
.github/workflows/docker_dev.yml
📚 Learning: 2025-09-20T02:56:24.501Z
Learnt from: adamoutler
Repo: jokob-sk/NetAlertX PR: 1184
File: .devcontainer/devcontainer.json:5-8
Timestamp: 2025-09-20T02:56:24.501Z
Learning: In the NetAlertX devcontainer setup, the final .devcontainer/Dockerfile is generated by combining the root Dockerfile with .devcontainer/resources/devcontainer-Dockerfile using the generate-dockerfile.sh script. The devcontainer.json should reference the generated file, not the root Dockerfile.
Applied to files:
.github/workflows/docker_dev.yml
🧬 Code graph analysis (1)
front/plugins/nmap_dev_scan/nmap_dev.py (1)
server/helper.py (4)
get_setting_value(210-265)extract_between_strings(447-453)extract_ip_addresses(554-557)extract_mac_addresses(548-551)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
- GitHub Check: docker_dev
🔇 Additional comments (8)
.github/workflows/docker_rewrite.yml (1)
46-46: ✓ Docker metadata action upgraded to v5.Line 46 upgrades
docker/metadata-action@v4tov5, resolving the critical actionlint warning about an outdated runner that was flagged in previous reviews. The upgrade is appropriate and maintains the existing tag generation logic..github/workflows/docker_dev.yml (3)
34-40: ✓ Timestamp-based version generation for dev builds.Lines 34–40 introduce a new step that generates a UTC timestamp in format
dev-YYYYMMDD-HHMMSS. This aligns well with the PR's datetime centralization effort and ensures each dev build gets a unique, sortable identifier. Usingdate -uensures consistency across different runner timezones.
52-52: ✓ Corrected .VERSION file write operation.Line 52 correctly switches from
>>(append) to>(overwrite) when writing the timestamp version to.VERSION. This ensures the file contains exactly the intended version, not accumulated content from previous runs.
56-56: ✓ Docker metadata action upgraded to v5 with timestamp tag integration.Line 56 upgrades to
docker/metadata-action@v5, resolving the critical actionlint warning. Line 63 integrates the timestamp version as a raw tag, ensuring dev image tags include the build timestamp for easy identification and traceability.Also applies to: 63-63
.github/workflows/docker_prod.yml (3)
35-42: ✓ Release tag–based versioning with proper extraction.Lines 35–38 extract the version from the git tag using the standard GITHUB_REF pattern, and lines 40–42 write it to
.VERSIONusing overwrite mode. This approach is consistent with the dev workflow and aligns with the PR's versioning centralization, ensuring prod builds use release-tag–derived versions.
47-47: ✓ Docker metadata action upgraded to v5 with explicit semver values.Line 47 upgrades to
docker/metadata-action@v5, resolving the critical actionlint warning. Lines 53–55 use explicitvalue=parameters to ensure semver tags are derived precisely from the release tag, providing tight control over prod image versioning.Also applies to: 53-55
60-72: ✓ Improved step clarity with descriptive comments.Lines 60 and 67 add comments clarifying the purpose of the GHCR and DockerHub login steps. This improves workflow maintainability without changing behavior.
front/plugins/nmap_dev_scan/nmap_dev.py (1)
24-24: LGTM! Removal of timeNowTZ aligns with PR objectives.The removal of
timeNowTZfrom the helper imports is correct. This plugin doesn't perform any timestamp operations—it only scans devices and writes results usingPlugin_Objects. The change aligns with the broader PR objective to centralize datetime logic and remove legacy time helpers.
Signed-off-by: jokob-sk <jokob.sk@gmail.com>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 2
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (2)
front/plugins/sync/sync.py (2)
176-206: Verify node name extraction logic for decoded files.When
decode_and_rename_files(imported on line 18) renames encrypted files from.encoded.to.decoded., the filename becomeslast_result.decoded.Node_1.1.log. On line 185,file_name.split('.')[1]extracts index 1 which would be'decoded', not the node name'Node_1'(which is at index 2).This logic error would cause incorrect node attribution for encrypted/decoded files, though it works correctly for non-encrypted files like
last_result.Node_1.log.Consider applying this fix to handle both file formats:
- # Store e.g. Node_1 from last_result.encoded.Node_1.1.log - syncHubNodeName = file_name.split('.')[1] + # Extract node name from either last_result.decoded.Node_1.1.log or last_result.Node_1.log + parts = file_name.split('.') + # If decoded/encoded file, node name is at index 2; otherwise at index 1 + syncHubNodeName = parts[2] if 'decoded' in file_name or 'encoded' in file_name else parts[1]
317-345: Fix return type in error paths to prevent AttributeError.The
get_datafunction returns an empty string""on error (lines 337, 345), but the caller on line 137 expects a dictionary and calls.get('node_name', 'unknown_node')on the return value. This would cause anAttributeErrorsince strings don't have a.get()method.Apply this fix:
except json.JSONDecodeError: message = f'[{pluginName}] Failed to parse JSON from {final_endpoint}' mylog('verbose', [message]) write_notification(message, 'alert', timeNowDB()) - return "" + return {} except requests.RequestException as e: mylog('verbose', [f'[{pluginName}] Error calling {final_endpoint}: {e}']) # If all endpoints fail message = f'[{pluginName}] Failed to get data from "{node_url}" via all endpoints' mylog('verbose', [message]) write_notification(message, 'alert', timeNowDB()) - return "" + return {}
🧹 Nitpick comments (4)
front/plugins/__test/test.py (1)
23-23: Consider removing unused imports and variables.While this is a development test file, several imports and variables are unused:
getPluginObject(line 23)bytes_to_string,sanitize_string,cleanDeviceName(line 26)plugin_objects(line 37)md5_hash(line 39)Removing them would reduce noise and make the file's actual dependencies clearer.
Also applies to: 26-26, 37-39
front/plugins/omada_sdn_imp/omada_sdn.py (1)
44-44: Remove unused import.The
get_plugins_configsfunction is imported but never used in this file.Apply this diff to remove the unused import:
-from utils.plugin_utils import get_plugins_configsfront/plugins/_publisher_mqtt/mqtt.py (1)
28-28: Remove unused import.The
timeNowDBimport is never used in this file. While it was likely added as part of the timestamp utility migration, theprepTimeStampfunction at line 571 needs a datetime object rather than a formatted string (whichtimeNowDBreturns), so the directdatetime.now(conf.tz)usage is appropriate for that context.Apply this diff to remove the unused import:
-from utils.datetime_utils import timeNowDBdocs/API_LOGS.md (1)
19-28: Consider adding a language specifier to the fenced code block.For consistency and proper syntax highlighting, consider marking the code block as plaintext:
-``` +```plaintext app.log app_front.log IP_changes.log
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (24)
docs/API.md(1 hunks)docs/API_GRAPHQL.md(2 hunks)docs/API_LOGS.md(1 hunks)front/php/server/util.php(5 hunks)front/plugins/__template/rename_me.py(1 hunks)front/plugins/__test/test.py(1 hunks)front/plugins/_publisher_mqtt/mqtt.py(2 hunks)front/plugins/dig_scan/digscan.py(1 hunks)front/plugins/freebox/freebox.py(1 hunks)front/plugins/ipneigh/ipneigh.py(1 hunks)front/plugins/nbtscan_scan/nbtscan.py(1 hunks)front/plugins/omada_sdn_imp/omada_sdn.py(1 hunks)front/plugins/sync/sync.py(6 hunks)front/plugins/unifi_api_import/unifi_api_import.py(1 hunks)front/plugins/wake_on_lan/wake_on_lan.py(1 hunks)server/api_server/api_server_start.py(24 hunks)server/api_server/graphql_endpoint.py(3 hunks)server/api_server/logs_endpoint.py(1 hunks)server/initialise.py(3 hunks)server/models/user_events_queue_instance.py(3 hunks)server/plugin.py(10 hunks)server/utils/plugin_utils.py(1 hunks)test/api_endpoints/test_graphq_endpoints.py(1 hunks)test/api_endpoints/test_logs_endpoints.py(1 hunks)
✅ Files skipped from review due to trivial changes (1)
- front/php/server/util.php
🚧 Files skipped from review as they are similar to previous changes (3)
- front/plugins/__template/rename_me.py
- front/plugins/ipneigh/ipneigh.py
- front/plugins/freebox/freebox.py
🧰 Additional context used
📓 Path-based instructions (5)
**/*.py
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
Use 'logger.mylog' for logging at levels: none, minimal, verbose, debug, or trace.
Files:
server/utils/plugin_utils.pyserver/api_server/logs_endpoint.pyserver/models/user_events_queue_instance.pyfront/plugins/omada_sdn_imp/omada_sdn.pyfront/plugins/sync/sync.pyfront/plugins/unifi_api_import/unifi_api_import.pyfront/plugins/__test/test.pyserver/api_server/graphql_endpoint.pyfront/plugins/_publisher_mqtt/mqtt.pytest/api_endpoints/test_graphq_endpoints.pyfront/plugins/dig_scan/digscan.pyserver/api_server/api_server_start.pytest/api_endpoints/test_logs_endpoints.pyfront/plugins/nbtscan_scan/nbtscan.pyfront/plugins/wake_on_lan/wake_on_lan.pyserver/plugin.pyserver/initialise.py
server/api_server/*.py
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
When introducing new server functionality, add endpoints only within 'server/api_server/*' and keep authorization checks consistent.
Files:
server/api_server/logs_endpoint.pyserver/api_server/graphql_endpoint.pyserver/api_server/api_server_start.py
test/**/*.py
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
Tests must reside under 'test/' and use pytest.
Files:
test/api_endpoints/test_graphq_endpoints.pytest/api_endpoints/test_logs_endpoints.py
server/api_server/api_server_start.py
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
All API endpoints must enforce Authorization headers: 'Authorization: Bearer <API_TOKEN>' obtained via 'get_setting_value('API_TOKEN')'.
Files:
server/api_server/api_server_start.py
server/initialise.py
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
Add or modify settings centrally via 'ccd()' in 'server/initialise.py' or via plugin manifest; never hardcode ports or secrets—always use 'get_setting_value()'.
Files:
server/initialise.py
🧠 Learnings (12)
📚 Learning: 2025-10-21T01:40:24.597Z
Learnt from: CR
Repo: jokob-sk/NetAlertX PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-10-21T01:40:24.597Z
Learning: Applies to server/helper.py : Use 'helper.py' ('timeNowTZ', 'normalize_mac', and sanitizers) for all time, MAC, and string operations; always validate MACs before database writes.
Applied to files:
server/utils/plugin_utils.py
📚 Learning: 2025-11-05T04:34:52.339Z
Learnt from: jokob-sk
Repo: jokob-sk/NetAlertX PR: 1271
File: server/helper.py:50-71
Timestamp: 2025-11-05T04:34:52.339Z
Learning: In the NetAlertX codebase, `timeNowDB` function is intentionally duplicated in both `server/helper.py` and `server/logger.py` to prevent circular import issues, since `helper.py` imports from `logger.py` (`from logger import mylog, logResult`). This duplication is by design.
Applied to files:
server/utils/plugin_utils.pyserver/models/user_events_queue_instance.pyfront/plugins/sync/sync.pyfront/plugins/__test/test.pyfront/plugins/_publisher_mqtt/mqtt.pyserver/api_server/api_server_start.py
📚 Learning: 2025-10-26T19:36:26.482Z
Learnt from: adamoutler
Repo: jokob-sk/NetAlertX PR: 1235
File: server/api_server/nettools_endpoint.py:13-34
Timestamp: 2025-10-26T19:36:26.482Z
Learning: In server/api_server/nettools_endpoint.py, the use of print() for module-level initialization warnings is acceptable and should be reviewed by the primary maintainer. The logger.mylog guideline may be specific to plugin code rather than core server code.
Applied to files:
server/api_server/logs_endpoint.py
📚 Learning: 2025-10-21T01:40:24.597Z
Learnt from: CR
Repo: jokob-sk/NetAlertX PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-10-21T01:40:24.597Z
Learning: Applies to server/api_server/*.py : When introducing new server functionality, add endpoints only within 'server/api_server/*' and keep authorization checks consistent.
Applied to files:
server/api_server/logs_endpoint.pyserver/api_server/api_server_start.py
📚 Learning: 2025-10-10T22:16:02.770Z
Learnt from: adamoutler
Repo: jokob-sk/NetAlertX PR: 1214
File: install/ubuntu24/uninstall.sh:129-141
Timestamp: 2025-10-10T22:16:02.770Z
Learning: NetAlertX uninstall procedures should only remove files from the repository (specifically /app files) and should not touch system packages like PHP, nginx, avahi, or other shared system components to avoid damaging user systems.
Applied to files:
server/api_server/logs_endpoint.py
📚 Learning: 2025-09-20T14:08:48.256Z
Learnt from: adamoutler
Repo: jokob-sk/NetAlertX PR: 1184
File: .devcontainer/scripts/setup.sh:90-96
Timestamp: 2025-09-20T14:08:48.256Z
Learning: In the NetAlertX devcontainer setup, the setup.sh script intentionally removes user_notifications.json from the API directory during development environment initialization to prevent notification clutter that accumulates during container launches and development work.
Applied to files:
server/api_server/logs_endpoint.py
📚 Learning: 2025-10-21T01:40:24.597Z
Learnt from: CR
Repo: jokob-sk/NetAlertX PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-10-21T01:40:24.597Z
Learning: Applies to front/plugins/*/script.py : Run plugin scripts as standalone executables with 'sys.path' configured for '/app/front/plugins' and '/app/server', following the provided template.
Applied to files:
front/plugins/omada_sdn_imp/omada_sdn.pyfront/plugins/sync/sync.pyfront/plugins/unifi_api_import/unifi_api_import.py
📚 Learning: 2025-10-21T01:40:24.597Z
Learnt from: CR
Repo: jokob-sk/NetAlertX PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-10-21T01:40:24.597Z
Learning: Applies to front/plugins/*/script.py : Log a concise summary (such as the total number of objects added) at info level before writing the plugin result file; use verbose/debug for extra context.
Applied to files:
front/plugins/sync/sync.py
📚 Learning: 2025-10-21T01:40:24.597Z
Learnt from: CR
Repo: jokob-sk/NetAlertX PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-10-21T01:40:24.597Z
Learning: Applies to front/plugins/plugin_helper.py : Use 'Plugin_Objects' from 'front/plugins/plugin_helper.py' to sanitize text and normalize MAC addresses before writing results.
Applied to files:
front/plugins/unifi_api_import/unifi_api_import.pyfront/plugins/dig_scan/digscan.pyfront/plugins/nbtscan_scan/nbtscan.pyfront/plugins/wake_on_lan/wake_on_lan.py
📚 Learning: 2025-10-21T01:40:24.597Z
Learnt from: CR
Repo: jokob-sk/NetAlertX PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-10-21T01:40:24.597Z
Learning: Applies to server/database.py : Leverage helpers in 'server/database.py' and 'server/db/*' for persistent state with SQLite.
Applied to files:
server/api_server/api_server_start.py
📚 Learning: 2025-10-21T01:40:24.597Z
Learnt from: CR
Repo: jokob-sk/NetAlertX PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-10-21T01:40:24.597Z
Learning: Applies to server/api_server/api_server_start.py : All API endpoints must enforce Authorization headers: 'Authorization: Bearer <API_TOKEN>' obtained via 'get_setting_value('API_TOKEN')'.
Applied to files:
server/api_server/api_server_start.py
📚 Learning: 2025-11-02T02:22:10.968Z
Learnt from: jokob-sk
Repo: jokob-sk/NetAlertX PR: 1261
File: server/app_state.py:106-115
Timestamp: 2025-11-02T02:22:10.968Z
Learning: In server/app_state.py, the pluginsStates parameter always contains complete plugin state objects with the structure: {"PLUGIN_NAME": {"lastChanged": "...", "totalObjects": N, "newObjects": N, "changedObjects": N}}. Type validation before calling .update() is not needed as the maintainer guarantees well-formed objects are always supplied.
Applied to files:
server/plugin.py
🧬 Code graph analysis (17)
server/utils/plugin_utils.py (3)
server/helper.py (5)
get_file_content(107-113)write_file(116-137)get_setting(149-206)get_setting_value(210-265)setting_value_to_python_type(270-359)server/app_state.py (1)
updateState(156-187)server/utils/crypto_utils.py (2)
decrypt_data(40-46)generate_deterministic_guid(63-66)
server/api_server/logs_endpoint.py (3)
server/logger.py (2)
mylog(84-90)Logger(53-94)server/helper.py (1)
get_setting_value(210-265)server/utils/datetime_utils.py (1)
timeNowDB(47-67)
server/models/user_events_queue_instance.py (2)
server/utils/datetime_utils.py (1)
timeNowDB(47-67)server/logger.py (1)
mylog(84-90)
front/plugins/omada_sdn_imp/omada_sdn.py (2)
server/utils/plugin_utils.py (1)
get_plugins_configs(185-228)server/helper.py (1)
get_setting_value(210-265)
front/plugins/sync/sync.py (4)
server/utils/plugin_utils.py (2)
get_plugins_configs(185-228)decode_and_rename_files(280-326)server/utils/datetime_utils.py (1)
timeNowDB(47-67)server/utils/crypto_utils.py (1)
encrypt_data(32-38)server/messaging/in_app.py (1)
write_notification(29-79)
front/plugins/unifi_api_import/unifi_api_import.py (2)
server/utils/plugin_utils.py (1)
get_plugins_configs(185-228)server/helper.py (1)
get_setting_value(210-265)
front/plugins/__test/test.py (3)
server/utils/plugin_utils.py (1)
getPluginObject(246-276)front/plugins/plugin_helper.py (1)
Plugin_Objects(245-304)server/helper.py (3)
get_setting_value(210-265)bytes_to_string(457-461)sanitize_string(496-500)
server/api_server/graphql_endpoint.py (1)
server/logger.py (1)
mylog(84-90)
front/plugins/_publisher_mqtt/mqtt.py (3)
server/utils/plugin_utils.py (1)
getPluginObject(246-276)server/helper.py (2)
get_setting_value(210-265)bytes_to_string(457-461)server/utils/datetime_utils.py (1)
timeNowDB(47-67)
test/api_endpoints/test_graphq_endpoints.py (1)
server/helper.py (1)
get_setting_value(210-265)
front/plugins/dig_scan/digscan.py (1)
server/utils/plugin_utils.py (1)
get_plugins_configs(185-228)
server/api_server/api_server_start.py (3)
server/api_server/logs_endpoint.py (1)
clean_log(18-57)server/models/user_events_queue_instance.py (2)
UserEventsQueueInstance(14-121)add_event(86-121)server/messaging/in_app.py (1)
write_notification(29-79)
test/api_endpoints/test_logs_endpoints.py (1)
server/helper.py (1)
get_setting_value(210-265)
front/plugins/nbtscan_scan/nbtscan.py (2)
server/utils/plugin_utils.py (1)
get_plugins_configs(185-228)server/helper.py (1)
get_setting_value(210-265)
front/plugins/wake_on_lan/wake_on_lan.py (2)
server/utils/plugin_utils.py (1)
get_plugins_configs(185-228)server/helper.py (1)
get_setting_value(210-265)
server/plugin.py (6)
server/helper.py (4)
get_file_content(107-113)write_file(116-137)get_setting(149-206)get_setting_value(210-265)server/utils/datetime_utils.py (2)
timeNowTZ(32-36)timeNowDB(47-67)server/app_state.py (1)
updateState(156-187)server/models/notification_instance.py (1)
NotificationInstance(28-316)server/messaging/in_app.py (1)
write_notification(29-79)server/utils/crypto_utils.py (1)
generate_deterministic_guid(63-66)
server/initialise.py (6)
server/helper.py (3)
getBuildTimeStampAndVersion(639-666)setting_value_to_python_type(270-359)get_setting_value(210-265)server/utils/datetime_utils.py (1)
timeNowDB(47-67)server/app_state.py (1)
updateState(156-187)server/utils/plugin_utils.py (2)
get_plugins_configs(185-228)get_set_value_for_init(331-367)server/messaging/in_app.py (1)
write_notification(29-79)server/utils/crypto_utils.py (1)
get_random_bytes(50-60)
🪛 Gitleaks (8.28.0)
docs/API_GRAPHQL.md
[high] 224-229: Discovered a potential authorization token provided in a curl command header, which could compromise the curl accessed resource.
(curl-auth-header)
🪛 markdownlint-cli2 (0.18.1)
docs/API_LOGS.md
19-19: Fenced code blocks should have a language specified
(MD040, fenced-code-language)
🪛 Ruff (0.14.3)
server/api_server/logs_endpoint.py
52-52: Do not catch blind exception: Exception
(BLE001)
server/models/user_events_queue_instance.py
115-115: Consider moving this statement to an else block
(TRY300)
117-117: Do not catch blind exception: Exception
(BLE001)
server/api_server/graphql_endpoint.py
286-286: Unused method argument: info
(ARG002)
test/api_endpoints/test_graphq_endpoints.py
28-28: Standard pseudo-random generators are not suitable for cryptographic purposes
(S311)
test/api_endpoints/test_logs_endpoints.py
43-43: Standard pseudo-random generators are not suitable for cryptographic purposes
(S311)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
- GitHub Check: docker_dev
🔇 Additional comments (17)
front/plugins/__test/test.py (1)
23-23: LGTM! Import path updates are correct.The import path changes correctly reflect the PR's refactoring:
getPluginObjectmoved toutils.plugin_utilsnamespacetimeNowTZremoved as it's unused in this fileThese changes are consistent with the PR's centralization of utilities.
Also applies to: 26-26
front/plugins/omada_sdn_imp/omada_sdn.py (1)
47-47: LGTM!Correctly removed the unused
timeNowTZimport while retainingget_setting_value, which is actively used throughout the file (lines 53, 56, 263-267, 429). This aligns with the PR's refactoring objectives.front/plugins/dig_scan/digscan.py (1)
15-18: LGTM!Import path updates align with the broader refactoring to centralize utilities under
utils.*namespace. Removal of unusedtimeNowTZkeeps imports clean.front/plugins/unifi_api_import/unifi_api_import.py (1)
16-19: LGTM!Import path updates are consistent with the centralized utility refactoring. Removal of unused
timeNowTZis appropriate.front/plugins/nbtscan_scan/nbtscan.py (1)
15-18: LGTM!Import changes align with the refactoring to move plugin utilities to
utils.plugin_utils. Cleanup of unusedtimeNowTZimport is good.front/plugins/wake_on_lan/wake_on_lan.py (1)
16-19: LGTM!Import path refactoring is consistent with the broader effort to centralize utilities. Removal of the unused
timeNowTZimport keeps the code clean.front/plugins/_publisher_mqtt/mqtt.py (2)
23-23: LGTM! Import path correctly updated.The import path for
getPluginObjecthas been correctly updated to reflect the new module structure.
571-571: LGTM! Error handling implementation is correct.The fallback to
datetime.now(conf.tz)is appropriate here sinceprepTimeStamprequires a datetime object to call.isoformat()on line 574, rather than a pre-formatted string.server/utils/plugin_utils.py (1)
7-9: LGTM! Import path refactoring aligns with centralization.The import path changes from
crypto_utilstoutils.crypto_utilsand the removal of unusedtimeNowTZare consistent with the PR's goal of centralizing timestamp utilities intoutils.datetime_utils.docs/API.md (1)
67-69: LGTM! Documentation accurately reflects new API capabilities.The expanded GraphQL description and new Logs endpoint entry properly document the new functionality introduced in this PR.
docs/API_GRAPHQL.md (1)
3-262: LGTM! Comprehensive LangStrings documentation.The documentation clearly explains the new LangStrings query, including parameters, fallback behavior, and practical curl examples. The grammar fix and updated endpoint listing improve clarity.
server/models/user_events_queue_instance.py (1)
86-122: LGTM! Well-structured event queueing method.The
add_eventmethod properly validates inputs, handles errors, and logs appropriately. The use oftimeNowDB()aligns with the PR's timestamp utility centralization. The broad exception handling is appropriate for file I/O operations.test/api_endpoints/test_logs_endpoints.py (1)
1-61: LGTM! Comprehensive test coverage for Logs endpoints.The tests properly cover success and error scenarios for both log purging and execution queue operations. Token-based authentication is correctly implemented in the test fixtures.
test/api_endpoints/test_graphq_endpoints.py (1)
1-170: LGTM! Thorough GraphQL endpoint test coverage.The tests comprehensively cover devices, settings, and the new LangStrings queries, including authorization checks, data structure validation, and fallback behavior. The test organization is clear and follows pytest best practices.
server/api_server/logs_endpoint.py (1)
18-51: LGTM! Well-designed log purging function with proper allowlist validation.The allowlist approach provides good security by restricting which files can be purged. The validation, logging, and notification patterns are consistent with the codebase standards.
front/plugins/sync/sync.py (2)
18-18: LGTM! Import paths updated correctly.The import paths have been successfully updated to use the new centralized utility modules (
utils.plugin_utils,utils.datetime_utils,utils.crypto_utils), aligning with the PR's refactoring objectives. All imported functions are used correctly throughout the file.Also applies to: 21-23
153-153: LGTM! Timestamp utility updated correctly.The change from
timeNowTZ()totimeNowDB()correctly uses the new centralized datetime utility. The timestamps are properly passed towrite_notification()for all notification calls.Also applies to: 259-259, 303-303, 312-312, 336-336, 344-344
Signed-off-by: jokob-sk <jokob.sk@gmail.com>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (4)
.github/ISSUE_TEMPLATE/i-have-an-issue.yml(3 hunks)front/plugins/sync/sync.py(7 hunks)server/api_server/api_server_start.py(24 hunks)server/api_server/logs_endpoint.py(1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
- front/plugins/sync/sync.py
🧰 Additional context used
📓 Path-based instructions (3)
server/api_server/api_server_start.py
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
All API endpoints must enforce Authorization headers: 'Authorization: Bearer <API_TOKEN>' obtained via 'get_setting_value('API_TOKEN')'.
Files:
server/api_server/api_server_start.py
server/api_server/*.py
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
When introducing new server functionality, add endpoints only within 'server/api_server/*' and keep authorization checks consistent.
Files:
server/api_server/api_server_start.pyserver/api_server/logs_endpoint.py
**/*.py
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
Use 'logger.mylog' for logging at levels: none, minimal, verbose, debug, or trace.
Files:
server/api_server/api_server_start.pyserver/api_server/logs_endpoint.py
🧠 Learnings (7)
📚 Learning: 2025-10-21T01:40:24.597Z
Learnt from: CR
Repo: jokob-sk/NetAlertX PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-10-21T01:40:24.597Z
Learning: Applies to server/api_server/*.py : When introducing new server functionality, add endpoints only within 'server/api_server/*' and keep authorization checks consistent.
Applied to files:
server/api_server/api_server_start.pyserver/api_server/logs_endpoint.py
📚 Learning: 2025-10-21T01:40:24.597Z
Learnt from: CR
Repo: jokob-sk/NetAlertX PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-10-21T01:40:24.597Z
Learning: Applies to server/api_server/api_server_start.py : All API endpoints must enforce Authorization headers: 'Authorization: Bearer <API_TOKEN>' obtained via 'get_setting_value('API_TOKEN')'.
Applied to files:
server/api_server/api_server_start.py
📚 Learning: 2025-11-05T04:34:52.339Z
Learnt from: jokob-sk
Repo: jokob-sk/NetAlertX PR: 1271
File: server/helper.py:50-71
Timestamp: 2025-11-05T04:34:52.339Z
Learning: In the NetAlertX codebase, `timeNowDB` function is intentionally duplicated in both `server/helper.py` and `server/logger.py` to prevent circular import issues, since `helper.py` imports from `logger.py` (`from logger import mylog, logResult`). This duplication is by design.
Applied to files:
server/api_server/api_server_start.py
📚 Learning: 2025-10-21T01:40:24.597Z
Learnt from: CR
Repo: jokob-sk/NetAlertX PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-10-21T01:40:24.597Z
Learning: Applies to server/database.py : Leverage helpers in 'server/database.py' and 'server/db/*' for persistent state with SQLite.
Applied to files:
server/api_server/api_server_start.py
📚 Learning: 2025-10-10T22:16:02.770Z
Learnt from: adamoutler
Repo: jokob-sk/NetAlertX PR: 1214
File: install/ubuntu24/uninstall.sh:129-141
Timestamp: 2025-10-10T22:16:02.770Z
Learning: NetAlertX uninstall procedures should only remove files from the repository (specifically /app files) and should not touch system packages like PHP, nginx, avahi, or other shared system components to avoid damaging user systems.
Applied to files:
server/api_server/logs_endpoint.py
📚 Learning: 2025-09-20T14:08:48.256Z
Learnt from: adamoutler
Repo: jokob-sk/NetAlertX PR: 1184
File: .devcontainer/scripts/setup.sh:90-96
Timestamp: 2025-09-20T14:08:48.256Z
Learning: In the NetAlertX devcontainer setup, the setup.sh script intentionally removes user_notifications.json from the API directory during development environment initialization to prevent notification clutter that accumulates during container launches and development work.
Applied to files:
server/api_server/logs_endpoint.py
📚 Learning: 2025-09-20T14:09:29.159Z
Learnt from: adamoutler
Repo: jokob-sk/NetAlertX PR: 1184
File: .devcontainer/scripts/setup.sh:103-116
Timestamp: 2025-09-20T14:09:29.159Z
Learning: In NetAlertX devcontainer setup, the netalertx user has write permissions to /var/log/nginx/ directory as it's explicitly chowned to netalertx:www-data in the Dockerfile, so setup.sh can write to nginx log files without sudo.
Applied to files:
.github/ISSUE_TEMPLATE/i-have-an-issue.yml
🧬 Code graph analysis (2)
server/api_server/api_server_start.py (4)
server/helper.py (1)
get_setting_value(210-265)server/api_server/logs_endpoint.py (1)
clean_log(18-57)server/models/user_events_queue_instance.py (2)
UserEventsQueueInstance(14-121)add_event(86-121)server/messaging/in_app.py (1)
write_notification(29-79)
server/api_server/logs_endpoint.py (2)
server/logger.py (2)
mylog(84-90)Logger(53-94)server/helper.py (1)
get_setting_value(210-265)
🪛 Ruff (0.14.3)
server/api_server/logs_endpoint.py
52-52: Do not catch blind exception: Exception
(BLE001)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
- GitHub Check: docker_dev
🔇 Additional comments (4)
.github/ISSUE_TEMPLATE/i-have-an-issue.yml (1)
49-49: LGTM! Enhanced issue template guidance.The updates improve the issue reporting process by:
- Clarifying what relevant
app.confsettings to include- Expanding debug/trace logging requirements with clear confirmation
- Adding email option for log submission
- Making Docker logs mandatory with detailed retrieval instructions
These changes will help users provide better diagnostic information.
Also applies to: 73-79, 88-88, 91-97
server/api_server/logs_endpoint.py (1)
1-57: LGTM! Logs endpoint properly implemented.The
clean_logfunction correctly:
- Validates log files against an allowed list
- Uses proper error handling with appropriate status codes
- Logs and notifies on all code paths
- Returns consistent JSON responses
The past review concerns about error handling (empty log message, missing notification parameter, wrong status code) have all been addressed.
server/api_server/api_server_start.py (2)
52-62: LGTM! Consistent 404 error handler.The custom 404 handler provides a standardized JSON response that aligns with the unified error handling pattern used throughout the API.
380-414: LGTM! Logs endpoints properly secured and implemented.Both new endpoints (
api_clean_logandapi_add_to_execution_queue) correctly:
- Enforce authorization checks as required by coding guidelines
- Validate required parameters
- Return consistent JSON responses
- Handle errors appropriately
The past review concern about missing authorization on
api_add_to_execution_queuehas been addressed.As per coding guidelines
Removed unnecessary blank lines in the nginx configuration template.
Signed-off-by: jokob-sk <jokob.sk@gmail.com>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 0
🧹 Nitpick comments (1)
server/api_server/api_server_start.py (1)
391-414: Refine the error field for consistency.The endpoint correctly enforces authorization and validates input. However, line 412 sets the
errorfield to the generic string"ERROR", while other endpoints in this file provide specific error descriptions (e.g., line 155:"macFrom and macTo are required", line 405:"Missing required 'action' field in JSON body"). Since themessagefield already contains the descriptive error fromqueue.add_event, consider using a more specific error label or using the message content.Apply this diff to improve consistency:
success, message = queue.add_event(action) status_code = 200 if success else 400 response = {"success": success, "message": message} if not success: - response["error"] = "ERROR" + response["error"] = "Failed to queue event"
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (1)
server/api_server/api_server_start.py(24 hunks)
🧰 Additional context used
📓 Path-based instructions (3)
server/api_server/api_server_start.py
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
All API endpoints must enforce Authorization headers: 'Authorization: Bearer <API_TOKEN>' obtained via 'get_setting_value('API_TOKEN')'.
Files:
server/api_server/api_server_start.py
server/api_server/*.py
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
When introducing new server functionality, add endpoints only within 'server/api_server/*' and keep authorization checks consistent.
Files:
server/api_server/api_server_start.py
**/*.py
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
Use 'logger.mylog' for logging at levels: none, minimal, verbose, debug, or trace.
Files:
server/api_server/api_server_start.py
🧠 Learnings (4)
📚 Learning: 2025-10-21T01:40:24.597Z
Learnt from: CR
Repo: jokob-sk/NetAlertX PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-10-21T01:40:24.597Z
Learning: Applies to server/api_server/*.py : When introducing new server functionality, add endpoints only within 'server/api_server/*' and keep authorization checks consistent.
Applied to files:
server/api_server/api_server_start.py
📚 Learning: 2025-10-21T01:40:24.597Z
Learnt from: CR
Repo: jokob-sk/NetAlertX PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-10-21T01:40:24.597Z
Learning: Applies to server/api_server/api_server_start.py : All API endpoints must enforce Authorization headers: 'Authorization: Bearer <API_TOKEN>' obtained via 'get_setting_value('API_TOKEN')'.
Applied to files:
server/api_server/api_server_start.py
📚 Learning: 2025-11-05T04:34:52.339Z
Learnt from: jokob-sk
Repo: jokob-sk/NetAlertX PR: 1271
File: server/helper.py:50-71
Timestamp: 2025-11-05T04:34:52.339Z
Learning: In the NetAlertX codebase, `timeNowDB` function is intentionally duplicated in both `server/helper.py` and `server/logger.py` to prevent circular import issues, since `helper.py` imports from `logger.py` (`from logger import mylog, logResult`). This duplication is by design.
Applied to files:
server/api_server/api_server_start.py
📚 Learning: 2025-10-21T01:40:24.597Z
Learnt from: CR
Repo: jokob-sk/NetAlertX PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-10-21T01:40:24.597Z
Learning: Applies to server/database.py : Leverage helpers in 'server/database.py' and 'server/db/*' for persistent state with SQLite.
Applied to files:
server/api_server/api_server_start.py
🧬 Code graph analysis (1)
server/api_server/api_server_start.py (2)
server/api_server/logs_endpoint.py (1)
clean_log(18-57)server/models/user_events_queue_instance.py (2)
UserEventsQueueInstance(14-121)add_event(86-121)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
- GitHub Check: docker_dev
🔇 Additional comments (4)
server/api_server/api_server_start.py (4)
55-62: LGTM - Clean 404 handler implementation.The custom error handler provides a consistent JSON response structure that aligns with other API responses in this file.
27-28: LGTM - Necessary imports for new logs functionality.These imports support the new
/logsendpoints added below.
46-46: LGTM - CORS configuration updated appropriately.The addition of
/logs/*to CORS resources is consistent with other endpoint patterns.
380-389: LGTM - Proper authorization and validation.The endpoint correctly enforces authorization, validates the required
fileparameter, and delegates to theclean_loghelper which performs whitelist validation.As per coding guidelines
Signed-off-by: jokob-sk <jokob.sk@gmail.com>
Signed-off-by: jokob-sk <jokob.sk@gmail.com>
Signed-off-by: jokob-sk <jokob.sk@gmail.com>
Signed-off-by: jokob-sk <jokob.sk@gmail.com>
Signed-off-by: jokob-sk <jokob.sk@gmail.com>
Signed-off-by: jokob-sk <jokob.sk@gmail.com>
Summary by CodeRabbit
New Features
Bug Fixes
Documentation
Tests