2017-05-30 14:24:04 +02:00
|
|
|
package main
|
|
|
|
|
|
|
|
import (
|
|
|
|
"os"
|
|
|
|
"fmt"
|
|
|
|
"regexp"
|
|
|
|
"encoding/json"
|
|
|
|
"path"
|
2017-05-30 17:03:41 +02:00
|
|
|
"io"
|
2017-05-30 14:24:04 +02:00
|
|
|
"io/ioutil"
|
|
|
|
"wimp-get/wimp"
|
2017-05-30 17:03:41 +02:00
|
|
|
"wimp-get/platform"
|
|
|
|
"os/exec"
|
|
|
|
"net/http"
|
2017-05-30 18:29:37 +02:00
|
|
|
"strings"
|
2017-05-30 14:24:04 +02:00
|
|
|
)
|
|
|
|
|
|
|
|
func main() {
|
|
|
|
if len(os.Args) != 2 {
|
|
|
|
fmt.Printf("Usage: %s <wimp id or url>\n", os.Args[0])
|
|
|
|
os.Exit(-1)
|
|
|
|
}
|
|
|
|
|
|
|
|
var id string;
|
|
|
|
wimpUrl, _ := regexp.Compile("^https?://play\\.wimpmusic\\.com/album/")
|
|
|
|
if wimpUrl.MatchString(os.Args[1]) {
|
|
|
|
id = wimpUrl.ReplaceAllString(os.Args[1], "")
|
|
|
|
} else {
|
|
|
|
id = os.Args[1]
|
|
|
|
}
|
|
|
|
|
|
|
|
exe, _ := os.Executable()
|
|
|
|
wDir := path.Dir(exe)
|
|
|
|
magicData, e := ioutil.ReadFile(wDir + "/magic.json")
|
|
|
|
if e != nil {
|
|
|
|
panic(e)
|
|
|
|
}
|
|
|
|
|
|
|
|
var magic map[string]interface{}
|
|
|
|
e = json.Unmarshal(magicData, &magic)
|
|
|
|
if e != nil {
|
|
|
|
panic(e)
|
|
|
|
}
|
|
|
|
|
|
|
|
println("Looking up album...")
|
|
|
|
|
|
|
|
album, e := wimp.GetAlbum(id, magic["sessionId"].(string))
|
|
|
|
if e != nil {
|
|
|
|
panic(e)
|
|
|
|
}
|
|
|
|
|
|
|
|
fmt.Printf("[ %s - %s (%d) ]\n", album.Artist, album.Title, album.Year)
|
2017-05-30 17:03:41 +02:00
|
|
|
|
|
|
|
// Determine whether we have more than one disc
|
2017-05-30 18:29:37 +02:00
|
|
|
maxdisc := 0
|
2017-05-30 17:03:41 +02:00
|
|
|
for _, track := range album.Tracks {
|
2017-05-30 18:29:37 +02:00
|
|
|
if track.Volume > maxdisc {
|
|
|
|
maxdisc = track.Volume
|
2017-05-30 17:03:41 +02:00
|
|
|
}
|
|
|
|
}
|
2017-05-30 18:29:37 +02:00
|
|
|
var multidisc bool
|
|
|
|
if maxdisc > 1 {
|
|
|
|
multidisc = true
|
|
|
|
}
|
2017-05-30 17:03:41 +02:00
|
|
|
|
|
|
|
dirName := album.Artist+" - "+album.Title+" ("+fmt.Sprintf("%d", album.Year)+") [WEB FLAC]"
|
2017-05-30 18:29:37 +02:00
|
|
|
dirName, e = platform.SanitiseFilename(dirName)
|
|
|
|
if e != nil {
|
|
|
|
panic(e)
|
|
|
|
}
|
2017-05-30 17:03:41 +02:00
|
|
|
|
|
|
|
e = os.Mkdir(dirName, os.FileMode(0755))
|
|
|
|
if e != nil {
|
|
|
|
panic(e)
|
|
|
|
}
|
|
|
|
|
2017-05-30 18:29:37 +02:00
|
|
|
var firstFile string // we use this later to generate spectrals
|
|
|
|
|
2017-05-30 17:03:41 +02:00
|
|
|
// Time to do the ripping!
|
2017-05-30 18:29:37 +02:00
|
|
|
for i, track := range album.Tracks {
|
2017-05-30 17:03:41 +02:00
|
|
|
num := fmt.Sprintf("%d", track.Number)
|
|
|
|
if len(num) < 2 {
|
|
|
|
num = "0"+num
|
|
|
|
}
|
|
|
|
|
|
|
|
fmt.Printf("[%d/%s] %s...", track.Volume, num, track.Title)
|
|
|
|
|
|
|
|
var filename string
|
|
|
|
if (multidisc) {
|
|
|
|
filename = fmt.Sprintf("%s/Disc %d/%s - %s.flac", dirName, track.Volume, num, track.Title)
|
|
|
|
} else {
|
|
|
|
filename = fmt.Sprintf("%s/%s - %s.flac", dirName, num, track.Title)
|
|
|
|
}
|
|
|
|
|
|
|
|
filename, e = platform.SanitiseFilename(filename)
|
|
|
|
if e != nil {
|
|
|
|
panic(e)
|
|
|
|
}
|
|
|
|
|
2017-05-30 18:29:37 +02:00
|
|
|
if i == 0 {
|
|
|
|
firstFile = filename
|
|
|
|
}
|
|
|
|
|
2017-05-30 17:03:41 +02:00
|
|
|
// create disc dir if necessary
|
|
|
|
if _, e = os.Stat(path.Dir(filename)); e != nil {
|
|
|
|
if os.IsNotExist(e) {
|
|
|
|
e = os.Mkdir(path.Dir(filename), os.FileMode(0755))
|
|
|
|
if e != nil {
|
|
|
|
panic(e)
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
panic(e)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
resp, e := http.Get(track.Url)
|
|
|
|
if e != nil {
|
|
|
|
panic(e)
|
|
|
|
}
|
|
|
|
|
|
|
|
ffmpeg := exec.Command(magic["ffmpeg"].(string), "-i", "-", "-metadata", "title="+track.Title, "-metadata", "artist="+track.Artist,
|
|
|
|
"-metadata", "album="+album.Title, "-metadata", "year="+fmt.Sprintf("%d", album.Year), "-metadata", "track="+fmt.Sprintf("%d", track.Number),
|
|
|
|
"-metadata", "albumartist="+album.Artist, "-metadata", "discnumber="+fmt.Sprintf("%d", track.Volume), filename)
|
|
|
|
|
|
|
|
stdin, e := ffmpeg.StdinPipe()
|
|
|
|
if e != nil {
|
|
|
|
panic(e)
|
|
|
|
}
|
|
|
|
|
|
|
|
e = ffmpeg.Start()
|
|
|
|
if e != nil {
|
|
|
|
panic(e)
|
|
|
|
}
|
|
|
|
|
|
|
|
_, e = io.Copy(stdin, resp.Body)
|
|
|
|
if e != nil {
|
|
|
|
panic(e)
|
|
|
|
}
|
|
|
|
|
|
|
|
resp.Body.Close()
|
|
|
|
|
|
|
|
println(" Done!")
|
|
|
|
}
|
2017-05-30 18:29:37 +02:00
|
|
|
|
|
|
|
// Get art
|
|
|
|
print("Getting album art...")
|
|
|
|
|
|
|
|
resp, e := http.Get(album.CoverUrl)
|
|
|
|
if e != nil {
|
|
|
|
panic(e)
|
|
|
|
}
|
|
|
|
defer resp.Body.Close()
|
|
|
|
|
|
|
|
var out io.Writer
|
|
|
|
if multidisc {
|
|
|
|
var outs []io.Writer
|
|
|
|
for i := 1; i <= maxdisc; i++ {
|
|
|
|
o, e := os.Create(fmt.Sprintf("%s/Disc %d/cover.jpg", dirName, i))
|
|
|
|
if e != nil {
|
|
|
|
panic(e)
|
|
|
|
}
|
|
|
|
outs = append(outs, o)
|
|
|
|
}
|
|
|
|
out = io.MultiWriter(outs...)
|
|
|
|
e = nil
|
|
|
|
} else {
|
|
|
|
out, e = os.Create(dirName+"/cover.jpg")
|
|
|
|
}
|
|
|
|
if e != nil {
|
|
|
|
panic(e)
|
|
|
|
}
|
|
|
|
|
|
|
|
_, e = io.Copy(out, resp.Body)
|
|
|
|
if e != nil {
|
|
|
|
panic(e)
|
|
|
|
}
|
|
|
|
|
|
|
|
println(" Done!")
|
|
|
|
|
|
|
|
// Generate Spectrals
|
|
|
|
var choice string
|
|
|
|
for !(choice == "y" || choice == "n") {
|
|
|
|
print("Generate spectrals? [y/n] ")
|
|
|
|
fmt.Scanln(&choice)
|
|
|
|
choice = strings.TrimRight(choice, "\n")
|
|
|
|
}
|
|
|
|
|
|
|
|
if choice == "y" {
|
|
|
|
full := exec.Command(magic["sox"].(string), firstFile, "-n", "remix", "1", "spectrogram",
|
|
|
|
"-x", "3000", "-y", "513", "-z", "120", "-w", "Kaiser", "-o", "SpecFull.png")
|
|
|
|
zoom := exec.Command(magic["sox"].(string), firstFile, "-n", "remix", "1", "spectrogram",
|
|
|
|
"-X", "500", "-y", "1025", "-z", "120", "-w", "Kaiser", "-S", "0:30", "-d", "0:04", "-o", "SpecZoom.png")
|
|
|
|
e = full.Run()
|
|
|
|
if e != nil {
|
|
|
|
println("Error generating full spectral!")
|
|
|
|
} else {
|
|
|
|
println("SpecFull.png written")
|
|
|
|
}
|
|
|
|
e = zoom.Run()
|
|
|
|
if e != nil {
|
|
|
|
println("Error generating zoomed spectral!")
|
|
|
|
} else {
|
|
|
|
println("SpecZoom.png written")
|
|
|
|
}
|
|
|
|
}
|
2017-05-30 14:24:04 +02:00
|
|
|
}
|