package main import ( "context" "flag" "log" "slices" "git.gensokyo.uk/yonah/monstersirenfetch" ) var ( flagAlbumsPath string flagSongsPath string flagOutputPath string ) func init() { flag.StringVar(&flagAlbumsPath, "a", "albums.json", "Path to file containing the response body of /api/albums") flag.StringVar(&flagSongsPath, "s", "songs.json", "Path to file containing the response body of /api/songs") flag.StringVar(&flagOutputPath, "o", "metadata.json", "Path to write enriched metadata") } func mustEnrich(ctx context.Context) { var ( albumsResponse monstersirenfetch.AlbumsResponse songsResponse monstersirenfetch.SongsResponse ) mustReadJSON(flagAlbumsPath, &albumsResponse) mustReadJSON(flagSongsPath, &songsResponse) n := new(netDirect) for i := range albumsResponse.Data { a := &albumsResponse.Data[i] if !a.IsFull() { if err := a.Enrich(ctx, n); err != nil { log.Fatal(err) } log.Printf("enriched album %s (%s) with %d songs", a.CID.String(), a.Name, len(a.Songs)) } else { log.Printf("skipped album %s (%s)", a.CID.String(), a.Name) } } for i := range songsResponse.Data.List { s := &songsResponse.Data.List[i] if !s.IsFull() { if err := s.Enrich(ctx, n); err != nil { log.Fatal(err) } log.Printf("enriched song %s: %s (%s)", s.CID.String(), s.SourceURL, s.Name) } else { log.Printf("skipped song %s: %s (%s)", s.CID.String(), s.SourceURL, s.Name) } } // consistency check: enriched songs match flattened songs if c, err := monstersirenfetch.Flatten(albumsResponse.Data, songsResponse.Data); err != nil { log.Fatal(err) } else { for _, ca := range c { if ca.Album == nil { log.Fatal("albums contain nil") } flattenSongs := make([]monstersirenfetch.AlbumSong, 0, len(ca.Songs)) for _, cs := range ca.Songs { if cs == nil { log.Fatal("songs contain nil") } flattenSongs = append(flattenSongs, monstersirenfetch.AlbumSong{CID: cs.CID, Name: cs.Name, Artists: cs.Artists}) } slices.SortFunc(flattenSongs, func(a, b monstersirenfetch.AlbumSong) int { return int(a.CID - b.CID) }) enrichSongs := make([]monstersirenfetch.AlbumSong, len(ca.Album.Songs)) copy(enrichSongs, ca.Album.Songs) slices.SortFunc(enrichSongs, func(a, b monstersirenfetch.AlbumSong) int { return int(a.CID - b.CID) }) if !slices.EqualFunc(flattenSongs, enrichSongs, func(a monstersirenfetch.AlbumSong, b monstersirenfetch.AlbumSong) bool { return a.CID == b.CID && a.Name == b.Name && slices.Equal(a.Artists, b.Artists) }) { log.Fatalf("album %s enrichment inconsistent with flatten state", ca.Album.Name) } else { log.Printf("validated %d songs associated with album %s", len(enrichSongs), ca.Album.CID.String()) } } } mustWriteJSON(flagOutputPath, &monstersirenfetch.Metadata{ Albums: albumsResponse.Data, Songs: songsResponse.Data.List, }) log.Println("metadata written to", flagOutputPath) }