Skip to content

Instantly share code, notes, and snippets.

@kitze
Created September 10, 2015 14:27
Show Gist options
  • Save kitze/87ab203d382c46fb0b3e to your computer and use it in GitHub Desktop.
Save kitze/87ab203d382c46fb0b3e to your computer and use it in GitHub Desktop.
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