From ce7bd5d106f883121ad18ba7c6fea7191cb1372d Mon Sep 17 00:00:00 2001 From: jose Date: Sat, 30 May 2020 10:30:36 +0800 Subject: [PATCH] File management adds video playback File sharing adds directory sharing and video playback functions Optimize file sharing UI Publish system firewall plugin Release Amazon storage plugin Other details adjustment --- BTPanel/__init__.py | 174 +++- BTPanel/static/css/site.css | 41 +- BTPanel/static/js/files.js | 121 ++- BTPanel/static/js/public.js | 2 +- BTPanel/static/js/soft.js | 2 +- BTPanel/templates/default/down.html | 1256 ++++++++++++++++++++++++++- BTPanel/templates/default/lan.js | 1042 ---------------------- class/ajax.py | 29 +- class/common.py | 2 +- class/db.py | 8 +- class/files.py | 41 +- class/jobs.py | 12 + class/panelBackup.py | 17 +- class/panelMessage.py | 134 +++ class/panelPlugin.py | 90 +- class/panelSite.py | 2 + class/panelVideo.py | 68 ++ class/panelWaf.py | 190 +--- class/php_info.php | 2 +- class/public.py | 21 +- class/setPanelLets.py | 4 +- 21 files changed, 1916 insertions(+), 1342 deletions(-) delete mode 100644 BTPanel/templates/default/lan.js create mode 100644 class/panelMessage.py create mode 100644 class/panelVideo.py diff --git a/BTPanel/__init__.py b/BTPanel/__init__.py index c3976ebf..590d6c18 100644 --- a/BTPanel/__init__.py +++ b/BTPanel/__init__.py @@ -144,7 +144,9 @@ admin_path_checks = [ '/panel', '/acme', '/down', - '/api' + '/api', + '/tips', + '/message' ] if admin_path in admin_path_checks: admin_path = '/bt' @@ -210,7 +212,7 @@ def reload_mod(): @app.before_request def request_check(): - if not public.path_safe_check(request.path): return abort(404) + #if not public.path_safe_check(request.path): return abort(404) if request.path in ['/service_status']: return if not request.path in ['/safe','/hook','/public','/mail_sys','/down']: @@ -218,7 +220,7 @@ def request_check(): if ip_check: return ip_check if request.path.find('/static/') != -1 or request.path == '/code': - if not 'login' in session and not 'admin_auth' in session: + if not 'login' in session and not 'admin_auth' in session and not 'down' in session: session.clear() return abort(401) domain_check = public.check_domain_panel() @@ -272,6 +274,11 @@ def close(): data['lan'] = public.getLan('close') return render_template('close.html',data=data) +@app.route('/tips',methods=method_get) +def tips(): + return render_template('tips.html') + + route_path = os.path.join(admin_path,'') if route_path[-1] == '/': route_path = route_path[:-1] if route_path[0] != '/': route_path = '/' + route_path @@ -395,7 +402,7 @@ def FtpPort(): try: file = public.GetConfigValue('setup_path')+'/pure-ftpd/etc/pure-ftpd.conf' conf = public.readFile(file) - rep = "\n#?\s*Bind\s+[0-9]+\.[0-9]+\.[0-9]+\.+[0-9]+,([0-9]+)" + rep = r"\n#?\s*Bind\s+[0-9]+\.[0-9]+\.[0-9]+\.+[0-9]+,([0-9]+)" port = re.search(rep,conf).groups()[0] except: port='21' @@ -466,6 +473,15 @@ def acme(pdata = None): 'get_auths','auth_domain','check_auth_status','download_cert','apply_cert','renew_cert','apply_cert_api','apply_dns_auth') return publicObject(acme_v2_object,defs,None,pdata) +@app.route('/message/',methods=method_all) +def message(action = None): + comReturn = comm.local() + if comReturn: return comReturn + import panelMessage + message_object = panelMessage.panelMessage() + defs = ('get_messages','get_message_find','create_message','status_message','remove_message','get_messages_all') + return publicObject(message_object,defs,action,None) + @app.route('/api',methods=method_all) def api(pdata = None): comReturn = comm.local() @@ -520,8 +536,8 @@ def ssh_security(pdata = None): return render_template( 'firewall.html',data=data) import ssh_security firewallObject = ssh_security.ssh_security() - defs = ('get_logs','san_ssh_security','set_password','set_sshkey','stop_key','get_config', - 'stop_password','get_key','return_ip','add_return_ip','del_return_ip','start_jian','stop_jian','get_jian') + defs = ('san_ssh_security','set_password','set_sshkey','stop_key','get_config', + 'stop_password','get_key','return_ip','add_return_ip','del_return_ip','start_jian','stop_jian','get_jian','get_logs') return publicObject(firewallObject,defs,None,pdata) @@ -612,7 +628,7 @@ def files(pdata = None): 'CheckExistsFiles','GetExecLog','GetSearch','ExecShell','GetExecShellMsg','exec_git','exec_composer','create_download_url', 'UploadFile','GetDir','CreateFile','CreateDir','DeleteDir','DeleteFile','get_download_url_list','remove_download_url','modify_download_url', 'CopyFile','CopyDir','MvFile','GetFileBody','SaveFileBody','Zip','UnZip','get_download_url_find', - 'SearchFiles','upload','read_history','re_history','auto_save_temp','get_auto_save_body', + 'SearchFiles','upload','read_history','re_history','auto_save_temp','get_auto_save_body','get_videos', 'GetFileAccess','SetFileAccess','GetDirSize','SetBatchData','BatchPaste','install_rar','get_path_size', 'DownloadFile','GetTaskSpeed','CloseLogs','InstallSoft','UninstallSoft','SaveTmpFile','get_composer_version','exec_composer','update_composer', 'GetTmpFile','del_files_store','add_files_store','get_files_store','del_files_store_types','add_files_store_types','exec_git', @@ -807,6 +823,13 @@ def plugin(pdata = None): @app.route('/public',methods=method_all) def panel_public(): get = get_input() + try: + import panelWaf + panelWaf_data = panelWaf.panelWaf() + if panelWaf_data.is_sql(get.__dict__):return 'ERROR' + if panelWaf_data.is_xss(get.__dict__):return 'ERROR' + except: + pass get.client_ip = public.GetClientIp() if not hasattr(get,'name'): get.name = '' if not hasattr(get,'fun'): return abort(404) @@ -1064,50 +1087,109 @@ def download(): if filename in ['alioss','qiniu','upyun','txcos','ftp']: return panel_cloud() if filename in ['gdrive','gcloud_storage']: return "Google storage products do not currently support downloads" if not os.path.exists(filename): return public.ReturnJson(False,"FILE_NOT_EXISTS"),json_header - mimetype = "application/octet-stream" - extName = filename.split('.')[-1] - if extName in ['png','gif','jpeg','jpg']: mimetype = None - return send_file(filename,mimetype=mimetype, - as_attachment=True, - attachment_filename=os.path.basename(filename), - cache_timeout=0) -@app.route('/down/',methods=method_all) -def down(token=None,mdown=None): - try: - if not token: return abort(404) - if len(token) != 12: return abort(404) - if not re.match(r"^\w+$",token): return abort(404) - find = public.M('download_token').where('token=?',(token,)).find() - if not find: return abort(404) - if time.time() > int(find['expire']): return abort(404) - if not os.path.exists(find['filename']): return abort(404) - if find['password']: - args = get_input() - if 'file_password' in args: - if not re.match(r"^\w+$",args.file_password): - return public.ReturnJson(False,'wrong password!'),json_header - if not args.file_password == find['password']: - return public.ReturnJson(False,'wrong password!'),json_header - else: - pdata = { - "password":True, - "filename":find['filename'].split('/')[-1], - "total":find['total'], - "token":find['token'], - "expire":find['expire'] - } - return render_template('down.html',data = pdata) - - filename = find['filename'] + if request.args.get('play') == 'true': + import panelVideo + start, end = panelVideo.get_range(request) + return panelVideo.partial_response(filename, start, end) + else: mimetype = "application/octet-stream" extName = filename.split('.')[-1] if extName in ['png','gif','jpeg','jpg']: mimetype = None return send_file(filename,mimetype=mimetype, - as_attachment=True, - attachment_filename=os.path.basename(filename), - cache_timeout=0) - except: return abort(404) + as_attachment=True, + attachment_filename=os.path.basename(filename), + cache_timeout=0) + +def get_dir_down(filename,token,find): + import files + args = public.dict_obj() + args.path = filename + to_path = filename.replace(find['filename'],'').strip('/') + + if request.args.get('play') == 'true': + pdata = files.files().get_videos(args) + return public.GetJson(pdata),json_header + else: + pdata = files.files().GetDir(args) + pdata['token'] = token + pdata['src_path'] = find['filename'] + pdata['to_path'] = to_path + pdata['expire'] = public.format_date(times=find['expire']) + pdata['filename'] = (find['filename'].split('/')[-1] + '/' + to_path).strip('/') + return render_template('down.html',data = pdata,to_size=public.to_size) + +@app.route('/down/',methods=method_all) +def down(token=None,fname=None): + try: + fname = request.args.get('fname') + if fname: + if(len(fname) > 256): return abort(404) + if fname: fname = fname.strip('/') + if not token: return abort(404) + if len(token) != 12: return abort(404) + if not request.args.get('play') in ['true',None,'']: + return abort(404) + + if not re.match(r"^\w+$",token): return abort(404) + find = public.M('download_token').where('token=?',(token,)).find() + + if not find: return abort(404) + if time.time() > int(find['expire']): return abort(404) + + if not os.path.exists(find['filename']): return abort(404) + if find['password'] and not token in session: + args = get_input() + if 'file_password' in args: + if not re.match(r"^\w+$",args.file_password): + return public.ReturnJson(False,'Wrong password!'),json_header + if re.match(r"^\d+$",args.file_password): + args.file_password += '.0' + if args.file_password != str(find['password']): + return public.ReturnJson(False,'Wrong password!'),json_header + session[token] = 1 + session['down'] = True + else: + pdata = { + "to_path":"", + "src_path": find['filename'], + "password":True, + "filename":find['filename'].split('/')[-1], + "total":find['total'], + "token":find['token'], + "expire":public.format_date(times=find['expire']) + } + return render_template('down.html',data = pdata) + if not find['password']: + session[token] = 1 + + if session[token] != 1: + return abort(404) + + filename = find['filename'] + if fname: + filename = os.path.join(filename,fname) + if not public.path_safe_check(fname,False): return abort(404) + if os.path.isdir(filename): + return get_dir_down(filename,token,find) + else: + if os.path.isdir(filename): + return get_dir_down(filename,token,find) + + if request.args.get('play') == 'true': + import panelVideo + start, end = panelVideo.get_range(request) + return panelVideo.partial_response(filename, start, end) + else: + mimetype = "application/octet-stream" + extName = filename.split('.')[-1] + if extName in ['png','gif','jpeg','jpg']: mimetype = None + return send_file(filename,mimetype=mimetype, + as_attachment=True, + attachment_filename=os.path.basename(filename), + cache_timeout=0) + except: + return abort(404) @app.route('/cloud',methods=method_get) diff --git a/BTPanel/static/css/site.css b/BTPanel/static/css/site.css index 598616ea..ce26d958 100644 --- a/BTPanel/static/css/site.css +++ b/BTPanel/static/css/site.css @@ -1137,10 +1137,8 @@ html .menu .menu_exit:hover { border-bottom: 1px solid #e6e6e6; color: #666; font-weight: normal; - padding: 5px 10px; - height: 35px; + padding: 8px; font-size: 12.5px; - box-sizing: content-box; } .divtable .table_toolbar{ left: 8px; @@ -6697,4 +6695,41 @@ select[disabled]{ } .php_info_group:last-child{ margin-bottom: 15px; +} + +#btvideo{ + display: inline-block; + height: 360px; +} +.video-list{ + display: inline-block; + width: 250px; + height: 360px; + overflow: auto; +} +.video-list .video-avt{ + background-color: #e8e8e8; +} +.movie_pay .layui-layer-content{ + overflow: hidden !important; +} +.video-list .video-avt td a, +.video-list .video-avt td{ + color: #20a53a; +} +.video-list tr td{ + border-top: 0px; + border-bottom: 1px solid #ddd; +} +.video-list tr:hover{ + cursor: pointer; +} +#btvideo video{ + outline: none; + padding: 0; + display: block; + background-color: #000; +} +.minText{ + white-space: nowrap; } \ No newline at end of file diff --git a/BTPanel/static/js/files.js b/BTPanel/static/js/files.js index df4d180d..6737f5c0 100644 --- a/BTPanel/static/js/files.js +++ b/BTPanel/static/js/files.js @@ -473,7 +473,8 @@ function GetFiles(Path, sort) { if (getCookie("rank") == "a") { $("#set_list").addClass("active"); $("#set_icon").removeClass("active"); - Body += "\ + if (rdata.PATH=='/') rdata.PATH = ''; + Body += "\ \ " + cnametext + fileMsg + "\ " + lan.files.calc_click + "\ @@ -491,7 +492,7 @@ function GetFiles(Path, sort) { } else { $("#set_icon").addClass("active"); $("#set_list").removeClass("active"); - Body += "