| 
									
										
										
										
											2023-09-08 18:48:21 -05:00
										 |  |  | package media | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | import ( | 
					
						
							|  |  |  | 	"encoding/json" | 
					
						
							|  |  |  | 	"errors" | 
					
						
							|  |  |  | 	"fmt" | 
					
						
							|  |  |  | 	"io" | 
					
						
							|  |  |  | 	u "net/url" | 
					
						
							|  |  |  | 	"os/exec" | 
					
						
							|  |  |  | 	"strings" | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	"codeberg.org/danjones000/strip-beats/config" | 
					
						
							| 
									
										
										
										
											2023-09-24 16:40:24 -05:00
										 |  |  | 	"codeberg.org/danjones000/strip-beats/media/brainz" | 
					
						
							| 
									
										
										
										
											2023-09-24 15:26:26 -05:00
										 |  |  | 	h "codeberg.org/danjones000/strip-beats/utils/http" | 
					
						
							| 
									
										
										
										
											2023-09-08 18:48:21 -05:00
										 |  |  | ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | type FPrint struct { | 
					
						
							|  |  |  | 	Duration    float64 | 
					
						
							|  |  |  | 	Fingerprint string | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func Fingerprint(path string) (FPrint, error) { | 
					
						
							|  |  |  | 	pr := FPrint{} | 
					
						
							|  |  |  | 	_, err := exec.LookPath("fpcalc") | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		return pr, errors.Join(errors.New("Unable to find fpcalc in PATH"), err) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	cmd := exec.Command("fpcalc", "-json", path) | 
					
						
							|  |  |  | 	out, err := cmd.Output() | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		return pr, errors.Join(errors.New(fmt.Sprintf("Failed to run %s", strings.Join(cmd.Args, " "))), err) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	err = json.Unmarshal(out, &pr) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		return pr, errors.Join(errors.New("Couldn't parse output from fpcalc"), err) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return pr, nil | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | type IdResults struct { | 
					
						
							|  |  |  | 	Status  string | 
					
						
							|  |  |  | 	Results []IdResult | 
					
						
							|  |  |  | 	Error   IdError | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | type IdResult struct { | 
					
						
							|  |  |  | 	Id         string | 
					
						
							|  |  |  | 	Score      float64 | 
					
						
							| 
									
										
										
										
											2023-09-24 16:40:24 -05:00
										 |  |  | 	Recordings []brainz.Recording | 
					
						
							| 
									
										
										
										
											2023-09-08 18:48:21 -05:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | type IdError struct { | 
					
						
							|  |  |  | 	Code    int | 
					
						
							|  |  |  | 	Message string | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func LookupFingerprint(print FPrint) (IdResults, error) { | 
					
						
							|  |  |  | 	res := IdResults{} | 
					
						
							|  |  |  | 	key := config.GetConfig().AcousticIdKey | 
					
						
							|  |  |  | 	if key == "" { | 
					
						
							|  |  |  | 		return res, errors.New("Missing acoustic_id_key from config") | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	url := "https://api.acoustid.org/v2/lookup" | 
					
						
							| 
									
										
										
										
											2023-09-24 15:26:26 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-09-08 18:48:21 -05:00
										 |  |  | 	form := u.Values{ | 
					
						
							|  |  |  | 		"format":      {"json"}, | 
					
						
							|  |  |  | 		"client":      {key}, | 
					
						
							|  |  |  | 		"duration":    {fmt.Sprintf("%.0f", print.Duration)}, | 
					
						
							|  |  |  | 		"fingerprint": {print.Fingerprint}, | 
					
						
							|  |  |  | 		"meta":        {"recordingids"}} | 
					
						
							| 
									
										
										
										
											2023-09-24 15:26:26 -05:00
										 |  |  | 	resp, err := h.PostForm(url, form) | 
					
						
							| 
									
										
										
										
											2023-09-08 18:48:21 -05:00
										 |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		return res, err | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	defer resp.Body.Close() | 
					
						
							|  |  |  | 	body, err := io.ReadAll(resp.Body) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		return res, err | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	json.Unmarshal(body, &res) | 
					
						
							|  |  |  | 	if res.Status == "error" { | 
					
						
							|  |  |  | 		err = errors.New(res.Error.Message) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	return res, err | 
					
						
							|  |  |  | } |