Index: lams_build/conf/etherpad/etherpad-lite/node_modules/ep_image_upload/ep.json
===================================================================
diff -u
--- lams_build/conf/etherpad/etherpad-lite/node_modules/ep_image_upload/ep.json (revision 0)
+++ lams_build/conf/etherpad/etherpad-lite/node_modules/ep_image_upload/ep.json (revision fea3e6eb1a66370c10e3ae985c276f79a3629635)
@@ -0,0 +1,34 @@
+{
+ "parts": [
+ {
+ "name": "ep_image_upload",
+ "client_hooks": {
+ "postToolbarInit": "ep_image_upload/static/js/toolbar",
+ "aceAttribsToClasses" : "ep_image_upload/static/js/clientHooks",
+ "aceDomLineProcessLineAttributes" : "ep_image_upload/static/js/clientHooks",
+ "aceInitialized": "ep_image_upload/static/js/clientHooks",
+ "aceRegisterBlockElements": "ep_image_upload/static/js/clientHooks",
+ "aceEditorCSS": "ep_image_upload/static/js/clientHooks",
+ "collectContentImage": "ep_image_upload/static/js/contentCollection",
+ "collectContentPre": "ep_image_upload/static/js/contentCollection",
+ "ccRegisterBlockElements": "ep_image_upload/static/js/contentCollection",
+ "collectContentPost": "ep_image_upload/static/js/contentCollection"
+ },
+ "hooks":{
+ "eejsBlock_styles": "ep_image_upload/index",
+ "eejsBlock_timesliderStyles": "ep_image_upload/index",
+ "clientVars": "ep_image_upload/index",
+ "eejsBlock_body": "ep_image_upload/index",
+ "collectContentImage": "ep_image_upload/static/js/contentCollection",
+ "getLineHTMLForExport": "ep_image_upload/exportHTML",
+ "stylesForExport": "ep_image_upload/exportHTML",
+ "expressConfigure": "ep_image_upload/index",
+ "eejsBlock_editbarMenuLeft": "ep_image_upload/editbar",
+ "collectContentPre": "ep_image_upload/static/js/contentCollection",
+ "collectContentPost": "ep_image_upload/static/js/contentCollection",
+ "ccRegisterBlockElements": "ep_image_upload/static/js/contentCollection",
+ "loadSettings": "ep_image_upload/settings"
+ }
+ }
+ ]
+}
Index: lams_build/conf/etherpad/etherpad-lite/node_modules/ep_image_upload/exportHTML.js
===================================================================
diff -u
--- lams_build/conf/etherpad/etherpad-lite/node_modules/ep_image_upload/exportHTML.js (revision 0)
+++ lams_build/conf/etherpad/etherpad-lite/node_modules/ep_image_upload/exportHTML.js (revision fea3e6eb1a66370c10e3ae985c276f79a3629635)
@@ -0,0 +1,27 @@
+'use strict';
+
+const Changeset = require('ep_etherpad-lite/static/js/Changeset');
+
+const _analyzeLine = (alineAttrs, apool) => {
+ let image = null;
+ if (alineAttrs) {
+ const opIter = Changeset.opIterator(alineAttrs);
+ if (opIter.hasNext()) {
+ const op = opIter.next();
+ image = Changeset.opAttributeValue(op, 'img', apool);
+ }
+ }
+
+ return image;
+};
+
+exports.getLineHTMLForExport = async (hook, context) => {
+ const image = _analyzeLine(context.attribLine, context.apool);
+ if (image) {
+ context.lineContent = `
`;
+ }
+};
+
+exports.stylesForExport = (hook, padId, cb) => {
+ cb('img{max-width:100%;max-height:500px}');
+};
Index: lams_build/conf/etherpad/etherpad-lite/node_modules/ep_image_upload/index.js
===================================================================
diff -u
--- lams_build/conf/etherpad/etherpad-lite/node_modules/ep_image_upload/index.js (revision 0)
+++ lams_build/conf/etherpad/etherpad-lite/node_modules/ep_image_upload/index.js (revision fea3e6eb1a66370c10e3ae985c276f79a3629635)
@@ -0,0 +1,172 @@
+'use strict';
+
+/**
+ * Server-side hooks
+ *
+ * @see {@link http://etherpad.org/doc/v1.5.7/#index_server_side_hooks}
+ */
+
+const eejs = require('ep_etherpad-lite/node/eejs/');
+const settings = require('ep_etherpad-lite/node/utils/Settings');
+const Busboy = require('busboy');
+const StreamUpload = require('stream_upload');
+const uuid = require('uuid');
+const path = require('path');
+const mimetypes = require('mime-db');
+const url = require('url');
+
+/**
+ * ClientVars hook
+ *
+ * Exposes plugin settings from settings.json to client code inside clientVars variable
+ * to be accessed from client side hooks
+ *
+ * @param {string} hookName Hook name ("clientVars").
+ * @param {object} args Object containing the arguments passed to hook. {pad: {object}}
+ * @param {function} cb Callback
+ *
+ * @returns {*} callback
+ *
+ * @see {@link http://etherpad.org/doc/v1.5.7/#index_clientvars}
+ */
+exports.clientVars = (hookName, args, cb) => {
+ const pluginSettings = {
+ storageType: 'base64',
+ };
+ if (!settings.ep_image_upload) {
+ settings.ep_image_upload = {};
+ }
+ const keys = Object.keys(settings.ep_image_upload);
+ keys.forEach((key) => {
+ if (key !== 'storage') {
+ pluginSettings[key] = settings.ep_image_upload[key];
+ }
+ });
+ if (settings.ep_image_upload.storage && settings.ep_image_upload.storage.type !== 'base64') {
+ pluginSettings.storageType = settings.ep_image_upload.storage.type;
+ }
+
+ if (!pluginSettings) {
+ console.warn(hookName,
+ 'ep_image_upload settings not found. The settings can be specified in EP settings.json.'
+ );
+
+ return cb();
+ }
+ pluginSettings.mimeTypes = mimetypes;
+
+ return cb({ep_image_upload: pluginSettings});
+};
+
+exports.eejsBlock_body = (hookName, args, cb) => {
+ const modal = eejs.require('ep_image_upload/templates/modal.ejs');
+ args.content += modal;
+
+ return cb();
+};
+
+exports.eejsBlock_styles = (hookName, args, cb) => {
+ const style = eejs.require('ep_image_upload/templates/styles.ejs');
+ args.content += style;
+
+ return cb();
+};
+
+exports.eejsBlock_timesliderStyles = (hookName, args, cb) => {
+ args.content += '';
+ return cb();
+};
+
+const drainStream = (stream) => {
+ stream.on('readable', stream.read.bind(stream));
+};
+
+exports.expressConfigure = (hookName, context) => {
+ context.app.post('/p/:padId/pluginfw/ep_image_upload/upload', (req, res, next) => {
+ const padId = req.params.padId;
+ let busboy;
+ const imageUpload = new StreamUpload({
+ extensions: settings.ep_image_upload.fileTypes,
+ maxSize: settings.ep_image_upload.maxFileSize,
+ baseFolder: settings.ep_image_upload.storage.baseFolder,
+ storage: settings.ep_image_upload.storage,
+ });
+ const storageConfig = settings.ep_image_upload.storage;
+ if (storageConfig) {
+ try {
+ busboy = new Busboy({
+ headers: req.headers,
+ limits: {
+ fileSize: settings.ep_image_upload.maxFileSize,
+ },
+ });
+ } catch (error) {
+ console.error('EP_IMAGE_UPLOAD ERROR', error);
+
+ return next(error);
+ }
+
+ let isDone;
+ const done = (error) => {
+ if (error) {
+ console.error('EP_IMAGE_UPLOAD UPLOAD ERROR', error);
+
+ return;
+ }
+
+ if (isDone) return;
+ isDone = true;
+
+ res.status(error.statusCode || 500).json(error);
+ req.unpipe(busboy);
+ drainStream(req);
+ busboy.removeAllListeners();
+ };
+
+ let uploadResult;
+ const newFileName = uuid.v4();
+ let accessPath = '';
+ busboy.on('file', (fieldname, file, filename, encoding, mimetype) => {
+ let savedFilename = path.join(padId, newFileName + path.extname(filename));
+
+ if (settings.ep_image_upload.storage && settings.ep_image_upload.storage.type === 'local') {
+ let baseURL = settings.ep_image_upload.storage.baseURL;
+ if (baseURL.charAt(baseURL.length - 1) !== '/') {
+ baseURL += '/';
+ }
+ accessPath = new url.URL(savedFilename, settings.ep_image_upload.storage.baseURL);
+ savedFilename = path.join(settings.ep_image_upload.storage.baseFolder, savedFilename);
+ }
+ file.on('limit', () => {
+ const error = new Error('File is too large');
+ error.type = 'fileSize';
+ error.statusCode = 403;
+ busboy.emit('error', error);
+ imageUpload.deletePartials();
+ });
+ file.on('error', (error) => {
+ busboy.emit('error', error);
+ });
+
+ uploadResult = imageUpload
+ .upload(file, {type: mimetype, filename: savedFilename});
+ });
+
+ busboy.on('error', done);
+ busboy.on('finish', () => {
+ if (uploadResult) {
+ uploadResult
+ .then((data) => {
+ if (accessPath) {
+ data = accessPath;
+ }
+
+ return res.status(201).json(data);
+ })
+ .catch((err) => res.status(500).json(err));
+ }
+ });
+ req.pipe(busboy);
+ }
+ });
+};