Mini Shell
# -*- coding: utf-8 -*-
# Copyright © Cloud Linux GmbH & Cloud Linux Software, Inc 2010-2021 All Rights Reserved
#
# Licensed under CLOUD LINUX LICENSE AGREEMENT
# http://cloudlinux.com/docs/LICENSE.TXT
import logging
import os
import configparser
import shutil
import json
from xray import gettext as _
class Plugin:
"""
Helper class which hides differences of WordPress plugins behind abstract methods.
"""
NAME = ''
SOURCE_DIR = ''
INFO_FILE_PATH = ''
ZIP_FILE_PATH = ''
PLUGIN_DATA = None
def _get_version(self):
"""Get the plugin version from plugin data"""
if (plugin_data := self._get_data_dict()) is None:
return None
for section in plugin_data:
if 'version' in plugin_data[section]:
return plugin_data[section]['version']
logging.error('Can\'t get the %s plugin version.', self.NAME)
return None
def _read_ini_file(self):
"""Read the ini file"""
config_object = configparser.ConfigParser()
config_object.read(self.INFO_FILE_PATH)
output={s:dict(config_object.items(s)) for s in config_object.sections()}
return output
def _get_data_dict(self):
"""Get the plugin data from ini file"""
if self.PLUGIN_DATA is None:
if os.path.exists(self.INFO_FILE_PATH):
data = self._read_ini_file()
self.PLUGIN_DATA = data
else:
logging.error('Can\'t read the %s plugin data.', self.NAME)
return None
return self.PLUGIN_DATA
def copy_plugin(self, plugin_version: str, dest_dir: str):
"""
Get plugin info if there is a new version and the update is true
copy the plugin archive to the given folder for updating
"""
if not plugin_version or not dest_dir:
logging.error('Can\'t get old plugin version or destination folder for %s.', self.NAME)
return None
new_version = self._get_version()
filename = self.NAME + '-' + new_version
dest_plugin_path = os.path.join(dest_dir, filename + '.zip')
# If there is a new version and the archive has not yet been copied, then copy it
if (plugin_version != new_version
and plugin_version is not None
and new_version is not None
and not os.path.exists(dest_plugin_path)):
try:
shutil.copyfile(self.ZIP_FILE_PATH, dest_plugin_path)
except IOError as e:
error = _("Error happened while copying WordPress {} plugin archive. Error: {}".format(self.NAME,
str(e)))
logging.error(error)
return format_response(False, error=error)
try:
st = os.stat(dest_dir)
os.chown(dest_plugin_path, st.st_uid, st.st_gid)
except OSError as e:
error = _("Error happened while setting permissions to WordPress {} plugin archive. "
"Error: {}".format(self.NAME, str(e)))
logging.error(error)
return format_response(False, error=error)
return format_response(True, package=dest_plugin_path)
def get_data(self):
"""Get the plugin data from ini file"""
if not self.PLUGIN_DATA:
self.PLUGIN_DATA = self._get_data_dict()
return format_response(True, data=self.PLUGIN_DATA)
class _AccelerateWp(Plugin):
"""AccelerateWP WordPress plugin manager"""
NAME = 'AccelerateWP'
SOURCE_DIR = '/opt/cloudlinux-site-optimization-module'
INFO_FILE_PATH = SOURCE_DIR + '/clsop.ini'
ZIP_FILE_PATH = SOURCE_DIR + '/clsop.zip'
_PLUGIN_MANAGERS = {"AccelerateWP": _AccelerateWp}
def format_response(is_success, **kwargs):
"""Prepare json response"""
success = 'success' if is_success else 'error'
result = {'result': success}
return json.dumps({**result, **kwargs})
def get_plugin_manager(plugin_name: str):
if plugin_name not in _PLUGIN_MANAGERS:
return None
return _PLUGIN_MANAGERS[plugin_name]()
def get_plugin(plugin_name, plugin_version, dest_dir):
"""
If there is a new version copy the plugin archive
to the given folder for updating
"""
manager = get_plugin_manager(plugin_name)
if manager is None:
error = _("The %s plugin unknown") % plugin_name
logging.error(error)
return format_response(False, error=error)
return manager.copy_plugin(plugin_version=plugin_version, dest_dir=dest_dir)
def get_plugin_data(plugin_name):
"""
Get plugin info
"""
manager = get_plugin_manager(plugin_name)
if manager is None:
error = _("The %s plugin unknown") % plugin_name
logging.error(error)
return format_response(False, error=error)
return manager.get_data()