package main import ( "fmt" "io" "log" "net/http" "os" "path" "regexp" "strconv" "github.com/PuerkitoBio/goquery" "github.com/bogem/id3v2" ) func main() { if len(os.Args) != 4 { fmt.Fprintf(os.Stderr, "usage: %v /path/to/download\n", os.Args[0]) os.Exit(1) } artist, year, dir := os.Args[1], os.Args[2], os.Args[3] fmt.Printf("[+] Retrieving tracks for %v (%v)\n", artist, year) fmt.Printf("[+] Saving to %v\n", dir) // Get weeklybeats HTML url := fmt.Sprintf("https://weeklybeats.com/%v?y=%v", artist, year) resp, err := http.Get(url) if err != nil { log.Fatal(err) } defer resp.Body.Close() if resp.StatusCode != 200 { log.Fatalf("status code error: %d %s", resp.StatusCode, resp.Status) } doc, err := goquery.NewDocumentFromReader(resp.Body) if err != nil { log.Fatal(err) } type track struct { title string fileName string url string num int } var tracks []track // Find the tracks urlRegex, err := regexp.Compile(`(https:\/\/weeklybeats\.s3\.amazonaws\.com\/music\/\d{4}\/(.+_weeklybeats-\d{4}_(\d+)_.+.mp3))`) if err != nil { log.Fatal(err) } doc.Find("h3.hn").Each(func(i int, s *goquery.Selection) { track := track{} // For each item, get the name, url, and number. js, exists := s.Find("div").Attr("onclick") if !exists { log.Fatal("error: url does not exist for a track") } submatches := urlRegex.FindStringSubmatch(js) track.url = submatches[1] track.fileName = submatches[2] num, err := strconv.Atoi(submatches[3]) if err != nil { log.Fatal(err) } track.num = num track.title = s.Find("a").Text() tracks = append(tracks, track) }) // Now, download the tracks. for track := range tracks { fmt.Printf("[+] Downloading %v\n", tracks[track].title) resp, err := http.Get(tracks[track].url) if err != nil { log.Fatal(err) } defer resp.Body.Close() p := path.Join(dir, tracks[track].fileName) out, err := os.Create(p) if err != nil { log.Fatal(err) } defer out.Close() _, err = io.Copy(out, resp.Body) if err != nil { log.Fatal(err) } fmt.Printf("[+] Tagging %v\n", tracks[track].title) tagFile, err := id3v2.Open(p, id3v2.Options{}) if err != nil { log.Fatal(err) } defer tagFile.Close() tagFile.SetAlbum(fmt.Sprintf("Weeklybeats %v", year)) tagFile.SetArtist(artist) tagFile.SetTitle(tracks[track].title) tagFile.AddTextFrame("TRCK", tagFile.DefaultEncoding(), fmt.Sprintf("%d", tracks[track].num)) err = tagFile.Save() if err != nil { log.Fatal(err) } } fmt.Println("[+] Done!") }