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 "./saveToAppFiles";
|
||||||
export * from "./singleton";
|
export * from "./singleton";
|
||||||
export * from "./openExternal";
|
export * from "./openExternal";
|
||||||
|
export * from "./downloadFile";
|
||||||
|
|||||||
@ -99,7 +99,7 @@ export class ExtensionManager {
|
|||||||
|
|
||||||
getNpmPackageTarballUrl(packageName: string) {
|
getNpmPackageTarballUrl(packageName: string) {
|
||||||
const command = [this.npmPath, "view", packageName, "dist.tarball", "--silent"];
|
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> {
|
protected installPackages(): Promise<void> {
|
||||||
|
|||||||
@ -16,8 +16,8 @@ import { Clipboard } from "../clipboard";
|
|||||||
import { extensionLoader } from "../../../extensions/extension-loader";
|
import { extensionLoader } from "../../../extensions/extension-loader";
|
||||||
import { extensionManager } from "../../../extensions/extension-manager";
|
import { extensionManager } from "../../../extensions/extension-manager";
|
||||||
import { Notifications } from "../notifications";
|
import { Notifications } from "../notifications";
|
||||||
import request from "request";
|
|
||||||
import logger from "../../../main/logger";
|
import logger from "../../../main/logger";
|
||||||
|
import { downloadFile } from "../../../common/utils";
|
||||||
|
|
||||||
@observer
|
@observer
|
||||||
export class Extensions extends React.Component {
|
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 () => {
|
installFromUrl = async () => {
|
||||||
const { downloadUrl } = this;
|
const { downloadUrl } = this;
|
||||||
if (!downloadUrl) {
|
if (!downloadUrl) {
|
||||||
@ -87,8 +75,8 @@ export class Extensions extends React.Component {
|
|||||||
logger.info('Install from packed extension URL', { tarballUrl });
|
logger.info('Install from packed extension URL', { tarballUrl });
|
||||||
if (tarballUrl) {
|
if (tarballUrl) {
|
||||||
try {
|
try {
|
||||||
const file = await this.downloadFile(tarballUrl);
|
const { promise: filePromise } = downloadFile({ url: tarballUrl });
|
||||||
this.installExtensionFromFile([file]);
|
this.installExtensionFromFile([await filePromise]);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
Notifications.error(`Installing extension from ${tarballUrl} has failed: ${String(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 { Badge } from "../badge";
|
||||||
import { Icon } from "../icon";
|
import { Icon } from "../icon";
|
||||||
import { _i18n } from "../../i18n";
|
import { _i18n } from "../../i18n";
|
||||||
import { cssNames, downloadFile } from "../../utils";
|
import { cssNames, saveFileDialog } from "../../utils";
|
||||||
import { Pod } from "../../api/endpoints";
|
import { Pod } from "../../api/endpoints";
|
||||||
import { PodLogSearch, PodLogSearchProps } from "./pod-log-search";
|
import { PodLogSearch, PodLogSearchProps } from "./pod-log-search";
|
||||||
|
|
||||||
@ -39,7 +39,7 @@ export const PodLogControls = observer((props: Props) => {
|
|||||||
|
|
||||||
const downloadLogs = () => {
|
const downloadLogs = () => {
|
||||||
const fileName = selectedContainer ? selectedContainer.name : pod.getName();
|
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) => {
|
const onContainerChange = (option: SelectOption) => {
|
||||||
|
|||||||
@ -7,7 +7,7 @@ import jsYaml from "js-yaml";
|
|||||||
import { Trans } from "@lingui/macro";
|
import { Trans } from "@lingui/macro";
|
||||||
import { AceEditor } from "../ace-editor";
|
import { AceEditor } from "../ace-editor";
|
||||||
import { ServiceAccount } from "../../api/endpoints";
|
import { ServiceAccount } from "../../api/endpoints";
|
||||||
import { copyToClipboard, cssNames, downloadFile } from "../../utils";
|
import { copyToClipboard, cssNames, saveFileDialog } from "../../utils";
|
||||||
import { Button } from "../button";
|
import { Button } from "../button";
|
||||||
import { Dialog, DialogProps } from "../dialog";
|
import { Dialog, DialogProps } from "../dialog";
|
||||||
import { Icon } from "../icon";
|
import { Icon } from "../icon";
|
||||||
@ -67,7 +67,7 @@ export class KubeConfigDialog extends React.Component<Props> {
|
|||||||
};
|
};
|
||||||
|
|
||||||
download = () => {
|
download = () => {
|
||||||
downloadFile("config", this.config, "text/yaml");
|
saveFileDialog("config", this.config, "text/yaml");
|
||||||
};
|
};
|
||||||
|
|
||||||
render() {
|
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 "./cssVar";
|
||||||
export * from "./cssNames";
|
export * from "./cssNames";
|
||||||
export * from "../../common/event-emitter";
|
export * from "../../common/event-emitter";
|
||||||
export * from "./downloadFile";
|
export * from "./saveFile";
|
||||||
export * from "./prevDefault";
|
export * from "./prevDefault";
|
||||||
export * from "./createStorage";
|
export * from "./createStorage";
|
||||||
export * from "./interval";
|
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