ep_adminpads2
Advanced tools
Comparing version 2.0.0 to 2.1.0
30
ep.json
{ | ||
"parts": [ | ||
{ | ||
"name": "ep_adminpads2", | ||
"hooks": { | ||
"expressCreateServer" : "ep_adminpads2/index:registerRoute", | ||
"socketio" : "ep_adminpads2/index:socketio", | ||
"padRemove" : "ep_adminpads2/index:updatePads", | ||
"padCreate" : "ep_adminpads2/index:updatePads", | ||
"eejsBlock_adminMenu" : "ep_adminpads2/index:eejsBlock_adminMenu" | ||
}, | ||
"client_hooks" : { | ||
"documentReady" : "ep_adminpads2/static/js/admin/pads:documentReady" | ||
} | ||
} | ||
] | ||
"parts": [ | ||
{ | ||
"name": "ep_adminpads2", | ||
"hooks": { | ||
"expressCreateServer": "ep_adminpads2", | ||
"socketio": "ep_adminpads2", | ||
"padRemove": "ep_adminpads2", | ||
"padCreate": "ep_adminpads2", | ||
"eejsBlock_adminMenu": "ep_adminpads2" | ||
}, | ||
"client_hooks": { | ||
"documentReady": "ep_adminpads2/static/js/admin/pads" | ||
} | ||
} | ||
] | ||
} |
204
index.js
@@ -0,1 +1,2 @@ | ||
const $ = require('cheerio'); | ||
const eejs = require('ep_etherpad-lite/node/eejs'); | ||
@@ -6,96 +7,60 @@ const padManager = require('ep_etherpad-lite/node/db/PadManager'); | ||
RegExp.quote = function (x) { | ||
return x.toString().replace(/[-\\^$*+?.()|[\]{}]/g, '\\$&'); | ||
}; | ||
const isNumeric = function (arg) { | ||
return typeof arg == 'number' || (typeof arg == 'string' && parseInt(arg)); | ||
}; | ||
const isNumeric = (arg) => typeof arg == 'number' || (typeof arg == 'string' && parseInt(arg)); | ||
let pads = { | ||
pads: [], | ||
search: async function (query) { | ||
let the_pads = await padManager.listAllPads(); | ||
return await pads._do_search(the_pads.padIDs, query); | ||
}, | ||
_do_search: async function (pads, query) { | ||
let data = { | ||
progress: 1, | ||
message: 'Search done.', | ||
query: query, | ||
total: pads.length, | ||
}, | ||
maxResult = 0, | ||
result = []; | ||
if (query['pattern'] != null && query['pattern'] !== '') { | ||
let pattern = '*' + query.pattern + '*'; | ||
pattern = RegExp.quote(pattern); | ||
pattern = pattern.replace(/(\\\*)+/g, '.*'); | ||
pattern = '^' + pattern + '$'; | ||
let regex = new RegExp(pattern, 'i'); | ||
pads.forEach(function (padID) { | ||
if (regex.test(padID)) { | ||
result.push(padID); | ||
} | ||
}); | ||
} else { | ||
result = pads; | ||
} | ||
const search = async (query) => { | ||
const {padIDs} = await padManager.listAllPads(); | ||
const data = { | ||
progress: 1, | ||
messageId: 'ep_adminpads2_search-done', | ||
query: query, | ||
total: padIDs.length, | ||
}; | ||
let maxResult = 0; | ||
let result = padIDs; | ||
if (query.pattern != null && query.pattern !== '') { | ||
let pattern = '*' + query.pattern + '*'; | ||
pattern = regExpQuote(pattern); | ||
pattern = pattern.replace(/(\\\*)+/g, '.*'); | ||
pattern = '^' + pattern + '$'; | ||
const regex = new RegExp(pattern, 'i'); | ||
result = result.filter(regex.test.bind(regex)); | ||
} | ||
data.total = result.length; | ||
data.total = result.length; | ||
maxResult = result.length - 1; | ||
if (maxResult < 0) { | ||
maxResult = 0; | ||
} | ||
maxResult = result.length - 1; | ||
if (maxResult < 0) { | ||
maxResult = 0; | ||
} | ||
if (!isNumeric(query.offset) || query.offset < 0) { | ||
query.offset = 0; | ||
} else if (query.offset > maxResult) { | ||
query.offset = maxResult; | ||
} | ||
if (!isNumeric(query.offset) || query.offset < 0) { | ||
query.offset = 0; | ||
} else if (query.offset > maxResult) { | ||
query.offset = maxResult; | ||
} | ||
if (!isNumeric(query.limit) || query.limit < 0) { | ||
query.limit = queryLimit; | ||
} | ||
if (!isNumeric(query.limit) || query.limit < 0) { | ||
query.limit = queryLimit; | ||
} | ||
let rs = result.slice(query.offset, query.offset + query.limit); | ||
let rs = result.slice(query.offset, query.offset + query.limit); | ||
pads.pads = rs; | ||
let entrySet; | ||
data.results = []; | ||
rs.forEach(function (value) { | ||
entrySet = {padName: value, lastEdited: '', userCount: 0}; | ||
data.results.push(entrySet); | ||
}); | ||
let getEdited = []; | ||
if (data.results.length > 0) { | ||
data.results.forEach(function (value) { | ||
getEdited.push( | ||
api.getLastEdited(value.padName) | ||
.then((resultObject) => { | ||
value.lastEdited = resultObject.lastEdited; | ||
resultObject = api.padUsersCount(value.padName); | ||
value.userCount = resultObject.padUsersCount; | ||
})); | ||
}); | ||
} else { | ||
data.message = 'No results'; | ||
} | ||
await Promise.all(getEdited); | ||
return data; | ||
}, | ||
data.results = rs.map((padName) => ({padName, lastEdited: '', userCount: 0})); | ||
if (!data.results.length) data.messageId = 'ep_adminpads2_no-results'; | ||
await Promise.all(data.results.map(async (entry) => { | ||
const pad = await padManager.getPad(entry.padName); | ||
entry.userCount = api.padUsersCount(entry.padName).padUsersCount; | ||
entry.lastEdited = await pad.getLastEdit(); | ||
})); | ||
return data; | ||
}; | ||
exports.registerRoute = function (hook_name, args, cb) { | ||
args.app.get('/admin/pads', function (req, res) { | ||
let render_args = { | ||
errors: [], | ||
}; | ||
res.send(eejs.require('ep_adminpads2/templates/admin/pads.html', render_args)); | ||
}); | ||
return cb(); | ||
exports.expressCreateServer = (hook_name, args, cb) => { | ||
args.app.get('/admin/pads', (req, res) => { | ||
let render_args = { | ||
errors: [], | ||
}; | ||
res.send(eejs.require('ep_adminpads2/templates/admin/pads.html', render_args)); | ||
}); | ||
return cb(); | ||
}; | ||
@@ -105,39 +70,48 @@ | ||
exports.socketio = function (hook_name, args) { | ||
io = args.io.of('/pluginfw/admin/pads'); | ||
io.on('connection', function (socket) { | ||
socket.on('load', async function (query) { | ||
let result = await pads.search({pattern: '', offset: 0, limit: queryLimit}); | ||
socket.emit('search-result', result); | ||
}); | ||
exports.socketio = (hook_name, args) => { | ||
io = args.io.of('/pluginfw/admin/pads'); | ||
io.on('connection', (socket) => { | ||
socket.on('load', async (query) => { | ||
let result = await search({pattern: '', offset: 0, limit: queryLimit}); | ||
socket.emit('search-result', result); | ||
}); | ||
socket.on('search', async function (query) { | ||
let result = await pads.search(query); | ||
socket.emit('search-result', result); | ||
}); | ||
socket.on('search', async (query) => { | ||
let result = await search(query); | ||
socket.emit('search-result', result); | ||
}); | ||
socket.on('delete', async function (padId) { | ||
let padExists = await padManager.doesPadExists(padId); | ||
if (padExists) { | ||
//pad exists, remove | ||
let pad = await padManager.getPad(padId); | ||
await pad.remove(); | ||
socket.emit('progress', {progress: 1}); | ||
} | ||
}); | ||
socket.on('delete', async (padId) => { | ||
let padExists = await padManager.doesPadExists(padId); | ||
if (padExists) { | ||
//pad exists, remove | ||
let pad = await padManager.getPad(padId); | ||
await pad.remove(); | ||
socket.emit('progress', {progress: 1}); | ||
} | ||
}); | ||
}); | ||
}; | ||
exports.updatePads = function (hook_name, args, cb) { | ||
io.emit('progress', {progress: 1}); | ||
return cb(); | ||
const updatePads = (hookName, args, cb) => { | ||
io.emit('progress', {progress: 1}); | ||
return cb(); | ||
}; | ||
exports.eejsBlock_adminMenu = function (hook_name, args, cb) { | ||
let hasAdminUrlPrefix = args.content.indexOf('<a href="admin/') !== -1, | ||
hasOneDirDown = args.content.indexOf('<a href="../') !== -1, | ||
hasTwoDirDown = args.content.indexOf('<a href="../../') !== -1, | ||
urlPrefix = hasAdminUrlPrefix ? 'admin/' : hasTwoDirDown ? '../../' : hasOneDirDown ? '../' : ''; | ||
args.content = args.content + '<li><a href="' + urlPrefix + 'pads" data-l10n-id="ep_adminpads2_manage-pads">Manage pads</a></li>'; | ||
return cb(); | ||
exports.padRemove = updatePads; | ||
exports.padCreate = updatePads; | ||
exports.eejsBlock_adminMenu = (hookName, context, cb) => { | ||
const ul = $('<ul>').html(context.content); | ||
const pfx = ul.find('li a').attr('href').match(/^((?:\.\.\/)*)/)[1]; | ||
ul.append( | ||
$('<li>').append( | ||
$('<a>') | ||
.attr('href', `${pfx}pads`) | ||
.attr('data-l10n-id', 'ep_adminpads2_manage-pads') | ||
.text('Manage pads'))); | ||
context.content = ul.html(); | ||
return cb(); | ||
}; | ||
const regExpQuote = (x) => x.toString().replace(/[-\\^$*+?.()|[\]{}]/g, '\\$&'); |
@@ -17,2 +17,4 @@ { | ||
"ep_adminpads2_unknown-status": "Unknown status", | ||
"ep_adminpads2_unknown-error": "Unknown error", | ||
"ep_adminpads2_search-done": "Search complete", | ||
"ep_adminpads2_no-results": "No results", | ||
@@ -19,0 +21,0 @@ |
@@ -17,2 +17,4 @@ { | ||
"ep_adminpads2_unknown-status": "Ismeretlen állapot", | ||
"ep_adminpads2_unknown-error": "Ismeretlen hiba", | ||
"ep_adminpads2_search-done": "Keresés befejezve", | ||
"ep_adminpads2_no-results": "Nincs találat", | ||
@@ -19,0 +21,0 @@ |
{ | ||
"name": "ep_adminpads2", | ||
"version": "2.0.0", | ||
"version": "2.1.0", | ||
"description": "Etherpad plugin to list and delete pads in /admin.", | ||
"keywords": [ | ||
"etherpad", | ||
"plugin", | ||
"ep" | ||
], | ||
"homepage": "https://github.com/rhansen/ep_adminpads2", | ||
@@ -14,3 +19,6 @@ "bugs": { | ||
"main": "index.js", | ||
"dependencies": { | ||
"cheerio": "^0.22.0" | ||
}, | ||
"license": "MIT" | ||
} |
@@ -1,191 +0,164 @@ | ||
exports.documentReady = function(hooks, context, cb) { | ||
if (context !== 'admin/pads') { | ||
return cb; | ||
} | ||
exports.documentReady = async (hookName, context) => { | ||
if (context !== 'admin/pads') return; | ||
var socket, | ||
loc = document.location, | ||
port = loc.port == '' ? (loc.protocol == 'https:' ? 443 : 80) : loc.port, | ||
url = loc.protocol + '//' + loc.hostname + ':' + port + '/', | ||
pathComponents = location.pathname.split('/'), | ||
// Strip admin/plugins | ||
baseURL = pathComponents.slice(0, pathComponents.length - 2).join('/') + '/', | ||
resource = baseURL.substring(1) + 'socket.io'; | ||
const basePath = location.pathname.split('/').slice(0, -2).join('/'); // Strip /admin/plugins. | ||
const socketioPath = `${basePath}/socket.io`; | ||
// Note: The socket.io URL should not contain ${basePath} because the path part of this URL is | ||
// used as the socket.io namespace. | ||
const socketioUrl = `${location.protocol}//${location.host}/pluginfw/admin/pads`; | ||
var room = url + 'pluginfw/admin/pads'; | ||
const socket = io.connect(socketioUrl, {path: socketioPath}); | ||
var changeTimer; | ||
let changeTimer; | ||
//connect | ||
socket = io.connect(room, {path: baseURL + 'socket.io', resource: resource}); | ||
$('#search-results').data('query', { | ||
pattern: '', | ||
offset: 0, | ||
limit: 12, | ||
}); | ||
$('.search-results').data('query', { | ||
pattern: '', | ||
offset: 0, | ||
limit: 12, | ||
}); | ||
let doUpdate = false; | ||
const doAutoUpdate = () => $('#results-autoupdate').prop('checked'); | ||
var doUpdate = false; | ||
var doAutoUpdate = function () { | ||
return $('#results-autoupdate').prop('checked'); | ||
}; | ||
const search = () => { | ||
clearTimeout(changeTimer); | ||
socket.emit('search', $('#search-results').data('query')); | ||
}; | ||
var search = function () { | ||
clearTimeout(changeTimer); | ||
socket.emit('search', $('.search-results').data('query')); | ||
}; | ||
const submitSearch = () => { | ||
const query = $('#search-results').data('query'); | ||
query.pattern = $('#search-query')[0].value; | ||
query.offset = 0; | ||
search(); | ||
}; | ||
var htmlEntities = function (padName) { | ||
return $('<div/>').text(padName).html(); | ||
}; | ||
const isInt = (input) => typeof input === 'number' && input % 1 === 0; | ||
var submitSearch = function () { | ||
var query = $('.search-results').data('query'); | ||
query.pattern = $('#search-query')[0].value; | ||
query.offset = 0; | ||
search(); | ||
}; | ||
const formatDate = (longtime) => { | ||
return (new Date(longtime)).toLocaleString(undefined, { | ||
dateStyle: 'short', | ||
timeStyle: 'long', | ||
}); | ||
}; | ||
var isInt = function (input) { | ||
return typeof input === 'number' && input % 1 === 0; | ||
}; | ||
const fillZeros = (x) => isInt(x) ? (x < 10 ? '0' + x : x) : ''; | ||
var formatDate = function (longtime) { | ||
var formattedDate = ''; | ||
if (longtime != null && isInt(longtime)) { | ||
var date = new Date(longtime); | ||
var month = date.getMonth() + 1; | ||
formattedDate = date.getFullYear() + '-' + fillZeros(month) + '-' + fillZeros(date.getDate()) + ' ' + fillZeros(date.getHours()) + ':' + fillZeros(date.getMinutes()) + ':' + fillZeros(date.getSeconds()); | ||
} | ||
return formattedDate; | ||
}; | ||
const updateHandlers = () => { | ||
$('#progress.dialog .close').off('click').click(() => $('#progress.dialog').hide()); | ||
var fillZeros = function (fillForm) { | ||
return isInt(fillForm) ? (fillForm < 10 ? '0' + fillForm : fillForm) : ''; | ||
}; | ||
$('#search-form').off('submit').on('submit', (e) => { | ||
e.preventDefault(); | ||
submitSearch(); | ||
}); | ||
function updateHandlers() { | ||
$('#progress.dialog .close').off('click').click(function () { | ||
$('#progress.dialog').hide(); | ||
}); | ||
$('#do-search').off('click').click(submitSearch); | ||
$('#search-form').off('submit').on('submit', function (e) { | ||
e.preventDefault(); | ||
submitSearch(); | ||
}); | ||
$('#search-query').off('change paste keyup').on('change paste keyup', (e) => { | ||
clearTimeout(changeTimer); | ||
changeTimer = setTimeout(() => { | ||
e.preventDefault(); | ||
submitSearch(); | ||
}, 500); | ||
}); | ||
$('#do-search').off('click').click(submitSearch); | ||
$('.do-delete').off('click').click((e) => { | ||
const row = $(e.target).closest('tr'); | ||
const padID = row.find('.padname').text(); | ||
if (confirm(_('ep_adminpads2_confirm', {padID: padID}) || | ||
`Do you really want to delete the pad ${padID}?`)) { | ||
doUpdate = true; | ||
socket.emit('delete', padID); | ||
} | ||
}); | ||
$('#search-query').off('change paste keyup').on('change paste keyup', function (e) { | ||
clearTimeout(changeTimer); | ||
changeTimer = setTimeout(function () { | ||
e.preventDefault(); | ||
submitSearch(); | ||
}, 500); | ||
}); | ||
$('#do-prev-page').off('click').click((e) => { | ||
const query = $('#search-results').data('query'); | ||
query.offset -= query.limit; | ||
if (query.offset < 0) query.offset = 0; | ||
search(); | ||
}); | ||
$('#do-next-page').off('click').click((e) => { | ||
const query = $('#search-results').data('query'); | ||
const total = $('#search-results').data('total'); | ||
if (query.offset + query.limit < total) { | ||
query.offset += query.limit; | ||
} | ||
search(); | ||
}); | ||
}; | ||
$('.do-delete').off('click').click(function (e) { | ||
var row = $(e.target).closest('tr'); | ||
var padID = row.find('.padname').text(); | ||
if (confirm(_('ep_adminpads2_confirm', {padID: padID}) || `Do you really want to delete the pad ${padID}?`)) { | ||
doUpdate = true; | ||
socket.emit('delete', padID); | ||
} | ||
}); | ||
updateHandlers(); | ||
$('.do-prev-page').off('click').click(function (e) { | ||
var query = $('.search-results').data('query'); | ||
query.offset -= query.limit; | ||
if (query.offset < 0) { | ||
query.offset = 0; | ||
} | ||
search(); | ||
}); | ||
$('.do-next-page').off('click').click(function (e) { | ||
var query = $('.search-results').data('query'); | ||
var total = $('.search-results').data('total'); | ||
if (query.offset + query.limit < total) { | ||
query.offset += query.limit; | ||
} | ||
search(); | ||
}); | ||
socket.on('progress', (data) => { | ||
$('#progress .close').hide(); | ||
$('#progress').show(); | ||
$('#progress').data('progress', data.progress); | ||
const message = $('<span>'); | ||
if (data.isError) { | ||
message.addClass('error'); | ||
message.text(_(data.messageId) || _('ep_adminpads2_unknown-error') || 'Unknown error'); | ||
} else { | ||
message.addClass('status'); | ||
message.text(_(data.messageId) || _('ep_adminpads2_unknown-status') || 'Unknown status'); | ||
} | ||
$('#progress .message').empty().append(message); | ||
updateHandlers(); | ||
socket.on('progress', function (data) { | ||
$('#progress .close').hide(); | ||
if (data.progress >= 1) { | ||
if (data.isError) { | ||
$('#progress').show(); | ||
$('#progress').data('progress', data.progress); | ||
var message = _('ep_adminpads2_unknown-status') || 'Unknown status'; | ||
if (data.message) { | ||
message = '<span class="status">' + data.message.toString() + '</span>'; | ||
} else { | ||
if (doUpdate || doAutoUpdate()) { | ||
doUpdate = false; | ||
search(); | ||
} | ||
if (data.error) { | ||
message = '<span class="error">' + data.error.toString() + '<span>'; | ||
} | ||
$('#progress .message').html(message); | ||
$('#progress').hide(); | ||
} | ||
} | ||
}); | ||
if (data.progress >= 1) { | ||
if (data.error) { | ||
$('#progress').show(); | ||
} else { | ||
if (doUpdate || doAutoUpdate()) { | ||
doUpdate = false; | ||
search(); | ||
} | ||
$('#progress').hide(); | ||
} | ||
} | ||
}); | ||
socket.on('search-result', (data) => { | ||
const widget = $('#search-results'); | ||
let limit = data.query.offset + data.query.limit; | ||
if (limit > data.total) { | ||
limit = data.total; | ||
} | ||
socket.on('search-result', function (data) { | ||
var widget = $('.search-results') | ||
, limit = data.query.offset + data.query.limit | ||
; | ||
if (limit > data.total) { | ||
limit = data.total; | ||
} | ||
widget.data('query', data.query); | ||
widget.data('total', data.total); | ||
widget.data('query', data.query); | ||
widget.data('total', data.total); | ||
widget.find('.offset').html(data.query.offset); | ||
widget.find('.limit').html(limit); | ||
widget.find('.total').html(data.total); | ||
widget.find('.offset').html(data.query.offset); | ||
widget.find('.limit').html(limit); | ||
widget.find('.total').html(data.total); | ||
widget.find('#results *').remove(); | ||
const resultList = widget.find('#results'); | ||
widget.find('.results *').remove(); | ||
var resultList = widget.find('.results'); | ||
if (data.results.length > 0) { | ||
data.results.forEach((resultset) => { | ||
const {padName, lastEdited, userCount} = resultset; | ||
const row = widget.find('#template').clone().removeAttr('id'); | ||
row.find('.padname').empty().append( | ||
$('<a>').attr('href', `../p/${encodeURIComponent(padName)}`).text(padName)); | ||
row.find('.last-edited').text(formatDate(lastEdited)); | ||
row.find('.user-count').text(userCount); | ||
resultList.append(row); | ||
}); | ||
} else { | ||
const noResults = _('ep_adminpads2_no-results') || 'No results'; | ||
resultList.append( | ||
$('<tr>').append( | ||
$('<td>') | ||
.attr('colspan', '4') | ||
.addClass('no-results') | ||
.text(noResults))); | ||
} | ||
if (data.results.length > 0) { | ||
data.results.forEach(function (resultset) { | ||
var padName = resultset.padName; | ||
var lastEdited = resultset.lastEdited; | ||
var userCount = resultset.userCount; | ||
var row = widget.find('.template tr').clone(); | ||
row.find('.padname').html('<a href="../p/' + encodeURIComponent(padName) + '">' + htmlEntities(padName) + '</a>' | ||
) | ||
; | ||
row.find('.last-edited').html(formatDate(lastEdited)); | ||
row.find('.user-count').html(userCount); | ||
resultList.append(row); | ||
}); | ||
} else { | ||
const noResults = _('ep_adminpads2_no-results') || 'No results'; | ||
resultList.append( | ||
$('<tr>').append( | ||
$('<td>') | ||
.attr('colspan', '4') | ||
.addClass('no - results') | ||
.text(noResults))); | ||
} | ||
updateHandlers(); | ||
}); | ||
updateHandlers(); | ||
}); | ||
socket.emit('load'); | ||
search(); | ||
return cb; | ||
socket.emit('load'); | ||
search(); | ||
return; | ||
}; |
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
38646
1
291
+ Addedcheerio@^0.22.0
+ Addedboolbase@1.0.0(transitive)
+ Addedcheerio@0.22.0(transitive)
+ Addedcss-select@1.2.0(transitive)
+ Addedcss-what@2.1.3(transitive)
+ Addeddom-serializer@0.1.1(transitive)
+ Addeddomelementtype@1.3.1(transitive)
+ Addeddomhandler@2.4.2(transitive)
+ Addeddomutils@1.5.1(transitive)
+ Addedentities@1.1.2(transitive)
+ Addedhtmlparser2@3.10.1(transitive)
+ Addedinherits@2.0.4(transitive)
+ Addedlodash.assignin@4.2.0(transitive)
+ Addedlodash.bind@4.2.1(transitive)
+ Addedlodash.defaults@4.2.0(transitive)
+ Addedlodash.filter@4.6.0(transitive)
+ Addedlodash.flatten@4.4.0(transitive)
+ Addedlodash.foreach@4.5.0(transitive)
+ Addedlodash.map@4.6.0(transitive)
+ Addedlodash.merge@4.6.2(transitive)
+ Addedlodash.pick@4.4.0(transitive)
+ Addedlodash.reduce@4.6.0(transitive)
+ Addedlodash.reject@4.6.0(transitive)
+ Addedlodash.some@4.6.0(transitive)
+ Addednth-check@1.0.2(transitive)
+ Addedreadable-stream@3.6.2(transitive)
+ Addedsafe-buffer@5.2.1(transitive)
+ Addedstring_decoder@1.3.0(transitive)
+ Addedutil-deprecate@1.0.2(transitive)