2024-01-13 04:01:05 +00:00
|
|
|
package main
|
|
|
|
|
|
|
|
import (
|
2024-04-24 16:36:10 +00:00
|
|
|
"flag"
|
2024-01-13 04:01:05 +00:00
|
|
|
"fmt"
|
2024-04-24 16:36:10 +00:00
|
|
|
"log"
|
2024-01-13 04:01:05 +00:00
|
|
|
"os"
|
|
|
|
)
|
|
|
|
|
|
|
|
// Possible algorithm
|
|
|
|
// First call the Genius API to get the lyrics
|
|
|
|
// Second scrape the Google search to get the musicmatch api version of the lyrics
|
|
|
|
// Compare two of them, If there are the same, print one, else print both files
|
|
|
|
|
|
|
|
// Possible flags -o (output) -versbose (print all debug) -search (the actual song you want to search)
|
|
|
|
|
2024-04-24 16:36:10 +00:00
|
|
|
var (
|
|
|
|
printDebug bool
|
|
|
|
useGenius bool
|
|
|
|
useGoogle bool
|
|
|
|
outputFile string
|
|
|
|
errorLog *log.Logger
|
|
|
|
mainLog *log.Logger
|
|
|
|
)
|
2024-01-13 04:01:05 +00:00
|
|
|
|
2024-04-24 16:36:10 +00:00
|
|
|
// flagsSet returns a set of all the flags what were actually set on the
|
|
|
|
// command line.
|
|
|
|
func flagsSet(flags *flag.FlagSet) map[string]bool {
|
|
|
|
s := make(map[string]bool)
|
|
|
|
flags.Visit(func(f *flag.Flag) {
|
|
|
|
s[f.Name] = true
|
|
|
|
})
|
|
|
|
return s
|
|
|
|
}
|
|
|
|
|
|
|
|
func start() int {
|
|
|
|
programName := os.Args[0]
|
|
|
|
errorLog = log.New(os.Stderr, "", 0)
|
|
|
|
mainLog = log.New(os.Stdout, "", 0)
|
|
|
|
|
|
|
|
flags := flag.NewFlagSet(os.Args[0], flag.ExitOnError)
|
|
|
|
flags.Usage = func() {
|
|
|
|
out := flags.Output()
|
|
|
|
fmt.Fprintf(out, "Usage: %v \n\n", programName)
|
|
|
|
fmt.Fprint(out, " This program is used to download lyrics for a song\n")
|
|
|
|
fmt.Fprint(out, " from the internet. There are two modes of operation.\n\n")
|
|
|
|
fmt.Fprint(out, " The first mode is scraping the lyrics from Google. So the operation is this: \n")
|
|
|
|
fmt.Fprint(out, " It first opens a chrome window, searches for the lyrics \n")
|
|
|
|
fmt.Fprint(out, " , and copies the lyrics returned by Google Search to a \n")
|
|
|
|
fmt.Fprint(out, " file defined by you.\n\n")
|
|
|
|
fmt.Fprint(out, " The second mode is getting the lyrics from Genius API. So the operation is this: \n")
|
|
|
|
fmt.Fprint(out, " It then tries to get search for the same song using the \n")
|
|
|
|
fmt.Fprint(out, " Genius API. It then tries to compare the lyrics with the \n")
|
|
|
|
fmt.Fprint(out, " Genius one.\n\n")
|
|
|
|
flags.PrintDefaults()
|
|
|
|
}
|
|
|
|
|
|
|
|
outputFlag := flags.String("output", "", "Optional. Lyrics filename")
|
|
|
|
verboseFlag := flags.Bool("verbose", false, "Optional. Turn on debug. Default is false.")
|
|
|
|
searchFlag := flags.String("search", "", "Required. Name of song to search. If the name of the song is not a single word, put in quotes\"\"")
|
|
|
|
helpFlag := flags.Bool("help", false, "Optional. Print Usage")
|
|
|
|
useGoogleFlag := flags.Bool("google", false, "Optional. Use google.")
|
|
|
|
useGeniusFlag := flags.Bool("genius", false, "Optional. Use genius")
|
|
|
|
configFileFlag := flags.String("configFile", "", "Optional. Use with genius")
|
|
|
|
|
|
|
|
err := flags.Parse(os.Args[1:])
|
|
|
|
if err != nil {
|
|
|
|
errorLog.Printf("Err: %+v", err)
|
|
|
|
return 1
|
|
|
|
}
|
|
|
|
|
|
|
|
if len(flags.Args()) > 1 {
|
|
|
|
errorLog.Println("Error: too many command-line arguments")
|
|
|
|
flags.Usage()
|
|
|
|
return 1
|
|
|
|
}
|
|
|
|
|
|
|
|
allSetFlags := flagsSet(flags)
|
|
|
|
|
|
|
|
if allSetFlags["help"] && (allSetFlags["output"] || allSetFlags["search"] || allSetFlags["verbose"]) {
|
|
|
|
errorLog.Println("Error: if -help is set, -output, -search and -verbose must remain unset")
|
|
|
|
flags.Usage()
|
|
|
|
return 1
|
|
|
|
}
|
|
|
|
|
|
|
|
if !allSetFlags["google"] && !allSetFlags["genius"] {
|
|
|
|
errorLog.Println("Error: One of -google or -genius must be set")
|
|
|
|
flags.Usage()
|
|
|
|
return 1
|
|
|
|
}
|
2024-01-13 04:01:05 +00:00
|
|
|
|
2024-04-24 16:36:10 +00:00
|
|
|
if allSetFlags["google"] && allSetFlags["genius"] {
|
|
|
|
errorLog.Println("Error: if -google is set, -genius must remain unset and vice versa")
|
|
|
|
flags.Usage()
|
|
|
|
return 1
|
|
|
|
}
|
2024-01-13 04:01:05 +00:00
|
|
|
|
2024-04-24 16:36:10 +00:00
|
|
|
if allSetFlags["google"] && allSetFlags["configFile"] {
|
|
|
|
errorLog.Println("Error: if -google is set, -configFile must remain unset and vice versa")
|
|
|
|
flags.Usage()
|
|
|
|
return 1
|
|
|
|
}
|
2024-01-13 04:01:05 +00:00
|
|
|
|
2024-04-24 16:36:10 +00:00
|
|
|
if *helpFlag {
|
|
|
|
flags.Usage()
|
|
|
|
return 0
|
|
|
|
}
|
|
|
|
|
|
|
|
songToSearch := *searchFlag
|
|
|
|
|
|
|
|
if len(songToSearch) == 0 {
|
|
|
|
errorLog.Println("Error: the song name must be provided for search")
|
|
|
|
flags.Usage()
|
|
|
|
return 1
|
|
|
|
}
|
|
|
|
|
|
|
|
if allSetFlags["output"] {
|
|
|
|
outputFile = *outputFlag
|
|
|
|
} else {
|
|
|
|
mainLog.Printf("Using %s as the name of the file(s) for downloaded lyrics..\n", songToSearch)
|
|
|
|
outputFile = fmt.Sprintf("%s_lyrics", songToSearch)
|
|
|
|
}
|
|
|
|
|
|
|
|
printDebug = *verboseFlag
|
|
|
|
if printDebug {
|
|
|
|
mainLog.Printf("Output flag: %s, Debug flag: %t, Search flag: %s\n", outputFile, printDebug, songToSearch)
|
|
|
|
}
|
|
|
|
|
|
|
|
useGenius = *useGeniusFlag
|
|
|
|
useGoogle = *useGoogleFlag
|
|
|
|
|
|
|
|
if useGoogle {
|
|
|
|
err := searchGoogle(songToSearch)
|
|
|
|
if err != nil {
|
|
|
|
errorLog.Printf("Err: %+v", err)
|
|
|
|
return 1
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if useGenius {
|
|
|
|
configFile := *configFileFlag
|
|
|
|
config, err := getConfig(configFile)
|
|
|
|
if err != nil {
|
|
|
|
errorLog.Printf("Err: %+v", err)
|
|
|
|
return 1
|
|
|
|
}
|
|
|
|
GENIUS_API_TOKEN = config.GeniusApiToken
|
|
|
|
err = searchGenius(songToSearch)
|
|
|
|
if err != nil {
|
|
|
|
errorLog.Printf("Err: %+v", err)
|
|
|
|
return 1
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0
|
|
|
|
}
|
|
|
|
|
|
|
|
func main() {
|
|
|
|
os.Exit(start())
|
2024-01-13 04:01:05 +00:00
|
|
|
}
|