124 lines
3.4 KiB
TypeScript
Raw Normal View History

2019-12-12 17:15:09 +09:00
import { interval, Subscription } from 'rxjs';
import {
UpdateCheckConfig,
UpdateInfo,
UpdateType
} from '@ucap-webmessenger/native';
import axios from 'axios';
import semver from 'semver';
import path from 'path';
import fse from 'fs-extra';
import zlib from 'zlib';
import { BrowserWindow, app } from 'electron';
import { UpdaterChannel } from '@ucap-webmessenger/native-electron';
import { startWith } from 'rxjs/operators';
import log from 'electron-log';
2019-12-12 17:15:09 +09:00
export class RendererUpdater {
private checkSubscription: Subscription | undefined;
private readonly appPath: string;
private readonly downloadPath: string;
private readonly unzipPath: string;
constructor(
private window: BrowserWindow,
private config: UpdateCheckConfig
) {
this.appPath = app.getAppPath() + '/';
const appPathFolder = this.appPath.slice(
0,
this.appPath.indexOf('app.asar')
);
this.downloadPath = path.resolve(appPathFolder, 'update.zip');
this.unzipPath = path.resolve(appPathFolder, '_app.asar');
}
startCheck() {
if (!semver.valid(this.config.currentVersion)) {
log.error(
2019-12-12 17:15:09 +09:00
`RendererUpdater::error currentVersion[${this.config.currentVersion}] is not valid`
);
return;
}
this.checkSubscription = interval(this.config.intervalHour * 60 * 60 * 1000)
.pipe(startWith(0))
.subscribe(i => {
axios
.post(this.config.feed)
.then(res => {
const appVersion = res.data.appVersion;
if (!semver.valid(appVersion)) {
log.error(
2019-12-12 17:15:09 +09:00
`RendererUpdater::error appVersion[${appVersion}] is not valid`
);
return;
}
if (semver.lt(this.config.currentVersion, appVersion)) {
this.download(appVersion, res.data.installUrl);
}
})
.catch(reason => {
log.error('RendererUpdater', reason);
2019-12-12 17:15:09 +09:00
});
});
}
stopCheck() {
if (!!this.checkSubscription) {
this.checkSubscription.unsubscribe();
}
}
apply() {
const downloadStream = fse.createReadStream(this.downloadPath);
const unzipStream = fse.createWriteStream(this.unzipPath);
const unzip = zlib.createGunzip();
downloadStream
.pipe(unzip)
.pipe(unzipStream)
.end(chunk => {
try {
fse.unlinkSync(this.appPath.slice(0, -1));
} catch (error) {
log.error('RendererUpdater::apply', error);
2019-12-12 17:15:09 +09:00
return;
}
try {
fse.renameSync(this.unzipPath, this.appPath.slice(0, -1));
} catch (error) {
log.error('RendererUpdater::apply', error);
2019-12-12 17:15:09 +09:00
return;
}
app.relaunch();
});
}
private download(appVersion: string, installUrl: string) {
axios
.get(installUrl, { responseType: 'blob' })
.then(res => {
fse.writeFile(this.downloadPath, res.data, err => {
if (!!err) {
log.error('RendererUpdater::download failed', err);
2019-12-12 17:15:09 +09:00
return;
}
const updateInfo: UpdateInfo = {
type: UpdateType.Differencial,
version: appVersion,
description: ''
};
this.window.webContents.send(UpdaterChannel.ExistInstant, updateInfo);
});
})
.catch(reason => {
log.error('RendererUpdater::download failed', reason);
2019-12-12 17:15:09 +09:00
});
}
}