hyfetch/hyfetch/main.py
2022-04-10 22:50:11 -04:00

168 lines
4.5 KiB
Python
Executable file

#!/usr/bin/env python3
from __future__ import annotations
import argparse
import json
from dataclasses import dataclass
from pathlib import Path
from typing import Iterable
from hypy_utils import printc, json_stringify, color
from .color_util import AnsiMode
from .neofetch_util import run_neofetch
from .presets import PRESETS, ColorProfile
CONFIG_PATH = Path.home() / '.config/hyfetch.json'
CONFIG_PATH.parent.mkdir(exist_ok=True, parents=True)
@dataclass
class Config:
preset: str
mode: AnsiMode
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?',
['8bit', 'rgb'], 'rgb')
# Print preset
print('Available presets:\n')
spacing = max(max(len(k) for k in PRESETS.keys()), 30)
flags = []
for name, preset in PRESETS.items():
flags.append([preset.color_text(' ' * spacing, foreground=False),
'&0' + preset.color_text(center_text(name, spacing), foreground=False),
preset.color_text(' ' * spacing, foreground=False)])
flags_per_row = 3
while flags:
current = flags[:flags_per_row]
flags = flags[flags_per_row:]
for line in range(len(current[0])):
printc(' '.join(flag[line] for flag in current))
print()
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=['8bit', 'rgb'])
parser.add_argument('--c-scale', dest='scale', help=f'Lighten colors by a multiplier', type=float)
parser.add_argument('--c-set-l', dest='light', help=f'Set lightness value of the colors', type=float)
args = parser.parse_args()
# Load config
config = check_config()
# Reset config
if args.config:
config = create_config()
# Param overwrite config
if args.preset:
config.preset = args.preset
if args.mode:
config.mode = args.mode
preset = PRESETS.get(config.preset)
# Lighten
if args.scale:
preset = ColorProfile([c.lighten(args.scale) for c in preset.colors])
if args.light:
preset = ColorProfile([c.set_light(args.light) for c in preset.colors])
# Run
run_neofetch(preset, config.mode)