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

feat:_ add settings to enable thumbnails on dashboard #227

Merged
merged 1 commit into from
Jun 22, 2024

Conversation

tphakala
Copy link
Owner

No description provided.

Copy link
Contributor

coderabbitai bot commented Jun 22, 2024

Walkthrough

This update enhances the BirdNET-Go dashboard by adding thumbnail and tooltip functionalities, as well as other structural and configuration adjustments. Key modifications include styling for thumbnails and tooltips, conditional cache initialization for bird images, new dashboard settings for thumbnails, and updates to HTML templates to reflect these settings.

Changes

Files Change Summary
assets/custom.css Added styles for .thumbnail-container and .thumbnail-tooltip to manage thumbnail display and positioning.
internal/analysis/realtime.go Conditional initialization of birdImageCache based on dashboard thumbnail settings.
internal/conf/config.go, config.yaml, defaults.go Introduced new Dashboard settings for thumbnail display, with defaults configured.
internal/httpcontroller/handlers.go, init.go, utils.go Added DashboardSettings field to data structure for template rendering and updated related methods.
internal/imageprovider/imageprovider.go, wikipedia.go Renamed struct fields for consistency, such as changing Url to URL.
views/fragments/birdsTableHTML.html, recentDetections.html Conditional rendering of thumbnails based on new DashboardSettings.

Sequence Diagram(s)

sequenceDiagram
    actor User
    participant Browser
    participant Server
    participant DataStore

    User->>+Browser: Load Dashboard
    Browser->>+Server: Request Dashboard Data
    Server->>+DataStore: Fetch Dashboard Data
    DataStore-->>-Server: Send Dashboard Data
    
    opt Dashboard Thumbnails Enabled
        Server->>+DataStore: Initialize Bird Image Cache
        DataStore-->>-Server: Bird Image Cache
    end
    
    Server-->>-Browser: Render Data with Thumbnails
    Browser-->>-User: Display Thumbnails on Dashboard
Loading

Poem

In the realm of BirdNET-Go,
Thumbnails perch with a glow. 🌟
Tooltips dance and gently sing,
Dashboard settings take wing.
With each feathered friend in sight,
Code and visuals now unite. 🐦


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>.
    • 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 generate interesting stats about this repository and render them as a table.
    • @coderabbitai show all the console.log statements in this repository.
    • @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 as 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 resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Additionally, you can add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.

CodeRabbit Configration 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.

Copy link
Contributor

@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: 5

Outside diff range and nitpick comments (1)
internal/conf/config.yaml (1)

Line range hint 26-26: Fix formatting issues in YAML configuration.

There are several formatting issues detected by yamllint, including wrong indentation and trailing spaces. These should be corrected to maintain the cleanliness and readability of the YAML file.

-    rotationday: 0      # day of the week for weekly rotation, 0 = Sunday
+  rotationday: 0        # day of the week for weekly rotation, 0 = Sunday

- realtime:
-   interval: 15            # duplicate prediction interval in seconds
+realtime:
+  interval: 15             # duplicate prediction interval in seconds

-    thumbnails:
-      summary: false
+  thumbnails:
+    summary: false

-    enabled: false
+  enabled: false

Also applies to: 33-33, 41-41, 44-44, 51-51, 58-58, 64-64, 89-89, 130-130

Tools
yamllint

[error] 44-44: trailing spaces (trailing-spaces)


[error] 51-51: trailing spaces (trailing-spaces)

Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

Commits

Files that changed from the base of the PR and between 5f2ad64 and fc0de69.

Files selected for processing (12)
  • assets/custom.css (1 hunks)
  • internal/analysis/realtime.go (1 hunks)
  • internal/conf/config.go (3 hunks)
  • internal/conf/config.yaml (1 hunks)
  • internal/conf/defaults.go (1 hunks)
  • internal/httpcontroller/handlers.go (3 hunks)
  • internal/httpcontroller/init.go (2 hunks)
  • internal/httpcontroller/utils.go (3 hunks)
  • internal/imageprovider/imageprovider.go (2 hunks)
  • internal/imageprovider/wikipedia.go (4 hunks)
  • views/fragments/birdsTableHTML.html (2 hunks)
  • views/fragments/recentDetections.html (4 hunks)
Files skipped from review due to trivial changes (2)
  • assets/custom.css
  • views/fragments/birdsTableHTML.html
Additional context used
yamllint
internal/conf/config.yaml

[warning] 26-26: wrong indentation: expected 4 but found 6 (indentation)


[error] 33-33: trailing spaces (trailing-spaces)


[error] 41-41: trailing spaces (trailing-spaces)


[error] 44-44: trailing spaces (trailing-spaces)


[error] 51-51: trailing spaces (trailing-spaces)


