pgadmin4/web/pgadmin/static/js/DownloadUtils.js

126 lines
4.3 KiB
JavaScript

//////////////////////////////////////////////////////////////////////////
//
// pgAdmin 4 - PostgreSQL Tools
//
// Copyright (C) 2013 - 2025, The pgAdmin Development Team
// This software is released under the PostgreSQL Licence
//
//////////////////////////////////////////////////////////////////////////
import usePreferences from '../../preferences/static/js/store';
import { callFetch, parseApiError } from './api_instance';
import { getBrowser, toPrettySize } from './utils';
const DownloadUtils = {
downloadViaLink: function (url, fileName) {
const link = document.createElement('a');
link.href = url;
link.download = fileName;
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
},
downloadBlob: function (blob, fileName) {
const urlCreator = window.URL || window.webkitURL;
const downloadUrl = urlCreator.createObjectURL(blob);
this.downloadViaLink(downloadUrl, fileName);
window.URL.revokeObjectURL(downloadUrl);
},
downloadTextData: function (textData, fileName, fileType) {
const respBlob = new Blob([textData], {type : fileType});
this.downloadBlob(respBlob, fileName);
},
downloadBase64UrlData: function (downloadUrl, fileName) {
this.downloadViaLink(downloadUrl, fileName);
},
downloadFileStream: async function (allOptions, fileName, fileType, onProgress) {
const data = [];
const response = await callFetch(allOptions.url, allOptions.options);
if(!response.ok) {
throw new Error(parseApiError(await response.json()));
}
if (!response.body) {
throw new Error(response.statusText);
}
const reader = response.body.getReader();
let done = false;
let receivedLength = 0; // received bytes
while (!done) {
const { value, done: doneReading } = await reader.read();
done = doneReading;
if (value) {
data.push(value);
receivedLength += value.length;
onProgress?.(toPrettySize(receivedLength, 'B', 2));
}
}
const blob = new Blob(data, {type: fileType});
this.downloadBlob(blob, fileName);
}
};
// If we are in Electron, we will use the Electron API to download files.
if(getBrowser().name == 'Electron') {
DownloadUtils.downloadTextData = async (textData, fileName, _fileType) =>{
const {automatically_open_downloaded_file, prompt_for_download_location} = usePreferences.getState().getPreferencesForModule('misc');
await window.electronUI.downloadTextData(textData, {
defaultPath: fileName,
}, prompt_for_download_location, automatically_open_downloaded_file);
};
DownloadUtils.downloadBase64UrlData = async (downloadUrl, fileName) => {
const {automatically_open_downloaded_file, prompt_for_download_location} = usePreferences.getState().getPreferencesForModule('misc');
await window.electronUI.downloadBase64UrlData(downloadUrl, {
defaultPath: fileName,
}, prompt_for_download_location, automatically_open_downloaded_file);
};
DownloadUtils.downloadFileStream = async (allOptions, fileName, _fileType, onProgress)=>{
const {automatically_open_downloaded_file, prompt_for_download_location} = usePreferences.getState().getPreferencesForModule('misc');
const filePath = await window.electronUI.getDownloadStreamPath({
defaultPath: fileName,
}, prompt_for_download_location);
// If the user cancels the download, we will not proceed
if(!filePath) {
return;
}
const response = await callFetch(allOptions.url, allOptions.options);
if(!response.ok) {
throw new Error(parseApiError(await response.json()));
}
if (!response.body) {
throw new Error(response.statusText);
}
const contentLength = response.headers.get('Content-Length');
window.electronUI.downloadStreamSaveTotal(filePath, contentLength ? parseInt(contentLength, 10) : null);
const reader = response.body.getReader();
let done = false;
let receivedLength = 0; // received bytes
while (!done) {
const { value, done: doneReading } = await reader.read();
done = doneReading;
if (value) {
window.electronUI.downloadStreamSaveChunk(filePath, value);
receivedLength += value.length;
onProgress?.(toPrettySize(receivedLength, 'B', 2));
}
}
window.electronUI.downloadStreamSaveEnd(filePath, automatically_open_downloaded_file);
};
}
export default DownloadUtils;