コード例 #1
0
ファイル: config.py プロジェクト: piratecaveman/colstract
    def __init__(self, path: str = None):
        self.default_path = pathlib.Path(
            os.environ['HOME']) / '.config' / 'colstract' / 'config.json'
        self.default_output = pathlib.Path(
            os.environ['HOME']) / '.cache' / 'colstract'
        self.default_xresources = pathlib.Path(
            os.environ['HOME']) / '.Xresources'
        self.log_file = pathlib.Path(
            os.environ['HOME']
        ) / '.cache' / 'colstract' / 'log' / 'colstract.log'
        self.template = {
            'output_dir': None,
            'xresources_path': None,
            'wallpaper_options': {
                "apply_wallpaper": False,
                "path": None,
                "setter": None,
                "setter_option": None
            },
            'reload_env': False
        }
        # logger
        self.logger = Logger(name='colstract-config',
                             log_file=str(self.log_file)).get_logger()

        # config path if provided
        self.__path: str = path
        self.path = self._path()
        self.config = self._config()
コード例 #2
0
 def __init__(self, path: str = None):
     self.config_options = Config(path)
     self.parser = XReader(path)
     self.logger = Logger(
         name='colstract-generator',
         log_file=self.config_options.log_file).get_logger()
     self.templates = self._templates()
コード例 #3
0
 def __init__(self, path: str = None):
     self.config_options = Config(path)
     self.log_file = self.config_options.log_file
     self.logger = Logger(name='colstract-xreader',
                          log_file=str(self.log_file)).get_logger()
     self.content = self._read()
     self.compiled_patterns = self._compiled_patterns()
     self.parsed_data = self._parsed()
コード例 #4
0
class XReader(object):
    def __init__(self, path: str = None):
        self.config_options = Config(path)
        self.log_file = self.config_options.log_file
        self.logger = Logger(name='colstract-xreader',
                             log_file=str(self.log_file)).get_logger()
        self.content = self._read()
        self.compiled_patterns = self._compiled_patterns()
        self.parsed_data = self._parsed()

    def _read(self):
        with open(self.config_options.config.get('xresources_path'),
                  'r') as file:
            data = file.read()
            self.logger.info(
                f"Read Xreources file at {self.config_options.config.get('xresources_path')}"
            )
        return data

    @staticmethod
    def _compiled_patterns() -> dict:
        color = r'#[A-Fa-f0-9]{6,8}'
        color_number = r'color[0-9]{1,2}'
        patterns = {
            'background': re.compile(f'background:.*({color})'),
            'foreground': re.compile(f'foreground:.*({color})'),
            'cursor': re.compile(f'cursorColor:.*({color})'),
            'colors': re.compile(f'({color_number}).*({color})')
        }
        return patterns

    def _parsed(self) -> dict:
        output = {
            'wallpaper':
            self.config_options.config.get('wallpaper_options').get('path'),
            'alpha':
            '100',
            'special': {
                'background':
                Color(
                    re.findall(self.compiled_patterns['background'],
                               self.content)[0]),
                'foreground':
                Color(
                    re.findall(self.compiled_patterns['foreground'],
                               self.content)[0]),
                'cursor':
                Color(
                    re.findall(self.compiled_patterns['cursor'],
                               self.content)[0])
            },
            'colors': {}
        }
        colors = re.findall(self.compiled_patterns['colors'], self.content)
        colors.sort(key=lambda x: int(x[0][5:]))
        for item in colors:
            output['colors'][item[0]] = Color(item[1])
        return output
