/ pkg / web / store.go
store.go
 1  package web
 2  
 3  import (
 4  	"log"
 5  	"net/http"
 6  	"time"
 7  
 8  	dogeboxd "github.com/dogeorg/dogeboxd/pkg"
 9  	"golang.org/x/mod/semver"
10  )
11  
12  type StoreListSourceEntryPup struct {
13  	LatestVersion string                          `json:"latestVersion"`
14  	LogoBase64    string                          `json:"logoBase64"`
15  	Versions      map[string]dogeboxd.PupManifest `json:"versions"`
16  }
17  
18  type StoreListSourceEntry struct {
19  	Name        string                             `json:"name"`
20  	Description string                             `json:"description"`
21  	Location    string                             `json:"location"`
22  	Type        string                             `json:"type"`
23  	LastChecked string                             `json:"lastChecked"`
24  	Pups        map[string]StoreListSourceEntryPup `json:"pups"`
25  }
26  
27  func (t api) getStoreList(w http.ResponseWriter, r *http.Request) {
28  	forceRefresh := r.URL.Query().Get("refresh") == "true"
29  
30  	available, err := t.sources.GetAll(forceRefresh)
31  	if err != nil {
32  		log.Println("Error fetching sources:", err)
33  		sendErrorResponse(w, http.StatusInternalServerError, "Error fetching sources")
34  		return
35  	}
36  
37  	response := map[string]StoreListSourceEntry{}
38  
39  	for k, entry := range available {
40  		pups := map[string]StoreListSourceEntryPup{}
41  
42  		for _, availablePup := range entry.Pups {
43  			// Check if we already have a pup in our list for this version.
44  			if _, ok := pups[availablePup.Name]; !ok {
45  				versions := map[string]dogeboxd.PupManifest{}
46  
47  				pups[availablePup.Name] = StoreListSourceEntryPup{
48  					LatestVersion: availablePup.Version,
49  					LogoBase64:    availablePup.LogoBase64,
50  					Versions:      versions,
51  				}
52  			}
53  
54  			// Retrieve the struct, modify it, and store it back in the map
55  			pupEntry := pups[availablePup.Name]
56  			pupEntry.Versions[availablePup.Version] = availablePup.Manifest
57  
58  			if semver.Compare("v"+availablePup.Version, "v"+pupEntry.LatestVersion) > 0 {
59  				pupEntry.LatestVersion = availablePup.Version
60  				pupEntry.LogoBase64 = availablePup.LogoBase64
61  			}
62  
63  			pups[availablePup.Name] = pupEntry
64  		}
65  
66  		// Override any entry in the listing with what we actually have installed.
67  		// We want to show that is _actually_ installed, rather than what might have been removed or updated underneath us.
68  		// nb. We don't let you remove a source if you have a pup installed from it, so this should be safe here.
69  		for _, installedPup := range t.dbx.Pups.GetStateMap() {
70  			if installedPup.Source.Location == entry.Config.Location && installedPup.Source.Name == entry.Config.Name {
71  				if _, ok := pups[installedPup.Manifest.Meta.Name]; !ok {
72  					pups[installedPup.Manifest.Meta.Name] = StoreListSourceEntryPup{
73  						Versions: map[string]dogeboxd.PupManifest{},
74  					}
75  				}
76  
77  				pups[installedPup.Manifest.Meta.Name].Versions[installedPup.Version] = installedPup.Manifest
78  			}
79  		}
80  
81  		response[k] = StoreListSourceEntry{
82  			Name:        entry.Config.Name,
83  			Description: entry.Config.Description,
84  			Location:    entry.Config.Location,
85  			Type:        entry.Config.Type,
86  			LastChecked: entry.LastChecked.Format(time.RFC3339),
87  			Pups:        pups,
88  		}
89  	}
90  
91  	sendResponse(w, response)
92  }