Skip to content

Commit

Permalink
Merge pull request #1884 from codefori/feature/ifsMultiDownload
Browse files Browse the repository at this point in the history
Allow multiple IFS files/folders download
  • Loading branch information
sebjulliand authored Feb 29, 2024
2 parents a740701 + d223a70 commit 14333b1
Show file tree
Hide file tree
Showing 5 changed files with 79 additions and 31 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -2484,7 +2484,7 @@
},
{
"command": "code-for-ibmi.downloadStreamfile",
"when": "view == ifsBrowser && !listMultiSelection && viewItem == streamfile",
"when": "view == ifsBrowser && viewItem =~ /^directory.*|streamfile$/",
"group": "3_ifsTransfer@1"
},
{
Expand Down
6 changes: 4 additions & 2 deletions src/locale/ids/da.ts
Original file line number Diff line number Diff line change
Expand Up @@ -115,8 +115,10 @@ export const da: Locale = {
'ifsBrowser.searchIFS.placeholder2': `Indtast søgetekst.`,
'ifsBrowser.searchIFS.title2': `Søg i {0}`,
'ifsBrowser.searchIFS.noGrep': `'grep' skal være installeret på systemet for IFS søgning.`,
'ifsBrowser.downloadStreamfile.infoMessage': `Fil blev hentet.`,
'ifsBrowser.downloadStreamfile.errorMessage': `Fejl ved hentning af {0}! {1}`,
'ifsBrowser.downloadStreamfile.downloading':'Henter',
'ifsBrowser.downloadStreamfile.overwrite':'{0} eksisterer allerede.\nVil du erstatte?',
'ifsBrowser.downloadStreamfile.complete': `Hentning gennemført.`,
'ifsBrowser.downloadStreamfile.errorMessage': `Fejl under hentning: {0}`,
'ifsBrowser.getChildren.errorMessage': `Fejl ved læsning af objekter.`,
'ifsBrowser.handleFileListErrors.errorMessage': `{0} {1} opstod ved visning af filer.`,
'ifsBrowser.doSearchInStreamfiles.title': `Søger`,
Expand Down
6 changes: 4 additions & 2 deletions src/locale/ids/en.ts
Original file line number Diff line number Diff line change
Expand Up @@ -115,8 +115,10 @@ export const en: Locale = {
'ifsBrowser.searchIFS.placeholder': `Enter search term or select one of the previous search terms.`,
'ifsBrowser.searchIFS.placeholder2': `Enter search term.`,
'ifsBrowser.searchIFS.noGrep': `grep must be installed on the remote system for the IFS search.`,
'ifsBrowser.downloadStreamfile.infoMessage': `File was downloaded.`,
'ifsBrowser.downloadStreamfile.errorMessage': `Error downloading {0}! {1}`,
'ifsBrowser.downloadStreamfile.downloading':'Downloading',
'ifsBrowser.downloadStreamfile.overwrite':'{0} already exists.\nDo you want to replace it?',
'ifsBrowser.downloadStreamfile.complete': `Download complete`,
'ifsBrowser.downloadStreamfile.errorMessage': `Error downloading file(s): {0}`,
'ifsBrowser.getChildren.errorMessage': `Error loading objects.`,
'ifsBrowser.handleFileListErrors.errorMessage': `{0} {1} occurred while listing files.`,
'ifsBrowser.doSearchInStreamfiles.title': `Searching`,
Expand Down
6 changes: 4 additions & 2 deletions src/locale/ids/fr.ts
Original file line number Diff line number Diff line change
Expand Up @@ -115,8 +115,10 @@ export const fr: Locale = {
'ifsBrowser.searchIFS.placeholder2': `Entrez le mot à chercher.`,
'ifsBrowser.searchIFS.title2': `Chercher dans {0}.`,
'ifsBrowser.searchIFS.noGrep': `grep doit être installé sur le système distant pour la recherche sur l'IFS.`,
'ifsBrowser.downloadStreamfile.infoMessage': `Le fichier a été téléchargé.`,
'ifsBrowser.downloadStreamfile.errorMessage': `Erreur lors du téléchargement de {0}! {1}`,
'ifsBrowser.downloadStreamfile.downloading':'Téléchargement',
'ifsBrowser.downloadStreamfile.overwrite':'{0} existe déjà.\nVoulez-vous le remplacer?',
'ifsBrowser.downloadStreamfile.complete': `Téléchargement terminé`,
'ifsBrowser.downloadStreamfile.errorMessage': `Erreur lors du téléchargement: {0}`,
'ifsBrowser.getChildren.errorMessage': `Erreur lors du chargement des objets.`,
'ifsBrowser.handleFileListErrors.errorMessage': `{0} {1} s'est produit lors du chargement des fichiers.`,
'ifsBrowser.doSearchInStreamfiles.title': `Recherche`,
Expand Down
90 changes: 66 additions & 24 deletions src/views/ifsBrowser.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import os from "os";
import path, { dirname } from "path";
import vscode, { FileType } from "vscode";
import path, { dirname, extname } from "path";
import vscode, { FileType, window } from "vscode";

import { existsSync, mkdirSync, rmdirSync } from "fs";
import { ConnectionConfiguration, GlobalConfiguration } from "../api/Configuration";
import { SortOptions } from "../api/IBMiContent";
import { Search } from "../api/Search";
Expand Down Expand Up @@ -729,20 +730,68 @@ export function initializeIFSBrowser(context: vscode.ExtensionContext) {
}
}),

vscode.commands.registerCommand(`code-for-ibmi.downloadStreamfile`, async (node: IFSItem) => {
vscode.commands.registerCommand(`code-for-ibmi.downloadStreamfile`, async (node: IFSItem, nodes?: IFSItem[]) => {
const ibmi = instance.getConnection();
if (ibmi) {
//Get filename from path on server
const remoteFilepath = path.join(ibmi.getLastDownloadLocation(), path.basename(node.path));
const localPath = (await vscode.window.showSaveDialog({ defaultUri: vscode.Uri.file(remoteFilepath) }))?.path;
if (localPath) {
await ibmi.setLastDownloadLocation(dirname(localPath));
try {
await ibmi.downloadFile(localPath, node.path);
vscode.window.showInformationMessage(t(`ifsBrowser.downloadStreamfile.infoMessage`));
} catch (e) {
vscode.window.showErrorMessage(t(`ifsBrowser.downloadStreamfile.errorMessage`, t(String(node.contextValue)), e));
}
const items = (nodes || [node]).filter(reduceIFSPath);
const saveIntoDirectory = items.length > 1 || items[0].file.type === "directory";
let downloadLocation: string | undefined;
if (saveIntoDirectory) {
downloadLocation = (await vscode.window.showOpenDialog({
canSelectMany: false,
canSelectFiles: false,
canSelectFolders: true,
defaultUri: vscode.Uri.file(ibmi.getLastDownloadLocation())
}))?.[0]?.path;
}
else {
const remoteFilepath = path.join(ibmi.getLastDownloadLocation(), path.basename(node.path));
downloadLocation = (await vscode.window.showSaveDialog({
defaultUri: vscode.Uri.file(remoteFilepath),
filters: { 'Streamfile': [extname(node.path) || '*'] }
}))?.path;
}

if (downloadLocation) {
await ibmi.setLastDownloadLocation(saveIntoDirectory ? downloadLocation : dirname(downloadLocation));
const increment = 100 / items.length;
window.withProgress({ title: t('ifsBrowser.downloadStreamfile.downloading'), location: vscode.ProgressLocation.Notification }, async (task) => {
try {
for (const item of items) {
const targetPath = item.path;
task.report({ message: targetPath, increment });
if (saveIntoDirectory) {
const target = path.join(Tools.fixWindowsPath(downloadLocation!), path.basename(targetPath));
if (item.file.type === "directory") {
let proceed = !existsSync(target);
if (!proceed) {
if (await vscode.window.showWarningMessage(t('ifsBrowser.downloadStreamfile.overwrite', target), { modal: true }, t("Yes"))) {
rmdirSync(target, { recursive: true });
proceed = true;
}
}

if (proceed) {
mkdirSync(target, { recursive: true });
await ibmi.downloadDirectory(target, targetPath, { concurrency: 5 });
}
}
else {
if (!existsSync(target) || await vscode.window.showWarningMessage(t('ifsBrowser.downloadStreamfile.overwrite', target), { modal: true }, t("Yes"))) {
await ibmi.downloadFile(target, targetPath);
}
}
}
else{
await ibmi.downloadFile(downloadLocation!, targetPath);
}
}
vscode.window.showInformationMessage(t(`ifsBrowser.downloadStreamfile.complete`));
}
catch (e) {
vscode.window.showErrorMessage(t(`ifsBrowser.downloadStreamfile.errorMessage`, e));
}
});
}
}
}),
Expand Down Expand Up @@ -820,15 +869,8 @@ async function showOpenDialog() {
}

/**
* Filters the content of an IFSItem array to keep only:
* - Folders
* - Files whose parent folders are not in the array
* Filters the content of an IFSItem array to keep only items whose parent are not in the array
*/
function reduceIFSPath(item: IFSItem, index: number, array: IFSItem[]) {
if (item.file.type === "directory") {
return true;
}
else {
return !array.filter(i => i.file.type === "directory").some(folder => item.file.path.startsWith(folder.file.path));
}
function reduceIFSPath(item: IFSItem, index: number, array: IFSItem[]) {
return !array.filter(i => i.file.type === "directory" && i !== item).some(folder => item.file.path.startsWith(folder.file.path));
}

0 comments on commit 14333b1

Please sign in to comment.