コード例 #5
0
class TemplateGenerator(object):
    def __init__(self, path: str = None):
        self.config_options = Config(path)
        self.parser = XReader(path)
        self.logger = Logger(
            name='colstract-generator',
            log_file=self.config_options.log_file).get_logger()
        self.templates = self._templates()

    @staticmethod
    def _templates() -> list:
        path = pathlib.Path(__file__).parent / 'templates'
        result = [thing for thing in path.iterdir() if thing.is_file()]
        return result

    def generate(self):
        for item in self.templates:
            item: pathlib.Path
            self.logger.info(f"creating {item.name}")
            with open(item, 'r') as file:
                template_blank: str = file.read()

            result = template_blank.format(
                **self.parser.parsed_data,
                **self.parser.parsed_data['special'],
                **self.parser.parsed_data['colors'])

            output_dir = pathlib.Path(
                self.config_options.config.get('output_dir'))
            if not output_dir.exists():
                self.logger.warning(
                    f"{output_dir} not present, attempting to create it")
                pathlib.Path.mkdir(output_dir, parents=True)
                self.logger.info(f"Created {output_dir}")

            output_file = output_dir / item.name
            with open(str(output_file), 'w') as out_:
                out_.write(result)
                self.logger.info(f"Generated {output_file}")
                print(f"Generated {output_file}")
コード例 #6
0
ファイル: reload.py プロジェクト: piratecaveman/colstract
 def __init__(self, path: str = None):
     self.config_options = Config(path)
     self.logger = Logger(log_file=self.config_options.log_file,
                          name='colstact-reload').get_logger()
コード例 #7
0
ファイル: reload.py プロジェクト: piratecaveman/colstract
class Reload(object):
    def __init__(self, path: str = None):
        self.config_options = Config(path)
        self.logger = Logger(log_file=self.config_options.log_file,
                             name='colstact-reload').get_logger()

    def xrdb(self) -> int:
        if not self.exists('xrdb'):
            self.logger.error("xrdb does not exist")
            return 1

        self.logger.info("Attempting to merge xrdb")
        command = [
            'xrdb', '-merge',
            str(
                pathlib.Path(self.config_options.config.get('output_dir')) /
                'colors.Xresources')
        ]

        self.logger.info(f"Running {' '.join(command)}")

        output_raw = subprocess.run(command, capture_output=True)
        return_code = output_raw.returncode
        output = output_raw.stdout.decode('utf-8').strip('\n')

        self.logger.info(f"The process completed with he stdout {output}")
        self.logger.info(f"The return code is : {return_code}")

        return return_code

    def tty(self) -> int:
        self.logger.info(f"Attempting to apply color scheme to TTY")
        command = [
            "sh",
            str(
                pathlib.Path(self.config_options.config.get("output_dir")) /
                'colors-tty.sh')
        ]
        self.logger.info(f"Running command {' '.join(command)}")
        output_raw = subprocess.run(command, capture_output=True)
        output = output_raw.stdout.decode('utf-8').strip('\n')
        return_code = output_raw.returncode

        self.logger.info(f"The process exited with the stdout: {output}")
        self.logger.info(f"The return code is: {return_code}")

        return return_code

    def i3(self) -> int:
        if not self.exists('i3-msg'):
            self.logger.error("i3-msg does not exist")
            return 1

        self.logger.info("Attempting to reload i3-wm")
        command = ["i3-msg", "reload"]

        self.logger.info(f"Running command {' '.join(command)}")
        output_raw = subprocess.run(command, capture_output=True)
        output = output_raw.stdout.decode('utf-8').strip('\n')
        return_code = output_raw.returncode

        self.logger.info(f"The process exited with the stdout: {output}")
        self.logger.info(f"The return code is: {return_code}")

        return return_code

    def bspwm(self) -> int:
        if not self.exists('bspc'):
            self.logger.error("bspc does not exist")
            return 1

        self.logger.info("Attempting to reload bspwm")
        command = ["bspc", "wm", "-r"]

        self.logger.info(f"Running command {' '.join(command)}")
        output_raw = subprocess.run(command, capture_output=True)
        output = output_raw.stdout.decode('utf-8').strip('\n')
        return_code = output_raw.returncode

        self.logger.info(f"The process exited with the stdout: {output}")
        self.logger.info(f"The return code is: {return_code}")

        return return_code

    def kitty(self) -> int:
        if not self.exists('kitty'):
            self.logger.error("kitty does not exist")
            return 1

        self.logger.info("Attempting to reload kitty")
        command = [
            "kitty", "@", "set-colors", "--all",
            str(
                pathlib.Path(self.config_options.config.get("output_dir")) /
                'colors-kitty.conf')
        ]

        self.logger.info(f"Running command {' '.join(command)}")
        output_raw = subprocess.run(command, capture_output=True)
        output = output_raw.stdout.decode('utf-8').strip('\n')
        return_code = output_raw.returncode

        self.logger.info(f"The process exited with the stdout: {output}")
        self.logger.info(f"The return code is: {return_code}")

        return return_code

    def polybar(self) -> int:
        self.logger.info("Attempting to reload polybar")
        command = ["pkill", "-USR1", "polybar"]

        self.logger.info(f"Running command {' '.join(command)}")
        output_raw = subprocess.run(command, capture_output=True)
        output = output_raw.stdout.decode('utf-8').strip('\n')
        return_code = output_raw.returncode

        self.logger.info(f"The process exited with the stdout: {output}")
        self.logger.info(f"The return code is: {return_code}")

        return return_code

    def sway(self) -> int:
        if not self.exists('swaymsg'):
            self.logger.error("swaymsg does not exist")
            return 1

        self.logger.info("Attempting to reload sway")
        command = ["swaymsg", "reload"]

        self.logger.info(f"Running command {' '.join(command)}")
        output_raw = subprocess.run(command, capture_output=True)
        output = output_raw.stdout.decode('utf-8').strip('\n')
        return_code = output_raw.returncode

        self.logger.info(f"The process exited with the stdout: {output}")
        self.logger.info(f"The return code is: {return_code}")

        return return_code

    def reload_all(self) -> None:
        self.logger.info("Attempting to reload environment")
        if self.xrdb() != 0:
            self.logger.error("Reloading xrdb failed")
        if self.tty() != 0:
            self.logger.error("Reloading TTY failed")
        if self.i3() != 0:
            self.logger.error("Reloading i3-wm failed")
        if self.bspwm() != 0:
            self.logger.error("Reloading bspwm failed")
        if self.sway() != 0:
            self.logger.error("Reloading sway failed")
        if self.kitty() != 0:
            self.logger.error("Reloading Kitty failed")
        if self.polybar() != 0:
            self.logger.error("Reloading  polybar failed")
        return

    @staticmethod
    def exists(program):
        output = subprocess.run(['which', program], capture_output=True)
        if "not found" in output.stdout.decode('utf-8').strip('\n'):
            return False
        elif output.returncode == 1:
            return False
        else:
            return True
