Commit ca9d897e authored by wudizhanche1000's avatar wudizhanche1000

海量更改

parent 85e50c1a
<h1>{{appsService.currentApp.name}}</h1>
<div *ngIf="!isInstalled">
<div *ngIf="!appsService.getDownloadInfo(appsService.currentApp)">
<button type="button" (click)="updateInstallConfig()" class="btn btn-primary" data-toggle="modal" data-target="#install-modal">安装
</button>
<button type="button" class="btn btn-secondary">导入</button>
<!--<button type="button" class="btn btn-secondary">正版代购</button>-->
</div>
<div *ngIf="appsService.getDownloadInfo(appsService.currentApp)">
<div *ngIf="appsService.getDownloadInfo(appsService.currentApp).status === 'install'">正在安装...</div>
<div *ngIf="appsService.getDownloadInfo(appsService.currentApp).status === 'wait'">等待安装...</div>
<progress *ngIf="appsService.getDownloadInfo(appsService.currentApp).status === 'active'" class="progress progress-striped progress-animated" value="{{appsService.getDownloadInfo(appsService.currentApp).progress}}" max="100"></progress>
</div>
<h1>{{currentApp.name}}</h1>
<div *ngIf="currentApp.status.status === 'init'">
<button type="button" class="btn btn-primary" data-toggle="modal" (click)="updateInstallConfig()"
data-target="#install-modal">安装
</button>
<button type="button" class="btn btn-secondary">导入</button>
<!--<button type="button" class="btn btn-secondary">正版代购</button>-->
</div>
<div *ngIf="isInstalled && (appsService.currentApp.id != 'ygopro')">
<button (click)="startApp(appsService.currentApp)" type="button" class="btn btn-primary">运行</button>
<div *ngIf="currentApp.status.status === 'installing'">正在安装...</div>
<div *ngIf="currentApp.status.status==='waiting'">等待安装...</div>
<progress *ngIf="currentApp.status.status === 'downloading'"
class="progress progress-striped progress-animated"
value="{{currentApp.status.progress}}" max="{{currentApp.status.total}}"></progress>
<div *ngIf="currentApp.status.status==='ready' && (currentApp.id != 'ygopro')">
<button (click)="startApp(currentApp)" type="button" class="btn btn-primary">运行</button>
<button type="button" data-toggle="modal" data-target="#settings-modal" class="btn btn-secondary">设置</button>
<!--<button (click)="appsService.browse(appsService.currentApp)" type="button" class="btn btn-secondary">游览本地文件</button>-->
<!--<button (click)="appsService.browse(currentApp)" type="button" class="btn btn-secondary">游览本地文件</button>-->
<div id="network" *ngIf="appsService.currentApp.network && appsService.currentApp.network.protocol == 'maotama'">
<div id="network" *ngIf="currentApp.network && currentApp.network.protocol == 'maotama'">
<div class="input-group">
<input *ngIf="appsService.connections.get(appsService.currentApp)" [value]="appsService.connections.get(appsService.currentApp).address || 'Loading...'" readonly type="text" class="form-control" aria-label="Text input with dropdown button" title="address">
<input *ngIf="appsService.connections.get(currentApp)"
[value]="appsService.connections.get(currentApp).address || 'Loading...'" readonly
type="text" class="form-control" aria-label="Text input with dropdown button" title="address">
<div class="input-group-btn">
<button *ngIf="!appsService.connections.get(appsService.currentApp)" (click)="appsService.network(appsService.currentApp, appsService.currentApp.network.servers[0])" type="button" class="btn btn-secondary">
<button *ngIf="!appsService.connections.get(currentApp)"
(click)="appsService.network(currentApp, currentApp.network.servers[0])"
type="button" class="btn btn-secondary">
联机
</button>
<button *ngIf="appsService.connections.get(appsService.currentApp)" (click)="copy(appsService.connections.get(appsService.currentApp).address)" [disabled]="!appsService.connections.get(appsService.currentApp).address" type="button" class="btn btn-secondary">
<button *ngIf="appsService.connections.get(currentApp)"
(click)="copy(appsService.connections.get(currentApp).address)"
[disabled]="!appsService.connections.get(currentApp).address" type="button"
class="btn btn-secondary">
复制
</button>
<button type="button" class="btn btn-secondary dropdown-toggle dropdown-toggle-split" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false" style="height: 38px;">
<button type="button" class="btn btn-secondary dropdown-toggle dropdown-toggle-split"
data-toggle="dropdown" aria-haspopup="true" aria-expanded="false" style="height: 38px;">
<span class="sr-only">Toggle Dropdown</span>
</button>
<div class="dropdown-menu" [class.dropdown-menu-right]="appsService.connections.get(appsService.currentApp)">
<div class="dropdown-menu"
[class.dropdown-menu-right]="appsService.connections.get(currentApp)">
<h6 class="dropdown-header">选择服务器</h6>
<a *ngFor="let server of appsService.currentApp.network.servers" (click)="appsService.network(appsService.currentApp, server)" class="dropdown-item" href="#">{{server.id}}</a>
<a *ngFor="let server of currentApp.network.servers"
(click)="appsService.network(currentApp, server)" class="dropdown-item"
href="#">{{server.id}}</a>
</div>
</div>
</div>
</div>
</div>
<ygopro *ngIf="isInstalled && (appsService.currentApp.id == 'ygopro')"></ygopro>
<ygopro *ngIf="currentApp.status.status==='ready'&& (currentApp.id == 'ygopro')" [app]="currentApp"></ygopro>
<br>
......@@ -82,9 +92,13 @@
<button type="button" class="btn btn-danger btn-sm">卸载</button>
</td>
<td *ngIf="!checkInstall(mod.id)">
<button *ngIf="!appsService.getDownloadInfo(mod.id)" (click)="install(mod.id)" type="button" class="btn btn-primary btn-sm">安装
<button *ngIf="!appsService.getDownloadInfo(mod.id)" (click)="install(mod.id)" type="button"
class="btn btn-primary btn-sm">安装
</button>
<progress *ngIf="appsService.getDownloadInfo(mod.id) && appsService.getDownloadInfo(mod.id).status === 'active'" class="progress progress-striped progress-animated" value="{{appsService.getDownloadInfo(mod.id).progress}}" max="100"></progress>
<progress
*ngIf="appsService.getDownloadInfo(mod.id) && appsService.getDownloadInfo(mod.id).status === 'active'"
class="progress progress-striped progress-animated"
value="{{appsService.getDownloadInfo(mod.id).progress}}" max="100"></progress>
<div *ngIf="appsService.getDownloadInfo(mod.id) && appsService.getDownloadInfo(mod.id).status === 'wait'">
等待安装...
</div>
......@@ -97,10 +111,12 @@
</table>
</div>
<div *ngIf="isInstalled">
<div *ngIf="currentApp.isInstalled()">
<h2>本地文件</h2>
<button (click)="appsService.browse(appsService.currentApp)" type="button" class="btn btn-secondary">浏览本地文件</button>
<button (click)="uninstall()" type="button" class="btn btn-secondary">{{'uninstall'|translate}}</button>
<button (click)="appsService.browse(currentApp)" type="button" class="btn btn-secondary">浏览本地文件</button>
<button (click)="uninstall(currentApp.id)" type="button" class="btn btn-secondary">
{{'uninstall'|translate}}
</button>
</div>
<div class="modal fade" id="settings-modal" tabindex="-1">
......@@ -133,7 +149,7 @@
</div>
<div id="local-files" role="tabpanel" class="tab-pane fade">
<div class="list-inline">
<button type="button" [disabled]="!isInstalled" (click)="uninstall()">
<button type="button" [disabled]="!currentApp.isInstalled()" (click)="uninstall()">
{{'uninstall'|translate}}
</button>
<i *ngIf="uninstalling" class="fa fa-circle-o-notch fa-spin fa-3x fa-fw"></i>
......@@ -148,41 +164,46 @@
</div>
</div>
</div><!-- Modal -->
<div class="modal fade" id="install-modal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true" *ngIf="installConfig">
<div class="modal fade" id="install-modal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true"
*ngIf="installConfig">
<div class="modal-dialog" role="document">
<form id="install-form" class="modal-content" (ngSubmit)="install()" #theForm="ngForm">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">&times;</span>
</button>
<h4 class="modal-title" id="myModalLabel">{{'install'|translate}} {{name}}</h4>
<h4 class="modal-title" id="myModalLabel">{{'install'|translate}} {{currentApp.name}}</h4>
</div>
<div class="modal-body">
<p>即将开始安装 {{name}}</p>
<p>即将开始安装 {{currentApp.name}}</p>
<!-- 安装位置选择只在 windows 下存在, 为了方便调试暂时不加ngif -->
<h4>{{'install_path'|translate}}</h4>
<div class="form-group">
<select class="form-control" name="installPath" [(ngModel)]="installConfig.installPath" title="path">
<option *ngFor="let library of settingsService.getLibraries()" value="{{library['path']}}">
{{ library['path']}}
<select class="form-control" name="installPath" [(ngModel)]="installConfig.installLibrary"
title="path">
<option *ngFor="let library of libraries" value="{{library}}">
{{ library}}
</option>
</select>
</div>
<h4>{{'shortcut'|translate}}</h4>
<div class="checkbox">
<label>
<input type="checkbox" name="application" [(ngModel)]="installConfig.createShortcut"> {{'create_shortcut'|translate}}
<input type="checkbox" name="application" [(ngModel)]="installConfig.createShortcut">
{{'create_shortcut'|translate}}
</label>
</div>
<div class="checkbox">
<label>
<input type="checkbox" name="desktop" [(ngModel)]="installConfig.createDesktopShortcut"> {{'create_desktop_shortcut'|translate}}
<input type="checkbox" name="desktop" [(ngModel)]="installConfig.createDesktopShortcut">
{{'create_desktop_shortcut'|translate}}
</label>
</div>
<h4>{{'additions'|translate}}</h4>
<div *ngFor="let reference of installConfig.references">
<label>
<input type="checkbox" [(ngModel)]="reference.id" name="references" value="{{reference.id}}"> {{reference.name}}
<input type="checkbox" [(ngModel)]="reference.install" name="references" value="{{reference.app.id}}">
{{reference.app.name}}
</label>
</div>
</div>
......
import {Component, OnInit} from "@angular/core";
import {Component, OnInit, Input, ChangeDetectorRef} from "@angular/core";
import {AppsService} from "./apps.service";
import {InstallConfig} from "./install-config";
import {SettingsService} from "./settings.sevices";
import {App} from "./app";
import {DownloadService} from "./download.service";
import {clipboard, remote} from "electron";
import {clipboard, remote, ipcRenderer} from "electron";
import * as path from "path";
import * as child_process from "child_process";
import {InstallService} from "./install.service";
declare var Notification;
declare var $;
@Component({
selector: 'app-detail',
templateUrl: 'app/app-detail.component.html',
styleUrls: ['app/app-detail.component.css'],
providers: [DownloadService]
})
export class AppDetailComponent implements OnInit {
@Input()
currentApp: App;
platform = process.platform;
installConfig: InstallConfig;
constructor(private appsService: AppsService, private settingsService: SettingsService, private downloadService: DownloadService) {
constructor(private appsService: AppsService, private settingsService: SettingsService,
private downloadService: DownloadService, private installService: InstallService,
private ref: ChangeDetectorRef) {
}
ngOnInit() {
this.updateInstallConfig();
// this.updateInstallConfig();
ipcRenderer.on('download-message-reply', (event, arg)=> {
console.log(arg);
});
ipcRenderer.send("download-message", "ping")
}
updateInstallConfig() {
this.installConfig = this.appsService.getInstallConfig(this.appsService.currentApp);
this.installConfig.installPath = this.settingsService.getDefaultLibrary().path;
}
get name() {
let currentApp = this.appsService.currentApp;
if (currentApp) {
return currentApp.name[this.settingsService.getLocale()];
this.installConfig = new InstallConfig(this.currentApp);
this.installConfig.installLibrary = this.settingsService.getDefaultLibrary().path;
this.installConfig.references = [];
for (let reference of this.currentApp.references.values()) {
this.installConfig.references.push(new InstallConfig(reference))
}
return "Loading";
};
get isInstalled() {
let currentApp = this.appsService.currentApp;
return !!(currentApp.local && currentApp.local.path);
}
get libraries(): string[] {
return this.settingsService.getLibraries().map((item)=>item.path);
}
get news() {
let currentApp = this.appsService.currentApp;
if (currentApp) {
return currentApp.news;
}
return this.currentApp.news;
}
get friends() {
......@@ -63,35 +63,36 @@ export class AppDetailComponent implements OnInit {
}
get mods() {
let contains = ["optional", "language", "emulator"];
let currentApp = this.appsService.currentApp;
if (currentApp) {
if (currentApp.references[process.platform] && currentApp.references[process.platform].length > 0) {
let refs = currentApp.references[process.platform];
refs = refs.filter((ref)=> {
return contains.includes(ref.type);
});
refs = refs.map((ref)=> {
let tmp = Object.create(ref);
switch (tmp.type) {
case "optional":
tmp.type = "选项";
break;
case "language":
tmp.type = "语言";
break;
default:
break;
}
//console.log(tmp.type);
return tmp;
});
return refs;
//return this.currentApp.references[process.platform];
}
}
// let contains = ["optional", "language", "emulator"];
//
// let currentApp = this.appsService.currentApp;
// if (currentApp) {
// if (currentApp.references[process.platform] && currentApp.references[process.platform].length > 0) {
// let refs = currentApp.references[process.platform];
// refs = refs.filter((ref)=> {
// return contains.includes(ref.type);
// });
// refs = refs.map((ref)=> {
// let tmp = Object.create(ref);
// switch (tmp.type) {
// case "optional":
// tmp.type = "选项";
// break;
// case "language":
// tmp.type = "语言";
// break;
// default:
// break;
// }
// //console.log(tmp.type);
// return tmp;
// });
// return refs;
//return this.currentApp.references[process.platform];
// }
// }
return [];
}
uninstalling: boolean;
......@@ -99,23 +100,64 @@ export class AppDetailComponent implements OnInit {
uninstall(id: string) {
if (confirm("确认删除?")) {
this.uninstalling = true;
this.appsService.uninstall(id).then(()=> {
this.uninstalling = false;
}
);
// this.appsService.uninstall(id).then(()=> {
// this.uninstalling = false;
// }
// );
}
}
install() {
async install() {
$('#install-modal').modal('hide');
this.appsService.download();
let currentApp = this.currentApp;
let options = this.installConfig;
let dependencies = currentApp.findDependencies();
let apps = dependencies.concat(currentApp).filter((app)=>!app.isInstalled());
for (let reference of options.references) {
if (reference.install) {
apps.push(reference.app);
apps.push(...reference.app.findDependencies())
}
}
let downloadPath = path.join(this.installConfig.installLibrary, "downloading");
try {
let downloadApps = await this.downloadService.addUris(apps, downloadPath);
this.downloadService.getProgress(currentApp)
.subscribe((progress)=> {
currentApp.status.status = "downloading";
currentApp.status.progress = progress.progress;
currentApp.status.total = progress.total;
this.ref.detectChanges();
},
(error)=> {
},
()=> {
currentApp.status.status = "waiting";
this.ref.detectChanges();
});
await Promise.all(downloadApps.map((app)=> {
return this.downloadService.getComplete(app)
.then((completeApp: App)=> {
return this.installService.add(completeApp, options);
});
}));
currentApp.status.status = "ready";
} catch (e) {
new Notification(currentApp.name, {body: "下载失败"});
}
}
selectDir() {
let dir = remote.dialog.showOpenDialog({properties: ['openFile', 'openDirectory']});
console.log(dir);
this.appsService.installConfig.installDir = dir[0];
// this.appsService.installConfig.installDir = dir[0];
return dir[0];
}
......@@ -131,12 +173,8 @@ export class AppDetailComponent implements OnInit {
let open = '';
let openApp = app.actions.get("main").open;
if (openApp) {
if (this.isInstalled) {
open = path.join(openApp.local.path, openApp.actions.get("main").execute);
args.push(execute);
} else {
console.error('open app not found');
}
open = path.join(openApp.local.path, openApp.actions.get("main").execute);
args.push(execute);
} else {
//没有需要通过open启动依赖,直接启动程序
open = execute;
......
......@@ -4,5 +4,24 @@
export class AppLocal {
path: string;
version: string;
files: string[];
files: Map<string,string>;
update(local) {
this.path = local.path;
this.version = local.version;
let files = new Map<string,string>();
for (let filename of Object.keys(local.files)) {
files.set(filename, local.files[filename]);
}
this.files = files;
}
toJSON() {
let t = {};
for (let [k,v] of this.files) {
t[k] = v;
}
return {path: this.path, version: this.version, files: t};
}
}
import {AppLocal} from "./app-local";
/*
export enum Reference_Type {
runtime, // directx
emulator, // wine, np2
dependency, //
optional, // fxtz
language,
host
}
*/
/*
export enum App_Category {
game,
music,
book,
runtime, // directx
emulator, // wine, np2
language
}
*/
export enum Category {
game, // 游戏
music, // 音乐
book, // 图书
runtime, // 运行库
emulator, // 模拟器
language, // 语言包
expansion, // 资料片
module, // 创意工坊
}
// export enum Status{
// downloading,
// init,
// installing,
// ready,
// updating,
// uninstalling,
// waiting,
// }
export class AppStatus {
progress: number;
total: number;
status: string;
}
export class App {
id: string;
name: string; // i18n
_name: string; // i18n
get name() {
return this._name;
}
set name(a) {
this._name = a;
}
description: string; //i18n
author: string; // English Only
homepage: string;
category: string;
category: Category;
parent: App;
actions: Map<string,{execute: string, args: string[], env: {}, open: App}>;
references: Map<string,App>;
dependencies: Map<string,App>;
locales: string[];
download: {[platform: string]: string}; // meta4 url
download: string; // meta4 url
news: {title: string, url: string, image: string}[];
network: any;
tags: string[];
version: {[platform: string]: string};
version: string;
local: AppLocal;
status: AppStatus;
isInstalled(): boolean {
return this.local !== undefined;
}
constructor(app) {
this.id = app.id;
......@@ -46,7 +64,7 @@ export class App {
this.description = app.description;
this.author = app.author;
this.homepage = app.homepage;
this.category = app.category;
this.category = Category[app.category as string];
this.actions = app.actions;
this.dependencies = app.dependencies;
this.parent = app.parent;
......@@ -57,8 +75,20 @@ export class App {
this.network = app.network;
this.tags = app.tags;
this.version = app.version;
this.local = app.local;
}
findDependencies(): App[] {
if (this.dependencies && this.dependencies.size > 0) {
let set = new Set();
for (let dependency of this.dependencies.values()) {
dependency.findDependencies()
.forEach((value)=> {
set.add(value);
});
set.add(dependency);
}
return Array.from(set);
}
return [];
}
}
:host {
/*background-color: darkslategray;*/
width: 280px;
flex-shrink: 0;
overflow-y: auto;
background-color: #f5f5f5;
border-right: 1px solid #eee;
}
a {
display: block;
padding: 10px 20px 10px 20px;
}
.active {
background-color: #428bca;
}
.active > a {
color: #fff;
}
span {
margin-left: 8px;
}
\ No newline at end of file
<span *ngIf="grouped_apps.installed">已安装</span>
<ul *ngIf="grouped_apps.installed" class="nav nav-sidebar">
<li *ngFor="let app of grouped_apps.installed" [class.active]="app===appsService.currentApp">
<a (click)="chooseApp(app)" href="#">{{app.name}}</a>
</li>
</ul><span *ngIf="grouped_apps.yugioh">游戏王</span>
<ul *ngIf="grouped_apps.yugioh" class="nav nav-sidebar">
<li *ngFor="let app of grouped_apps.yugioh" [class.active]="app===appsService.currentApp">
<a (click)="chooseApp(app)" href="#">{{app.name}}</a>
</li>
</ul><span *ngIf="grouped_apps.touhou">东方 Project</span>
<ul *ngIf="grouped_apps.touhou" class="nav nav-sidebar">
<li *ngFor="let app of grouped_apps.touhou" [class.active]="app===appsService.currentApp">
<a (click)="chooseApp(app)" href="#">{{app.name}}</a>
</li>
</ul><span *ngIf="grouped_apps.touhou_pc98">东方旧作</span>
<ul *ngIf="grouped_apps.touhou_pc98" class="nav nav-sidebar">
<li *ngFor="let app of grouped_apps.touhou_pc98" [class.active]="app===appsService.currentApp">
<a (click)="chooseApp(app)" href="#">{{app.name}}</a>
</li>
</ul>
\ No newline at end of file
import {Component, OnInit} from "@angular/core";
import {AppsService} from "./apps.service";
import {App} from "./app";
@Component({
selector: 'apps',
templateUrl: 'app/apps.component.html',
styleUrls: ['app/apps.component.css'],
})
export class AppsComponent implements OnInit {
constructor(private appsService: AppsService) {
}
ngOnInit() {
}
chooseApp(app: App) {
this.appsService.currentApp = app;
}
get grouped_apps() {
let contains = ["game", "music", "book"];
let apps = Array.from(this.appsService.allApps.values());
let result = {};
for (let app of apps) {
if (contains.includes(app.category)) {
let tag;
if (app.local) {
tag = 'installed';
} else {
tag = app.tags[0];
}
if (!result[tag]) {
result[tag] = []
}
result[tag].push(app)
}
}
//console.log(result)
return result
}
}
\ No newline at end of file
import {Injectable, ApplicationRef} from "@angular/core";
import {Http} from "@angular/http";
import {App} from "./app";
import {App, AppStatus} from "./app";
import {InstallConfig} from "./install-config";
import {SettingsService} from "./settings.sevices";
import * as os from "os";
......@@ -10,6 +10,9 @@ import * as readline from "readline";
import * as mkdirp from "mkdirp";
import * as child_process from "child_process";
import {remote} from "electron";
import "rxjs/Rx";
import {AppLocal} from "./app-local";
const Aria2 = require('aria2');
const Sudo = require('electron-sudo').default;
......@@ -32,30 +35,13 @@ Sudo.prototype.fork = function (modulePath, args, options) {
@Injectable()
export class AppsService {
installConfig: InstallConfig;
private _currentApp: App;
get currentApp(): App {
return this._currentApp;
constructor(private http: Http, private settingsService: SettingsService, private ref: ApplicationRef,) {
}
set currentApp(app: App) {
this._currentApp = app;
}
constructor(private http: Http, private settingsService: SettingsService, private ref: ApplicationRef) {
this.loadApps(()=> {
if (this.data.size > 0) {
this.currentApp = this.data.get('ygopro');
}
});
}
private data: Map<string,App>;
get allApps(): Map<string,App> {
return this.data;
}
// get allApps(): Map<string,App> {
// return this.data;
// }
//[{"id": "th01", "gid": "aria2gid", "status": "active/install/complete/wait", "progress": "0-100"}]
downloadsInfo = [];
......@@ -96,11 +82,11 @@ export class AppsService {
let tarObj = {
id: this.downloadsInfo[index].id,
xzFile: res.files[0].path,
installDir: this.installConfig.installPath
// installDir: this.installConfig.installLibrary
};
new Promise((resolve)=> {
let refs = this.searchApp(this.downloadsInfo[index].id).references;
console.log(refs);
// let refs = this.searchApp(this.downloadsInfo[index].id).references;
// console.log(refs);
//[{"id": "th01", "wait":["wine", "dx"], resolve: resolve, tarObj: tarObj}]
let waitObj;
......@@ -124,7 +110,7 @@ export class AppsService {
// }
// });
// }
//console.log("wait obj:", waitObj);
// console.log("wait obj:", waitObj);
if (waitObj) {
this.waitInstallQueue.push(waitObj);
......@@ -181,40 +167,15 @@ export class AppsService {
return dir;
}
loadApps(callback) {
this.http.get('./apps.json')
.map(response => {
let apps = response.json();
let localAppData = JSON.parse(localStorage.getItem("localAppData"));
apps = apps.map((app: any)=> {
if (localAppData) {
localAppData.map((v)=> {
if (v.id === app.id) {
app.local = v.local;
}
});
}
return app;
});
return apps;
}).map(this.loadAppsList)
.subscribe((apps) => {
this.data = apps;
if (typeof(callback) === 'function') {
callback();
}
loadApps() {
return this.http.get('./apps.json')
.toPromise()
.then((response)=> {
let data = response.json();
return this.loadAppsList(data);
});
}
getLocalString(app: App, tag: string): string {
let locale = this.settingsService.getLocale();
let value = app[tag][locale];
if (!value) {
value = app[tag]["en-US"];
}
return value;
}
loadAppsList = (data: any): Map<string,App> => {
let apps = new Map<string,App>();
let locale = this.settingsService.getLocale();
......@@ -222,6 +183,17 @@ export class AppsService {
for (let item of data) {
let app = new App(item);
let local = localStorage.getItem(app.id);
if (local) {
app.local = new AppLocal();
app.local.update(JSON.parse(local));
}
app.status = new AppStatus();
if (local) {
app.status.status = "ready";
} else {
app.status.status = "init";
}
// 去除无关语言
['name', 'description'].forEach((key)=> {
......@@ -233,7 +205,7 @@ export class AppsService {
});
// 去除平台无关的内容
['actions', 'dependencies', 'references', 'download'].forEach((key)=> {
['actions', 'dependencies', 'references', 'download', 'version'].forEach((key)=> {
if (app[key]) {
if (app[key][platform]) {
app[key] = app[key][platform];
......@@ -265,31 +237,20 @@ export class AppsService {
let value = app[key];
if (value) {
if (Array.isArray(value)) {
let map = new Map<string,App>();
value.forEach((appId, index, array)=> {
array[index] = apps.get(appId);
})
map.set(appId, apps.get(appId));
});
app[key] = map;
} else {
app[key] = apps.get(value);
}
}
});
}
console.log(apps);
return apps;
};
searchApp(id): App {
return this.data.get(id);
}
checkInstall(id): boolean {
if (this.searchApp(id)) {
if (this.searchApp(id).local.path) {
return true;
}
}
return false;
}
deleteFile(path: string): Promise<string> {
return new Promise((resolve, reject)=> {
......@@ -308,44 +269,53 @@ export class AppsService {
})
}
saveAppLocal(app: App, appLocal: AppLocal) {
localStorage.setItem(app.id, JSON.stringify(appLocal));
}
install(config: InstallConfig) {
let app = config.app;
}
uninstall(id: string) {
//let current = this;
if (this.checkInstall(id)) {
let files: string[] = this.searchApp(id).local.files.sort().reverse();
// 删除本目录
files.push('.');
let install_dir = this.searchApp(id).local.path;
return files
.map((file)=>
()=>path.join(install_dir, file)
)
.reduce((promise: Promise<string>, task)=>
promise.then(task).then(this.deleteFile)
, Promise.resolve(''))
.then((value)=> {
this.searchApp(id).local = null;
localStorage.setItem("localAppData", JSON.stringify(this.data));
});
}
// //let current = this;
// if (this.checkInstall(id)) {
// let files: string[] = this.searchApp(id).local.files.sort().reverse();
// // 删除本目录
// files.push('.');
// let install_dir = this.searchApp(id).local.path;
// return files
// .map((file)=>
// ()=>path.join(install_dir, file)
// )
// .reduce((promise: Promise<string>, task)=>
// promise.then(task).then(this.deleteFile)
// , Promise.resolve(''))
// .then((value)=> {
// this.searchApp(id).local = null;
// localStorage.setItem("localAppData", JSON.stringify(this.data));
// return Promise.resolve()
// });
// }
}
download() {
let id = this.currentApp.id;
if (this.downloadsInfo.findIndex((v)=> {
return v.id == id
}) !== -1) {
console.log("this app is downloading")
} else {
let url = this.currentApp.download;
this.aria2.addUri([url], {'dir': this.download_dir}, (error, gid)=> {
console.log(error, gid);
if (error) {
console.error(error);
}
this.downloadsInfo.push({"id": id, "gid": gid, "status": "active", "progress": 0});
});
}
// let id = this.currentApp.id;
// if (this.downloadsInfo.findIndex((v)=> {
// return v.id == id
// }) !== -1) {
// console.log("this app is downloading")
// } else {
// let url = this.currentApp.download;
// this.aria2.addUri([url], {'dir': this.download_dir}, (error, gid)=> {
// console.log(error, gid);
// if (error) {
// console.error(error);
// }
// this.downloadsInfo.push({"id": id, "gid": gid, "status": "active", "progress": 0});
// });
// }
}
getDownloadInfo(id) {
......@@ -358,21 +328,6 @@ export class AppsService {
}
getInstallConfig(app: App): InstallConfig {
//let id = app.id;
this.installConfig = new InstallConfig(app);
let platform = process.platform;
let references: InstallConfig[] = [];
if (app.references[platform]) {
// app.references[platform].forEach((item)=> {
// references.push();
// });
}
this.installConfig.references = references;
return this.installConfig;
}
// tar
tarQueue = [];
isExtracting = false;
......@@ -476,8 +431,8 @@ export class AppsService {
this.downloadsInfo[downLoadsInfoIndex].status = "complete";
// 为了卸载时能重新显示安装条
this.downloadsInfo.splice(downLoadsInfoIndex, 1);
this.data.get(tarObj.id).local = appLocal.local;
console.log(11111, this.data.get(tarObj.id), appLocal);
// this.data.get(tarObj.id).local = appLocal.local;
// console.log(11111, this.data.get(tarObj.id), appLocal);
//[{"id": "th01", "wait":["wine", "dx"], resolve: resolve, tarObj: tarObj}]
this.waitInstallQueue = this.waitInstallQueue.map((waitObj)=> {
......
......@@ -2,24 +2,90 @@
* Created by weijian on 2016/10/26.
*/
import {Injectable} from "@angular/core";
import {SettingsService} from "./settings.sevices";
import {ipcRenderer} from "electron";
import {Injectable, NgZone} from "@angular/core";
import {Http} from "@angular/http";
import {Observable} from "rxjs/Observable";
import {EventEmitter} from "events";
import {App} from "./app";
const Aria2 = require('aria2');
@Injectable()
export class DownloadService {
aria2 = new Aria2();
baseURL = 'http://thief.mycard.moe/metalinks/'
appGidMap = new Map<App,string>();
gidAppMap = new Map<string,App>();
eventEmitter = new EventEmitter();
open = this.aria2.open();
constructor(private settingsService: SettingsService) {
ipcRenderer.send("download-message", "123");
constructor(private ngZone: NgZone, private http: Http) {
this.aria2.onDownloadComplete = (gid)=> {
let app = this.gidAppMap.get(gid.gid);
if (app) {
this.appGidMap.delete(app);
this.gidAppMap.delete(gid.gid);
this.eventEmitter.emit(app.id, 'complete');
}
}
}
sendEvent(event, args) {
ipcRenderer.send('')
getComplete(app: App): Promise<App> {
if (this.appGidMap.has(app)) {
return new Promise((resolve, reject)=> {
this.eventEmitter.once(app.id, (event)=> {
resolve(app);
})
});
}
}
listenEvent() {
console.log(ipcRenderer);
getProgress(app: App): Observable<any> {
let gid = this.appGidMap.get(app);
return Observable.create((observer)=> {
let interval;
this.ngZone.runOutsideAngular(()=> {
interval = setInterval(()=> {
this.aria2.tellStatus(gid).then((status: any)=> {
if (status.status === 'complete') {
observer.complete();
} else if (status.status === "active") {
observer.next({total: status.totalLength, progress: status.completedLength})
} else if (status.status === "error") {
observer.error(status.errorCode)
}
});
}, 1000);
});
return ()=> {
clearInterval(interval);
}
});
}
async addUris(apps: App[], path: string): Promise<App[]> {
let tasks = [];
for (let app of apps) {
let task = await this.addUri(app, path);
tasks.push(task);
}
return tasks;
}
async addUri(app: App, path: string): Promise<App> {
let id = app.id;
await this.open;
if (this.appGidMap.has(app)) {
return app;
} else {
let meta4link = `${this.baseURL}${id}.meta4`;
let response = await this.http.get(meta4link).toPromise();
let meta4 = btoa(response.text());
let gid = (await this.aria2.addMetalink(meta4, {dir: path}))[0];
this.appGidMap.set(app, gid);
this.gidAppMap.set(gid, app);
return app;
}
}
}
......@@ -6,21 +6,18 @@ import {App} from "./app";
export class InstallConfig {
app: App;
install: boolean;
installPath: string;
installLibrary: string;
installDir: string;
createShortcut: boolean;
createDesktopShortcut: boolean;
references: InstallConfig[];
constructor(app: App, installPath = ".", installDir = "", install = true, shortcut = false, desktopShortcut = false) {
constructor(app: App, installLibrary = "", installDir = "", install = true, shortcut = false, desktopShortcut = false) {
this.app = app;
this.createShortcut = shortcut;
this.createDesktopShortcut = desktopShortcut;
this.install = install;
this.installDir = installDir;
}
updateChecked() {
this.installLibrary = installLibrary;
}
}
\ No newline at end of file
/**
* Created by weijian on 2016/11/2.
*/
import {Injectable} from "@angular/core";
import {App} from "./app";
import {InstallConfig} from "./install-config";
import * as path from "path";
import * as child_process from "child_process";
import * as mkdirp from "mkdirp";
import * as readline from "readline";
import * as fs from 'fs';
import {EventEmitter} from "events";
import {AppLocal} from "./app-local";
import {Http} from "@angular/http";
import ReadableStream = NodeJS.ReadableStream;
@Injectable()
export class InstallService {
tarPath: string;
installQueue: Map<App,InstallConfig> = new Map();
eventEmitter: EventEmitter = new EventEmitter();
installingQueue: Set<App> = new Set();
checksumUri = "http://thief.mycard.moe/checksums/";
constructor(private http: Http) {
if (process.platform === "win32") {
this.tarPath = path.join(process.resourcesPath, 'bin/tar.exe');
} else {
this.tarPath = "tar"
}
}
createDirectory(dir: string) {
return new Promise((resolve, reject)=> {
mkdirp(dir, resolve);
})
}
getComplete(app: App): Promise<App> {
return null;
}
extract(file: string, destPath: string) {
return new Promise((resolve, reject)=> {
let tarProcess = child_process.spawn(this.tarPath, ['xvf', file, '-C', destPath]);
let rl = readline.createInterface({
input: <ReadableStream>tarProcess.stderr,
});
rl.on('line', (input)=> {
});
tarProcess.on('exit', (code)=> {
if (code === 0) {
resolve();
} else {
reject(code);
}
})
});
}
async postInstall(app: App, appPath: string) {
let action = app.actions.get('install');
if (action) {
let env = Object.assign({}, action.env);
let command = [];
command.push(path.join(appPath, action.execute));
command.push(...action.args);
let open = action.open;
if (open) {
let openAction = open.actions.get("main");
env = Object.assign(env, openAction.env);
command.unshift(...openAction.args);
command.unshift(path.join(open.local.path, openAction.execute));
}
return new Promise((resolve, reject)=> {
let child = child_process.spawn(command.shift(), command, {
env: env,
stdio: 'inherit',
shell: true,
});
child.on('error', (error)=> {
console.log(error);
});
child.on('exit', (code)=> {
if (code === 0) {
resolve();
} else {
reject();
}
})
})
}
}
saveAppLocal(app: App) {
if (app.local) {
let a = JSON.stringify(app.local)
console.log(a);
localStorage.setItem(app.id, a);
}
}
async backupFiles(app: App, files: Iterable<string>) {
let backupPath = path.join(app.local.path, "backup");
await this.createDirectory(backupPath);
for (let file of files) {
await new Promise((resolve, reject)=> {
let oldPath = path.join(app.local.path, file);
let newPath = path.join(backupPath, file);
fs.rename(oldPath, newPath, resolve);
});
}
}
async doInstall() {
for (let app of this.installQueue.keys()) {
let depInstalled = app.findDependencies()
.every((dependency)=>dependency.isInstalled());
if (depInstalled && !this.installingQueue.has(app)) {
this.installingQueue.add(app);
let options = this.installQueue.get(app);
let checksumMap: Map<string,string> = await this.http.get(`${this.checksumUri}${app.id}`)
.map((response)=> {
let map = new Map<string,string>();
for (let line of response.text().split('\n')) {
if (line !== "") {
let [checksum,filename]=line.split(' ', 2);
map.set(filename, checksum);
}
}
return map;
}).toPromise();
let packagePath = path.join(options.installLibrary, 'downloading', `${app.id}.tar.xz`);
let destPath: string;
if (app.parent) {
let differenceSet = new Set<string>();
let parentFilesMap = app.parent.local.files;
for (let key of checksumMap.keys()) {
if (parentFilesMap.has(key)) {
differenceSet.add(key);
}
}
await this.backupFiles(app.parent, differenceSet);
destPath = app.parent.local.path;
} else {
destPath = path.join(options.installLibrary, app.id);
await this.createDirectory(destPath);
}
this.installQueue.delete(app);
await this.extract(packagePath, destPath);
await this.postInstall(app, destPath);
let local = new AppLocal();
local.path = destPath;
local.files = checksumMap;
local.version = app.version;
app.local = local;
this.saveAppLocal(app);
this.installingQueue.delete(app);
if (this.installQueue.size > 0) {
await this.doInstall()
}
}
}
}
add(app: App, options: InstallConfig) {
if (!this.installQueue.has(app)) {
this.installQueue.set(app, options);
if (!app.isInstalled()) {
this.doInstall()
}
}
}
}
\ No newline at end of file
......@@ -12,4 +12,30 @@
background-color: #336699;
height: 236px;
flex-shrink: 0;
}
#apps{
/*background-color: darkslategray;*/
width: 280px;
flex-shrink: 0;
overflow-y: auto;
background-color: #f5f5f5;
border-right: 1px solid #eee;
}
a {
display: block;
padding: 10px 20px 10px 20px;
}
.active {
background-color: #428bca;
}
.active > a {
color: #fff;
}
span {
margin-left: 8px;
}
\ No newline at end of file
<!-- Begin page content -->
<div id="main">
<apps *ngIf="appsService.allApps"></apps>
<app-detail *ngIf="appsService._currentApp"></app-detail>
<div id="apps" *ngIf="apps">
<span *ngIf="grouped_apps.installed">已安装</span>
<ul *ngIf="grouped_apps.installed" class="nav nav-sidebar">
<li *ngFor="let app of grouped_apps.installed" [class.active]="app===currentApp">
<a (click)="chooseApp(app)" href="#">{{app.name}}</a>
</li>
</ul>
<span *ngIf="grouped_apps.yugioh">游戏王</span>
<ul *ngIf="grouped_apps.yugioh" class="nav nav-sidebar">
<li *ngFor="let app of grouped_apps.yugioh" [class.active]="app===currentApp">
<a (click)="chooseApp(app)" href="#">{{app.name}}</a>
</li>
</ul>
<span *ngIf="grouped_apps.touhou">东方 Project</span>
<ul *ngIf="grouped_apps.touhou" class="nav nav-sidebar">
<li *ngFor="let app of grouped_apps.touhou" [class.active]="app===currentApp">
<a (click)="chooseApp(app)" href="#">{{app.name}}</a>
</li>
</ul>
<span *ngIf="grouped_apps.touhou_pc98">东方旧作</span>
<ul *ngIf="grouped_apps.touhou_pc98" class="nav nav-sidebar">
<li *ngFor="let app of grouped_apps.touhou_pc98" [class.active]="app===currentApp">
<a (click)="chooseApp(app)" href="#">{{app.name}}</a>
</li>
</ul>
</div>
<app-detail *ngIf="currentApp" [currentApp]="currentApp"></app-detail>
<roster></roster>
</div>
<webview id="candy" [src]="candy_url" nodeintegration></webview>
\ No newline at end of file
/**
* Created by zh99998 on 16/9/2.
*/
import {Component} from "@angular/core";
import {Component, OnInit} from "@angular/core";
import {AppsService} from "./apps.service";
import {LoginService} from "./login.service";
import {App, Category} from "./app";
import {DownloadService} from "./download.service";
@Component({
selector: 'lobby',
templateUrl: 'app/lobby.component.html',
styleUrls: ['app/lobby.component.css'],
})
export class LobbyComponent {
candy_url;
export class LobbyComponent implements OnInit {
candy_url: string;
currentApp: App;
private apps: Map<string,App>;
constructor(private appsService: AppsService, private loginService: LoginService) {
constructor(private appsService: AppsService, private loginService: LoginService,private downloadService:DownloadService) {
this.candy_url = './candy/index.html?jid=' + this.loginService.user.username + '@mycard.moe&password=' + this.loginService.user.external_id + '&nickname=' + this.loginService.user.username + '&autojoin=ygopro_china_north@conference.mycard.moe'
}
ngOnInit() {
this.appsService.loadApps()
.then((apps)=> {
this.apps = apps;
this.currentApp = this.apps.get("th06");
})
}
chooseApp(app: App) {
this.currentApp = app;
}
get grouped_apps() {
let contains = ["game", "music", "book"].map((value)=>Category[value]);
let result = {};
for (let app of this.apps.values()) {
if (contains.includes(app.category)) {
let tag;
if (app.isInstalled()) {
tag = 'installed';
} else {
tag = app.tags[0];
}
if (!result[tag]) {
result[tag] = []
}
result[tag].push(app)
}
}
return result
}
}
......@@ -6,7 +6,6 @@ import {MyCardComponent} from "./mycard.component";
import {LoginComponent} from "./login.component";
import {StoreComponent} from "./store.component";
import {LobbyComponent} from "./lobby.component";
import {AppsComponent} from "./apps.component";
import {AppDetailComponent} from "./app-detail.component";
import {RosterComponent} from "./roster.component";
import {CommunityComponent} from "./community.component";
......@@ -15,12 +14,20 @@ import {AppsService} from "./apps.service";
import {TranslateModule} from "ng2-translate";
import {SettingsService} from "./settings.sevices";
import {LoginService} from "./login.service";
import {DownloadService} from "./download.service";
import {InstallService} from "./install.service";
@NgModule({
imports: [BrowserModule, FormsModule, ReactiveFormsModule, HttpModule, TranslateModule.forRoot()],
declarations: [MyCardComponent, LoginComponent, StoreComponent, LobbyComponent, CommunityComponent, AppsComponent, AppDetailComponent, RosterComponent, YGOProComponent],
declarations: [
MyCardComponent, LoginComponent, StoreComponent, LobbyComponent,
CommunityComponent, AppDetailComponent, RosterComponent, YGOProComponent,
],
bootstrap: [MyCardComponent],
providers: [AppsService, SettingsService, LoginService],
providers: [
AppsService, SettingsService, LoginService, DownloadService,
InstallService
],
schemas: [NO_ERRORS_SCHEMA]
})
export class MyCard {
......
......@@ -3,16 +3,32 @@
*/
import {Injectable} from "@angular/core";
import {remote} from "electron";
import * as path from "path";
@Injectable()
export class SettingsService {
static SETTING_LIBRARY = "library";
libraries: [{"default": boolean,path: string}];
static defaultLibraries = [
{
"default": true,
path: path.join(remote.app.getPath("appData"), "library")
},
];
libraries: {"default": boolean,path: string}[];
getLibraries() {
if (!this.libraries) {
let data = localStorage.getItem(SettingsService.SETTING_LIBRARY);
this.libraries = JSON.parse(data);
if (!data) {
this.libraries = SettingsService.defaultLibraries;
localStorage.setItem(SettingsService.SETTING_LIBRARY,
JSON.stringify(SettingsService.defaultLibraries));
} else {
this.libraries = JSON.parse(data);
}
}
return this.libraries;
}
......@@ -25,16 +41,23 @@ export class SettingsService {
}
static SETTING_LOCALE = "locale";
static defaultLocale = remote.app.getLocale();
locale: string;
getLocale(): string {
if (!this.locale) {
this.locale = localStorage.getItem(SettingsService.SETTING_LOCALE);
let locale = localStorage.getItem(SettingsService.SETTING_LOCALE);
if (!locale) {
this.locale = SettingsService.defaultLocale;
localStorage.setItem(SettingsService.SETTING_LOCALE, SettingsService.defaultLocale);
} else {
this.locale = locale;
}
}
return this.locale;
}
setLocal(locale: string) {
setLocale(locale: string) {
this.locale = locale;
localStorage.setItem(SettingsService.SETTING_LOCALE, locale);
}
......
/**
* Created by zh99998 on 16/9/2.
*/
import {Component, OnInit, ChangeDetectorRef} from "@angular/core";
import {Component, OnInit, ChangeDetectorRef, Input} from "@angular/core";
import {AppsService} from "./apps.service";
import * as fs from "fs";
import * as path from "path";
......@@ -11,6 +11,7 @@ import {remote} from "electron";
import * as ini from "ini";
import {EncodeOptions} from "ini";
import {LoginService} from "./login.service";
import {App} from "./app";
declare var $;
......@@ -67,7 +68,8 @@ interface Room {
styleUrls: ['app/ygopro.component.css'],
})
export class YGOProComponent implements OnInit {
app = this.appsService.searchApp('ygopro');
@Input()
app: App;
decks: string[] = [];
current_deck: string;
......
......@@ -94,8 +94,11 @@
"language"
],
"dependencies": {
"win32": [],
"win32": [
"th06"
],
"darwin": [
"th06",
"wine"
]
},
......@@ -1384,6 +1387,7 @@
}
},
"version": {
"win32": "1.06",
"darwin": "1.06"
},
"download": {
......@@ -2188,6 +2192,7 @@
}
},
"version": {
"win32": "1.06",
"darwin": "1.06"
},
"download": {
......
"use strict";
/**
* Created by weijian on 2016/10/27.
*/
const Rx = require("rxjs/Rx");
const {ipcMain} = require('electron');
const child_process_1 = require("child_process");
// import * as Aria2 from "aria2";
const Aria2 = require("aria2");
let a = (createProcess("D:/Github/mycard/bin/aria2c.exe", ['--enable-rpc', '--rpc-allow-origin-all', "--continue", "--split=10", "--min-split-size=1M", "--max-connection-per-server=10"]));
a.on('error', (error) => {
console.log(error);
});
// console.log(Aria2,2);
function createProcess(aria2c_path, args = []) {
return child_process_1.spawn(aria2c_path, args);
}
let options = {'host': 'localhost', 'port': 6800, 'secure': false};
let aria2 = new Aria2(options);
aria2.onDownloadComplete = (response) => {
console.log(response);
};
let open = aria2.open();
function addUri(uri, path) {
return open.then(() => {
return aria2.addUri(uri, { 'dir': path });
});
}
function pause(gid) {
return aria2.pause(gid);
}
function reportStatus() {
aria2.tellActive();
}
//ipcMain.on()
//# sourceMappingURL=aria2.js.map
\ No newline at end of file
{
"version": 3,
"file": "aria2.js",
"sourceRoot": "",
"sources": [
"aria2.ts"
],
"names": [],
"mappings": ";AAAA;;GAEG;AACH,MAAM,EAAE,GAAG,OAAO,CAAC,SAAS,CAAC,CAAC;AAC9B,MAAM,EAAC,OAAO,EAAC,GAAE,OAAO,CAAC,UAAU,CAAC,CAAC;AACrC,gCAAkC,eAAe,CAAC,CAAA;AAClD,kCAAkC;AAClC,MAAM,KAAK,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;AAE/B,IAAI,CAAC,GAAG,CAAC,aAAa,CAAC,iCAAiC,EAAE,CAAC,cAAc,EAAE,wBAAwB,EAAE,YAAY,EAAE,YAAY,EAAE,qBAAqB,EAAE,gCAAgC,CAAC,CAAC,CAAC,CAAA;AAC3L,CAAC,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,KAAK;IAChB,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;AACvB,CAAC,CAAC,CAAC;AACH,wBAAwB;AACxB,uBAAuB,WAAmB,EAAE,IAAI,GAAa,EAAE;IAC3D,MAAM,CAAC,qBAAK,CAAC,WAAW,EAAE,IAAI,CAAC,CAAC;AACpC,CAAC;AAED,IAAI,OAAO,GAAG,EAAC,MAAM,EAAE,WAAW,EAAE,MAAM,EAAE,IAAI,EAAE,QAAQ,EAAE,KAAK,EAAC,CAAA;AAClE,IAAI,KAAK,GAAG,IAAI,KAAK,CAAC,OAAO,CAAC,CAAC;AAE/B,KAAK,CAAC,kBAAkB,GAAG,CAAC,QAAQ;IAChC,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;AAC1B,CAAC,CAAC;AAEF,IAAI,IAAI,GAAG,KAAK,CAAC,IAAI,EAAE,CAAC;AACxB,gBAAgB,GAAa,EAAE,IAAY;IACvC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC;QACb,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,GAAG,EAAE,EAAC,KAAK,EAAE,IAAI,EAAC,CAAC,CAAC;IAC5C,CAAC,CAAC,CAAC;AACP,CAAC;AACD,eAAe,GAAW;IACtB,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,CAAA;AAC3B,CAAC;AAED;IACI,KAAK,CAAC,UAAU,EAAE,CAAA;AACtB,CAAC;AAED,cAAc"
}
\ No newline at end of file
/**
* Created by weijian on 2016/10/27.
*/
const Rx = require("rxjs/Rx");
const {ipcMain}= require('electron');
import {ChildProcess, spawn} from "child_process";
// import * as Aria2 from "aria2";
const Aria2 = require("aria2");
let a = (createProcess("D:/Github/mycard/bin/aria2c.exe", ['--enable-rpc', '--rpc-allow-origin-all', "--continue", "--split=10", "--min-split-size=1M", "--max-connection-per-server=10"]))
a.on('error', (error)=> {
console.log(error);
});
// console.log(Aria2,2);
function createProcess(aria2c_path: string, args: string[] = []): ChildProcess {
return spawn(aria2c_path, args);
}
let options = {'host': 'localhost', 'port': 6800, 'secure': false}
let aria2 = new Aria2(options);
aria2.onDownloadComplete = (response)=> {
console.log(response);
};
let open = aria2.open();
function addUri(uri: string[], path: string) {
return open.then(()=> {
return aria2.addUri(uri, {'dir': path});
});
}
function pause(gid: string): Promise<string> {
return aria2.pause(gid)
}
function reportStatus() {
aria2.tellActive()
}
//ipcMain.on()
......@@ -103,7 +103,9 @@ function createAria2c() {
throw 'unsupported platform';
}
//--split=10 --min-split-size=1M --max-connection-per-server=10
let aria2c = child_process.spawn(aria2c_path, ['--enable-rpc', '--rpc-allow-origin-all', "--continue", "--split=10", "--min-split-size=1M", "--max-connection-per-server=10"]);
let aria2c = child_process.spawn(aria2c_path,
['--enable-rpc', '--rpc-allow-origin-all', "--continue", "--split=10", "--min-split-size=1M", "--max-connection-per-server=10"],
{stdio: 'ignore'});
aria2c.on('data', (data)=> {
console.log(data);
});
......
......@@ -58,6 +58,9 @@
"productName": "MyCard",
"appId": "com.mycard.mycard",
"category": "public.app-category.social-networking",
"extraResources": [
"bin"
],
"win": {
"iconUrl": "http://mycard.moe/logo.png",
"remoteReleases": true
......
......@@ -3,7 +3,7 @@
"target": "es6",
"lib": [
"dom",
"es2016"
"es2017"
],
"module": "commonjs",
"moduleResolution": "node",
......
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