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:
parent
78dcd5d18d
commit
9284611e7e
38
src/common/utils/downloadFile.ts
Normal file
38
src/common/utils/downloadFile.ts
Normal 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();
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -12,3 +12,4 @@ export * from "./splitArray";
|
||||
export * from "./saveToAppFiles";
|
||||
export * from "./singleton";
|
||||
export * from "./openExternal";
|
||||
export * from "./downloadFile";
|
||||
|
||||
@ -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> {
|
||||
|
||||
@ -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)}`);
|
||||
}
|
||||
|
||||
@ -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) => {
|
||||
|
||||
@ -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() {
|
||||
|
||||
@ -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);
|
||||
}
|
||||
@ -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";
|
||||
|
||||
18
src/renderer/utils/saveFile.ts
Normal file
18
src/renderer/utils/saveFile.ts
Normal 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);
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user