func GetSpotifyClient(clientID, clientSecret, refreshToken string) *spotify.Client { // So as not to introduce a web flow into this program, we cheat a bit here // by just using a refresh token and not an access token (because access // tokens expiry very quickly and are therefore not suitable for inclusion // in configuration). This will force a refresh on the first call, but meh. token := new(oauth2.Token) token.Expiry = time.Now().Add(time.Second * -1) token.RefreshToken = refreshToken // See comment above. We've already procured the first access/refresh token // pair outside of this program, so no redirect URL is necessary. authenticator := spotify.NewAuthenticator("no-redirect-url") authenticator.SetAuthInfo(clientID, clientSecret) client := authenticator.NewClient(token) return &client }
func Auth(spotifyClientId string, authRedirectUrl string, cacheWebApiToken bool) *spotify.Client { if spotifyClientId == "" { fmt.Print("Spotify Client ID not set") return nil } auth := spotify.NewAuthenticator(authRedirectUrl, spotify.ScopeUserLibraryRead, spotify.ScopeUserFollowRead, spotify.ScopePlaylistReadCollaborative, spotify.ScopePlaylistReadPrivate) auth.SetAuthInfo(spotifyClientId, "") token := loadToken() if token == nil || hasExpired(token.Expiry) { url := auth.AuthURL("") url = strings.Replace(url, "response_type=code", "response_type=token", -1) fmt.Printf("For web api authorization go to url:\n\n%v\n\n", url) fmt.Print("And paste the access token here: ") reader := bufio.NewReader(os.Stdin) accessToken, _ := reader.ReadString('\n') accessToken = strings.Trim(accessToken, " \n\r") result := strings.Split(accessToken, " ") seconds, err := strconv.ParseInt(strings.Split(result[2], ":")[1], 10, 64) if err != nil { fmt.Printf("Error %v\n", err) return nil } expiry := time.Now().Add(time.Duration(seconds) * time.Second) token = &oauth2.Token{ AccessToken: strings.Split(result[0], ":")[1], TokenType: strings.Split(result[1], ":")[1], Expiry: expiry, } if cacheWebApiToken { persistToken(token) } } client := auth.NewClient(token) return &client }
func main() { flag.Parse() auth := spotify.NewAuthenticator("http://localhost:8888/", spotify.ScopePlaylistReadPrivate, spotify.ScopePlaylistReadCollaborative) authurl := auth.AuthURL("potato") fmt.Println(authurl) coderesult := make(chan *oauth2.Token, 1) http.HandleFunc("/", func(rw http.ResponseWriter, req *http.Request) { rw.WriteHeader(204) fmt.Println("wrote to req") go func() { tok, err := auth.Token("potato", req) if err != nil { log.Fatal(err) } pretty.Println(tok) coderesult <- tok go func() { done.Add(1) defer done.Done() if fi, err := os.OpenFile("auth", os.O_WRONLY|os.O_CREATE|os.O_EXCL, 0600); err == nil { err := json.NewEncoder(fi).Encode(tok) if err != nil { log.Println("Error with token writing:", err) } else { log.Println("Finished writing to file") } fi.Close() } else { log.Println("error opening auth file:", err) } }() }() }) go func() { err := http.ListenAndServe("localhost:8888", nil) if err != nil { log.Fatal(err) } }() fmt.Println("running server") if fi, err := os.Open("auth"); err == nil { defer fi.Close() var mtok oauth2.Token err = json.NewDecoder(fi).Decode(&mtok) if err != nil { log.Println("Bad file for token:", err) } else { coderesult <- &mtok } } else { log.Println("auth fi err:", err) } tok := <-coderesult cli := auth.NewClient(tok) plays, err := cli.CurrentUsersPlaylists() if err != nil { log.Fatal(err) } news := make(chan spotify.SimplePlaylist, 2) disc := make(chan spotify.SimplePlaylist, 1) go func() { for _, p := range plays.Playlists { if strings.Contains(p.Name, "New") { news <- p } else if IsDiscWeek(&p) { disc <- p } } close(news) close(disc) }() fmt.Println("news:\n") for p := range news { pretty.Println(p.Name) } p := <-disc pretty.Println(p) if *dothing { err = MakePlist(&cli, p.ID) if err != nil { log.Println("MakePlist err:", err) } } done.Wait() }