コード例 #8
0
 def __init__(self, path: str = None):
     self.config_options = Config(path)
     self.walconfig = pathlib.Path(__file__).parent / 'walconfig'
     self.log_file = self.config_options.log_file
     self.logger = Logger(name='colstract-wallpaper_setter',
                          log_file=self.log_file).get_logger()
コード例 #9
0
class WallSetter(object):
    def __init__(self, path: str = None):
        self.config_options = Config(path)
        self.walconfig = pathlib.Path(__file__).parent / 'walconfig'
        self.log_file = self.config_options.log_file
        self.logger = Logger(name='colstract-wallpaper_setter',
                             log_file=self.log_file).get_logger()

    def wallpaper_apply(self, backend: str) -> int:
        """
        Apply wallpaper using provided backend
        Currently only these backends are supported: (feh, nitrogen)
        :param backend:
        :return:
        """
        if backend not in ('feh', 'nitrogen'):
            self.logger.error(f"{backend} is not supported as of this version")
            print(f"{backend} is not supported as of this version")
            return 1
        self.logger.info(f"Using {backend} as backend for setting wallpaper")
        default_option = '--bg-fill' if backend == 'feh' else '--set-scaled'
        with open(self.walconfig / f'{backend}.json', 'r') as file:
            options: dict = json.loads(file.read())
            self.logger.info(
                f" {backend} configuration file {backend}.json loaded")

        set_options = self.config_options.config.get('wallpaper_options').get(
            'setter_option')
        if set_options is None:
            self.logger.warning(
                f"No setter options provided, using {default_option}")
            set_options = default_option
        elif set_options in options.get('options'):
            self.logger.info(f"Using {set_options} option to set wallpaper")
            pass
        else:
            self.logger.warning(
                f"Invalid parameter {set_options}. Using default option: {default_option}"
            )
            set_options = default_option

        function_call = subprocess.run(['which', backend], capture_output=True)
        if function_call.returncode == 0:
            program_path = function_call.stdout.decode('utf-8').strip('\n')
            self.logger.info(f"{backend} located at {program_path}")
        else:
            self.logger.error(f"failed to locate program {backend}")
            print(f"failed to locate {backend}")
            return 1

        self.logger.info(
            f"Calling: {program_path} {set_options} {self.config_options.config.get('wallpaper_options').get('path')}"
        )

        output = subprocess.run([
            program_path, set_options,
            self.config_options.config.get('wallpaper_options').get('path')
        ]).returncode
        if output == 0:
            self.logger.info("Wallpaper applied successfully")
            print("Wallpaper applied successfully")
        else:
            self.logger.error(
                f"Failed to apply wallpaper. Return Code: {output}")
            print(f"Failed to apply wallpaper with return code {output}")

        return 0
