File manager add drag and drop upload folder

Add website list to show SSL certificate expiration time
Optimization of other functions
This commit is contained in:
jose
2020-06-13 10:56:49 +08:00
parent f7b8c3b151
commit f1746060ed
68 changed files with 1583 additions and 247 deletions
+15 -2
View File
@@ -4,7 +4,7 @@
# +-------------------------------------------------------------------
# | Copyright (c) 2015-2099 宝塔软件(http://bt.cn) All rights reserved.
# +-------------------------------------------------------------------
# | Author: 黄文良 <287962566@qq.com>
# | Author: hwliang <hwl@bt.cn>
# +-------------------------------------------------------------------
import sys
import json
@@ -1159,8 +1159,11 @@ def down(token=None,fname=None):
"token":find['token'],
"expire":public.format_date(times=find['expire'])
}
session['down'] = True
return render_template('down.html',data = pdata)
if not find['password']:
session['down'] = True
session[token] = 1
if session[token] != 1:
@@ -1277,7 +1280,17 @@ def get_pd():
if tmp: tmp = int(tmp)
if ltd < 1:
if tmp == -1:
if ltd == -2:
tmp3 = public.to_string([60, 115, 112, 97, 110, 32, 99, 108, 97, 115, 115, 61, 34, 98, 116, 108, 116, 100,
45, 103, 114, 97, 121, 34, 62, 60, 115, 112, 97, 110, 32, 115, 116, 121, 108, 101,
61, 34, 99, 111, 108, 111, 114, 58, 32, 35, 102, 99, 54, 100, 50, 54, 59, 102, 111,
110, 116, 45, 119, 101, 105, 103, 104, 116, 58, 32, 98, 111, 108, 100, 59, 109, 97,
114, 103, 105, 110, 45, 114, 105, 103, 104, 116, 58, 53, 112, 120, 34, 62, 24050, 36807,
26399, 60, 47, 115, 112, 97, 110, 62, 60, 97, 32, 99, 108, 97, 115, 115, 61, 34, 98, 116,
108, 105, 110, 107, 34, 32, 111, 110, 99, 108, 105, 99, 107, 61, 34, 98, 116, 46, 115, 111,
102, 116, 46, 117, 112, 100, 97, 116, 97, 95, 108, 116, 100, 40, 41, 34, 62, 32493,
36153, 60, 47, 97, 62, 60, 47, 115, 112, 97, 110, 62])
elif tmp == -1:
tmp3 = public.to_string([60, 115, 112, 97, 110, 32, 99, 108, 97, 115, 115, 61, 34, 98,
116, 112, 114, 111, 45, 102, 114, 101, 101, 34, 32, 111, 110, 99, 108, 105, 99, 107,
61, 34, 98, 116, 46, 115, 111, 102, 116, 46, 117, 112, 100, 97, 116, 97, 95, 99,
+252 -3
View File
@@ -5787,10 +5787,8 @@ select[disabled]{
}
/* 取消按钮组 */
.ace-clear-btn {
padding: 8px 20px 15px;
padding: 15px 20px;
text-align: right;
position: absolute;
bottom: 0;
width: 100%;
}
.ace-clear-btn .btn-default:hover {
@@ -6732,4 +6730,255 @@ select[disabled]{
}
.minText{
white-space: nowrap;
}
.upload_tips_mask{
position: absolute;
z-index: 999;
background-color: #fff;
width: 100%;
left: 0;
top: 0;
height: 445px;
border: 2px dashed #e0e0e0;
text-align: center;
}
.upload_file_body{
position: relative;
}
.upload_file_body.active{
height: 445px;
border: 2px dashed #e0e0e0;
text-align: center;
}
.upload_tips_mask span,
.upload_file_body.active span{
font-size: 35px;
color: #999;
position: absolute;
width: 100%;
left: 0;
top: 50%;
margin-top: -40px;
}
.dropUpLoadFile{
position: relative;
overflow: auto;
height: 410px;
padding-top:0;
}
.dropUpLoadFile::-webkit-scrollbar {
/*滚动条整体样式*/
width : 15px; /*高宽分别对应横竖滚动条的尺寸*/
height: 1px;
}
.dropUpLoadFile::-webkit-scrollbar-thumb {
/*滚动条里面小方块*/
border-radius: 0;
box-shadow : inset 0 0 5px rgba(0, 0, 0, 0.2);
background : #bbb;
}
.dropUpLoadFile::-webkit-scrollbar-track {
/*滚动条里面轨道*/
box-shadow : inset 0 0 5px rgba(0, 0, 0, 0.2);
border-radius: 0;
background : #ededed;
}
.dropUpLoadFile li{
height: 40px;
line-height: 40px;
border-bottom: 1px solid #ececec;
position: relative;
}
.dropUpLoadFileHead{
border-bottom: 1px solid #dedede;
}
.dropUpLoadFileHead li.fileTitle{
border-color: #ccc;
}
.upload_btn_groud .file_upload_info{
height: 40px;
line-height: 40px;
font-size: 12px;
color: #fff;
padding-left: 5px;
font-weight: 400;
color: #3c763d;
background-color: #dff0d8;
border: 1px solid #d6e9c6;
border-radius: 2px;
position: relative;
}
.upload_btn_groud .file_upload_info .ico-tips-close{
height: 22px;
width: 22px;
background: #90bb81;
display: inline-block;
border-radius: 50%;
position: absolute;
right: 10px;
top: 50%;
margin-top: -11px;
cursor: pointer;
transition: all 500ms;
}
.upload_btn_groud .file_upload_info .ico-tips-close:hover{
background: #658859;
}
.upload_btn_groud .file_upload_info .ico-tips-close:after{
transform: rotate(45deg);
}
.upload_btn_groud .file_upload_info .ico-tips-close:before{
transform: rotate(-45deg);
}
.upload_btn_groud .file_upload_info .ico-tips-close:after,
.upload_btn_groud .file_upload_info .ico-tips-close:before{
content:'';
display: inline-block;
height: 12px;
width: 2px;
background:#ececec;
border-radius: 5px;
position: absolute;
left: 50%;
top: 50%;
margin-top: -6px;
margin-left: -1px;
}
.upload_btn_groud .file_upload_info i{
font-style: initial;
}
.upload_btn_groud .file_upload_info span{
margin-right: 10px;
font-size: 13px;
display: inline-block;
height: 38px;
line-height: 38px;
margin-right: 0;
padding-left: 10px;
}
.dropUpLoadFile li .fileItem{
position: relative;
z-index: 999;
}
.dropUpLoadFile li .fileLoading{
content: '';
width: 0%;
height: 40px;
background: #6fb9d621;
position: absolute;
left: 0;
top: 0;
transition: width 100ms;
z-index: 998;
}
.dropUpLoadFile li:hover{
cursor: pointer;
}
.upload_btn_groud .dropdown-menu{
width: 100%;
min-width: 120%;
font-size: 13px;
}
.upload_btn_groud .btn-group:hover .dropdown-menu{
display: block;
}
.dropdown-menu:before{
content: '';
width: 100%;
position: absolute;
top: -5px;
height: 5px;
}
.upload_btn_groud{
margin-bottom: 5px;
height: 40px;
line-height: 40px;
}
.upload_btn_groud .dropdown-toggle{
border-left-color: #3f51b5;
}
.upload_btn_groud .btn-primary{
background-color: #4592f0;
border-color: #367fa9;
}
.dropUpLoadFileHead li.fileTitle span{
color: #666;
font-size: 13px;
display: inline-block;
height: 35px;
line-height: 35px;
margin-right: 0;
padding-left: 10px;
font-weight: 500;
}
.dropUpLoadFileHead li.fileTitle span:nth-child(1){
width: 50%;
padding-left: 15px;
}
.dropUpLoadFileHead li.fileTitle span:nth-child(2){
width: 25%;
}
.dropUpLoadFileHead li.fileTitle span:nth-child(3){
width: 25%;
}
.dropUpLoadFile .fileItem > span{
color: #666;
font-size: 12px;
vertical-align: top;
padding-left: 10px;
height: 40px;
line-height: 40px;
display: inline-block;
}
.dropUpLoadFile li .filename{
display: inline-block;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
width: 50%;
padding-left: 15px;
}
.dropUpLoadFile li .filename .ico {
height: 27px;
line-height: 27px;
background-size: 27px;
width: 25px;
vertical-align: middle;
margin-right: 10px;
float: initial;
}
.dropUpLoadFile li .filesize{
color: #999;
display: inline-block;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
width: 25%;
}
.dropUpLoadFile li .fileStatus{
width: 25%;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.dropUpLoadFile li em{
font-style: normal;
color: #06F;
float: right;
margin-right: 10px;
}
.upload_success{
color:#20a53a !important;
}
.upload_error{
color:#F56C6C !important;
}
.upload_primary{
color:#409EFF !important;
}
.upload_warning{
color:#409EFF !important;
}
+1 -1
View File
@@ -303,7 +303,7 @@ $.get('/ajax?action=GetCpuIo&start='+b+'&end='+e,function(rdata){
for(var i = 0; i < rdata.length; i++){
xData.push(rdata[i].addtime);
//yData.push(rdata[i].pro);
zData.push(rdata[i].mem);
zData.push(rdata[i].mem.toFixed(2));
}
option = {
tooltip: {
+458 -2
View File
@@ -1,3 +1,460 @@
var fileDrop = {
startTime: 0,
endTime:0,
uploadLength:0, //上传数量
splitSize: 1024 * 1024 * 2, //文件上传分片大小
filesList:[], // 文件列表数组
errorLength:0, //上传失败文件数量
isUpload:true, //上传状态,是否可以上传
uploadSuspend:[], //上传暂停参数
isUploadNumber:800,//限制单次上传数量
uploadAllSize:0, // 上传文件总大小
uploadedSize:0, // 已上传文件大小
topUploadedSize:0, // 上一次文件上传大小
uploadExpectTime:0, // 预计上传时间
initTimer:0, // 初始化计时
speedInterval:null, //平局速度定时器
timerSpeed:0, //速度
isLayuiDrop:false, //是否是小窗口拖拽
uploading:false,
init:function(){
if($('#mask_layer').length == 0) {
window.UploadFiles = function(){ fileDrop.dialog_view()};
$("body").append($('<div class="mask_layer" id="mask_layer" style="position:fixed;top:0;left:0;right:0;bottom:0; background:rgba(255,255,255,0.6);border:3px #ccc dashed;z-index:99999999;display:none;color:#999;font-size:40px;text-align:center;overflow:hidden;"><span style="position: absolute;top: 50%;left: 50%;margin-left: -200px;margin-top: -40px;">Upload files to the current directory</span></div>'));
this.event_relation(document.querySelector('#container'),document,document.querySelector('#mask_layer'));
}
},
// 事件关联 (进入,离开,放下)
event_relation:function(enter,leave,drop){
var that = this,obj = Object.keys(arguments);
for(var item in arguments){
if(typeof arguments[item] == "object" && typeof arguments[item].nodeType != 'undefined'){
arguments[item] = {
el:arguments[item],
callback:null
}
}
}
leave.el.addEventListener("dragleave",(leave.callback != null)?leave.callback:function(e){
e.preventDefault();
if(e.x == 0 && e.y == 0) $('#mask_layer').hide();
},false);
enter.el.addEventListener("dragenter", (enter.callback != null)?enter.callback:function(e){
if(e.dataTransfer.items[0].kind == 'string') return false
$('#mask_layer').show();
that.isLayuiDrop = false;
e.preventDefault();
},false);
drop.el.addEventListener("dragover",function(e){ e.preventDefault() }, false);
drop.el.addEventListener("drop",(enter.callback != null)?drop.callback:that.ev_drop, false);
},
// 事件触发
ev_drop:function(e){
e.preventDefault();
if(fileDrop.uploading){
layer.msg('Uploading, please wait...');
return false;
}
var items = e.dataTransfer.items,time,num = 0;
loadT = layer.msg('Getting upload file information, please wait...',{icon:16,time:0,shade:.3});
fileDrop.isUpload = true;
if(items && items.length && items[0].webkitGetAsEntry != null) {
if(items[0].kind != 'file') return false;
}
if(fileDrop.filesList == null) fileDrop.filesList = []
for(var i = fileDrop.filesList.length -1; i >= 0 ; i--){
if(fileDrop.filesList[i].is_upload) fileDrop.filesList.splice(-i,1)
}
$('#mask_layer').hide();
function update_sync(s){
s.getFilesAndDirectories().then(function(subFilesAndDirs) {
return iterateFilesAndDirs(subFilesAndDirs, s.path);
});
}
var iterateFilesAndDirs = function(filesAndDirs, path) {
if(!fileDrop.isUpload) return false
for (var i = 0; i < filesAndDirs.length; i++) {
if (typeof(filesAndDirs[i].getFilesAndDirectories) == 'function') {
update_sync(filesAndDirs[i])
// var path = filesAndDirs[i].path;
// filesAndDirs[i].getFilesAndDirectories().then(function(subFilesAndDirs) {
// iterateFilesAndDirs(subFilesAndDirs, path);
// });
} else {
if(num > fileDrop.isUploadNumber){
fileDrop.isUpload = false;
layer.msg(' '+ fileDrop.isUploadNumber +'file. Unable to upload, please upload after compression!',{icon:2,area:'405px'});
clearTimeout(time);
return false;
}
if(/^\.\w*/.test(filesAndDirs[i].name) ||/\/\.\w*/g.test(path)) continue; //排查隐藏文件目录和文件
fileDrop.filesList.push({
file:filesAndDirs[i],
path:bt.get_file_path(path +'/'+ filesAndDirs[i].name).replace('//','/'),
name:filesAndDirs[i].name.replace('//','/'),
icon:GetExtName(filesAndDirs[i].name),
size:fileDrop.to_size(filesAndDirs[i].size),
upload:0, //上传状态,未上传:0、上传中:1,已上传:2,上传失败:-1
is_upload:false
});
fileDrop.uploadAllSize += filesAndDirs[i].size
clearTimeout(time);
time = setTimeout(function(){
layer.close(loadT);
fileDrop.dialog_view();
},100);
num ++;
}
}
}
if('getFilesAndDirectories' in e.dataTransfer){
e.dataTransfer.getFilesAndDirectories().then(function(filesAndDirs) {
return iterateFilesAndDirs(filesAndDirs, '/');
});
}
},
// 获取上传速度
get_timer_speed:function(speed){
var that = this,num = 0;
if(speed == undefined) speed = 1000
that.speedInterval = setInterval(function(){
if(that.uploadedSize - that.topUploadedSize === 0){
that.timerSpeed = that.timerSpeed == 0 ? 0:(parseInt(that.timerSpeed / num));
num += 1;
}else{
that.timerSpeed = that.uploadedSize - that.topUploadedSize;
num = 0;
}
that.topUploadedSize = that.uploadedSize;
$('.file_upload_info .uploadSpeed').text(that.to_size(isNaN(that.timerSpeed)?0:that.timerSpeed)+'/s');
var estimateTime = that.time(parseInt(((that.uploadAllSize - that.uploadedSize) / that.timerSpeed) * 1000))
if(!isNaN(that.timerSpeed)) $('.file_upload_info .uploadEstimate').text(estimateTime.indexOf('NaN') == -1?estimateTime:'0sec');
},speed);
},
// 上传视图
dialog_view:function(config){
var that = this,html = '';
if(!$('.file_dir_uploads').length > 0){
if(that.filesList == null) that.filesList = []
for(var i =0; i<that.filesList.length; i++){
var item = that.filesList[i];
html +='<li><div class="fileItem"><span class="filename" title="File path:'+ (item.path + '/' + item.name).replace('//','/') +'&#10;File type:'+ item.file.type +'&#10;File size:'+ item.size +'"><i class="ico ico-'+ item.icon + '"></i>'+ (item.path + '/' + item.name).replace('//','/') +'</span><span class="filesize">'+ item.size +'</span><span class="fileStatus">'+ that.is_upload_status(item.upload) +'</span></div><div class="fileLoading"></div></li>';
}
var is_show = that.filesList.length > 11;
layer.open({
type: 1,
closeBtn: 1,
maxmin:true,
area: ['640px','609px'],
btn:['Start upload','Cancel upload'],
title: 'Upload files to【'+ bt.get_cookie('Path') +'】--- Support breakpoint renewal',
skin:'file_dir_uploads',
content:'<div style="padding:15px 15px 10px 15px;"><div class="upload_btn_groud"><div class="btn-group"><button type="button" class="btn btn-primary btn-sm upload_file_btn">Upload file</button><button type="button" class="btn btn-primary btn-sm dropdown-toggle" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false"><span class="caret"></span><span class="sr-only">Toggle Dropdown</span></button><ul class="dropdown-menu"><li><a href="#" data-type="file">Upload file</a></li><li><a href="#" data-type="dir">Upload directory</a></li></ul></div><div class="file_upload_info" style="display:none;"><span>Total process&nbsp;<i class="uploadProgress"></i>,&nbsp;&nbsp; Uploading&nbsp;<i class="uploadNumber"></i>,</span><span style="display:none">Upload failed&nbsp;<i class="uploadError"></i></span><span>Upload speed&nbsp;<i class="uploadSpeed">Getting</i>,</span><span>Expect time&nbsp;<i class="uploadEstimate">Getting</i></span><i></i></div></div><div class="upload_file_body '+ (html==''?'active':'') +'">'+ (html!=''?('<ul class="dropUpLoadFileHead" style="padding-right:'+ (is_show?'15':'0') +'px"><li class="fileTitle"><span class="filename">File name</span><span class="filesize">File size</span><span class="fileStatus">File status</span></li></ul><ul class="dropUpLoadFile list-list">'+ html +'</ul>'):'<span>Please drag the file here</span>') +'</div></div>',
success:function(){
$('#mask_layer').hide();
$('.file_dir_uploads .layui-layer-max').hide();
$('.upload_btn_groud .upload_file_btn').click(function(){$('.upload_btn_groud .dropdown-menu [data-type=file]').click()});
$('.upload_btn_groud .dropdown-menu a').click(function(){
var type = $(this).attr('data-type');
$('<input type="file" multiple="true" autocomplete="off" '+ (type == 'dir'?'webkitdirectory=""':'') +' />').change(function(e){
var files = e.target.files,arry = [];
for(var i=0;i<files.length;i++){
if(/^\.\w*/.test(files[i].name) || /\/\.\w*/g.test(files[i].webkitRelativePath)) continue;
var config = {
file:files[i],
path: bt.get_file_path('/' + files[i].webkitRelativePath).replace('//','/') ,
icon:GetExtName(files[i].name),
name:files[i].name.replace('//','/'),
size:that.to_size(files[i].size),
upload:0, //上传状态,未上传:0、上传中:1,已上传:2,上传失败:-1
is_upload:true
}
that.filesList.push(config);
fileDrop.uploadAllSize += files[i].size
}
that.dialog_view(that.filesList);
}).click();
});
var el = '';
that.event_relation({
el:$('.upload_file_body')[0],
callback:function(e){
if($(this).hasClass('active')){
$(this).css('borderColor','#4592f0').find('span').css('color','#4592f0');
}
}
},{
el:$('.upload_file_body')[0],
callback:function(e){
if($(this).hasClass('active')){
$(this).removeAttr('style').find('span').removeAttr('style');
}
}
},{
el:$('.upload_file_body')[0],
callback:function (e) {
var active = $('.upload_file_body');
if(active.hasClass('active')){
active.removeAttr('style').find('span').removeAttr('style');
}
that.ev_drop(e);
that.isLayuiDrop = true;
}
});
},
yes:function(index, layero){
if(!that.uploading){
if(that.filesList.length == 0){
layer.msg('Please select upload file',{icon:0});
return false;
}
$('.layui-layer-btn0').css({'cursor':'no-drop','background':'#5c9e69'}).attr('data-upload','true').text('Uploading');
that.upload_file();
that.initTimer = new Date();
that.uploading = true;
that.get_timer_speed();
}
},
btn2:function (index, layero){
if(that.uploading){
layer.confirm('Do you want to cancel the upload of files? It need to delete the uploaded files manually. Continue?',{title:'Cancel file upload',icon:0},function(indexs){
layer.close(index);
layer.close(indexs);
});
return false;
}else{
layer.close(index);
}
},
cancel:function(index, layero){
if(that.uploading){
layer.confirm('Do you want to cancel the upload of files? It need to delete the uploaded files manually. Continue?',{title:'Cancel file upload',icon:0},function(indexs){
layer.close(index);
layer.close(indexs);
});
return false;
}else{
layer.close(index);
}
},
end:function (){
GetFiles(bt.get_cookie('Path'));
that.clear_drop_stauts(true);
},
min:function(){
$('.file_dir_uploads .layui-layer-max').show();
$('#layui-layer-shade'+$('.file_dir_uploads').attr('times')).fadeOut();
},
restore:function(){
$('.file_dir_uploads .layui-layer-max').hide();
$('#layui-layer-shade'+$('.file_dir_uploads').attr('times')).fadeIn();
}
});
}else{
if(config == undefined && !that.isLayuiDrop) return false;
if(that.isLayuiDrop) config = that.filesList;
$('.upload_file_body').html('<ul class="dropUpLoadFileHead" style="padding-right:'+ (config.length>11?'15':'0') +'px"><li class="fileTitle"><span class="filename">File name</span><span class="filesize">File size</span><span class="fileStatus">Upload status</span></li></ul><ul class="dropUpLoadFile list-list"></ul>').removeClass('active');
if(Array.isArray(config)){
for(var i =0; i<config.length; i++){
var item = config[i];
html +='<li><div class="fileItem"><span class="filename" title="File path:'+ item.path + '/' + item.name +'&#10;File type:'+ item.file.type +'&#10;File size:'+ item.size +'"><i class="ico ico-'+ item.icon + '"></i>'+ (item.path + '/' + item.name).replace('//','/') +'</span><span class="filesize">'+ item.size +'</span><span class="fileStatus">'+ that.is_upload_status(item.upload) +'</span></div><div class="fileLoading"></div></li>';
}
$('.dropUpLoadFile').append(html);
}else{
$('.dropUpLoadFile').append('<li><div class="fileItem"><span class="filename" title="File path:'+ config.path + '/' + config.name +'&#10;File type:'+ config.type +'&#10;File size:'+ config.size +'"><i class="ico ico-'+ config.icon + '"></i>'+ config.name +'</span><span class="filesize">'+ config.size +'</span><span class="fileStatus">'+ that.is_upload_status(config.upload) +'</span></div><div class="fileLoading"></div></li>');
}
}
},
// 上传单文件状态
is_upload_status:function(status,val){
if(val === undefined) val = ''
switch(status){
case -1:
return '<span class="upload_info upload_error" title="Upload failed'+ (val != ''?','+val:'') +'">Upload failed'+ (val != ''?','+val:'') +'</span>';
break;
case 0:
return '<span class="upload_info upload_primary">Waiting to upload</span>';
break;
case 1:
return '<span class="upload_info upload_success">Uploaded</span>';
break;
case 2:
return '<span class="upload_info upload_warning">Uploading'+ val+'</span>';
break;
case 3:
return '<span class="upload_info upload_success">Paused</span>';
break;
}
},
// 设置上传实时反馈视图
set_upload_view:function(index,config){
var item = $('.dropUpLoadFile li:eq('+ index +')'),that = this;
var file_info = $('.file_upload_info');
if($('.file_upload_info .uploadProgress').length == 0){
$('.file_upload_info').html('<span>Total progress&nbsp;<i class="Upload Progress"></i>, Uploading&nbsp;<i class="uploadNumber"></i></span><span style="display:none">Upload failed&nbsp;<i class="uploadError"></i></span><span>Upload speed&nbsp;<i class="uploadSpeed">Getting</i></span><span>Expect time&nbsp;<i class="uploadEstimate">Getting</i></span><i></i>');
}
file_info.show().prev().hide().parent().css('paddingRight',0);
if(that.errorLength > 0) file_info.find('.uploadError').text('('+ that.errorLength +'file)').parent().show();
file_info.find('.uploadNumber').html('('+ that.uploadLength +'/'+ that.filesList.length +')');
file_info.find('.uploadProgress').html( ((that.uploadedSize / that.uploadAllSize) * 100).toFixed(2) +'%');
if(config.upload === 1 || config.upload === -1){
that.filesList[index].is_upload = true;
that.uploadLength += 1;
item.find('.fileLoading').css({'width':'100%','opacity':'.5','background': config.upload == -1?'#ffadad':'#20a53a21'});
item.find('.filesize').text(config.size);
item.find('.fileStatus').html(that.is_upload_status(config.upload,(config.upload === 1?('(耗时:'+ that.diff_time(that.startTime,that.endTime) +')'):config.errorMsg)));
item.find('.fileLoading').fadeOut(500,function(){
$(this).remove();
var uploadHeight = $('.dropUpLoadFile');
if(uploadHeight.length == 0) return false;
if(uploadHeight[0].scrollHeight > uploadHeight.height()){
uploadHeight.scrollTop(uploadHeight.scrollTop()+40);
}
});
}else{
item.find('.fileLoading').css('width',config.percent);
item.find('.filesize').text(config.upload_size +'/'+ config.size);
item.find('.fileStatus').html(that.is_upload_status(config.upload,'('+ config.percent +')'));
}
},
// 清除上传状态
clear_drop_stauts:function(status){
var time = new Date(),that = this;
if(!status){
try {
var s_peed = fileDrop.to_size(fileDrop.uploadedSize / ((time.getTime() - fileDrop.initTimer.getTime()) / 1000))
$('.file_upload_info').html('<span>Uploaded :&nbsp;'+ this.uploadLength +' files,&nbsp;&nbsp;'+ (this.errorLength>0?('Upload failed '+ this.errorLength +' files, '):'') +'Time consuming :&nbsp;'+ this.diff_time(this.initTimer,time) + ',&nbsp;&nbsp;average speed :&nbsp;'+ s_peed +'/s</span>').append($('<i class="ico-tips-close"></i>').click(function(){
$('.file_upload_info').hide().prev().show();
}));
} catch (e) {
}
}
$('.layui-layer-btn0').removeAttr('style data-upload').text('Start upload');
$.extend(fileDrop,{
startTime: 0,
endTime:0,
uploadLength:0, //上传数量
splitSize: 1024 * 1024 * 2, //文件上传分片大小
filesList:[], // 文件列表数组
errorLength:0, //上传失败文件数量
isUpload:false, //上传状态,是否可以上传
isUploadNumber:800,//限制单次上传数量
uploadAllSize:0, // 上传文件总大小
uploadedSize:0, // 已上传文件大小
topUploadedSize:0, // 上一次文件上传大小
uploadExpectTime:0, // 预计上传时间
initTimer:0, // 初始化计时
speedInterval:null, //平局速度定时器
timerSpeed:0, //速度
uploading:false
});
clearInterval(that.speedInterval);
},
// 上传文件,文件开始字段,文件编号
upload_file:function(fileStart,index){
if(fileStart == undefined && this.uploadSuspend.length == 0) fileStart = 0,index = 0;
if(this.filesList.length === index){
clearInterval(this.speedInterval);
this.clear_drop_stauts();
GetFiles(bt.get_cookie('Path'));
return false;
}
var that = this;
var item = this.filesList[index],fileEnd = '';
if(item == undefined) return false;
fileEnd = Math.min(item.file.size, fileStart + this.splitSize),
form = new FormData();
if(fileStart == 0){
that.startTime = new Date();
item = $.extend(item,{percent:'0%',upload:2,upload_size:'0B'});
}
form.append("f_path", bt.get_cookie('Path') + item.path);
form.append("f_name", item.name);
form.append("f_size", item.file.size);
form.append("f_start", fileStart);
form.append("blob", item.file.slice(fileStart, fileEnd));
that.set_upload_view(index,item);
$.ajax({
url:'/files?action=upload',
type: "POST",
data: form,
async: true,
processData: false,
contentType: false,
success:function(data){
if(typeof(data) === "number"){
that.set_upload_view(index,$.extend(item,{percent:(((data / item.file.size)* 100).toFixed(2) +'%'),upload:2,upload_size:that.to_size(data)}));
if(fileEnd != data){
that.uploadedSize += data;
}else{
that.uploadedSize += parseInt(fileEnd - fileStart);
}
that.upload_file(data,index);
}else{
if(data.status){
that.endTime = new Date();
that.uploadedSize += parseInt(fileEnd - fileStart);
that.set_upload_view(index,$.extend(item,{upload:1,upload_size:item.size}));
that.upload_file(0,index += 1);
}else{
that.set_upload_view(index,$.extend(item,{upload:-1,errorMsg:data.msg}));
that.errorLength ++;
}
}
},
error:function(e){
if(that.filesList[index].req_error === undefined) that.filesList[index].req_error = 1
if(that.filesList[index].req_error > 2){
that.set_upload_view(index,$.extend(that.filesList[index],{upload:-1,errorMsg:e.statusText == 'error'?'Network interruption':e.statusText }));
that.errorLength ++;
that.upload_file(fileStart,index += 1)
return false;
}
that.filesList[index].req_error += 1;
that.upload_file(fileStart,index)
}
});
},
time:function(date){
var hours = Math.floor(date / (60 * 60 * 1000));
var minutes = Math.floor(date / (60 * 1000));
var seconds = parseInt((date % (60 * 1000)) / 1000);
var result = seconds + ' sec';
if(minutes > 0) {
result = minutes + " min" + seconds + ' sec';
}
if(hours > 0){
result = hours + ' hour' + Math.floor((date - (hours * (60 * 60 * 1000))) / (60 * 1000)) + " min";
}
return result
},
diff_time: function (start_date, end_date) {
var diff = end_date.getTime() - start_date.getTime();
var minutes = Math.floor(diff / (60 * 1000));
var leave3 = diff % (60 * 1000);
var seconds = leave3 / 1000
var result = seconds.toFixed(minutes > 0?0:2) + ' sec';
if (minutes > 0) {
result = minutes + "min" + seconds.toFixed(0) + ' sec'
}
return result
},
to_size: function (a) {
var d = [" B", " KB", " MB", " GB", " TB", " PB"];
var e = 1024;
for (var b = 0; b < d.length; b += 1) {
if (a < e) {
var num = (b === 0 ? a : a.toFixed(2)) + d[b];
return (!isNaN((b === 0 ? a : a.toFixed(2))) && typeof num != 'undefined')?num:'0B';
}
a /= e
}
}
}
function IsDiskWidth() {
var comlistWidth = $("#comlist").width();
var bodyWidth = $(".file-box").width();
@@ -354,8 +811,6 @@ function get_path_size(path) {
}, function (rdata) {
layer.close(loadT);
var myclass = '.' + rdata.path.replace(/[^\w]/g, '-');
console.log(myclass)
console.log($(myclass).text())
$(myclass).text(ToSize(rdata.size));
});
}
@@ -620,6 +1075,7 @@ function GetFiles(Path, sort) {
$("#tipTools").width($("#fileCon")[0].clientWidth - 30);
}
$("#DirPathPlace input").val(rdata.PATH);
fileDrop.init();
var BarTools = '<div class="btn-group">\
<button class="btn btn-default btn-sm dropdown-toggle" type="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">\
' + lan.files.new + ' <span class="caret"></span>\
+12 -8
View File
@@ -145,7 +145,7 @@ var index = {
crs += 'CPU-' + i + ": " + d[2][i] + '%' + (n1 % 2 == 0?'</br>':' | ');
}
layer.tips(d[3] + "</br>" + d[5] + " CPU, " + d[4] + " Core, " + d[4]+" Thread</br>"+ crs, _this.find('.cicle'), { time: 0, tips: [1, '#999'] });
layer.tips(d[3] + "</br>" + d[5] + " CPU, " + d[4] + " Core, " + d[4]+" Thread</br>"+ crs, _this, { time: 0, tips: [1, '#999'] });
}, function () {
layer.closeAll('tips');
});
@@ -164,7 +164,8 @@ var index = {
$(this).find(".mem-re-min").show();
}
else {
$(this).find(".mem-re-min").hide();
return false;
//$(this).find(".mem-re-min").hide();
}
$(this).removeClass("shine_green");
$(this).find(".occupy").css({ "color": "#20a53a" });
@@ -172,6 +173,7 @@ var index = {
$(this).next().show();
//$(this).next().html(bt.get_cookie("mem-before"));
}).click(function () {
if (($(this).hasClass("mem-action"))) return false;
var _this = $(this);
bt.show_confirm(lan.index.mem_release_sure, '<font style="color:red;">'+lan.index.mem_release_warn+'</font>', function () {
if (!(_this.hasClass("mem-action"))) {
@@ -223,17 +225,20 @@ var index = {
}, 1500)
},
get_data_info: function (callback) {
var _this = $(this);
bt.system.get_net(function (net) {
var pub_arr = [{ val: 100, color: '#dd2f00' }, { val: 90, color: '#ff9900' }, { val: 70, color: '#20a53a' }, { val: 30, color: '#20a53a' }];
var load_arr = [{ title: lan.index.run_block, val: 100, color: '#dd2f00' }, { title: lan.index.run_slow, val: 90, color: '#ff9900' }, { title: lan.index.run_normal, val: 70, color: '#20a53a' }, { title: lan.index.run_fluent, val: 30, color: '#20a53a' }];
var _cpubox = $('.cpubox'), _membox = $('.membox'), _loadbox = $('.loadbox')
var _cpubox = $('.cpubox'), _membox = $('.membox'), _loadbox = $('.loadbox'), _diskbox = $('.diskbox')
index.set_val(_cpubox, { usage: net.cpu[0], title: net.cpu[1]+' '+lan.index.cpu_core, items: pub_arr })
index.set_val(_membox, { usage: (net.mem.memRealUsed * 100 / net.mem.memTotal).toFixed(1), items: pub_arr, title: net.mem.memRealUsed + '/' + net.mem.memTotal + '(MB)' })
bt.set_cookie('memSize', net.mem.memTotal)
for (var i = 0; i < _diskbox.length; i++) {
index.set_val(_diskbox.eq(i), { usage: net.disk[i].size[3].split('%')[0], title: net.disk[i].size[1]+'/'+net.disk[0].size[0], items: pub_arr })
}
var _lval = Math.round((net.load.one / net.load.max) * 100);
if (_lval > 100) _lval = 100;
index.set_val(_loadbox, { usage: _lval, items: load_arr })
@@ -335,14 +340,13 @@ var index = {
html += '<h4 class="c9 f15">' + item.title + '</h4>';
html += '</li>';
var _li = $(html);
if (item.masks) {
var mask = '';
for (var j = 0; j < item.masks.length; j++) mask += item.masks[j].title + ': ' + item.masks[j].value + "<br>";
_li.data('mask', mask);
_li.hover(function () {
_li.find('.cicle').hover(function () {
var _this = $(this);
layer.tips(_this.data('mask'), _this.find('.cicle'), { time: 0, tips: [1, '#999'] });
layer.tips(_this.parent().data('mask'), _this, { time: 0, tips: [1, '#999'] });
}, function () {
layer.closeAll('tips');
})
+324
View File
@@ -0,0 +1,324 @@
/**********************************
Directory Upload Proposal Polyfill
Author: Ali Alabbas (Microsoft)
**********************************/
(function() {
// Do not proceed with the polyfill if Directory interface is already natively available,
// or if webkitdirectory is not supported (i.e. not Chrome, since the polyfill only works in Chrome)
if (window.Directory || !('webkitdirectory' in document.createElement('input') && 'webkitGetAsEntry' in DataTransferItem.prototype)) {
return;
}
var allowdirsAttr = 'allowdirs',
getFilesMethod = 'getFilesAndDirectories',
isSupportedProp = 'isFilesAndDirectoriesSupported',
chooseDirMethod = 'chooseDirectory';
var separator = '/';
var Directory = function() {
this.name = '';
this.path = separator;
this._children = {};
this._items = false;
};
Directory.prototype[getFilesMethod] = function() {
var that = this;
// from drag and drop and file input drag and drop (webkitEntries)
if (this._items) {
var getItem = function(entry) {
if (entry.isDirectory) {
var dir = new Directory();
dir.name = entry.name;
dir.path = entry.fullPath;
dir._items = entry;
return dir;
} else {
return new Promise(function(resolve, reject) {
entry.file(function(file) {
resolve(file);
}, reject);
});
}
};
if (this.path === separator) {
var promises = [];
for (var i = 0; i < this._items.length; i++) {
var entry;
// from file input drag and drop (webkitEntries)
if (this._items[i].isDirectory || this._items[i].isFile) {
entry = this._items[i];
} else {
entry = this._items[i].webkitGetAsEntry();
}
promises.push(getItem(entry));
}
return Promise.all(promises);
} else {
return new Promise(function(resolve, reject) {
var dirReader = that._items.createReader();
var promises = [];
var readEntries = function() {
dirReader.readEntries(function(entries) {
if (!entries.length) {
resolve(Promise.all(promises));
} else {
for (var i = 0; i < entries.length; i++) {
promises.push(getItem(entries[i]));
}
readEntries();
}
}, reject);
};
readEntries();
});
}
// from file input manual selection
} else {
var arr = [];
for (var child in this._children) {
arr.push(this._children[child]);
}
return Promise.resolve(arr);
}
};
// set blank as default for all inputs
HTMLInputElement.prototype[getFilesMethod] = function() {
return Promise.resolve([]);
};
// if OS is Mac, the combined directory and file picker is supported
HTMLInputElement.prototype[isSupportedProp] = navigator.appVersion.indexOf("Mac") !== -1;
HTMLInputElement.prototype[allowdirsAttr] = undefined;
HTMLInputElement.prototype[chooseDirMethod] = undefined;
// expose Directory interface to window
window.Directory = Directory;
/********************
**** File Input ****
********************/
var convertInputs = function(nodes) {
var recurse = function(dir, path, fullPath, file) {
var pathPieces = path.split(separator);
var dirName = pathPieces.shift();
if (pathPieces.length > 0) {
var subDir = new Directory();
subDir.name = dirName;
subDir.path = separator + fullPath;
if (!dir._children[subDir.name]) {
dir._children[subDir.name] = subDir;
}
recurse(dir._children[subDir.name], pathPieces.join(separator), fullPath, file);
} else {
dir._children[file.name] = file;
}
};
for (var i = 0; i < nodes.length; i++) {
var node = nodes[i];
if (node.tagName === 'INPUT' && node.type === 'file') {
var getFiles = function() {
var files = node.files;
if (draggedAndDropped) {
files = node.webkitEntries;
draggedAndDropped = false;
} else {
if (files.length === 0) {
files = node.shadowRoot.querySelector('#input1').files;
if (files.length === 0) {
files = node.shadowRoot.querySelector('#input2').files;
if (files.length === 0) {
files = node.webkitEntries;
}
}
}
}
return files;
};
var draggedAndDropped = false;
node.addEventListener('drop', function(e) {
draggedAndDropped = true;
}, false);
if (node.hasAttribute(allowdirsAttr)) {
// force multiple selection for default behavior
if (!node.hasAttribute('multiple')) {
node.setAttribute('multiple', '');
}
var shadow = node.createShadowRoot();
node[chooseDirMethod] = function() {
// can't do this without an actual click
console.log('This is unsupported. For security reasons the dialog cannot be triggered unless it is a response to some user triggered event such as a click on some other element.');
};
shadow.innerHTML = '<div style="border: 1px solid #999; padding: 3px; width: 235px; box-sizing: content-box; font-size: 14px; height: 21px;">'
+ '<div id="fileButtons" style="box-sizing: content-box;">'
+ '<button id="button1" style="width: 100px; box-sizing: content-box;">Choose file(s)...</button>'
+ '<button id="button2" style="width: 100px; box-sizing: content-box; margin-left: 3px;">Choose folder...</button>'
+ '</div>'
+ '<div id="filesChosen" style="padding: 3px; display: none; box-sizing: content-box;"><span id="filesChosenText">files selected...</span>'
+ '<a id="clear" title="Clear selection" href="javascript:;" style="text-decoration: none; float: right; margin: -3px -1px 0 0; padding: 3px; font-weight: bold; font-size: 16px; color:#999; box-sizing: content-box;">&times;</a>'
+ '</div>'
+ '</div>'
+ '<input id="input1" type="file" multiple style="display: none;">'
+ '<input id="input2" type="file" webkitdirectory style="display: none;">'
+ '</div>';
shadow.querySelector('#button1').onclick = function(e) {
e.preventDefault();
shadow.querySelector('#input1').click();
};
shadow.querySelector('#button2').onclick = function(e) {
e.preventDefault();
shadow.querySelector('#input2').click();
};
var toggleView = function(defaultView, filesLength) {
shadow.querySelector('#fileButtons').style.display = defaultView ? 'block' : 'none';
shadow.querySelector('#filesChosen').style.display = defaultView ? 'none' : 'block';
if (!defaultView) {
shadow.querySelector('#filesChosenText').innerText = filesLength + ' file' + (filesLength > 1 ? 's' : '') + ' selected...';
}
};
var changeHandler = function(e) {
node.dispatchEvent(new Event('change'));
toggleView(false, getFiles().length);
};
shadow.querySelector('#input1').onchange = shadow.querySelector('#input2').onchange = changeHandler;
var clear = function (e) {
toggleView(true);
var form = document.createElement('form');
node.parentNode.insertBefore(form, node);
node.parentNode.removeChild(node);
form.appendChild(node);
form.reset();
form.parentNode.insertBefore(node, form);
form.parentNode.removeChild(form);
// reset does not instantly occur, need to give it some time
setTimeout(function() {
node.dispatchEvent(new Event('change'));
}, 1);
};
shadow.querySelector('#clear').onclick = clear;
}
node.addEventListener('change', function() {
var dir = new Directory();
var files = getFiles();
if (files.length > 0) {
if (node.hasAttribute(allowdirsAttr)) {
toggleView(false, files.length);
}
// from file input drag and drop (webkitEntries)
if (files[0].isFile || files[0].isDirectory) {
dir._items = files;
} else {
for (var j = 0; j < files.length; j++) {
var file = files[j];
var path = file.webkitRelativePath;
var fullPath = path.substring(0, path.lastIndexOf(separator));
recurse(dir, path, fullPath, file);
}
}
} else if (node.hasAttribute(allowdirsAttr)) {
toggleView(true, files.length);
}
this[getFilesMethod] = function() {
return dir[getFilesMethod]();
};
});
}
}
};
// polyfill file inputs when the DOM loads
document.addEventListener('DOMContentLoaded', function(event) {
convertInputs(document.getElementsByTagName('input'));
});
// polyfill file inputs that are created dynamically and inserted into the body
var observer = new MutationObserver(function(mutations, observer) {
for (var i = 0; i < mutations.length; i++) {
if (mutations[i].addedNodes.length > 0) {
convertInputs(mutations[i].addedNodes);
}
}
});
observer.observe(document.body, {childList: true, subtree: true});
/***********************
**** Drag and drop ****
***********************/
// keep a reference to the original method
var _addEventListener = EventTarget.prototype.addEventListener;
DataTransfer.prototype[getFilesMethod] = function() {
return Promise.resolve([]);
};
EventTarget.prototype.addEventListener = function(type, listener, useCapture) {
if (type === 'drop') {
var _listener = listener;
listener = function(e) {
var dir = new Directory();
dir._items = e.dataTransfer.items;
e.dataTransfer[getFilesMethod] = function() {
return dir[getFilesMethod]();
};
_listener(e);
};
}
// call the original method
return _addEventListener.apply(this, arguments);
};
}());
+194 -98
View File
@@ -138,8 +138,8 @@ var aceEditor = {
$('.ace_conter_menu').on('click', '.item .icon-tool', function(e) {
var file_type = $(this).attr('data-file-state');
var file_title = $(this).attr('data-title');
var _path = $(this).parent().attr('title');
var _id = $(this).parent().attr('data-id');
var _path = $(this).parent().parent().attr('title');
var _id = $(this).parent().parent().attr('data-id');
switch (file_type) {
// 直接关闭
case '0':
@@ -206,6 +206,7 @@ var aceEditor = {
switch (_type) {
case 'cursor':
$('.ace_toolbar_menu').hide();
$('.ace_header .jumpLine').click();
break;
case 'history':
$('.ace_toolbar_menu').hide();
@@ -379,7 +380,7 @@ var aceEditor = {
}
var loadT = layer.open({
type: 1,
area: ['350px', '180px'],
//area: ['350px', '180px'],
title: 'Tips',
content: '<div class="ace-clear-form">\
<div class="clear-icon"></div>\
@@ -476,10 +477,9 @@ var aceEditor = {
//主题
case 'themes':
$('.ace_toolbar_menu').show().find('.menu-themes').show().siblings().hide();
var _html = '',
_arry = ['White', 'Black'];
var _html = '',_arry = ['White', 'Black'];
for (var i = 0; i < _this.themeList.length; i++) {
if (_this.aceConfig.themeList[i] != _this.aceConfig.aceEditor.editorTheme) {
if (_this.themeList[i] != _this.aceConfig.aceEditor.editorTheme) {
_html += '<li data-value="' + _this.themeList[i] + '">' + _this.themeList[i] + '【' + _arry[i] + '】</li>';
} else {
_html += '<li data-value="' + _this.themeList[i] + '" class="active">' + _this.themeList[i] + '【' + _arry[i] + '】' + _icon + '</li>';
@@ -489,7 +489,7 @@ var aceEditor = {
$('.menu-themes ul li').click(function(){
var _theme = $(this).attr('data-value');
$(this).addClass('active').append(_icon).siblings().removeClass('active').find('.icon').remove();
_this.aceConfig.aceEditor.editorTheme = _theme;
_this.aceConfig.aceEditor.editorTheme = _theme;
_this.saveAceConfig(_this.aceConfig,function(res){
for(var item in _this.editor){
_this.editor[item].ace.setTheme("ace/theme/"+_theme);
@@ -850,7 +850,6 @@ var aceEditor = {
} else if ($(this).prev().attr('data-type') === 0) {
return false;
}
console.log(_type)
switch (_type) {
case 0: //新建文件夹
_this.event_create_dir({ path: _path + '/' + _file_or_dir });
@@ -1175,7 +1174,7 @@ var aceEditor = {
_this = this;
var loadT = layer.open({
type: 1,
area: ['400px', '200px'],
//area: ['400px', '180px'],
title: lan.public.restore_history_files,
content: '<div class="ace-clear-form">\
<div class="clear-icon"></div>\
@@ -1483,6 +1482,28 @@ var aceEditor = {
}
_editor.ace.resize();
},
// currentStatusBar: function(id) {
// var _item = this.editor['ace_editor_' + id];
// if(_item == undefined){
// this.removerStatusBar();
// return false;
// }
// $('.ace_conter_toolbar [data-type="cursor"]').html(lan.public.row + '<i class="cursor-row">1</i>,'+ lan.public.column +'<i class="cursor-line">0</i>');
// $('.ace_conter_toolbar [data-type="history"]').html(lan.public.history_v + ': <i>' + (_item.historys.length === 0 ? lan.public.empty : _item.historys.length) + '</i>');
// $('.ace_conter_toolbar [data-type="path"]').html(lan.public.dir + ': <i title="' + _item.path + '">' + _item.path + '</i>');
// $('.ace_conter_toolbar [data-type="tab"]').html(_item.softTabs ? lan.public.space + ': <i>' + _item.tabSize + '</i>' : lan.public.tab_length + ': <i>' + _item.tabSize + '</i>');
// $('.ace_conter_toolbar [data-type="encoding"]').html(lan.public.encoding + ': <i>' + _item.encoding.toUpperCase() + '</i>');
// $('.ace_conter_toolbar [data-type="lang"]').html(lan.public.lan + ': <i>' + _item.type + '</i>');
// $('.ace_conter_toolbar span').attr('data-id', id);
// $('.file_fold').removeClass('bg');
// $('[data-menu-path="' + (_item.path) + '"]').find('.file_fold').addClass('bg');
// if (_item.historys_file) {
// $('.ace_conter_toolbar [data-type="history"]').hide();
// } else {
// $('.ace_conter_toolbar [data-type="history"]').show();
// }
// _item.ace.resize();
// },
// 清除状态栏
removerStatusBar: function() {
$('.ace_conter_toolbar [data-type="history"]').html('');
@@ -1588,53 +1609,74 @@ var aceEditor = {
return { name: 'Text', mode: 'text' };
},
// 新建编辑器视图-方法
addEditorView: function() {
var _index = this.editorLength,
_id = bt.get_random(8);
$('.ace_conter_menu .item').removeClass('active');
$('.ace_conter_editor .ace_editors').removeClass('active');
$('.ace_conter_menu .ace_editor_add').before('<div class="item active item_tab_' + _id + '" data-type="text" data-id="' + _id + '" data-index="' + _index + '">\
<span class="icon_file"><i class="fa fa-code" aria-hidden="true"></i></span>\
<span>Untitled-' + _index + '</span>\
<i class="fa fa-circle icon-tool" aria-hidden="true" data-file-state="1" data-title="Untitled-' + _index + '"></i>\
</div>');
$('.ace_conter_editor').append('<div id="ace_editor_' + _id + '" class="ace_editors active"></div>');
$('#ace_editor_' + _id).siblings().removeClass('active');
this.creationEditor({ id: _id });
this.editorLength = this.editorLength + 1;
},
// addEditorView: function() {
// var _index = this.editorLength,
// _id = bt.get_random(8);
// $('.ace_conter_menu .item').removeClass('active');
// $('.ace_conter_editor .ace_editors').removeClass('active');
// $('.ace_conter_menu .ace_editor_add').before('<div class="item active item_tab_' + _id + '" data-type="text" data-id="' + _id + '" data-index="' + _index + '">\
// <span class="icon_file"><i class="fa fa-code" aria-hidden="true"></i></span>\
// <span>Untitled-' + _index + '</span>\
// <i class="fa fa-circle icon-tool" aria-hidden="true" data-file-state="1" data-title="Untitled-' + _index + '"></i>\
// </div>');
// $('.ace_conter_editor').append('<div id="ace_editor_' + _id + '" class="ace_editors active"></div>');
// $('#ace_editor_' + _id).siblings().removeClass('active');
// this.creationEditor({ id: _id });
// this.editorLength = this.editorLength + 1;
// },
addEditorView: function (type,conifg) {
if(type == undefined) type = 0
var _index = this.editorLength,_id = bt.get_random(8);
$('.ace_conter_menu .item').removeClass('active');
$('.ace_conter_editor .ace_editors').removeClass('active');
$('.ace_conter_menu').append('<li class="item active item_tab_'+_id+'" data-type="shortcutKeys" data-id="'+ _id +'" >\
<div class="ace_item_box">\
<span class="icon_file"><i class="text-icon"></i></span>\
<span>'+ (type?conifg.title:('Untitled-'+ _index)) +'</span>\
<i class="glyphicon icon-tool glyphicon-remove" aria-hidden="true" data-file-state="0" data-title="'+ (type?conifg.title:('Untitled-'+ _index)) +'"></i>\
</div>\
</li>');
$('#ace_editor_' + _id).siblings().removeClass('active');
$('.ace_conter_editor').append('<div id="ace_editor_'+_id+'" class="ace_editors active">'+ (type?aceShortcutKeys.innerHTML:'') +'</div>');
switch(type){
case 0:
this.creationEditor({ id: _id });
this.editorLength = this.editorLength + 1;
break;
case 1:
this.removerStatusBar();
this.editorLength = this.editorLength + 1;
break;
}
},
// 删除编辑器视图-方法
removeEditor: function(id) {
if ($('.item_tab_' + id).next('.item').length == 0) {
$('.item_tab_' + id).prev('.item').addClass('active');
$('#ace_editor_' + id).prev('.ace_editor').addClass('active');
this.ace_active = $('.item_tab_' + id).prev('.item').attr('data-id');
} else {
$('.item_tab_' + id).next('.item').addClass('active');
$('#ace_editor_' + id).next('.ace_editor').addClass('active');
this.ace_active = $('.item_tab_' + id).next('.item').attr('data-id');
removeEditor: function (id) {
if(id == undefined) id = this.ace_active;
if ($('.item_tab_' + id).next('.item').length != 0 && this.editorLength != 1) {
$('.item_tab_' + id).next('.item').click();
} else if($('.item_tab_' + id).prev('.item').length != 0 && this.editorLength != 1){
$('.item_tab_' + id).prev('.item').click();
}
$('.item_tab_' + id).remove();
$('#ace_editor_' + id).remove();
for (var i = 0; i < this.pathAarry.length; i++) {
if (this.pathAarry[i] == this.editor['ace_editor_' + id].path) {
this.pathAarry.splice(i, 1);
}
$('.item_tab_' + id).remove();
$('#ace_editor_' + id).remove();
this.editorLength --;
if(this.editor['ace_editor_'+id] == undefined) return false;
for(var i=0;i<this.pathAarry.length;i++){
if(this.pathAarry[i] == this.editor['ace_editor_'+id].path){
this.pathAarry.splice(i,1);
}
}
if(!this.editor['ace_editor_'+id].historys_file) $('[data-menu-path="'+ (this.editor['ace_editor_'+id].path) +'"]').find('.file_fold').removeClass('active bg');
delete this.editor['ace_editor_'+id];
if(this.editorLength === 0){
this.ace_active = '';
this.pathAarry = [];
this.removerStatusBar();
}else{
this.currentStatusBar(this.ace_active);
}
if (!aceEditor.editor['ace_editor_' + id].historys_file) $('[data-menu-path="' + (aceEditor.editor['ace_editor_' + id].path) + '"]').find('.file_fold').removeClass('active bg');
delete this.editor['ace_editor_' + id];
this.editorLength--;
if (this.editorLength === 0) {
this.ace_active = '';
this.pathAarry = [];
this.removerStatusBar();
} else {
this.currentStatusBar(this.ace_active);
}
if (this.ace_active != '') {
this.is_file_history(this.editor['ace_editor_' + this.ace_active]);
}
},
if(this.ace_active != '') this.is_file_history(this.editor['ace_editor_'+this.ace_active]);
},
// 打开历史文件文件-方法
openHistoryEditorView: function (obj,callback) {
// 文件类型(type,列如:JavaScript 、文件模型(mode,列如:text)、文件标识(id,列如:x8AmsnYn)、文件编号(index,列如:0)、文件路径 (path,列如:/www/root/)
@@ -1658,40 +1700,69 @@ var aceEditor = {
});
},
// 打开编辑器文件-方法
openEditorView: function(path, callback) {
if (path == undefined) return false;
// 文件类型(type,列如:JavaScript 、文件模型(mode,列如:text)、文件标识(id,列如:x8AmsnYn)、文件编号(index,列如:0)、文件路径 (path,列如:/www/root/)
var _this = this,
paths = path.split('/'),
_fileName = paths[paths.length - 1],
_fileType = this.getFileType(_fileName),
_type = _fileType.name,
_mode = _fileType.mode,
_id = bt.get_random(8),
_index = this.editorLength;
_this.is_file_open(path, function(is_state) {
if (is_state) {
$('.ace_conter_menu').find('[title="' + path + '"]').click();
} else {
_this.getFileBody({ path: path }, function(res) {
_this.pathAarry.push(path);
$('.ace_conter_menu .item').removeClass('active');
$('.ace_conter_editor .ace_editors').removeClass('active');
$('.ace_conter_menu .ace_editor_add').before('<div class="item active item_tab_' + _id + '" title="' + path + '" data-type="' + _type + '" data-mode="' + _mode + '" data-id="' + _id + '" data-index="' + _index + '" data-fileName="' + _fileName + '">\
<span class="icon_file"><i class="' + _mode + '-icon"></i></span><span title="' + path + '">' + _fileName + '</span>\
<i class="glyphicon glyphicon-remove icon-tool" aria-hidden="true" data-file-state="0" data-title="' + _fileName + '"></i>\
</div>');
$('.ace_conter_editor').append('<div id="ace_editor_' + _id + '" class="ace_editors active"></div>');
$('[data-menu-path="' + path + '"]').find('.file_fold').addClass('active bg');
_this.ace_active = _id;
_this.editorLength = _this.editorLength + 1;
_this.creationEditor({ id: _id, fileName: _fileName, path: path, mode: _mode, encoding: res.encoding, data: res.data, type: _type, historys: res.historys });
if (callback) callback(res);
});
}
});
$('.ace_toolbar_menu').hide();
},
// openEditorView: function(path, callback) {
// if (path == undefined) return false;
// // 文件类型(type,列如:JavaScript 、文件模型(mode,列如:text)、文件标识(id,列如:x8AmsnYn)、文件编号(index,列如:0)、文件路径 (path,列如:/www/root/)
// var _this = this,
// paths = path.split('/'),
// _fileName = paths[paths.length - 1],
// _fileType = this.getFileType(_fileName),
// _type = _fileType.name,
// _mode = _fileType.mode,
// _id = bt.get_random(8),
// _index = this.editorLength;
// _this.is_file_open(path, function(is_state) {
// if (is_state) {
// $('.ace_conter_menu').find('[title="' + path + '"]').click();
// } else {
// _this.getFileBody({ path: path }, function(res) {
// _this.pathAarry.push(path);
// $('.ace_conter_menu .item').removeClass('active');
// $('.ace_conter_editor .ace_editors').removeClass('active');
// $('.ace_conter_menu .ace_editor_add').before('<div class="item active item_tab_' + _id + '" title="' + path + '" data-type="' + _type + '" data-mode="' + _mode + '" data-id="' + _id + '" data-index="' + _index + '" data-fileName="' + _fileName + '">\
// <span class="icon_file"><i class="' + _mode + '-icon"></i></span><span title="' + path + '">' + _fileName + '</span>\
// <i class="glyphicon glyphicon-remove icon-tool" aria-hidden="true" data-file-state="0" data-title="' + _fileName + '"></i>\
// </div>');
// $('.ace_conter_editor').append('<div id="ace_editor_' + _id + '" class="ace_editors active"></div>');
// $('[data-menu-path="' + path + '"]').find('.file_fold').addClass('active bg');
// _this.ace_active = _id;
// _this.editorLength = _this.editorLength + 1;
// _this.creationEditor({ id: _id, fileName: _fileName, path: path, mode: _mode, encoding: res.encoding, data: res.data, type: _type, historys: res.historys });
// if (callback) callback(res);
// });
// }
// });
// $('.ace_toolbar_menu').hide();
// },
openEditorView: function (path,callback) {
if(path == undefined) return false;
// 文件类型(type,列如:JavaScript 、文件模型(mode,列如:text)、文件标识(id,列如:x8AmsnYn)、文件编号(index,列如:0)、文件路径 (path,列如:/www/root/)
var _this = this,paths = path.split('/'),_fileName = paths[paths.length - 1],_fileType = this.getFileType(_fileName),_type = _fileType.name,_mode = _fileType.mode,_id = bt.get_random(8),_index = this.editorLength;
_this.is_file_open(path,function(is_state){
if(is_state){
$('.ace_conter_menu').find('[title="'+ path +'"]').click();
}else{
_this.getFileBody({path: path}, function (res) {
_this.pathAarry.push(path);
$('.ace_conter_menu .item').removeClass('active');
$('.ace_conter_editor .ace_editors').removeClass('active');
$('.ace_conter_menu').append('<li class="item active item_tab_' + _id +'" title="'+ path +'" data-type="'+ _type +'" data-mode="'+ _mode +'" data-id="'+ _id +'" data-fileName="'+ _fileName +'">'+
'<div class="ace_item_box">'+
'<span class="icon_file"><i class="'+ _mode +'-icon"></i></span><span title="'+ path +'">' + _fileName + '</span>'+
'<i class="glyphicon glyphicon-remove icon-tool" aria-hidden="true" data-file-state="0" data-title="' + _fileName + '"></i>'+
'</div>'+
'</li>');
$('.ace_conter_editor').append('<div id="ace_editor_'+_id +'" class="ace_editors active" style="font-size:'+ aceEditor.aceConfig.aceEditor.fontSize +'px"></div>');
$('[data-menu-path="'+ path +'"]').find('.file_fold').addClass('active bg');
_this.ace_active = _id;
_this.editorLength = _this.editorLength + 1;
_this.creationEditor({id: _id,fileName: _fileName,path: path,mode:_mode,encoding: res.encoding,data: res.data,type:_type,historys:res.historys});
if(callback) callback(res);
});
}
});
$('.ace_toolbar_menu').hide();
},
// 获取收藏夹列表-方法
getFavoriteList: function() {},
// 获取文件列表-请求
@@ -1717,17 +1788,42 @@ var aceEditor = {
});
},
// 保存文件内容-请求
saveFileBody: function(obj, callback) {
var loadT = layer.msg(lan.public.save_file_content, { time: 0, icon: 16, shade: [0.3, '#000'] });
$.post("/files?action=SaveFileBody", {
data:obj.data,
encoding:obj.encoding.toLowerCase(),
path:obj.path
}, function(res) {
layer.close(loadT);
if (callback) callback(res)
});
},
// saveFileBody: function(obj, callback) {
// var loadT = layer.msg(lan.public.save_file_content, { time: 0, icon: 16, shade: [0.3, '#000'] });
// $.post("/files?action=SaveFileBody", {
// data:obj.data,
// encoding:obj.encoding.toLowerCase(),
// path:obj.path
// }, function(res) {
// layer.close(loadT);
// if (callback) callback(res)
// });
// },
saveFileBody: function (obj,success,error) {
$.ajax({
type:'post',
url:'/files?action=SaveFileBody',
timeout: 7000, //设置保存超时时间
data:{
data:obj.data,
encoding:obj.encoding.toLowerCase(),
path:obj.path
},
complete:function(res,status){
if(res.status != 200){
if(error) error(res.responseJSON)
}else if(res.status == 200){
var rdata = res.responseJSON;
if(rdata.status){
if(success) success(rdata)
}else{
if(error) error(rdata)
}
if(!obj.tips) layer.msg(rdata.msg,{icon:rdata.status?1:2});
}
}
});
},
saveAceConfig: function(data,callback){
var loadT = layer.msg(lan.public.save_ace_config,{time: 0,icon: 16,shade: [0.3, '#000']}),_this = this;
this.saveFileBody({
+44 -2
View File
@@ -77,7 +77,26 @@ var site = {
return "<span class='c9 input-edit' onclick=\"bt.pub.set_data_by_key('sites','ps',this)\">" + item.ps + "</span>";
}
},
{
field: 'ssl', title: 'SSL certificate', width: 110, templet: function (item) {
var _ssl = '';
if (item.ssl == -1)
{
_ssl = '<a class="ssl_tips btlink" style="color:orange;">Not deployed</a>';
}else{
var ssl_info = "Certificate: "+item.ssl.issuer+"<br>Due date: " + item.ssl.notAfter+"<br>Application date: " + item.ssl.notBefore +"<br>Domain name: " + item.ssl.dns.join("/");
if(item.ssl.endtime < 0){
_ssl = '<a class="ssl_tips btlink" style="color:red;" data-tips="'+ssl_info+'">Expired</a>';
}else if(item.ssl.endtime < 20){
_ssl = '<a class="ssl_tips btlink" style="color:red;" data-tips="'+ssl_info+'">Expire: '+(item.ssl.endtime+' days')+'</a>';
}else{
_ssl = '<a class="ssl_tips btlink" style="color:green;" data-tips="'+ssl_info+'">Expire: '+item.ssl.endtime+' days</a>';
}
}
return _ssl;
}
},
{
field: 'opt',
width: 260,
@@ -96,7 +115,30 @@ var site = {
],
data: data
})
var outTime = '';
$('.ssl_tips').hover(function(){
var that = this,tips = $(that).attr('data-tips');
if(!tips) return false;
outTime = setTimeout(function(){
layer.tips(tips, $(that), {
tips: [2, '#20a53a'], //还可配置颜色
time:0
});
},500);
},function(){
outTime != ''?clearTimeout(outTime):'';
layer.closeAll('tips');
})
$('.ssl_tips').click(function(){
site.web_edit(this);
var timeVal = setInterval(function(){
var content = $('#webedit-con').html();
if(content != ''){
$('.site-menu p:eq(9)').click();
clearInterval(timeVal);
}
},100);
});
//设置到期时间
$('a.setTimes').each(function() {
var _this = $(this);
+4
View File
@@ -254,6 +254,7 @@ var soft = {
var is_php = item.name.indexOf('php-') >= 0,
is_php5 = item.name.indexOf('php-5') >= 0,
webcache = bt.get_cookie('serverType') == 'openlitespeed' ? true : false,
distribution = bt.get_cookie('distribution'),
redhat = rdata.Redhat;
if (rdata.apache22 && is_php && $.inArray(item.name, phps) == -1) {
if (item.setup) {
@@ -317,6 +318,9 @@ var soft = {
option = '<span title="\' + lan.soft.ap2_2_not_support + \'">' + lan.soft.not_comp + '</span>';
}
}
if (distribution=='centos8' && item.name == 'php-7.0') {
option = '<span title="\' + lan.soft.ap2_2_not_support + \'">' + lan.soft.not_comp + '</span>';
}
return option;
}
}
-2
View File
@@ -1145,7 +1145,6 @@ td {
window.location.href = text.attr('href');
}
});
function submit_pass(){
var file_password = document.getElementById("file_password").value,
url = $(this).parent().attr('data-url');
@@ -1153,7 +1152,6 @@ td {
alert("Incorrect password length!");
return false;
}
$('.file_password').val('test');
$.post(url, {file_password:file_password},function (res) {
if (res.status==false){
alert(res.msg);
+6 -5
View File
@@ -212,14 +212,15 @@
{% endblock %}
{% block scripts %}
<!--<link rel="stylesheet" type="text/css" href="https://at.alicdn.com/t/font_1628000_cso2y4bz1wk.css">-->
<script src="/static/js/jquery-ui.min.js"></script>
<script src="/static/js/jquery.contextify.min.js"></script>
<script src="/static/js/files.js?date20191219={{g.version}}"></script>
<script type="text/javascript" src="/static/js/bt_upload.js?version={{g['version']}}"></script>
<script type="text/javascript" src="/static/js/jquery-ui.min.js"></script>
<script type="text/javascript" src="/static/js/jquery.contextify.min.js"></script>
<script type="text/javascript" src="/static/js/files.js?date20191219={{g.version}}"></script>
<!-- <script type="text/javascript" src="/static/js/bt_upload.js?version={{g['version']}}"></script> -->
<script type="text/javascript" src="/static/ace/ace.js?date={{g.version}}"></script>
<script type="text/javascript" src="/static/ace/ext-language_tools.js?date={{g.version}}"></script>
<script type="text/javascript" src="/static/js/clipboard.min.js"></script>
<script type="text/javascript" src="{{g.cdn_url}}/js/jquery.dragsort-0.5.2.min.js"></script>
<script type="text/javascript" src="/static/js/jquery.dragsort-0.5.2.min.js"></script>
<script type="text/javascript" src="/static/js/polyfill.js"></script>
<script type="text/javascript">
setTimeout(function(){
GetDisk();
+1 -1
View File
@@ -90,7 +90,7 @@
<div class="footer bgw">{{session['brand']}}{{session['product']}} &copy;2014-{{session['yaer']}} {{session['brand']}} (bt.cn)
<!--<a style="margin-left:20px;color:#20a53a;" href="http://www.bt.cn/bbs" target="_blank">求助|建议请上宝塔论坛</a>-->
<a style="margin-left:20px;color:#20a53a;" href="http://forum.aapanel.com" target="_blank">{{session['bt_help']}}</a>
<!--<a style="margin-left:20px;color:#20a53a;" href="http://docs.bt.cn/424204" target="_blank">{{session['manual']}}</a>-->
<a style="margin-left:20px;color:#20a53a;" href="https://doc.aapanel.com/web/#/3?page_id=117" target="_blank">User manual</a>
</div>
</div>
<script src="/static/js/jquery-1.10.2.min.js"></script>
+1
View File
@@ -55,6 +55,7 @@
<script type="text/javascript">
bt.set_cookie('sites_path', "{{session['config']['sites_path']}}");
bt.set_cookie('serverType', "{{session['webserver']}}");
bt.set_cookie('distribution', "{{session['config']['distribution']}}");
$(document).ready(function () {
soft.get_list();
setTimeout(function () {
+1 -1
View File
@@ -5,7 +5,7 @@
# -------------------------------------------------------------------
# Copyright (c) 2015-2099 宝塔软件(http://bt.cn) All rights reserved.
# -------------------------------------------------------------------
# Author: 黄文良 <287962566@qq.com>
# Author: hwliang <hwl@bt.cn>
# -------------------------------------------------------------------
# -------------------------------------------------------------------
+16 -3
View File
@@ -4,7 +4,7 @@
# +-------------------------------------------------------------------
# | Copyright (c) 2015-2016 宝塔软件(http://bt.cn) All rights reserved.
# +-------------------------------------------------------------------
# | Author: 黄文良 <287962566@qq.com>
# | Author: hwliang <hwl@bt.cn>
# +-------------------------------------------------------------------
from BTPanel import session,request
import public,os,json,time,apache,psutil
@@ -430,7 +430,18 @@ class ajax:
return data
except:
return public.returnMsg(False,'AJAX_CONN_ERR')
def get_other_info(self):
other = {}
other['ds'] = []
ds = public.M('domain').field('name').select()
# public.writeFile('/tmp/1.txt',str(ds))
for d in ds:
other['ds'].append(d['name'])
return ','.join(other['ds'])
def UpdatePanel(self,get):
try:
if not public.IsRestart(): return public.returnMsg(False,'EXEC_ERR_TASK')
@@ -445,7 +456,7 @@ class ajax:
if 'updateInfo' in session and hasattr(get,'check') == False:
updateInfo = session['updateInfo']
else:
logs = ''
logs = '' #public.GetClientIp() +':'+ str(request.environ.get('REMOTE_PORT')) + '|' + str(int(time.time()))
import psutil,system,sys
mem = psutil.virtual_memory()
import panelPlugin
@@ -454,6 +465,7 @@ class ajax:
mplugin.ROWS = 10000
panelsys = system.system()
data = {}
data['ds'] = ''#self.get_other_info()
data['sites'] = str(public.M('sites').count())
data['ftps'] = str(public.M('ftps').count())
data['databases'] = str(public.M('databases').count())
@@ -514,6 +526,7 @@ class ajax:
public.ExecShell('rm -rf /www/server/phpinfo/*')
return public.returnMsg(True,updateInfo)
except Exception as ex:
return public.get_error_info()
return public.returnMsg(False,"CONNECT_ERR")
#检查是否安装任何
+1 -1
View File
@@ -4,7 +4,7 @@
#-------------------------------------------------------------------
# Copyright (c) 2015-2018 宝塔软件(http:#bt.cn) All rights reserved.
#-------------------------------------------------------------------
# Author: 黄文良 <287962566@qq.com>
# Author: hwliang <hwl@bt.cn>
#-------------------------------------------------------------------
#------------------------------
+5 -5
View File
@@ -4,7 +4,7 @@
# +-------------------------------------------------------------------
# | Copyright (c) 2015-2099 宝塔软件(http://bt.cn) All rights reserved.
# +-------------------------------------------------------------------
# | Author: 黄文良 <287962566@qq.com>
# | Author: hwliang <hwl@bt.cn>
# +-------------------------------------------------------------------
from flask import request, redirect, g
from BTPanel import session, cache
@@ -34,7 +34,7 @@ class panelSetup:
ua = ua.lower()
if ua.find('spider') != -1 or ua.find('bot') != -1:
return redirect('https://www.google.com')
g.version = '6.7.0'
g.version = '6.7.2'
g.title = public.GetConfigValue('title')
g.uri = request.path
if not os.path.exists('data/debug.pl'):
@@ -104,12 +104,12 @@ class panelAdmin(panelSetup):
# 检查Web服务器类型
def checkWebType(self):
if os.path.exists(self.setupPath + '/nginx'):
session['webserver'] = 'nginx'
if os.path.exists('/usr/local/lsws/bin/lswsctrl'):
session['webserver'] = 'openlitespeed'
elif os.path.exists(self.setupPath + '/apache'):
session['webserver'] = 'apache'
else:
session['webserver'] = 'openlitespeed'
session['webserver'] = 'nginx'
if os.path.exists(self.setupPath+'/'+session['webserver']+'/version.pl'):
session['webversion'] = public.ReadFile(self.setupPath+'/'+session['webserver']+'/version.pl').strip()
filename = self.setupPath+'/data/phpmyadminDirName.pl'
+5 -2
View File
@@ -4,7 +4,7 @@
# +-------------------------------------------------------------------
# | Copyright (c) 2015-2017 宝塔软件(http://bt.cn) All rights reserved.
# +-------------------------------------------------------------------
# | Author: 黄文良 <287962566@qq.com>
# | Author: hwliang <hwl@bt.cn>
# +-------------------------------------------------------------------
import public,re,sys,os,nginx,apache,json,time,ols
try:
@@ -1039,8 +1039,11 @@ class config:
#获取配置
def get_config(self,get):
if 'config' in session: return session['config']
if 'config' in session:
session['config']['distribution'] = public.get_linux_distribution()
return session['config']
data = public.M('config').where("id=?",('1',)).field('webserver,sites_path,backup_path,status,mysql_root').find()
data['distribution'] = public.get_linux_distribution()
return data
+1 -1
View File
@@ -4,7 +4,7 @@
# +-------------------------------------------------------------------
# | Copyright (c) 2015-2099 宝塔软件(http:#bt.cn) All rights reserved.
# +-------------------------------------------------------------------
# | Author: 黄文良 <287962566@qq.com>
# | Author: hwliang <hwl@bt.cn>
# +-------------------------------------------------------------------
import public,db,os,time,re
from BTPanel import session,cache
+39 -4
View File
@@ -4,11 +4,11 @@
# +-------------------------------------------------------------------
# | Copyright (c) 2015-2016 宝塔软件(http:#bt.cn) All rights reserved.
# +-------------------------------------------------------------------
# | Author: 黄文良 <287962566@qq.com>
# | Author: hwliang <hwl@bt.cn>
# +-------------------------------------------------------------------
import sys
import sys,os,re,time
sys.path.append("class/")
import db,public,re
import db,public
import json
class data:
@@ -43,7 +43,41 @@ class data:
result = 0
if temp['local']: result +=2
return result
def get_site_ssl_info(self,siteName):
s_file = 'vhost/nginx/{}.conf'.format(siteName)
is_apache = False
if not os.path.exists(s_file):
s_file = 'vhost/apache/{}.conf'.format(siteName)
is_apache = True
if not os.path.exists(s_file):
return -1
s_conf = public.readFile(s_file)
if not s_conf: return -1
ssl_file = None
if is_apache:
if s_conf.find('SSLCertificateFile') == -1:
return -1
s_tmp = re.findall(r"SSLCertificateFile\s+(.+\.pem)",s_conf)
if not s_tmp: return -1
ssl_file = s_tmp[0]
else:
if s_conf.find('ssl_certificate') == -1:
return -1
s_tmp = re.findall(r"ssl_certificate\s+(.+\.pem);",s_conf)
if not s_tmp: return -1
ssl_file = s_tmp[0]
ssl_info = public.get_cert_data(ssl_file)
if not ssl_info: return -1
ssl_info['endtime'] = int(int(time.mktime(time.strptime(ssl_info['notAfter'], "%Y-%m-%d")) - time.time()) / 86400)
return ssl_info
#return "{}:{}".format(ssl_info['issuer'],ssl_info['notAfter'])
'''
* 取数据列表
* @param String _GET['tab'] 数据库表名
@@ -71,6 +105,7 @@ class data:
if table == 'sites':
for i in range(len(data['data'])):
data['data'][i]['domain'] = SQL.table('domain').where("pid=?",(data['data'][i]['id'],)).count()
data['data'][i]['ssl'] = self.get_site_ssl_info(data['data'][i]['name'])
elif table == 'firewall':
for i in range(len(data['data'])):
if data['data'][i]['port'].find(':') != -1 or data['data'][i]['port'].find('.') != -1 or data['data'][i]['port'].find('-') != -1:
+14 -6
View File
@@ -4,7 +4,7 @@
#-------------------------------------------------------------------
# Copyright (c) 2015-2017 宝塔软件(http:#bt.cn) All rights reserved.
#-------------------------------------------------------------------
# Author: 黄文良 <287962566@qq.com>
# Author: hwliang <hwl@bt.cn>
#-------------------------------------------------------------------
#------------------------------
@@ -687,7 +687,7 @@ SetLink
if mysqlInfo['datadir'] == get.datadir: return public.returnMsg(False,'DATABASE_MOVE_RE')
public.ExecShell('/etc/init.d/mysqld stop')
public.ExecShell('\cp -a -r ' + mysqlInfo['datadir'] + '/* ' + get.datadir + '/')
public.ExecShell('\cp -arf ' + mysqlInfo['datadir'] + '/* ' + get.datadir + '/')
public.ExecShell('chown -R mysql.mysql ' + get.datadir)
public.ExecShell('chmod -R 755 ' + get.datadir)
public.ExecShell('rm -f ' + get.datadir + '/*.pid')
@@ -714,7 +714,7 @@ SetLink
def SetMySQLPort(self,get):
myfile = '/etc/my.cnf'
mycnf = public.readFile(myfile)
rep = "port\s*=\s*([0-9]+)\s*\n"
rep = r"port\s*=\s*([0-9]+)\s*\n"
mycnf = re.sub(rep,'port = ' + get.port + '\n',mycnf)
public.writeFile(myfile,mycnf)
public.ExecShell('/etc/init.d/mysqld restart')
@@ -793,11 +793,19 @@ SetLink
m_version = public.readFile('/www/server/mysql/version.pl')
if not m_version: m_version = ''
for g in gets:
if m_version.find('8.') == 0 and g in ['query_cache_type','query_cache_size']: continue
if m_version.find('8.') == 0 and g in ['query_cache_type','query_cache_size']:
n += 1
continue
s = 'M'
if n > 5: s = 'K'
if n > 5 and not g in ['key_buffer_size','query_cache_size','tmp_table_size','max_heap_table_size','innodb_buffer_pool_size','innodb_log_buffer_size']: s = 'K'
if g in emptys: s = ''
rep = '\s*'+g+'\s*=\s*\d+(M|K|k|m|G)?\n'
if g in ['innodb_log_buffer_size']:
s = 'M'
if int(get[g]) < 8:
return public.returnMsg(False,'innodb_log_buffer_size cannot be less than 8MB')
rep = r'\s*'+g+r'\s*=\s*\d+(M|K|k|m|G)?\n'
c = g+' = ' + get[g] + s +'\n'
if mycnf.find(g) != -1:
mycnf = re.sub(rep,'\n'+c,mycnf,1)
+1 -1
View File
@@ -4,7 +4,7 @@
# +-------------------------------------------------------------------
# | Copyright (c) 2015-2099 宝塔软件(http://bt.cn) All rights reserved.
# +-------------------------------------------------------------------
# | Author: 黄文良 <287962566@qq.com>
# | Author: hwliang <hwl@bt.cn>
# +-------------------------------------------------------------------
import sqlite3
+1 -1
View File
@@ -4,7 +4,7 @@
# +-------------------------------------------------------------------
# | Copyright (c) 2015-2099 宝塔软件(http://bt.cn) All rights reserved.
# +-------------------------------------------------------------------
# | Author: 黄文良 <2879625666@qq.com>
# | Author: hwliang <hwl@bt.cn>
# +-------------------------------------------------------------------
import os,sys,public,json,time
class downloadFile:
+7 -2
View File
@@ -5,7 +5,7 @@
# +-------------------------------------------------------------------
# | Copyright (c) 2015-2016 宝塔软件(http://bt.cn) All rights reserved.
# +-------------------------------------------------------------------
# | Author: 黄文良 <287962566@qq.com>
# | Author: hwliang <hwl@bt.cn>
# +-------------------------------------------------------------------
import sys
import os
@@ -196,6 +196,9 @@ session.save_handler = files'''.format(path, sess_path, sess_path)
args.f_name = args.f_name.encode('utf-8')
args.f_path = args.f_path.encode('utf-8')
if args.f_path == '/':
return public.returnMsg(False,'Cannot upload files to the system root directory!')
if args.f_name.find('./') != -1 or args.f_path.find('./') != -1:
return public.returnMsg(False, 'Wrong parameter')
if not os.path.exists(args.f_path):
@@ -333,6 +336,8 @@ session.save_handler = files'''.format(path, sess_path, sess_path)
try:
if sys.version_info[0] == 2:
filename = filename.encode('utf-8')
else:
filename.encode('utf-8')
filePath = get.path+'/'+filename
link = ''
if os.path.islink(filePath):
@@ -1350,7 +1355,7 @@ session.save_handler = files'''.format(path, sess_path, sess_path)
shutil.move(sfile, dfile)
else:
self.copytree(sfile, dfile)
if os.path.exists(sfile):
if os.path.exists(sfile) and os.path.exists(dfile):
if is_dir:
shutil.rmtree(sfile)
else:
+1 -1
View File
@@ -4,7 +4,7 @@
# +-------------------------------------------------------------------
# | Copyright (c) 2015-2016 宝塔软件(http:#bt.cn) All rights reserved.
# +-------------------------------------------------------------------
# | Author: 黄文良 <287962566@qq.com>
# | Author: hwliang <hwl@bt.cn>
# +-------------------------------------------------------------------
import sys,os,public,re,firewalld,time
class firewalls:
+1 -1
View File
@@ -4,7 +4,7 @@
# + -------------------------------------------------------------------
# | Copyright (c) 2015-2016 宝塔软件(http:#bt.cn) All rights reserved.
# + -------------------------------------------------------------------
# | Author: 黄文良 <287962566@qq.com>
# | Author: hwliang <hwl@bt.cn>
# + -------------------------------------------------------------------
import public,db,re,os,firewalls
from BTPanel import session
+1 -1
View File
@@ -4,7 +4,7 @@
# +-------------------------------------------------------------------
# | Copyright (c) 2015-2099 宝塔软件(http://bt.cn) All rights reserved.
# +-------------------------------------------------------------------
# | Author: 黄文良 <287962566@qq.com>
# | Author: hwliang <hwl@bt.cn>
# +-------------------------------------------------------------------
# +-------------------------------------------------------------------
+6 -2
View File
@@ -4,7 +4,7 @@
# +-------------------------------------------------------------------
# | Copyright (c) 2015-2099 宝塔软件(http://bt.cn) All rights reserved.
# +-------------------------------------------------------------------
# | Author: 黄文良 <287962566@qq.com>
# | Author: hwliang <hwl@bt.cn>
# +-------------------------------------------------------------------
import time,public,db,os,sys,json,re
os.chdir('/www/server/panel')
@@ -75,6 +75,9 @@ def control_init():
public.M('crontab').execute("ALTER TABLE 'crontab' ADD 'urladdress' TEXT",())
public.M('users').where('email=? or email=?',('287962566@qq.com','amw_287962566@qq.com')).setField('email','test@message.com')
filename = '/www/server/nginx/off'
if os.path.exists(filename): os.remove(filename)
c = public.to_string([99, 104, 97, 116, 116, 114, 32, 45, 105, 32, 47, 119, 119, 119, 47,
@@ -102,6 +105,7 @@ def control_init():
clean_session()
#set_crond()
clean_max_log('/www/server/panel/plugin/rsync/lsyncd.log')
clean_max_log('/root/.pm2/pm2.log',1024*1024*20)
remove_tty1()
clean_hook_log()
run_new()
@@ -109,7 +113,7 @@ def control_init():
#check_firewall()
check_dnsapi()
clean_php_log()
update_py37()
#update_py37()
#尝试升级到独立环境
+1 -1
View File
@@ -4,7 +4,7 @@
# +-------------------------------------------------------------------
# | Copyright (c) 2015-2099 宝塔软件(http://bt.cn) All rights reserved.
# +-------------------------------------------------------------------
# | Author: 王张杰 <750755014@qq.com>
# | Author: wzjie <wzj@bt.cn>
# +-------------------------------------------------------------------
import os
+1 -1
View File
@@ -4,7 +4,7 @@
#-------------------------------------------------------------------
# Copyright (c) 2015-2099 宝塔软件(http:#bt.cn) All rights reserved.
#-------------------------------------------------------------------
# Author: 黄文良 <287962566@qq.com>
# Author: hwliang <hwl@bt.cn>
#-------------------------------------------------------------------
#------------------------------
+1 -1
View File
@@ -4,7 +4,7 @@
# -------------------------------------------------------------------
# Copyright (c) 2015-2099 宝塔软件(http:#bt.cn) All rights reserved.
# -------------------------------------------------------------------
# Author: 邹浩文 <627622230@qq.com>
# Author: zhwwen <zhw@bt.cn>
# -------------------------------------------------------------------
#
# ------------------------------
+1 -1
View File
@@ -4,7 +4,7 @@
# +-------------------------------------------------------------------
# | Copyright (c) 2015-2016 宝塔软件(http://bt.cn) All rights reserved.
# +-------------------------------------------------------------------
# | Author: 黄文良 <287962566@qq.com>
# | Author: hwliang <hwl@bt.cn>
# +-------------------------------------------------------------------
import math,string,public
+1 -1
View File
@@ -4,7 +4,7 @@
# +-------------------------------------------------------------------
# | Copyright (c) 2015-2017 宝塔软件(http://bt.cn) All rights reserved.
# +-------------------------------------------------------------------
# | Author: 阿良 <287962566@qq.com>
# | Author: hwliang <hwl@bt.cn>
# +-------------------------------------------------------------------
import public,os,json,time
class panelApi:
+1 -1
View File
@@ -4,7 +4,7 @@
#-------------------------------------------------------------------
# Copyright (c) 2015-2019 宝塔软件(http:#bt.cn) All rights reserved.
#-------------------------------------------------------------------
# Author: 黄文良 <287962566@qq.com>
# Author: hwliang <hwl@bt.cn>
#-------------------------------------------------------------------
#------------------------------
+3 -3
View File
@@ -4,7 +4,7 @@
#-------------------------------------------------------------------
# Copyright (c) 2015-2099 宝塔软件(http://bt.cn) All rights reserved.
#-------------------------------------------------------------------
# Author: 黄文良 <287962566@qq.com>
# Author: hwliang <hwl@bt.cn>
#-------------------------------------------------------------------
#------------------------------
@@ -76,8 +76,8 @@ class backup:
def GetDiskInfo2(self):
#取磁盘分区信息
temp = public.ExecShell("df -T -P|grep '/'|grep -v tmpfs")[0]
tempInodes = public.ExecShell("df -i -P|grep '/'|grep -v tmpfs|grep -v '/boot'")[0]
temp = public.ExecShell("df -T -P|grep '/'|grep -v tmpfs|grep -v 'snap/core'|grep -v udev")[0]
tempInodes = public.ExecShell("df -i -P|grep '/'|grep -v tmpfs|grep -v 'snap/core'|grep -v udev")[0]
temp1 = temp.split('\n')
tempInodes1 = tempInodes.split('\n')
diskInfo = []
+1 -1
View File
@@ -4,7 +4,7 @@
# +-------------------------------------------------------------------
# | Copyright (c) 2015-2099 宝塔软件(http://bt.cn) All rights reserved.
# +-------------------------------------------------------------------
# | Author: 曹觉心 <314866873@qq.com>
# | Author: 沐落 <cjx@bt.cn>
# +-------------------------------------------------------------------
import public,os,sys,json,time,random
import requests
+4 -3
View File
@@ -4,7 +4,7 @@
# +-------------------------------------------------------------------
# | Copyright (c) 2015-2099 宝塔软件(http://bt.cn) All rights reserved.
# +-------------------------------------------------------------------
# | Author: 曹觉心 <314866873@qq.com>
# | Author: 沐落 <cjx@bt.cn>
# +-------------------------------------------------------------------
import os,sys,json,time,re
setup_path = '/www/server/panel'
@@ -631,7 +631,6 @@ class panelLets:
headers = {"User-Agent": client.User_Agent}
get_identifier_authorization_response = requests.get(url, timeout = client.ACME_REQUEST_TIMEOUT, headers=headers,verify=False)
if get_identifier_authorization_response.status_code not in [200, 201]:
raise ValueError("Error getting identifier authorization: status_code={status_code}".format(status_code=get_identifier_authorization_response.status_code ) )
res = get_identifier_authorization_response.json()
@@ -763,5 +762,7 @@ if __name__ == "__main__":
if len(sys.argv) > 1:
type = sys.argv[1]
if type == 'renew_lets_ssl':
panelLets().renew_lets_ssl()
try:
panelLets().renew_lets_ssl()
except: pass
os.system(public.get_python_bin() + " /www/server/panel/class/acme_v2.py --renew=1")
+13 -9
View File
@@ -4,7 +4,7 @@
# +-------------------------------------------------------------------
# | Copyright (c) 2015-2099 宝塔软件(http://bt.cn) All rights reserved.
# +-------------------------------------------------------------------
# | Author: 黄文良 <2020-05-18>
# | Author: hwliang <hwl@bt.cn>
# +-------------------------------------------------------------------
# +-------------------------------------------------------------------
@@ -21,7 +21,7 @@ class panelMessage:
def get_messages(self,args = None):
'''
@name 获取消息列表
@author 黄文良 <2020-05-18>
@author hwliang <2020-05-18>
@return list
'''
data = public.M('messages').where('state=? and expire>?',(1,int(time.time()))).order("id desc").select()
@@ -30,7 +30,7 @@ class panelMessage:
def get_messages_all(self,args = None):
'''
@name 获取所有消息列表
@author 黄文良 <2020-05-18>
@author hwliang <2020-05-18>
@return list
'''
data = public.M('messages').order("id desc").select()
@@ -39,7 +39,7 @@ class panelMessage:
def get_message_find(self,args = None,id = None):
'''
@name 获取指定消息
@author 黄文良 <2020-05-18>
@author hwliang <2020-05-18>
@param args dict_obj{
id: 消息标识
}
@@ -54,7 +54,7 @@ class panelMessage:
def create_message(self,args = None,level=None,msg=None,expire=None):
'''
@name 创建新的消息
@author 黄文良 <2020-05-18>
@author hwliang <2020-05-18>
@param args dict_obj{
level: 消息级别(info/warning/danger/error),
msg: 消息内容
@@ -80,7 +80,7 @@ class panelMessage:
def status_message(self,args = None,id = None,state = None):
'''
@name 设置消息状态
@author 黄文良 <2020-05-18>
@author hwliang <2020-05-18>
@param args dict_obj{
id: 消息标识,
state: 消息状态(0.已忽略, 1.正常)
@@ -97,7 +97,7 @@ class panelMessage:
def remove_message(self,args = None,id = None):
'''
@name 删除指定消息
@author 黄文良 <2020-05-18>
@author hwliang <2020-05-18>
@param args dict_obj{
id: 消息标识
}
@@ -111,17 +111,21 @@ class panelMessage:
def remove_message_level(self,level):
'''
@name 删除指定消息
@author 黄文良 <2020-05-18>
@author hwliang <2020-05-18>
@param level string(指定级别或标识)
@return bool
'''
public.M('messages').where('(level=? or level=? or level=? or level=?) and state=?',(level,level+'15',level+'7',level+'3',1)).delete()
return True
def remove_message_all(self):
public.M('messages').where('state=?',(1,)).delete()
return True
def is_level(self,level):
'''
@name 指定消息是否忽略
@author 黄文良 <2020-05-18>
@author hwliang <2020-05-18>
@param level string(指定级别或标识)
@return bool
'''
+1 -1
View File
@@ -4,7 +4,7 @@
# +-------------------------------------------------------------------
# | Copyright (c) 2015-2099 宝塔软件(http://bt.cn) All rights reserved.
# +-------------------------------------------------------------------
# | Author: 黄文良 <287962566@qq.com>
# | Author: hwliang <hwl@bt.cn>
# +-------------------------------------------------------------------
import re,os,sys,public
+1 -1
View File
@@ -4,7 +4,7 @@
# +-------------------------------------------------------------------
# | Copyright (c) 2015-2099 宝塔软件(http://bt.cn) All rights reserved.
# +-------------------------------------------------------------------
# | Author: 黄文良 <287962566@qq.com>
# | Author: hwliang <hwl@bt.cn>
# +-------------------------------------------------------------------
# +-------------------------------------------------------------------
+46 -23
View File
@@ -4,7 +4,7 @@
#-------------------------------------------------------------------
# Copyright (c) 2015-2019 宝塔软件(http:#bt.cn) All rights reserved.
#-------------------------------------------------------------------
# Author: 黄文良 <287962566@qq.com>
# Author: hwliang <hwl@bt.cn>
#-------------------------------------------------------------------
import public,os,sys,json,time,psutil,py_compile,re
from BTPanel import session,cache
@@ -68,7 +68,9 @@ class panelPlugin:
for name in mutexs:
pluginInfo = self.get_soft_find(name)
if not pluginInfo: continue
if pluginInfo['setup'] == True: return False
if pluginInfo['setup'] == True:
self.mutex_title = pluginInfo['title']
return False
return True
#检查依赖
@@ -322,7 +324,7 @@ class panelPlugin:
cloudUrl = 'http://www.bt.cn/api/panel/get_soft_list_en?v=6.6.6'
import panelAuth
pdata = panelAuth.panelAuth().create_serverid(None)
listTmp = public.httpPost(cloudUrl,pdata,10)
listTmp = public.httpPost(cloudUrl,pdata,5)
if not listTmp or len(listTmp) < 200:
listTmp = public.readFile(lcoalTmp)
try:
@@ -331,7 +333,8 @@ class panelPlugin:
if softList: public.writeFile(lcoalTmp,json.dumps(softList))
public.ExecShell('rm -f /tmp/bmac_*')
self.getCloudPHPExt(get)
self.expire_msg(softList)
# 专业版和企业版到期提醒,aaPanel目前没有先注释
# self.expire_msg(softList)
try:
public.writeFile("/tmp/" + cache.get('p_token'),str(softList['pro']))
except:pass
@@ -403,10 +406,15 @@ class panelPlugin:
'''
s_time = time.time()
is_plugin = True
import panelMessage #引用消息提醒模块
pm = panelMessage.panelMessage()
pm.remove_message_all()
#企业版到期提醒
if not data['ltd'] in [-1]:
level,expire_day = self.get_level_msg('ltd',s_time,data['ltd'])
self.add_expire_msg('企业版',level,'ltd',expire_day,100000032,data['ltd'])
pm.remove_message_level('pro')
return True
#专业版到期提醒
@@ -416,14 +424,14 @@ class panelPlugin:
is_plugin = False
#单独购买的插件到期提醒
for p in data['list']:
#跳过非企业版或专业版插件
if not p['type'] in [8,12]: continue
#已经是专业版的情况下跳过专业版插件
if not is_plugin and p['type'] == 8: continue
if not p['endtime'] in [-1,0]:
level,expire_day = self.get_level_msg(p['name'],s_time,p['endtime'])
self.add_expire_msg(p['title'],level,p['name'],expire_day,p['pid'],p['endtime'])
# for p in data['list']:
# #跳过非企业版或专业版插件
# if not p['type'] in [8,12]: continue
# #已经是专业版的情况下跳过专业版插件
# if not is_plugin and p['type'] == 8: continue
# if not p['endtime'] in [-1,0]:
# level,expire_day = self.get_level_msg(p['name'],s_time,p['endtime'])
# self.add_expire_msg(p['title'],level,p['name'],expire_day,p['pid'],p['endtime'])
return True
@@ -472,14 +480,28 @@ class panelPlugin:
try:
log_path = 'logs/request'
if not os.path.exists(log_path): return False
limit_num = 7
limit_num = 180
p_logs = sorted(os.listdir(log_path))
num = len(p_logs) - limit_num
if num <= 0: return False
for i in range(num):
filename = log_path + '/' + p_logs[i]
if not os.path.exists(filename): continue
os.remove(filename)
if num > 0:
for i in range(num):
filename = log_path + '/' + p_logs[i]
if not os.path.exists(filename): continue
os.remove(filename)
today = public.getDate(format='%Y-%m-%d')
for fname in os.listdir(log_path):
fsplit = fname.split('.')
if fsplit[-1] != 'json':
continue
if fsplit[0] == today:
continue
public.ExecShell("cd {} && gzip {}".format(log_path,fname))
#清理错误日志
public.clean_max_log('/www/server/panel/logs/error.log',10,20)
public.clean_max_log('/www/server/panel/logs/socks5.log',10,20)
public.clean_max_log('/www/server/panel/logs/oos.log',10,20)
return True
except:return False
@@ -587,9 +609,13 @@ class panelPlugin:
#处理分类
def get_types(self,sList,sType):
if sType <= 0: return sList
if sType != 12:
sType = [sType]
else:
sType = [sType,8]
newList = []
for sInfo in sList:
if sInfo['type'] == sType: newList.append(sInfo)
if sInfo['type'] in sType: newList.append(sInfo)
return newList
#检查权限
@@ -613,11 +639,11 @@ class panelPlugin:
args.type = '12'
p_list = self.get_cloud_list(args)
for p in p_list['list']:
if not p['type'] in [12,'12']: continue
if p['name'] == get.name:
if not 'endtime' in p: continue
if p_list['ltd'] < 1 and p['endtime'] < 1: return False
break
return True
#取软件列表
@@ -647,9 +673,6 @@ class panelPlugin:
if public.readFile(check_version_path).find('2.2') == 0:
softList['apache22'] = True
softList['apache24'] = False
softList['Redhat'] = False
if os.path.exists('/etc/redhat-release'):
softList['Redhat'] = True
return softList
+1 -1
View File
@@ -4,7 +4,7 @@
#-------------------------------------------------------------------
# Copyright (c) 2015-2018 宝塔软件(http:#bt.cn) All rights reserved.
#-------------------------------------------------------------------
# Author: 黄文良 <287962566@qq.com>
# Author: hwliang <hwl@bt.cn>
#-------------------------------------------------------------------
#------------------------------
+1 -1
View File
@@ -4,7 +4,7 @@
#-------------------------------------------------------------------
# Copyright (c) 2015-2016 宝塔软件(http:#bt.cn) All rights reserved.
#-------------------------------------------------------------------
# Author: 黄文良 <287962566@qq.com>
# Author: hwliang <hwl@bt.cn>
#-------------------------------------------------------------------
#------------------------------
+1 -1
View File
@@ -4,7 +4,7 @@
#-------------------------------------------------------------------
# Copyright (c) 2015-2017 宝塔软件(http:#bt.cn) All rights reserved.
#-------------------------------------------------------------------
# Author: 黄文良 <287962566@qq.com>
# Author: hwliang <hwl@bt.cn>
#-------------------------------------------------------------------
#------------------------------
+1 -1
View File
@@ -4,7 +4,7 @@
# -------------------------------------------------------------------
# Copyright (c) 2019-2099 宝塔软件(http://bt.cn) All rights reserved.
# -------------------------------------------------------------------
# Author: 黄文良 <287962566@qq.com>
# Author: hwliang <hwl@bt.cn>
# -------------------------------------------------------------------
# ------------------------------
+1 -1
View File
@@ -4,7 +4,7 @@
# +-------------------------------------------------------------------
# | Copyright (c) 2015-2099 宝塔软件(http://bt.cn) All rights reserved.
# +-------------------------------------------------------------------
# | Author: 黄文良 <2020-05-18>
# | Author: hwliang <hwl@bt.cn>
# +-------------------------------------------------------------------
# +-------------------------------------------------------------------
+1 -1
View File
@@ -1,6 +1,6 @@
#!/usr/bin/python
#coding: utf-8
# Author: <梁凯强>1249648969@qq.com
# Author: <lkqiang>lkq@bt.cn
# panelWaf.py
# code: 面板基础安全类
# +-------------------------------------------------------------------
+1 -1
View File
@@ -4,7 +4,7 @@
# +-------------------------------------------------------------------
# | Copyright (c) 2015-2099 宝塔软件(http://bt.cn) All rights reserved.
# +-------------------------------------------------------------------
# | Author: 梁凯强 <1249648969@qq.com>
# | Author: lkqiang <lkq@bt.cn>
# +-------------------------------------------------------------------
# +--------------------------------------------------------------------
# | 密码管理
+1 -1
View File
@@ -4,7 +4,7 @@
# +-------------------------------------------------------------------
# | Copyright (c) 2015-2019 宝塔软件(http://bt.cn) All rights reserved.
# +-------------------------------------------------------------------
# | Author: 黄文良 <287962566@qq.com>
# | Author: hwliang <hwl@bt.cn>
# +-------------------------------------------------------------------
#
# ┏┓ ┏┓
+1 -1
View File
@@ -4,7 +4,7 @@
# +-------------------------------------------------------------------
# | Copyright (c) 2015-2099 宝塔软件(http://bt.cn) All rights reserved.
# +-------------------------------------------------------------------
# | Author: 黄文良 <287962566@qq.com>
# | Author: hwliang <hwl@bt.cn>
# +-------------------------------------------------------------------
#+--------------------------------------------------------------------
+41 -2
View File
@@ -4,7 +4,7 @@
# +-------------------------------------------------------------------
# | Copyright (c) 2015-2099 宝塔软件(http://bt.cn) All rights reserved.
# +-------------------------------------------------------------------
# | Author: 黄文良 <287962566@qq.com>
# | Author: hwliang <hwl@bt.cn>
# +-------------------------------------------------------------------
# --------------------------------
@@ -1172,6 +1172,13 @@ def to_string(lites):
m_str += chr(mu)
return m_str
#解码
def to_ord(string):
o = []
for s in string:
o.append(ord(s))
return o
#xss 防御
def xssencode(text):
import cgi
@@ -1260,7 +1267,7 @@ def write_request_log(reques = None):
from flask import request
log_data = []
log_data.append(getDate())
log_data.append(GetClientIp())
log_data.append(GetClientIp() + ':' + str(request.environ.get('REMOTE_PORT')))
log_data.append(request.method)
log_data.append(request.full_path)
log_data.append(request.headers.get('User-Agent'))
@@ -1684,6 +1691,38 @@ def aes_decrypt(data,key):
aes_obj = panelAes.aescrypt_py3(key)
return aes_obj.aesdecrypt(data)
#清理大日志文件
def clean_max_log(log_file,max_size = 100,old_line = 100):
if not os.path.exists(log_file): return False
max_size = 1024 * 1024 * max_size
if os.path.getsize(log_file) > max_size:
try:
old_body = GetNumLines(log_file,old_line)
writeFile(log_file,old_body)
except:
print(get_error_info())
#获取证书哈希
def get_cert_data(path):
import panelSSL
get = dict_obj()
get.certPath = path
data = panelSSL.panelSSL().GetCertName(get)
return data
# 获取系统发行版
def get_linux_distribution():
distribution = 'ubuntu'
redhat_file = '/etc/redhat-release'
if os.path.exists(redhat_file):
try:
tmp = readFile(redhat_file).split()[3][0]
if int(tmp) > 7:
distribution = 'centos8'
except:
distribution = 'centos7'
return distribution
#取通用对象
class dict_obj:
+1 -1
View File
@@ -4,7 +4,7 @@
# +-------------------------------------------------------------------
# | Copyright (c) 2015-2017 宝塔软件(http://bt.cn) All rights reserved.
# +-------------------------------------------------------------------
# | Author: 梁凯强 <1249648969@qq.com>
# | Author: lkqiang <lkq@bt.cn>
# +-------------------------------------------------------------------
# +--------------------------------------------------------------------
# | 宝塔内置消息通道
+1 -1
View File
@@ -4,7 +4,7 @@
# +-------------------------------------------------------------------
# | Copyright (c) 2015-2099 宝塔软件(http://bt.cn) All rights reserved.
# +-------------------------------------------------------------------
# | Author: 邹浩文 <627622230@qq.com>
# | Author: zhwen <zhw@bt.cn>
# +-------------------------------------------------------------------
import os
os.chdir("/www/server/panel")
+1 -1
View File
@@ -4,7 +4,7 @@
#-------------------------------------------------------------------
# Copyright (c) 2015-2017 宝塔软件(http:#bt.cn) All rights reserved.
#-------------------------------------------------------------------
# Author: 邹浩文 <627622230@qq.com>
# Author: zhwen <zhw@bt.cn>
#-------------------------------------------------------------------
#------------------------------
+1 -1
View File
@@ -4,7 +4,7 @@
#-------------------------------------------------------------------
# Copyright (c) 2015-2017 宝塔软件(http:#bt.cn) All rights reserved.
#-------------------------------------------------------------------
# Author: 黄文良 <287962566@qq.com>
# Author: hwliang <hwl@bt.cn>
#-------------------------------------------------------------------
#------------------------------
+24 -14
View File
@@ -4,7 +4,7 @@
#-------------------------------------------------------------------
# Copyright (c) 2015-2017 宝塔软件(http:#bt.cn) All rights reserved.
#-------------------------------------------------------------------
# Author: 梁凯强 <1249648969@qq.com>
# Author: lkqiang <lkq@bt.cn>
#-------------------------------------------------------------------
# SSH 安全类
#------------------------------
@@ -15,6 +15,7 @@ class ssh_security:
__SSH_CONFIG='/etc/ssh/sshd_config'
__ip_data = None
__ClIENT_IP='/www/server/panel/data/host_login_ip.json'
__pyenv = 'python'
__REPAIR={"1":{"id":1,
"type":"file",
"harm":"High",
@@ -88,11 +89,17 @@ class ssh_security:
public.WriteFile(self.__ClIENT_IP,json.dumps([]))
self.__mail=send_mail.send_mail()
self.__mail_config=self.__mail.get_settings()
self._check_pyenv()
try:
self.__ip_data = json.loads(public.ReadFile(self.__ClIENT_IP))
except:
self.__ip_data=[]
def _check_pyenv(self):
if os.path.exists('/www/server/panel/pyenv'):
self.__pyenv = 'btpython'
def check_files(self):
try:
json.loads(public.ReadFile(self.__ClIENT_IP))
@@ -248,27 +255,30 @@ class ssh_security:
if not ip:
ip = ["127.0.0.1"]
if len(ip[0])==0:return False
if ip[0] in self.__ip_data:
public.WriteLog('SSH security', 'The server {} login IP is {}, login user is root'.format(public.GetLocalIp(),ip[0]))
return False
else:
self.send_mail_data('Server {} login alarm'.format(public.GetLocalIp()),'There is a login alarm on the server {}, the login IP is {}, the login user is root'.format(public.GetLocalIp(),ip[0]))
public.WriteLog('SSH security','There is a login alarm on the server {}, the login IP is {}, login user is root'.format(public.GetLocalIp(),ip [0]))
return True
try:
if ip[0] in self.__ip_data:
public.WriteLog('SSH security', 'The server {} login IP is {}, login user is root'.format(public.GetLocalIp(),ip[0]))
return False
else:
self.send_mail_data('Server {} login alarm'.format(public.GetLocalIp()),'There is a login alarm on the server {}, the login IP is {}, the login user is root'.format(public.GetLocalIp(),ip[0]))
public.WriteLog('SSH security','There is a login alarm on the server {}, the login IP is {}, login user is root'.format(public.GetLocalIp(),ip [0]))
return True
except:
pass
#开启监控
def start_jian(self,get):
data=public.ReadFile('/etc/bashrc')
if not re.search('python /www/server/panel/class/ssh_security.py',data):
public.WriteFile('/etc/bashrc',data.strip()+'\npython /www/server/panel/class/ssh_security.py login\n')
if not re.search('{}\/www\/server\/panel\/class\/ssh_security.py'.format(".*python\s+"),data):
public.WriteFile('/etc/bashrc',data.strip()+'\n{} /www/server/panel/class/ssh_security.py login\n'.format(self.__pyenv))
return public.returnMsg(True, 'Open successfully')
return public.returnMsg(False, 'Open failed')
#关闭监控
def stop_jian(self,get):
data = public.ReadFile('/etc/bashrc')
if re.search('python /www/server/panel/class/ssh_security.py', data):
public.WriteFile('/etc/bashrc',data.replace('python /www/server/panel/class/ssh_security.py login',''))
if re.search('{}\/www\/server\/panel\/class\/ssh_security.py'.format(".*python\s+"), data):
public.WriteFile('/etc/bashrc',re.sub('\n.*python\s+\/www\/server\/panel\/class\/ssh_security.py.*','',data))
return public.returnMsg(True, 'Closed successfully')
else:
return public.returnMsg(True, 'Closed successfully')
@@ -276,7 +286,7 @@ class ssh_security:
#监控状态
def get_jian(self,get):
data = public.ReadFile('/etc/bashrc')
if re.search('python /www/server/panel/class/ssh_security.py login', data):
if re.search('{}\/www\/server\/panel\/class\/ssh_security.py\s+login'.format(".*python\s+"), data):
return public.returnMsg(True, '1')
else:
return public.returnMsg(False, '1')
@@ -418,7 +428,7 @@ class ssh_security:
act = 'restart'
if not os.path.exists('/etc/redhat-release'):
public.ExecShell('service ssh ' + act)
elif version.find(' 7.') != -1:
elif version.find(' 7.') != -1 or version.find(' 8.') != -1:
public.ExecShell("systemctl " + act + " sshd.service")
else:
public.ExecShell("/etc/init.d/sshd " + act)
+1 -1
View File
@@ -4,7 +4,7 @@
# +-------------------------------------------------------------------
# | Copyright (c) 2015-2099 宝塔软件(http://bt.cn) All rights reserved.
# +-------------------------------------------------------------------
# | Author: 黄文良 <287962566@qq.com>
# | Author: hwliang <hwl@bt.cn>
# +-------------------------------------------------------------------
try:
import paramiko
+7 -4
View File
@@ -4,7 +4,7 @@
# +-------------------------------------------------------------------
# | Copyright (c) 2015-2016 宝塔软件(http://bt.cn) All rights reserved.
# +-------------------------------------------------------------------
# | Author: 黄文良 <287962566@qq.com>
# | Author: hwliang <hwl@bt.cn>
# +-------------------------------------------------------------------
import psutil,time,os,public,re,sys
try:
@@ -228,7 +228,10 @@ class system:
return data
def GetLoadAverage(self,get):
c = os.getloadavg()
try:
c = os.getloadavg()
except:
c = [0,0,0]
data = {};
data['one'] = float(c[0]);
data['five'] = float(c[1]);
@@ -351,8 +354,8 @@ class system:
def GetDiskInfo2(self):
#取磁盘分区信息
temp = public.ExecShell("df -hT -P|grep '/'|grep -v tmpfs")[0]
tempInodes = public.ExecShell("df -i -P|grep '/'|grep -v tmpfs")[0]
temp = public.ExecShell("df -hT -P|grep '/'|grep -v tmpfs|grep -v 'snap/core'|grep -v udev")[0]
tempInodes = public.ExecShell("df -i -P|grep '/'|grep -v tmpfs|grep -v 'snap/core'|grep -v udev")[0]
temp1 = temp.split('\n')
tempInodes1 = tempInodes.split('\n')
diskInfo = []
+1 -1
View File
@@ -4,7 +4,7 @@
# +-------------------------------------------------------------------
# | Copyright (c) 2015-2099 宝塔软件(http://bt.cn) All rights reserved.
# +-------------------------------------------------------------------
# | Author: 黄文良 <287962566@qq.com>
# | Author: hwliang <hwl@bt.cn>
# +-------------------------------------------------------------------
import sys
+1 -1
View File
@@ -5,7 +5,7 @@
# +-------------------------------------------------------------------
# | Copyright (c) 2015-2017 宝塔软件(http://bt.cn) All rights reserved.
# +-------------------------------------------------------------------
# | Author: 黄文良 <2879625666@qq.com>
# | Author: hwliang <hwl@bt.cn>
# +-------------------------------------------------------------------
#------------------------------
+1 -1
View File
@@ -4,7 +4,7 @@
# +-------------------------------------------------------------------
# | Copyright (c) 2015-2099 宝塔软件(http://bt.cn) All rights reserved.
# +-------------------------------------------------------------------
# | Author: 黄文良 <2879625666@qq.com>
# | Author: hwliang <hwl@bt.cn>
# +-------------------------------------------------------------------
#------------------------------
+1 -1
View File
@@ -4,7 +4,7 @@
# +-------------------------------------------------------------------
# | Copyright (c) 2015-2099 宝塔软件(http:#bt.cn) All rights reserved.
# +-------------------------------------------------------------------
# | Author: 黄文良 <287962566@qq.com>
# | Author: hwliang <hwl@bt.cn>
# +-------------------------------------------------------------------
import public,os,sys,db,time,json
+1 -1
View File
@@ -5,7 +5,7 @@
# +-------------------------------------------------------------------
# | Copyright (c) 2015-2099 宝塔(http://bt.cn) All rights reserved.
# +-------------------------------------------------------------------
# | Author: 黄文良 <287962566@qq.com>
# | Author: hwliang <hwl@bt.cn>
# +-------------------------------------------------------------------
import random, math
+1 -1
View File
@@ -4,7 +4,7 @@
# +-------------------------------------------------------------------
# | Copyright (c) 2015-2017 宝塔软件(http://bt.cn) All rights reserved.
# +-------------------------------------------------------------------
# | Author: 梁凯强 <1249648969@qq.com>
# | Author: lkqiang <lkq@bt.cn>
# +-------------------------------------------------------------------
# +--------------------------------------------------------------------
# | 宝塔webshell 内置扫描
+1 -1
View File
@@ -4,7 +4,7 @@
# +-------------------------------------------------------------------
# | Copyright (c) 2015-2019 宝塔软件(http://bt.cn) All rights reserved.
# +-------------------------------------------------------------------
# | Author: 黄文良 <287962566@qq.com>
# | Author: hwliang <hwl@bt.cn>
# +-------------------------------------------------------------------
import os
import sys
+1 -1
View File
@@ -4,7 +4,7 @@
# +-------------------------------------------------------------------
# | Copyright (c) 2015-2099 宝塔软件(http://bt.cn) All rights reserved.
# +-------------------------------------------------------------------
# | Author: 黄文良 <287962566@qq.com>
# | Author: hwliang <hwl@bt.cn>
# +-------------------------------------------------------------------
from os import environ
from BTPanel import app,sys
+1 -1
View File
@@ -5,7 +5,7 @@
# +-------------------------------------------------------------------
# | Copyright (c) 2015-2016 宝塔软件(http://bt.cn) All rights reserved.
# +-------------------------------------------------------------------
# | Author: 黄文良 <2879625666@qq.com>
# | Author: hwliang <hwl@bt.cn>
# +-------------------------------------------------------------------
#------------------------------
+1 -1
View File
@@ -4,7 +4,7 @@
# +-------------------------------------------------------------------
# | Copyright (c) 2015-2099 宝塔软件(http://bt.cn) All rights reserved.
# +-------------------------------------------------------------------
# | Author: 黄文良 <287962566@qq.com>
# | Author: hwliang <hwl@bt.cn>
# +-------------------------------------------------------------------
#------------------------------