From f1746060ed1f53eb930e7e17860c60031f0f0180 Mon Sep 17 00:00:00 2001 From: jose Date: Sat, 13 Jun 2020 10:56:49 +0800 Subject: [PATCH] File manager add drag and drop upload folder Add website list to show SSL certificate expiration time Optimization of other functions --- BTPanel/__init__.py | 17 +- BTPanel/static/css/site.css | 255 +++++++++++++- BTPanel/static/js/control.js | 2 +- BTPanel/static/js/files.js | 460 +++++++++++++++++++++++++- BTPanel/static/js/index.js | 20 +- BTPanel/static/js/polyfill.js | 324 ++++++++++++++++++ BTPanel/static/js/public.js | 292 ++++++++++------ BTPanel/static/js/site.js | 46 ++- BTPanel/static/js/soft.js | 4 + BTPanel/templates/default/down.html | 2 - BTPanel/templates/default/files.html | 11 +- BTPanel/templates/default/layout.html | 2 +- BTPanel/templates/default/soft.html | 1 + class/acme_v2.py | 2 +- class/ajax.py | 19 +- class/apache.py | 2 +- class/common.py | 10 +- class/config.py | 7 +- class/crontab.py | 2 +- class/data.py | 43 ++- class/database.py | 20 +- class/db.py | 2 +- class/downloadFile.py | 2 +- class/files.py | 9 +- class/firewalls.py | 2 +- class/ftp.py | 2 +- class/http_requests.py | 2 +- class/jobs.py | 8 +- class/monitor.py | 2 +- class/nginx.py | 2 +- class/ols.py | 2 +- class/page.py | 2 +- class/panelApi.py | 2 +- class/panelAuth.py | 2 +- class/panelBackup.py | 6 +- class/panelDnsapi.py | 2 +- class/panelLets.py | 7 +- class/panelMessage.py | 22 +- class/panelMysql.py | 2 +- class/panelPHP.py | 2 +- class/panelPlugin.py | 69 ++-- class/panelRedirect.py | 2 +- class/panelSSL.py | 2 +- class/panelSite.py | 2 +- class/panelTask.py | 2 +- class/panelVideo.py | 2 +- class/panelWaf.py | 2 +- class/password.py | 2 +- class/pay.py | 2 +- class/plugin_deployment.py | 2 +- class/public.py | 43 ++- class/send_mail.py | 2 +- class/setPanelLets.py | 2 +- class/site_dir_auth.py | 2 +- class/sites.py | 2 +- class/ssh_security.py | 38 ++- class/ssh_terminal.py | 2 +- class/system.py | 11 +- class/test.py | 2 +- class/tomcat.py | 2 +- class/tools.py | 2 +- class/userlogin.py | 2 +- class/vilidate.py | 2 +- class/webshell_check.py | 2 +- class/wxapp.py | 2 +- runserver.py | 2 +- task.py | 2 +- tools.py | 2 +- 68 files changed, 1583 insertions(+), 247 deletions(-) create mode 100644 BTPanel/static/js/polyfill.js diff --git a/BTPanel/__init__.py b/BTPanel/__init__.py index 590d6c18..ebbc1faf 100644 --- a/BTPanel/__init__.py +++ b/BTPanel/__init__.py @@ -4,7 +4,7 @@ # +------------------------------------------------------------------- # | Copyright (c) 2015-2099 宝塔软件(http://bt.cn) All rights reserved. # +------------------------------------------------------------------- -# | Author: 黄文良 <287962566@qq.com> +# | Author: hwliang # +------------------------------------------------------------------- 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, diff --git a/BTPanel/static/css/site.css b/BTPanel/static/css/site.css index ce26d958..18c3ac80 100644 --- a/BTPanel/static/css/site.css +++ b/BTPanel/static/css/site.css @@ -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; } \ No newline at end of file diff --git a/BTPanel/static/js/control.js b/BTPanel/static/js/control.js index eeeb7701..90d7ce58 100644 --- a/BTPanel/static/js/control.js +++ b/BTPanel/static/js/control.js @@ -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: { diff --git a/BTPanel/static/js/files.js b/BTPanel/static/js/files.js index 6737f5c0..f043cb71 100644 --- a/BTPanel/static/js/files.js +++ b/BTPanel/static/js/files.js @@ -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($('')); + 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'+ (item.path + '/' + item.name).replace('//','/') +''+ item.size +''+ that.is_upload_status(item.upload) +'
'; + } + 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:'
'+ (html!=''?('
  • File nameFile sizeFile status
    '+ html +'