コード例 #10
0
ファイル: config.py プロジェクト: piratecaveman/colstract
class Config(object):
    def __init__(self, path: str = None):
        self.default_path = pathlib.Path(
            os.environ['HOME']) / '.config' / 'colstract' / 'config.json'
        self.default_output = pathlib.Path(
            os.environ['HOME']) / '.cache' / 'colstract'
        self.default_xresources = pathlib.Path(
            os.environ['HOME']) / '.Xresources'
        self.log_file = pathlib.Path(
            os.environ['HOME']
        ) / '.cache' / 'colstract' / 'log' / 'colstract.log'
        self.template = {
            'output_dir': None,
            'xresources_path': None,
            'wallpaper_options': {
                "apply_wallpaper": False,
                "path": None,
                "setter": None,
                "setter_option": None
            },
            'reload_env': False
        }
        # logger
        self.logger = Logger(name='colstract-config',
                             log_file=str(self.log_file)).get_logger()

        # config path if provided
        self.__path: str = path
        self.path = self._path()
        self.config = self._config()

    def _path(self) -> pathlib.Path:
        path_ = None
        if self.__path is None:
            self.logger.info(
                f'Using default path: {self.default_path} - no custom path provided'
            )
            path_ = self.default_path
        elif self.__path is not None:
            path_ = pathlib.Path(self.__path)
            if not path_.exists():
                self.logger.warning(
                    f'{path_} does not exist. Using default path: {self.default_path}'
                )
                path_ = self.default_path
            else:
                self.logger.info(f'Using custom config path {path_}')
        return path_

    def _config(self) -> dict:
        if not self.path.exists():
            self.logger.error(f'{self.path} does not exist')
            raise FileNotFoundError(f"{self.path} does not exist")

        with open(self.path, 'r') as file:
            data: dict = json.loads(file.read())
            self.logger.info(f'config read from {self.path}')

        config_ = copy.deepcopy(self.template)

        config_['output_dir'] = data.get('output_dir')
        if config_['output_dir'] is None:
            self.logger.info(
                f'output directory not specified. Using default {self.default_output}'
            )
            config_['output_dir'] = self.default_output

        config_['xresources_path'] = data.get('xresources_path')
        if config_['xresources_path'] is None:
            self.logger.info(
                f'xresources file not specified. Using default {self.default_xresources}'
            )
            config_['xresources_path'] = self.default_xresources

        # wallpaper options logging
        config_['wallpaper_options'].update(
            data.get('wallpaper_options',
                     self.template.get('wallpaper_options')))

        # if it is to be applied
        if config_['wallpaper_options']['apply_wallpaper']:
            self.logger.info(
                'apply_Wallpaper is True. Wallpaper will be applied if path is provided'
            )

            # if path actually exists
            if pathlib.Path(str(
                    config_['wallpaper_options']['path'])).exists():
                self.logger.info(f'Wallpaper file exists')

            else:
                self.logger.error(
                    f'Wallpaper file does not exist at {config_.get("wallpaper_options").get("path")}'
                )
        else:
            self.logger.info(
                'apply_wallpaper is False. Wallpaper will not be processed')

        config_['reload_env'] = data.get('reload_env', False)

        return config_