Commit 783edb27 authored by wudizhanche1000's avatar wudizhanche1000

修复安装问题

parent a6591636
...@@ -83,7 +83,7 @@ ...@@ -83,7 +83,7 @@
<!--安装modal--> <!--安装modal-->
<div class="modal fade" id="install-modal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true" *ngIf="installOption"> <div class="modal fade" id="install-modal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true" *ngIf="installOption">
<div class="modal-dialog" role="document"> <div class="modal-dialog" role="document">
<form id="install-form" class="modal-content" (ngSubmit)="install(currentApp)" #theForm="ngForm"> <form id="install-form" class="modal-content" (ngSubmit)="install(currentApp,installOption,referencesInstall)" #theForm="ngForm">
<div class="modal-header"> <div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-label="Close"> <button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span>&times;</span> <span>&times;</span>
......
...@@ -95,8 +95,9 @@ export class AppDetailComponent implements OnInit { ...@@ -95,8 +95,9 @@ export class AppDetailComponent implements OnInit {
} }
async installMod(mod: App) { async installMod(mod: App) {
this.updateInstallOption(mod);
await this.install(mod); let option = new InstallOption(mod, path.dirname(mod.parent.local!.path));
await this.install(mod, option, {});
} }
...@@ -107,21 +108,18 @@ export class AppDetailComponent implements OnInit { ...@@ -107,21 +108,18 @@ export class AppDetailComponent implements OnInit {
} }
} }
async install(targetApp: App) { async install(targetApp: App, options: InstallOption, referencesInstall: {[id: string]: boolean}) {
$('#install-modal').modal('hide'); $('#install-modal').modal('hide');
let options = this.installOption;
try { try {
await this.appsService.install(targetApp, options); await this.appsService.install(targetApp, options);
if (this.references.length > 0) { for (let [id,install] of Object.entries(referencesInstall)) {
for (let [id,isInstalled] of Object.entries(this.referencesInstall)) { if (install) {
if (isInstalled) {
let reference = targetApp.references.get(id)!; let reference = targetApp.references.get(id)!;
console.log("reference install ", id, targetApp, targetApp.references, reference);
await this.appsService.install(reference, options); await this.appsService.install(reference, options);
} }
} }
}
} catch (e) { } catch (e) {
console.error(e); console.error(e);
new Notification(targetApp.name, {body: "下载失败"}); new Notification(targetApp.name, {body: "下载失败"});
......
...@@ -3,7 +3,6 @@ import {App} from "./app"; ...@@ -3,7 +3,6 @@ import {App} from "./app";
* Created by zh99998 on 16/9/6. * Created by zh99998 on 16/9/6.
*/ */
export class AppLocal { export class AppLocal {
library: string;
path: string; path: string;
version: string; version: string;
files: Map<string,string>; files: Map<string,string>;
......
...@@ -100,8 +100,9 @@ export class App { ...@@ -100,8 +100,9 @@ export class App {
isDownloading(): boolean { isDownloading(): boolean {
return this.status.status === "downloading"; return this.status.status === "downloading";
} }
isUninstalling():boolean{
return this.status.status==="uninstalling"; isUninstalling(): boolean {
return this.status.status === "uninstalling";
} }
runable(): boolean { runable(): boolean {
...@@ -146,4 +147,9 @@ export class App { ...@@ -146,4 +147,9 @@ export class App {
return []; return [];
} }
readyForInstall(): boolean {
let dependencies = this.findDependencies();
return dependencies.every((dependency) => dependency.isReady());
}
} }
\ No newline at end of file
...@@ -216,26 +216,35 @@ export class AppsService { ...@@ -216,26 +216,35 @@ export class AppsService {
}); });
}; };
if (!app.isInstalled()) { if (!app.isInstalled()) {
try {
let apps: App[] = []; let apps: App[] = [];
let dependencies = app.findDependencies().filter((dependency) => { let dependencies = app.findDependencies().filter((dependency) => {
return !dependency.isInstalled(); return !dependency.isInstalled();
}); });
apps.push(...dependencies, app); apps.push(...dependencies, app);
try {
let downloadPath = path.join(option.installLibrary, 'downloading'); let downloadPath = path.join(option.installLibrary, 'downloading');
let tasks: Promise<any>[] = []; let tasks: Promise<any>[] = [];
for (let a of apps) { for (let a of apps) {
tasks.push(addDownloadTask(a, downloadPath)); tasks.push(addDownloadTask(a, downloadPath));
} }
let downloadResults = await Promise.all(tasks); let downloadResults = await Promise.all(tasks);
let installTasks: Promise<void>[] = [];
for (let result of downloadResults) { for (let result of downloadResults) {
console.log(result); console.log(result);
let o = new InstallOption(result.app, option.installLibrary); let o = new InstallOption(result.app, option.installLibrary);
o.downloadFiles = result.files; o.downloadFiles = result.files;
this.installService.push({app: result.app, option: o});
let task = this.installService.push({app: result.app, option: o});
installTasks.push(task);
} }
await Promise.all(installTasks);
} catch (e) { } catch (e) {
app.status.status = 'init'; for (let a of apps) {
if (!a.isReady()) {
a.status.status = 'init';
}
}
console.log(e); console.log(e);
throw e; throw e;
} }
......
/** /**
* Created by weijian on 2016/11/2. * Created by weijian on 2016/11/2.
*/ */
import {Injectable, ApplicationRef} from "@angular/core"; import {Injectable, ApplicationRef, EventEmitter} from "@angular/core";
import {App, Category} from "./app"; import {App, Category} from "./app";
import {InstallOption} from "./install-option"; import {InstallOption} from "./install-option";
import * as path from "path"; import * as path from "path";
...@@ -9,7 +9,6 @@ import * as child_process from "child_process"; ...@@ -9,7 +9,6 @@ import * as child_process from "child_process";
import * as mkdirp from "mkdirp"; import * as mkdirp from "mkdirp";
import * as readline from "readline"; import * as readline from "readline";
import * as fs from "fs"; import * as fs from "fs";
import {EventEmitter} from "events";
import {AppLocal} from "./app-local"; import {AppLocal} from "./app-local";
import {Http} from "@angular/http"; import {Http} from "@angular/http";
import {ComparableSet} from "./shared/ComparableSet" import {ComparableSet} from "./shared/ComparableSet"
...@@ -31,7 +30,7 @@ export interface InstallStatus { ...@@ -31,7 +30,7 @@ export interface InstallStatus {
export class InstallService { export class InstallService {
tarPath: string; tarPath: string;
installingId: string = ''; installingId: string = '';
eventEmitter: EventEmitter = new EventEmitter(); eventEmitter = new EventEmitter<void>();
readonly checksumURL = "https://thief.mycard.moe/checksums/"; readonly checksumURL = "https://thief.mycard.moe/checksums/";
readonly updateServerURL = 'https://thief.mycard.moe/update/metalinks'; readonly updateServerURL = 'https://thief.mycard.moe/update/metalinks';
...@@ -70,19 +69,22 @@ export class InstallService { ...@@ -70,19 +69,22 @@ export class InstallService {
// } // }
// } // }
push(task: InstallTask): string { async push(task: InstallTask): Promise<void> {
let id = this.createId(); if (!task.app.readyForInstall()) {
this.installQueue.set(id, task); await new Promise((resolve, reject) => {
if (this.installQueue.size > 0 && this.installingId == '') { this.eventEmitter.subscribe(() => {
this.doInstall(); if (task.app.readyForInstall()) {
resolve();
} else if (task.app.findDependencies().find((dependency: App) => !dependency.isInstalled())) {
reject("Dependencies failed");
}
});
});
} }
return id; await this.doInstall(task);
} }
async doInstall() { async doInstall(task: InstallTask) {
if (this.installQueue.size > 0 && this.installingId == '') {
let [id,task] = this.installQueue.entries().next().value!;
this.installingId = id;
try { try {
let app = task.app; let app = task.app;
let dependencies = app.findDependencies(); let dependencies = app.findDependencies();
...@@ -130,6 +132,7 @@ export class InstallService { ...@@ -130,6 +132,7 @@ export class InstallService {
clearInterval(interval); clearInterval(interval);
} }
await this.postInstall(app, installDir); await this.postInstall(app, installDir);
console.log("post install success");
let local = new AppLocal(); let local = new AppLocal();
local.path = installDir; local.path = installDir;
local.files = checksumFile; local.files = checksumFile;
...@@ -140,16 +143,13 @@ export class InstallService { ...@@ -140,16 +143,13 @@ export class InstallService {
} }
// } // }
} catch (e) { } catch (e) {
console.log("exception in doInstall", e);
throw e; throw e;
} }
finally { finally {
this.installQueue.delete(id); this.eventEmitter.emit();
this.installingId = '';
if (this.installQueue.size > 0) {
this.doInstall();
}
}
} }
} }
createDirectory(dir: string) { createDirectory(dir: string) {
...@@ -158,14 +158,6 @@ export class InstallService { ...@@ -158,14 +158,6 @@ export class InstallService {
}) })
} }
getComplete(app: App): Promise<App> {
return new Promise((resolve, reject) => {
this.eventEmitter.once(app.id, (complete: any) => {
resolve();
});
});
}
extract(file: string, dir: string): Observable<string> { extract(file: string, dir: string): Observable<string> {
return Observable.create((observer: Observer<string>) => { return Observable.create((observer: Observer<string>) => {
let tarProcess = child_process.spawn(this.tarPath, ['xvf', file, '-C', dir]); let tarProcess = child_process.spawn(this.tarPath, ['xvf', file, '-C', dir]);
...@@ -208,13 +200,13 @@ export class InstallService { ...@@ -208,13 +200,13 @@ export class InstallService {
shell: true, shell: true,
}); });
child.on('error', (error) => { child.on('error', (error) => {
console.log(error); reject(error);
}); });
child.on('exit', (code) => { child.on('exit', (code) => {
if (code === 0) { if (code === 0) {
resolve(); resolve(code);
} else { } else {
reject(); reject(code);
} }
}) })
}) })
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment