Files
element-web/src/utils/exportUtils/JSONExport.ts
T

110 lines
4.2 KiB
TypeScript
Raw Normal View History

2021-06-24 18:19:12 +05:30
import Exporter from "./Exporter";
import { Room } from "matrix-js-sdk/src/models/room";
import { MatrixEvent } from "matrix-js-sdk/src/models/event";
import { formatFullDateNoDay, formatFullDateNoDayNoTime } from "../../DateUtils";
import { haveTileForEvent } from "../../components/views/rooms/EventTile";
import { exportTypes } from "./exportUtils";
import { exportOptions } from "./exportUtils";
2021-06-24 18:23:08 +05:30
import { EventType } from "matrix-js-sdk/src/@types/event";
2021-07-02 16:52:33 +05:30
import { MutableRefObject } from "react";
2021-06-24 18:19:12 +05:30
export default class JSONExporter extends Exporter {
protected totalSize: number;
2021-06-29 10:57:02 +05:30
protected messages: any[];
2021-06-24 18:19:12 +05:30
2021-07-02 10:23:25 +05:30
constructor(
room: Room,
exportType: exportTypes,
exportOptions: exportOptions,
2021-07-02 16:52:33 +05:30
exportProgressRef: MutableRefObject<HTMLParagraphElement>,
2021-07-02 10:23:25 +05:30
) {
2021-07-02 16:52:33 +05:30
super(room, exportType, exportOptions, exportProgressRef);
2021-06-24 18:19:12 +05:30
this.totalSize = 0;
2021-06-29 10:57:02 +05:30
this.messages = [];
2021-06-24 18:19:12 +05:30
}
2021-06-29 10:57:02 +05:30
protected createJSONString(): string {
2021-06-24 18:19:12 +05:30
const exportDate = formatFullDateNoDayNoTime(new Date());
const creator = this.room.currentState.getStateEvents(EventType.RoomCreate, "")?.getSender();
const creatorName = this.room?.getMember(creator)?.rawDisplayName || creator;
const topic = this.room.currentState.getStateEvents(EventType.RoomTopic, "")?.getContent()?.topic || "";
const exporter = this.client.getUserId();
const exporterName = this.room?.getMember(exporter)?.rawDisplayName || exporter;
2021-06-29 10:57:02 +05:30
const jsonObject = {
room_name: this.room.name,
room_creator: creatorName,
topic,
export_date: exportDate,
exported_by: exporterName,
messages: this.messages,
2021-06-30 14:08:22 +05:30
};
2021-06-29 10:57:02 +05:30
return JSON.stringify(jsonObject, null, 2);
2021-06-24 18:19:12 +05:30
}
protected async getJSONString(mxEv: MatrixEvent) {
if (this.exportOptions.attachmentsIncluded && this.isAttachment(mxEv)) {
try {
const blob = await this.getMediaBlob(mxEv);
if (this.totalSize + blob.size < this.exportOptions.maxSize) {
this.totalSize += blob.size;
const filePath = this.getFilePath(mxEv);
if (this.totalSize == this.exportOptions.maxSize) {
this.exportOptions.attachmentsIncluded = false;
}
this.addFile(filePath, blob);
2021-06-24 18:19:12 +05:30
}
} catch (err) {
console.log("Error fetching file: " + err);
}
}
const jsonEvent: any = mxEv.toJSON();
const clearEvent = mxEv.isEncrypted() ? jsonEvent.decrypted : jsonEvent;
2021-06-29 10:57:02 +05:30
return clearEvent;
2021-06-24 18:19:12 +05:30
}
protected async createOutput(events: MatrixEvent[]) {
2021-07-02 10:23:25 +05:30
for (let i = 0; i < events.length; i++) {
const event = events[i];
2021-07-02 16:52:33 +05:30
this.updateProgress(`Processing event ${i + 1} out of ${events.length}`, false, true);
2021-06-27 20:55:54 +05:30
if (this.cancelled) return this.cleanUp();
2021-06-24 18:19:12 +05:30
if (!haveTileForEvent(event)) continue;
2021-06-29 10:57:02 +05:30
this.messages.push(await this.getJSONString(event));
2021-06-24 18:19:12 +05:30
}
2021-06-29 10:57:02 +05:30
return this.createJSONString();
2021-06-24 18:19:12 +05:30
}
public async export() {
console.info("Starting export process...");
console.info("Fetching events...");
2021-06-25 15:49:39 +05:30
2021-06-24 18:19:12 +05:30
const fetchStart = performance.now();
const res = await this.getRequiredEvents();
const fetchEnd = performance.now();
console.log(`Fetched ${res.length} events in ${(fetchEnd - fetchStart)/1000}s`);
2021-06-24 18:19:12 +05:30
2021-06-25 15:49:39 +05:30
console.info("Creating output...");
2021-06-24 18:19:12 +05:30
const text = await this.createOutput(res);
if (this.files.length) {
this.addFile("export.json", new Blob([text]));
await this.downloadZIP();
2021-06-24 18:19:12 +05:30
} else {
const fileName = `matrix-export-${formatFullDateNoDay(new Date())}.json`;
await this.downloadPlainText(fileName, text);
2021-06-24 18:19:12 +05:30
}
const exportEnd = performance.now();
2021-06-25 15:49:39 +05:30
2021-06-27 20:55:54 +05:30
if (this.cancelled) {
console.info("Export cancelled successfully");
} else {
2021-06-30 14:08:22 +05:30
console.info("Export successful!");
2021-06-27 20:55:54 +05:30
console.log(`Exported ${res.length} events in ${(exportEnd - fetchStart)/1000} seconds`);
}
2021-06-25 15:49:39 +05:30
2021-06-30 14:08:22 +05:30
this.cleanUp();
2021-06-24 18:19:12 +05:30
}
}