Skip to content

Commit

Permalink
Merge pull request #449 from ZIMkaRU/feature/add-progress-perc-to-loa…
Browse files Browse the repository at this point in the history
…ding-win-for-import-db-module

Add progress perc to loading win for import-db module
  • Loading branch information
ezewer authored Nov 20, 2024
2 parents 5fd813e + d4864b7 commit c55ff55
Show file tree
Hide file tree
Showing 6 changed files with 146 additions and 44 deletions.
4 changes: 4 additions & 0 deletions build/locales/en/translations.json
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,10 @@
},
"modalDialog": {
"title": "Database import"
},
"loadingWindow": {
"description": "Importing DB ...",
"unzippedBytes": "DB size {{prettyUnzippedBytes}}"
}
}
},
Expand Down
4 changes: 4 additions & 0 deletions build/locales/ru/translations.json
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,10 @@
},
"modalDialog": {
"title": "Импорт базы данных"
},
"loadingWindow": {
"description": "Импортирование БД ...",
"unzippedBytes": "размер БД {{prettyUnzippedBytes}}"
}
}
},
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@
"new-github-issue-url": "0.2.1",
"showdown": "2.0.3",
"truncate-utf8-bytes": "1.0.2",
"yauzl": "2.10.0"
"yauzl": "3.2.0"
},
"devDependencies": {
"@mapbox/node-pre-gyp": "1.0.11",
Expand Down
129 changes: 93 additions & 36 deletions src/archiver.js
Original file line number Diff line number Diff line change
Expand Up @@ -140,83 +140,140 @@ const zip = async (
const unzip = (
zipPath,
folderPath,
params = {}
params
) => {
const { extractFiles } = { ...params }
const extractedfileNames = []
let isClosedByError = false
const {
extractFiles,
progressHandler
} = params ?? {}
return new Promise((_resolve, _reject) => {
const entryStates = []
let totalUncompressedSize = 0
let unzippedBytes = 0
let lastProgressEventMts = Date.now()

const asyncProgressHandler = async () => {
try {
if (typeof progressHandler !== 'function') {
return
}

if (
!Number.isFinite(totalUncompressedSize) ||
totalUncompressedSize === 0 ||
!Number.isFinite(unzippedBytes)
) {
return
}

const progress = unzippedBytes / totalUncompressedSize
const prettyUnzippedBytes = bytesToSize(unzippedBytes)

await progressHandler({
progress,
unzippedBytes,
prettyUnzippedBytes
})
} catch (err) {
console.debug(err)
}
}
const resolve = (entryState) => {
if (entryState) {
entryState.isClosedSuccessfully = true
}
if (
entryStates.some((state) => state?.isClosedWithError) ||
entryStates.some((state) => !state?.isClosedSuccessfully)
) {
return
}

asyncProgressHandler()

return _resolve(entryStates.map((state) => state?.entry?.fileName))
}
const reject = (err, zipfile, entryState) => {
if (entryState) {
entryState.isClosedWithError = true
}
if (zipfile) {
zipfile.close()
}

return _reject(err)
}

return new Promise((resolve, reject) => {
try {
yauzl.open(zipPath, { lazyEntries: true }, (err, zipfile) => {
yauzl.open(zipPath, { lazyEntries: false }, (err, zipfile) => {
if (err) {
reject(err)

return
}

zipfile.on('error', reject)
zipfile.on('end', () => {
if (isClosedByError) {
return
}

resolve(extractedfileNames)
})
zipfile.readEntry()

zipfile.on('end', () => resolve())
zipfile.on('entry', (entry) => {
const { fileName } = entry
const filePath = path.join(folderPath, fileName)
const errorMessage = yauzl.validateFileName(fileName)

if (/\/$/.test(fileName)) {
zipfile.readEntry()

return
}
if (
Array.isArray(extractFiles) &&
extractFiles.every(file => file !== fileName)
) {
zipfile.readEntry()

return
}

const entryState = {
isClosedWithError: false,
isClosedSuccessfully: false,
entry
}
totalUncompressedSize += entry?.uncompressedSize ?? 0
entryStates.push(entryState)

if (errorMessage) {
isClosedByError = true
zipfile.close()
reject(new InvalidFileNameInArchiveError(errorMessage))
reject(
new InvalidFileNameInArchiveError(errorMessage),
zipfile,
entryState
)

return
}

zipfile.openReadStream(entry, (err, readStream) => {
if (err) {
isClosedByError = true
zipfile.close()
reject(err)
reject(err, zipfile, entryState)

return
}

const output = fs.createWriteStream(filePath)

output.on('close', () => {
extractedfileNames.push(fileName)

zipfile.readEntry()
})
output.on('close', () => resolve(entryState))
output.on('error', (err) => {
isClosedByError = true
zipfile.close()
reject(err)
reject(err, zipfile, entryState)
})

readStream.on('error', (err) => {
isClosedByError = true
zipfile.close()
reject(err)
reject(err, zipfile, entryState)
})
readStream.on('data', (chunk) => {
unzippedBytes += chunk.length
const currMts = Date.now()

if (currMts - lastProgressEventMts < 500) {
return
}

lastProgressEventMts = currMts
asyncProgressHandler()
})

readStream.pipe(output)
Expand Down
39 changes: 36 additions & 3 deletions src/import-db.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@ const pauseApp = require('./pause-app')
const relaunch = require('./relaunch')
const { rm, isMainWinAvailable } = require('./helpers')
const wins = require('./window-creators/windows')
const {
setLoadingDescription
} = require('./window-creators/change-loading-win-visibility-state')
const {
DB_FILE_NAME,
DB_SHM_FILE_NAME,
Expand Down Expand Up @@ -78,7 +81,33 @@ module.exports = ({
throw new InvalidFilePathError()
}

await pauseApp()
const progressHandler = async (args) => {
const {
progress,
prettyUnzippedBytes
} = args ?? {}

const _description = i18next
.t('common.importDB.loadingWindow.description')
const _unzipped = i18next.t(
'common.importDB.loadingWindow.unzippedBytes',
{ prettyUnzippedBytes }
)

const unzipped = prettyUnzippedBytes
? `<br><small style="color:#808b93">${_unzipped}</small>`
: ''
const description = `${_description}${unzipped}`

await setLoadingDescription({ progress, description })
}

await pauseApp({
loadingWinParams: {
description: i18next
.t('common.importDB.loadingWindow.description')
}
})
await _rmDbExcludeMain(pathToUserData, DB_FILE_NAME)
const extractedfileNames = await unzip(
filePaths[0],
Expand All @@ -89,7 +118,8 @@ module.exports = ({
DB_SHM_FILE_NAME,
DB_WAL_FILE_NAME,
SECRET_KEY_FILE_NAME
]
],
progressHandler
}
)

Expand All @@ -100,8 +130,11 @@ module.exports = ({
relaunch()
} catch (err) {
try {
const _win = isMainWinAvailable(wins.loadingWindow)
? wins.loadingWindow
: win
await showErrorModalDialog(
win,
_win,
i18next.t('common.importDB.modalDialog.title'),
err
)
Expand Down
12 changes: 8 additions & 4 deletions src/pause-app.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,12 +28,16 @@ const _closeServer = () => {
})
}

module.exports = async (opts = {}) => {
module.exports = async (opts) => {
const {
beforeClosingServHook = () => {}
} = opts
beforeClosingServHook = () => {},
loadingWinParams
} = opts ?? {}

await showLoadingWindow({ isRequiredToCloseAllWins: true })
await showLoadingWindow({
isRequiredToCloseAllWins: true,
...loadingWinParams
})

await beforeClosingServHook()

Expand Down

0 comments on commit c55ff55

Please sign in to comment.