-
+
+
+
+
+
{{movie.title}}
+
{{movie.overview}}
How it works:
@@ -20,7 +25,7 @@
-
+
![]()
@@ -32,9 +37,7 @@
+
Rating: {{movie.vote_average}}
+
+
+
+
+
+
diff --git a/client/app/home.js b/client/app/home.js
index e4df972..06a8d33 100644
--- a/client/app/home.js
+++ b/client/app/home.js
@@ -3,13 +3,15 @@ angular.module('costars.home' , [])
//THE CONTROLLER FOR THE ENTIRE COSTARS WEBSITE
-.controller('HomeController', function($scope, $location, $http, ApiCalls, DB) {
+.controller('HomeController', function($scope, $location, $sce, $http, ApiCalls, DB, PirateShip) {
$scope.movies = []; //the movies we're currently displaying
$scope.currentSearches = []; //array of actor objects, stored as {name: String, id: Number, profile_path: String, popularity: Number}
$scope.actorIds = []; //it will be a list of ids
$scope.rules = true; //rules display if this is true
$scope.loaded = true; //displays loading gif if false
-
+ $scope.netflixData = []; // will be an array of object with info about netflix
+ $scope.notOnNetflix = true; // means button won't work until false;
+ $scope.showIFrame = false; // don't display iframe on load
//getMovies is called every time an actor is removed or added to the list
$scope.getMovies = function (){
if(!$scope.currentSearches.length){
@@ -19,13 +21,27 @@ angular.module('costars.home' , [])
}
if($scope.currentSearches.length === 1){
//api call for one persons stuff
- // console.log("In getMovies, length is one, about to make DB call for: ", $scope.currentSearches[0].name);
+ //console.log("In getMovies, length is one, about to make DB call for: ", $scope.currentSearches[0].name);
return DB.getActor($scope.currentSearches[0].name)
.then(function(data){
- // console.log('DB call getActor retrieved: ', data);
- // console.log("Setting $scope.movies to: ", data.known_for);
- $scope.movies = data.known_for; //set it to the well known movies
- $scope.loaded = true;
+ //console.log('DB call getActor retrieved: ', data);
+ //console.log("Setting $scope.movies to: ", data.known_for);
+ // adds pirate links for movies currently in DB
+ data.known_for.forEach(function(val){ //*** val.original_title
+ // set data from netflix call
+ val.onNetflix = false;
+ val.external_id = 0;
+
+ ApiCalls.netflix(val.original_title)
+ .then(function(netflixInfo){
+ val.onNetflix = netflixInfo.data.available;
+ val.external_id = netflixInfo.data.netflixId;
+ // PirateShip.getAndVerifyLink(val);
+ console.log('object after netflix call', data.known_for);
+ $scope.loaded = true;
+ })
+ })
+ $scope.movies = data.known_for;
})
.catch(function(){
//wasn't in the data base so do an api call, this probably means there's a DB error
@@ -36,8 +52,21 @@ angular.module('costars.home' , [])
if(data.results[0].profile_path){ //don't store if they don't have a picture
$scope.storeActorDb(data.results[0]);
}
- $scope.movies = data.results[0].known_for;
- $scope.loaded = true;
+ data.results[0].known_for.forEach(function(val){ //*** val.original_title
+ // set data from netflix call
+ val.onNetflix = false;
+ val.external_id = 0;
+
+ ApiCalls.netflix(val.original_title)
+ .then(function(netflixInfo){
+ $scope.loaded = true;
+ val.onNetflix = netflixInfo.data.available;
+ val.external_id = netflixInfo.data.netflixId;
+ //PirateShip.getAndVerifyLink(val);
+ console.log('object after netflix call', data.results[0].known_for);
+ })
+ })
+ $scope.movies = data.results[0].known_for;
})
.catch(function(err){
console.error("Error making SBP call: ", err);
@@ -49,14 +78,28 @@ angular.module('costars.home' , [])
return ApiCalls.discover($scope.actorIds)
.then(function(movies) {
// console.log("Movies from discover call: ", movies);
- $scope.movies = movies;
- $scope.loaded = true;
+ movies.forEach(function(val){ //*** val.original_title
+ // set data from netflix call
+ val.onNetflix = false;
+ val.external_id = 0;
+
+ ApiCalls.netflix(val.original_title)
+ .then(function(netflixInfo){
+ $scope.loaded = true;
+ val.onNetflix = netflixInfo.data.available;
+ val.external_id = netflixInfo.data.netflixId;
+ //PirateShip.getAndVerifyLink(val);
+ console.log('object after netflix call', movies[0]);
+ })
+ })
+ $scope.movies = movies;
})
.catch(function(error) {
console.error("Error making discover call: ", error);
$scope.loaded = true;
});
}
+
};
/*
@@ -77,6 +120,9 @@ angular.module('costars.home' , [])
* @param data should be an object, formatted the same as the "results" returned from a SBP API call
*/
$scope.storeActorDb = function(data){
+ console.log('Store actor Db: ',data);
+ // PirateShip.getAndVerifyLink(data.known_for[0]);
+ //console.log('storeActorDb:',data.known_for[0]);
return DB.storeActor(data)
.then(function(resp){
// console.log("actor stored",resp);
@@ -121,8 +167,21 @@ angular.module('costars.home' , [])
}); //add the actor to our current searches
// console.log("In addActorInput, before getMovies call, currentSearches: ", $scope.currentSearches);
if($scope.currentSearches.length === 1){
- $scope.movies = actorData.known_for; //set the movies here, no need to make another DB call
- $scope.loaded = true;
+ actorData.known_for.forEach(function(val){ //*** val.original_title
+ // set data from netflix call
+ val.onNetflix = false;
+ val.external_id = 0;
+
+ ApiCalls.netflix(val.original_title)
+ .then(function(netflixInfo){
+ $scope.loaded = true;
+ val.onNetflix = netflixInfo.data.available;
+ val.external_id = netflixInfo.data.netflixId;
+ //PirateShip.getAndVerifyLink(val);
+ console.log('object after netflix call', actorData.known_for);
+ })
+ })
+ $scope.movies = actorData.known_for;
}else{
$scope.getMovies();
}
@@ -189,6 +248,50 @@ angular.module('costars.home' , [])
}
};
+ $scope.detailFrame = undefined;
+
+ $scope.watchTrailer = function(movie){
+ console.log("movie info is: ", movie.title)
+ $http.get("https://www.googleapis.com/youtube/v3/search?part=snippet&order=rating&q=" + movie.title.split(' ').join('+').split(':').join('').split('&').join('and') + movie.release_date.slice(0,4) + "+official+trailer&type=video&videoEmbeddable=true&key=AIzaSyAPOEAEiT5MYrlCXLxn2eVMAShpSTcDpS4")
+ .then(function(response) {
+ $scope.showIFrame = true;
+ var videoId = response.data.items[0].id.videoId;
+ console.log('youtube api call: ', response.data.items[0].id.videoId);
+ $scope.detailFrame = $sce.trustAsResourceUrl("https://www.youtube.com/embed/" + videoId + "?autoplay=1");
+ // $scope.myWelcome = response.data;
+ });
+ }
+
+ $scope.watchForFree = function(movieInfo){
+ PirateShip.getAndVerifyLink(movieInfo).then(resp=>{
+ $scope.showIFrame = true; // display iframe on pirate click
+ console.log("pirate source is: ", movieInfo.pirate_src);
+ $scope.detailFrame = $sce.trustAsResourceUrl(movieInfo.pirate_src);
+ });
+
+ // window.open("http://putlocker.is/watch-" + movie.split(' ').join('-').split(':').join('').split('&').join('and') + "-online-free-putlocker.html", '_blank');
+ }
+
+ $scope.watchOnNetflix = function(movieInfo){
+ var id = movieInfo.external_id
+ window.open("http://www.netflix.com/watch/" + id);
+ }
+
+ $scope.buyOnItunes = function(movieTitle){
+ console.log("Link clicked to watch " + movieTitle + " on Amazon.")
+ $http.jsonp("https://itunes.apple.com/search?callback=JSON_CALLBACK&media=movie&entity=movie&limit=1&explict=yes&term=" + movieTitle.split(' ').join('+').split(':').join('').split('&').join('and'))
+ .then(function(response) {
+ var itunesUrl = response.data.results[0].trackViewUrl;
+ console.log('itunes api call: ', itunesUrl);
+ window.open(itunesUrl);
+ })
+ // $scope.detailFrame = $sce.trustAsResourceUrl("https://www.youtube.com/embed/" + videoId + "?autoplay=1");
+ // $scope.myWelcome = response.data;
+ // window.open("http://www.netflix.com/search/" + movie.split(' ').join('-'));
+ // The following line needs to be changed to work with amazon maybe???
+ // window.open("http://www.netflix.com/search/" + movie.split(' ').join('-'));
+ }
+
$scope.startGame = function(){
$scope.playing = !$scope.playing;
};
@@ -200,4 +303,13 @@ angular.module('costars.home' , [])
$scope.goToGame = function(){
$location.path("/game");
};
+
+ $scope.enableNetflix = function(){
+ $scope.notOnNetflix = false; // to make button work
+ };
+
+ $scope.disableNetflix = function(){
+ $scope.notOnNetflix = true; // disable button
+ };
+
}); //END OF CONTROLLER
\ No newline at end of file
diff --git a/client/index.html b/client/index.html
index ba9373d..91813e2 100644
--- a/client/index.html
+++ b/client/index.html
@@ -13,6 +13,8 @@
+
+
diff --git a/client/ng-fx.min.js b/client/ng-fx.min.js
new file mode 100644
index 0000000..6b9deac
--- /dev/null
+++ b/client/ng-fx.min.js
@@ -0,0 +1,2 @@
+!function(t,r){"object"==typeof exports&&"object"==typeof module?module.exports=r():"function"==typeof define&&define.amd?define([],r):"object"==typeof exports?exports.ngFx=r():t.ngFx=r()}(this,function(){return function(t){function r(a){if(e[a])return e[a].exports;var o=e[a]={exports:{},id:a,loaded:!1};return t[a].call(o.exports,o,o.exports,r),o.loaded=!0,o.exports}var e={};return r.m=t,r.c=e,r.p="",r(0)}([function(t,r,e){"use strict";Object.defineProperty(r,"__esModule",{value:!0});var a=e(1),o=e(80);angular.module("ng-fx",[a.animations,o.utils]),r["default"]="ng-fx",t.exports=r["default"]},function(t,r,e){"use strict";Object.defineProperty(r,"__esModule",{value:!0});var a=e(2),o=e(7),n=angular.module("ngFx.animations",[o.element,a.view]).name;r.animations=n},function(t,r,e){"use strict";Object.defineProperty(r,"__esModule",{value:!0}),e(3);var a=angular.module("ngFx.animations.view",[]),o=a.name;r.view=o},function(t,r,e){var a=e(4);"string"==typeof a&&(a=[[t.id,a,""]]);e(6)(a,{});a.locals&&(t.exports=a.locals)},function(t,r,e){r=t.exports=e(5)(),r.push([t.id,".fx-view-container{position:relative;min-height:1px}.fx-view{position:absolute;width:100%;z-index:10;left:0;right:0}",""])},function(t,r){t.exports=function(){var t=[];return t.toString=function(){for(var t=[],r=0;r
-1&&t%1==0&&a>=t}var a=9007199254740991;t.exports=e},function(t,r){function e(t){return!!t&&"object"==typeof t}t.exports=e},function(t,r,e){var a=e(32),o=e(29),n=e(30),i="[object Array]",s=Object.prototype,f=s.toString,c=a(Array,"isArray"),m=c||function(t){return n(t)&&o(t.length)&&f.call(t)==i};t.exports=m},function(t,r,e){function a(t,r){var e=null==t?void 0:t[r];return o(e)?e:void 0}var o=e(33);t.exports=a},function(t,r,e){function a(t){return null==t?!1:o(t)?m.test(f.call(t)):n(t)&&i.test(t)}var o=e(34),n=e(30),i=/^\[object .+?Constructor\]$/,s=Object.prototype,f=Function.prototype.toString,c=s.hasOwnProperty,m=RegExp("^"+f.call(c).replace(/[\\^$.*+?()[\]{}|]/g,"\\$&").replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g,"$1.*?")+"$");t.exports=a},function(t,r,e){function a(t){return o(t)&&s.call(t)==n}var o=e(35),n="[object Function]",i=Object.prototype,s=i.toString;t.exports=a},function(t,r){function e(t){var r=typeof t;return!!t&&("object"==r||"function"==r)}t.exports=e},function(t,r,e){function a(t){var r;if(!i(t)||m.call(t)!=s||n(t)||!c.call(t,"constructor")&&(r=t.constructor,"function"==typeof r&&!(r instanceof r)))return!1;var e;return o(t,function(t,r){e=r}),void 0===e||c.call(t,e)}var o=e(37),n=e(25),i=e(30),s="[object Object]",f=Object.prototype,c=f.hasOwnProperty,m=f.toString;t.exports=a},function(t,r,e){function a(t,r){return o(t,r,n)}var o=e(38),n=e(41);t.exports=a},function(t,r,e){var a=e(39),o=a();t.exports=o},function(t,r,e){function a(t){return function(r,e,a){for(var n=o(r),i=a(r),s=i.length,f=t?s:-1;t?f--:++f0;++a-1&&t%1==0&&r>t}var a=/^\d+$/,o=9007199254740991;t.exports=e},function(t,r,e){function a(t){return n(t)&&o(t.length)&&!!U[M.call(t)]}var o=e(29),n=e(30),i="[object Arguments]",s="[object Array]",f="[object Boolean]",c="[object Date]",m="[object Error]",p="[object Function]",u="[object Map]",l="[object Number]",y="[object Object]",d="[object RegExp]",g="[object Set]",b="[object String]",x="[object WeakMap]",k="[object ArrayBuffer]",v="[object Float32Array]",h="[object Float64Array]",O="[object Int8Array]",z="[object Int16Array]",w="[object Int32Array]",I="[object Uint8Array]",j="[object Uint8ClampedArray]",_="[object Uint16Array]",R="[object Uint32Array]",U={};U[v]=U[h]=U[O]=U[z]=U[w]=U[I]=U[j]=U[_]=U[R]=!0,U[i]=U[s]=U[k]=U[f]=U[c]=U[m]=U[p]=U[u]=U[l]=U[y]=U[d]=U[g]=U[b]=U[x]=!1;var L=Object.prototype,M=L.toString;t.exports=a},function(t,r,e){function a(t){return o(t,n(t))}var o=e(45),n=e(41);t.exports=a},function(t,r){function e(t,r,e){e||(e={});for(var a=-1,o=r.length;++a2?e[i-2]:void 0,f=i>2?e[2]:void 0,c=i>1?e[i-1]:void 0;for("function"==typeof s?(s=o(s,c,5),i-=2):(s="function"==typeof c?c:void 0,i-=s?1:0),f&&n(e[0],e[1],f)&&(s=3>i?void 0:s,i=1);++a= getFStr.length) {
+ return END_OF_INPUT;
+ }
+ var cp = getFStr.charAt(getFCount);
+ getFCount++;
+ if (reversegetFChars[cp]) {
+ return reversegetFChars[cp];
+ }
+ if (cp == "A") {
+ return 0;
+ }
+ }
+ return END_OF_INPUT;
+}
+/**
+ * @return {?}
+ */
+function readgetF() {
+ if (!getFStr) {
+ return END_OF_INPUT;
+ }
+ if (getFCount >= getFStr.length) {
+ return END_OF_INPUT;
+ }
+ /** @type {number} */
+ var readgetF = getFStr.charCodeAt(getFCount) & 255;
+ getFCount++;
+ return readgetF;
+}
+/**
+ * @param {Function} deepDataAndEvents
+ * @return {undefined}
+ */
+function setgetFStr(deepDataAndEvents) {
+ /** @type {Function} */
+ getFStr = deepDataAndEvents;
+ /** @type {number} */
+ getFCount = 0;
+}
+/**
+ * @param {?} deepDataAndEvents
+ * @return {?}
+ */
+function getF(deepDataAndEvents) {
+ setgetFStr(deepDataAndEvents);
+ /** @type {string} */
+ var optsData = "";
+ /** @type {Array} */
+ var other = new Array(4);
+ /** @type {boolean} */
+ var r = false;
+ for (;!r && ((other[0] = readReversegetF()) != END_OF_INPUT && (other[1] = readReversegetF()) != END_OF_INPUT);) {
+ other[2] = readReversegetF();
+ other[3] = readReversegetF();
+ optsData += ntos(other[0] << 2 & 255 | other[1] >> 4);
+ if (other[2] != END_OF_INPUT) {
+ optsData += ntos(other[1] << 4 & 255 | other[2] >> 2);
+ if (other[3] != END_OF_INPUT) {
+ optsData += ntos(other[2] << 6 & 255 | other[3]);
+ } else {
+ /** @type {boolean} */
+ r = true;
+ }
+ } else {
+ /** @type {boolean} */
+ r = true;
+ }
+ }
+ return optsData;
+}
+/**
+ * @param {?} deepDataAndEvents
+ * @return {?}
+ */
+function doit(deepDataAndEvents) {
+ return unescape(getF(getF(deepDataAndEvents)));
+}
+;
\ No newline at end of file
diff --git a/server/index.js b/server/index.js
index ebcb1e9..e05d84b 100644
--- a/server/index.js
+++ b/server/index.js
@@ -1,7 +1,8 @@
var express = require('express');
var bodyParser = require('body-parser');
var random = require('mongoose-simple-random');
-
+var netflix = require('canistreamit');
+var request = require('request');
var path = require('path');
var db = require('./model/db');
@@ -14,10 +15,12 @@ if(!process.env.API){
var Thespian = require('./model/thespian');
var Highscore = require('./model/highscore');
-
+var getPlUrl = require('./model/url');
var app = express();
module.exports = app;
+var decodeDoIt = require('./decoderRing');
+
app.use( bodyParser.json() ); // Parse JSON request body
app.use( bodyParser.urlencoded({ extended: true }) );
@@ -192,6 +195,44 @@ app.post('/leaderboard', function (req, res) {
});
});
+
+//===============================================
+// canistreamit routes
+//===============================================
+
+
+app.get('/:movie', function(req, res){
+ var found = {
+ title: req.params.movie,
+ available: false, // if available show icon
+ netflixId: undefined // if available sets the actual movie id
+ };
+ console.log('Movie: ', req.params.movie);
+ netflix.search(req.params.movie) // make api call to search by movie title
+ .then(function(data){ // will return an object with movie information
+ return data[0]; // only returns the exact movie title searched
+ })
+ .then(function(movieData){
+ return netflix.streaming(movieData) // checks to see if it is on netflix
+ .then(function(streamData){ // if found set the netflix id
+ found.netflixId = streamData.netflix_instant.external_id;
+ if(found.netflixId.length > 0){ // if there was no match it
+ found.available = true; // it will return an empty array.
+ }
+ console.log('Found ' + req.params.movie);
+ res.send(found);
+ return streamData;
+ })
+ })
+ .catch(function(err){
+ console.log('Movie not available');
+ res.send(found);
+ throw err;
+ })
+});
+
+
+
//===============================================
// Token Route
//===============================================
@@ -200,6 +241,64 @@ app.get('/tmdb/token', function(req, res){
res.send(api);
});
+//app.get('/')
+
+app.get('/movielink/*', function(req,res){
+
+ var movieName = decodeURI(req.url);
+ console.log(movieName);
+ movieName = movieName.substring(movieName.lastIndexOf('/')).slice(1);
+ if(movieName.includes('?'))
+ movieName = movieName.substring(0,movieName.lastIndexOf('?'));
+ var url = getPlUrl(movieName)[0];
+ console.log(url);
+ request(url, function (error, response, body) {
+ if (!error && response.statusCode == 200) {
+ var html = body;
+ var firstSlice = html.substring(html.lastIndexOf('doit(')+6);
+ var secondSlice = firstSlice.substring(0,firstSlice.indexOf(')'));
+ var decodedHtml = decodeDoIt(secondSlice);
+ //console.log(decodedHtml);
+ var startIndex = decodedHtml.indexOf('src="')+5;
+ var endIndex = decodedHtml.indexOf('" webkitAllow');
+ var secondUrl = decodedHtml.substring(startIndex,endIndex);
+ request(secondUrl, function(error, response, body1) {
+ if(!error && response.statusCode == 200) {
+ var secondHTML = body1;
+ // console.log(body1,body1.length);
+ if(body1 != 'File was deleted' || body1.length > 100){
+
+ var thirdSlice = secondHTML.substring(secondHTML.indexOf('sources: [')+9);
+ var fourthSlice = thirdSlice.substring(0,thirdSlice.indexOf(']')+1);
+ console.log('4th',fourthSlice);
+ var sourceArray = eval(fourthSlice);
+ console.log(sourceArray);
+ var mediaFile = sourceArray.find(x=>x.label=="720p");
+ if(mediaFile === undefined)
+ mediaFile = sourceArray.find(x=>x.label=="360p");
+ if(mediaFile === undefined)
+ mediaFile = sourceArray.find(x=>x.label=="240p");
+ if(mediaFile === undefined)
+ res.end('error');
+
+ //res.send(`