Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Release 0.0.6 alpha #1

Merged
merged 4 commits into from
Jul 4, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 35 additions & 5 deletions app/api/Player.js
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,34 @@ export default class Player {
);
}

initYouTube(itemTitle: string, source: string) {
console.info('Initializing plyr...');
this.currentPlayer = 'plyr';

this.player =
this.player ||
plyr.setup({
volume: 10,
autoplay: true,
showPosterOnEnd: true
})[0];

const player = this.player;

player.source({
title: `${itemTitle} Trailer`,
type: 'video',
sources: [
{
src: source,
type: 'youtube'
}
]
});

return player;
}

async initCast(
provider: ChromecastPlayerProvider,
// selectedDeviceId: string,
Expand All @@ -86,11 +114,13 @@ export default class Player {
this.currentPlayer = 'plyr';
this.powerSaveBlockerId = powerSaveBlocker.start('prevent-app-suspension');

this.player = plyr.setup({
volume: 10,
autoplay: true,
showPosterOnEnd: true
})[0];
this.player =
this.player ||
plyr.setup({
volume: 10,
autoplay: true,
showPosterOnEnd: true
})[0];

const player = this.player;

Expand Down
4 changes: 2 additions & 2 deletions app/api/metadata/MetadataAdapter.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
*/
import OpenSubtitles from 'opensubtitles-api';
import { merge, resolveCache, setCache } from '../torrents/BaseTorrentProvider';
import TheMovieDBMetadataProvider from './TheMovieDBMetadataProvider';
import TheMovieDbMetadataProvider from './TheMovieDbMetadataProvider';
// import TraktMetadataProvider from './TraktMetadataProvider';
import type { runtimeType } from './MetadataProviderInterface';

Expand All @@ -29,7 +29,7 @@ const openSubtitles = new OpenSubtitles({
function MetadataAdapter() {
return [
// new TraktMetadataProvider(),
new TheMovieDBMetadataProvider()
new TheMovieDbMetadataProvider()
];
}

Expand Down
11 changes: 10 additions & 1 deletion app/api/metadata/MetadataProviderInterface.js
Original file line number Diff line number Diff line change
Expand Up @@ -67,8 +67,17 @@ export type contentType = {
images: imagesType
};

type optionsType = {
sort?: 'ratings' | 'popular' | 'trending',
genres?: Array<string>
};

export interface MetadataProviderInterface {
getMovies: (page: number, limit: number) => Promise<contentType>,
getMovies: (
page: number,
limit: number,
options: optionsType
) => Promise<contentType>,
getMovie: (itemId: string) => contentType,
getShows: (page: number, limit: number) => Promise<contentType>,
getShow: (itemId: string) => contentType,
Expand Down
79 changes: 48 additions & 31 deletions app/api/metadata/TheMovieDBMetadataProvider.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import axios from 'axios';
import { parseRuntimeMinutesToObject } from './MetadataAdapter';
import type { MetadataProviderInterface } from './MetadataProviderInterface';

export default class TheMovieDBMetadataProvider
export default class TheMovieDbMetadataProvider
implements MetadataProviderInterface {
apiKey = '809858c82322872e2be9b2c127ccdcf7';

Expand Down Expand Up @@ -53,7 +53,7 @@ export default class TheMovieDBMetadataProvider
baseURL: this.apiUri,
params: {
api_key: this.apiKey,
append_to_response: 'external_ids'
append_to_response: 'external_ids,videos'
}
});
}
Expand Down Expand Up @@ -163,55 +163,72 @@ function formatImage(
return `${imageUri}${size}/${path}`;
}

function formatMetadata(movie, type: string, imageUri: string, genres) {
function formatMetadata(item, type: string, imageUri: string, genres) {
return {
// 'title' property is on movies only. 'name' property is on
// shows only
title: movie.name || movie.title,
year: new Date(movie.release_date).getFullYear(),
title: item.name || item.title,
year: new Date(item.release_date).getFullYear(),
// @DEPRECATE
id: String(movie.id),
id: String(item.id),
ids: {
tmdbId: movie.id,
tmdbId: String(item.id),
imdbId:
movie.imdb_id ||
(movie.external_ids && movie.external_ids.imdb_id
? movie.external_ids.imdb_id
item.imdb_id ||
(item.external_ids && item.external_ids.imdb_id
? item.external_ids.imdb_id
: '')
},
type,
certification: 'n/a',
summary: movie.overview,
genres: movie.genres
? movie.genres.map(genre => genre.name)
: movie.genre_ids
? movie.genre_ids.map(genre => genres[String(genre)])
summary: item.overview,
genres: item.genres
? item.genres.map(genre => genre.name)
: item.genre_ids
? item.genre_ids.map(genre => genres[String(genre)])
: [],
rating: movie.vote_average,
runtime: movie.runtime ? parseRuntimeMinutesToObject(movie.runtime) : 'n/a',
trailer: 'n/a',
rating: item.vote_average,
runtime: item.runtime ||
(item.episode_run_time && item.episode_run_time.length > 0)
? parseRuntimeMinutesToObject(
type === 'movies' ? item.runtime : item.episode_run_time[0]
)
: {
full: 'n/a',
hours: 'n/a',
minutes: 'n/a'
},
trailer: item.videos &&
item.videos.results &&
item.videos.results.length > 0
? `http://youtube.com/watch?v=${item.videos.results[0].key}`
: 'n/a',
images: {
fanart: {
full: formatImage(imageUri, movie.backdrop_path, 'original'),
medium: formatImage(imageUri, movie.backdrop_path, 'w780'),
thumb: formatImage(imageUri, movie.backdrop_path, 'w342')
full: formatImage(imageUri, item.backdrop_path, 'original'),
medium: formatImage(imageUri, item.backdrop_path, 'w780'),
thumb: formatImage(imageUri, item.backdrop_path, 'w342')
},
poster: {
full: formatImage(imageUri, movie.poster_path, 'original'),
medium: formatImage(imageUri, movie.poster_path, 'w780'),
thumb: formatImage(imageUri, movie.poster_path, 'w342')
full: formatImage(imageUri, item.poster_path, 'original'),
medium: formatImage(imageUri, item.poster_path, 'w780'),
thumb: formatImage(imageUri, item.poster_path, 'w342')
}
}
};
}

function formatSeasons(show) {
const firstSeasonIsZero = show.seasons.length > 0
? show.seasons[0].season_number === 0
: false;

return show.seasons.map(season => ({
season: season.season_number + 1,
season: firstSeasonIsZero ? season.season_number + 1 : season.season_number,
overview: show.overview,
id: season.id,
id: String(season.id),
ids: {
tmdbId: season.id
tmdbId: String(season.id)
},
images: {
full: season.poster_path,
Expand All @@ -223,9 +240,9 @@ function formatSeasons(show) {

function formatSeason(season) {
return season.episodes.map(episode => ({
id: episode.id,
id: String(episode.id),
ids: {
tmdbId: episode.id
tmdbId: String(episode.id)
},
title: episode.name,
season: episode.season_number,
Expand All @@ -243,9 +260,9 @@ function formatSeason(season) {

function formatEpisode(episode) {
return {
id: episode.id,
id: String(episode.id),
ids: {
tmdbId: episode.id
tmdbId: String(episode.id)
},
title: episode.name,
season: episode.season_number,
Expand Down
25 changes: 22 additions & 3 deletions app/api/torrents/BaseTorrentProvider.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
// @flow
/* eslint prefer-template: 0 */
import cache from 'lru-cache';
import URL from 'url';
import url from 'url';
import TheMovieDbMetadataProvider from '../metadata/TheMovieDBMetadataProvider';
import type { torrentType } from './TorrentProviderInterface';

export const providerCache = cache({
Expand Down Expand Up @@ -76,6 +77,24 @@ export function determineQuality(
return '';
}

export async function convertTmdbToImdb(tmdbId: string): Promise<string> {
const theMovieDbProvider = new TheMovieDbMetadataProvider();
const movie = await theMovieDbProvider.getMovie(tmdbId);
if (!movie.ids.imdbId) {
throw new Error('Cannot convert tmdbId to imdbId');
}
return movie.ids.imdbId;
}

// export async function convertImdbtoTmdb(imdbId: string): Promise<string> {
// const theMovieDbProvider = new TheMovieDbMetadataProvider();
// const movie = await theMovieDbProvider.getMovie(imdbId);
// if (!movie.ids.imdbId) {
// throw new Error('Cannot convert imdbId to tmdbId');
// }
// return movie.ids.imdbId;
// }

export function formatSeasonEpisodeToString(
season: number,
episode: number
Expand Down Expand Up @@ -201,8 +220,8 @@ export function resolveEndpoint(defaultEndpoint: string, providerId: string) {
case undefined:
return defaultEndpoint;
default:
return URL.format({
...URL.parse(defaultEndpoint),
return url.format({
...url.parse(defaultEndpoint),
hostname: process.env[endpointEnvVariable],
host: process.env[endpointEnvVariable]
});
Expand Down
17 changes: 11 additions & 6 deletions app/api/torrents/PctTorrentProvider.js
Original file line number Diff line number Diff line change
Expand Up @@ -65,37 +65,42 @@ export default class PctTorrentProvider implements TorrentProviderInterface {
const filterTorrents = show
.filter(
eachEpisode =>
eachEpisode.season === season && eachEpisode.episode === episode
String(eachEpisode.season) === String(season) &&
String(eachEpisode.episode) === String(episode)
)
.map(eachEpisode => eachEpisode.torrents);

return filterTorrents.length ? filterTorrents[0] : [];
return filterTorrents.length > 0 ? filterTorrents[0] : [];
}

static formatEpisode({ season, episode, torrents }) {
return {
season,
episode,
torrents: this.formatTorrents(torrents)
torrents: this.formatEpisodeTorrents(torrents)
};
}

static formatMovieTorrent(torrent) {
return {
quality: torrent.quality,
magnet: torrent.url,
seeders: torrent.seed,
seeders: torrent.seed || torrent.seeds,
leechers: 0,
metadata: String(torrent.url),
_provider: 'pct'
};
}

static formatTorrents(torrents) {
static formatEpisodeTorrents(torrents) {
return Object.keys(torrents).map(videoQuality => ({
quality: videoQuality === '0' ? '0p' : videoQuality,
magnet: torrents[videoQuality].url,
seeders: torrents[videoQuality].seeds || torrents[videoQuality].seed,
seeders:
torrents[videoQuality].seeds ||
torrents[videoQuality].seed ||
torrents[videoQuality].seeders ||
0,
leechers: torrents[videoQuality].peers || torrents[videoQuality].peer,
_provider: 'pct'
}));
Expand Down
8 changes: 7 additions & 1 deletion app/api/torrents/TorrentAdapter.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import {
determineQuality,
formatSeasonEpisodeToString,
formatSeasonEpisodeToObject,
convertTmdbToImdb,
sortTorrentsBySeeders,
getHealth,
resolveCache,
Expand All @@ -29,7 +30,7 @@ const providers = [
];

export default async function TorrentAdapter(
itemId: string,
_itemId: string,
type: string,
extendedDetails: extendedDetailsType = {},
returnAll: boolean = false,
Expand All @@ -42,6 +43,11 @@ export default async function TorrentAdapter(
return resolveCache(args);
}

// Temporary hack to convert tmdbIds to imdbIds if necessary
const itemId = !_itemId.includes('tt')
? await convertTmdbToImdb(_itemId)
: _itemId;

const torrentPromises = providers.map(provider =>
provider.provide(itemId, type, extendedDetails)
);
Expand Down
Loading