diff --git a/durdraw/durfetch.py b/durdraw/durfetch.py index 759a4a3..819b24e 100644 --- a/durdraw/durfetch.py +++ b/durdraw/durfetch.py @@ -86,13 +86,15 @@ def main(): parser.add_argument("-V", "--version", help="Show Version information and quit", action="store_true") #parser.add_argument("-l", nargs="?", default="list") args = parser.parse_args() - use_fetcher = "neofetch" - if neofetcher.fetcher_available(name=use_fetcher): - print("Pulling data from neofetch.") - neofetch_data = neofetcher.run() + if (fetcher := neofetcher.find_available_fetcher()): + print(f"Pulling data from {fetcher}.") + fetch_data = neofetcher.run(fetcher) print("done.") else: - print(f"Error: Durfetch requires {use_fetcher}. Please make sure \"{use_fetcher}\" is installed and in the PATH.") + print("Error: Durfetch requires one of the following fetchers:") + for fetcher in neofetcher.od_fetchers.keys(): + print(f" -> {fetcher}") + print("Please make sure one of the above is installed and in the PATH.") exit(1) #print(args.filename, args.list, args.l, neofetch_data) #if args.filename == None: # no file name passed, so pick an appropriate one. @@ -111,9 +113,9 @@ def main(): exit(1) elif args.filename == []: # no file name passed, so pick an appropriate one. if args.rand: # don't prefix path, cuz all_dur_files() already did it - filename = [auto_load_file(neofetch_data, rand=args.rand, fake_os=faked)] + filename = [auto_load_file(fetch_data, rand=args.rand, fake_os=faked)] else: - filename = [get_internal_durf_path() + "/" + auto_load_file(neofetch_data, fake_os=faked)] + filename = [get_internal_durf_path() + "/" + auto_load_file(fetch_data, fake_os=faked)] else: filename = args.filename #print(filename) diff --git a/durdraw/neofetcher.py b/durdraw/neofetcher.py index 3085106..224874d 100644 --- a/durdraw/neofetcher.py +++ b/durdraw/neofetcher.py @@ -1,12 +1,20 @@ # Run Neofetch. Extract data from it. Return a dict containing neofetch data. import os -import pathlib +import shutil import re import subprocess +from typing import OrderedDict neo_keys = ['OS', 'Host', 'Kernel', 'Uptime', 'Packages', 'Shell', 'Resolution', 'DE', 'WM', 'WM Theme', 'Terminal', 'Terminal Font', 'CPU', 'GPU', 'Memory'] +# list of available fetchers - name: cmd +# dictionary order determines cmd priority if multiple are present +od_fetchers = OrderedDict({ + "fastfetch": ["fastfetch", "--pipe", "-l", "none"], + "neofetch": ["neofetch", "--stdout"], +}) + def strip_escape_codes(text): # 7-bit C1 ANSI sequences ansi_escape = re.compile(r''' @@ -24,47 +32,45 @@ def strip_escape_codes(text): text = re.sub(r'\d+\.\d+ms', '', text).strip() return text -def fetcher_available(name="neofetch"): - arg = "--version" - try: - devnull = open(os.devnull) - subprocess.Popen([name, arg], stdout=devnull, stderr=devnull).communicate() - except OSError as e: - #if e.errno == os.errno.ENOENT: - # return False - return False - return True +def fetcher_available(name: str) -> bool: + return (name in od_fetchers) and bool(shutil.which(name)) + +def find_available_fetcher() -> str: + for key, _ in od_fetchers.items(): + if fetcher_available(key): + return key + return "" + +def run(fetcher=""): + if not fetcher and not (fetcher := find_available_fetcher()): + return -def run(): # make an empty dict of Neofetch keys for us to populate and return - neofetch_results = {} - for key in neo_keys: - neofetch_results[key] = '' - # Run neofetch, capture the output - #fetcher_exec = pathlib.Path(__file__).parent.joinpath("neofetch/neofetch") - fetcher_exec = ["neofetch", "--stdout"] # not a full path. just the executable run from the $PATH - #fetcher_exec = ["fastfetch", "-c", "ci"] # not a full path. just the executable run from the $PATH - neofetch_output = subprocess.check_output(fetcher_exec).decode() - neofetch_lines = neofetch_output.split('\n')[2:] - # Parse the neofetch output into neofetch_results{} - for line in neofetch_lines: + fetch_results = {key: '' for key in neo_keys} + # ignore parent process so fastfetch correctly determines the shell + env = os.environ.copy() + env['FFTS_IGNORE_PARENT'] = '1' + fetch_output = subprocess.check_output(od_fetchers[fetcher], env=env).decode() + fetch_lines = fetch_output.split('\n')[2:] + # Parse the fetch output into fetch_results{} + for line in fetch_lines: if line == '': break try: - line = strip_escape_codes(line) + #line = strip_escape_codes(line) key = line.split(': ')[0].strip() value = line.split(': ')[1].strip() #value = value.split(' ')[0].strip() # Remove trailing " 0.020ms" crap. #new_value = re.sub(r'ms$', " ", value) #new_value = re.sub(r'\s+\d+\.\d+ms$', '', value).strip() - new_value = value + #new_value = value #print(f"found key: {key}, new_value: {new_value}") except: break - if key in neo_keys: - neofetch_results[key] = value - return neofetch_results + if key in fetch_results: + fetch_results[key] = value + return fetch_results if __name__ == "__main__": results = run()