@@ -33,7 +33,7 @@ import (
3333 "github.com/spf13/viper"
3434)
3535
36- // CachedItem represents a cached content item for completion
36+ // CachedItem represents a cached content item for completion.
3737type CachedItem struct {
3838 Title string `json:"title"`
3939 Path string `json:"path"` // Actual API path
@@ -42,24 +42,24 @@ type CachedItem struct {
4242 Description string `json:"description"` // Optional description
4343}
4444
45- // CacheEntry represents a cached response for a browse path
45+ // CacheEntry represents a cached response for a browse path.
4646type CacheEntry struct {
4747 Items []CachedItem `json:"items"`
4848 FetchedAt time.Time `json:"fetched_at"`
4949}
5050
51- // BrowseCache provides caching for hierarchical path completion
51+ // BrowseCache provides caching for hierarchical path completion.
5252type BrowseCache struct {
5353 cacheDir string
5454 entries map [string ]* CacheEntry
5555 mu sync.RWMutex
5656 dirty bool // Track if cache needs saving
5757}
5858
59- // Global cache instance
59+ // Global cache instance.
6060var browseCache * BrowseCache
6161
62- // NewBrowseCache creates a new browse cache
62+ // NewBrowseCache creates a new browse cache.
6363func NewBrowseCache () (* BrowseCache , error ) {
6464 cacheDir , err := os .UserCacheDir ()
6565 if err != nil {
@@ -69,7 +69,7 @@ func NewBrowseCache() (*BrowseCache, error) {
6969 cacheDir = filepath .Join (cacheDir , "kefw2" )
7070
7171 // Create cache directory if it doesn't exist
72- if err := os .MkdirAll (cacheDir , 0755 ); err != nil {
72+ if err := os .MkdirAll (cacheDir , 0750 ); err != nil {
7373 return nil , fmt .Errorf ("failed to create cache directory: %w" , err )
7474 }
7575
@@ -84,7 +84,7 @@ func NewBrowseCache() (*BrowseCache, error) {
8484 return cache , nil
8585}
8686
87- // InitCache initializes the global browse cache
87+ // InitCache initializes the global browse cache.
8888func InitCache () {
8989 var err error
9090 browseCache , err = NewBrowseCache ()
@@ -97,18 +97,18 @@ func InitCache() {
9797 }
9898}
9999
100- // cacheFilePath returns the path to the cache file
100+ // cacheFilePath returns the path to the cache file.
101101func (c * BrowseCache ) cacheFilePath () string {
102102 return filepath .Join (c .cacheDir , "browse_cache.json" )
103103}
104104
105- // IsEnabled returns whether caching is enabled
105+ // IsEnabled returns whether caching is enabled.
106106func (c * BrowseCache ) IsEnabled () bool {
107107 return viper .GetBool ("cache.enabled" )
108108}
109109
110- // GetTTL returns the TTL for a given service type
111- // Defaults are set in root.go initConfig(): default=300, radio=300, podcast=300, upnp=60
110+ // GetTTL returns the TTL for a given service type.
111+ // Defaults are set in root.go initConfig(): default=300, radio=300, podcast=300, upnp=60.
112112func (c * BrowseCache ) GetTTL (service string ) time.Duration {
113113 key := fmt .Sprintf ("cache.ttl_%s" , service )
114114 seconds := viper .GetInt (key )
@@ -122,7 +122,7 @@ func (c *BrowseCache) GetTTL(service string) time.Duration {
122122 return time .Duration (seconds ) * time .Second
123123}
124124
125- // Get retrieves items from cache if valid
125+ // Get retrieves items from cache if valid.
126126func (c * BrowseCache ) Get (path string , service string ) ([]CachedItem , bool ) {
127127 if ! c .IsEnabled () {
128128 return nil , false
@@ -146,7 +146,7 @@ func (c *BrowseCache) Get(path string, service string) ([]CachedItem, bool) {
146146 return entry .Items , true
147147}
148148
149- // Set stores items in cache
149+ // Set stores items in cache.
150150func (c * BrowseCache ) Set (path string , service string , items []CachedItem ) {
151151 if ! c .IsEnabled () {
152152 return
@@ -163,7 +163,7 @@ func (c *BrowseCache) Set(path string, service string, items []CachedItem) {
163163 c .dirty = true
164164}
165165
166- // Clear removes all cached data
166+ // Clear removes all cached data.
167167func (c * BrowseCache ) Clear () error {
168168 c .mu .Lock ()
169169 defer c .mu .Unlock ()
@@ -175,7 +175,7 @@ func (c *BrowseCache) Clear() error {
175175 return os .Remove (c .cacheFilePath ())
176176}
177177
178- // Status returns cache statistics
178+ // Status returns cache statistics.
179179func (c * BrowseCache ) Status () (entries int , size int64 , oldestAge time.Duration ) {
180180 c .mu .RLock ()
181181 defer c .mu .RUnlock ()
@@ -201,7 +201,7 @@ func (c *BrowseCache) Status() (entries int, size int64, oldestAge time.Duration
201201 return
202202}
203203
204- // Load loads cache from disk
204+ // Load loads cache from disk.
205205func (c * BrowseCache ) Load () error {
206206 c .mu .Lock ()
207207 defer c .mu .Unlock ()
@@ -223,7 +223,7 @@ func (c *BrowseCache) Load() error {
223223 return nil
224224}
225225
226- // Save persists cache to disk
226+ // Save persists cache to disk.
227227func (c * BrowseCache ) Save () error {
228228 c .mu .Lock ()
229229 defer c .mu .Unlock ()
@@ -246,20 +246,20 @@ func (c *BrowseCache) Save() error {
246246 return err
247247 }
248248
249- if err := os .WriteFile (c .cacheFilePath (), data , 0644 ); err != nil {
249+ if err := os .WriteFile (c .cacheFilePath (), data , 0600 ); err != nil {
250250 return err
251251 }
252252
253253 c .dirty = false
254254 return nil
255255}
256256
257- // CacheDir returns the cache directory path
257+ // CacheDir returns the cache directory path.
258258func (c * BrowseCache ) CacheDir () string {
259259 return c .cacheDir
260260}
261261
262- // FindItemByTitle finds a cached item by its title within a parent path
262+ // FindItemByTitle finds a cached item by its title within a parent path.
263263func (c * BrowseCache ) FindItemByTitle (parentPath , service , title string ) (* CachedItem , bool ) {
264264 items , ok := c .Get (parentPath , service )
265265 if ! ok {
@@ -274,8 +274,8 @@ func (c *BrowseCache) FindItemByTitle(parentPath, service, title string) (*Cache
274274 return nil , false
275275}
276276
277- // ResolveDisplayPath resolves a display path (title-based) to an API path
278- // Returns the API path and the last item, or empty string if not found
277+ // ResolveDisplayPath resolves a display path (title-based) to an API path.
278+ // Returns the API path and the last item, or empty string if not found.
279279func (c * BrowseCache ) ResolveDisplayPath (displayPath , service string ) (string , * CachedItem , bool ) {
280280 if displayPath == "" {
281281 return "" , nil , true // Empty path = top level, no API path needed
@@ -318,7 +318,7 @@ func (c *BrowseCache) ResolveDisplayPath(displayPath, service string) (string, *
318318// Cache Command
319319// ============================================
320320
321- // cacheCmd represents the cache command
321+ // cacheCmd represents the cache command.
322322var cacheCmd = & cobra.Command {
323323 Use : "cache" ,
324324 Short : "Manage browse cache for tab completion" ,
@@ -328,11 +328,11 @@ The cache stores browse results to speed up tab completion.
328328Cache location: ~/.cache/kefw2/` ,
329329}
330330
331- // cacheClearCmd clears the cache
331+ // cacheClearCmd clears the cache.
332332var cacheClearCmd = & cobra.Command {
333333 Use : "clear" ,
334334 Short : "Clear all cached browse data" ,
335- Run : func (cmd * cobra.Command , args []string ) {
335+ Run : func (_ * cobra.Command , _ []string ) {
336336 if browseCache == nil {
337337 errorPrinter .Println ("Cache not initialized" )
338338 return
@@ -345,11 +345,11 @@ var cacheClearCmd = &cobra.Command{
345345 },
346346}
347347
348- // cacheStatusCmd shows cache status
348+ // cacheStatusCmd shows cache status.
349349var cacheStatusCmd = & cobra.Command {
350350 Use : "status" ,
351351 Short : "Show cache statistics" ,
352- Run : func (cmd * cobra.Command , args []string ) {
352+ Run : func (_ * cobra.Command , _ []string ) {
353353 // Get cache directory
354354 cacheDir , err := os .UserCacheDir ()
355355 if err != nil {
@@ -361,7 +361,7 @@ var cacheStatusCmd = &cobra.Command{
361361 rowsCachePath := filepath .Join (cacheDir , "rows_cache.json" )
362362 if info , err := os .Stat (rowsCachePath ); err == nil {
363363 // Read and parse the cache file to count entries
364- data , readErr := os .ReadFile (rowsCachePath )
364+ data , readErr := os .ReadFile (rowsCachePath ) //nolint:gosec // Path is constructed from user's cache dir
365365 var entryCount int
366366 var oldestAge time.Duration
367367 if readErr == nil {
@@ -422,7 +422,7 @@ var cacheStatusCmd = &cobra.Command{
422422 },
423423}
424424
425- // formatBytes formats bytes as human-readable string
425+ // formatBytes formats bytes as human-readable string.
426426func formatBytes (bytes int64 ) string {
427427 const unit = 1024
428428 if bytes < unit {
0 commit comments