Instantly share code, notes, and snippets.
Last active
January 22, 2016 09:47
-
Star
0
(0)
You must be signed in to star a gist -
Fork
0
(0)
You must be signed in to fork a gist
-
Save crosalot/de74daf2b2006a3c3359 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
'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('&'); | |
_.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