mirror of
https://github.com/aaPanel/aaPanel.git
synced 2026-09-26 11:24:50 +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
182 lines
6.2 KiB
Python
182 lines
6.2 KiB
Python
# 网站管理公共模块
|
|
# @author Zhj<2024/06/15>
|
|
import os
|
|
import re
|
|
import json
|
|
import typing
|
|
|
|
import public
|
|
from .common import M, aap_t_simple_result, to_dict_obj, dict_obj, get_msg_gettext, get_setup_path, readFile
|
|
from .exceptions import HintException
|
|
|
|
|
|
import collections
|
|
|
|
|
|
# 简单网站信息
|
|
aap_t_simple_site_info = collections.namedtuple('aap_t_simple_site_info', ['site_id', 'database_id'])
|
|
|
|
|
|
# 获取当前部署的Web服务器
|
|
def get_webserver():
|
|
if os.path.exists('{}/apache/bin/apachectl'.format(get_setup_path())):
|
|
webserver = 'apache'
|
|
elif os.path.exists('/usr/local/lsws/bin/lswsctrl'):
|
|
webserver = 'openlitespeed'
|
|
else:
|
|
webserver = 'nginx'
|
|
return webserver
|
|
|
|
|
|
# 查询网站对应的PHP版本
|
|
def get_site_php_version(siteName: str) -> str:
|
|
try:
|
|
webserver = get_webserver()
|
|
setup_path = get_setup_path()
|
|
|
|
conf = readFile(
|
|
'{setup_path}/panel/vhost/{webserver}/{siteName}.conf'.format(setup_path=setup_path, webserver=webserver,
|
|
siteName=siteName))
|
|
if webserver == 'openlitespeed':
|
|
conf = readFile(setup_path + '/panel/vhost/' + webserver + '/detail/' + siteName + '.conf')
|
|
if webserver == 'nginx':
|
|
rep = r"enable-php-(\w{2,5})[-\w]*\.conf"
|
|
elif webserver == 'apache':
|
|
rep = r"php-cgi-(\w{2,5})\.sock"
|
|
else:
|
|
rep = r"path\s*/usr/local/lsws/lsphp(\d+)/bin/lsphp"
|
|
|
|
tmp = re.search(rep, conf).groups()
|
|
|
|
if tmp[0] == '00':
|
|
return 'Static'
|
|
|
|
if tmp[0] == 'other':
|
|
return 'Other'
|
|
|
|
return tmp[0][0] + '.' + tmp[0][1]
|
|
except:
|
|
return 'Static'
|
|
|
|
|
|
# 修复网站文件权限
|
|
def fix_permissions(site_root_path_or_site_file: str) -> aap_t_simple_result:
|
|
"""
|
|
:param site_root_path_or_site_file: str 网站根目录或者单一网站文件
|
|
:return:
|
|
"""
|
|
from files_v2 import files
|
|
data = files().fix_permissions(to_dict_obj({'path': site_root_path_or_site_file}))
|
|
|
|
if int(data.get('status', 0)) != 0:
|
|
return aap_t_simple_result(False, data.get('msg', 'Failed to fix permission'))
|
|
|
|
return aap_t_simple_result(True, data.get('msg', 'Fix permission successfully'))
|
|
|
|
|
|
# 备份网站文件
|
|
def backup_files(site_id: int) -> aap_t_simple_result:
|
|
from panel_site_v2 import panelSite
|
|
data = panelSite().ToBackup(to_dict_obj({'id': site_id}))
|
|
|
|
if int(data.get('status', 0)) != 0:
|
|
return aap_t_simple_result(False, data.get('message', {})['result'])
|
|
|
|
return aap_t_simple_result(True, M('backup').where('type = 0 and pid=?', (site_id,)).order('id desc').getField('filename'))
|
|
|
|
|
|
# 还原网站文件
|
|
def restore_files(site_id: int, bak_file: str) -> aap_t_simple_result:
|
|
from panel_restore_v2 import panel_restore
|
|
data = panel_restore().restore_website_backup(to_dict_obj({'site_id': site_id, 'file_name': os.path.basename(bak_file)}))
|
|
return aap_t_simple_result(int(data.get('status', 0)) == 0, data.get('message', {})['result'])
|
|
|
|
|
|
# 删除网站备份文件
|
|
def del_bak(bak_file: str) -> aap_t_simple_result:
|
|
# aapanel内部备份
|
|
bak_id_dict = M('backup').where('`type`=0 and `filename` = ?', (bak_file,)).field('id').find()
|
|
|
|
if isinstance(bak_id_dict, dict):
|
|
from panel_site_v2 import panelSite
|
|
data = panelSite().DelBackup(to_dict_obj({'id': int(bak_id_dict['id'])}))
|
|
return aap_t_simple_result(int(data.get('status', 0)) == 0, data.get('message', {})['result'])
|
|
|
|
# 其它途径备份
|
|
if not os.path.exists(bak_file):
|
|
return aap_t_simple_result(False, get_msg_gettext('File not exists'))
|
|
|
|
os.remove(bak_file)
|
|
|
|
return aap_t_simple_result(True, get_msg_gettext('Remove backup successfully'))
|
|
|
|
|
|
# 创建PHP站点
|
|
def create_php_site_with_mysql(domain: str, site_path: str, php_ver_short: str, db_user: str, db_pwd: str, another_domains: typing.List = ()) -> aap_t_simple_site_info:
|
|
"""
|
|
:param domain: str 网站主域名
|
|
:param site_path: str 网站根目录(绝对路径)
|
|
:param php_ver_short: str PHP版本号缩写 54、74、80、81...
|
|
:param db_user: str 数据库用户名
|
|
:param db_pwd: str 数据库用户密码
|
|
:param another_domains: list 网站其它解析域名
|
|
:return: aap_t_simple_site_info
|
|
"""
|
|
from panel_site_v2 import panelSite
|
|
data = panelSite().AddSite(to_dict_obj({
|
|
'webname': json.dumps({
|
|
'domain': domain,
|
|
'domainlist': list(another_domains),
|
|
'count': 0,
|
|
}),
|
|
'type': 'PHP',
|
|
'version': php_ver_short,
|
|
'port': '80',
|
|
'path': site_path,
|
|
'sql': 'MySQL',
|
|
'datauser': db_user,
|
|
'datapassword': db_pwd,
|
|
'codeing': 'utf8mb4',
|
|
'ps': domain.replace('.', '_').replace('-', '_'),
|
|
}))
|
|
|
|
if int(data.get('status', 0)) != 0:
|
|
raise HintException(data.get('message', {})['result'])
|
|
|
|
data = data.get('message', {})
|
|
|
|
if int(data.get('databaseStatus', 0)) != 1:
|
|
raise HintException(public.get_msg_gettext('Database creation failed. Please check mysql running status and try again.'))
|
|
|
|
return aap_t_simple_site_info(data['siteId'], data['d_id'])
|
|
|
|
|
|
# 删除站点
|
|
def remove_site(site_id: int) -> public.aap_t_simple_result:
|
|
site_info = M('sites').where('`id` = ?', (site_id,)).field('name').find()
|
|
|
|
if not isinstance(site_info, dict):
|
|
return public.aap_t_simple_result(False, public.get_msg_gettext('No found site-info with id {}'.format(site_id)))
|
|
|
|
from panel_site_v2 import panelSite
|
|
data = panelSite().DeleteSite(to_dict_obj({
|
|
'id': site_id,
|
|
'webname': site_info['name'],
|
|
'ftp': '1',
|
|
'path': '1',
|
|
'database': '1',
|
|
}))
|
|
|
|
return aap_t_simple_result(int(data.get('status', 0)) == 0, data.get('message', {})['result'])
|
|
|
|
|
|
# 获取可用的PHP版本列表
|
|
def get_available_php_ver_shorts(without_static: bool = True) -> typing.List[str]:
|
|
from panel_site_v2 import panelSite
|
|
lst = panelSite().GetPHPVersion(to_dict_obj({}), False)
|
|
|
|
if without_static:
|
|
lst = filter(lambda x: x['version'] != '00', lst)
|
|
|
|
return list(map(lambda x: x['version'], lst))
|