Skip to content
This repository has been archived by the owner on Feb 16, 2019. It is now read-only.

Latest commit

 

History

History
195 lines (120 loc) · 8.57 KB

v3.md

File metadata and controls

195 lines (120 loc) · 8.57 KB

stremio-addons v3

WIP DOCUMENT used during research for designing the new spec and the P2P extension

Preliminary notes

Some things in the current iteration of stremio-addons are obsolete, such as:

  • .add-ing addon server objects directly
  • validate

Other desing considerations:

  • must be very transport agnostic, in order to support HTTP/HTTPS, mitigate mixed content policy, use fetch; additionally it should be compatible with IPFS
  • eliminate selection policy (and priorities), and instead shift this responsibility to the client
  • consider if fallthrough can be eliminated and the significance of checkArgs reduced to mere type/idPrefix filter
  • SHOULD WE and HOW should we do custom functions / messages; considering the entirely declarative nature of addons, custom methods would only be something that stremio clients themselves have to decide on providing. The best decision seems to be to keep this out of the spec, and stick with the declarative nature of the protocol
  • Custom RESOURCES will be allowed
  • The Discover and Board mechanics can be unified on a models level with a Metadata.getAllCatalogs() that just aggregaates all catalogs from all add-ons
  • Consider moving the Search to an in-house stremio service, maybe ElasticSearch; that would simplify the role of Cinemeta; DISCARDED because we still have add-ons like YouTube where you ABSOLUTELY have to rely on their own search

Analysis

Let us describe a v3 add-on as having:

  1. A manifest
  2. One or more metadata catalogs (listed in the manifest)
  3. Supported type(s) and supported idPrefix(es) - used to determine whether to perform a /stream/ or /meta/

Furthermore stremboard can be replaced by something like Metadata.getAllCatalogs() which gets / keeps track of all catalogs collected.

Start:

