main.py 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129
  1. #!/usr/bin/env python3
  2. import argparse
  3. import json
  4. from dataclasses import dataclass
  5. from pathlib import Path
  6. from typing import Literal, Iterable
  7. from hypy_utils import printc, json_stringify
  8. from .neofetch_util import run_neofetch
  9. from .presets import PRESETS
  10. CONFIG_PATH = Path.home() / '.config/hyfetch.json'
  11. CONFIG_PATH.parent.mkdir(exist_ok=True, parents=True)
  12. @dataclass
  13. class Config:
  14. preset: str
  15. mode: Literal['default', 'ansi', '8bit', 'rgb']
  16. def save(self):
  17. CONFIG_PATH.write_text(json_stringify(self), 'utf-8')
  18. def check_config() -> Config:
  19. """
  20. Check if the configuration exists. Return the config object if it exists. If not, call the
  21. config creator
  22. TODO: Config path param
  23. :return: Config object
  24. """
  25. if CONFIG_PATH.is_file():
  26. return Config(**json.loads(CONFIG_PATH.read_text('utf-8')))
  27. return create_config()
  28. def literal_input(prompt: str, options: Iterable[str], default: str) -> str:
  29. """
  30. Ask the user to provide an input among a list of options
  31. :param prompt: Input prompt
  32. :param options: Options
  33. :param default: Default option
  34. :return: Selection
  35. """
  36. options = list(options)
  37. lows = [o.lower() for o in options]
  38. op_text = '|'.join([f'&l&n{o}&r' if o == default else o for o in options])
  39. printc(f'{prompt} ({op_text})')
  40. selection = input('> ') or default
  41. while not selection.lower() in lows:
  42. print(f'Invalid selection! {selection} is not one of {"|".join(options)}')
  43. selection = input('> ') or default
  44. print()
  45. return options[lows.index(selection)]
  46. def center_text(txt: str, spaces: int) -> str:
  47. """
  48. Put the text in the center in a defined space
  49. >>> center_text('meow', 9)
  50. ' meow '
  51. :param txt: Text
  52. :param spaces: Total space of the text
  53. :return: Text with length spaces
  54. """
  55. spaces -= len(txt)
  56. if spaces % 2 == 1:
  57. spaces -= 1
  58. txt += ' '
  59. while spaces > 0:
  60. spaces -= 2
  61. txt = f' {txt} '
  62. return txt
  63. def create_config() -> Config:
  64. """
  65. Create config interactively
  66. :return: Config object (automatically stored)
  67. """
  68. # Select color system
  69. # TODO: Demo of each color system
  70. color_system = literal_input('Which &acolor &bsystem &rdo you want to use?',
  71. ['ansi', '8bit', 'rgb'], 'rgb')
  72. # Print preset
  73. print('Available presets:')
  74. spacing = max(max(len(k) for k in PRESETS.keys()), 30)
  75. for name, preset in PRESETS.items():
  76. printc(preset.color_text(center_text(name, spacing), foreground=False))
  77. # preset_demo = ''.join(f'{c.to_ansi_rgb(False)} ' for c in preset.with_length(flag_length))
  78. # printc(name + ' ' * (spacing - len(name)) + preset_demo)
  79. print()
  80. tmp = PRESETS['rainbow'].color_text('preset')
  81. preset = literal_input(f'Which {tmp} do you want to use?', PRESETS.keys(), 'rainbow')
  82. # Create config
  83. c = Config(preset, color_system)
  84. # Save config
  85. save = literal_input(f'Save config?', ['y', 'n'], 'y')
  86. if save == 'y':
  87. c.save()
  88. return c
  89. def run():
  90. parser = argparse.ArgumentParser(description='neofetch with flags <3')
  91. # TODO: Param overwrite config
  92. config = check_config()
  93. run_neofetch(PRESETS.get(config.preset))