ExportEtherpad: New `importEtherpad`, `exportEtherpad` hooks
parent
44fd70491d
commit
2facf3a0c5
|
@ -56,6 +56,7 @@
|
||||||
(low-level API) and `ep_etherpad-lite/static/js/AttributeMap` (high-level
|
(low-level API) and `ep_etherpad-lite/static/js/AttributeMap` (high-level
|
||||||
API).
|
API).
|
||||||
* The `import` server-side hook has a new `ImportError` context property.
|
* The `import` server-side hook has a new `ImportError` context property.
|
||||||
|
* New `exportEtherpad` and `importEtherpad` server-side hooks.
|
||||||
* The `handleMessageSecurity` and `handleMessage` server-side hooks have a new
|
* The `handleMessageSecurity` and `handleMessage` server-side hooks have a new
|
||||||
`sessionInfo` context property that includes the user's author ID, the pad ID,
|
`sessionInfo` context property that includes the user's author ID, the pad ID,
|
||||||
and whether the user only has read-only access.
|
and whether the user only has read-only access.
|
||||||
|
|
|
@ -966,6 +966,48 @@ Example:
|
||||||
exports.exportEtherpadAdditionalContent = () => ['comments'];
|
exports.exportEtherpadAdditionalContent = () => ['comments'];
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## `exportEtherpad`
|
||||||
|
|
||||||
|
Called from `src/node/utils/ExportEtherpad.js`.
|
||||||
|
|
||||||
|
Called when exporting to an `.etherpad` file.
|
||||||
|
|
||||||
|
Context properties:
|
||||||
|
|
||||||
|
* `pad`: The exported pad's Pad object.
|
||||||
|
* `data`: JSONable output object. This is pre-populated with records from core
|
||||||
|
Etherpad as well as pad-specific records with prefixes from the
|
||||||
|
`exportEtherpadAdditionalContent` hook. Registered hook functions can modify
|
||||||
|
this object (but not replace the object) to perform any desired
|
||||||
|
transformations to the exported data (such as the inclusion of
|
||||||
|
plugin-specific records). All registered hook functions are executed
|
||||||
|
concurrently, so care should be taken to avoid race conditions with other
|
||||||
|
plugins.
|
||||||
|
* `dstPadId`: The pad ID that should be used when writing pad-specific records
|
||||||
|
to `data` (instead of `pad.id`). This avoids leaking the writable pad ID
|
||||||
|
when a user exports a read-only pad. This might be a dummy value; plugins
|
||||||
|
should not assume that it is either the pad's real writable ID or its
|
||||||
|
read-only ID.
|
||||||
|
|
||||||
|
## `importEtherpad`
|
||||||
|
|
||||||
|
Called from `src/node/utils/ImportEtherpad.js`.
|
||||||
|
|
||||||
|
Called when importing from an `.etherpad` file.
|
||||||
|
|
||||||
|
Context properties:
|
||||||
|
|
||||||
|
* `pad`: Temporary Pad object containing the pad's data read from the imported
|
||||||
|
`.etherpad` file. The `pad.db` object is a temporary in-memory database
|
||||||
|
whose records will be copied to the real database after they are validated
|
||||||
|
(see the `padCheck` hook). Registered hook functions MUST NOT use the real
|
||||||
|
database to access (read or write) pad-specific records; they MUST instead
|
||||||
|
use `pad.db`. All registered hook functions are executed concurrently, so
|
||||||
|
care should be taken to avoid race conditions with other plugins.
|
||||||
|
* `data`: Raw JSONable object from the `.etherpad` file. This data must not be
|
||||||
|
modified.
|
||||||
|
* `srcPadId`: The pad ID used for the pad-specific information in `data`.
|
||||||
|
|
||||||
## `import`
|
## `import`
|
||||||
|
|
||||||
Called from: `src/node/handler/ImportHandler.js`
|
Called from: `src/node/handler/ImportHandler.js`
|
||||||
|
|
|
@ -55,5 +55,10 @@ exports.getPadRaw = async (padId, readOnlyId) => {
|
||||||
})();
|
})();
|
||||||
const data = {[dstPfx]: pad};
|
const data = {[dstPfx]: pad};
|
||||||
for (const [dstKey, p] of new Stream(records).batch(100).buffer(99)) data[dstKey] = await p;
|
for (const [dstKey, p] of new Stream(records).batch(100).buffer(99)) data[dstKey] = await p;
|
||||||
|
await hooks.aCallAll('exportEtherpad', {
|
||||||
|
pad,
|
||||||
|
data,
|
||||||
|
dstPadId: readOnlyId || padId,
|
||||||
|
});
|
||||||
return data;
|
return data;
|
||||||
};
|
};
|
||||||
|
|
|
@ -90,7 +90,8 @@ exports.setPadRaw = async (padId, r, authorId = '') => {
|
||||||
keyParts[1] = padId;
|
keyParts[1] = padId;
|
||||||
key = keyParts.join(':');
|
key = keyParts.join(':');
|
||||||
} else {
|
} else {
|
||||||
logger.warn(`(pad ${padId}) Ignoring record with unsupported key: ${key}`);
|
logger.debug(`(pad ${padId}) The record with the following key will be ignored unless an ` +
|
||||||
|
`importEtherpad hook function processes it: ${key}`);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
await padDb.set(key, value);
|
await padDb.set(key, value);
|
||||||
|
@ -100,6 +101,13 @@ exports.setPadRaw = async (padId, r, authorId = '') => {
|
||||||
|
|
||||||
const pad = new Pad(padId, padDb);
|
const pad = new Pad(padId, padDb);
|
||||||
await pad.init(null, authorId);
|
await pad.init(null, authorId);
|
||||||
|
await hooks.aCallAll('importEtherpad', {
|
||||||
|
pad,
|
||||||
|
// Shallow freeze meant to prevent accidental bugs. It would be better to deep freeze, but
|
||||||
|
// it's not worth the added complexity.
|
||||||
|
data: Object.freeze(records),
|
||||||
|
srcPadId: originalPadId,
|
||||||
|
});
|
||||||
await pad.check();
|
await pad.check();
|
||||||
} finally {
|
} finally {
|
||||||
await padDb.close();
|
await padDb.close();
|
||||||
|
|
Loading…
Reference in New Issue