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",
|
"react-gemini-scrollbar": "github:matrix-org/react-gemini-scrollbar#9cf17f63b7c0b0ec5f31df27da0f82f7238dc594",
|
||||||
"resize-observer-polyfill": "^1.5.0",
|
"resize-observer-polyfill": "^1.5.0",
|
||||||
"sanitize-html": "^1.18.4",
|
"sanitize-html": "^1.18.4",
|
||||||
|
"tar-js": "^0.3.0",
|
||||||
"text-encoding-utf-8": "^1.0.1",
|
"text-encoding-utf-8": "^1.0.1",
|
||||||
"url": "^0.11.0",
|
"url": "^0.11.0",
|
||||||
"velocity-animate": "^1.5.2",
|
"velocity-animate": "^1.5.2",
|
||||||
|
|
|
@ -418,6 +418,7 @@
|
||||||
"Collecting app version information": "Collecting app version information",
|
"Collecting app version information": "Collecting app version information",
|
||||||
"Collecting logs": "Collecting logs",
|
"Collecting logs": "Collecting logs",
|
||||||
"Uploading report": "Uploading report",
|
"Uploading report": "Uploading report",
|
||||||
|
"Downloading report": "Downloading report",
|
||||||
"Waiting for response from server": "Waiting for response from server",
|
"Waiting for response from server": "Waiting for response from server",
|
||||||
"Messages containing my display name": "Messages containing my display name",
|
"Messages containing my display name": "Messages containing my display name",
|
||||||
"Messages containing my username": "Messages containing my username",
|
"Messages containing my username": "Messages containing my username",
|
||||||
|
|
|
@ -21,6 +21,7 @@ import pako from 'pako';
|
||||||
import {MatrixClientPeg} from '../MatrixClientPeg';
|
import {MatrixClientPeg} from '../MatrixClientPeg';
|
||||||
import PlatformPeg from '../PlatformPeg';
|
import PlatformPeg from '../PlatformPeg';
|
||||||
import { _t } from '../languageHandler';
|
import { _t } from '../languageHandler';
|
||||||
|
import Tar from "tar-js";
|
||||||
|
|
||||||
import * as rageshake from './rageshake';
|
import * as rageshake from './rageshake';
|
||||||
|
|
||||||
|
@ -33,26 +34,7 @@ if (!TextEncoder) {
|
||||||
TextEncoder = TextEncodingUtf8.TextEncoder;
|
TextEncoder = TextEncodingUtf8.TextEncoder;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
async function collectBugReport(opts) {
|
||||||
* 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 || {};
|
opts = opts || {};
|
||||||
const progressCallback = opts.progressCallback || (() => {});
|
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"));
|
progressCallback(_t("Uploading report"));
|
||||||
await _submitReport(bugReportEndpoint, body, progressCallback);
|
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) {
|
function _submitReport(endpoint, body, progressCallback) {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
const req = new XMLHttpRequest();
|
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"
|
resolved "https://registry.yarnpkg.com/tapable/-/tapable-1.1.3.tgz#a1fccc06b58db61fd7a45da2da44f5f3a3e67ba2"
|
||||||
integrity sha512-4WK/bYZmj8xLr+HUCODHGF1ZFzsYffasLUgEiMBY4fgtltdO6B4WJtlSbPaDTLpYTcGVwM2qLnFTICEcNxs3kA==
|
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:
|
tar@^4:
|
||||||
version "4.4.13"
|
version "4.4.13"
|
||||||
resolved "https://registry.yarnpkg.com/tar/-/tar-4.4.13.tgz#43b364bc52888d555298637b10d60790254ab525"
|
resolved "https://registry.yarnpkg.com/tar/-/tar-4.4.13.tgz#43b364bc52888d555298637b10d60790254ab525"
|
||||||
|
|
Loading…
Reference in a new issue