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 }