* fix: reduce the number of api call Signed-off-by: James <james@jan.ai> * fix: download progress Signed-off-by: James <james@jan.ai> * chore: save blob * fix: server boot up * fix: download state not updating Signed-off-by: James <james@jan.ai> * fix: copy assets * Add Dockerfile CPU for Jan Server and Jan Web * Add Dockerfile GPU for Jan Server and Jan Web * feat: S3 adapter * Update check find count from ./pre-install and correct copy:asserts command * server add bundleDependencies @janhq/core * server add bundleDependencies @janhq/core * fix: update success/failed download state (#1945) * fix: update success/failed download state Signed-off-by: James <james@jan.ai> * fix: download model progress and state handling for both Desktop and Web --------- Signed-off-by: James <james@jan.ai> Co-authored-by: James <james@jan.ai> Co-authored-by: Louis <louis@jan.ai> * chore: refactor * fix: load models empty first time open * Add Docker compose * fix: assistants onUpdate --------- Signed-off-by: James <james@jan.ai> Co-authored-by: James <james@jan.ai> Co-authored-by: Hien To <tominhhien97@gmail.com> Co-authored-by: NamH <NamNh0122@gmail.com>
133 lines
4.4 KiB
TypeScript
133 lines
4.4 KiB
TypeScript
import { ipcMain } from 'electron'
|
|
import { resolve } from 'path'
|
|
import { WindowManager } from './../managers/window'
|
|
import request from 'request'
|
|
import { createWriteStream, renameSync } from 'fs'
|
|
import { DownloadEvent, DownloadRoute } from '@janhq/core'
|
|
const progress = require('request-progress')
|
|
import {
|
|
DownloadManager,
|
|
getJanDataFolderPath,
|
|
normalizeFilePath,
|
|
} from '@janhq/core/node'
|
|
|
|
export function handleDownloaderIPCs() {
|
|
/**
|
|
* Handles the "pauseDownload" IPC message by pausing the download associated with the provided fileName.
|
|
* @param _event - The IPC event object.
|
|
* @param fileName - The name of the file being downloaded.
|
|
*/
|
|
ipcMain.handle(DownloadRoute.pauseDownload, async (_event, fileName) => {
|
|
DownloadManager.instance.networkRequests[fileName]?.pause()
|
|
})
|
|
|
|
/**
|
|
* Handles the "resumeDownload" IPC message by resuming the download associated with the provided fileName.
|
|
* @param _event - The IPC event object.
|
|
* @param fileName - The name of the file being downloaded.
|
|
*/
|
|
ipcMain.handle(DownloadRoute.resumeDownload, async (_event, fileName) => {
|
|
DownloadManager.instance.networkRequests[fileName]?.resume()
|
|
})
|
|
|
|
/**
|
|
* Handles the "abortDownload" IPC message by aborting the download associated with the provided fileName.
|
|
* The network request associated with the fileName is then removed from the networkRequests object.
|
|
* @param _event - The IPC event object.
|
|
* @param fileName - The name of the file being downloaded.
|
|
*/
|
|
ipcMain.handle(DownloadRoute.abortDownload, async (_event, fileName) => {
|
|
const rq = DownloadManager.instance.networkRequests[fileName]
|
|
if (rq) {
|
|
DownloadManager.instance.networkRequests[fileName] = undefined
|
|
rq?.abort()
|
|
} else {
|
|
WindowManager?.instance.currentWindow?.webContents.send(
|
|
DownloadEvent.onFileDownloadError,
|
|
{
|
|
fileName,
|
|
err: { message: 'aborted' },
|
|
}
|
|
)
|
|
}
|
|
})
|
|
|
|
/**
|
|
* Downloads a file from a given URL.
|
|
* @param _event - The IPC event object.
|
|
* @param url - The URL to download the file from.
|
|
* @param fileName - The name to give the downloaded file.
|
|
*/
|
|
ipcMain.handle(
|
|
DownloadRoute.downloadFile,
|
|
async (_event, url, localPath, network) => {
|
|
const strictSSL = !network?.ignoreSSL
|
|
const proxy = network?.proxy?.startsWith('http')
|
|
? network.proxy
|
|
: undefined
|
|
if (typeof localPath === 'string') {
|
|
localPath = normalizeFilePath(localPath)
|
|
}
|
|
const array = localPath.split('/')
|
|
const fileName = array.pop() ?? ''
|
|
const modelId = array.pop() ?? ''
|
|
|
|
const destination = resolve(getJanDataFolderPath(), localPath)
|
|
const rq = request({ url, strictSSL, proxy })
|
|
|
|
// Put request to download manager instance
|
|
DownloadManager.instance.setRequest(localPath, rq)
|
|
|
|
// Downloading file to a temp file first
|
|
const downloadingTempFile = `${destination}.download`
|
|
|
|
progress(rq, {})
|
|
.on('progress', function (state: any) {
|
|
WindowManager?.instance.currentWindow?.webContents.send(
|
|
DownloadEvent.onFileDownloadUpdate,
|
|
{
|
|
...state,
|
|
fileName,
|
|
modelId,
|
|
}
|
|
)
|
|
})
|
|
.on('error', function (err: Error) {
|
|
WindowManager?.instance.currentWindow?.webContents.send(
|
|
DownloadEvent.onFileDownloadError,
|
|
{
|
|
fileName,
|
|
err,
|
|
modelId,
|
|
}
|
|
)
|
|
})
|
|
.on('end', function () {
|
|
if (DownloadManager.instance.networkRequests[localPath]) {
|
|
// Finished downloading, rename temp file to actual file
|
|
renameSync(downloadingTempFile, destination)
|
|
|
|
WindowManager?.instance.currentWindow?.webContents.send(
|
|
DownloadEvent.onFileDownloadSuccess,
|
|
{
|
|
fileName,
|
|
modelId,
|
|
}
|
|
)
|
|
DownloadManager.instance.setRequest(localPath, undefined)
|
|
} else {
|
|
WindowManager?.instance.currentWindow?.webContents.send(
|
|
DownloadEvent.onFileDownloadError,
|
|
{
|
|
fileName,
|
|
modelId,
|
|
err: { message: 'aborted' },
|
|
}
|
|
)
|
|
}
|
|
})
|
|
.pipe(createWriteStream(downloadingTempFile))
|
|
}
|
|
)
|
|
}
|