Created
September 10, 2015 14:27
-
-
Save kitze/87ab203d382c46fb0b3e to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
app.service('YouTubeService', function ($q, $rootScope, $timeout, MockService, $cordovaOauth) { | |
const clientId = 'hidden'; | |
const youtubeScope = 'https://gdata.youtube.com'; | |
const serverKey = 'hidden'; | |
var isRealDevice = window.cordova !== undefined; | |
var results = []; | |
var pageTokens = []; | |
var initializeDefer; | |
var mock = true; | |
var channelPlaylistIdMap = MockService.getChannelPlaylistIdMap(); | |
var lastWeek = new moment().subtract(7, 'days'); | |
function authorizeApi() { | |
var deferred = $q.defer(); | |
// if the token exists in local storage use it to authorize the api | |
var localStorageToken = window.localStorage.getItem('access_token'); | |
console.log('localStorageToken', localStorageToken); | |
if (!_.isEmpty(localStorageToken)){ | |
console.log('local token is fine'); | |
deferred.resolve({'access_token': localStorageToken}); | |
return deferred.promise; | |
} | |
console.log('local token is invalid, authenticating again!'); | |
// if it's a real device or emulator a web client should be spawned to authenticate the user with $cordova Oauth | |
if (isRealDevice) { | |
return $cordovaOauth.google(clientId, [youtubeScope]); | |
} | |
else { | |
// if the code is tested in a browser the default gapi authorize function is called | |
gapi.auth.authorize( | |
{ | |
client_id: clientId, | |
scope: [youtubeScope], | |
immediate: true | |
}, function (authResult) { | |
deferred.resolve(authResult); | |
}); | |
return deferred.promise; | |
} | |
} | |
function initialize() { | |
console.log('initializing'); | |
initializeDefer = $q.defer(); | |
if (gapi.client === undefined) { | |
initializeDefer.reject({error: 'gapi.client is not defined'}); | |
return initializeDefer.promise; | |
} | |
console.log('gapi.client is defined!'); | |
gapi.client.setApiKey(serverKey); | |
$timeout(function () { | |
authorizeApi().then(function (authResult) { | |
if (authResult && authResult.access_token !== undefined) { | |
console.log('authResult', authResult); | |
window.localStorage.setItem('access_token', authResult.access_token); | |
gapi.auth.setToken({ | |
'access_token': authResult.access_token | |
}); | |
gapi.client.load('youtube', 'v3').then(function (res) { | |
console.log('youtube client loaded'); | |
$rootScope.$broadcast('scroll.refreshComplete'); | |
initializeDefer.resolve(true); | |
}); | |
} | |
}, function (error) { | |
console.error('error', error); | |
}); | |
}, 1); | |
return initializeDefer.promise; | |
} | |
function errorHandler(reason) { | |
console.log('Error: ' + reason.result.error.message); | |
} | |
function morePagesToLoad(response) { | |
return pageTokens.indexOf(response.result.nextPageToken) === -1 | |
} | |
function getSubs(nextPageToken) { | |
var apiDefer = $q.defer(); | |
initialize() | |
.then(function () { | |
console.log('initialize success!!'); | |
var params = { | |
'part': 'snippet', | |
'mine': true, | |
'maxResults': 50 | |
}; | |
if (nextPageToken) { | |
params.pageToken = nextPageToken; | |
} | |
if (mock === true) { | |
apiDefer.resolve(MockService.getSubs()); | |
return; | |
} | |
gapi.client.youtube.subscriptions.list(params).then(function (response) { | |
if (morePagesToLoad(response)) { | |
results = results.concat(response.result.items); | |
//console.log('got some results'); | |
pageTokens.push(response.result.nextPageToken); | |
return getSubs(requestName, response.result.nextPageToken, apiPromise); | |
} | |
else { | |
console.log('resolving final results', results); | |
pageTokens = []; | |
apiDefer.resolve(results); | |
} | |
}, errorHandler); | |
}, function (error) { | |
console.log('error is', error); | |
initialize(); | |
}); | |
return apiDefer.promise; | |
} | |
function getVideosFromPlaylist(playlistId) { | |
console.log('getting videos from list:', playlistId); | |
var defer = $q.defer(); | |
gapi.client.youtube.playlistItems.list({ | |
'part': 'snippet', | |
'maxResults': 10, | |
'playlistId': playlistId | |
}).then(function (response) { | |
defer.resolve(response.result.items); | |
}); | |
return defer.promise; | |
} | |
function getUploadPlaylistId(channelId) { | |
var defer = $q.defer(); | |
if (mock === true) { | |
defer.resolve(channelPlaylistIdMap[channelId]); | |
return defer.promise; | |
} | |
console.log('getting upload playlist id for channel', channelId); | |
gapi.client.youtube.channels.list({ | |
'part': 'contentDetails', | |
'maxResults': 10, | |
'id': channelId | |
}).then(function (response) { | |
var uploadsPlaylistId = response.result.items[0].contentDetails.relatedPlaylists.uploads; | |
defer.resolve(uploadsPlaylistId); | |
}); | |
return defer.promise; | |
} | |
var videoPlaylistIdMap = {}; | |
function getVideosForChannel(channel) { | |
var channelId = channel.snippet.resourceId.channelId; | |
var defer = $q.defer(); | |
getUploadPlaylistId(channelId).then(function (uploadPlaylistId) { | |
console.log('got the id ', uploadPlaylistId); | |
videoPlaylistIdMap[channelId] = uploadPlaylistId; | |
getVideosFromPlaylist(uploadPlaylistId).then(function (videos) { | |
defer.resolve(videos); | |
}); | |
}); | |
return defer.promise; | |
} | |
function getSubsFeed() { | |
console.log('getting subs feed'); | |
var defer = $q.defer(); | |
var calls = []; | |
var allVideos = []; | |
getSubs().then(function (subscriptions) { | |
console.log('got subs!'); | |
_.each(_.first(subscriptions, 5), function (sub) { | |
calls.push(getVideosForChannel(sub).then(function (vids) { | |
allVideos = allVideos.concat(_.map(vids, function (vid) { | |
return vid.snippet | |
})); | |
})); | |
}); | |
Q.allSettled(calls).then(function () { | |
//filter videos older than 1 week | |
allVideos = _.filter(allVideos, function (video) { | |
var parsedDate = new moment(video.publishedAt); | |
return !parsedDate.isBefore(lastWeek); | |
}); | |
// sort by date | |
allVideos = allVideos.sort(function (a, b) { | |
return new Date(b.publishedAt) - new Date(a.publishedAt); | |
}); | |
defer.resolve(allVideos); | |
}); | |
}); | |
return defer.promise; | |
} | |
return { | |
getSubs: getSubs, | |
getVideosForChannel: getVideosForChannel, | |
getSubsFeed: getSubsFeed | |
} | |
} | |
); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment