Vulcan/packages/nova-embedly/lib/server/get_embedly_data.js
Comus Leong 464e20a96c eslint & clean up code, also fixed some bugs (#1515)
* [eslint] update eslint rules & add .eslintignore to ignore non-ready nova packages

* [clean-up] nova-voting

* [clean-up] [bug] nova-users: missing user parameter

* [clean-up] nova-users

* [clean-up] nova-subscribe

* [clean-up] nova-settings

* [clean-up] nova-rss

* [clean-up] [bug] nova-posts: correct UsersRemoveDeletePosts

* [clean-up] nova-posts

* [clean-up] nova-notifications

* [clean-up] [bug] nova-newsletter: no error.message on throw error

* [clean-up] nova-newsletter

* [clean-up] nova-lib

* [clean-up] nova-kadira

* [clean-up] nova-inject-data

* [clean-up] nova-getting-started

* [clean-up] nova-forms

* [clean-up] nova-events

* [clean-up] [bug] nova-embedly: no FlowRouter

* [clean-up] nova-embedly

* [clean-up] nova-email-templates

* [clean-up] nova-email

* [clean-up] nova-debug

* [clean-up] nova-core

* [clean-up] [bug] nova-comments: correct UsersRemoveDeleteComments

* [clean-up] nova-comments

* [clean-up] [bug] nova-cloudinary: use Telescope.settings.collection instand

* [clean-up] nova-cloudinary

* [clean-up] nova-categories

* [clean-up] nova-base-components

* [clean-up] nova-api

* [eslint] extends react recommended

* [clean-up] for jsx files

* [eslint] extends meteor recommended

* i forgot this one little change
2016-11-25 13:46:55 -05:00

156 lines
5 KiB
JavaScript

import Telescope from 'meteor/nova:lib';
import Posts from "meteor/nova:posts";
import Users from 'meteor/nova:users';
var getEmbedlyData = function (url) {
// var data = {};
var extractBase = 'http://api.embed.ly/1/extract';
var embedlyKey = Telescope.settings.get('embedlyKey');
var thumbnailWidth = Telescope.settings.get('thumbnailWidth', 200);
var thumbnailHeight = Telescope.settings.get('thumbnailHeight', 125);
if(!embedlyKey) {
// fail silently to still let the post be submitted as usual
console.log("Couldn't find an Embedly API key! Please add it to your Telescope settings or remove the Embedly module."); // eslint-disable-line
return null;
}
try {
var result = Meteor.http.get(extractBase, {
params: {
key: embedlyKey,
url: url,
image_width: thumbnailWidth,
image_height: thumbnailHeight,
image_method: 'crop'
}
});
// console.log(result)
if (!!result.data.images && !!result.data.images.length) // there may not always be an image
result.data.thumbnailUrl = result.data.images[0].url.replace("http:", ""); // add thumbnailUrl as its own property and remove "http"
if (result.data.authors && result.data.authors.length > 0) {
result.data.sourceName = result.data.authors[0].name;
result.data.sourceUrl = result.data.authors[0].url;
}
var embedlyData = _.pick(result.data, 'title', 'media', 'description', 'thumbnailUrl', 'sourceName', 'sourceUrl');
return embedlyData;
} catch (error) {
console.log(error); // eslint-disable-line
// the first 13 characters of the Embedly errors are "failed [400] ", so remove them and parse the rest
var errorObject = JSON.parse(error.message.substring(13));
throw new Meteor.Error(errorObject.error_code, errorObject.error_message);
}
}
// For security reason, we make the media property non-modifiable by the client and
// we use a separate server-side API call to set it (and the thumbnail object if it hasn't already been set)
// Async variant that directly modifies the post object with update()
function addMediaAfterSubmit (post) {
var set = {};
if(post.url){
var data = getEmbedlyData(post.url);
if (!!data) {
// only add a thumbnailUrl if there isn't one already
if (!post.thumbnailUrl && !!data.thumbnailUrl) {
set.thumbnailUrl = data.thumbnailUrl;
}
// add media if necessary
if (!!data.media.html) {
set.media = data.media;
}
// add source name & url if they exist
if (!!data.sourceName && !!data.sourceUrl) {
set.sourceName = data.sourceName;
set.sourceUrl = data.sourceUrl;
}
}
// make sure set object is not empty (Embedly call could have failed)
if(!_.isEmpty(set)) {
Posts.update(post._id, {$set: set});
}
}
}
Telescope.callbacks.add("posts.new.async", addMediaAfterSubmit);
function updateMediaOnEdit (modifier, post) {
var newUrl = modifier.$set.url;
if(newUrl && newUrl !== post.url){
var data = getEmbedlyData(newUrl);
if(!!data) {
if (!!data.media.html) {
modifier.$set.media = data.media;
}
// add source name & url if they exist
if (!!data.sourceName && !!data.sourceUrl) {
modifier.$set.sourceName = data.sourceName;
modifier.$set.sourceUrl = data.sourceUrl;
}
}
}
return modifier;
}
Telescope.callbacks.add("posts.edit.sync", updateMediaOnEdit);
var regenerateThumbnail = function (post) {
delete post.thumbnailUrl;
delete post.media;
delete post.sourceName;
delete post.sourceUrl;
addMediaAfterSubmit(post);
};
Meteor.methods({
testGetEmbedlyData: function (url) {
check(url, String);
console.log(getEmbedlyData(url)); // eslint-disable-line
},
getEmbedlyData: function (url) {
check(url, String);
return getEmbedlyData(url);
},
embedlyKeyExists: function () {
return !!Telescope.settings.get('embedlyKey');
},
generateThumbnail: function (post) {
check(post, Posts.simpleSchema());
if (Users.canEdit(Meteor.user(), post)) {
regenerateThumbnail(post);
}
},
generateThumbnails: function (limit = 20, mode = "generate") {
// mode = "generate" : generate thumbnails only for all posts that don't have one
// mode = "all" : regenerate thumbnais for all posts
if (Users.isAdmin(Meteor.user())) {
console.log("// Generating thumbnails…"); // eslint-disable-line
const selector = {url: {$exists: true}};
if (mode === "generate") {
selector.thumbnailUrl = {$exists: false};
}
const posts = Posts.find(selector, {limit: limit, sort: {postedAt: -1}});
posts.forEach((post, index) => {
Meteor.setTimeout(function () {
console.log(`// ${index}. fetching thumbnail for “${post.title}” (_id: ${post._id})`); // eslint-disable-line
try {
regenerateThumbnail(post);
} catch (error) {
console.log(error); // eslint-disable-line
}
}, index * 1000);
});
}
}
});