src/dialogs/localmedia/localmedia.js:        stremio.fallthrough([addon], "meta.find", { query: { } }, function(err, result) {
src/pages/discover/discover.js:            stremio.fallthrough([].concat(addons), "meta.find", q, receiveRes);
src/pages/search/search.js:                if (imdbMatch) return stremio.meta.get({ query: { imdb_id: imdbMatch[0] } }, function(err, resp) {
node_modules/stremio-models/metadata.js:		stremio.meta.get({ query: query }, function(err, resp) {
node_modules/stremio-models/metadata.js:			stremio.meta.find({ query: q, projection: "lean", limit: idsRetr.length }, function(err, res) {
node_modules/stremio-models/metadata.js:		stremio.meta.find({
node_modules/stremio-models/stream.js:			stremio.fallthrough(group, "stream.find", args, count(function(err, resp, addon) {
node_modules/stremio-models/subtitles.js:		stremio.fallthrough(getSubsAddons("subtitles.hash"), "subtitles.hash", { url: url }, cb);
node_modules/stremio-models/subtitles.js:		stremio.fallthrough(getSubsAddons("subtitles.find"), "subtitles.find", args, function(err, resp) {
node_modules/stremio-models/subtitles.js:		stremio.fallthrough(getSubsAddons("subtitles.tracks"), "subtitles.tracks", { url: url }, function(err, tracks) {
node_modules/stremboard/index.js:                else stremio.meta.find({ query: notif.getMetaQuery() }, function(err, res) {
node_modules/stremboard/index.js:                stremio.meta.find({
node_modules/stremboard/index.js:        stremio.fallthrough([addon], "meta.find", args, function(err, res) {

With comments:


// getting a catalog from local media (local add-on can just have one catalog defined)  - can just use `Metadata.getAllCatalogs()`
src/dialogs/localmedia/localmedia.js:        stremio.fallthrough([addon], "meta.find", { query: { } }, function(err, result) {

// should use `Metadata.getAllCatalogs()`
src/pages/discover/discover.js:            stremio.fallthrough([].concat(addons), "meta.find", q, receiveRes);

// individual meta get - should use /meta/{type}/{id}
src/pages/search/search.js:                if (imdbMatch) return stremio.meta.get({ query: { imdb_id: imdbMatch[0] } }, function(err, resp) {

// individual meta get - should use /meta/{type}/{id}
node_modules/stremio-models/metadata.js:		stremio.meta.get({ query: query }, function(err, resp) {

// retrieveManyById - TRICKY
// should be dropped in discover; it's only used for featured ATM; this should be migrated to the catalogs spec
node_modules/stremio-models/metadata.js:			stremio.meta.find({ query: q, projection: "lean", limit: idsRetr.length }, function(err, res) {

// gets similar - TRICKY
// proposal: we should just make /meta/{type}/{id} return details about similar, and this would be DROPPED
node_modules/stremio-models/metadata.js:		stremio.meta.find({

// should use /stream/{type}/{id}
node_modules/stremio-models/stream.js:			stremio.fallthrough(group, "stream.find", args, count(function(err, resp, addon) {

// will NOT use add-on: localServer/subHash?url=...
node_modules/stremio-models/subtitles.js:		stremio.fallthrough(getSubsAddons("subtitles.hash"), "subtitles.hash", { url: url }, cb);

// should use /subtitles/{type}/{id}
node_modules/stremio-models/subtitles.js:		stremio.fallthrough(getSubsAddons("subtitles.find"), "subtitles.find", args, function(err, resp) 

// will NOT use add-on: localServer/subtitles.json?url=...
node_modules/stremio-models/subtitles.js:		stremio.fallthrough(getSubsAddons("subtitles.tracks"), "subtitles.tracks", { url: url }, function(err, tracks) {

// gets details for a notifItem w/o meta: should be OBSOLETE
node_modules/stremboard/index.js:                else stremio.meta.find({ query: notif.getMetaQuery() }, function(err, res) {

// getting recommendations - TRICKY
// SOLUTION: cinemeta add-on should allow referencing movies like /movie/{type}/wiki:{wikiURL}
node_modules/stremboard/index.js:                stremio.meta.find({

// should use `Metadata.getAllCatalogs()`
node_modules/stremboard/index.js:        stremio.fallthrough([addon], "meta.find", args, function(err, res) {


also name-to-imdb
also stremio-server

Add-on

const addon = new Addon(manifest)

addon.defineCatalogHandler(function(type, id, cb) {
	cb(null, [{
		....
	}])
})

addon.defineMetaHandler(function(type, id, cb) {

})

addon.defineStreamHandler(function(type, id, cb) {

})

// alternative
addon.defineCustomResource('resource', function(type, id, cb) {

})

// --publish flag would immediately publish /manifest.json and all catalogs defined in the manifest (or only `/catalog/movie/top.json`)

Tester tool / UI

stremio-open-ui: bootstrap + angular based UI stremio-addon-lint: ...

ElasticSearch test

docker run -p 9200:9200 -p 9300:9300 -e "discovery.type=single-node" -e http.cors.allow-origin="http://localhost:3030" -e http.cors.enabled=true -e http.cors.allow-headers=X-Requested-With,X-Auth-Token,Content-Type,Content-Length,Authorization -e http.cors.allow-credentials=true -d docker.elastic.co/elasticsearch/elasticsearch:6.2.2
docker run -p 1358:1358 -d appbaseio/dejavu

Design decisions

  • use node-fetch because it has a nice browser fallback to browser natives
  • HTTP addons should use X-Stremio-Addon header on landing pages to point to the manifest.json
  • To solve the legacy exception with IMDB IDs (starting with "tt"), we just consider "tt" a valid ID prefix and no longer require ID prefixes to be split with a colon (":") - this means that new add-ons will have to handle IMDB IDs directly, and to signal you support it you just have to provide idPrefixes: ["tt"] in your manifest

NAT traversal/hole punching

Useful information about that:

https://stackoverflow.com/questions/38786438/libutp-%C2%B5tp-and-nat-traversal-udp-hole-punching?utm_medium=organic&utm_source=google_rich_qa&utm_campaign=google_rich_qa

https://github.com/arvidn/libtorrent/blob/c1ade2b75f8f7771509a19d427954c8c851c4931/src/bt_peer_connection.cpp#L1421

https://github.com/mafintosh/utp-native

https://github.com/mafintosh/hyperdht#dhtholepunchpeer-node-callback

https://webrtchacks.com/an-intro-to-webrtcs-natfirewall-problem/

https://www.html5rocks.com/en/tutorials/webrtc/infrastructure/

https://github.com/nicojanssens/1tp

https://github.com/libp2p/js-libp2p-webrtc-star

https://github.com/libp2p/js-libp2p-webrtc-direct

https://github.com/libp2p/js-libp2p/tree/master/examples/discovery-mechanisms

https://webrtc.github.io/samples/src/content/peerconnection/trickle-ice/

IPNS

Currently, js-ipfs does not provide an IPNS implementation. Implementing it seems straightforward, see:

https://github.com/ipfs/go-ipfs/blob/master/namesys/routing.go#L114

https://github.com/ipfs/go-ipfs/blob/master/namesys/routing.go#L141

https://github.com/ipfs/go-ipfs/blob/master/namesys/routing.go#L157

We are relying on routing though, but this should be easy with supernodes / delegated nodes