[error] 58-58: trailing spaces (trailing-spaces)


[error] 64-64: trailing spaces (trailing-spaces)


[error] 89-89: trailing spaces (trailing-spaces)


[error] 130-130: no new line character at the end of file (new-line-at-end-of-file)

Additional comments not posted (10)
views/fragments/recentDetections.html (2)

32-41: Thumbnail conditional rendering logic appears correctly implemented.

This segment properly integrates the thumbnail display within the conditional block which checks the Thumbnails.Recent setting. This is a good practice as it ensures that thumbnails are only rendered when enabled in the settings, potentially saving bandwidth and processing time.


Line range hint 68-91: Responsive layout adaptation is well-handled.

The responsive layout for smaller screens using .sm:hidden and conditional rendering for thumbnails is well implemented. This ensures a good user experience across different device sizes. However, ensure that the attributes and methods used in the template (like {{title .CommonName}}) are supported and correctly implemented.

internal/imageprovider/imageprovider.go (2)

16-20: Field naming and struct organization is clear and consistent.

The renaming of struct fields in BirdImage to capitalize the first letter is a necessary change for fields that need to be exported in Go. This change adheres to Go's convention for visibility, making these fields accessible outside the package.


115-117: Efficient memory size estimation for BirdImage.

The method EstimateSize efficiently calculates the memory size of a BirdImage instance, which is crucial for managing resources in image caching mechanisms. This implementation is a good practice for performance optimization.

internal/httpcontroller/init.go (1)

Line range hint 31-49: Proper initialization of server components with clear struct organization.

The Server struct initialization in the New function is well-structured, ensuring that all necessary components like DashboardSettings and BirdImageCache are properly initialized. This setup is crucial for the robustness and scalability of the server configuration.

internal/conf/config.yaml (1)

47-51: Configuration settings for thumbnails are correctly added.

The addition of thumbnail settings under the dashboard key is correctly implemented. This allows easy on/off toggling of thumbnail features in different sections of the application, aligning with the PR's objectives.

Tools
yamllint

[error] 51-51: trailing spaces (trailing-spaces)

internal/imageprovider/wikipedia.go (1)

21-23: Good refactor to improve code readability and compliance with Go conventions.

Changing the field names from lowercase to uppercase enhances visibility (exported vs. unexported) and follows Go naming conventions. Ensure that all references to these fields in the application are updated to reflect these changes.

Also applies to: 72-76

internal/conf/config.go (2)

20-25: New Dashboard struct for configuration settings

The addition of the Dashboard struct with Thumbnails nested struct is well-defined and aligns with the PR's objective to manage thumbnail settings on the dashboard. The comments on each field provide clarity on their purpose.


77-77: Integration of Dashboard settings into the Realtime struct

The integration of the Dashboard struct into the Realtime struct of the Settings configuration is correctly implemented. This centralizes the management of dashboard-related configurations, facilitating easier maintenance and scalability.

internal/httpcontroller/handlers.go (1)

155-163: Proper integration of DashboardSettings in the topBirdsHandler

The addition of DashboardSettings to the data struct in topBirdsHandler is correctly implemented. This allows the handler to access dashboard configuration settings, which is necessary for conditional rendering based on the thumbnail settings. This change supports the PR's objective to enhance dashboard functionality.

Comment on lines +48 to +49
viper.SetDefault("realtime.dashboard.thumbnails.summary", false)
viper.SetDefault("realtime.dashboard.thumbnails.recent", true)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Tip

Codebase Verification

Ensure the new settings are integrated and used within the application.

The search results indicate that the new settings realtime.dashboard.thumbnails.summary and realtime.dashboard.thumbnails.recent are only defined in internal/conf/defaults.go and are not referenced or used elsewhere in the codebase. This suggests that these settings might not be integrated into the application logic.

  • Integration Required: Ensure that the new settings are referenced and utilized appropriately in the relevant parts of the application where dashboard thumbnails are handled.
Analysis chain

Ensure consistency in default settings across the application.

The new dashboard thumbnail settings (summary and recent) are added correctly. Verify that these settings are consistently handled across different parts of the application, especially in areas where these settings are checked or modified.

Scripts executed

The following scripts were executed for the analysis:


Script:

#!/bin/bash
# Description: Search for usage of the new thumbnail settings across the application.

# Test: Search for the settings usage. Expect: Consistent handling across the application.
rg --type go "realtime.dashboard.thumbnails.(summary|recent)"

Length of output: 245



Script:

#!/bin/bash
# Description: Search for usage of the new thumbnail settings across the entire codebase.

# Test: Search for the settings usage in all files. Expect: Consistent handling across the application.
rg 'realtime.dashboard.thumbnails.(summary|recent)'

