package main import ( "flag" "fmt" "log" "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) var ( printDebug bool useGenius bool useGoogle bool outputFile string errorLog *log.Logger mainLog *log.Logger ) // 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 } if allSetFlags["google"] && allSetFlags["genius"] { errorLog.Println("Error: if -google is set, -genius must remain unset and vice versa") flags.Usage() return 1 } if allSetFlags["google"] && allSetFlags["configFile"] { errorLog.Println("Error: if -google is set, -configFile must remain unset and vice versa") flags.Usage() return 1 } 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()) }