forked from phusion/ghost-algolia
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathindex.js
140 lines (128 loc) · 4.92 KB
/
index.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
// Apps not ready yet - Not used for now
// https://github.com/TryGhost/Ghost/wiki/Apps-Getting-Started-for-Ghost-Devs
//
// var App = require('ghost-app'),
// GhostAlgolia;
//
// GhostAlgolia = App.extend({
//
// install: function () {},
//
// uninstall: function () {},
//
// activate: function () {},
//
// deactivate: function () {},
// });
//
// module.exports = GhostAlgolia;
const converter = require('../../../current/core/server/lib/mobiledoc/converters/markdown-converter'),
client = require('../../../current/core/server/models').Client,
indexFactory = require('./lib/indexFactory'),
parserFactory = require('./lib/parserFactory');
const GhostAlgolia = {
init: (events, config, urlUtils) => {
bulkIndex(events, config, urlUtils);
registerEvents(events, config);
}
};
/*
* Index all published posts at server start if Algolia indexing activated in config
*/
function bulkIndex(events, config, urlUtils){
// Emitted in ghost-server.js
events.on('server.start', function(){
// Wait one second before starting the bulk index. Though the server.start event is emitted, ghost is not yet fully started
setTimeout(() => {
client.findOne({slug: 'ghost-frontend'}, {context: {internal: true}})
.then((client) => getContent(urlUtils.urlFor('api', true) + 'posts/?formats=mobiledoc&limit=all&include=authors&client_id=ghost-frontend&client_secret=' + client.attributes.secret))
.then((data) => {
let posts = JSON.parse(data).posts;
if(posts.length > 0) {
let index = indexFactory(config);
if(index.connect()) {
index.countRecords().then((nbRecords) => {
if(nbRecords === 0) {
let parser = parserFactory(),
nbFragments = 0;
posts.forEach((post) => {
post.attributes = post; // compatibility with posts returned internally in events (below)
nbFragments += parser.parse(post, index);
});
if(nbFragments) { index.save(); }
}
})
.catch((err) => console.error(err));
}
}
})
.catch((err) => console.error(err));
}, 1000);
});
}
/*
* Register (post) events to react to admin panel actions
*/
function registerEvents(events, config){
// React to post being published (from unpublished)
events.on('post.published', function(post) {
let index = indexFactory(config);
if(index.connect() && parserFactory().parse(post, index)) {
index.save()
.then(() => { console.log('GhostAlgolia: post "' + post.attributes.title + '" has been added to the index.'); })
.catch((err) => console.log(err));
};
});
// React to post being edited in a published state
events.on('post.published.edited', function(post) {
let index = indexFactory(config);
if(index.connect()) {
let promisePublishedEdited;
if(parserFactory().parse(post, index)) {
promisePublishedEdited = index.delete(post)
.then(() => index.save());
} else {
promisePublishedEdited = index.delete(post);
}
promisePublishedEdited
.then(() => { console.log('GhostAlgolia: post "' + post.attributes.title + '" has been updated in the index.'); })
.catch((err) => console.log(err));
};
});
// React to post being unpublished (from published)
// Also handles deletion of published posts as the unpublished event is emitted
// before the deleted event which becomes redundant. Deletion of unpublished posts
// is of no concern as they never made it to the index.
events.on('post.unpublished', function(post) {
let index = indexFactory(config);
const postTitle = post.attributes.title || post._previousAttributes.title;
if(index.connect()) {
index.delete(post)
.then(() => { console.log('GhostAlgolia: post "' + postTitle + '" has been removed from the index.'); })
.catch((err) => console.log(err));
};
});
}
// https://www.tomas-dvorak.cz/posts/nodejs-request-without-dependencies/
function getContent (url) {
// return new pending promise
return new Promise((resolve, reject) => {
// select http or https module, depending on reqested url
const lib = url.startsWith('https') ? require('https') : require('http');
const request = lib.get(url, (response) => {
// handle http errors
if (response.statusCode < 200 || response.statusCode > 299) {
reject(new Error('Failed to load page, status code: ' + response.statusCode));
}
// temporary data holder
const body = [];
// on every content chunk, push it to the data array
response.on('data', (chunk) => body.push(chunk));
// we are done, resolve promise with those joined chunks
response.on('end', () => resolve(body.join('')));
});
// handle connection errors of the request
request.on('error', (err) => reject(err))
})
};
module.exports = GhostAlgolia;