From e88f11a11ad13f8e9675cc003d60753fb5c517d9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B8rnar=20Kaarevik?= Date: Sat, 8 Feb 2025 23:03:20 +0100 Subject: [PATCH 1/3] Rewrite of cli to using argparse --- crystal_orb_cli.py | 124 ++++++++++++++++----------------------------- 1 file changed, 43 insertions(+), 81 deletions(-) mode change 100644 => 100755 crystal_orb_cli.py diff --git a/crystal_orb_cli.py b/crystal_orb_cli.py old mode 100644 new mode 100755 index 193db0a..562db9a --- a/crystal_orb_cli.py +++ b/crystal_orb_cli.py @@ -1,4 +1,5 @@ #!/usr/bin/env python3 +import argparse import dataclasses import sys @@ -70,94 +71,55 @@ def print_colorized_departures(stop_place: str): for dep in departures: print(dep.colorize()) -def print_help_info(): - print( -"""Help info for the crystal orb cli. -Possible commands: - - query the api for all busses from the given stop place --h or --help - Show this screen --l or --list-stop-places - List the admissible stop places. - This is configured in the STOP_PLACES dict in crystal_orb.py --n or --next - Limit the response to only the next bus matching the query --b or --bus - Limit the response to only the supplied bus line --s or --stop - Change the stop place to the supplied place --t or --to - Limit the response to buses going into town --f or --from - Limit the response to buses going away from town""") if __name__ == "__main__": - args = sys.argv - # If no arguments are passed, we just print the default stop - if len(args) < 2: - print_colorized_departures("gløshaugen") + parser = argparse.ArgumentParser() + DEFAULT_STOP_PLACE = "gløshaugen" + + # Requiring argument + parser.add_argument("-b", "--bus", + help="limit output to only the supplied bus line") + parser.add_argument("-s", "--stop", + help="limit output to only the supplied stop place") + + # No argument + parser.add_argument("-l", "--list-stop-places", action="store_true", + help="list admissible stop places") + parser.add_argument("-n", "--next", action="store_true", + help="limit output to one response, the next matching the query") + parser.add_argument("-t", "--to", action="store_true", + help="show only buses going into town") + parser.add_argument("-f", "--from", action="store_true", + help="show only buses going away from town") + args = parser.parse_args() + + # list places and exit + if args.list_stop_places: + for place in STOP_PLACES.keys(): + print(place) sys.exit(0) - if "-h" in args or "--help" in args: - print_help_info() - sys.exit(0) + # use stop input to fetch buses + if args.stop is None: + deps = get_departure_as_classes(DEFAULT_STOP_PLACE) + else: + try: + deps = get_departure_as_classes(args.stop) + except: + print(f"Stop {args.stop} not admissible. Run --list-stop-places for help.") + sys.exit(0) - # Values for control flow and processing on the available departures - stop_place = "gløshaugen" - bus_line = None - towards_city_center = None - take_one = False - - # Parse input arguments to the program - for i, arg in enumerate(args): - if i == 1 and arg[0] != "-": # First argument is taken as the stop place - stop_place = arg.lower() - elif arg == "-n" or arg == "--next": # Limits to only giving "the next bus" matching the query - take_one = True - elif arg == "-b" or arg == "--bus": # Limit to specific bus line - try: - bus_line = args[i+1] - except: - print("Bus line not supplied to -b or --bus.") - elif arg == "--list-stop-places" or arg == "-l": # Just print stop places - print("Admissible stop places:") - for place in STOP_PLACES.keys(): - print(f"\t{place}") - sys.exit() - elif arg == "-t" or arg == "--to": # Limit to buses going to town - towards_city_center = True - elif arg == "-f" or arg == "--from": # Limit to buses leaving town - towards_city_center = False - elif arg == "-s" or arg == "--stop": # Change stop - try: - stop_place = args[i+1].lower() - except: - print("Stop place not supplied to -s or --stop") - else: - pass - - # Arguments are parsed, we can execute the query - try: - deps = get_departure_as_classes(stop_place) - except: - print(f"Stop {stop_place} not admissible. Run --list-stop-places for help.") - sys.exit(0) - - if bus_line is not None: - deps = list(filter(lambda d: str(d.line) == bus_line, deps)) - if towards_city_center is not None: - if towards_city_center: - deps = list(filter(lambda d: d.towards_midtbyen, deps)) - else: - deps = list(filter(lambda d: not d.towards_midtbyen, deps)) - - if take_one: + # filter output + if args.bus is not None: + deps = list(filter(lambda d: str(d.line) == args.bus, deps)) + if args.to: + deps = list(filter(lambda d: d.towards_midtbyen, deps)) + if args.__dict__["from"]: # from is a reserved keyword in python + deps = list(filter(lambda d: not d.towards_midtbyen, deps)) + if args.next: print(deps[0].colorize()) else: for dep in deps: print(dep.colorize()) - + sys.exit(0) - - -- 2.51.2 From bdf5c31c9cda248504bc029a88805d1ac5df15f9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B8rnar=20Kaarevik?= Date: Sat, 8 Feb 2025 23:51:16 +0100 Subject: [PATCH 2/3] Handling for responses with already departed buses --- crystal_orb_cli.py | 24 +++++++++++++++--------- 1 file changed, 15 insertions(+), 9 deletions(-) diff --git a/crystal_orb_cli.py b/crystal_orb_cli.py index 562db9a..3fab8c5 100755 --- a/crystal_orb_cli.py +++ b/crystal_orb_cli.py @@ -34,22 +34,26 @@ class Departure: def __post_init__(self): self.departure_time = datetime.fromisoformat(self.departure_time) - def colorize(self): - out_str = "" - out_str += "\033[2;20;35m" + str(self.departure_time.time()) + "\033[0m" + def colorize(self, timestamp = None): + out_str = "\033[0;37m" + if timestamp is not None and self.departure_time < timestamp: + out_str += "\033[9m" + out_str += "\033[2;35m" + str(self.departure_time.time()) + "\033[22;37m" out_str += ": " out_str += pad(str(self.line), 4, justification="r") out_str += " " - out_str += "\033[3;37m" + pad(self.destination, 35+19) + "\033[0m" + out_str += "\033[3;37m" + pad(self.destination, 35+19) + "\033[23;37m" out_str += " (" - if self.is_realtime: out_str += "\033[0;32mR\033[0m" + if self.is_realtime: out_str += "\033[32mR\033[37m" else: out_str += " " out_str += ", " - if self.towards_midtbyen: out_str += "\033[0;32mTo \033[0m" - else: out_str += "\033[0;31mFrom\033[0m" + if self.towards_midtbyen: out_str += "\033[32mTo \033[37m" + else: out_str += "\033[31mFrom\033[37m" out_str += ")" + if timestamp is not None and self.departure_time < timestamp: + out_str += "\033[0m" return out_str @@ -116,10 +120,12 @@ if __name__ == "__main__": deps = list(filter(lambda d: d.towards_midtbyen, deps)) if args.__dict__["from"]: # from is a reserved keyword in python deps = list(filter(lambda d: not d.towards_midtbyen, deps)) + current_time = datetime.now() if args.next: - print(deps[0].colorize()) + deps = list(filter(lambda d: d.departure_time > current_time, deps)) + print(deps[0].colorize(current_time)) else: for dep in deps: - print(dep.colorize()) + print(dep.colorize(current_time)) sys.exit(0) -- 2.51.2 From b756581e3568b9fc7937d3df329b63d381ad2683 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B8rnar=20Kaarevik?= Date: Sat, 1 Mar 2025 22:38:31 +0100 Subject: [PATCH 3/3] Added all suggestions from review of oysteikt --- crystal_orb_cli.py | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/crystal_orb_cli.py b/crystal_orb_cli.py index 3fab8c5..5233151 100755 --- a/crystal_orb_cli.py +++ b/crystal_orb_cli.py @@ -80,20 +80,20 @@ if __name__ == "__main__": parser = argparse.ArgumentParser() DEFAULT_STOP_PLACE = "gløshaugen" - # Requiring argument + # Requiring value parser.add_argument("-b", "--bus", help="limit output to only the supplied bus line") parser.add_argument("-s", "--stop", help="limit output to only the supplied stop place") - # No argument + # Boolean flags parser.add_argument("-l", "--list-stop-places", action="store_true", help="list admissible stop places") parser.add_argument("-n", "--next", action="store_true", help="limit output to one response, the next matching the query") parser.add_argument("-t", "--to", action="store_true", help="show only buses going into town") - parser.add_argument("-f", "--from", action="store_true", + parser.add_argument("-f", "--from", action="store_true", dest="from_", help="show only buses going away from town") args = parser.parse_args() @@ -115,11 +115,11 @@ if __name__ == "__main__": # filter output if args.bus is not None: - deps = list(filter(lambda d: str(d.line) == args.bus, deps)) + deps = [d for d in deps if d.line == args.bus] if args.to: - deps = list(filter(lambda d: d.towards_midtbyen, deps)) - if args.__dict__["from"]: # from is a reserved keyword in python - deps = list(filter(lambda d: not d.towards_midtbyen, deps)) + deps = [d for d in deps if d.towards_midtbyen] + if args.from_: + deps = [d for d in deps if not d.towards_midtbyen] current_time = datetime.now() if args.next: deps = list(filter(lambda d: d.departure_time > current_time, deps)) -- 2.51.2