hyfetch/hyfetch/main.py
Azalea (on HyDEV-Daisy) d198b3a947 [+] Implement CLI
2022-04-10 05:55:44 -04:00

150 lines
3.8 KiB
Python
Executable file

#!/usr/bin/env python3
import argparse
import json
from dataclasses import dataclass
from pathlib import Path
from typing import Literal, Iterable
from hypy_utils import printc, json_stringify, color
from .neofetch_util import run_neofetch
from .presets import PRESETS
CONFIG_PATH = Path.home() / '.config/hyfetch.json'
CONFIG_PATH.parent.mkdir(exist_ok=True, parents=True)
@dataclass
class Config:
preset: str
mode: Literal['default', 'ansi', '8bit', 'rgb']
def save(self):
CONFIG_PATH.write_text(json_stringify(self), 'utf-8')
def check_config() -> Config:
"""
Check if the configuration exists. Return the config object if it exists. If not, call the
config creator
TODO: Config path param
:return: Config object
"""
if CONFIG_PATH.is_file():
return Config(**json.loads(CONFIG_PATH.read_text('utf-8')))
return create_config()
def literal_input(prompt: str, options: Iterable[str], default: str) -> str:
"""
Ask the user to provide an input among a list of options
:param prompt: Input prompt
:param options: Options
:param default: Default option
:return: Selection
"""
options = list(options)
lows = [o.lower() for o in options]
op_text = '|'.join([f'&l&n{o}&r' if o == default else o for o in options])
printc(f'{prompt} ({op_text})')
selection = input('> ') or default
while not selection.lower() in lows:
print(f'Invalid selection! {selection} is not one of {"|".join(options)}')
selection = input('> ') or default
print()
return options[lows.index(selection)]
def center_text(txt: str, spaces: int) -> str:
"""
Put the text in the center in a defined space
>>> center_text('meow', 9)
' meow '
:param txt: Text
:param spaces: Total space of the text
:return: Text with length spaces
"""
spaces -= len(txt)
if spaces % 2 == 1:
spaces -= 1
txt += ' '
while spaces > 0:
spaces -= 2
txt = f' {txt} '
return txt
def create_config() -> Config:
"""
Create config interactively
:return: Config object (automatically stored)
"""
# Select color system
# TODO: Demo of each color system
color_system = literal_input('Which &acolor &bsystem &rdo you want to use?',
['ansi', '8bit', 'rgb'], 'rgb')
# Print preset
print('Available presets:')
spacing = max(max(len(k) for k in PRESETS.keys()), 30)
for name, preset in PRESETS.items():
printc(preset.color_text(center_text(name, spacing), foreground=False))
# preset_demo = ''.join(f'{c.to_ansi_rgb(False)} ' for c in preset.with_length(flag_length))
# printc(name + ' ' * (spacing - len(name)) + preset_demo)
print()
tmp = PRESETS['rainbow'].color_text('preset')
preset = literal_input(f'Which {tmp} do you want to use?', PRESETS.keys(), 'rainbow')
# Create config
c = Config(preset, color_system)
# Save config
save = literal_input(f'Save config?', ['y', 'n'], 'y')
if save == 'y':
c.save()
return c
def run():
# Create CLI
hyfetch = color('&b&lhy&f&lfetch&r')
parser = argparse.ArgumentParser(description=color(f'{hyfetch} - neofetch with flags <3'))
parser.add_argument('-c', '--config', action='store_true', help=color(f'Configure {hyfetch}'))
parser.add_argument('-p', '--preset', help=f'Use preset', choices=PRESETS.keys())
parser.add_argument('-m', '--mode', help=f'Color mode', choices=['ansi', '8bit', 'rgb'])
args = parser.parse_args()
# Load config
config = check_config()
# Reset config
if args.config:
create_config()
# Param overwrite config
if args.preset:
config.preset = args.preset
if args.mode:
config.mode = args.mode
# Run
run_neofetch(PRESETS.get(config.preset))