Mini Shell
#!/opt/cloudlinux/venv/bin/python3 -Ibb
##
# Copyright (с) Cloud Linux GmbH & Cloud Linux Software, Inc 2010-2022 All Rights Reserved
#
# Licensed under CLOUD LINUX LICENSE AGREEMENT
# https://www.cloudlinux.com/legal/
##
import os
import pwd
import logging
from enum import Enum
from datetime import datetime, timedelta
from clcommon.cpapi import docroot
from clwpos.wp_utils import wp_get_constant
from xray import gettext as _
from xray.internal.utils import user_context
from secureio import disable_quota
class PluginStatuses(Enum):
"""
INSTALLED = plugin exists in MU directory
ERROR = plugin should have been installed: there are advices w/o incompatibility
and created_at > 2days (wordpress-install cron expected to trigger install)
NOT_INSTALLED = plugin does not exist in MU directory:
in ideal world it means whether there are no compatible advices or
wordpress-plugin install cron has not worked yet
"""
INSTALLED = 'INSTALLED'
ERROR = 'ERROR'
NOT_INSTALLED = 'NOT_INSTALLED'
def create_mu_plugins_dir_if_not_exist(user, mu_plugin_dir):
"""
Creates MU plugin dir if does not exist yet
"""
if os.path.isdir(mu_plugin_dir):
return
user_data = pwd.getpwnam(user)
with user_context(user_data.pw_uid, user_data.pw_gid), disable_quota():
try:
os.makedirs(mu_plugin_dir)
except OSError as e:
logging.error("Failed creating must use plugin folder. Path: %s. Reason: %s",
mu_plugin_dir, str(e))
raise ValueError(_('Unable to create MU plugins directory'))
def get_mu_directory(user, full_wp_path):
"""
Gets path to directory with MU plugins
"""
mu_directory = None
user_data = pwd.getpwnam(user)
with user_context(user_data.pw_uid, user_data.pw_gid):
try:
mu_directory = wp_get_constant(full_wp_path, 'WPMU_PLUGIN_DIR', raise_exception=True)
except Exception as e:
logging.error('Unable to read WPMU_PLUGIN_DIR constant, "error=%s"', str(e))
if not mu_directory:
try:
mu_directory = wp_get_constant(full_wp_path, 'WP_CONTENT_DIR', raise_exception=True)
except Exception as e:
logging.error('Unable to read WP_CONTENT_DIR constant, "error=%s"', str(e))
return mu_directory
def is_plugin_installed(user, domain, website):
"""
Checks whether there is cl-smart-advice.php in MU plugins directory
"""
full_website_path = docroot(domain)[0] + website
mu_directory = get_mu_directory(user, full_website_path)
if not mu_directory:
logging.warning('Path to directory with MU plugins was not obtained')
return None
plugin_must_use_file = os.path.join(mu_directory, 'cl-smart-advice.php')
return os.path.islink(plugin_must_use_file)
def should_have_been_installed(advices_for_website, issues):
"""
1. At least 1 advice has no incompatibilities
2. The newest advice w/o incompatibilities was created > 2 days ago
"""
issue_types = []
if issues:
issue_types = [issue['advice_type'] for issue in issues]
return [
advice
for advice in advices_for_website
if is_advice_should_been_synced(advice, issue_types)
]
def is_advice_should_been_synced(advice, website_issue_types):
"""
If advice does not have incompatibility and older than cron time (once a day) ->
it should have been synced, which triggers plugin installation
"""
created_at = datetime.fromisoformat(advice['created_at'])
return advice['advice']['type'] not in website_issue_types and \
created_at < datetime.now(created_at.tzinfo) - timedelta(days=2)
def get_plugin_status(username, domain, website, issues, current_advices):
"""
If smart-advice.php in MU plugin dir -> INSTALLED
If there is at least 1 advice w/o issues and the newest advice is > 2 days -> cron should've work
and install plugin, most likely error happened -> ERROR
otherwise: NOT_INSTALLED: all advices are incompatible or wordpress-plugin install cron did not work yet
"""
if is_plugin_installed(username, domain, website):
return PluginStatuses.INSTALLED.value
elif should_have_been_installed(current_advices, issues):
return PluginStatuses.ERROR.value
return PluginStatuses.NOT_INSTALLED.value
Zerion Mini Shell 1.0