mirror of
https://github.com/aaPanel/aaPanel.git
synced 2026-08-25 00:52:26 +02:00
Since version 7.7.0, we recommend yours update python to 3.12. [+] Using nginx technology to load static files improves access speed [+] Refactor homepage, website, FTP, and database using vue3 [+] Table loading changed to skeleton screen [+] Add Website statistics-v2 professional plug-in [+] Add Home page - top 5 resource occupancy [+] Add protection for Files management (requires Tamper-proof for Enterprise 3.7) [+] Website, FTP, Databases page add program status [+] Add FTP log analysis (only supports Centos) [+] Add password-free login to phpMyAdmin [+] Add Proxy Project in Website (Supported when web service uses Nginx) [+] Add WP Toolkit (Pro version only) [+] Redesigned Docker module [+] Add WP Toolkit Protection [+] Add WP Toolkit Backup and Restore [+] Add WP Toolkit Migrated [+] Add WP Toolkit Clone site (supports new domain and subdomain) [+] Add WP Toolkit Create site from backup of other panel [+] Add WP Toolkit support for Cron automatic backup (only save Local disk) [+] Add WP Toolkit operation log [+] Add Integrity check for WP Toolkit [+] Add WP Toolkit plug-in management and themes management [*] Optimize phpMyAdmin formula access method [*] Optimize Home page PHP display problem [*] Optimize jump to the login interface after the login expires [*] Optimize automatic renewal of SSL at some times [*] Optimize Let's Encrypt to increase application success rate [-] Fix Logs Audit cannot be opened [-] Fix apache URL rewrite issue [-] Fix phpmyadmin installation problem [-] Fix the problem that some servers cannot install software [-] Fix upload file error [-] Fix left menu hiding problem [-] Fix aaPanel Mobile QR code display problem [-] Fix problem that third-party plug-ins are not displayed in the App Store [-] Fix issue where the menu bar is blank when opening new tabs [-] Fixed panel not being accessible in some cases [-] Fix the issue where Curl warning caused the inability to apply for SSL [-] Fix Quota issues for Website, FTP, Databases [-] Fix file interface display problem on mobile terminal
201 lines
5.2 KiB
Python
201 lines
5.2 KiB
Python
import os
|
|
import sys
|
|
from typing import Optional, Tuple, Callable
|
|
|
|
if "/www/server/panel/class" not in sys.path:
|
|
sys.path.insert(0, "/www/server/panel/class")
|
|
|
|
import public
|
|
|
|
|
|
def webserver() -> Optional[str]:
|
|
if os.path.exists('/www/server/apache/bin/apachectl'):
|
|
web_server = 'apache'
|
|
elif os.path.exists('/www/server/nginx/sbin/nginx'):
|
|
web_server = 'nginx'
|
|
elif os.path.exists('/usr/local/lsws/bin/lswsctrl'):
|
|
web_server = 'openlitespeed'
|
|
else:
|
|
web_server = None
|
|
return web_server
|
|
|
|
|
|
def check_server_config() -> Optional[str]:
|
|
w_s = webserver()
|
|
setup_path = "/www/server"
|
|
if w_s == 'nginx':
|
|
shell_str = (
|
|
"ulimit -n 8192; "
|
|
"{setup_path}/nginx/sbin/nginx -t -c {setup_path}/nginx/conf/nginx.conf"
|
|
).format(setup_path=setup_path)
|
|
result: Tuple[str, str] = public.ExecShell(shell_str)
|
|
searchStr = 'successful'
|
|
elif w_s == 'apache':
|
|
shell_str = (
|
|
"ulimit -n 8192; "
|
|
"{setup_path}/apache/bin/apachectl -t"
|
|
).format(setup_path=setup_path)
|
|
result: Tuple[str, str] = public.ExecShell(shell_str)
|
|
searchStr = 'Syntax OK'
|
|
else:
|
|
return None
|
|
if result[1].find(searchStr) == -1:
|
|
public.WriteLog("TYPE_SOFT", 'CONF_CHECK_ERR', (result[1],))
|
|
return result[1]
|
|
|
|
|
|
def read_file(filename, mode='r') -> Optional[str]:
|
|
"""
|
|
读取文件内容
|
|
@filename 文件名
|
|
return string(bin) 若文件不存在,则返回None
|
|
"""
|
|
import os
|
|
if not os.path.exists(filename):
|
|
return None
|
|
fp = None
|
|
try:
|
|
fp = open(filename, mode=mode)
|
|
f_body = fp.read()
|
|
except:
|
|
return None
|
|
finally:
|
|
if fp and not fp.closed:
|
|
fp.close()
|
|
return f_body
|
|
|
|
|
|
def write_file(filename: str, s_body: str, mode='w+') -> bool:
|
|
"""
|
|
写入文件内容
|
|
@filename 文件名
|
|
@s_body 欲写入的内容
|
|
return bool 若文件不存在则尝试自动创建
|
|
"""
|
|
try:
|
|
fp = open(filename, mode=mode)
|
|
fp.write(s_body)
|
|
fp.close()
|
|
return True
|
|
except:
|
|
try:
|
|
fp = open(filename, mode=mode, encoding="utf-8")
|
|
fp.write(s_body)
|
|
fp.close()
|
|
return True
|
|
except:
|
|
return False
|
|
|
|
|
|
def debug_api_warp(fn):
|
|
def inner(*args, **kwargs):
|
|
try:
|
|
return fn(*args, **kwargs)
|
|
except:
|
|
public.print_log(public.get_error_info())
|
|
return {
|
|
|
|
}
|
|
|
|
return inner
|
|
|
|
|
|
# 重载Web服务配置
|
|
def service_reload():
|
|
setup_path = "/www/server"
|
|
if os.path.exists('{}/nginx/sbin/nginx'.format(setup_path)):
|
|
result = public.ExecShell('/etc/init.d/nginx reload')
|
|
if result[1].find('nginx.pid') != -1:
|
|
public.ExecShell('pkill -9 nginx && sleep 1')
|
|
public.ExecShell('/etc/init.d/nginx start')
|
|
elif os.path.exists('{}/apache/bin/apachectl'.format(setup_path)):
|
|
result = public.ExecShell('/etc/init.d/httpd reload')
|
|
else:
|
|
result = public.ExecShell('rm -f /tmp/lshttpd/*.sock* && /usr/local/lsws/bin/lswsctrl restart')
|
|
return result
|
|
|
|
|
|
# 防正则转译
|
|
def pre_re_key(input_str: str) -> str:
|
|
re_char = ['$', '(', ')', '*', '+', '.', '[', ']', '{', '}', '?', '^', '|', '\\']
|
|
res = []
|
|
for i in input_str:
|
|
if i in re_char:
|
|
res.append("\\" + i)
|
|
else:
|
|
res.append(i)
|
|
return "".join(res)
|
|
|
|
|
|
def get_log_path() -> str:
|
|
log_path = public.readFile("{}/data/sites_log_path.pl".format(public.get_panel_path()))
|
|
if isinstance(log_path, str) and os.path.isdir(log_path):
|
|
return log_path
|
|
return public.GetConfigValue('logs_path')
|
|
|
|
|
|
|
|
# 2024/4/18 上午9:44 域名编码转换
|
|
def to_puny_code(domain):
|
|
try:
|
|
try:
|
|
import idna
|
|
except:
|
|
os.system("btpip install idna -I")
|
|
import idna
|
|
|
|
import re
|
|
match = re.search(u"[^u\0000-u\001f]+", domain)
|
|
if not match:
|
|
return domain
|
|
try:
|
|
if domain.startswith("*."):
|
|
return "*." + idna.encode(domain[2:]).decode("utf8")
|
|
else:
|
|
return idna.encode(domain).decode("utf8")
|
|
except:
|
|
return domain
|
|
except:
|
|
return domain
|
|
|
|
|
|
# 2024/4/18 下午5:48 中文路径处理
|
|
def to_puny_code_path(path):
|
|
if sys.version_info[0] == 2: path = path.encode('utf-8')
|
|
if os.path.exists(path): return path
|
|
import re
|
|
match = re.search(u"[\x80-\xff]+", path)
|
|
if not match: match = re.search(u"[\u4e00-\u9fa5]+", path)
|
|
if not match: return path
|
|
npath = ''
|
|
for ph in path.split('/'):
|
|
npath += '/' + to_puny_code(ph)
|
|
return npath.replace('//', '/')
|
|
|
|
|
|
|
|
class _DB:
|
|
|
|
def __call__(self, table: str):
|
|
import db
|
|
with db.Sql() as t:
|
|
t.table(table)
|
|
return t
|
|
|
|
|
|
DB = _DB()
|
|
|
|
GET_CLASS = public.dict_obj
|
|
|
|
listen_ipv6: Callable[[], bool] = public.listen_ipv6
|
|
|
|
ExecShell: Callable = public.ExecShell
|
|
|
|
|
|
def use_http2() -> bool:
|
|
versionStr = public.readFile('/www/server/nginx/version.pl')
|
|
if isinstance(versionStr, str):
|
|
if versionStr.find('1.8.1') == -1:
|
|
return True
|
|
return False
|