Length of output: 235

Comment on lines +206 to +239
// ThumbnailAttribution returns the HTML-formatted attribution for a bird's thumbnail image.
// It takes the bird's scientific name as input and returns a template.HTML string.
// If the attribution information is incomplete or an error occurs, it returns an empty template.HTML.
func (s *Server) thumbnailAttribution(scientificName string) template.HTML {
if s.BirdImageCache == nil {
// Return empty string if the cache is not initialized
return template.HTML("")
}

birdImage, err := s.BirdImageCache.Get(scientificName)
if err != nil {
log.Printf("Error getting thumbnail info for %s: %v", scientificName, err)
return template.HTML("")
}

// Skip if no author or license information
if birdImage.AuthorName == "" || birdImage.LicenseName == "" {
return template.HTML("")
}

var toReturn string
if birdImage.AuthorUrl == "" {
toReturn = fmt.Sprintf("© %s / <a href=%s>%s</a>", birdImage.AuthorName, birdImage.LicenseUrl, birdImage.LicenseName)
var attribution string
if birdImage.AuthorURL == "" {
attribution = fmt.Sprintf("© %s / <a href=\"%s\">%s</a>",
html.EscapeString(birdImage.AuthorName),
html.EscapeString(birdImage.LicenseURL),
html.EscapeString(birdImage.LicenseName))
} else {
toReturn = fmt.Sprintf("© <a href=%s>%s</a> / <a href=%s>%s</a>", birdImage.AuthorUrl, birdImage.AuthorName, birdImage.LicenseUrl, birdImage.LicenseName)
attribution = fmt.Sprintf("© <a href=\"%s\">%s</a> / <a href=\"%s\">%s</a>",
html.EscapeString(birdImage.AuthorURL),
html.EscapeString(birdImage.AuthorName),
html.EscapeString(birdImage.LicenseURL),
html.EscapeString(birdImage.LicenseName))
}

return template.HTML(toReturn)
return template.HTML(attribution)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Refine HTML generation in the ThumbnailAttribution function.

The function handles various error conditions well. However, the HTML generation could be vulnerable to XSS if not properly sanitized. Ensure that html.EscapeString is used consistently to prevent XSS vulnerabilities, especially in dynamically generated links.

- attribution = fmt.Sprintf("© %s / <a href=\"%s\">%s</a>", birdImage.AuthorName, birdImage.LicenseURL, birdImage.LicenseName)
+ attribution = fmt.Sprintf("© %s / <a href=\"%s\">%s</a>", html.EscapeString(birdImage.AuthorName), html.EscapeString(birdImage.LicenseURL), html.EscapeString(birdImage.LicenseName))
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.

Suggested change
// ThumbnailAttribution returns the HTML-formatted attribution for a bird's thumbnail image.
// It takes the bird's scientific name as input and returns a template.HTML string.
// If the attribution information is incomplete or an error occurs, it returns an empty template.HTML.
func (s *Server) thumbnailAttribution(scientificName string) template.HTML {
if s.BirdImageCache == nil {
// Return empty string if the cache is not initialized
return template.HTML("")
}
birdImage, err := s.BirdImageCache.Get(scientificName)
if err != nil {
log.Printf("Error getting thumbnail info for %s: %v", scientificName, err)
return template.HTML("")
}
// Skip if no author or license information
if birdImage.AuthorName == "" || birdImage.LicenseName == "" {
return template.HTML("")
}
var toReturn string
if birdImage.AuthorUrl == "" {
toReturn = fmt.Sprintf("© %s / <a href=%s>%s</a>", birdImage.AuthorName, birdImage.LicenseUrl, birdImage.LicenseName)
var attribution string
if birdImage.AuthorURL == "" {
attribution = fmt.Sprintf("© %s / <a href=\"%s\">%s</a>",
html.EscapeString(birdImage.AuthorName),
html.EscapeString(birdImage.LicenseURL),
html.EscapeString(birdImage.LicenseName))
} else {
toReturn = fmt.Sprintf("© <a href=%s>%s</a> / <a href=%s>%s</a>", birdImage.AuthorUrl, birdImage.AuthorName, birdImage.LicenseUrl, birdImage.LicenseName)
attribution = fmt.Sprintf("© <a href=\"%s\">%s</a> / <a href=\"%s\">%s</a>",
html.EscapeString(birdImage.AuthorURL),
html.EscapeString(birdImage.AuthorName),
html.EscapeString(birdImage.LicenseURL),
html.EscapeString(birdImage.LicenseName))
}
return template.HTML(toReturn)
return template.HTML(attribution)
var attribution string
if birdImage.AuthorURL == "" {
attribution = fmt.Sprintf("© %s / <a href=\"%s\">%s</a>",
html.EscapeString(birdImage.AuthorName),
html.EscapeString(birdImage.LicenseURL),
html.EscapeString(birdImage.LicenseName))
} else {
attribution = fmt.Sprintf("© <a href=\"%s\">%s</a> / <a href=\"%s\">%s</a>",
html.EscapeString(birdImage.AuthorURL),
html.EscapeString(birdImage.AuthorName),
html.EscapeString(birdImage.LicenseURL),
html.EscapeString(birdImage.LicenseName))
}

Comment on lines +188 to +203
// Thumbnail returns the URL of a given bird's thumbnail image.
// It takes the bird's scientific name as input and returns the image URL as a string.
// If the image is not found or an error occurs, it returns an empty string.
func (s *Server) thumbnail(scientificName string) string {
if s.BirdImageCache == nil {
// Return empty string if the cache is not initialized
return ""
}

birdImage, err := s.BirdImageCache.Get(scientificName)
if err != nil {
// Return empty string if an error occurs
return ""
}

return birdImage.Url
return birdImage.URL
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Improve error handling and logging in thumbnail retrieval function.

The function correctly checks for an uninitialized cache and handles errors by returning an empty string, which is a safe failover. Consider adding a log statement for the error scenario to aid in debugging issues related to thumbnail retrieval.

+ log.Printf("Error retrieving thumbnail for %s: %v", scientificName, err)

Committable suggestion was skipped due to low confidence.

Comment on lines +113 to +119
var birdImageCache *imageprovider.BirdImageCache
if settings.Realtime.Dashboard.Thumbnails.Summary || settings.Realtime.Dashboard.Thumbnails.Recent {
// Initialize the bird image cache
birdImageCache = initBirdImageCache(dataStore, metrics)
} else {
birdImageCache = nil
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ensure robust initialization logic for birdImageCache.

The conditional initialization of birdImageCache based on dashboard settings is implemented correctly. This is a good use of configuration to control resource utilization. However, consider adding error handling within initBirdImageCache to ensure that issues during initialization are caught and logged properly.

+ if err != nil {
+     log.Printf("Failed to initialize bird image cache: %v", err)
+     return nil
+ }

Committable suggestion was skipped due to low confidence.

Comment on lines +9 to +11
{{if .DashboardSettings.Thumbnails.Recent}}
<th scope="col" class="py-2 px-6" style="width:20%;">Thumbnail</th>
{{end}}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Tip

Codebase Verification

Ensure robust error handling for dynamic settings in template logic.

The review comment correctly highlights the need for error handling when rendering templates based on dynamic settings. The current implementation does not include nil checks for DashboardSettings in the Go code or default handling in the template.

  • Go Code: internal/httpcontroller/handlers.go does not have nil checks for DashboardSettings before using it in the template.
  • Template: views/fragments/recentDetections.html directly accesses .DashboardSettings.Thumbnails.Recent without any default handling.

To prevent potential runtime errors, consider adding nil checks in the Go code and default values or conditional checks in the template.

  • Add nil checks for DashboardSettings in the Go code.
  • Implement default handling or conditional checks in the template.
Analysis chain

Ensure robust error handling for dynamic settings in template logic.

The conditional rendering based on .DashboardSettings.Thumbnails.Recent is a good approach for dynamic UI changes. However, ensure that there's error handling or a default case in scenarios where .DashboardSettings might be nil or not properly initialized, to prevent runtime errors in the template rendering.

Scripts executed

The following scripts were executed for the analysis:


Script:

#!/bin/bash
# Description: Verify that there's a fallback or error handling for `.DashboardSettings` being nil.
ast-grep --lang go --pattern $'func $_($_, $_, $_) $_ {
  if $_ == nil {
    $$$
  }
}'

Length of output: 88



Script:

#!/bin/bash
# Search for `.DashboardSettings` usage in the Go codebase to find any nil checks or error handling.
rg '\.DashboardSettings' --glob '*.go'

# Inspect the template file for any conditional checks or defaults related to `.DashboardSettings`.
rg '\.DashboardSettings' --glob 'views/fragments/recentDetections.html'

Length of output: 537



Script:

#!/bin/bash
# Inspect the `handlers.go` file for any nil checks or error handling for `DashboardSettings`.
rg 'DashboardSettings' internal/httpcontroller/handlers.go -A 10 -B 10

# Verify if the template file has any conditional checks or defaults for `DashboardSettings`.
rg 'DashboardSettings' views/fragments/recentDetections.html -A 5 -B 5

Length of output: 3206

@tphakala tphakala merged commit 1219025 into main Jun 22, 2024
11 checks passed
@tphakala tphakala deleted the improve-thumbnails branch June 22, 2024 10:36
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.

1 participant