From fd2c89c879e5a146cedbad0de377fbb3624ac1c8 Mon Sep 17 00:00:00 2001 From: Seb Julliand Date: Tue, 27 Feb 2024 22:25:56 +0100 Subject: [PATCH 1/3] WIP Signed-off-by: Seb Julliand --- src/api/IBMi.ts | 8 +------- src/api/Tools.ts | 35 +++++++++++++++++++++++++++++++---- src/extension.ts | 1 - src/views/ifsBrowser.ts | 4 ++-- src/views/objectBrowser.ts | 16 ++++------------ 5 files changed, 38 insertions(+), 26 deletions(-) diff --git a/src/api/IBMi.ts b/src/api/IBMi.ts index 7ef974e07..6a8c3d9f6 100644 --- a/src/api/IBMi.ts +++ b/src/api/IBMi.ts @@ -1147,13 +1147,7 @@ export default class IBMi { fileToPath(file: string | vscode.Uri): string { if (typeof file === "string") { - if (process.platform === `win32` && file[0] === `/`) { - //Issue with getFile not working propertly on Windows - //when there was a / at the start. - return file.substring(1); - } else { - return file; - } + return Tools.fixWindowsPath(file); } else { return file.fsPath; diff --git a/src/api/Tools.ts b/src/api/Tools.ts index 2e0578846..efef40064 100644 --- a/src/api/Tools.ts +++ b/src/api/Tools.ts @@ -1,12 +1,15 @@ import Crypto from 'crypto'; -import { readFileSync } from "fs"; -import path from "path"; +import { readFileSync, statSync } from "fs"; +import os from "os"; +import path, { dirname } from "path"; import vscode from "vscode"; +import { t } from "../locale"; import { IBMiMessage, IBMiMessages, QsysPath } from '../typings'; import { API, GitExtension } from "./import/git"; -import { t } from "../locale"; export namespace Tools { + let lastDownloadLocation = os.homedir(); + export class SqlError extends Error { public sqlstate: string = "0"; constructor(message: string) { @@ -304,10 +307,34 @@ export namespace Tools { ).join("\n"); } - export function generateTooltipHtmlTable(header:string, rows: Record){ + export function generateTooltipHtmlTable(header: string, rows: Record) { return `` .concat(`${header ? `${header}` : ``}`) .concat(`${Object.entries(rows).map(([key, value]) => ``).join(``)}`) .concat(`
${t(key)}: ${value}
`); + } + + export function setLastDownloadLocation(path:string){ + path = fixWindowsPath(path); + if(statSync(path).isDirectory()){ + lastDownloadLocation = path; + } + else{ + lastDownloadLocation = dirname(path); } + } + + export function getLastDownloadLocation(){ + return lastDownloadLocation; + } + + export function fixWindowsPath(path:string){ + if (process.platform === `win32` && path[0] === `/`) { + //Issue with getFile not working propertly on Windows + //when there was a / at the start. + return path.substring(1); + } else { + return path; + } + } } \ No newline at end of file diff --git a/src/extension.ts b/src/extension.ts index b857eaa9d..bdd44af8a 100644 --- a/src/extension.ts +++ b/src/extension.ts @@ -35,7 +35,6 @@ export async function activate(context: ExtensionContext): Promise console.log(`Congratulations, your extension "code-for-ibmi" is now active!`); await loadAllofExtension(context); - const checkLastConnections = () => { const connections = (GlobalConfiguration.get(`connections`) || []); const lastConnections = (GlobalStorage.get().getLastConnections() || []).filter(lc => connections.find(c => c.name === lc.name)); diff --git a/src/views/ifsBrowser.ts b/src/views/ifsBrowser.ts index f48c7db17..53dc045b7 100644 --- a/src/views/ifsBrowser.ts +++ b/src/views/ifsBrowser.ts @@ -733,10 +733,10 @@ export function initializeIFSBrowser(context: vscode.ExtensionContext) { const ibmi = instance.getConnection(); if (ibmi) { //Get filename from path on server - const remoteFilepath = path.join(os.homedir(), path.basename(node.path)); - + const remoteFilepath = path.join(Tools.getLastDownloadLocation(), path.basename(node.path)); const localPath = (await vscode.window.showSaveDialog({ defaultUri: vscode.Uri.file(remoteFilepath) }))?.path; if (localPath) { + Tools.setLastDownloadLocation(localPath); try { await ibmi.downloadFile(localPath, node.path); vscode.window.showInformationMessage(t(`ifsBrowser.downloadStreamfile.infoMessage`)); diff --git a/src/views/objectBrowser.ts b/src/views/objectBrowser.ts index 3765b5baf..d3f43eab3 100644 --- a/src/views/objectBrowser.ts +++ b/src/views/objectBrowser.ts @@ -1,5 +1,6 @@ import fs from "fs"; import os from "os"; +import path from "path"; import util from "util"; import vscode from "vscode"; import { ConnectionConfiguration, DefaultOpenMode, GlobalConfiguration } from "../api/Configuration"; @@ -796,20 +797,11 @@ export function initializeObjectBrowser(context: vscode.ExtensionContext) { const memberContent = await contentApi.downloadMemberContent(asp, library, file, member); - let localFilepath = await vscode.window.showSaveDialog({ defaultUri: vscode.Uri.file(os.homedir() + `/` + basename) }); - + const localFilepath = (await vscode.window.showSaveDialog({ defaultUri: vscode.Uri.file(path.join(Tools.getLastDownloadLocation(), basename)) }))?.path; if (localFilepath) { - let localPath = localFilepath.path; - if (process.platform === `win32`) { - //Issue with getFile not working properly on Windows - //when there is a / at the start. - if (localPath[0] === `/`) { - localPath = localPath.substring(1); - } - } - + Tools.setLastDownloadLocation(localFilepath); try { - await writeFileAsync(localPath, memberContent, `utf8`); + await writeFileAsync(Tools.fixWindowsPath(localFilepath), memberContent, `utf8`); vscode.window.showInformationMessage(t(`objectBrowser.downloadMemberContent.infoMessage`)); } catch (e) { vscode.window.showErrorMessage(t(`objectBrowser.downloadMemberContent.errorMessage`, e)); From 4768b47a0d30152413618779d259834ac1d43017 Mon Sep 17 00:00:00 2001 From: Seb Julliand Date: Tue, 27 Feb 2024 22:37:09 +0100 Subject: [PATCH 2/3] Reuse the last location when downloading Signed-off-by: Seb Julliand --- src/api/Tools.ts | 12 +++--------- src/views/ifsBrowser.ts | 4 ++-- src/views/objectBrowser.ts | 4 ++-- 3 files changed, 7 insertions(+), 13 deletions(-) diff --git a/src/api/Tools.ts b/src/api/Tools.ts index efef40064..b0f465cdd 100644 --- a/src/api/Tools.ts +++ b/src/api/Tools.ts @@ -1,7 +1,7 @@ import Crypto from 'crypto'; -import { readFileSync, statSync } from "fs"; +import { readFileSync } from "fs"; import os from "os"; -import path, { dirname } from "path"; +import path from "path"; import vscode from "vscode"; import { t } from "../locale"; import { IBMiMessage, IBMiMessages, QsysPath } from '../typings'; @@ -315,13 +315,7 @@ export namespace Tools { } export function setLastDownloadLocation(path:string){ - path = fixWindowsPath(path); - if(statSync(path).isDirectory()){ - lastDownloadLocation = path; - } - else{ - lastDownloadLocation = dirname(path); - } + lastDownloadLocation = path; } export function getLastDownloadLocation(){ diff --git a/src/views/ifsBrowser.ts b/src/views/ifsBrowser.ts index 53dc045b7..d3be7b605 100644 --- a/src/views/ifsBrowser.ts +++ b/src/views/ifsBrowser.ts @@ -1,5 +1,5 @@ import os from "os"; -import path from "path"; +import path, { dirname } from "path"; import vscode, { FileType } from "vscode"; import { ConnectionConfiguration, GlobalConfiguration } from "../api/Configuration"; @@ -736,7 +736,7 @@ export function initializeIFSBrowser(context: vscode.ExtensionContext) { const remoteFilepath = path.join(Tools.getLastDownloadLocation(), path.basename(node.path)); const localPath = (await vscode.window.showSaveDialog({ defaultUri: vscode.Uri.file(remoteFilepath) }))?.path; if (localPath) { - Tools.setLastDownloadLocation(localPath); + Tools.setLastDownloadLocation(dirname(localPath)); try { await ibmi.downloadFile(localPath, node.path); vscode.window.showInformationMessage(t(`ifsBrowser.downloadStreamfile.infoMessage`)); diff --git a/src/views/objectBrowser.ts b/src/views/objectBrowser.ts index d3f43eab3..9519a83c8 100644 --- a/src/views/objectBrowser.ts +++ b/src/views/objectBrowser.ts @@ -1,6 +1,6 @@ import fs from "fs"; import os from "os"; -import path from "path"; +import path, { dirname } from "path"; import util from "util"; import vscode from "vscode"; import { ConnectionConfiguration, DefaultOpenMode, GlobalConfiguration } from "../api/Configuration"; @@ -799,7 +799,7 @@ export function initializeObjectBrowser(context: vscode.ExtensionContext) { const localFilepath = (await vscode.window.showSaveDialog({ defaultUri: vscode.Uri.file(path.join(Tools.getLastDownloadLocation(), basename)) }))?.path; if (localFilepath) { - Tools.setLastDownloadLocation(localFilepath); + Tools.setLastDownloadLocation(dirname(localFilepath)); try { await writeFileAsync(Tools.fixWindowsPath(localFilepath), memberContent, `utf8`); vscode.window.showInformationMessage(t(`objectBrowser.downloadMemberContent.infoMessage`)); From cbc8c05db3275c1608ce91f819bba61099348cb2 Mon Sep 17 00:00:00 2001 From: Seb Julliand Date: Tue, 27 Feb 2024 23:14:49 +0100 Subject: [PATCH 3/3] Save the last download location at connection level Signed-off-by: Seb Julliand --- src/api/Configuration.ts | 4 +++- src/api/IBMi.ts | 22 ++++++++++++++++++++-- src/api/Tools.ts | 11 ----------- src/views/ifsBrowser.ts | 4 ++-- src/views/objectBrowser.ts | 4 ++-- 5 files changed, 27 insertions(+), 18 deletions(-) diff --git a/src/api/Configuration.ts b/src/api/Configuration.ts index 45f5ea0e6..fcf2c8e93 100644 --- a/src/api/Configuration.ts +++ b/src/api/Configuration.ts @@ -1,4 +1,4 @@ - +import os from "os"; import * as vscode from 'vscode'; import { DeploymentMethod } from '../typings'; import { FilterType } from './Filter'; @@ -62,6 +62,7 @@ export namespace ConnectionConfiguration { defaultDeploymentMethod: DeploymentMethod | ''; protectedPaths: string[]; showHiddenFiles: boolean; + lastDownloadLocation:string; [name: string]: any; } @@ -143,6 +144,7 @@ export namespace ConnectionConfiguration { defaultDeploymentMethod: parameters.defaultDeploymentMethod || ``, protectedPaths: (parameters.protectedPaths || []), showHiddenFiles: (parameters.showHiddenFiles === true || parameters.showHiddenFiles === undefined), + lastDownloadLocation: (parameters.lastDownloadLocation || os.homedir()) } } diff --git a/src/api/IBMi.ts b/src/api/IBMi.ts index 6a8c3d9f6..e4130ef67 100644 --- a/src/api/IBMi.ts +++ b/src/api/IBMi.ts @@ -3,6 +3,8 @@ import * as node_ssh from "node-ssh"; import * as vscode from "vscode"; import { ConnectionConfiguration } from "./Configuration"; +import { existsSync } from "fs"; +import os from "os"; import path from 'path'; import { instance } from "../instantiate"; import { CommandData, CommandResult, ConnectionData, IBMiMember, RemoteCommand } from "../typings"; @@ -613,7 +615,7 @@ export default class IBMi { // Next, we're going to see if we can get the CCSID from the user or the system. // Some things don't work without it!!! - try { + try { const [userInfo] = await runSQL(`select CHARACTER_CODE_SET_ID from table( QSYS2.QSYUSRINFO( USERNAME => upper('${this.currentUser}') ) )`); if (userInfo.CHARACTER_CODE_SET_ID !== `null` && typeof userInfo.CHARACTER_CODE_SET_ID === 'number') { this.qccsid = userInfo.CHARACTER_CODE_SET_ID; @@ -676,7 +678,7 @@ export default class IBMi { } } - if((this.qccsid < 1 || this.qccsid === 65535)){ + if ((this.qccsid < 1 || this.qccsid === 65535)) { this.outputChannel?.appendLine(`\nUser CCSID is ${this.qccsid}; falling back to using default CCSID ${this.defaultCCSID}\n`); } @@ -1145,6 +1147,22 @@ export default class IBMi { await this.client.getDirectory(this.fileToPath(localDirectory), remoteDirectory, options); } + getLastDownloadLocation() { + if(this.config?.lastDownloadLocation && existsSync(Tools.fixWindowsPath(this.config.lastDownloadLocation))){ + return this.config.lastDownloadLocation; + } + else{ + return os.homedir(); + } + } + + async setLastDownloadLocation(location: string) { + if (this.config && location && location !== this.config.lastDownloadLocation) { + this.config.lastDownloadLocation = location; + await ConnectionConfiguration.update(this.config); + } + } + fileToPath(file: string | vscode.Uri): string { if (typeof file === "string") { return Tools.fixWindowsPath(file); diff --git a/src/api/Tools.ts b/src/api/Tools.ts index b0f465cdd..2befcb355 100644 --- a/src/api/Tools.ts +++ b/src/api/Tools.ts @@ -1,6 +1,5 @@ import Crypto from 'crypto'; import { readFileSync } from "fs"; -import os from "os"; import path from "path"; import vscode from "vscode"; import { t } from "../locale"; @@ -8,8 +7,6 @@ import { IBMiMessage, IBMiMessages, QsysPath } from '../typings'; import { API, GitExtension } from "./import/git"; export namespace Tools { - let lastDownloadLocation = os.homedir(); - export class SqlError extends Error { public sqlstate: string = "0"; constructor(message: string) { @@ -314,14 +311,6 @@ export namespace Tools { .concat(``); } - export function setLastDownloadLocation(path:string){ - lastDownloadLocation = path; - } - - export function getLastDownloadLocation(){ - return lastDownloadLocation; - } - export function fixWindowsPath(path:string){ if (process.platform === `win32` && path[0] === `/`) { //Issue with getFile not working propertly on Windows diff --git a/src/views/ifsBrowser.ts b/src/views/ifsBrowser.ts index d3be7b605..05d59cf22 100644 --- a/src/views/ifsBrowser.ts +++ b/src/views/ifsBrowser.ts @@ -733,10 +733,10 @@ export function initializeIFSBrowser(context: vscode.ExtensionContext) { const ibmi = instance.getConnection(); if (ibmi) { //Get filename from path on server - const remoteFilepath = path.join(Tools.getLastDownloadLocation(), path.basename(node.path)); + const remoteFilepath = path.join(ibmi.getLastDownloadLocation(), path.basename(node.path)); const localPath = (await vscode.window.showSaveDialog({ defaultUri: vscode.Uri.file(remoteFilepath) }))?.path; if (localPath) { - Tools.setLastDownloadLocation(dirname(localPath)); + await ibmi.setLastDownloadLocation(dirname(localPath)); try { await ibmi.downloadFile(localPath, node.path); vscode.window.showInformationMessage(t(`ifsBrowser.downloadStreamfile.infoMessage`)); diff --git a/src/views/objectBrowser.ts b/src/views/objectBrowser.ts index 9519a83c8..6eb145fe0 100644 --- a/src/views/objectBrowser.ts +++ b/src/views/objectBrowser.ts @@ -797,9 +797,9 @@ export function initializeObjectBrowser(context: vscode.ExtensionContext) { const memberContent = await contentApi.downloadMemberContent(asp, library, file, member); - const localFilepath = (await vscode.window.showSaveDialog({ defaultUri: vscode.Uri.file(path.join(Tools.getLastDownloadLocation(), basename)) }))?.path; + const localFilepath = (await vscode.window.showSaveDialog({ defaultUri: vscode.Uri.file(path.join(connection.getLastDownloadLocation(), basename)) }))?.path; if (localFilepath) { - Tools.setLastDownloadLocation(dirname(localFilepath)); + await connection.setLastDownloadLocation(dirname(localFilepath)); try { await writeFileAsync(Tools.fixWindowsPath(localFilepath), memberContent, `utf8`); vscode.window.showInformationMessage(t(`objectBrowser.downloadMemberContent.infoMessage`));