Skip to content
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

Improvements to node specific page #221

Merged
merged 6 commits into from
Dec 21, 2024
Merged

Improvements to node specific page #221

merged 6 commits into from
Dec 21, 2024

Conversation

dthaler
Copy link
Collaborator

@dthaler dthaler commented Dec 20, 2024

Add a separate page for spectral density (addresses part of #217)

Let event filters be in Javascript and not require post (Fixes #185)

Summary by CodeRabbit

Release Notes

  • New Features

    • Introduced a new Razor page for displaying spectral density data with Chart.js integration.
    • Added dynamic filtering options for event types and time ranges on the Node Events page.
    • Enhanced frequency analysis with the new FrequencyInfo class for better data encapsulation.
  • Improvements

    • Restructured methods for S3 timestamp retrieval and audio sample analysis for improved clarity and maintainability.
    • Updated event handling logic in the Node Events model for better readability and structure.
    • Enhanced user interactivity on the Node Events page with client-side filtering.
  • Bug Fixes

    • Improved error handling for data retrieval processes to ensure graceful degradation.
    • Enhanced logging for HTTP response errors related to S3 resource access.
  • Documentation

    • Updated page titles and added relevant properties to enhance user experience.

Copy link

coderabbitai bot commented Dec 20, 2024

Warning

Rate limit exceeded

@dthaler has exceeded the limit for the number of commits or files that can be reviewed per hour. Please wait 17 minutes and 53 seconds before requesting another review.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

📥 Commits

Reviewing files that changed from the base of the PR and between 8677db8 and 9dd4ed1.

📒 Files selected for processing (2)
  • OrcanodeMonitor/Pages/NodeEvents.cshtml.cs (2 hunks)
  • OrcanodeMonitor/Pages/SpectralDensity.cshtml.cs (1 hunks)

Walkthrough

The pull request introduces significant changes to the OrcanodeMonitor application, focusing on improving the handling of timestamp and frequency data. A new TimestampResult class and FrequencyInfo class have been added to encapsulate data retrieval and analysis. The changes include refactoring methods in the Fetcher and FfmpegCoreAnalyzer classes to improve code structure and maintainability. Additionally, new pages for spectral density have been introduced, and the node events page has been updated with client-side filtering using JavaScript.

Changes

File Change Summary
OrcanodeMonitor/Core/Fetcher.cs - Added TimestampResult class
- Introduced GetLatestS3TimestampAsync method
- Refactored UpdateS3DataAsync and UpdateManifestTimestampAsync methods
OrcanodeMonitor/Core/FfmpegCoreAnalyzer.cs - Added FrequencyInfo class
- Refactored frequency analysis methods to return FrequencyInfo
- Updated method signatures to use new FrequencyInfo type
OrcanodeMonitor/Pages/NodeEvents.cshtml - Updated page with JavaScript-based filtering
- Removed server-side form submissions
- Added dynamic event filtering
OrcanodeMonitor/Pages/NodeEvents.cshtml.cs - Replaced _nodeId with _node
- Added NodeName property
- Introduced new methods for event class determination
OrcanodeMonitor/Pages/SpectralDensity.cshtml - New Razor page for spectral density visualization
- Integrated Chart.js for frequency data display
OrcanodeMonitor/Pages/SpectralDensity.cshtml.cs - Added SpectralDensityModel class
- Implemented methods for fetching and processing frequency data

Assessment against linked issues

Objective Addressed Explanation
Week/month toggle via JavaScript [#185]
Ensure UptimePercentage continues to work [#185] UptimePercentage functionality was not explicitly addressed or tested in the changes.

Poem

🐰 Hoppity hop, through code we leap,
Timestamps and frequencies, secrets we keep
JavaScript filters, charts so bright
Refactoring magic takes flight!
A rabbit's code dance, pure delight 🎉


Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media?

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR. (Beta)
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

@dthaler dthaler changed the title UI updates Improvements to node specific page Dec 20, 2024
Copy link

@coderabbitai coderabbitai bot left a 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

🧹 Nitpick comments (12)
OrcanodeMonitor/Pages/SpectralDensity.cshtml.cs (2)

15-15: Use a more appropriate logger type for clarity.
Currently, the logger is declared as ILogger, which contradicts the SpectralDensityModel class scope. To maintain consistency and clarity, consider using ILogger.

- private readonly ILogger<NodeEventsModel> _logger;
+ private readonly ILogger<SpectralDensityModel> _logger;

30-74: Consider making frequency range configurable.
Presently, the maximum frequency is hardcoded to 23kHz. If the system needs to handle extended ranges or different sampling rates, externalizing this constant could enhance maintainability and reusability.

OrcanodeMonitor/Pages/NodeEvents.cshtml.cs (2)

31-31: Potential performance consideration with inline property.
The UptimePercentage property calls GetUptimePercentage each time it is accessed. Ensure this property is not accessed repeatedly in performance-critical paths. A small caching mechanism or a computed field might be beneficial if usage is high.


51-77: Improve readability with a switch expression.
The multiple else-if blocks in GetTypeClass can be streamlined using a C# switch expression for better readability and maintainability.

-private string GetTypeClass(OrcanodeEvent item)
-{
-    if (item.Type == OrcanodeEventTypes.HydrophoneStream)
-    {
-        return "hydrophoneStream";
-    }
-    else if (item.Type == OrcanodeEventTypes.DataplicityConnection)
-    {
-        return "dataplicityConnection";
-    }
-    ...
-    else
-    {
-        return string.Empty;
-    }
-}
+private string GetTypeClass(OrcanodeEvent item) => item.Type switch
+{
+    OrcanodeEventTypes.HydrophoneStream => "hydrophoneStream",
+    OrcanodeEventTypes.DataplicityConnection => "dataplicityConnection",
+    OrcanodeEventTypes.MezmoLogging => "mezmoLogging",
+    OrcanodeEventTypes.AgentUpgradeStatus => "agentUpgradeStatus",
+    OrcanodeEventTypes.SDCardSize => "sdCardSize",
+    _ => string.Empty
+};
OrcanodeMonitor/Pages/NodeEvents.cshtml (1)

63-119: Consider debouncing or throttling filter application.
If the application has large datasets or frequent UI interactions, debouncing the filterTable() call can improve performance. For current usage, this may not be critical.

OrcanodeMonitor/Core/FfmpegCoreAnalyzer.cs (2)

Line range hint 81-125: Recommend breaking down the AnalyzeFrequencies method.
This method covers multiple steps: computing FFT, determining maximum amplitude, checking hum frequencies, etc. Splitting these steps into smaller private methods (e.g., CheckSilence, CheckHumFrequencies) may improve readability and testability.


Line range hint 134-164: Ensure memory usage is managed for large audio files.
Storing the entire stream in memory may be expensive for large inputs. Evaluate whether partial or chunked processing is possible if memory constraints arise.

OrcanodeMonitor/Core/Fetcher.cs (2)

739-743: Consider initializing fields for clarity and maintenance.
This class has no constructor or property initializers, which is fine here since it's simple. However, in C#, it's considered a good practice to explicitly define getters/setters for public properties, or at minimum add a constructor to guide maintainers on how these fields are intended to be set.


894-902: Validate manifest retrieval readiness.
Fetching the .m3u8 file might occasionally return a success code but contain no data (if the file was updated but not fully written yet). Consider verifying the file size or content before proceeding so that partially written manifests don’t lead to exceptions or null returns.

OrcanodeMonitor/Pages/SpectralDensity.cshtml (3)

10-11: Load Chart.js via local bundle or pinned CDN version for stability.
Relying on an unpinned version from a generic CDN may introduce unexpected breakage if Chart.js decides to release a backward-incompatible minor patch. Consider pinning the dependency or bundling a stable version of Chart.js.


14-28: Improve chart labeling for advanced use cases.
The chart is labeled as “Last Sample Spectral Density,” but you may want to distinguish multiple data series in the future. Consider structuring your dataset list to allow for easy expansion, e.g., by adding a “node name” or a “timestamp descriptor” to the label.


30-45: Permit negative amplitude values if needed.
Currently, the y-axis minimum is pinned at zero. If there will ever be negative reading values or anomalies, consider adjusting the y-axis range or forcing the chart to auto-scale.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 700535f and 638952e.

📒 Files selected for processing (6)
  • OrcanodeMonitor/Core/Fetcher.cs (4 hunks)
  • OrcanodeMonitor/Core/FfmpegCoreAnalyzer.cs (5 hunks)
  • OrcanodeMonitor/Pages/NodeEvents.cshtml (2 hunks)
  • OrcanodeMonitor/Pages/NodeEvents.cshtml.cs (2 hunks)
  • OrcanodeMonitor/Pages/SpectralDensity.cshtml (1 hunks)
  • OrcanodeMonitor/Pages/SpectralDensity.cshtml.cs (1 hunks)
🧰 Additional context used
📓 Learnings (1)
OrcanodeMonitor/Pages/NodeEvents.cshtml.cs (3)
Learnt from: dthaler
PR: orcasound/orcanode-monitor#173
File: OrcanodeMonitor/Pages/NodeEvents.cshtml.cs:0-0
Timestamp: 2024-11-12T04:20:49.636Z
Learning: In the `NodeEventsModel` class, the ID is part of the route, so the functions `OnGet` and `OnPost` cannot be called with an empty ID.
Learnt from: dthaler
PR: orcasound/orcanode-monitor#179
File: OrcanodeMonitor/Pages/NodeEvents.cshtml.cs:40-40
Timestamp: 2024-11-12T04:20:49.636Z
Learning: In the `NodeEventsModel` class within `OrcanodeMonitor/Pages/NodeEvents.cshtml.cs`, input validation for parameters like `id` is handled by the route configuration, so additional validation in the method is unnecessary.
Learnt from: dthaler
PR: orcasound/orcanode-monitor#173
File: OrcanodeMonitor/Pages/NodeEvents.cshtml.cs:18-19
Timestamp: 2024-11-12T04:20:49.636Z
Learning: In the `NodeEventsModel` class in `OrcanodeMonitor/Pages/NodeEvents.cshtml.cs`, input validation for the `Selected` property is unnecessary unless additional statuses are introduced in the future, as the current behavior safely defaults to "month" when an invalid value is provided.
🔇 Additional comments (7)
OrcanodeMonitor/Pages/NodeEvents.cshtml.cs (1)

19-20: Confirm that a missing Node ID is handled gracefully.
Using .First() on the LINQ query can throw an exception if no matching record is found. If that is intentional, consider adding a try-catch or using .FirstOrDefault() to avoid unhandled exceptions.

OrcanodeMonitor/Pages/NodeEvents.cshtml (2)

8-9: Great improvement!
Displaying the node’s name in the header helps contextualize the page for the user.


21-38: Client-side filtering buttons are well-structured.
Removing post requests simplifies the UI for time range and event type filtering. This is a solid improvement in user experience and performance.

OrcanodeMonitor/Core/FfmpegCoreAnalyzer.cs (2)

12-16: Good design choice with a dedicated data class.
Introducing FrequencyInfo to encapsulate frequency amplitudes and status clarifies responsibilities and improves maintainability.


66-79: Validate the length of data inputs before applying FFT.
If data is too short or null, a potential exception could occur. A quick check and fallback logic (e.g., returning an empty dictionary) could prevent unexpected runtime errors.

OrcanodeMonitor/Core/Fetcher.cs (1)

789-793: Avoid potential repeated invocation loops.
When UpdateS3DataAsync calls GetLatestS3TimestampAsync and returns early on null, it might lead to repeated invocations from elsewhere in the application trying to retrieve a timestamp. Ensure there's a mechanism to detect repeated failures, e.g., logging how often the retrieval fails or temporarily backing off to avoid excessive repeated network calls.

Would you like a script to confirm that there are no unexpected repeated calls in the rest of the codebase?

OrcanodeMonitor/Pages/SpectralDensity.cshtml (1)

1-2: Validate route parameter usage.
Ensure that the “{id}” parameter is robustly handled in the PageModel (e.g., SpectralDensityModel) to prevent potential null references or malformed IDs.

Do you want me to generate a script to search for the SpectralDensityModel usage and confirm it properly processes “id”?

OrcanodeMonitor/Core/Fetcher.cs Outdated Show resolved Hide resolved
OrcanodeMonitor/Core/Fetcher.cs Show resolved Hide resolved
Signed-off-by: Dave Thaler <[email protected]>
Copy link

@coderabbitai coderabbitai bot left a 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

🔭 Outside diff range comments (1)
OrcanodeMonitor/Core/Fetcher.cs (1)

Line range hint 900-952: Improve manifest parsing and error handling.

Several areas need attention:

  1. The manifest parsing is fragile, assuming specific line positions
  2. Stream handling could be more explicit
  3. Error handling could be more specific
     public async static Task<FrequencyInfo?> GetLatestAudioSampleAsync(Orcanode node, string unixTimestampString, bool updateNode, ILogger logger)
     {
         OrcanodeOnlineStatus oldStatus = node.S3StreamStatus;
-        string url = "https://" + node.S3Bucket + ".s3.amazonaws.com/" + node.S3NodeName + "/hls/" + unixTimestampString + "/live.m3u8";
+        string url = BuildS3Url(node.S3Bucket, node.S3NodeName, $"hls/{unixTimestampString}/live.m3u8");
         using HttpResponseMessage response = await _httpClient.GetAsync(url);
         if (!response.IsSuccessStatusCode)
         {
+            logger.LogError($"Failed to fetch manifest for {node.S3NodeName}: {response.StatusCode}");
             return null;
         }

         // ... (existing code)

-        string[] lines = manifestContent.Split('\n', StringSplitOptions.RemoveEmptyEntries);
-        int lineNumber = lines.Count();
-        lineNumber = (lineNumber > 3) ? lineNumber - 3 : lineNumber - 1;
-        string lastLine = lines[lineNumber];
+        var tsFiles = lines
+            .Where(line => line.EndsWith(".ts"))
+            .ToList();
+        
+        if (!tsFiles.Any())
+        {
+            logger.LogError($"No .ts files found in manifest for {node.S3NodeName}");
+            return null;
+        }
+        
+        // Get the second-to-last .ts file if available, otherwise the last one
+        string lastLine = tsFiles.Count > 1 ? tsFiles[tsFiles.Count - 2] : tsFiles.Last();

         Uri newUri = new Uri(baseUri, lastLine);
         try
         {
-            using Stream stream = await _httpClient.GetStreamAsync(newUri);
+            await using var stream = await _httpClient.GetStreamAsync(newUri);
             FrequencyInfo frequencyInfo = await FfmpegCoreAnalyzer.AnalyzeAudioStreamAsync(stream, oldStatus);
             return frequencyInfo;
         }
         catch (Exception ex)
         {
-            logger.LogError(ex, "Exception in UpdateManifestTimestampAsync");
+            logger.LogError(ex, $"Failed to analyze audio stream for {node.S3NodeName}: {ex.Message}");
             return null;
         }
     }
♻️ Duplicate comments (1)
OrcanodeMonitor/Pages/SpectralDensity.cshtml.cs (1)

80-84: ⚠️ Potential issue

Add input validation and error handling.

The page handler needs proper input validation and error handling for the node ID parameter.

     public async Task OnGetAsync(string id)
     {
+        if (string.IsNullOrEmpty(id))
+        {
+            _logger.LogWarning("Empty node ID provided");
+            return;
+        }
+
         _nodeId = id;
-        await UpdateFrequencyDataAsync();
+        try
+        {
+            await UpdateFrequencyDataAsync();
+        }
+        catch (Exception ex)
+        {
+            _logger.LogError(ex, "Error processing frequency data for node {NodeId}", id);
+            throw;
+        }
     }
🧹 Nitpick comments (6)
OrcanodeMonitor/Pages/SpectralDensity.cshtml.cs (3)

12-28: LGTM! Consider adding XML documentation.

The class structure follows good practices with proper dependency injection and encapsulation. Consider adding XML documentation to describe the purpose of the class and its public members.

Add documentation like this:

+    /// <summary>
+    /// Razor Page model for displaying spectral density data for a specific node.
+    /// </summary>
     public class SpectralDensityModel : PageModel
     {

45-46: Extract magic numbers into named constants at class level.

The magic numbers for frequency calculations should be defined as class-level constants with clear documentation.

+    /// <summary>
+    /// Maximum frequency in Hz for spectral density analysis
+    /// </summary>
+    private const int MAX_FREQUENCY_HZ = 23000;
+
+    /// <summary>
+    /// Number of points to use in the frequency distribution
+    /// </summary>
+    private const int FREQUENCY_POINT_COUNT = 1000;

     private async Task UpdateFrequencyDataAsync()
     {
-        const int MaxFrequency = 23000;
-        const int PointCount = 1000;
+        // Use class constants

48-63: Add detailed comments explaining the mathematical logic.

The logarithmic bucketing logic is complex and would benefit from more detailed comments explaining the mathematical approach.

-    // Compute the logarithmic base needed to get PointCount points.
+    // Calculate logarithmic frequency buckets:
+    // 1. Use base b such that b^PointCount = MaxFrequency
+    // 2. This gives us logarithmically spaced frequency points
+    // 3. Each frequency f is assigned to bucket floor(log_b(f))
     double b = Math.Pow(MaxFrequency, 1.0 / PointCount);
     double logb = Math.Log(b);
OrcanodeMonitor/Pages/NodeEvents.cshtml.cs (2)

61-65: Consider using a constant for the time range class name.

The method is well-implemented with proper UTC handling. Consider extracting "pastWeek" as a constant to maintain consistency and ease future updates.

+    private const string PAST_WEEK_CLASS = "pastWeek";
     public string GetTimeRangeClass(OrcanodeEvent item)
     {
         DateTime OneWeekAgo = DateTime.UtcNow.AddDays(-7);
-        return (item.DateTimeUtc > OneWeekAgo) ? "pastWeek" : string.Empty;
+        return (item.DateTimeUtc > OneWeekAgo) ? PAST_WEEK_CLASS : string.Empty;
     }

67-70: Consider using string.Join for better empty class handling.

While the current implementation works, using string.Join would handle empty classes more elegantly.

     public string GetEventClasses(OrcanodeEvent item)
     {
-        string classes = GetTypeClass(item) + " " + GetTimeRangeClass(item);
-        return classes;
+        return string.Join(" ", new[] { GetTypeClass(item), GetTimeRangeClass(item) }
+            .Where(c => !string.IsNullOrEmpty(c)));
     }
OrcanodeMonitor/Core/Fetcher.cs (1)

745-784: Consider extracting S3 URL construction to a separate method.

The method handles errors well, but the S3 URL construction could be extracted to improve reusability and maintainability.

+    private static string BuildS3Url(string bucket, string nodeName, string file)
+    {
+        return $"https://{bucket}.s3.amazonaws.com/{nodeName}/{file}";
+    }

     public async static Task<TimestampResult?> GetLatestS3TimestampAsync(Orcanode node, bool updateNode, ILogger logger)
     {
-        string url = "https://" + node.S3Bucket + ".s3.amazonaws.com/" + node.S3NodeName + "/latest.txt";
+        string url = BuildS3Url(node.S3Bucket, node.S3NodeName, "latest.txt");
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 638952e and f77d830.

📒 Files selected for processing (4)
  • OrcanodeMonitor/Core/Fetcher.cs (4 hunks)
  • OrcanodeMonitor/Pages/NodeEvents.cshtml.cs (2 hunks)
  • OrcanodeMonitor/Pages/SpectralDensity.cshtml.cs (1 hunks)
  • Test/UnintelligibilityTests.cs (1 hunks)
🧰 Additional context used
📓 Learnings (1)
OrcanodeMonitor/Pages/NodeEvents.cshtml.cs (3)
Learnt from: dthaler
PR: orcasound/orcanode-monitor#173
File: OrcanodeMonitor/Pages/NodeEvents.cshtml.cs:0-0
Timestamp: 2024-11-12T04:20:49.636Z
Learning: In the `NodeEventsModel` class, the ID is part of the route, so the functions `OnGet` and `OnPost` cannot be called with an empty ID.
Learnt from: dthaler
PR: orcasound/orcanode-monitor#179
File: OrcanodeMonitor/Pages/NodeEvents.cshtml.cs:40-40
Timestamp: 2024-11-12T04:20:49.636Z
Learning: In the `NodeEventsModel` class within `OrcanodeMonitor/Pages/NodeEvents.cshtml.cs`, input validation for parameters like `id` is handled by the route configuration, so additional validation in the method is unnecessary.
Learnt from: dthaler
PR: orcasound/orcanode-monitor#173
File: OrcanodeMonitor/Pages/NodeEvents.cshtml.cs:18-19
Timestamp: 2024-11-12T04:20:49.636Z
Learning: In the `NodeEventsModel` class in `OrcanodeMonitor/Pages/NodeEvents.cshtml.cs`, input validation for the `Selected` property is unnecessary unless additional statuses are introduced in the future, as the current behavior safely defaults to "month" when an invalid value is provided.
🔇 Additional comments (5)
Test/UnintelligibilityTests.cs (1)

27-28: LGTM! Clean adaptation to the new FrequencyInfo architecture.

The test has been properly updated to work with the new FrequencyInfo return type while maintaining the same test semantics. This change aligns well with the architectural improvement of separating frequency analysis data from status information.

Let's verify that all other test files have been updated to handle the new FrequencyInfo return type:

✅ Verification successful

LGTM! The architectural change is consistently implemented.

The verification confirms that:

  1. AnalyzeFileAsync is only used in UnintelligibilityTests.cs and properly returns FrequencyInfo
  2. The implementation in FfmpegCoreAnalyzer.cs correctly defines the method with FrequencyInfo return type
  3. No other test files are using the old pattern of directly assigning OrcanodeOnlineStatus from AnalyzeFileAsync
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Check for any remaining direct usage of AnalyzeFileAsync that might expect OrcanodeOnlineStatus
# This helps ensure all test files are consistent with the new architecture

# Search for test files that might still expect OrcanodeOnlineStatus from AnalyzeFileAsync
ast-grep --pattern 'status = await FfmpegCoreAnalyzer.AnalyzeFileAsync'

# Also check for any direct assignments that might need updating
ast-grep --pattern 'OrcanodeOnlineStatus $_ = await FfmpegCoreAnalyzer.AnalyzeFileAsync'

Length of output: 2282


Script:

#!/bin/bash
# Let's try a different approach using ripgrep to find any usage of AnalyzeFileAsync
# This will help us verify if all test files are using the new FrequencyInfo return type

# Search for any direct usage of AnalyzeFileAsync
rg "AnalyzeFileAsync" -A 2 -B 2

# Also search for any remaining OrcanodeOnlineStatus assignments
rg "OrcanodeOnlineStatus.*=.*AnalyzeFileAsync"

Length of output: 991

OrcanodeMonitor/Pages/NodeEvents.cshtml.cs (3)

19-21: LGTM! Well-structured node handling implementation.

The change from storing just the ID to storing the entire node object improves encapsulation and provides better access to node properties. The null handling is properly implemented.


45-49: LGTM! Improved async database access.

The change to async/await pattern is appropriate for database operations. The direct node query is more efficient than separate ID lookup.


51-59: LGTM! Clean event type classification implementation.

Well-structured switch expression that handles all event types with a safe fallback.

OrcanodeMonitor/Core/Fetcher.cs (1)

954-973: LGTM! Well-structured manifest update implementation.

The method properly handles the FrequencyInfo update and status change events. The hardcoded AudioStandardDeviation value is intentional as per previous discussions.

OrcanodeMonitor/Pages/SpectralDensity.cshtml.cs Outdated Show resolved Hide resolved
OrcanodeMonitor/Core/Fetcher.cs Outdated Show resolved Hide resolved
Copy link

@coderabbitai coderabbitai bot left a 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 (5)
OrcanodeMonitor/Pages/NodeEvents.cshtml.cs (3)

10-10: Remove unused import

The System.Xml.Linq namespace appears to be unused in this file.

-using System.Xml.Linq;

53-53: Consider splitting long LINQ chain for readability

The LINQ chain is correct but could be more readable if split across multiple lines.

-            _events = Fetcher.GetRecentEventsForNode(_databaseContext, Id, SinceTime, logger).Where(e => e.Type == EventType || EventType == OrcanodeEventTypes.All).ToList() ?? new List<OrcanodeEvent>();
+            _events = Fetcher.GetRecentEventsForNode(_databaseContext, Id, SinceTime, logger)
+                .Where(e => e.Type == EventType || EventType == OrcanodeEventTypes.All)
+                .ToList() ?? new List<OrcanodeEvent>();

72-81: Consider reusing SinceTime logic

The OneWeekAgo calculation could be aligned with the existing SinceTime property for consistency.

-            DateTime OneWeekAgo = DateTime.UtcNow.AddDays(-7);
+            DateTime oneWeekAgo = TimePeriod == "week" ? SinceTime : DateTime.UtcNow.AddDays(-7);
OrcanodeMonitor/Pages/NodeEvents.cshtml (2)

16-27: Consider using a template for uptime spans

The uptime percentage spans follow a repetitive pattern and could be generated using a template or helper method.

Consider creating a helper method in the model:

public string RenderUptimeSpan(string type, string timeRange, bool isVisible = false)
{
    return $@"<span id=""uptime-{type}-{timeRange}"" 
                   class=""uptime-percentage"" 
                   style=""display: {(isVisible ? "" : "none")}"">
                {GetUptimePercentage(type, timeRange)}%
            </span>";
}

71-138: Add error handling for DOM elements

The JavaScript functions should handle cases where elements are not found.

 function showUptimePercentage(id) {
     // Hide all uptime percentage elements.
     var elements = document.querySelectorAll('.uptime-percentage');
     elements.forEach(function(element) {
         element.style.display = 'none';
     });

     // Show the selected uptime percentage.
-    document.getElementById(id).style.display = '';
+    const element = document.getElementById(id);
+    if (element) {
+        element.style.display = '';
+    } else {
+        console.warn(`Uptime percentage element ${id} not found`);
+    }
 }
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between f77d830 and 811ff88.

📒 Files selected for processing (2)
  • OrcanodeMonitor/Pages/NodeEvents.cshtml (2 hunks)
  • OrcanodeMonitor/Pages/NodeEvents.cshtml.cs (2 hunks)
🧰 Additional context used
📓 Learnings (1)
OrcanodeMonitor/Pages/NodeEvents.cshtml.cs (3)
Learnt from: dthaler
PR: orcasound/orcanode-monitor#173
File: OrcanodeMonitor/Pages/NodeEvents.cshtml.cs:0-0
Timestamp: 2024-11-12T04:20:49.636Z
Learning: In the `NodeEventsModel` class, the ID is part of the route, so the functions `OnGet` and `OnPost` cannot be called with an empty ID.
Learnt from: dthaler
PR: orcasound/orcanode-monitor#179
File: OrcanodeMonitor/Pages/NodeEvents.cshtml.cs:40-40
Timestamp: 2024-11-12T04:20:49.636Z
Learning: In the `NodeEventsModel` class within `OrcanodeMonitor/Pages/NodeEvents.cshtml.cs`, input validation for parameters like `id` is handled by the route configuration, so additional validation in the method is unnecessary.
Learnt from: dthaler
PR: orcasound/orcanode-monitor#173
File: OrcanodeMonitor/Pages/NodeEvents.cshtml.cs:18-19
Timestamp: 2024-11-12T04:20:49.636Z
Learning: In the `NodeEventsModel` class in `OrcanodeMonitor/Pages/NodeEvents.cshtml.cs`, input validation for the `Selected` property is unnecessary unless additional statuses are introduced in the future, as the current behavior safely defaults to "month" when an invalid value is provided.
🔇 Additional comments (6)
OrcanodeMonitor/Pages/NodeEvents.cshtml.cs (3)

19-21: LGTM! Good encapsulation and null safety

The change from storing just the ID to storing the entire node object improves encapsulation, and the null coalescing operators provide safe fallbacks.


56-60: LGTM! Method signature change aligns with async pattern

The change to async/await pattern is good. Based on previous learnings, the ID is validated by the route configuration, so using First() is acceptable here.


62-70: LGTM! Clean type mapping implementation

The switch expression provides a clean and comprehensive mapping of event types to CSS classes.

OrcanodeMonitor/Pages/NodeEvents.cshtml (3)

8-14: LGTM! Good navigation implementation

The dynamic node name and navigation to the spectral density page are well implemented, aligning with the PR objectives.


29-45: LGTM! Well-structured filter UI

The filter buttons are well-organized and provide clear visual feedback through CSS classes.


Line range hint 47-69: LGTM! Clean table implementation

The table structure with dynamic class assignment supports the client-side filtering requirement effectively.

OrcanodeMonitor/Pages/NodeEvents.cshtml.cs Show resolved Hide resolved
Signed-off-by: Dave Thaler <[email protected]>
Copy link

@coderabbitai coderabbitai bot left a 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 (2)
OrcanodeMonitor/Pages/SpectralDensity.cshtml.cs (1)

12-13: Add XML documentation for better maintainability.

Consider adding XML documentation to describe the purpose of the class and its public members.

+    /// <summary>
+    /// Razor Page model for spectral density visualization.
+    /// Handles retrieval and processing of frequency data for display.
+    /// </summary>
     public class SpectralDensityModel : PageModel
OrcanodeMonitor/Core/Fetcher.cs (1)

Line range hint 937-944: Extract magic numbers to named constants.

The manifest parsing logic uses magic numbers that should be constants for better maintainability.

+    private const int MANIFEST_PENULTIMATE_OFFSET = 3;
+    private const int MANIFEST_MINIMUM_LINES = 1;
     // Get a recent filename in the manifest.
     string[] lines = manifestContent.Split('\n', StringSplitOptions.RemoveEmptyEntries);
     int lineNumber = lines.Count();
-    lineNumber = (lineNumber > 3) ? lineNumber - 3 : lineNumber - 1;
+    lineNumber = (lineNumber > MANIFEST_PENULTIMATE_OFFSET) ? 
+        lineNumber - MANIFEST_PENULTIMATE_OFFSET : 
+        lineNumber - MANIFEST_MINIMUM_LINES;
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 811ff88 and 8677db8.

📒 Files selected for processing (2)
  • OrcanodeMonitor/Core/Fetcher.cs (4 hunks)
  • OrcanodeMonitor/Pages/SpectralDensity.cshtml.cs (1 hunks)
🔇 Additional comments (7)
OrcanodeMonitor/Pages/SpectralDensity.cshtml.cs (4)

1-22: Well-structured class with proper dependency injection and encapsulation!

The class follows good practices with:

  • Dependency injection for database context and logger
  • Proper encapsulation using private fields with public accessors
  • Clear separation of concerns

23-29: LGTM! Constructor properly initializes dependencies.

The constructor follows good practices by properly initializing all dependencies and setting default values.


71-72: ⚠️ Potential issue

Add guard against division by zero.

While the if (count[i] > 0) check should prevent division by zero, it's better to be defensive in the calculation itself.

-            int frequency = (int)Math.Pow(b, i);
-            int amplitude = (int)(sums[i] / count[i]);
+            int frequency = (int)Math.Pow(b, i);
+            int amplitude = count[i] > 0 ? (int)(sums[i] / count[i]) : 0;

Likely invalid or redundant comment.


81-85: ⚠️ Potential issue

Add input validation for the id parameter.

The method should validate the input parameter to prevent potential issues with null or empty IDs.

     public async Task OnGetAsync(string id)
     {
+        if (string.IsNullOrEmpty(id))
+        {
+            _logger.LogWarning("Empty or null node ID provided");
+            return;
+        }
         _nodeId = id;
         await UpdateFrequencyDataAsync();
     }

Likely invalid or redundant comment.

OrcanodeMonitor/Core/Fetcher.cs (3)

739-748: Well-designed immutable class!

The TimestampResult class follows best practices with:

  • Immutable properties
  • Constructor-based initialization
  • Clear and focused responsibility

750-787: Excellent error handling and logging!

The method properly handles different error scenarios with:

  • Specific status code checks (404, 403)
  • Detailed error logging
  • Appropriate state updates based on error conditions

957-976: LGTM! Method correctly updates manifest timestamp and status.

The implementation properly handles status updates and event generation.

Signed-off-by: Dave Thaler <[email protected]>
@dthaler dthaler merged commit d3b801f into main Dec 21, 2024
8 checks passed
@dthaler dthaler deleted the chart branch December 21, 2024 18:19
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Make week/month toggle be done via javascript not posting
1 participant