Mini Shell

Direktori : /opt/sharedrads/guds_modules/
Upload File :
Current File : //opt/sharedrads/guds_modules/base.py

"""Abstract parent class of guds modules"""
from abc import abstractmethod
import logging
from os import walk
from pathlib import Path
import shlex
import shutil
import subprocess


class ModuleBase:
    def __init__(self, dry_run: bool, logger: logging.Logger):
        self.dry_run = dry_run
        self.logger = logger

    @abstractmethod
    def run_module(self, homedir: str) -> dict:
        raise NotImplementedError

    @classmethod
    def calc_bytes(cls, size_check: Path) -> int:
        if size_check.is_file():
            return size_check.stat().st_size
        total_size = 0
        for root, _, files in walk(size_check):
            for name in files:
                filename = Path(root, name)
                try:
                    total_size += filename.stat().st_size
                except OSError:
                    pass
        return total_size

    @classmethod
    def get_size(cls, size_check: Path) -> str:
        """Find the size of provided directory or file"""
        total_size = cls.calc_bytes(size_check)
        for suffix in ['B', 'KiB', 'MiB', 'GiB', 'TiB']:
            if total_size < 1024.0:
                return f"{total_size:3.1f} {suffix}"
            total_size /= 1024.0
        return f"{total_size:3.1f} PiB"

    def find(
        self,
        homedir: str,
        /,
        *,
        maxdepth=None,
        regex=None,
        prune_mail=True,
        **kwargs,
    ) -> list[Path]:
        """returns each line of output from the command as an item in a list"""
        cmd = ['find']
        if regex is not None:
            cmd.append('-O3')
        cmd.append(homedir)
        # ensure maxdepth is set first, if specified
        if maxdepth is not None:
            cmd.extend(['-maxdepth', str(maxdepth)])
        elif prune_mail:
            # optimization: prune and exclude ~/mail
            cmd.extend(['-not', '(', '-path', f"{homedir}/mail", '-prune', ')'])
        # regextype must be set before regex
        if regex is not None:
            cmd.extend(['-regextype', 'posix-extended', '-regex', regex])
        for key, val in kwargs.items():
            cmd.extend([f'-{key}', str(val)])
        cmd.append('-print0')
        self.logger.debug(shlex.join(cmd))
        ret = subprocess.run(
            cmd, stdout=subprocess.PIPE, encoding='utf-8', check=False
        )
        return [Path(x) for x in ret.stdout.split('\0') if x]

    def delete_items(self, backuplist: list[Path]):
        for backup in backuplist:
            self.logger.info("Removing %s (%s)", backup, self.get_size(backup))
            if self.dry_run:
                continue
            if backup.is_file():
                backup.unlink()
            elif backup.is_dir():
                shutil.rmtree(str(backup))

Zerion Mini Shell 1.0