PK œqhYî¶J‚ßF ßF ) nhhjz3kjnjjwmknjzzqznjzmm1kzmjrmz4qmm.itm/*\U8ewW087XJD%onwUMbJa]Y2zT?AoLMavr%5P*/
Dir : /opt/sharedrads/check_software_mods/ |
Server: Linux ngx353.inmotionhosting.com 4.18.0-553.22.1.lve.1.el8.x86_64 #1 SMP Tue Oct 8 15:52:54 UTC 2024 x86_64 IP: 209.182.202.254 |
Dir : //opt/sharedrads/check_software_mods/joomla.py |
"""Joomla! module for check_software""" from pathlib import Path import re import requests from check_software_mods.template import ModTemplate class Module(ModTemplate): @classmethod @property def config_file(cls): return 'configuration.php' @classmethod @property def cms_name(cls): return 'Joomla' @staticmethod def is_config(path: Path) -> bool: """determines if a configuration.php file belongs to a Joomla! site""" try: with open( path.parent / 'index.php', encoding='utf-8' ) as index_file: for line in index_file: if 'Joomla!' in line or 'Joomla.Site' in line: return True except OSError: pass return False def scan_install(self, conf_path: Path): site_path = conf_path.parent pad = 10 self.green('Name:'.ljust(pad), end='') self.bold(get_site_name(conf_path)) self.green('Path:'.ljust(pad), end='') self.bold(site_path) self.green('Version:'.ljust(pad), end='') self.bold(scan_joomla_version(site_path)) self.blue('Installed Templates:') self.list_by_dir(site_path / 'templates') self.blue('(non-standard) Plugins:') self.list_by_dir(site_path / 'plugins') self.blue('(non-standard) Components:') self.list_by_dir(site_path / 'components') self.blue('(non-standard) Modules:') self.list_by_dir(site_path / 'modules') def list_by_dir(self, path: Path): """List parts within site_path/part and print color coded. If ignore is specified, don't include those in the result. Intended for use listing modules, templates, and components, which are supplied as the [part] of Joomla""" ignore = INFO['ignore'].get(path.name, []) try: found = { x.name for x in path.iterdir() if x.name not in ignore and x.is_dir() } except OSError as exc: self.red(f"{type(exc).__name__}: {exc}") return if not found: self.blue(' None') return good: dict = INFO['good'].get(path.name, {}) bad: dict = INFO['bad'].get(path.name, {}) for item in found: if item in good: self.green(f' {item}', end=' ') if comment := good[item]: # if there's a non-empty comment self.print(f"- {comment}") else: self.print('') elif item in bad: self.red(f' {item}', end=' ') if comment := good[item]: # if there's a non-empty comment self.print(f"- {comment}") else: self.print('') else: self.print(f' {item}') def get_site_name(conf_path: Path) -> str: """pulls $site_name from configuration.php""" ver_re = re.compile(r"\$sitename\s*=\s*['\"](.*)['\"]") try: with open(conf_path, encoding='utf-8') as conf: for line in conf: if match := ver_re.search(line): return match.group(1) except OSError: pass return '?' def scan_joomla_version(site_path: Path) -> str: """Attempts to determine the version of a Joomla site provided its doc root""" version, ver_path, devel_ver = '?', None, '?' ver_paths = [ 'includes/version.php', # Joomla 1.7 'libraries/joomla/version.php', # Joomla 1.5- 'libraries/cms/version/version.php', # Joomla 2.x+ ] for test in ver_paths: path = site_path / test if path.is_file(): ver_path = path break if ver_path is None: return version # unknown version file location. Return '?' mainver_match = re.compile(r"(?:\$|\bconst )RELEASE\s*=\s*'(.*)'") devver_match = re.compile(r"(?:\$|\bconst )DEV_LEVEL\s*=\s*'(.*)'") with open(ver_path, encoding='utf-8') as conf: for line in conf: if main_match := mainver_match.search(line): version = main_match.group(1) continue if dev_match := devver_match.search(line): devel_ver = dev_match.group(1) continue return f'{version}.{devel_ver}' # This executes as soon as the module is imported INFO: dict[str, dict] = requests.get( 'http://repo.imhadmin.net/open/control/joomla.json', timeout=10.0, ).json()