Browse Source

Merge pull request #224 from SimJunYou/piholePrivacy

DNS Stats widget - fix Pihole privacy edge case
Svilen Markov 9 months ago
parent
commit
07fe5b3cb1
1 changed files with 28 additions and 7 deletions
  1. 28 7
      internal/feed/pihole.go

+ 28 - 7
internal/feed/pihole.go

@@ -1,6 +1,7 @@
 package feed
 
 import (
+	"encoding/json"
 	"errors"
 	"log/slog"
 	"net/http"
@@ -9,13 +10,33 @@ import (
 )
 
 type piholeStatsResponse struct {
-	TotalQueries      int            `json:"dns_queries_today"`
-	QueriesSeries     map[int64]int  `json:"domains_over_time"`
-	BlockedQueries    int            `json:"ads_blocked_today"`
-	BlockedSeries     map[int64]int  `json:"ads_over_time"`
-	BlockedPercentage float64        `json:"ads_percentage_today"`
-	TopBlockedDomains map[string]int `json:"top_ads"`
-	DomainsBlocked    int            `json:"domains_being_blocked"`
+	TotalQueries      int                     `json:"dns_queries_today"`
+	QueriesSeries     map[int64]int           `json:"domains_over_time"`
+	BlockedQueries    int                     `json:"ads_blocked_today"`
+	BlockedSeries     map[int64]int           `json:"ads_over_time"`
+	BlockedPercentage float64                 `json:"ads_percentage_today"`
+	TopBlockedDomains piholeTopBlockedDomains `json:"top_ads"`
+	DomainsBlocked    int                     `json:"domains_being_blocked"`
+}
+
+// If user has some level of privacy enabled on Pihole, `json:"top_ads"` is an empty array
+// Use custom unmarshal behavior to avoid not getting the rest of the valid data when unmarshalling
+type piholeTopBlockedDomains map[string]int
+
+func (p *piholeTopBlockedDomains) UnmarshalJSON(data []byte) error {
+	// NOTE: do not change to piholeTopBlockedDomains type here or it will cause a stack overflow
+	// because of the UnmarshalJSON method getting called recursively
+	temp := make(map[string]int)
+
+	err := json.Unmarshal(data, &temp)
+
+	if err != nil {
+		*p = make(piholeTopBlockedDomains)
+	} else {
+		*p = temp
+	}
+
+	return nil
 }
 
 func FetchPiholeStats(instanceURL, token string) (*DNSStats, error) {