summarylogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.SRCINFO8
-rw-r--r--PKGBUILD9
-rw-r--r--package.json110
-rw-r--r--torrent_collection.js427
-rw-r--r--ysubs.js146
5 files changed, 691 insertions, 9 deletions
diff --git a/.SRCINFO b/.SRCINFO
index 42db126de68a..268f814be735 100644
--- a/.SRCINFO
+++ b/.SRCINFO
@@ -1,6 +1,6 @@
pkgbase = popcorntime-git
pkgdesc = Stream movies and TV shows from torrents
- pkgver = r5909.49c524e
+ pkgver = r5929.1815690
pkgrel = 1
url = https://popcorntime.sh
install = popcorntime.install
@@ -25,9 +25,9 @@ pkgbase = popcorntime-git
conflicts = popcorn-time-ce
options = !strip
source = git+https://github.com/popcorn-official/popcorn-desktop.git#branch=master
- source = https://popcorntime.sh/package.json
- source = https://popcorntime.sh/torrent_collection.js
- source = https://popcorntime.sh/ysubs.js
+ source = package.json
+ source = torrent_collection.js
+ source = ysubs.js
source = popcorntime.desktop
sha256sums = SKIP
sha256sums = cb1eea1c8e40b8d65014ffe126039221da813aa5bdfc838b998513bdce47cb0c
diff --git a/PKGBUILD b/PKGBUILD
index da21797c652d..490fde4ddfea 100644
--- a/PKGBUILD
+++ b/PKGBUILD
@@ -5,7 +5,7 @@
pkgname=popcorntime-git
_pkgname=popcorntime
_gitname=popcorn-desktop
-pkgver=r5909.49c524e
+pkgver=r5929.1815690
pkgrel=1
pkgdesc="Stream movies and TV shows from torrents"
arch=('i686' 'x86_64')
@@ -18,9 +18,9 @@ provides=('popcorntime')
options=('!strip')
install=popcorntime.install
source=("git+https://github.com/popcorn-official/${_gitname}.git#branch=master"
- "https://popcorntime.sh/package.json"
- "https://popcorntime.sh/torrent_collection.js"
- "https://popcorntime.sh/ysubs.js"
+ "package.json"
+ "torrent_collection.js"
+ "ysubs.js"
"${_pkgname}.desktop")
sha256sums=('SKIP'
'cb1eea1c8e40b8d65014ffe126039221da813aa5bdfc838b998513bdce47cb0c'
@@ -74,4 +74,3 @@ package() {
}
# vim:set ts=2 sw=2 et:
-
diff --git a/package.json b/package.json
new file mode 100644
index 000000000000..f6f36da3841b
--- /dev/null
+++ b/package.json
@@ -0,0 +1,110 @@
+{
+ "name": "Popcorn-Time",
+ "companyName": "Popcorn Time",
+ "installIcon": "./src/app/images/popcorntime.ico",
+ "unInstallIcon": "./src/app/images/butter_uninstall.ico",
+ "homepage": "http://popcorntime.sh/",
+ "bugs": "https://github.com/popcorn-official/popcorn-desktop/issues",
+ "repository": {
+ "type": "git",
+ "url": "https://github.com/popcorn-official/popcorn-desktop.git"
+ },
+ "license": "GPL-3.0",
+ "main": "app://host/src/app/index.html",
+ "version": "0.3.9",
+ "releaseName": "There's nothing on TV",
+ "scripts": {
+ "postinstall": "node_modules/.bin/bower install --config.interactive=false && grunt setup",
+ "postupdate": "node_modules/.bin/bower update --config.interactive=false && grunt setup",
+ "test": "grunt --verbose",
+ "start": "gulp start"
+ },
+ "window": {
+ "title": "Popcorn Time",
+ "icon": "./src/app/images/icon.png",
+ "toolbar": false,
+ "frame": false,
+ "min_width": 960,
+ "min_height": 520,
+ "resizable": true,
+ "show": false,
+ "position": "center"
+ },
+ "dependencies": {
+ "butter-provider": "git+https://github.com/butterproviders/butter-provider",
+ "butter-settings-popcorntime.io": "git+https://github.com/popcorn-official/butter-settings-popcorn",
+ "butter-provider-yts": "git+https://github.com/team-pct/butter-provider-yts",
+ "butter-provider-tvapi": "git+https://github.com/team-pct/butter-provider-tvapi",
+ "butter-provider-haruhichan": "git+https://github.com/hackhackhack/butter-provider-haruhichan",
+ "butter-provider-vodo": "git+https://github.com/butterproviders/butter-provider-vodo",
+ "popcorn-txt-api": "git+https://github.com/hackhackhack/popcorn-txt-api",
+
+ "adm-zip": "0.4.7",
+ "airplay-js": "git+https://github.com/guerrerocarlos/node-airplay-js.git",
+ "async": "1.5.0",
+ "chromecast-js": "git+https://github.com/alxhotel/chromecast-js.git",
+ "kat-api": "git+https://github.com/team-pct/kat-api",
+ "rarbg-api": "git+https://github.com/team-pct/rarbg-api",
+ "defer-request": "0.0.2",
+ "i18n": "0.x.x",
+ "iconv-lite": "0.x.x",
+ "jschardet": "1.4.1",
+ "json-rpc2": "1.0.2",
+ "markdown": "0.5.x",
+ "memoizee": "0.x.x",
+ "mkdirp": "*",
+ "moment": ">=2.11.2",
+ "mv": "2.x.x",
+ "nedb": "1.4.0",
+ "node-captions": "0.4.6",
+ "node-tvdb": "1.6.x",
+ "node-webkit-fdialogs": "latest",
+ "nodecast-js": "^1.0.1",
+ "opensubtitles-api": "^2.3.x",
+ "os-name": "1.x.x",
+ "peerflix": "git+https://github.com/popcorn-official/peerflix.git",
+ "q": "2.0.3",
+ "read-torrent": "1.3.0",
+ "readdirp": "*",
+ "request": "2.x.x",
+ "rimraf": "2.x.x",
+ "sanitizer": "0.x.x",
+ "semver": "5.x.x",
+ "send": "0.13.x",
+ "strike-api": "0.2.0",
+ "tar": "2.2.1",
+ "temp": "0.x.x",
+ "torrent-tracker-health": "0.x.x",
+ "trakt.tv": "1.x.x",
+ "trakt.tv-ondeck": "0.x",
+ "underscore": "1.x.x",
+ "upnp-mediarenderer-client": "1.2.2",
+ "urijs": "1.x.x",
+ "xmlbuilder": "4.1.0"
+ },
+ "devDependencies": {
+ "bower": "1.7.x",
+ "del": "^2.2.0",
+ "grunt": "0.4.5",
+ "grunt-bower-clean": "0.x.x",
+ "grunt-contrib-clean": "1.x.x",
+ "grunt-contrib-compress": "1.x.x",
+ "grunt-contrib-jshint": "1.x.x",
+ "grunt-contrib-stylus": "1.x.x",
+ "grunt-contrib-watch": "0.6.x",
+ "grunt-exec": "0.4.x",
+ "grunt-githooks": "0.x.x",
+ "grunt-jsbeautifier": "*",
+ "grunt-nw-builder": "^2.0.0",
+ "grunt-shell": "1.x.x",
+ "gulp": "^3.9.0",
+ "gulp-stylus": "^2.3.0",
+ "load-grunt-tasks": "3.x.x",
+ "nib": "^1.1.0",
+ "nw-builder": "^2.0.2",
+ "nw-gyp": "0.x.x",
+ "run-sequence": "^1.1.5",
+ "stylus": "0.x.x",
+ "yargs": "^3.31.0"
+ }
+}
diff --git a/torrent_collection.js b/torrent_collection.js
new file mode 100644
index 000000000000..89d33492db9b
--- /dev/null
+++ b/torrent_collection.js
@@ -0,0 +1,427 @@
+(function (App) {
+ 'use strict';
+
+ var clipboard = gui.Clipboard.get(),
+ collection = path.join(data_path + '/TorrentCollection/');
+
+ var TorrentCollection = Backbone.Marionette.ItemView.extend({
+ template: '#torrent-collection-tpl',
+ className: 'torrent-collection',
+
+ events: {
+ 'mousedown .file-item': 'openFileSelector',
+ 'mousedown .result-item': 'onlineOpen',
+ 'mousedown .item-delete': 'deleteItem',
+ 'mousedown .item-rename': 'renameItem',
+ 'mousedown .magnet-icon': 'openMagnet',
+ 'click .collection-delete': 'clearCollection',
+ 'click .collection-open': 'openCollection',
+ 'click .collection-import': 'importItem',
+ 'click .notorrents-frame': 'importItem',
+ 'click .online-search': 'onlineSearch',
+ 'click .engine-icon': 'changeEngine',
+ 'submit #online-form': 'onlineSearch',
+ 'click .online-back': 'onlineClose',
+ 'contextmenu #online-input': 'rightclick_search'
+ },
+
+ initialize: function () {
+ if (!fs.existsSync(collection)) {
+ fs.mkdirSync(collection);
+ console.debug('TorrentCollection: data directory created');
+ }
+ this.files = fs.readdirSync(collection);
+ this.searchEngine = Settings.onlineSearchEngine;
+ },
+
+ onShow: function () {
+ Mousetrap.bind(['esc', 'backspace'], function (e) {
+ $('#filterbar-torrent-collection').click();
+ });
+
+ this.render();
+ },
+
+ onRender: function () {
+ $('.engine-icon').removeClass('active');
+ $('#' + this.searchEngine.toLowerCase() + '-icon').addClass('active');
+ $('#online-input').focus();
+ if (this.files[0]) {
+ $('.notorrents-info').css('display', 'none');
+ $('.collection-actions').css('display', 'block');
+ $('.torrents-info').css('display', 'block');
+ }
+
+ this.$('.tooltipped').tooltip({
+ delay: {
+ 'show': 800,
+ 'hide': 100
+ }
+ });
+ },
+
+ changeEngine: function (e) {
+ e.preventDefault();
+
+ Settings.onlineSearchEngine = this.searchEngine = e.currentTarget.dataset.id;
+ AdvSettings.set('onlineSearchEngine', this.searchEngine);
+
+ if ($('#online-input').val().length !== 0) {
+ $('.engine-icon').removeClass('active');
+ $('#' + this.searchEngine.toLowerCase() + '-icon').addClass('active');
+ this.onlineSearch();
+ } else {
+ this.render();
+ }
+ },
+
+ onlineSearch: function (e) {
+ if (e) {
+ e.preventDefault();
+ }
+ var that = this;
+ var input = $('#online-input').val();
+ var category = $('.online-categories > select').val();
+ AdvSettings.set('OnlineSearchCategory', category);
+ if (category === 'TV Series') {
+ category = 'TV';
+ }
+ var current = $('.onlinesearch-info > ul.file-list').html();
+
+ if (input === '' && current === '') {
+ return;
+ } else if (input === '' && current !== '') {
+ this.onlineClose();
+ return;
+ }
+
+ $('.onlinesearch-info>ul.file-list').html('');
+
+ $('.online-search').removeClass('fa-search').addClass('fa-spin fa-spinner');
+
+ var index = 0;
+
+ if (this.searchEngine === 'KAT') {
+
+ var kat = require('kat-api');
+ kat.search({
+ query: input.toLocaleLowerCase(),
+ category: category.toLocaleLowerCase() //IT IS BUGGED ATM
+ }).then(function (data) {
+ console.debug('KAT search: %s results', data.results.length);
+ data.results.forEach(function (item) {
+ var itemModel = {
+ title: item.title,
+ magnet: item.magnet,
+ seeds: item.seeds,
+ peers: item.peers,
+ size: Common.fileSize(parseInt(item.size)),
+ index: index
+ };
+
+ if (item.title.match(/trailer/i) !== null && input.match(/trailer/i) === null) {
+ return;
+ }
+ that.onlineAddItem(itemModel);
+ index++;
+ });
+
+ that.$('.tooltipped').tooltip({
+ html: true,
+ delay: {
+ 'show': 50,
+ 'hide': 50
+ }
+ });
+ $('.notorrents-info,.torrents-info').hide();
+ $('.online-search').removeClass('fa-spin fa-spinner').addClass('fa-search');
+ $('.onlinesearch-info').show();
+ if (index === 0) {
+ $('.onlinesearch-info>ul.file-list').html('<br><br><div style="text-align:center;font-size:30px">' + i18n.__('No results found') + '</div>');
+ }
+ }).catch(function (err) {
+ console.debug('KAT search failed:', err.message);
+ var error;
+ if (err.message === 'No results') {
+ error = 'No results found';
+ } else {
+ error = 'Failed!';
+ }
+ $('.onlinesearch-info>ul.file-list').html('<br><br><div style="text-align:center;font-size:30px">' + i18n.__(error) + '</div>');
+
+ $('.online-search').removeClass('fa-spin fa-spinner').addClass('fa-search');
+ $('.notorrents-info,.torrents-info').hide();
+ $('.onlinesearch-info').show();
+ });
+
+ } else {
+
+ var rarbg = require('rarbg-api');
+ rarbg.search(input, category).then(function (result) {
+ console.debug('rarbg search: %s results', result.results.length);
+ result.results.forEach(function (item) {
+ var itemModel = {
+ title: item.title,
+ magnet: item.torrentLink,
+ seeds: item.seeds,
+ peers: item.leechs,
+ size: Common.fileSize(parseInt(item.size)),
+ index: index
+ };
+
+ if (item.title.match(/trailer/i) !== null && input.match(/trailer/i) === null) {
+ return;
+ }
+ that.onlineAddItem(itemModel);
+ index++;
+ });
+
+ that.$('.tooltipped').tooltip({
+ html: true,
+ delay: {
+ 'show': 50,
+ 'hide': 50
+ }
+ });
+ $('.notorrents-info,.torrents-info').hide();
+ $('.online-search').removeClass('fa-spin fa-spinner').addClass('fa-search');
+ $('.onlinesearch-info').show();
+ if (index === 0) {
+ $('.onlinesearch-info>ul.file-list').html('<br><br><div style="text-align:center;font-size:30px">' + i18n.__('No results found') + '</div>');
+ }
+ }).catch(function (err) {
+ console.debug('rarbg search failed:', err.message || err);
+ var error;
+ if (err === 'No torrents found') {
+ error = 'No results found';
+ } else if (err && err.match(/bot/i) !== null) {
+ error = 'RARBG thinks you\'re a bot, check <a class="links" href="https://www.rarbg.com/bot_check.php">https://www.rarbg.com/bot_check.php</a>';
+ } else if (err === 'There was a problem loading Rarbg') {
+ error = 'RARBG could not be contacted<br>Please retry or check <a class="links" href="https://www.rarbg.com/">https://rarbg.com/</a>';
+ } else {
+ error = 'Failed!';
+ }
+ $('.onlinesearch-info>ul.file-list').html('<br><br><div style="text-align:center;font-size:30px">' + i18n.__(error) + '</div>');
+
+ $('.online-search').removeClass('fa-spin fa-spinner').addClass('fa-search');
+ $('.notorrents-info,.torrents-info').hide();
+ $('.onlinesearch-info').show();
+ });
+ }
+ },
+
+ onlineAddItem: function (item) {
+ var ratio = item.peers > 0 ? item.seeds / item.peers : +item.seeds;
+ $('.onlinesearch-info>ul.file-list').append(
+ '<li class="result-item" data-index="' + item.index + '" data-file="' + item.magnet + '"><a>' + item.title + '</a><div class="item-icon magnet-icon tooltipped" data-toogle="tooltip" data-placement="right" title="' + i18n.__('Magnet link') + '"></div><i class="online-size tooltipped" data-toggle="tooltip" data-placement="left" title="' + i18n.__('Ratio:') + ' ' + ratio.toFixed(2) + '<br>' + i18n.__('Seeds:') + ' ' + item.seeds + ' - ' + i18n.__('Peers:') + ' ' + item.peers + '">' + item.size + '</i></li>'
+ );
+ if (item.seeds === 0) { // recalc the peers/seeds
+ var torrent = item.magnet.split('&tr')[0] + '&tr=udp://tracker.openbittorrent.com:80/announce' + '&tr=udp://9.rarbg.com:2710/announce' + '&tr=udp://tracker.coppersurfer.tk:6969' + '&tr=udp://tracker.publicbt.com:80/announce';
+ require('torrent-tracker-health')(torrent, {
+ timeout: 1000
+ }).then(function (res) {
+ //console.log('torrent index %s: %s -> %s (seeds)', item.index, item.seeds, res.seeds)
+ ratio = res.peers > 0 ? res.seeds / res.peers : +res.seeds;
+ $('.result-item[data-index=' + item.index + '] i').attr('data-original-title', i18n.__('Ratio:') + ' ' + ratio.toFixed(2) + '<br>' + i18n.__('Seeds:') + ' ' + res.seeds + ' - ' + i18n.__('Peers:') + ' ' + res.peers);
+ });
+ }
+ },
+
+ onlineOpen: function (e) {
+ var file = $(e.currentTarget).context.dataset.file;
+ Settings.droppedMagnet = file;
+ window.handleTorrent(file);
+ },
+
+ onlineClose: function () {
+ $('.onlinesearch-info>ul.file-list').html('');
+ $('.onlinesearch-info').hide();
+ this.render();
+ },
+
+ rightclick_search: function (e) {
+ e.stopPropagation();
+ var search_menu = new this.context_Menu(i18n.__('Cut'), i18n.__('Copy'), i18n.__('Paste'));
+ search_menu.popup(e.originalEvent.x, e.originalEvent.y);
+ },
+
+ context_Menu: function (cutLabel, copyLabel, pasteLabel) {
+ var menu = new gui.Menu(),
+
+ cut = new gui.MenuItem({
+ label: cutLabel || 'Cut',
+ click: function () {
+ document.execCommand('cut');
+ }
+ }),
+
+ copy = new gui.MenuItem({
+ label: copyLabel || 'Copy',
+ click: function () {
+ document.execCommand('copy');
+ }
+ }),
+
+ paste = new gui.MenuItem({
+ label: pasteLabel || 'Paste',
+ click: function () {
+ var text = clipboard.get('text');
+ $('#online-input').val(text);
+ }
+ });
+
+ menu.append(cut);
+ menu.append(copy);
+ menu.append(paste);
+
+ return menu;
+ },
+
+ openFileSelector: function (e) {
+ var _file = $(e.currentTarget).context.innerText,
+ file = _file.substring(0, _file.length - 2); // avoid ENOENT
+
+ if (_file.indexOf('.torrent') !== -1) {
+ Settings.droppedTorrent = file;
+ window.handleTorrent(collection + file);
+ } else { // assume magnet
+ var content = fs.readFileSync(collection + file, 'utf8');
+ Settings.droppedMagnet = content;
+ Settings.droppedStoredMagnet = file;
+ window.handleTorrent(content);
+ }
+ },
+
+ openMagnet: function (e) {
+ this.$('.tooltip').css('display', 'none');
+ e.preventDefault();
+ e.stopPropagation();
+
+ var magnetLink;
+
+ if ($(e.currentTarget.parentNode).context.className === 'file-item') {
+ // stored
+ var _file = $(e.currentTarget.parentNode).context.innerText,
+ file = _file.substring(0, _file.length - 2); // avoid ENOENT
+ magnetLink = fs.readFileSync(collection + file, 'utf8');
+ } else {
+ // search result
+ magnetLink = $(e.currentTarget.parentNode).context.attributes['data-file'].value;
+ }
+
+ if (e.button === 2) { //if right click on magnet link
+ var clipboard = gui.Clipboard.get();
+ clipboard.set(magnetLink, 'text'); //copy link to clipboard
+ $('.notification_alert').text(i18n.__('The magnet link was copied to the clipboard')).fadeIn('fast').delay(2500).fadeOut('fast');
+ } else {
+ gui.Shell.openExternal(magnetLink);
+ }
+ },
+
+ deleteItem: function (e) {
+ this.$('.tooltip').css('display', 'none');
+ e.preventDefault();
+ e.stopPropagation();
+
+ var _file = $(e.currentTarget.parentNode).context.innerText,
+ file = _file.substring(0, _file.length - 2); // avoid ENOENT
+
+ fs.unlinkSync(collection + file);
+ console.debug('Torrent Collection: deleted', file);
+
+ // update collection
+ this.files = fs.readdirSync(collection);
+ this.render();
+ },
+
+ renameItem: function (e) {
+ this.$('.tooltip').css('display', 'none');
+ e.preventDefault();
+ e.stopPropagation();
+
+ var _file = $(e.currentTarget.parentNode).context.innerText,
+ file = _file.substring(0, _file.length - 2), // avoid ENOENT
+ isTorrent = false;
+
+ if (file.endsWith('.torrent')) {
+ isTorrent = 'torrent';
+ }
+
+ var newName = this.renameInput(file);
+ if (!newName) {
+ return;
+ }
+
+ if (isTorrent) { //torrent
+ if (!newName.endsWith('.torrent')) {
+ newName += '.torrent';
+ }
+ } else { //magnet
+ if (newName.endsWith('.torrent')) {
+ newName = newName.replace('.torrent', '');
+ }
+ }
+
+ if (!fs.existsSync(collection + newName) && newName) {
+ fs.renameSync(collection + file, collection + newName);
+ console.debug('Torrent Collection: renamed', file, 'to', newName);
+ } else {
+ $('.notification_alert').show().text(i18n.__('This name is already taken')).delay(2500).fadeOut(400);
+ }
+
+ // update collection
+ this.files = fs.readdirSync(collection);
+ this.render();
+ },
+
+ renameInput: function (oldName) {
+ var userInput = prompt(i18n.__('Enter new name'), oldName);
+ if (!userInput || userInput === oldName) {
+ return false;
+ } else {
+ return userInput;
+ }
+ },
+
+ clearCollection: function () {
+ deleteFolder(collection);
+ console.debug('Torrent Collection: delete all', collection);
+ App.vent.trigger('torrentCollection:show');
+ },
+
+ openCollection: function () {
+ console.debug('Opening: ' + collection);
+ gui.Shell.openItem(collection);
+ },
+
+ importItem: function () {
+ this.$('.tooltip').css('display', 'none');
+
+ var that = this;
+ var input = document.querySelector('.collection-import-hidden');
+ input.addEventListener('change', function (evt) {
+ var file = $('.collection-import-hidden')[0].files[0];
+ that.render();
+ window.ondrop({
+ dataTransfer: {
+ files: [file]
+ },
+ preventDefault: function () {}
+ });
+ }, false);
+
+ input.click();
+ },
+
+ onDestroy: function () {
+ Mousetrap.unbind(['esc', 'backspace']);
+ },
+
+ closeTorrentCollection: function () {
+ App.vent.trigger('torrentCollection:close');
+ }
+
+ });
+
+ App.View.TorrentCollection = TorrentCollection;
+})(window.App);
diff --git a/ysubs.js b/ysubs.js
new file mode 100644
index 000000000000..a1c0db04d84f
--- /dev/null
+++ b/ysubs.js
@@ -0,0 +1,146 @@
+(function (context) {
+ 'use strict';
+
+ var App = context.App ? context.App : context;
+ var _ = require('underscore');
+ var request = require('request');
+ var Q = require('q');
+
+ var baseUrl = 'http://api.yifysubtitles.com/subs/';
+ var mirrorUrl = 'http://api.ysubs.com/subs/';
+ var prefix = 'http://www.yifysubtitles.com';
+
+ var inherits = require('util').inherits;
+
+ var TTL = 1000 * 60 * 60 * 4; // 4 hours
+ var YSubs = function () {
+ if (!(this instanceof YSubs)) {
+ return new YSubs();
+ }
+
+ App.Providers.CacheProvider.call(this, 'subtitle', TTL);
+ };
+
+ // Language mapping to match PT langcodes
+ var languageMapping = {
+ 'albanian': 'sq',
+ 'arabic': 'ar',
+ 'bengali': 'bn',
+ 'brazilian-portuguese': 'pt-br',
+ 'bulgarian': 'bg',
+ 'bosnian': 'bs',
+ 'chinese': 'zh',
+ 'croatian': 'hr',
+ 'czech': 'cs',
+ 'danish': 'da',
+ 'dutch': 'nl',
+ 'english': 'en',
+ 'estonian': 'et',
+ 'farsi-persian': 'fa',
+ 'finnish': 'fi',
+ 'french': 'fr',
+ 'german': 'de',
+ 'greek': 'el',
+ 'hebrew': 'he',
+ 'hungarian': 'hu',
+ 'indonesian': 'id',
+ 'italian': 'it',
+ 'japanese': 'ja',
+ 'korean': 'ko',
+ 'lithuanian': 'lt',
+ 'macedonian': 'mk',
+ 'malay': 'ms',
+ 'norwegian': 'no',
+ 'polish': 'pl',
+ 'portuguese': 'pt',
+ 'romanian': 'ro',
+ 'russian': 'ru',
+ 'serbian': 'sr',
+ 'slovenian': 'sl',
+ 'spanish': 'es',
+ 'swedish': 'sv',
+ 'thai': 'th',
+ 'turkish': 'tr',
+ 'urdu': 'ur',
+ 'ukrainian': 'uk',
+ 'vietnamese': 'vi'
+ };
+
+
+
+ YSubs.prototype = Object.create(App.Providers.CacheProvider.prototype);
+ YSubs.prototype.constructor = YSubs;
+ YSubs.prototype.config = {
+ name: 'ysubs',
+ type: 'subtitle'
+ };
+
+ var querySubtitles = function (imdbIds) {
+ if (_.isEmpty(imdbIds)) {
+ return {};
+ }
+
+ var url = baseUrl + _.map(imdbIds.sort(), function (id) {
+ return id;
+ }).join('-');
+ var mirrorurl = mirrorUrl + _.map(imdbIds.sort(), function (id) {
+ return id;
+ }).join('-');
+
+ var deferred = Q.defer();
+
+ request({
+ url: url,
+ json: true
+ }, function (error, response, data) {
+ if (error || response.statusCode >= 400 || !data || !data.success) {
+ request({
+ url: mirrorurl,
+ json: true
+ }, function (error, response, data) {
+ if (error || response.statusCode >= 400 || !data || !data.success) {
+ deferred.reject(error);
+ } else {
+ deferred.resolve(data);
+ }
+ });
+ } else {
+ deferred.resolve(data);
+ }
+ });
+
+ return deferred.promise;
+ };
+
+ var formatForPopcorn = function (data) {
+ var allSubs = {};
+ // Iterate each movie
+ _.each(data.subs, function (langs, imdbId) {
+ var movieSubs = {};
+ // Iterate each language
+ _.each(langs, function (subs, lang) {
+ // Pick highest rated
+ var langCode = languageMapping[lang];
+ movieSubs[langCode] = prefix + _.max(subs, function (s) {
+ return s.rating;
+ }).url;
+ });
+
+ // Remove unsupported subtitles
+ var filteredSubtitle = App.Localization.filterSubtitle(movieSubs);
+
+ allSubs[imdbId] = filteredSubtitle;
+ });
+
+ return Common.sanitize(allSubs);
+ };
+
+ YSubs.prototype.query = function (ids) {
+ return Q.when(querySubtitles(ids))
+ .then(formatForPopcorn);
+ };
+
+
+
+ App.Providers.install(YSubs);
+})(window);