Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/jaruba/stremio-imdb-watchlist
Add-on to create a catalog of your IMDB user watchlist.
https://github.com/jaruba/stremio-imdb-watchlist
Last synced: about 2 months ago
JSON representation
Add-on to create a catalog of your IMDB user watchlist.
- Host: GitHub
- URL: https://github.com/jaruba/stremio-imdb-watchlist
- Owner: jaruba
- Created: 2019-02-21T15:04:02.000Z (almost 6 years ago)
- Default Branch: master
- Last Pushed: 2020-04-21T19:01:22.000Z (over 4 years ago)
- Last Synced: 2024-07-31T15:03:00.513Z (5 months ago)
- Language: JavaScript
- Size: 28.3 KB
- Stars: 15
- Watchers: 5
- Forks: 4
- Open Issues: 2
-
Metadata Files:
- Readme: README.md
Awesome Lists containing this project
- awesome-stremio - IMDB Watchlist - Node.js Express Addon Using User Data and Proxying Another Stremio Addon
README
# Stremio Add-on to Add an IMDB Watchlist as a Catalog
This is a simple add-on that uses an ajax call to get a list of items from IMDB, then converts those items to Stremio supported Meta Objects.
## Using locally
**Pre-requisites: Node.js, Git**
```
git clone https://github.com/jaruba/stremio-imdb-watchlist.git
cd stremio-imdb-watchlist
npm i
npm start
```This will print `http://127.0.0.1:7505/[imdb-user-id]/manifest.json`. Add a IMDB list id instead of `[imdb-user-id]` in this URL and [load the add-on in Stremio](https://github.com/jaruba/stremio-imdb-watchlist#7-install-add-on-in-stremio).
## Using remotely
Use `https://1fe84bc728af-imdb-watchlist.beamup.dev/[imdb-user-id]/manifest.json`. Add a IMDB list id instead of `[imdb-user-id]` in this URL and [load the add-on in Stremio](https://github.com/jaruba/stremio-imdb-watchlist#7-install-add-on-in-stremio).
## What is a IMDB List ID
Presuming that the user profile page you want to add is `https://www.imdb.com/user/ur1000000/`, the IMDB user id in this case is `ur1000000`.
## How this add-on was made
### 1. Create a `package.json` and add dependencies
```json
{
"name": "stremio-imdb-watchlist",
"version": "0.0.1",
"description": "Add-on to create a catalog of your IMDB user watchlist.",
"main": "index.js",
"scripts": {
"start": "node index.js"
},
"dependencies": {
"needle": "^2.2.4",
"cheerio": "1.0.0-rc.2",
"express": "^4.16.4",
"cors": "^2.8.5",
"named-queue": "^2.2.1"
}
}
```We will use `needle` to make the html page request, `cheerio` to create a jQuery instance of the HTML content, `express` to create the add-on http server, `cors` to easily add CORS to our http server responses and `named-queue` because although we'll get two catalog requests (one for movies and one for series), we only need to do one ajax request as IMDB lists include both. That's where `named-queue` comes in, as it merges tasks by `id`, so we only do one ajax request to respond to both catalog requests.
### 2. Add-on manifest
In this step, we define the add-on name, description and purpose.
Create an `index.js` file:
```javascript
const manifest = {// set add-on id, any string unique between add-ons
id: 'org.imdbwatchlist',// setting a semver add-on version is mandatory
version: '0.0.1',// human readable add-on name
name: 'IMDB Watchlist Add-on',// description of the add-on
description: 'Add-on to create a catalog of your IMDB user watchlist.',// we only need 'catalog' for this add-on, can also be 'meta', 'stream' and 'subtitles'
resources: ['catalog'],// we set the add-on types, can also be 'tv', 'channel' and 'other'
types: ['movie', 'series'],// we define our catalogs, we'll make one for 'movies' and one for 'series'
catalogs: [
{
// id of catalog, any string unique between this add-ons catalogs
id: 'imdb-movie-watchlist',// human readable catalog name
name: 'IMDB Movie Watchlist',// the type of this catalog provides
type: 'movie'
}, {
id: 'imdb-series-watchlist',
name: 'IMDB Series Watchlist',
type: 'series'
}
]
}// create add-on server
const express = require('express')
const app = express()
const cors = require('cors')// add CORS to server responses
app.use(cors())// respond to the manifest request
app.get('/:imdbUser/manifest.json', (req, res) => {
res.setHeader('Cache-Control', 'max-age=604800') // one week
res.setHeader('Content-Type', 'application/json')
res.send(manifest)
})
```### 3. Get Watchlist ID from User ID
Now we need to get the watchlist ID based on the user ID the add-on user provides.
```javascript
// we'll use needle to request the HTML page
const needle = require('needle')// we'll use cheerio to create a jQuery instance from the HTML page
const cheerio = require('cheerio')// set request headers to have Chrome Android user agent
const headers = {
'User-Agent': 'Mozilla/5.0 (Linux; Android 8.0.0; TA-1053 Build/OPR1.170623.026) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3368.0 Mobile Safari/537.36',
}// object to cache our watchlist ID based on user ID
const cacheLists = {}// function to get list id from user id
function getListId(userId, cb) {// check if it's in cache first
if (cacheLists[userId]) {
cb(false, cacheLists[userId])
return
}// set request referer to the user page of the user id
headers.referer = 'https://m.imdb.com/user/'+userId+'/'// set request url, in this case, the watchlist page of the user
const getUrl = 'https://m.imdb.com/user/'+userId+'/watchlist/'// send request
needle.get(getUrl, { headers }, (err, resp) => {
if (!err && resp && resp.body) {// load jQuery instance from the HTML page
const $ = cheerio.load(resp.body)const listMeta = $('meta[property="pageId"]')
// check to see if the needed HTML element exists
if (!listMeta || listMeta.length != 1) {
cb('Error parsing page #1')
return
}// get list id from page
const listId = listMeta.attr('content')// check list id for sanity
if (!listId || !listId.startsWith('ls')) {
cb('Error parsing page #2')
return
}// cache list id
cacheLists[userId] = listId// respond with the list id
cb(false, listId)} else {
// respond with error
cb(err || 'Empty html body when requesting list id')
}
})
}
```### 4. Proxy a Different Add-on to get List Responses Based on List ID
We won't handle converting IMDB items to Stremio Meta Objects in this guide, we will proxy a different add-on that does this. The secondary add-on will be `stremio-imdb-list`, the source code for it and a guide on how it was made can [found here](https://github.com/jaruba/stremio-imdb-list).
```javascript
// we use `named-queue` to merge more tasks
// with the same user id
const namedQueue = require('named-queue')const queue = new namedQueue((task, cb) => {
// get the list id from user id with the
// function from the previous step
getListId(task.id, cb)
}, Infinity)// where the secondary add-on is hosted
const listEndpoint = 'https://1fe84bc728af-imdb-list.beamup.dev/'function getList(type, userId, cb) {
queue.push({ id: userId }, (listErr, listId) => {
if (listId) {
// list id is correct, let's request the
// list contents from the secondary add-on
const getUrl = listEndpoint + listId + '/date_added/catalog/' + type + '/imdb-' + type + '-list.json'
needle.get(getUrl, { headers }, (err, resp) => {
if (err) {
// failed, send error
cb(err)
} else if (!resp || !resp.body) {
// failed, send error
cb('Empty list response from endpoint')
}
else {
// success, return result
cb(false, resp.body)
}
})
} else {
// request failed, send error
cb(listErr || 'Could not get watchlist id')
}
})
}
```### 5. Catalog Handler
We create the catalog handler, get the user id from the user as it's part of the add-on url and merge http requests for the same user id.
```javascript
// users pass the user id in the add-on url
// this will be available as `req.params.imdbUser`
app.get('/:imdbUser/catalog/:type/:id.json', (req, res) => {// handle failures
function fail(err) {
console.error(err)
res.writeHead(500)
res.end(JSON.stringify({ err: 'handler error' }))
}// ensure request parameters are known
if (req.params.imdbUser && ['movie','series'].indexOf(req.params.type) > -1) {
// use function from previous step
// to get list items from user id
getList(req.params.type, req.params.imdbUser, (err, resp) => {
if (resp) {
res.setHeader('Cache-Control', 'max-age=86400') // one day
res.setHeader('Content-Type', 'application/json')
res.send(resp)
} else
fail(err)
})
} else
fail('Unknown request parameters')
})```
### 6. Run the Add-on Server
```javascript
app.listen(7505, () => {
console.log('http://127.0.0.1:7505/[imdb-user-id]/manifest.json')
})
```### 7. Install Add-on in Stremio
![addlink](https://user-images.githubusercontent.com/1777923/43146711-65a33ccc-8f6a-11e8-978e-4c69640e63e3.png)