mirror of
https://github.com/element-hq/element-web
synced 2024-11-26 19:26:04 +03:00
Add a rageshake function to download the logs locally
For https://github.com/vector-im/riot-web/issues/3304 This generates something similar to what the rageshake server does, just in an easy package for people to use. tar-js was chosen over zip or anything else because it's small, simple, and stable. Note: this doesn't work in Chrome, but firefox seems to be okay with it. Chrome appears to be blocking the download for some reason - the very first download was fine, but none afterwards
This commit is contained in:
parent
cad9562f8d
commit
01a7a6987e
4 changed files with 95 additions and 20 deletions
|
@ -97,6 +97,7 @@
|
|||
"react-gemini-scrollbar": "github:matrix-org/react-gemini-scrollbar#9cf17f63b7c0b0ec5f31df27da0f82f7238dc594",
|
||||
"resize-observer-polyfill": "^1.5.0",
|
||||
"sanitize-html": "^1.18.4",
|
||||
"tar-js": "^0.3.0",
|
||||
"text-encoding-utf-8": "^1.0.1",
|
||||
"url": "^0.11.0",
|
||||
"velocity-animate": "^1.5.2",
|
||||
|
|
|
@ -418,6 +418,7 @@
|
|||
"Collecting app version information": "Collecting app version information",
|
||||
"Collecting logs": "Collecting logs",
|
||||
"Uploading report": "Uploading report",
|
||||
"Downloading report": "Downloading report",
|
||||
"Waiting for response from server": "Waiting for response from server",
|
||||
"Messages containing my display name": "Messages containing my display name",
|
||||
"Messages containing my username": "Messages containing my username",
|
||||
|
|
|
@ -21,6 +21,7 @@ import pako from 'pako';
|
|||
import {MatrixClientPeg} from '../MatrixClientPeg';
|
||||
import PlatformPeg from '../PlatformPeg';
|
||||
import { _t } from '../languageHandler';
|
||||
import Tar from "tar-js";
|
||||
|
||||
import * as rageshake from './rageshake';
|
||||
|
||||
|
@ -33,26 +34,7 @@ if (!TextEncoder) {
|
|||
TextEncoder = TextEncodingUtf8.TextEncoder;
|
||||
}
|
||||
|
||||
/**
|
||||
* Send a bug report.
|
||||
*
|
||||
* @param {string} bugReportEndpoint HTTP url to send the report to
|
||||
*
|
||||
* @param {object} opts optional dictionary of options
|
||||
*
|
||||
* @param {string} opts.userText Any additional user input.
|
||||
*
|
||||
* @param {boolean} opts.sendLogs True to send logs
|
||||
*
|
||||
* @param {function(string)} opts.progressCallback Callback to call with progress updates
|
||||
*
|
||||
* @return {Promise} Resolved when the bug report is sent.
|
||||
*/
|
||||
export default async function sendBugReport(bugReportEndpoint, opts) {
|
||||
if (!bugReportEndpoint) {
|
||||
throw new Error("No bug report endpoint has been set.");
|
||||
}
|
||||
|
||||
async function collectBugReport(opts) {
|
||||
opts = opts || {};
|
||||
const progressCallback = opts.progressCallback || (() => {});
|
||||
|
||||
|
@ -106,10 +88,96 @@ export default async function sendBugReport(bugReportEndpoint, opts) {
|
|||
}
|
||||
}
|
||||
|
||||
return body;
|
||||
}
|
||||
|
||||
/**
|
||||
* Send a bug report.
|
||||
*
|
||||
* @param {string} bugReportEndpoint HTTP url to send the report to
|
||||
*
|
||||
* @param {object} opts optional dictionary of options
|
||||
*
|
||||
* @param {string} opts.userText Any additional user input.
|
||||
*
|
||||
* @param {boolean} opts.sendLogs True to send logs
|
||||
*
|
||||
* @param {function(string)} opts.progressCallback Callback to call with progress updates
|
||||
*
|
||||
* @return {Promise} Resolved when the bug report is sent.
|
||||
*/
|
||||
export default async function sendBugReport(bugReportEndpoint, opts) {
|
||||
if (!bugReportEndpoint) {
|
||||
throw new Error("No bug report endpoint has been set.");
|
||||
}
|
||||
|
||||
opts = opts || {};
|
||||
const progressCallback = opts.progressCallback || (() => {});
|
||||
const body = await collectBugReport(opts);
|
||||
|
||||
progressCallback(_t("Uploading report"));
|
||||
await _submitReport(bugReportEndpoint, body, progressCallback);
|
||||
}
|
||||
|
||||
/**
|
||||
* Downloads the files from a bug report. This is the same as sendBugReport,
|
||||
* but instead causes the browser to download the files locally.
|
||||
*
|
||||
* @param {object} opts optional dictionary of options
|
||||
*
|
||||
* @param {string} opts.userText Any additional user input.
|
||||
*
|
||||
* @param {boolean} opts.sendLogs True to send logs
|
||||
*
|
||||
* @param {function(string)} opts.progressCallback Callback to call with progress updates
|
||||
*
|
||||
* @return {Promise} Resolved when the bug report is downloaded (or started).
|
||||
*/
|
||||
export async function downloadBugReport(opts) {
|
||||
opts = opts || {};
|
||||
const progressCallback = opts.progressCallback || (() => {});
|
||||
const body = await collectBugReport(opts);
|
||||
|
||||
progressCallback(_t("Downloading report"));
|
||||
let metadata = "";
|
||||
const tape = new Tar();
|
||||
let i = 0;
|
||||
for (const e of body.entries()) {
|
||||
if (e[0] === 'compressed-log') {
|
||||
await new Promise((resolve => {
|
||||
const reader = new FileReader();
|
||||
reader.addEventListener('loadend', ev => {
|
||||
tape.append(`log-${i++}.log`, pako.ungzip(ev.target.result));
|
||||
resolve();
|
||||
});
|
||||
reader.readAsArrayBuffer(e[1]);
|
||||
}))
|
||||
} else {
|
||||
metadata += `${e[0]} = ${e[1]}\n`;
|
||||
}
|
||||
}
|
||||
tape.append('issue.txt', metadata);
|
||||
|
||||
// We have to create a new anchor to download if we want a filename. Otherwise we could
|
||||
// just use window.open.
|
||||
const dl = document.createElement('a');
|
||||
dl.href = `data:application/octet-stream;base64,${btoa(uint8ToString(tape.out))}`;
|
||||
dl.download = 'rageshake.tar';
|
||||
document.body.appendChild(dl);
|
||||
dl.click();
|
||||
document.body.removeChild(dl);
|
||||
}
|
||||
|
||||
// Source: https://github.com/beatgammit/tar-js/blob/master/examples/main.js
|
||||
function uint8ToString(buf) {
|
||||
let i, length, out = '';
|
||||
for (i = 0, length = buf.length; i < length; i += 1) {
|
||||
out += String.fromCharCode(buf[i]);
|
||||
}
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
function _submitReport(endpoint, body, progressCallback) {
|
||||
return new Promise((resolve, reject) => {
|
||||
const req = new XMLHttpRequest();
|
||||
|
|
|
@ -8251,6 +8251,11 @@ tapable@^1.0.0, tapable@^1.1.3:
|
|||
resolved "https://registry.yarnpkg.com/tapable/-/tapable-1.1.3.tgz#a1fccc06b58db61fd7a45da2da44f5f3a3e67ba2"
|
||||
integrity sha512-4WK/bYZmj8xLr+HUCODHGF1ZFzsYffasLUgEiMBY4fgtltdO6B4WJtlSbPaDTLpYTcGVwM2qLnFTICEcNxs3kA==
|
||||
|
||||
tar-js@^0.3.0:
|
||||
version "0.3.0"
|
||||
resolved "https://registry.yarnpkg.com/tar-js/-/tar-js-0.3.0.tgz#6949aabfb0ba18bb1562ae51a439fd0f30183a17"
|
||||
integrity sha1-aUmqv7C6GLsVYq5RpDn9DzAYOhc=
|
||||
|
||||
tar@^4:
|
||||
version "4.4.13"
|
||||
resolved "https://registry.yarnpkg.com/tar/-/tar-4.4.13.tgz#43b364bc52888d555298637b10d60790254ab525"
|
||||
|
|
Loading…
Reference in a new issue