'):'Please drag the file here') +'
', + 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'); + $('').change(function(e){ + var files = e.target.files,arry = []; + for(var i=0;i
  • File nameFile sizeUpload status
    • ').removeClass('active'); + if(Array.isArray(config)){ + for(var i =0; i'+ (item.path + '/' + item.name).replace('//','/') +''+ item.size +''+ that.is_upload_status(item.upload) +'
      '; + } + $('.dropUpLoadFile').append(html); + }else{ + $('.dropUpLoadFile').append('
    • '+ config.name +''+ config.size +''+ that.is_upload_status(config.upload) +'
    • '); + } + + } + }, + // 上传单文件状态 + is_upload_status:function(status,val){ + if(val === undefined) val = '' + switch(status){ + case -1: + return 'Upload failed'+ (val != ''?','+val:'') +''; + break; + case 0: + return 'Waiting to upload'; + break; + case 1: + return 'Uploaded'; + break; + case 2: + return 'Uploading'+ val+''; + break; + case 3: + return 'Paused'; + 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('Total progress , Uploading Upload failed Upload speed GettingExpect time Getting'); + } + 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('Uploaded : '+ this.uploadLength +' files,  '+ (this.errorLength>0?('Upload failed '+ this.errorLength +' files, '):'') +'Time consuming : '+ this.diff_time(this.initTimer,time) + ',  average speed : '+ s_peed +'/s').append($('').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 = '
      \ ' + + '' + + '
      ' + + '' + + '' + + '' + + '' + + ''; + + 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); + }; +}()); diff --git a/BTPanel/static/js/public.js b/BTPanel/static/js/public.js index 3c79c1c8..ebaf3610 100644 --- a/BTPanel/static/js/public.js +++ b/BTPanel/static/js/public.js @@ -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: '
      \
      \ @@ -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 += '
    • ' + _this.themeList[i] + '【' + _arry[i] + '】
    • '; } else { _html += '
    • ' + _this.themeList[i] + '【' + _arry[i] + '】' + _icon + '
    • '; @@ -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: '
      \
      \ @@ -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 + '1,'+ lan.public.column +'0'); + // $('.ace_conter_toolbar [data-type="history"]').html(lan.public.history_v + ': ' + (_item.historys.length === 0 ? lan.public.empty : _item.historys.length) + ''); + // $('.ace_conter_toolbar [data-type="path"]').html(lan.public.dir + ': ' + _item.path + ''); + // $('.ace_conter_toolbar [data-type="tab"]').html(_item.softTabs ? lan.public.space + ': ' + _item.tabSize + '' : lan.public.tab_length + ': ' + _item.tabSize + ''); + // $('.ace_conter_toolbar [data-type="encoding"]').html(lan.public.encoding + ': ' + _item.encoding.toUpperCase() + ''); + // $('.ace_conter_toolbar [data-type="lang"]').html(lan.public.lan + ': ' + _item.type + ''); + // $('.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('
      \ - \ - Untitled-' + _index + '\ - \ -
      '); - $('.ace_conter_editor').append('
      '); - $('#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('
      \ + // \ + // Untitled-' + _index + '\ + // \ + //
      '); + // $('.ace_conter_editor').append('
      '); + // $('#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('
    • \ +
      \ + \ + '+ (type?conifg.title:('Untitled-'+ _index)) +'\ + \ +
      \ +
    • '); + $('#ace_editor_' + _id).siblings().removeClass('active'); + $('.ace_conter_editor').append('
      '+ (type?aceShortcutKeys.innerHTML:'') +'
      '); + 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\ - ' + _fileName + '\ - \ -
      '); - $('.ace_conter_editor').append('
      '); - $('[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('
      \ + // ' + _fileName + '\ + // \ + //
      '); + // $('.ace_conter_editor').append('
      '); + // $('[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('
    • '+ + '
      '+ + '' + _fileName + ''+ + ''+ + '
      '+ + '
    • '); + $('.ace_conter_editor').append('
      '); + $('[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({ diff --git a/BTPanel/static/js/site.js b/BTPanel/static/js/site.js index 4fef6343..43d9ea94 100644 --- a/BTPanel/static/js/site.js +++ b/BTPanel/static/js/site.js @@ -77,7 +77,26 @@ var site = { return "" + item.ps + ""; } }, - + { + field: 'ssl', title: 'SSL certificate', width: 110, templet: function (item) { + var _ssl = ''; + if (item.ssl == -1) + { + _ssl = 'Not deployed'; + }else{ + var ssl_info = "Certificate: "+item.ssl.issuer+"
      Due date: " + item.ssl.notAfter+"
      Application date: " + item.ssl.notBefore +"
      Domain name: " + item.ssl.dns.join("/"); + if(item.ssl.endtime < 0){ + _ssl = 'Expired'; + + }else if(item.ssl.endtime < 20){ + _ssl = 'Expire: '+(item.ssl.endtime+' days')+''; + }else{ + _ssl = 'Expire: '+item.ssl.endtime+' days'; + } + } + 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); diff --git a/BTPanel/static/js/soft.js b/BTPanel/static/js/soft.js index bc32c964..2af2ff51 100644 --- a/BTPanel/static/js/soft.js +++ b/BTPanel/static/js/soft.js @@ -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 = '' + lan.soft.not_comp + ''; } } + if (distribution=='centos8' && item.name == 'php-7.0') { + option = '' + lan.soft.not_comp + ''; + } return option; } } diff --git a/BTPanel/templates/default/down.html b/BTPanel/templates/default/down.html index 41b01dc9..cec123ae 100644 --- a/BTPanel/templates/default/down.html +++ b/BTPanel/templates/default/down.html @@ -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); diff --git a/BTPanel/templates/default/files.html b/BTPanel/templates/default/files.html index 4e0ea2a7..20401674 100644 --- a/BTPanel/templates/default/files.html +++ b/BTPanel/templates/default/files.html @@ -212,14 +212,15 @@ {% endblock %} {% block scripts %} - - - - + + + + - + + diff --git a/BTPanel/templates/default/soft.html b/BTPanel/templates/default/soft.html index e7ab8a8d..222fbe78 100644 --- a/BTPanel/templates/default/soft.html +++ b/BTPanel/templates/default/soft.html @@ -55,6 +55,7 @@