1if (typeof Object.create !== 'function') { 2 Object.create = function (obj) { 3 function F() { } 4 F.prototype = obj; 5 return new F(); 6 }; 7} 8 9(function ($, window, document, undefined) { 10 $.fn.socialfeed = function (_options) { 11 12 var defaults = { 13 plugin_folder: '', // a folder in which the plugin is located (with a slash in the end) 14 template: 'template.html', // a path to the template file 15 show_media: false, // show images of attachments if available 16 media_min_width: 300, 17 length: 500, // maximum length of post message shown 18 date_format: 'll', 19 date_locale: 'en' 20 }; 21 //--------------------------------------------------------------------------------- 22 var options = $.extend(defaults, _options), 23 container = $(this), 24 template, 25 social_networks = ['facebook', 'instagram', 'vk', 'google', 'blogspot', 'pinterest', 'rss'], 26 posts_to_load_count = 0, 27 loaded_post_count = 0; 28 // container.empty().css('display', 'block'); 29 //--------------------------------------------------------------------------------- 30 31 //--------------------------------------------------------------------------------- 32 // This function performs consequent data loading from all of the sources by calling corresponding functions 33 function calculatePostsToLoadCount() { 34 social_networks.forEach(function (network) { 35 if (options[network]) { 36 if (options[network].accounts) { 37 posts_to_load_count += options[network].limit * options[network].accounts.length; 38 } else if (options[network].urls) { 39 posts_to_load_count += options[network].limit * options[network].urls.length; 40 } else { 41 posts_to_load_count += options[network].limit; 42 } 43 } 44 }); 45 } 46 47 calculatePostsToLoadCount(); 48 49 50 51 52 function fireCallback() { 53 var fire = true; 54 social_networks.forEach(function (network) { 55 if (Feed[network]) { 56 Feed[network].accountsToLoad.forEach(function (account) { 57 if (!account.loaded) { 58 fire = false; 59 } 60 }); 61 } 62 }); 63 if (fire && options.callback) { 64 options.callback(); 65 } 66 } 67 68 var Utility = { 69 request: function (url, callback) { 70 $.ajax({
71 url: url, 72 dataType: 'jsonp', 73 success: callback, 74 error: function () { 75 posts_to_load_count--; 76 } 77 }); 78 }, 79 get_request: function (url, callback) { 80 $.get(url, callback, 'json'); 81 }, 82 wrapLinks: function (string, social_network) { 83 var exp = /(\b(https?|ftp|file):\/\/[-A-Z0-9+&@#\/%?=~_|!:,.;]*[-A-Z0-9+&@#\/%=~_|])/ig; 84 if (social_network === 'google-plus') { 85 string = string.replace(/(@|#)([a-z0-9_]+['])/ig, Utility.wrapGoogleplusTagTemplate); 86 } else { 87 string = string.replace(exp, Utility.wrapLinkTemplate); 88 } 89 return string; 90 }, 91 wrapLinkTemplate: function (string) { 92 return '<a target="_blank" href="' + string + '">' + string + '<\/a>'; 93 }, 94 wrapGoogleplusTagTemplate: function (string) { 95 return '<a target="_blank" href="https://plus.google.com/s/' + string + '" >' + string + '<\/a>'; 96 }, 97 shorten: function (string) { 98 string = $.trim(string); 99 if (string.length > options.length) { 100 return jQuery.trim(string).substring(0, options.length).split(" ").slice(0, -1).join(" ") + "..."; 101 } else { 102 return string; 103 } 104 }, 105 stripHTML: function (string) { 106 if (typeof string === "undefined" || string === null) { 107 return ''; 108 } 109 return string.replace(/(<([^>]+)>)|nbsp;|\s{2,}|/ig, ""); 110 } 111 }; 112 113 function SocialFeedPost(social_network, data) { 114 if (!data) { 115 return; 116 } 117 this.content = data; 118 this.content.social_network = social_network; 119 this.content.attachment = (this.content.attachment === undefined) ? '' : this.content.attachment; 120 this.content.time_ago = data.dt_create.locale(options.date_locale).fromNow(); 121 this.content.date = data.dt_create.locale(options.date_locale).format(options.date_format); 122 this.content.dt_create = this.content.dt_create.valueOf(); 123 this.content.text = Utility.wrapLinks(Utility.shorten(data.message + ' ' + data.description), data.social_network); 124 this.content.moderation_passed = (options.moderation) ? options.moderation(this.content) : true; 125 126 Feed[social_network].posts.push(this); 127 } 128 SocialFeedPost.prototype = { 129 render: function () { 130 var rendered_html = Feed.template(this.content); 131 var data = this.content; 132 133 if ($(container).children('[social-feed-id=' + data.id + ']').length !== 0) { 134 return false; 135 } 136 if ($(container).children().length === 0) { 137 $(container).append(rendered_html); 138 } else { 139 var i = 0, 140 insert_index = -1; 141 $.each($(container).children(), function () { 142 if ($(this).attr('dt-create') < data.dt_create) { 143 insert_index = i; 144 return false; 145 } 146 i++; 147 }); 148 $(container).append(rendered_html); 149 if (insert_index >= 0) { 150 insert_index++; 151 var before = $(container).children('div:nth-child(' + insert_index + ')'), 152 current = $(container).children('div:last-child'); 153 $(current).insertBefore(before); 154 } 155 156 } 157 if (options.media_min_width) { 158 159 var query = '[social-feed-id=' + data.id + '] img.attachment'; 160 var image = $(query); 161 162 // preload the image 163 var height, width = ''; 164 var img = new Image(); 165 var imgSrc = image.attr("src"); 166 167 $(img).load(function () { 168
169 if (img.width < options.media_min_width) { 170 image.hide(); 171 } 172 // garbage collect img 173 delete img; 174 175 }).error(function () { 176 // image couldnt be loaded 177 image.hide(); 178 179 }).attr({ 180 src: imgSrc 181 }); 182 183 } 184 185 //loaded_post_count++; 186 //console.log("loads", loaded_post_count, posts_to_load_count); 187 //if (loaded_post_count == posts_to_load_count) { 188 // fireCallback(); 189 //} 190 191 //this.rendered = true; 192 193 //var finished = true; 194 //social_networks.forEach(function (network) { 195 // if (Feed[network] && Feed[network].posts) { 196 // for (var i = 0; i < Feed[network].posts.length; i++) { 197 // var post = Feed[network].posts[i]; 198 // if (!post.rendered) { 199 // finished = false; 200 // } 201 // } 202 // } 203 //}); 204 //if (finished) { 205 // fireCallback(); 206 //} 207 208 } 209 210 }; 211 212 var Feed = { 213 template: false, 214 init: function () { 215 Feed.getTemplate(function () { 216 social_networks.forEach(function (network) { 217 if (options[network]) { 218 if (options[network].accounts) { 219 Feed[network].accountsToLoad = options[network].accounts.map(function (account) { 220 return { 221 name: account, 222 loaded: false 223 }; 224 }); 225 226 //loaded[network] = 0; 227 options[network].accounts.forEach(function (account) { 228 //loaded[network]++; 229 Feed[network].getData(account); 230 }); 231 } else if (options[network].urls) { 232 options[network].urls.forEach(function (url) { 233 Feed[network].getData(url); 234 }); 235 } else { 236 Feed[network].getData(); 237 } 238 } 239 }); 240 }); 241 }, 242 getTemplate: function (callback) { 243 if (Feed.template) 244 return callback(); 245 else { 246 if (options.template_html) { 247 Feed.template = doT.template(options.template_html); 248 return callback(); 249 } else { 250 $.get(options.template, function (template_html) { 251 Feed.template = doT.template(template_html); 252 return callback(); 253 }); 254 } 255 } 256 }, 257 twitter: { 258 posts: [], 259 accountsToLoad: [], 260 loaded: false, 261 api: 'http://api.tweecool.com/', 262 263 getData: function (account) { 264 265 var cb = new Codebird(); 266 cb.setConsumerKey(options.twitter.consumer_key, options.twitter.consumer_secret); 267 268 // Allow setting your own proxy with Codebird 269 if (options.twitter.proxy !== undefined) { 270 cb.setProxy(options.twitter.proxy); 271 } 272 273 switch (account[0]) { 274 case '@': 275 var userid = account.substr(1); 276 cb.__call( 277 "statuses_userTimeline", 278 "id=" + userid + "&count=" + options.twitter.limit, 279 function (reply) { 280 Feed.twitter.utility.getPosts(reply, account) 281 }, 282 true // this parameter required 283 ); 284 break; 285 case '#': 286 var hashtag = account.substr(1); 287 cb.__call( 288 "search_tweets", 289 "q=" + hashtag + "&count=" + options.twitter.limit, 290 function (reply) { 291 Feed.twitter.utility.getPosts(reply.statuses, account); 292 }, 293 true // this parameter required 294 ); 295 break; 296 default: 297 } 298 }, 299 utility: { 300 getPosts: function (json, account) { 301 if (json) { 302 $.each(json, function () { 303 var element = this; 304 var post = new SocialFeedPost('twitter', Feed.twitter.utility.unifyPostData(element)); 305 if (post.content) { 306 post.render(); 307 } 308 });
309 Feed.twitter.accountsToLoad.forEach(function (acc) { 310 if (acc.name === account) { 311 acc.loaded = true; 312 } 313 }); 314 fireCallback(); 315 } 316 }, 317 unifyPostData: function (element) { 318 var post = {}; 319 if (element.id) { 320 post.id = element.id_str; 321 //prevent a moment.js console warning due to Twitter's poor date format. 322 post.dt_create = moment(element.created_at, 'dd MMM DD HH:mm:ss ZZ YYYY'); 323 post.author_link = 'http://twitter.com/' + element.user.screen_name; 324 post.author_picture = element.user.profile_image_url_https; 325 post.post_url = post.author_link + '/status/' + element.id_str; 326 post.author_name = element.user.name; 327 post.message = element.text; 328 post.description = ''; 329 post.link = 'http://twitter.com/' + element.user.screen_name + '/status/' + element.id_str; 330 331 if (options.show_media === true) { 332 if (element.entities.media && element.entities.media.length > 0) { 333 var image_url = element.entities.media[0].media_url_https; 334 if (image_url) { 335 post.attachment = '<img class="attachment" src="' + image_url + '" />'; 336 } 337 } 338 } 339 } 340 if (post.author_name == "Interspiro") { 341 return post; 342 } 343 else { 344 return false; 345 } 346 } 347 } 348 }, 349 facebook: { 350 posts: [], 351 graph: 'https://graph.facebook.com/', 352 accountsToLoad: [], 353 loaded: false, 354 getData: function (account) { 355 var proceed = function (request_url) { 356 Utility.request(request_url, function (reply) { Feed.facebook.utility.getPosts(reply, account); }); 357 }; 358 var fields = '?fields=id,from,message,created_time,story'; 359 fields += (options.show_media === true) ? ',full_picture' : ''; 360 var request_url, limit = '&limit=' + options.facebook.limit,
361 query_extention = '&access_token=' + options.facebook.access_token + '&callback=?'; 362 switch (account[0]) { 363 case '@': 364 var username = account.substr(1); 365 Feed.facebook.utility.getUserId(username, function (userdata) { 366 if (userdata.id !== '') { 367 request_url = Feed.facebook.graph + 'v8.0/' + userdata.id + '/posts' + fields + limit + query_extention; 368 proceed(request_url); 369 } 370 }); 371 break; 372 case '!': 373 var page = account.substr(1); 374 request_url = Feed.facebook.graph + 'v8.0/' + page + '/feed' + fields + limit + query_extention; 375 console.log(request_url) 376 proceed(request_url); 377 break; 378 default: 379 proceed(request_url); 380 } 381 }, 382 utility: { 383 getUserId: function (username, callback) {
384 var query_extention = '&access_token=' + options.facebook.access_token + '&callback=?'; 385 var url = 'https://graph.facebook.com/' + username + '?' + query_extention; 386 var result = ''; 387 $.get(url, callback, 'json'); 388 }, 389 prepareAttachment: function (element) { 390 var image_url = element.full_picture; 391 if (image_url.indexOf('_b.') !== -1) { 392 //do nothing it is already big 393 } else if (image_url.indexOf('safe_image.php') !== -1) { 394 image_url = Feed.facebook.utility.getExternalImageURL(image_url, 'url'); 395 396 } else if (image_url.indexOf('app_full_proxy.php') !== -1) { 397 image_url = Feed.facebook.utility.getExternalImageURL(image_url, 'src'); 398 399 } else if (element.object_id) { 400 image_url = Feed.facebook.graph + element.object_id + '/picture/?type=normal'; 401 } 402 403 return '<img class="attachment" src="' + image_url + '" />'; 404 }, 405 getExternalImageURL: function (image_url, parameter) { 406 image_url = decodeURIComponent(image_url).split(parameter + '=')[1]; 407 if (image_url.indexOf('fbcdn-sphotos') === -1) { 408 return image_url.split('&')[0]; 409 } else { 410 return image_url; 411 } 412 413 }, 414 getPosts: function (json, account) { 415 if (json['data']) { 416 if (json['data'].length < options.facebook.limit) { 417 posts_to_load_count -= (options.facebook.limit - json['data'].length); 418 } 419 json['data'].forEach(function (element) { 420 var post = new SocialFeedPost('facebook', Feed.facebook.utility.unifyPostData(element)); 421 post.render(); 422 }); 423 } 424 Feed.facebook.accountsToLoad.forEach(function (acc) { 425 if (acc.name === account) { 426 acc.loaded = true; 427 } 428 }); 429 fireCallback(); 430 }, 431 unifyPostData: function (element) { 432 var post = {}, 433 text = (element.message) ? element.message : element.story; 434 435 post.id = element.id; 436 post.dt_create = moment(element.created_time); 437 if (element.from) { 438 if (element.from.id) { 439 post.author_link = 'http://facebook.com/' + element.from.id; 440 post.author_picture = Feed.facebook.graph + element.from.id + '/picture'; 441 } 442 443 post.author_name = element.from.name; 444 } 445 post.name = element.name || ""; 446 post.message = (text) ? text : ''; 447 post.description = (element.description) ? element.description : ''; 448 post.link = (element.link) ? element.link : (element.from) ? 'http://facebook.com/' + element.from.id : ''; 449 450 if (options.show_media === true) { 451 if (element.full_picture) { 452 var attachment = Feed.facebook.utility.prepareAttachment(element); 453 if (attachment) { 454 post.attachment = attachment; 455 } 456 } 457 } 458 return post; 459 } 460 } 461 }, 462 google: { 463 posts: [], 464 accountsToLoad: [], 465 loaded: false, 466 api: 'https://www.googleapis.com/plus/v1/', 467 getData: function (account) { 468 var request_url; 469 switch (account[0]) { 470 case '#': 471 var hashtag = account.substr(1); 472 request_url = Feed.google.api + 'activities?query=' + hashtag + '&key=' + options.google.access_token + '&maxResults=' + options.google.limit; 473 Utility.get_request(request_url, function (reply) { Feed.google.utility.getPosts(reply, account) }); 474 break; 475 case '@': 476 var username = account.substr(1); 477 request_url = Feed.google.api + 'people/' + username + '/activities/public?key=' + options.google.access_token + '&maxResults=' + options.google.limit; 478 Utility.get_request(request_url, function (reply) { Feed.google.utility.getPosts(reply, account) }); 479 break; 480 default: 481 } 482 }, 483 utility: { 484 getPosts: function (json, account) { 485 if (json.items) { 486 $.each(json.items, function (i) { 487 var post = new SocialFeedPost('google', Feed.google.utility.unifyPostData(json.items[i])); 488 post.render(); 489 }); 490 }
491 Feed.google.accountsToLoad.forEach(function (acc) { 492 if (acc.name === account) { 493 acc.loaded = true; 494 } 495 }); 496 fireCallback(); 497 }, 498 unifyPostData: function (element) { 499 var post = {}; 500 501 post.id = element.id; 502 post.attachment = ''; 503 post.description = ''; 504 post.dt_create = moment(element.published); 505 post.author_link = element.actor.url; 506 post.author_picture = element.actor.image.url; 507 post.author_name = element.actor.displayName; 508 509 if (options.show_media === true) { 510 if (element.object.attachments) { 511 $.each(element.object.attachments, function () { 512 var image = ''; 513 if (this.fullImage) { 514 image = this.fullImage.url; 515 } else { 516 if (this.objectType === 'album') { 517 if (this.thumbnails && this.thumbnails.length > 0) { 518 if (this.thumbnails[0].image) { 519 image = this.thumbnails[0].image.url; 520 } 521 } 522 } 523 } 524 post.attachment = '<img class="attachment" src="' + image
524+ '"/>'; 525 }); 526 } 527 } 528 post.message = element.title; 529 post.link = element.url; 530 531 return post; 532 } 533 } 534 }, 535 instagram: { 536 posts: [], 537 api: 'https://graph.instagram.com/', 538 accountsToLoad: [], 539 loaded: false, 540 accessType: function () { 541 // If we have both the client_id and access_token set in options, 542 // use access_token for authentication. If client_id is not set 543 // then use access_token. If neither are set, log an error to console. 544 if (typeof options.instagram.access_token === 'undefined' && typeof options.instagram.client_id === 'undefined') { 545 console.log('You need to define a client_id or access_token to authenticate with Instagram\'s API.'); 546 return undefined; 547 } 548 if (options.instagram.access_token) { options.instagram.client_id = undefined; } 549 options.instagram.access_type = (typeof options.instagram.client_id === 'undefined' ? 'access_token' : 'client_id'); 550 return options.instagram.access_type; 551 }, 552 getData: function (account) { 553 var url; 554 var InstagramAccount = $('.instagram-social').attr('data-instagram-id'); 555 var InstagramID = $('.instagram-social').attr('data-instagram-id'); 556 // API endpoint URL depends on which authentication type we're using. 557 if (this.accessType() !== 'undefined') { 558 var authTokenParams = options.instagram.access_type + '=' + options.instagram[options.instagram.access_type]; 559 } 560 561 switch (account[0]) { 562 case '@': 563 var username = account.substr(1); 564 url = Feed.instagram.api + '/' + InstagramID + '/media?fields=id,media_url,media_type,caption,username,timestamp,permalink&' + authTokenParams + '&' + 'limit=' + options.instagram.limit + '&callback=?'; 565 console.log("@:" + url) 566 Utility.request(url, Feed.instagram.utility.getImages); 567 568 break; 569 case '#': 570 var hashtag = account.substr(1); 571 url = Feed.instagram.api + 'tags/' + hashtag + '/media/recent/?' + authTokenParams + '&' + 'count=' + options.instagram.limit + '&callback=?'; 572 Utility.request(url, function (reply) { Feed.instagram.utility.getImages(reply, account) }); 573 console.log("#:" + url) 574 break; 575 case '&': 576 var id = account.substr(1); 577 url = Feed.instagram.api + 'users/' + id + '/?' + authTokenParams + '&' + 'count=' + options.instagram.limit + '&callback=?'; 578 console.log("&:" + url) 579 Utility.request(url, function (reply) { Feed.instagram.utility.getUsers(reply, account) }); 580 default: 581 } 582 }, 583 utility: { 584 getImages: function (json, account) { 585 if (json.data) { 586 json.data.forEach(function (element) { 587 if (element.media_type == "IMAGE") { 588 var post = new SocialFeedPost('instagram', Feed.instagram.utility.unifyPostData(element)); 589 590 post.render(); 591 } 592 593 }); 594 }
595 Feed.instagram.accountsToLoad.forEach(function (acc) { 596 if (acc.name === account) { 597 acc.loaded = true; 598 } 599 }); 600 fireCallback(); 601 }, 602 getUsers: function (json, account) { 603 // API endpoint URL depends on which authentication type we're using. 604 if (options.instagram.access_type !== 'undefined') { 605 var authTokenParams = options.instagram.access_type + '=' + options.instagram[options.instagram.access_type]; 606 } 607 608 if (!jQuery.isArray(json.data)) json.data = [json.data] 609 json.data.forEach(function (user) { 610 var InstagramAccount = $('.instagram-social').attr('data-instagram-id'); 611 var InstagramID = $('.instagram-social').attr('data-instagram-id'); 612 613 var url = Feed.instagram.api + '/' + InstagramID + '/media?fields=id,media_url,media_type,caption,username,timestamp,permalink&' + authTokenParams + '&' + 'limit=' + options.instagram.limit + '&callback=?'; 614 Utility.request(url, Feed.instagram.utility.getImages); 615 }); 616 Feed.instagram.accountsToLoad.forEach(function (acc) { 617 if (acc.name === account) { 618 acc.loaded = true; 619 } 620 }); 621 fireCallback(); 622 }, 623 unifyPostData: function (element) { 624 if (element.media_type == 'IMAGE') { 625 var post = {}; 626 627 post.id = element.id; 628 post.dt_create = moment(element.timestamp * 1000); 629 post.author_link = 'http://instagram.com/' + element.username; 630 //post.author_picture = element.user.profile_picture; 631 post.author_name = element.username; 632 post.message = (element.caption && element.caption) ? element.caption : ''; 633 post.description = ''; 634 post.link = element.permalink; 635 if (options.show_media) { 636 post.attachment = '<img class="attachment" src="' + element.media_url + '' + '" />'; 637 } 638 return post; 639 } 640 641 } 642 } 643 }, 644 vk: { 645 posts: [], 646 accountsToLoad: [], 647 loaded: false, 648 base: 'http://vk.com/', 649 api: 'https://api.vk.com/method/', 650 user_json_template: 'https://api.vk.com/method/' + 'users.get?fields=first_name,%20last_name,%20screen_name,%20photo&uid=', 651 group_json_template: 'https://api.vk.com/method/' + 'groups.getById?fields=first_name,%20last_name,%20screen_name,%20photo&gid=', 652 getData: function (account) { 653 var request_url; 654 655 switch (account[0]) { 656 case '@': 657 var username = account.substr(1); 658 request_url = Feed.vk.api + 'wall.get?owner_id=' + username + '&filter=' + options.vk.source + '&count=' + options.vk.limit + '&callback=?'; 659 Utility.get_request(request_url, function (reply) { Feed.vk.utility.getPosts(reply, account); }); 660 break; 661 case '#': 662 var hashtag = account.substr(1); 663 request_url = Feed.vk.api + 'newsfeed.search?q=' + hashtag + '&count=' + options.vk.limit + '&callback=?'; 664 Utility.get_request(request_url, function (reply) { Feed.vk.utility.getPosts(reply, account); }); 665 break; 666 default: 667 } 668 }, 669 utility: { 670 getPosts: function (json, account) { 671 if (json.response) { 672 $.each(json.response, function () { 673 if (this != parseInt(this) && this.post_type === 'post') { 674 var owner_id = (this.owner_id) ? this.owner_id : this.from_id, 675 vk_wall_owner_url = (owner_id > 0) ? (Feed.vk.user_json_template + owner_id + '&callback=?') : (Feed.vk.group_json_template + (-1) * owner_id + '&callback=?'), 676 element = this; 677 Utility.get_request(vk_wall_owner_url, function (wall_owner) { 678 Feed.vk.utility.unifyPostData(wall_owner, element, json); 679 }); 680 } 681 }); 682 }
683 Feed.vk.accountsToLoad.forEach(function (acc) { 684 if (acc.name === account) { 685 acc.loaded = true; 686 } 687 }); 688 fireCallback(); 689 }, 690 unifyPostData: function (wall_owner, element, json) { 691 var post = {}; 692 693 post.id = element.id; 694 post.dt_create = moment.unix(element.date); 695 post.description = ' '; 696 post.message = Utility.stripHTML(element.text); 697 if (options.show_media) { 698 if (element.attachment) { 699 if (element.attachment.type === 'link') 700 post.attachment = '<img class="attachment" src="' + element.attachment.link.image_src + '" />'; 701 if (element.attachment.type === 'video') 702 post.attachment = '<img class="attachment" src="' + element.attachment.video.image_big + '" />'; 703 if (element.attachment.type === 'photo') 704 post.attachment = '<img class="attachment" src="' + element.attachment.photo.src_big + '" />'; 705 } 706 } 707 708 if (element.from_id > 0) { 709 var vk_user_json = Feed.vk.user_json_template + element.from_id + '&callback=?'; 710 Utility.get_request(vk_user_json, function (user_json) { 711 var vk_post = new SocialFeedPost('vk', Feed.vk.utility.getUser(user_json, post, element, json)); 712 vk_post.render(); 713 }); 714 715 } else { 716 var vk_group_json = Feed.vk.group_json_template + (-1) * element.from_id + '&callback=?'; 717 Utility.get_request(vk_group_json, function (user_json) { 718 var vk_post = new SocialFeedPost('vk', Feed.vk.utility.getGroup(user_json, post, element, json)); 719 vk_post.render(); 720 }); 721 } 722 }, 723 getUser: function (user_json, post, element, json) { 724 post.author_name = user_json.response[0].first_name + ' ' + user_json.response[0].last_name; 725 post.author_picture = user_json.response[0].photo; 726 post.author_link = Feed.vk.base + user_json.response[0].screen_name; 727 post.link = Feed.vk.base + user_json.response[0].screen_name + '?w=wall' + element.from_id + '_' + element.id; 728 729 return post; 730 }, 731 getGroup: function (user_json, post, element, json) { 732 post.author_name = user_json.response[0].name; 733 post.author_picture = user_json.response[0].photo; 734 post.author_link = Feed.vk.base + user_json.response[0].screen_name; 735 post.link = Feed.vk.base + user_json.response[0].screen_name + '?w=wall-' + user_json.response[0].gid + '_' + element.id; 736 737 return post; 738 } 739 } 740 }, 741 blogspot: { 742 accountsToLoad: [], 743 loaded: false, 744 getData: function (account) { 745 var url; 746 747 switch (account[0]) { 748 case '@': 749 var username = account.substr(1); 750 url = 'http://' + username + '.blogspot.com/feeds/posts/default?alt=json-in-script&callback=?'; 751 request(url, function (reply) { Feed.blogspot.utility.getPosts(reply, account) }); 752 break; 753 default: 754 } 755 }, 756 utility: { 757 getPosts: function (json, account) { 758 $.each(json.feed.entry, function () { 759 var post = {}, 760 element = this;
761 post.id = element.id['$t'].replace(/[^a-z0-9]/gi, ''); 762 post.dt_create = moment((element.published['$t'])); 763 post.author_link = element.author[0]['uri']['$t']; 764 post.author_picture = 'http:' + element.author[0]['gd$image']['src']; 765 post.author_name = element.author[0]['name']['$t']; 766 post.message = element.title['$t'] + '</br></br>' + stripHTML(element.content['$t']); 767 post.description = ''; 768 post.link = element.link.pop().href; 769 770 if (options.show_media) { 771 if (element['media$thumbnail']) { 772 post.attachment = '<img class="attachment" src="' + element['media$thumbnail']['url'] + '" />'; 773 } 774 } 775 776 post.render(); 777 778 }); 779 Feed.blogspot.accountsToLoad.forEach(function (acc) { 780 if (acc.name === account) { 781 acc.loaded = true; 782 } 783 }); 784 fireCallback(); 785 } 786 } 787 }, 788 pinterest: { 789 posts: [], 790 accountsToLoad: [], 791 loaded: false, 792 apiv1: 'https://api.pinterest.com/v1/', 793 794 getData: function (account) { 795 var request_url, 796 limit = 'limit=' + options.pinterest.limit, 797 fields = 'fields=id,created_at,link,note,creator(url,first_name,last_name,image),image', 798 query_extention = fields + '&access_token='
798+ options.pinterest.access_token + '&' + limit + '&callback=?'; 799 switch (account[0]) { 800 case '@': 801 var username = account.substr(1); 802 if (username === 'me') { 803 request_url = Feed.pinterest.apiv1 + 'me/pins/?' + query_extention; 804 } else { 805 request_url = Feed.pinterest.apiv1 + 'boards/' + username + '/pins?' + query_extention; 806 } 807 break; 808 default: 809 } 810 Utility.request(request_url, function (reply) { Feed.pinterest.utility.getPosts(reply, account) }); 811 }, 812 utility: { 813 814 getPosts: function (json, account) { 815 json.data.forEach(function (element) { 816 var post = new SocialFeedPost('pinterest', Feed.pinterest.utility.unifyPostData(element)); 817 post.render(); 818 }); 819 Feed.pinterest.accountsToLoad.forEach(function (acc) { 820 if (acc.name === account) { 821 acc.loaded = true; 822 } 823 }); 824 fireCallback(); 825 }, 826 827 unifyPostData: function (element) { 828 var post = {}; 829 830 post.id = element.id; 831 post.dt_create = moment(element.created_at); 832 post.author_link = element.creator.url; 833 post.author_picture = element.creator.image['60x60'].url; 834 post.author_name = element.creator.first_name + element.creator.last_name; 835 post.message = element.note; 836 post.description = ''; 837 post.social_network = 'pinterest'; 838 post.link = element.link ? element.link : 'https://www.pinterest.com/pin/' + element.id; 839 if (options.show_media) { 840 post.attachment = '<img class="attachment" src="' + element.image['original'].url + '" />'; 841 } 842 return post; 843 } 844 } 845 }, 846 rss: { 847 posts: [], 848 accountsToLoad: [], 849 loaded: false, 850 api: 'https://query.yahooapis.com/v1/public/yql?q=', 851 datatype: 'json', 852 853 getData: function (url) { 854 var limit = options.rss.limit, 855 yql = encodeURIComponent('select entry FROM feednormalizer where url=\'' + url + '\' AND output=\'atom_1.0\' | truncate(count=' + limit + ')'), 856 request_url = Feed.rss.api + yql + '&format=json&callback=?'; 857 858 Utility.request(request_url, function (reply) { Feed.rss.utility.getPosts(reply, account) }, Feed.rss.datatype); 859 }, 860 utility: { 861 862 getPosts: function (json, account) { 863 if (json.query.count > 0) { 864 $.each(json.query.results.feed, function (index, element) { 865 var post = new SocialFeedPost('rss', Feed.rss.utility.unifyPostData(index, element)); 866 post.render(); 867 }); 868 } 869 Feed.rss.accountsToLoad.forEach(function (acc) { 870 if (acc.name === account) { 871 acc.loaded = true; 872 } 873 }); 874 fireCallback(); 875 }, 876 877 unifyPostData: function (index, element) { 878 879 var item = element; 880 881 if (element.entry !== undefined) { 882 item = element.entry; 883 } 884 var post = {}; 885 886 post.id = '"' + item.id + '"'; 887 post.dt_create = moment(item.published, 'YYYY-MM-DDTHH:mm:ssZ', 'en'); 888 889 post.author_link = ''; 890 post.author_picture = ''; 891 post.author_name = ''; 892 if (item.creator !== undefined) { 893 post.author_name = item.creator; 894 } 895 post.message = item.title; 896 post.description = ''; 897 if (item.summary !== undefined) { 898 post.description = Utility.stripHTML(item.summary.content); 899 } 900 post.social_network = 'rss'; 901 post.link = item.link.href; 902 if (options.show_media && item.thumbnail !== undefined) { 903 post.attachment = '<img class="attachment" src="' + item.thumbnail.url + '" />'; 904 } 905 return post; 906 } 907 } 908 } 909 }; 910 911 //make the plugin chainable 912 return this.each(function () { 913 // Initialization 914 Feed.init(); 915 if (options.update_period) { 916 setInterval(function () { 917 return Feed.init(); 918 }, options.update_period); 919 } 920 }) 921 }; 922 923})(jQuery);
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.