-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathspotify.rkt
130 lines (99 loc) · 4.7 KB
/
spotify.rkt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
#lang racket
(provide spotify-auth-url
spotify-auth-code-redirect-url
spotify-auth-token-redirect-url
fetch-token)
(require simple-http)
(require net/uri-codec)
(require net/base64)
(require net/http-client)
(require json)
(require db)
(require racquel)
(require "keys.rkt")
(define spotify-api-base-url "api.spotify.com")
(define spotify-auth-base-url "accounts.spotify.com")
(define host "http://localhost:9090")
(define spotify-auth-code-redirect-url "/spotify-cb")
(define spotify-auth-token-redirect-url "/spotify-token")
(define oauth-headers '("Content-Type: application/x-www-form-urlencoded"
"Accept: application/json"))
(define json-headers '("Content-Type: application/json"
"Accept: application/json"))
(define spotify-headers
(cons (bytes->string/utf-8
(bytes-append #"Authorization: Basic "
(base64-encode (bytes-append client-id #":" client-secret)
#"")))
oauth-headers))
(define (spotify-api-headers access-token)
(cons (string-append "Authorization: Bearer " access-token)
json-headers))
(define spotify-auth-param (alist->form-urlencoded
(list (cons 'client_id
(bytes->string/utf-8 client-id))
(cons 'response_type "code")
(cons 'scope
"playlist-read-private playlist-read-collaborative")
(cons 'redirect_uri
(string-append host
spotify-auth-code-redirect-url))
(cons 'show_dialog "true"))))
(define spotify-auth-url (string-append spotify-auth-base-url
"/authorize" "?"
spotify-auth-param))
;; virtual db connection (aka. - thread pools)
(define db-conn (virtual-connection (λ () (sqlite3-connect #:database "vcr.db"
#:mode 'create))))
(define auth-data%
(data-class object%
(table-name "auth_data")
(init-column (access-token #f "access_token") (expires-in #f "expires_in")
(refresh-token #f "refresh_token") (scope #f "scope")
(token-type #f "token_type"))
(super-new)))
(define (make-auth-data auth-hash)
(println auth-hash)
(if (hash-has-key? auth-hash 'access_token)
(new auth-data%
[access-token (hash-ref auth-hash 'access_token)]
[expires-in (hash-ref auth-hash 'expires_in)]
[refresh-token (hash-ref auth-hash 'refresh_token)]
[scope (hash-ref auth-hash 'scope)]
[token-type (hash-ref auth-hash 'token_type)])
(error (jsexpr->string auth-hash))))
(define (fetch-token code)
(println (string-append "Fetching token for " code))
(define-values (_ status body) (http-sendrecv spotify-auth-base-url "/api/token"
#:ssl? #t
#:method #"POST"
#:data
(alist->form-urlencoded
(list (cons 'grant_type "authorization_code")
(cons 'code code)
(cons 'redirect_uri
(string-append host
spotify-auth-code-redirect-url))))
#:headers spotify-headers))
(insert-data-object db-conn (make-auth-data (read-json body))))
;;(define b (match-let-values (((_ _ _ _ members _ _ _ _) (data-class-info auth-data%)))
;; (map (λ (fields)
;; (list (car fields)
;; (hash-ref a (string->symbol (caddr fields)))))
;; members)))
;;
;;(new auth-data%
;; b)
(println "ooye")
;;(map (λ (obj) (delete-data-object db-conn obj))
(define user-auth-data (first (select-data-objects db-conn auth-data%)))
(define access-token (get-column access-token user-auth-data))
(define (spotify-request url)
(call-with-values (λ ()
(http-sendrecv spotify-api-base-url url
#:ssl? #t
#:method #"GET"
#:headers (spotify-api-headers access-token)))
(λ (_ status body) (read-json body))))
(spotify-request "/v1/me/playlists")
;;(fetch-token spotify-code)