You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

115 lines
3.4 KiB

4 years ago
  1. 'use strict';
  2. const $ = require('cheerio');
  3. const eejs = require('ep_etherpad-lite/node/eejs');
  4. const padManager = require('ep_etherpad-lite/node/db/PadManager');
  5. const api = require('ep_etherpad-lite/node/db/API');
  6. let ioNs = null;
  7. const queryLimit = 12;
  8. const isNumeric = (arg) => typeof arg === 'number' || (typeof arg === 'string' && parseInt(arg));
  9. const regExpQuote = (x) => x.toString().replace(/[-\\^$*+?.()|[\]{}]/g, '\\$&');
  10. const search = async (query) => {
  11. const {padIDs} = await padManager.listAllPads();
  12. const data = {
  13. progress: 1,
  14. messageId: 'ep_adminpads2_search-done',
  15. query,
  16. total: padIDs.length,
  17. };
  18. let maxResult = 0;
  19. let result = padIDs;
  20. if (query.pattern != null && query.pattern !== '') {
  21. let pattern = `*${query.pattern}*`;
  22. pattern = regExpQuote(pattern);
  23. pattern = pattern.replace(/(\\\*)+/g, '.*');
  24. pattern = `^${pattern}$`;
  25. const regex = new RegExp(pattern, 'i');
  26. result = result.filter(regex.test.bind(regex));
  27. }
  28. data.total = result.length;
  29. maxResult = result.length - 1;
  30. if (maxResult < 0) {
  31. maxResult = 0;
  32. }
  33. if (!isNumeric(query.offset) || query.offset < 0) {
  34. query.offset = 0;
  35. } else if (query.offset > maxResult) {
  36. query.offset = maxResult;
  37. }
  38. if (!isNumeric(query.limit) || query.limit < 0) {
  39. query.limit = queryLimit;
  40. }
  41. const rs = result.slice(query.offset, query.offset + query.limit);
  42. data.results = rs.map((padName) => ({padName, lastEdited: '', userCount: 0}));
  43. if (!data.results.length) data.messageId = 'ep_adminpads2_no-results';
  44. await Promise.all(data.results.map(async (entry) => {
  45. const pad = await padManager.getPad(entry.padName);
  46. entry.userCount = api.padUsersCount(entry.padName).padUsersCount;
  47. entry.lastEdited = await pad.getLastEdit();
  48. }));
  49. return data;
  50. };
  51. exports.expressCreateServer = (hookName, {app}, cb) => {
  52. app.get('/admin/pads', (req, res) => {
  53. res.send(eejs.require('ep_adminpads2/templates/admin/pads.html', {errors: []}));
  54. });
  55. return cb();
  56. };
  57. exports.socketio = (hookName, {io}, cb) => {
  58. ioNs = io.of('/pluginfw/admin/pads');
  59. ioNs.on('connection', (socket) => {
  60. const _search = async (query) => {
  61. try {
  62. const result = await search(query);
  63. socket.emit('search-result', result);
  64. } catch (err) {
  65. socket.emit('search-error', err.stack ? err.stack : err.toString());
  66. }
  67. };
  68. socket.on('load', () => _search({pattern: '', offset: 0, limit: queryLimit}));
  69. socket.on('search', _search);
  70. socket.on('delete', async (padId) => {
  71. const padExists = await padManager.doesPadExists(padId);
  72. if (padExists) {
  73. // pad exists, remove
  74. const pad = await padManager.getPad(padId);
  75. await pad.remove();
  76. socket.emit('progress', {progress: 1});
  77. }
  78. });
  79. });
  80. return cb();
  81. };
  82. const updatePads = (hookName, context, cb) => {
  83. ioNs.emit('progress', {progress: 1});
  84. return cb();
  85. };
  86. exports.padRemove = updatePads;
  87. exports.padCreate = updatePads;
  88. exports.eejsBlock_adminMenu = (hookName, context, cb) => {
  89. const ul = $('<ul>').html(context.content);
  90. const pfx = ul.find('li a').attr('href').match(/^((?:\.\.\/)*)/)[1];
  91. ul.append(
  92. $('<li>').append(
  93. $('<a>')
  94. .attr('href', `${pfx}pads`)
  95. .attr('data-l10n-id', 'ep_adminpads2_manage-pads')
  96. .text('Manage pads')));
  97. context.content = ul.html();
  98. return cb();
  99. };