mirror of https://github.com/requarks/wiki
parent
6ea243e8d4
commit
91d524eb06
File diff suppressed because one or more lines are too long
@ -1,88 +1,84 @@
|
||||
"use strict";
|
||||
|
||||
jQuery( document ).ready(function( $ ) {
|
||||
if($('#search-input').length) {
|
||||
|
||||
if($('#search-input').length) {
|
||||
$('#search-input').focus();
|
||||
|
||||
$('#search-input').focus();
|
||||
$('.searchresults').css('display', 'block');
|
||||
|
||||
$('.searchresults').css('display', 'block');
|
||||
|
||||
var vueHeader = new Vue({
|
||||
el: '#header-container',
|
||||
data: {
|
||||
searchq: '',
|
||||
searchres: [],
|
||||
searchsuggest: [],
|
||||
searchload: 0,
|
||||
searchactive: false,
|
||||
searchmoveidx: 0,
|
||||
searchmovekey: '',
|
||||
searchmovearr: []
|
||||
var vueHeader = new Vue({
|
||||
el: '#header-container',
|
||||
data: {
|
||||
searchq: '',
|
||||
searchres: [],
|
||||
searchsuggest: [],
|
||||
searchload: 0,
|
||||
searchactive: false,
|
||||
searchmoveidx: 0,
|
||||
searchmovekey: '',
|
||||
searchmovearr: []
|
||||
},
|
||||
watch: {
|
||||
searchq: (val, oldVal) => {
|
||||
vueHeader.searchmoveidx = 0;
|
||||
if(val.length >= 3) {
|
||||
vueHeader.searchactive = true;
|
||||
vueHeader.searchload++;
|
||||
socket.emit('search', { terms: val }, (data) => {
|
||||
vueHeader.searchres = data.match;
|
||||
vueHeader.searchsuggest = data.suggest;
|
||||
vueHeader.searchmovearr = _.concat([], vueHeader.searchres, vueHeader.searchsuggest);
|
||||
if(vueHeader.searchload > 0) { vueHeader.searchload--; }
|
||||
});
|
||||
} else {
|
||||
vueHeader.searchactive = false;
|
||||
vueHeader.searchres = [];
|
||||
vueHeader.searchsuggest = [];
|
||||
vueHeader.searchmovearr = [];
|
||||
vueHeader.searchload = 0;
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
searchq: (val, oldVal) => {
|
||||
vueHeader.searchmoveidx = 0;
|
||||
if(val.length >= 3) {
|
||||
vueHeader.searchactive = true;
|
||||
vueHeader.searchload++;
|
||||
socket.emit('search', { terms: val }, (data) => {
|
||||
vueHeader.searchres = data.match;
|
||||
vueHeader.searchsuggest = data.suggest;
|
||||
vueHeader.searchmovearr = _.concat([], vueHeader.searchres, vueHeader.searchsuggest);
|
||||
if(vueHeader.searchload > 0) { vueHeader.searchload--; }
|
||||
});
|
||||
} else {
|
||||
vueHeader.searchactive = false;
|
||||
vueHeader.searchres = [];
|
||||
vueHeader.searchsuggest = [];
|
||||
vueHeader.searchmovearr = [];
|
||||
vueHeader.searchload = 0;
|
||||
}
|
||||
},
|
||||
searchmoveidx: (val, oldVal) => {
|
||||
if(val > 0) {
|
||||
vueHeader.searchmovekey = (vueHeader.searchmovearr[val - 1]) ?
|
||||
'res.' + vueHeader.searchmovearr[val - 1]._id :
|
||||
'sug.' + vueHeader.searchmovearr[val - 1];
|
||||
} else {
|
||||
vueHeader.searchmovekey = '';
|
||||
}
|
||||
searchmoveidx: (val, oldVal) => {
|
||||
if(val > 0) {
|
||||
vueHeader.searchmovekey = (vueHeader.searchmovearr[val - 1]) ?
|
||||
'res.' + vueHeader.searchmovearr[val - 1]._id :
|
||||
'sug.' + vueHeader.searchmovearr[val - 1];
|
||||
} else {
|
||||
vueHeader.searchmovekey = '';
|
||||
}
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
useSuggestion: (sug) => {
|
||||
vueHeader.searchq = sug;
|
||||
},
|
||||
methods: {
|
||||
useSuggestion: (sug) => {
|
||||
vueHeader.searchq = sug;
|
||||
},
|
||||
closeSearch: () => {
|
||||
vueHeader.searchq = '';
|
||||
},
|
||||
moveSelectSearch: () => {
|
||||
if(vueHeader.searchmoveidx < 1) { return; }
|
||||
let i = vueHeader.searchmoveidx - 1;
|
||||
closeSearch: () => {
|
||||
vueHeader.searchq = '';
|
||||
},
|
||||
moveSelectSearch: () => {
|
||||
if(vueHeader.searchmoveidx < 1) { return; }
|
||||
let i = vueHeader.searchmoveidx - 1;
|
||||
|
||||
if(vueHeader.searchmovearr[i]) {
|
||||
window.location.assign('/' + vueHeader.searchmovearr[i]._id);
|
||||
} else {
|
||||
vueHeader.searchq = vueHeader.searchmovearr[i];
|
||||
}
|
||||
if(vueHeader.searchmovearr[i]) {
|
||||
window.location.assign('/' + vueHeader.searchmovearr[i]._id);
|
||||
} else {
|
||||
vueHeader.searchq = vueHeader.searchmovearr[i];
|
||||
}
|
||||
|
||||
},
|
||||
moveDownSearch: () => {
|
||||
if(vueHeader.searchmoveidx < vueHeader.searchmovearr.length) {
|
||||
vueHeader.searchmoveidx++;
|
||||
}
|
||||
},
|
||||
moveUpSearch: () => {
|
||||
if(vueHeader.searchmoveidx > 0) {
|
||||
vueHeader.searchmoveidx--;
|
||||
}
|
||||
},
|
||||
moveDownSearch: () => {
|
||||
if(vueHeader.searchmoveidx < vueHeader.searchmovearr.length) {
|
||||
vueHeader.searchmoveidx++;
|
||||
}
|
||||
},
|
||||
moveUpSearch: () => {
|
||||
if(vueHeader.searchmoveidx > 0) {
|
||||
vueHeader.searchmoveidx--;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
$('main').on('click', vueHeader.closeSearch);
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
$('main').on('click', vueHeader.closeSearch);
|
||||
|
||||
});
|
||||
}
|
@ -0,0 +1,48 @@
|
||||
"use strict";
|
||||
|
||||
module.exports = (socket) => {
|
||||
|
||||
//-----------------------------------------
|
||||
// SEARCH
|
||||
//-----------------------------------------
|
||||
|
||||
socket.on('search', (data, cb) => {
|
||||
cb = cb || _.noop;
|
||||
entries.search(data.terms).then((results) => {
|
||||
cb(results);
|
||||
});
|
||||
});
|
||||
|
||||
//-----------------------------------------
|
||||
// UPLOADS
|
||||
//-----------------------------------------
|
||||
|
||||
socket.on('uploadsGetFolders', (data, cb) => {
|
||||
cb = cb || _.noop;
|
||||
upl.getUploadsFolders().then((f) => {
|
||||
cb(f);
|
||||
})
|
||||
});
|
||||
|
||||
socket.on('uploadsCreateFolder', (data, cb) => {
|
||||
cb = cb || _.noop;
|
||||
upl.createUploadsFolder(data.foldername).then((f) => {
|
||||
cb(f);
|
||||
});
|
||||
});
|
||||
|
||||
socket.on('uploadsGetImages', (data, cb) => {
|
||||
cb = cb || _.noop;
|
||||
upl.getUploadsFiles('image', data.folder).then((f) => {
|
||||
cb(f);
|
||||
});
|
||||
});
|
||||
|
||||
socket.on('uploadsDeleteFile', (data, cb) => {
|
||||
cb = cb || _.noop;
|
||||
upl.deleteUploadsFile(data.uid).then((f) => {
|
||||
cb(f);
|
||||
});
|
||||
});
|
||||
|
||||
};
|
File diff suppressed because it is too large
Load Diff
@ -1,133 +0,0 @@
|
||||
"use strict";
|
||||
|
||||
const Promise = require('bluebird'),
|
||||
_ = require('lodash'),
|
||||
path = require('path');
|
||||
|
||||
/**
|
||||
* Search Model
|
||||
*/
|
||||
module.exports = {
|
||||
|
||||
_si: null,
|
||||
|
||||
/**
|
||||
* Initialize Search model
|
||||
*
|
||||
* @param {Object} appconfig The application config
|
||||
* @return {Object} Search model instance
|
||||
*/
|
||||
init(appconfig) {
|
||||
|
||||
let self = this;
|
||||
|
||||
return self;
|
||||
|
||||
},
|
||||
|
||||
find(terms) {
|
||||
|
||||
let self = this;
|
||||
terms = _.chain(terms)
|
||||
.deburr()
|
||||
.toLower()
|
||||
.trim()
|
||||
.replace(/[^a-z0-9 ]/g, '')
|
||||
.split(' ')
|
||||
.filter((f) => { return !_.isEmpty(f); })
|
||||
.join(' ')
|
||||
.value();
|
||||
|
||||
return db.Entry.find(
|
||||
{ $text: { $search: terms } },
|
||||
{ score: { $meta: "textScore" }, title: 1 }
|
||||
)
|
||||
.sort({ score: { $meta: "textScore" } })
|
||||
.limit(10)
|
||||
.exec()
|
||||
.then((hits) => {
|
||||
|
||||
/*if(hits.length < 5) {
|
||||
return self._si.matchAsync({
|
||||
beginsWith: terms,
|
||||
threshold: 3,
|
||||
limit: 5,
|
||||
type: 'simple'
|
||||
}).then((matches) => {
|
||||
|
||||
return {
|
||||
match: hits,
|
||||
suggest: matches
|
||||
};
|
||||
|
||||
});
|
||||
} else {*/
|
||||
return {
|
||||
match: hits,
|
||||
suggest: []
|
||||
};
|
||||
//}
|
||||
|
||||
}).catch((err) => {
|
||||
|
||||
if(err.type === 'NotFoundError') {
|
||||
return {
|
||||
match: [],
|
||||
suggest: []
|
||||
};
|
||||
} else {
|
||||
winston.error(err);
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
},
|
||||
|
||||
/**
|
||||
* Delete an entry from the index
|
||||
*
|
||||
* @param {String} The entry path
|
||||
* @return {Promise} Promise of the operation
|
||||
*/
|
||||
delete(entryPath) {
|
||||
|
||||
let self = this;
|
||||
/*let hasResults = false;
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
|
||||
self._si.search({
|
||||
query: {
|
||||
AND: { 'entryPath': [entryPath] }
|
||||
}
|
||||
}).on('data', (results) => {
|
||||
|
||||
hasResults = true;
|
||||
|
||||
if(results.totalHits > 0) {
|
||||
let delIds = _.map(results.hits, 'id');
|
||||
self._si.del(delIds).on('end', () => { return resolve(true); });
|
||||
} else {
|
||||
resolve(true);
|
||||
}
|
||||
|
||||
}).on('error', (err) => {
|
||||
|
||||
if(err.type === 'NotFoundError') {
|
||||
resolve(true);
|
||||
} else {
|
||||
winston.error(err);
|
||||
reject(err);
|
||||
}
|
||||
|
||||
}).on('end', () => {
|
||||
if(!hasResults) {
|
||||
resolve(true);
|
||||
}
|
||||
});
|
||||
|
||||
});*/
|
||||
|
||||
}
|
||||
|
||||
};
|
@ -1,184 +0,0 @@
|
||||
// ===========================================
|
||||
// REQUARKS WIKI - WebSocket Server
|
||||
// 1.0.0
|
||||
// Licensed under AGPLv3
|
||||
// ===========================================
|
||||
|
||||
global.ROOTPATH = __dirname;
|
||||
global.PROCNAME = 'WS';
|
||||
|
||||
// ----------------------------------------
|
||||
// Load Winston
|
||||
// ----------------------------------------
|
||||
|
||||
var _isDebug = process.env.NODE_ENV === 'development';
|
||||
global.winston = require('./lib/winston')(_isDebug);
|
||||
|
||||
// ----------------------------------------
|
||||
// Fetch internal handshake key
|
||||
// ----------------------------------------
|
||||
|
||||
if(!process.argv[2] || process.argv[2].length !== 40) {
|
||||
winston.error('[WS] Illegal process start. Missing handshake key.');
|
||||
process.exit(1);
|
||||
}
|
||||
global.internalAuth = require('./lib/internalAuth').init(process.argv[2]);;
|
||||
|
||||
// ----------------------------------------
|
||||
// Load global modules
|
||||
// ----------------------------------------
|
||||
|
||||
winston.info('[WS] WS Server is initializing...');
|
||||
|
||||
var appconfig = require('./models/config')('./config.yml');
|
||||
global.db = require('./models/mongo').init(appconfig);
|
||||
global.upl = require('./models/ws/uploads').init(appconfig);
|
||||
global.entries = require('./models/entries').init(appconfig);
|
||||
global.mark = require('./models/markdown');
|
||||
global.search = require('./models/ws/search').init(appconfig);
|
||||
|
||||
// ----------------------------------------
|
||||
// Load local modules
|
||||
// ----------------------------------------
|
||||
|
||||
var _ = require('lodash');
|
||||
var express = require('express');
|
||||
var path = require('path');
|
||||
var http = require('http');
|
||||
var socketio = require('socket.io');
|
||||
var moment = require('moment');
|
||||
|
||||
// ----------------------------------------
|
||||
// Define Express App
|
||||
// ----------------------------------------
|
||||
|
||||
global.app = express();
|
||||
|
||||
// ----------------------------------------
|
||||
// Controllers
|
||||
// ----------------------------------------
|
||||
|
||||
app.get('/', function(req, res){
|
||||
res.send('Requarks Wiki WebSocket server');
|
||||
});
|
||||
|
||||
// ----------------------------------------
|
||||
// Start WebSocket server
|
||||
// ----------------------------------------
|
||||
|
||||
winston.info('[SERVER] Starting WebSocket server on port ' + appconfig.wsPort + '...');
|
||||
|
||||
app.set('port', appconfig.wsPort);
|
||||
var server = http.Server(app);
|
||||
var io = socketio(server);
|
||||
|
||||
server.on('error', (error) => {
|
||||
if (error.syscall !== 'listen') {
|
||||
throw error;
|
||||
}
|
||||
|
||||
switch (error.code) {
|
||||
case 'EACCES':
|
||||
console.error('Listening on port ' + appconfig.port + ' requires elevated privileges!');
|
||||
process.exit(1);
|
||||
break;
|
||||
case 'EADDRINUSE':
|
||||
console.error('Port ' + appconfig.port + ' is already in use!');
|
||||
process.exit(1);
|
||||
break;
|
||||
default:
|
||||
throw error;
|
||||
}
|
||||
});
|
||||
|
||||
server.listen(appconfig.wsPort, () => {
|
||||
winston.info('[WS] WebSocket server started successfully! [RUNNING]');
|
||||
});
|
||||
|
||||
io.on('connection', (socket) => {
|
||||
|
||||
//-----------------------------------------
|
||||
// SEARCH
|
||||
//-----------------------------------------
|
||||
|
||||
socket.on('searchAdd', (data) => {
|
||||
if(internalAuth.validateKey(data.auth)) {
|
||||
search.add(data.content);
|
||||
}
|
||||
});
|
||||
|
||||
socket.on('searchDel', (data, cb) => {
|
||||
cb = cb || _.noop;
|
||||
if(internalAuth.validateKey(data.auth)) {
|
||||
search.delete(data.entryPath);
|
||||
}
|
||||
});
|
||||
|
||||
socket.on('search', (data, cb) => {
|
||||
cb = cb || _.noop;
|
||||
search.find(data.terms).then((results) => {
|
||||
cb(results);
|
||||
});
|
||||
});
|
||||
|
||||
//-----------------------------------------
|
||||
// UPLOADS
|
||||
//-----------------------------------------
|
||||
|
||||
socket.on('uploadsSetFolders', (data) => {
|
||||
if(internalAuth.validateKey(data.auth)) {
|
||||
upl.setUploadsFolders(data.content);
|
||||
}
|
||||
});
|
||||
|
||||
socket.on('uploadsGetFolders', (data, cb) => {
|
||||
cb = cb || _.noop;
|
||||
cb(upl.getUploadsFolders());
|
||||
});
|
||||
|
||||
socket.on('uploadsValidateFolder', (data, cb) => {
|
||||
cb = cb || _.noop;
|
||||
if(internalAuth.validateKey(data.auth)) {
|
||||
cb(upl.validateUploadsFolder(data.content));
|
||||
}
|
||||
});
|
||||
|
||||
socket.on('uploadsCreateFolder', (data, cb) => {
|
||||
cb = cb || _.noop;
|
||||
upl.createUploadsFolder(data.foldername).then((fldList) => {
|
||||
cb(fldList);
|
||||
});
|
||||
});
|
||||
|
||||
socket.on('uploadsSetFiles', (data) => {
|
||||
if(internalAuth.validateKey(data.auth)) {
|
||||
upl.setUploadsFiles(data.content);
|
||||
}
|
||||
});
|
||||
|
||||
socket.on('uploadsAddFiles', (data) => {
|
||||
if(internalAuth.validateKey(data.auth)) {
|
||||
upl.addUploadsFiles(data.content);
|
||||
}
|
||||
});
|
||||
|
||||
socket.on('uploadsGetImages', (data, cb) => {
|
||||
cb = cb || _.noop;
|
||||
cb(upl.getUploadsFiles('image', data.folder));
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
// ----------------------------------------
|
||||
// Shutdown gracefully
|
||||
// ----------------------------------------
|
||||
|
||||
process.on('disconnect', () => {
|
||||
winston.warn('[WS] Lost connection to main server. Exiting... [' + moment().toISOString() + ']');
|
||||
server.close();
|
||||
process.exit();
|
||||
});
|
||||
|
||||
process.on('exit', () => {
|
||||
server.stop();
|
||||
});
|
Loading…
Reference in new issue