package endpoints import ( "encoding/json" "fmt" "log" "math/rand" "net/http" "os" audio "physick.ru/culture_exam/Audio" settings "physick.ru/culture_exam/Settings" ) type Song struct { Name string Duration int Start int Meta audio.TrackMeta } type SongsList struct { Songs []Song } var cache *SongsList = nil func (base Song) String() string { var outp, jsonErr = json.Marshal(base) if jsonErr != nil { return fmt.Sprintf("Failed to parse settings: %s", jsonErr.Error()) } return string(outp) } func (base SongsList) String() string { var outp, jsonErr = json.Marshal(base) if jsonErr != nil { return fmt.Sprintf("Failed to parse settings: %s", jsonErr.Error()) } return string(outp) } func getSongs(w http.ResponseWriter, r *http.Request) { var songsList, err = GetAvaliableSongs() if err != nil { w.WriteHeader(http.StatusInternalServerError) log.Printf("Failed to get files: %v\n", err.Error()) return } w.Header().Add("Content-Type", "application/json") fmt.Fprint(w, songsList) } func getRandomSong(w http.ResponseWriter, r *http.Request) { var songsList, err = GetAvaliableSongs() if err != nil { w.WriteHeader(http.StatusInternalServerError) log.Printf("Failed to get files: %v\n", err.Error()) return } var index = rand.Intn(len(songsList.Songs)) w.Header().Add("Content-Type", "application/json") var outp = songsList.Songs[index] outp.Start = settings.Current.Distribution.GetDistributedInt(outp.Duration) fmt.Fprint(w, outp) } func GetAvaliableSongs() (SongsList, error) { if cache != nil { return *cache, nil } var files, dirErr = os.ReadDir(settings.Current.SongsLocation) if dirErr != nil { return SongsList{}, dirErr } var outp = SongsList { Songs: make([]Song, 0, len(files)), } for i, v := range files { fmt.Printf("Indexing %d/%d\n", i+1, len(files)) var fullPath = fmt.Sprintf("%s/%s", settings.Current.SongsLocation, v.Name()) var duration, durErr = audio.GetSongDuration(fullPath) if durErr != nil { log.Printf("Failed to parse file metadata: File: %s, error: %s\n", fullPath, durErr.Error()) continue } var meta, metaErr = audio.GenerateMetadata(v.Name()) if metaErr != nil { log.Printf("Failed to get metadata from file: %s", metaErr) continue } var song = Song { Name: v.Name(), Duration: int(duration.Seconds()), Meta: meta, } outp.Songs = append(outp.Songs, song) } cache = &outp return outp, nil }