Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Imports Letterboxd scores into taste.io

Letterboxd -> Taste.io import script

This script imports your Letterboxd ratings into taste.io.

Usage

Too lazy to make this into an npm package so here's how you could use it. You'll need nodejs and npm.

  1. Save the script
  2. Run npm i through2 JSONStream got cookie x-ray in the script's directory
  3. Login to taste.io and go to your home page. Open your browser's developer tools to the network tab. Refresh the page and look for the request to the /me endpoint. Copy the Authorization token from the headers.
  4. Edit the script at the top with your own letterboxd username and taste.io token.
  5. Run node letterboxd2taste.js
  6. cool ur done now
'use strict'
// CONFIGURE YOUR SETTINGS HERE
// Letterboxd username
const LETTERBOXD_USERNAME = 'rahatarmanahmed'
// Taste.io Authorization token
// Too lazy to impl auth considering my account is facebook oauth'd
const TOKEN = ''
// Maps letterboxd 10 point rating scale to taste.io 4 point scale.
// Adjust if desired
const mapRating = function(rating) {
// 1 2 3 4 5 6 7 8, 9, 10
return [null, 1, 1, 1, 2, 2, 3, 3, 3, 4, 4][rating]
}
// =================================================================
// DOING A CODE HERE DON'T BE LOOKIN DOWN THERE LESS U LOOKIN FOR IT
const through2 = require('through2')
const JSONStream = require('JSONStream')
const got = require('got')
const cookie = require('cookie')
const Xray = require('x-ray')
const x = Xray()
const serializeCookie = function(obj) {
return Object.keys(obj).map((key) => cookie.serialize(key, obj[key])).join('; ')
}
// Scrape my letterboxd watchlist
const url = `http://letterboxd.com/${LETTERBOXD_USERNAME}/films/`
x(url, '.film-list', x('.poster-container', [{
rating: '@data-owner-rating',
title: '.film-poster img@alt'
}]))
.paginate('.paginate-next@href')
.write()
// Stream the scraped titles one by one
.pipe(JSONStream.parse('*'))
.pipe(through2.obj(function({title, rating}, enc, cb){
if(rating == 0) {
console.log(`Skipping ${title}`)
return cb(null)
}
console.log(`Rating ${title} as ${rating} -> ${mapRating(rating)}...`)
got('https://www.taste.io/api/items/search?q=' + encodeURIComponent(title), { headers: {
Authorization: 'Bearer ' + TOKEN
}, json: true })
.then(res => {
if(!res.body.length) return
const cook = cookie.parse(res.headers['set-cookie'].join('; '))
return got.post('https://www.taste.io/api/ratings', {
headers: {
Authorization: 'Bearer ' + TOKEN,
Cookie: serializeCookie(cook),
'X-XSRF-TOKEN': cook['XSRF-TOKEN']
},
body: {
id: res.body[0].slug,
rating: mapRating(rating)
}
})
})
.then(_ => cb(null, 'Success!\n'))
.catch(err => { console.error(err); cb(err) })
}))
// Pipe results to stdout!
.pipe(process.stdout)
.on('error', err => console.error(err))
@johanhermansson

This comment has been minimized.

Copy link

@johanhermansson johanhermansson commented Aug 7, 2019

Updated script to new Letterboxd/Taste structure: https://gist.github.com/johanhermansson/aca79bd3d1171cbce50960065fa9ea74

@pedromga

This comment has been minimized.

Copy link

@pedromga pedromga commented Sep 29, 2019

just what i was looking for. does this still work? if so, what happens if the movie is missing from taste database? thanks in advance.

@rahatarmanahmed

This comment has been minimized.

Copy link
Owner Author

@rahatarmanahmed rahatarmanahmed commented Sep 29, 2019

i dunno i just wrote this in an hour 3 years ago, it's not exactly production quality.

@johanhermansson

This comment has been minimized.

Copy link

@johanhermansson johanhermansson commented Sep 30, 2019

@pedromga Check out my Gist above, I used it myself in August :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.