1
0
mirror of https://github.com/lensapp/lens.git synced 2025-05-20 05:10:56 +00:00

fix downloading file, added common/utils/downloadFile

Signed-off-by: Roman <ixrock@gmail.com>
This commit is contained in:
Roman 2020-11-23 12:30:33 +02:00
parent 78dcd5d18d
commit 9284611e7e
9 changed files with 66 additions and 33 deletions

View File

@ -0,0 +1,38 @@
import path from "path";
import request from "request";
export interface DownloadFileOptions {
url: string;
fileName?: string; // default: based on filename from URL
gzip?: boolean; // default: true
}
export interface DownloadFileTicket {
fileName: string;
promise: Promise<File>;
cancel(): void;
}
export function downloadFile(opts: DownloadFileOptions): DownloadFileTicket {
const { url, gzip = true, fileName = path.basename(url) } = opts;
const fileChunks: Buffer[] = [];
const req = request(url, { gzip });
const promise: Promise<File> = new Promise((resolve, reject) => {
req.on("data", (chunk: Buffer) => {
fileChunks.push(chunk);
});
req.on("complete", () => {
resolve(new File(fileChunks, fileName));
});
req.on("error", err => {
reject({ url, err });
});
});
return {
fileName: fileName,
promise: promise,
cancel() {
req.abort();
}
}
}

View File

@ -12,3 +12,4 @@ export * from "./splitArray";
export * from "./saveToAppFiles";
export * from "./singleton";
export * from "./openExternal";
export * from "./downloadFile";

View File

@ -99,7 +99,7 @@ export class ExtensionManager {
getNpmPackageTarballUrl(packageName: string) {
const command = [this.npmPath, "view", packageName, "dist.tarball", "--silent"];
return child_process.execSync(command.join(" "), { encoding: "utf8" });
return child_process.execSync(command.join(" "), { encoding: "utf8" }).trim();
}
protected installPackages(): Promise<void> {

View File

@ -16,8 +16,8 @@ import { Clipboard } from "../clipboard";
import { extensionLoader } from "../../../extensions/extension-loader";
import { extensionManager } from "../../../extensions/extension-manager";
import { Notifications } from "../notifications";
import request from "request";
import logger from "../../../main/logger";
import { downloadFile } from "../../../common/utils";
@observer
export class Extensions extends React.Component {
@ -56,18 +56,6 @@ export class Extensions extends React.Component {
}
}
// fixme: doesn't work
// todo: move to common/utils
async downloadFile(url: string, fileName = path.basename(url)): Promise<File> {
return new Promise((resolve, reject) => {
const downloadingReq = request(url, { gzip: true });
downloadingReq.on("complete", (res, body: Buffer) => {
resolve(new File([body], fileName));
});
downloadingReq.on("error", reject);
})
}
installFromUrl = async () => {
const { downloadUrl } = this;
if (!downloadUrl) {
@ -87,8 +75,8 @@ export class Extensions extends React.Component {
logger.info('Install from packed extension URL', { tarballUrl });
if (tarballUrl) {
try {
const file = await this.downloadFile(tarballUrl);
this.installExtensionFromFile([file]);
const { promise: filePromise } = downloadFile({ url: tarballUrl });
this.installExtensionFromFile([await filePromise]);
} catch (err) {
Notifications.error(`Installing extension from ${tarballUrl} has failed: ${String(err)}`);
}

View File

@ -6,7 +6,7 @@ import { Select, SelectOption } from "../select";
import { Badge } from "../badge";
import { Icon } from "../icon";
import { _i18n } from "../../i18n";
import { cssNames, downloadFile } from "../../utils";
import { cssNames, saveFileDialog } from "../../utils";
import { Pod } from "../../api/endpoints";
import { PodLogSearch, PodLogSearchProps } from "./pod-log-search";
@ -39,7 +39,7 @@ export const PodLogControls = observer((props: Props) => {
const downloadLogs = () => {
const fileName = selectedContainer ? selectedContainer.name : pod.getName();
downloadFile(fileName + ".log", logs.join("\n"), "text/plain");
saveFileDialog(fileName + ".log", logs.join("\n"), "text/plain");
};
const onContainerChange = (option: SelectOption) => {

View File

@ -7,7 +7,7 @@ import jsYaml from "js-yaml";
import { Trans } from "@lingui/macro";
import { AceEditor } from "../ace-editor";
import { ServiceAccount } from "../../api/endpoints";
import { copyToClipboard, cssNames, downloadFile } from "../../utils";
import { copyToClipboard, cssNames, saveFileDialog } from "../../utils";
import { Button } from "../button";
import { Dialog, DialogProps } from "../dialog";
import { Icon } from "../icon";
@ -67,7 +67,7 @@ export class KubeConfigDialog extends React.Component<Props> {
};
download = () => {
downloadFile("config", this.config, "text/yaml");
saveFileDialog("config", this.config, "text/yaml");
};
render() {

View File

@ -1,12 +0,0 @@
export function downloadFile(filename: string, contents: any, type: string) {
const data = new Blob([contents], { type: type });
const url = URL.createObjectURL(data);
const link = document.createElement("a");
link.href = url;
link.download = filename;
link.style.display = "none";
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
URL.revokeObjectURL(url);
}

View File

@ -8,7 +8,7 @@ export * from "../../common/utils";
export * from "./cssVar";
export * from "./cssNames";
export * from "../../common/event-emitter";
export * from "./downloadFile";
export * from "./saveFile";
export * from "./prevDefault";
export * from "./createStorage";
export * from "./interval";

View File

@ -0,0 +1,18 @@
/**
* Request default save-file dialog in browser.
* @param filename Name of file to be saved locally
* @param contents String or Buffer
* @param type Content-type
*/
export function saveFileDialog(filename: string, contents: BlobPart | BlobPart[], type: string) {
const data = new Blob([contents].flat(), { type });
const url = URL.createObjectURL(data);
const link = document.createElement("a");
link.href = url;
link.download = filename;
link.style.display = "none";
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
URL.revokeObjectURL(url);
}