diff --git a/config.go b/config.go index 5c5792e..3b9a7b5 100644 --- a/config.go +++ b/config.go @@ -53,6 +53,9 @@ type Config struct { // ServerList is a list of ServerConfig structs, which gets parsed into servers. ServerList []ServerConfig `mapstructure:"servers"` + // Special extensions for the download map + SpecialExtensions map[string]string `mapstructure:"specialExtensions"` + // ReloadFunc is called when a reload is done via http api. ReloadFunc func() @@ -163,7 +166,7 @@ func (r *Redirector) ReloadConfig() error { r.config.TopChoices = len(r.servers) } - // Check if on the config is declared or use default logic + // Check if on the config is declared or use default logic if r.config.SameCityThreshold == 0 { r.config.SameCityThreshold = 200000.0 } @@ -230,7 +233,7 @@ func (r *Redirector) reloadServers() error { "path": u.Path, "latitude": s.Latitude, "longitude": s.Longitude, - "country": s.Country, + "country": s.Country, }).Info("Added server") } }(i, server, u) @@ -314,7 +317,7 @@ func (r *Redirector) reloadMap() error { return nil } log.WithField("file", mapFile).Info("Loading download map") - newMap, err := loadMapFile(mapFile) + newMap, err := loadMapFile(mapFile, r.config.SpecialExtensions) if err != nil { return err } diff --git a/dlrouter.yaml b/dlrouter.yaml index 8330145..7fd0651 100644 --- a/dlrouter.yaml +++ b/dlrouter.yaml @@ -52,4 +52,13 @@ servers: - server: stpete-mirror.armbian.com/apt/ - server: xogium.performanceservers.nl/apt/ - server: github.com/armbian/mirror/releases/download/ - continent: GITHUB \ No newline at end of file + continent: GITHUB + +specialExtensions: + boot-sms.img.xz: -boot-sms + boot-boe.img.xz: -boot-boe + boot-csot.img.xz: -boot-csot + rootfs.img.xz: -rootfs + img.qcow2: -qcow2 + img.qcow2.xz: -qcow2 + boot.bin.xz: -uboot-bin \ No newline at end of file diff --git a/map.go b/map.go index e989f3c..687fc24 100644 --- a/map.go +++ b/map.go @@ -1,7 +1,6 @@ package redirector import ( - "encoding/csv" "encoding/json" "errors" "io" @@ -12,6 +11,7 @@ import ( log "github.com/sirupsen/logrus" + "golang.org/x/exp/maps" "golang.org/x/text/cases" "golang.org/x/text/language" ) @@ -20,7 +20,7 @@ import ( var ErrUnsupportedFormat = errors.New("unsupported map format") // loadMapFile loads a file as a map -func loadMapFile(file string) (map[string]string, error) { +func loadMapFile(file string, specialExtensions map[string]string) (map[string]string, error) { f, err := os.Open(file) if err != nil { @@ -32,40 +32,13 @@ func loadMapFile(file string) (map[string]string, error) { ext := path.Ext(file) switch ext { - case ".csv": - return loadMapCSV(f) case ".json": - return loadMapJSON(f) + return loadMapJSON(f, specialExtensions) } return nil, ErrUnsupportedFormat } -// loadMapCSV loads a pipe separated file of mappings -func loadMapCSV(f io.Reader) (map[string]string, error) { - m := make(map[string]string) - - r := csv.NewReader(f) - - r.Comma = '|' - - for { - row, err := r.Read() - - if err != nil { - if err == io.EOF { - break - } - - return nil, err - } - - m[strings.TrimLeft(row[0], "/")] = strings.TrimLeft(row[1], "/") - } - - return m, nil -} - // Map represents a JSON format of an asset list type Map struct { Assets []ReleaseFile `json:"assets"` @@ -88,11 +61,14 @@ type ReleaseFile struct { var distroCaser = cases.Title(language.Und) -var imageExtensions = []string{"img.xz", "img.qcow2", "boot.bin.xz"} - // loadMapJSON loads a map file from JSON, based on the format specified in the github issue. // See: https://github.com/armbian/os/pull/129 -func loadMapJSON(f io.Reader) (map[string]string, error) { +func loadMapJSON(f io.Reader, specialExtensions map[string]string) (map[string]string, error) { + // Avoid panics + if specialExtensions == nil { + specialExtensions = make(map[string]string) + } + m := make(map[string]string) var data Map @@ -135,21 +111,15 @@ func loadMapJSON(f io.Reader) (map[string]string, error) { } // Check special case for some extensions - switch { - case strings.Contains(file.Extension, "boot-sms.img.xz"): - sb.WriteString("-boot-sms") - case strings.Contains(file.Extension, "boot-boe.img.xz"): - sb.WriteString("-boot-boe") - case strings.Contains(file.Extension, "boot-csot.img.xz"): - sb.WriteString("-boot-csot") - case strings.Contains(file.Extension, "rootfs.img.xz"): - sb.WriteString("-rootfs") - case strings.Contains(file.Extension, "img.qcow2"): - sb.WriteString("-qcow2") - case strings.Contains(file.Extension, "boot.bin.xz"): - sb.WriteString("-uboot-bin") + for k, v := range specialExtensions { + if strings.Contains(file.Extension, k) { + sb.WriteString(v) + } } + imageExtensions := maps.Keys(specialExtensions) + imageExtensions = append(imageExtensions, "img.xz") // extra allocation, but it's fine + // Add board into the map without an extension for _, ext := range imageExtensions { if strings.HasSuffix(file.Extension, ext) { diff --git a/map_test.go b/map_test.go index 0b58977..4466dac 100644 --- a/map_test.go +++ b/map_test.go @@ -7,13 +7,17 @@ import ( . "github.com/onsi/gomega" ) -var _ = Describe("Map", func() { - It("Should successfully load the map from a CSV/Pipe separated file", func() { - m, err := loadMapCSV(strings.NewReader(`bananapi/Bullseye_current|bananapi/archive/Armbian_21.08.1_Bananapi_bullseye_current_5.10.60.img.xz|Aug 26 2021|332M`)) +var testExtensions = map[string]string{ + "boot-sms.img.xz": "-boot-sms", + "boot-boe.img.xz": "-boot-boe", + "boot-csot.img.xz": "-boot-csot", + "rootfs.img.xz": "-rootfs", + "img.qcow2": "-qcow2", + "img.qcow2.xz": "-qcow2", + "boot.bin.xz": "-uboot-bin", +} - Expect(err).To(BeNil()) - Expect(m["bananapi/Bullseye_current"]).To(Equal("bananapi/archive/Armbian_21.08.1_Bananapi_bullseye_current_5.10.60.img.xz")) - }) +var _ = Describe("Map", func() { It("Should successfully load the map from a JSON file", func() { data := `{ "assets": [ @@ -34,7 +38,7 @@ var _ = Describe("Map", func() { ] }` - m, err := loadMapJSON(strings.NewReader(data)) + m, err := loadMapJSON(strings.NewReader(data), testExtensions) Expect(err).To(BeNil()) Expect(m["aml-s9xx-box/Bookworm_current_server"]).To(Equal("/aml-s9xx-box/archive/Armbian_23.11.1_Aml-s9xx-box_bookworm_current_6.1.63.img.xz")) @@ -85,7 +89,7 @@ var _ = Describe("Map", func() { ] }` - m, err := loadMapJSON(strings.NewReader(data)) + m, err := loadMapJSON(strings.NewReader(data), testExtensions) Expect(err).To(BeNil()) Expect(m["khadas-vim1/Bookworm_current_xfce"]).To(Equal("/khadas-vim1/archive/Armbian_23.11.1_Khadas-vim1_bookworm_current_6.1.63_xfce_desktop.img.xz")) @@ -200,7 +204,7 @@ var _ = Describe("Map", func() { ] }` - m, err := loadMapJSON(strings.NewReader(data)) + m, err := loadMapJSON(strings.NewReader(data), testExtensions) Expect(err).To(BeNil()) Expect(m["khadas-vim4/Bookworm_legacy_server"]).To(Equal("/khadas-vim4/archive/Armbian_23.11.1_Khadas-vim4_bookworm_legacy_5.4.180.oowow.img.xz"))