summaryrefslogtreecommitdiff
path: root/main.go
blob: 74596523e7d82f11ff72c0060216751f65365b6c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
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 <artist> <year> /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!")
}