Skip to content

Instantly share code, notes, and snippets.

@crosalot
Last active January 22, 2016 09:47
Show Gist options
  • Save crosalot/de74daf2b2006a3c3359 to your computer and use it in GitHub Desktop.
Save crosalot/de74daf2b2006a3c3359 to your computer and use it in GitHub Desktop.
'use strict';
angular
.module('odmbase')
.controller('SocialFeedCtrl', ['$scope', '$window', '$http', '$timeout', 'Auth', 'CommonGoal', 'Update', 'User', SocialFeedCtrl]);
function SocialFeedCtrl ($scope, $window, $http, $timeout, Auth, CommonGoal, Update, User) {
var maxFeedsRequestTime = 10;
var maxFeedsRequest = 300;
var socialGoalList = [];
var initFeedList;
$scope.feedList = [];
$scope.busy = false;
$scope.connected = {
facebook: false,
twitter: false,
googleplus: false,
instagram: false,
pinterest: false
};
Auth.getDetail(null, function (user, isMe) {
if (!user) {
// TODO: 404
$location.path('/');
}
$scope.user = user;
CommonGoal.one().get({social_feed_provider__isnull: false, created_by:$scope.user.id, limit: 1000}).then(function (resp) {
_.each(resp.objects, function (model) {
socialGoalList.push(model.social_feed_provider+'--'+model.social_feed_id);
});
Update.one().get({social_feed_provider__isnull: false, created_by:$scope.user.id, limit: 1000}).then(function (resp) {
_.each(resp.objects, function (model) {
socialGoalList.push(model.social_feed_provider + '--' + model.social_feed_id);
});
initFeedList = [];
$timeout(function () {
if ($scope.user.social_feed_token_facebook) {
$scope.connectFacebook(initFeedList);
}
if ($scope.user.social_feed_token_twitter) {
$scope.connectTwitter(initFeedList);
}
if ($scope.user.social_feed_token_google_plus) {
$scope.connectGooglePlus(initFeedList);
}
if ($scope.user.social_feed_token_instagram) {
$scope.connectInstagram(initFeedList);
}
}, 1000);
});
});
});
var feed_init_success = {facebook: false, twitter: false, google_plus:false, instagram:false, pinterest: false};
var initRendered = false;
var initFeed = function (digest) {
if (!initFeedList) {
return;
}
var isSuccessAll = true;
_.each(feed_init_success, function (success, provider) {
if ($scope.user['social_feed_token_' + provider]) {
isSuccessAll = isSuccessAll && feed_init_success[provider];
}
});
if (isSuccessAll && !initRendered) {
$scope.feedList = [];
if (digest) {
$scope.feedList.push.apply($scope.feedList, initFeedList);
$scope._sortFeedList();
}
else {
$scope.$apply(function () {
$scope.feedList.push.apply($scope.feedList, initFeedList);
$scope._sortFeedList();
initRendered = true;
});
}
}
};
var getHashtags = function (text) {
var re = /(?:^|\W)#(\w+)(?!\w)/g;
var match;
var matches = [];
while (match = re.exec(text)) {
matches.push({name: match[1]});
}
return matches;
};
var setImage = function (model, url, append) {
var imageObject = {
"forceUpload": true,
"image": url,
"image_thumbnail_1x": {
height: 160,
style: "landscape",
url: url,
width: 160
},
"image_thumbnail_2x": {
height: 160,
style: "landscape",
url: url,
width: 160
},
"image_thumbnail_3x": {
height: 160,
style: "landscape",
url: url,
width: 160
}
};
if (append) {
model.image_set = model.image_set || {};
model.image_set.all = model.image_set.all || [];
model.image_set.all.push(imageObject);
}
else {
model.image_set = {
"all": [
imageObject
]
};
}
};
var saveAccessToken = function (provider, accessToken, cb) {
provider = provider.replace('-', '_');
$scope.user['social_feed_token_' + provider] = accessToken;
cb = cb || function () {};
$scope.user.save().then(cb);
};
var cleanStatus = function (status) {
status.description = status.description.replace(/(<([^>]+)>)/ig,"");
_.each(SOCIAL_FEED_TAGS, function (tag) {
status.description = status.description.replace(tag, '');
});
status.created_by = $scope.user;
status.is_public = true;
status.end_date = null;
status.absolute_url = '';
status.created = moment(status.created).valueOf();
status.social_feed_provider = status.provider;
status.social_feed_id = status.social_feed_id? status.social_feed_id: status.id;
status.isPushed = socialGoalList.indexOf(status.social_feed_provider + '--' + status.social_feed_id) >= 0;
delete status.id;
delete status.title;
};
$scope._sortFeedList = function () {
$scope.feedList = _.sortBy($scope.feedList, 'created').reverse();
// UPDATE MASONRY
$timeout(function () {
$('#masonry-list').masonry();
$scope.busy = false;
}, 2000);
};
$scope.disconnect = function (provider) {
saveAccessToken(provider, null);
_.filter($scope.feedList, function (status) {
return status.provider != provider;
});
};
// ---------- FACEBOOK ----------
$scope.connectFacebook = function (initFeedList) {
var facebookFeedsRequestCount = 0;
var facebookFeedsRequestTimeCount = 0;
var _getFacebookFeed = function (next) {
$scope.busy = true;
var requestUrl = next? next: '/me/posts/';
$window.FB.api(requestUrl, {
fields: 'message, full_picture, link, caption',
limit: 100,
access_token: $scope.user.social_feed_token_facebook
}, function(response) {
// expire case
if (response.error && response.error.type == 'OAuthException') {
saveAccessToken('facebook', null, initFeed);
$scope.busy = false;
return;
}
facebookFeedsRequestCount += response.data.length;
facebookFeedsRequestTimeCount++;
// DISABLED FACEBOOK BTN
$scope.connected.facebook = true;
var statuses = _.filter(response.data, function (status) {
if (status.message) {
var matchTags = false;
_.each(SOCIAL_FEED_TAGS, function (tag) {
if (status.message.toLowerCase().indexOf(tag) > 0) {
matchTags = true;
}
});
return matchTags;
}
});
_.each(statuses, function (status) {
status.provider = 'facebook';
status.description = status.message;
status.created = status.created_time;
status.tags = getHashtags(status.description);
status.social_feed_url = status.link? status.link: 'https://www.facebook.com/' + status.id;
if (status.caption == 'youtube.com') {
status.media_selected = 'youtube';
status.youtube_url = status.link;
}
else if (status.full_picture) {
status.media_selected = 'image_set';
setImage(status, status.full_picture);
}
cleanStatus(status);
});
if (initFeedList) {
initFeedList.push.apply(initFeedList, statuses);
}
else {
$scope.$apply(function () {
$scope.feedList.push.apply($scope.feedList, statuses);
});
}
if (facebookFeedsRequestCount < maxFeedsRequest && facebookFeedsRequestTimeCount < maxFeedsRequestTime && response.paging && response.paging.next) {
_getFacebookFeed(response.paging.next);
}
else if (initFeedList) {
feed_init_success['facebook'] = true;
initFeed();
}
else {
$scope._sortFeedList();
}
});
};
if ($scope.user.social_feed_token_facebook) {
_getFacebookFeed();
}
else {
$window.FB.api("/me/permissions","DELETE",function(response){
console.log(response);
$window.FB.login(function (response) {
console.log(response.authResponse.accessToken);
saveAccessToken('facebook', response.authResponse.accessToken);
_getFacebookFeed();
}, {scope: 'email, user_posts'});
});
}
};
// ---------- END: FACEBOOK ----------
// ---------- TWITTER ----------
$scope._getTwitterFeed = function (accessToken, initFeedList) {
var params = {};
var splited = accessToken.split('&amp;');
_.each(splited, function (querystring) {
var querystringSplited = querystring.split('=');
params[querystringSplited[0]] = querystringSplited[1];
});
$http.post('/api/v1/socialfeed/twitter/', params)
.success(function (data) {
$scope.connected.twitter = true;
_.each(data.statuses, function (status) {
status.provider = 'twitter';
status.description = status.text;
status.created = status.created_at;
status.tags = getHashtags(status.description);
status.social_feed_url = 'https://twitter.com/' + status.user.screen_name + '/status/' + status.id_str;
if (status.entities.media && status.entities.media.length && _.find(status.entities.media, {'type': 'photo'})) {
var photo = _.find(status.entities.media, {'type': 'photo'}).media_url_https;
status.media_selected = 'image_set';
photo = '/proxy/?url=' + photo;
setImage(status, photo);
}
else if (status.entities.urls && status.entities.urls.length) {
var youtubeItem = _.find(status.entities.urls, function (url) {
return url.display_url.lastIndexOf('youtube', 0) === 0 || url.display_url.lastIndexOf('youtu.be', 0) === 0;
});
if (youtubeItem) {
status.media_selected = 'youtube';
status.youtube_url = youtubeItem.expanded_url;
}
}
cleanStatus(status);
});
if (initFeedList) {
initFeedList.push.apply(initFeedList, data.statuses);
initFeed();
feed_init_success['twitter'] = true;
}
else {
$scope.feedList.push.apply($scope.feedList, data.statuses);
$scope._sortFeedList();
}
})
.error(function (data) {
//if (data.error == 'Wrong token') {
$scope.connected.twitter = false;
saveAccessToken('twitter', null, initFeed);
$scope.busy = false;
//}
});
};
$scope.connectTwitter = function (initFeedList) {
$scope.busy = true;
if ($scope.user.social_feed_token_twitter) {
$scope._getTwitterFeed($scope.user.social_feed_token_twitter, initFeedList);
}
else {
$window.open('/account/login/twitter/', '', "width=530,height=500");
$window.socialSignCallback = function (accessToken) {
saveAccessToken('twitter', accessToken);
// DISABLED TWITTER BTN
$scope.connected.twitter = true;
$scope._getTwitterFeed(accessToken, initFeedList);
};
}
};
// ---------- END: TWITTER ----------
// ---------- GOOGLEPLUS ----------
$scope.connectGooglePlus = function (initFeedList) {
var clientId = GOOGLE_OAUTH2_CLIENT_ID;
var apiKey = GOOGLE_OAUTH2_API_KEY;
var scopes = 'https://www.googleapis.com/auth/plus.me';
handleClientLoad();
function handleClientLoad() {
// Step 2: Reference the API key
$window.gapi.client.setApiKey(apiKey);
$window.setTimeout(checkAuth,1);
}
function checkAuth() {
if ($scope.user.social_feed_token_google_plus) {
$window.gapi.auth.setToken({access_token: $scope.user.social_feed_token_google_plus});
makeApiCall();
}
else {
$window.gapi.auth.authorize({client_id: clientId, scope: scopes, immediate: false}, handleAuthResult);
}
}
function handleAuthResult(authResult) {
saveAccessToken('google_plus', authResult.access_token);
if (authResult && !authResult.error) {
makeApiCall();
} else {
// TODO: IN CASE OF AUTH LOGIN ERROR
}
}
// Load the API and make an API call. Display the results on the screen.
function makeApiCall() {
// Step 4: Load the Google+ API
$window.gapi.client.load('plus', 'v1').then(function () {
// Step 5: Assemble the API request
var request = $window.gapi.client.plus.activities.list({
'userId': 'me',
'collection': 'public',
'maxResults': 100 // isMax from google+
});
// Step 6: Execute the API request
request.then(function (response) {
// DISABLED GOOGLE PLUS BTN
$scope.connected.googleplus = true;
var statuses = _.filter(response.result.items, function (status) {
var matchTags = false;
_.each(SOCIAL_FEED_TAGS, function (tag) {
if (status.object.content.toLowerCase().indexOf(tag) > 0) {
matchTags = true;
}
});
return matchTags;
});
_.each(statuses, function (status) {
status.provider = 'google-plus';
status.created = moment(status.published).valueOf();
status.tags = getHashtags(status.object.content);
status.description = status.object.content;
status.social_feed_url = status.url;
if (status.object.attachments && _.find(status.object.attachments, {'objectType': 'video'})) {
status.media_selected = 'youtube';
var youtubeItem = _.find(status.object.attachments, {'objectType': 'video'});
if (youtubeItem) {
status.youtube_url = youtubeItem.url;
}
}
else if (status.object.attachments && _.find(status.object.attachments, {'objectType': 'photo'})) {
status.media_selected = 'image_set';
var imageItem = _.find(status.object.attachments, {'objectType': 'photo'});
setImage(status, imageItem.image.url);
}
else if (status.object.attachments && _.find(status.object.attachments, {'objectType': 'album'})) {
status.media_selected = 'image_set';
var albumItem = _.find(status.object.attachments, {'objectType': 'album'});
setImage(status, albumItem.thumbnails[0].image.url);
}
cleanStatus(status);
});
if (initFeedList) {
initFeedList.push.apply(initFeedList, statuses);
feed_init_success['google_plus'] = true;
initFeed();
}
else {
$scope.$apply(function () {
$scope.feedList.push.apply($scope.feedList, statuses);
$scope._sortFeedList();
});
}
}, function (reason) {
$scope.connected.google_plus = false;
saveAccessToken('google_plus', null, initFeed);
$scope.busy = false;
console.log('Error: ' + reason.result.error.message);
initFeed();
});
});
}
};
// ---------- END: GOOGLEPLUS ----------
// ---------- INSTAGRAM ----------
var instagramFeedsRequestCount = 0;
var instagramFeedsRequestTimeCount = 0;
function getParameterByName(url, name) {
name = name.replace(/[\[]/, "\\[").replace(/[\]]/, "\\]");
var regex = new RegExp("[\\?&]" + name + "=([^&#]*)"),
results = regex.exec(url);
return results === null ? "" : decodeURIComponent(results[1].replace(/\+/g, " "));
}
var _getInstagramFeed = function (accessToken, next, initFeedList) {
var requestUrl = 'https://api.instagram.com/v1/users/self/media/recent/?callback=JSON_CALLBACK&access_token=' + accessToken;
if (next) {
requestUrl += '&max_id=' + getParameterByName(next, 'max_id');
}
$http.jsonp(requestUrl)
.success(function (response) {
if (response.meta.code != 200) {
$scope.connected.instagram = false;
saveAccessToken('instagram', null, initFeed);
$scope.busy = false;
console.log('ERROR: ', data);
return;
}
// DISABLED TWITTER BTN
$scope.connected.instagram = true;
var counter = 0;
if (response.data && response.data.length) {
counter = response.data.length;
}
instagramFeedsRequestCount += counter;
var statuses = _.filter(response.data, function (status) {
if (status.caption && status.caption.text) {
var matchTags = false;
_.each(SOCIAL_FEED_TAGS, function (tag) {
if (status.caption.text.toLowerCase().indexOf(tag) > 0) {
matchTags = true;
}
});
return matchTags;
}
});
_.each(statuses, function (status) {
status.provider = 'instagram';
status.description = status.caption.text;
status.created = status.created_time;
status.tags = getHashtags(status.description);
status.social_feed_url = status.link;
if (status.images && status.images.standard_resolution) {
status.media_selected = 'image_set';
setImage(status, status.images.standard_resolution.url);
}
cleanStatus(status);
});
if (initFeedList) {
initFeedList.push.apply(initFeedList, statuses);
feed_init_success['instagram'] = true;
}
else {
$scope.feedList.push.apply($scope.feedList, statuses);
//$scope._sortFeedList();
}
if (instagramFeedsRequestCount < maxFeedsRequest && instagramFeedsRequestTimeCount < maxFeedsRequestTime && response.pagination && response.pagination.next_url) {
_getInstagramFeed(accessToken, response.pagination.next_url, initFeedList);
}
else if (initFeedList) {
feed_init_success['instagram'] = true;
initFeed(true);
}
else {
$scope._sortFeedList();
}
})
.error(function (data) {
$scope.connected.instagram = false;
saveAccessToken('instagram', null, initFeed);
$scope.busy = false;
console.log('ERROR: ', data);
});
};
$scope.connectInstagram = function (initFeedList) {
$scope.busy = true;
if ($scope.user.social_feed_token_instagram) {
_getInstagramFeed($scope.user.social_feed_token_instagram, null, initFeedList);
}
else {
$window.open('/account/login/instagram/', '', "width=530,height=500");
$window.socialSignCallback = function (accessToken) {
saveAccessToken('instagram', accessToken);
_getInstagramFeed(accessToken, null, initFeedList);
};
}
};
// ---------- END: INSTAGRAM ----------
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment