element-web/src/utils/exportUtils/Exporter.ts

155 lines
5 KiB
TypeScript
Raw Normal View History

2021-05-24 15:18:13 +00:00
import { MatrixEvent } from "matrix-js-sdk/src/models/event";
2021-05-24 15:50:16 +00:00
import { Room } from "matrix-js-sdk/src/models/room";
2021-06-03 07:51:56 +00:00
import { MatrixClientPeg } from "../../MatrixClientPeg";
import { TimelineWindow } from "matrix-js-sdk/src/timeline-window";
import { arrayFastClone } from "../arrays";
2021-06-04 09:38:17 +00:00
import { exportTypes } from "./exportUtils";
import { RoomMember } from 'matrix-js-sdk/src/models/room-member';
2021-05-24 15:18:13 +00:00
2021-06-03 08:09:14 +00:00
export default abstract class Exporter {
2021-06-04 09:38:17 +00:00
constructor(protected room: Room, protected exportType: exportTypes, protected numberOfEvents?: number) {}
2021-06-03 07:51:56 +00:00
2021-06-03 08:09:14 +00:00
protected getTimelineConversation = () : MatrixEvent[] => {
2021-06-03 07:51:56 +00:00
if (!this.room) return;
const cli = MatrixClientPeg.get();
const timelineSet = this.room.getUnfilteredTimelineSet();
const timelineWindow = new TimelineWindow(
cli, timelineSet,
{windowLimit: Number.MAX_VALUE});
timelineWindow.load(null, 30);
2021-06-04 09:38:17 +00:00
const events: MatrixEvent[] = timelineWindow.getEvents();
2021-06-03 07:51:56 +00:00
// Clone and reverse the events so that we preserve the order
arrayFastClone(events)
.reverse()
.forEach(event => {
cli.decryptEventIfNeeded(event);
});
return events;
};
2021-06-04 09:38:17 +00:00
protected eventToJson(ev) {
const jsonEvent = ev.toJSON();
const e = ev.isEncrypted() ? jsonEvent.decrypted : jsonEvent;
if (ev.isEncrypted()) {
e.curve25519Key = ev.getSenderKey();
e.ed25519Key = ev.getClaimedEd25519Key();
e.algorithm = ev.getWireContent().algorithm;
e.forwardingCurve25519KeyChain = ev.getForwardingCurve25519KeyChain();
} else {
delete e.curve25519Key;
delete e.ed25519Key;
delete e.algorithm;
delete e.forwardingCurve25519KeyChain;
}
return e;
}
protected getRequiredEvents = async () : Promise<MatrixEvent[]> => {
const client = MatrixClientPeg.get();
const eventMapper = client.getEventMapper({ preventReEmit: true });
let prevToken: string|null = null;
let limit = this.numberOfEvents || Number.MAX_VALUE;
let events: MatrixEvent[] = [];
const stateRes: any[] = [];
while (limit) {
const eventsPerCrawl = Math.min(limit, 100);
const res: any = await client.createMessagesRequest(this.room.roomId, prevToken, eventsPerCrawl, "b");
2021-06-04 09:38:17 +00:00
if (res.state) stateRes.push(...res.state);
if (res.chunk.length === 0) break;
limit -= eventsPerCrawl;
const matrixEvents: MatrixEvent[] = res.chunk.map(eventMapper);
matrixEvents.forEach(mxEv => events.push(mxEv));
prevToken = res.end;
}
events = events.reverse()
let stateEvents = [];
if (stateRes !== undefined) {
stateEvents = stateRes.map(eventMapper);
}
const profiles = {};
stateEvents.forEach(ev => {
if (ev.event.content &&
ev.event.content.membership === "join") {
profiles[ev.event.sender] = {
displayname: ev.event.content.displayname,
avatar_url: ev.event.content.avatar_url,
};
}
});
const decryptionPromises = events
.filter(event => event.isEncrypted())
.map(event => {
return client.decryptEventIfNeeded(event, {
isRetry: true,
emit: false,
});
});
// Let us wait for all the events to get decrypted.
await Promise.all(decryptionPromises);
const eventsWithProfile = events.map((ev) => {
const e = this.eventToJson(ev);
let profile: any = {};
if (e.sender in profiles) profile = profiles[e.sender];
const object = {
event: e,
profile: profile,
};
return object;
});
const matrixEvents = eventsWithProfile.map(e => {
const matrixEvent = eventMapper(e.event);
const member = new RoomMember(this.room.roomId, matrixEvent.getSender());
member.name = e.profile.displayname;
const memberEvent = eventMapper(
{
content: {
membership: "join",
avatar_url: e.profile.avatar_url,
displayname: e.profile.displayname,
},
type: "m.room.member",
event_id: matrixEvent.getId() + ":eventIndex",
room_id: matrixEvent.getRoomId(),
sender: matrixEvent.getSender(),
origin_server_ts: matrixEvent.getTs(),
state_key: matrixEvent.getSender(),
},
);
member.events.member = memberEvent;
matrixEvent.sender = member;
return matrixEvent;
});
return matrixEvents;
}
2021-05-24 15:50:16 +00:00
abstract export(): Promise<Blob>;
2021-05-24 15:18:13 +00:00
}