diff --git a/CHANGELOG.md b/CHANGELOG.md index 9425ec5..122bbe1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,8 @@ +# 0.3.0 + ++ Added colors ++ Added multiple Tríwat post input + # 0.2.0 + Added Tríwat post parsing utilities diff --git a/pyproject.toml b/pyproject.toml index ea4d75d..68dfcc3 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -2,11 +2,12 @@ name = "sakuragasaki46_micorail" authors = [ { name = "Sakuragasaki46" } ] dynamic = [ "version" ] -requires-python = ">=3.10" +requires-python = ">=3.12" classifiers = [ "Private :: X" ] dependencies = [ + "suou>=0.12.4" ] [tool.setuptools.dynamic] diff --git a/src/micorail/__init__.py b/src/micorail/__init__.py index b01fc9a..cf04571 100644 --- a/src/micorail/__init__.py +++ b/src/micorail/__init__.py @@ -6,7 +6,7 @@ from .utils import HourMin from .rails import main_rails from .triwat import main_triwat -__version__ = "0.2.0" +__version__ = "0.3.0" def build_parser(): parser = argparse.ArgumentParser() @@ -22,7 +22,8 @@ def build_parser(): parser_r.add_argument('-q', '--search', help='search a station by its name') parser_t = parsers.add_parser('triwat', aliases=('t',)) - parser_t.add_argument('id', help="post ID (copy from discord)") + parser_t.add_argument('--multi', help="multiple posts", action='store_true') + parser_t.add_argument('id', help="post ID (copy from discord)", nargs='?', default = None) parser_t.add_argument('parent', help="parent ID (copy from discord)", nargs='?', default=None) return parser diff --git a/src/micorail/rails.py b/src/micorail/rails.py index b254928..f1d421c 100644 --- a/src/micorail/rails.py +++ b/src/micorail/rails.py @@ -5,6 +5,9 @@ from functools import lru_cache import json from math import ceil from heapq import heapify, heappush, heappop +from suou import chalk + +from .utils import HourMin ALL_DATA = json.load(open('data/network.json')) LEGACY_DATA = json.load(open('data/network.1.json')) @@ -156,7 +159,7 @@ def main_rails(args): query = args.search.lower() for st_code, st_name in ALL_DATA['stations'].items(): if query in take_first(st_name).lower(): - print('*', st_code, st_name) + print(f'{chalk.blue('*')}', chalk.bold(st_code), st_name) return st_start = find_station(args.start) @@ -164,10 +167,10 @@ def main_rails(args): st_time = args.time if not st_start or not st_end: - print('error: missing stations') + print('**', f'{chalk.red(f'Missing stations')}') return route = find_route(st_start.code, st_end.code) for st_step, time in route: - print(HourMin(st_time + time), st_step.code, st_step.name) \ No newline at end of file + print(chalk.cyan(f'{HourMin(st_time + time)}'), chalk.bold(st_step.code), st_step.name) \ No newline at end of file diff --git a/src/micorail/triwat.py b/src/micorail/triwat.py index 2348e50..fd4dade 100644 --- a/src/micorail/triwat.py +++ b/src/micorail/triwat.py @@ -9,6 +9,8 @@ import json import sys import re +from suou import chalk + @dataclass class TriwatPost: id: str @@ -40,29 +42,37 @@ def id_to_date(id: str | int): timestamp = timestamp_millis / 1000 return datetime.datetime.fromtimestamp(EPOCH + timestamp) -def store_triwat_post(p: TriwatPost) -> bool: +def store_triwat_posts(posts: list[TriwatPost], datafile: int) -> bool: try: - with open(f"data/triwat.{int(p.id) >> 51}.json") as f: + with open(f"data/triwat.{datafile}.json") as f: data = json.load(f) except FileNotFoundError: data = {'posts': []} - post_exists = [x for x in data['posts'] if x['id'] == p.id] - if post_exists: - return False + count = 0 + + for post in posts: + post_exists = [x for x in data['posts'] if x['id'] == post.id] + if post_exists: + continue - data['posts'].append(p.to_json()) + data['posts'].append(post.to_json()) + count += 1 - with open(f'data/triwat.{int(p.id) >> 51}.json', 'w') as fw: + with open(f'data/triwat.{datafile}.json', 'w') as fw: json.dump(data, fw, indent=2) - return True + + return count -def main_triwat(args): - post_id = args.id - reply_id = args.parent or None +def input_single_post(post_id, reply_id) -> TriwatPost | None: + - whole_post = sys.stdin.read().strip() + try: + whole_post = sys.stdin.read().strip() + except KeyboardInterrupt: + print(f'** {chalk.red("Post input interrupted.")}') + raise first_line, *rest = whole_post.splitlines() @@ -95,7 +105,7 @@ def main_triwat(args): content = '\n'.join(rest) - p = TriwatPost( + return TriwatPost( id = post_id, date = id_to_date(post_id), title = title, @@ -106,8 +116,30 @@ def main_triwat(args): muted = muted ) - if store_triwat_post(p): - print(f'** Post {p.id} stored!') + +def main_triwat(args): + post_id = args.id or None + reply_id = args.parent or None + if post_id: + posts = [input_single_post(post_id, reply_id)] + elif args.multi: + posts = [] + print(f'** {chalk.blue('Multi mode enabled. ')}') + while (post_id_l := input(chalk.blue(f'[Post #{len(posts) + 1} id]: ')).strip()): + reply_id_l = input(chalk.blue(f'[Parent #{len(posts) + 1} id (optional)]: ')).strip() + posts.append(input_single_post(post_id_l, reply_id_l or None)) + else: + print(f'** {chalk.red('No post id provided. Please provide a post id and an optional reply id or use --multi option to input multiple posts.')}') + return + + store_files: dict[int, list[TriwatPost]] = {} + for p in posts: + store_files.setdefault(int(p.id) >> 51, []).append(p) + count = 0 + for datafile, postlist in store_files.items(): + count += store_triwat_posts(postlist, datafile) + + print(f'** {chalk.green(f'{count} posts stored!')}')