Last active
September 29, 2019 01:57
-
-
Save benwaffle/e56087c84b767a9ead0b8b00eefd2241 to your computer and use it in GitHub Desktop.
Import watchlist from IMDb to Trakt.tv
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package main | |
import ( | |
"bytes" | |
"encoding/csv" | |
"encoding/json" | |
"fmt" | |
"io" | |
"io/ioutil" | |
"net/http" | |
"os" | |
"strings" | |
"time" | |
) | |
type DeviceCodeResp struct { | |
DeviceCode string `json:"device_code"` | |
UserCode string `json:"user_code"` | |
VerificationURL string `json:"verification_url"` | |
ExpiresIn int `json:"expires_in"` | |
Interval int `json:"interval"` | |
} | |
type OauthTokenReq struct { | |
Code string `json:"code"` | |
ClientID string `json:"client_id"` | |
ClientSecret string `json:"client_secret"` | |
} | |
type OauthTokenResp struct { | |
AccessToken string `json:"access_token"` | |
TokenType string `json:"token_type"` | |
ExpiresIn int `json:"expires_in"` | |
RefreshToken string `json:"refresh_token"` | |
Scope string `json:"scope"` | |
CreatedAt int `json:"created_at"` | |
} | |
const ( | |
ClientID = "" | |
ClientSecret = "" | |
) | |
func getDeviceCode(client *http.Client) DeviceCodeResp { | |
body := []byte("{\n \"client_id\": \"\"\n}") | |
req, _ := http.NewRequest("POST", "https://api.trakt.tv/oauth/device/code", bytes.NewBuffer(body)) | |
req.Header.Add("Content-Type", "application/json") | |
resp, err := client.Do(req) | |
if err != nil { | |
panic("Errored when sending request to the server") | |
} | |
defer resp.Body.Close() | |
resp_body, _ := ioutil.ReadAll(resp.Body) | |
var obj DeviceCodeResp | |
err = json.Unmarshal(resp_body, &obj) | |
if err != nil { | |
fmt.Println(resp.Status) | |
fmt.Println(string(resp_body)) | |
panic(err) | |
} | |
fmt.Println(obj) | |
return obj | |
} | |
func pollAccessToken(deviceCode DeviceCodeResp, client *http.Client) string { | |
for { | |
tokenReq := OauthTokenReq{ | |
Code: deviceCode.DeviceCode, | |
ClientID: ClientID, | |
ClientSecret: ClientSecret, | |
} | |
body, err := json.Marshal(tokenReq) | |
req, _ := http.NewRequest("POST", "https://api.trakt.tv/oauth/device/token", bytes.NewBuffer(body)) | |
req.Header.Add("Content-Type", "application/json") | |
resp, err := client.Do(req) | |
if err != nil { | |
panic("Errored when sending request to the server") | |
} | |
defer resp.Body.Close() | |
resp_body, _ := ioutil.ReadAll(resp.Body) | |
if resp.StatusCode == 200 { | |
var obj OauthTokenResp | |
err = json.Unmarshal(resp_body, &obj) | |
if err != nil { | |
fmt.Println(resp.Status) | |
fmt.Println(string(resp_body)) | |
panic(err) | |
} | |
fmt.Println(obj) | |
return obj.AccessToken | |
} else if resp.StatusCode == 400 { | |
// no-op | |
} else if resp.StatusCode == 410 { | |
panic("expired") | |
} else { | |
fmt.Printf("unknown status code when polling for token: %d\n", resp.StatusCode) | |
} | |
time.Sleep(time.Duration(deviceCode.Interval) * time.Second) | |
} | |
} | |
func main() { | |
file, _ := os.Open(os.Args[1]) | |
reader := csv.NewReader(file) | |
movies := make([]string, 0) | |
tvShows := make([]string, 0) | |
for { | |
record, err := reader.Read() | |
if err == io.EOF { | |
break | |
} | |
id := record[1] | |
name := record[5] | |
typ := record[7] | |
// fmt.Println(id, name, typ) | |
if typ == "tvSeries" || typ == "tvMiniSeries" || typ == "tvShort" { | |
tvShows = append(tvShows, fmt.Sprintf("{\"ids\": {\"imdb\": \"%s\"}}", id)) | |
} else if typ == "movie" || typ == "tvMovie" || typ == "video" || typ == "short" { | |
movies = append(movies, fmt.Sprintf("{\"ids\": {\"imdb\": \"%s\"}}", id)) | |
} else { | |
fmt.Printf("%s: unknown type %s\n", name, typ) | |
} | |
} | |
client := &http.Client{} | |
code := getDeviceCode(client) | |
fmt.Printf("Go to %s and enter %s . Polling...\n", code.VerificationURL, code.UserCode) | |
accessToken := pollAccessToken(code, client) | |
fmt.Println(accessToken) | |
body := fmt.Sprintf("{\"movies\": [%s], \"shows\": [%s]}", strings.Join(movies, ","), strings.Join(tvShows, ",")) | |
req, _ := http.NewRequest("POST", "https://api.trakt.tv/sync/watchlist", bytes.NewBufferString(body)) | |
req.Header.Add("Content-Type", "application/json") | |
req.Header.Add("Authorization", fmt.Sprintf("Bearer %s", accessToken)) | |
req.Header.Add("trakt-api-version", "2") | |
req.Header.Add("trakt-api-key", ClientID) | |
resp, err := client.Do(req) | |
if err != nil { | |
fmt.Println("Errored when sending request to the server") | |
return | |
} | |
defer resp.Body.Close() | |
resp_body, _ := ioutil.ReadAll(resp.Body) | |
fmt.Println(resp.Status) | |
fmt.Println(string(resp_body)) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment