diff --git a/LichessClientTG_bot/formatters.py b/LichessClientTG_bot/formatters.py index da8dfce..5bed3ed 100644 --- a/LichessClientTG_bot/formatters.py +++ b/LichessClientTG_bot/formatters.py @@ -29,11 +29,6 @@ class StatsFormatter: return "-" return f"{accuracy:.0f}%" - @staticmethod - def _format_result(result: str) -> str: - """Format a raw '1-0'/'0-1'/'1/2-1/2' result string for display""" - return "½-½" if result == "1/2-1/2" else result - @staticmethod def _format_row_outcome_circle(row: dict) -> str: """ @@ -51,10 +46,11 @@ class StatsFormatter: def _format_game_rows_block(rows: list) -> str: """ Format a list of individual game rows as a column-aligned, monospace table: - outcome | accuracy(tracked) | name(tracked) | rating(tracked) | result | rating(opponent) | accuracy(opponent) + outcome | accuracy(tracked) | name(tracked)+color | rating(tracked) | vs | rating(opponent) | accuracy(opponent) Only the tracked player is named — the opponent is shown by rating/accuracy - only, keeping the line short enough for mobile screens. + only, keeping the line short enough for mobile screens. A small circle right + after the tracked player's name shows which color they played (⚪ white / ⚫ black). Column widths are computed from the actual data so every column lines up character-for-character. Caller is expected to wrap the result in a @@ -68,36 +64,36 @@ class StatsFormatter: prepared = [] for row in rows: circle = StatsFormatter._format_row_outcome_circle(row) - if row.get('tracked_is_white') is False: - tracked_name = row.get('black_name') or '?' - tracked_rating = row.get('black_rating') - tracked_accuracy = row.get('black_accuracy') - opp_rating = row.get('white_rating') - opp_accuracy = row.get('white_accuracy') - else: + tracked_is_white = row.get('tracked_is_white') is not False + color_marker = "⚪" if tracked_is_white else "⚫" + if tracked_is_white: tracked_name = row.get('white_name') or '?' tracked_rating = row.get('white_rating') tracked_accuracy = row.get('white_accuracy') opp_rating = row.get('black_rating') opp_accuracy = row.get('black_accuracy') - tracked_name = tracked_name[:NAME_WIDTH] + else: + tracked_name = row.get('black_name') or '?' + tracked_rating = row.get('black_rating') + tracked_accuracy = row.get('black_accuracy') + opp_rating = row.get('white_rating') + opp_accuracy = row.get('white_accuracy') + name_field = f"{tracked_name[:NAME_WIDTH]}{color_marker}" tr_str = str(tracked_rating) if tracked_rating is not None else "-" or_str = str(opp_rating) if opp_rating is not None else "-" ta = StatsFormatter._format_accuracy(tracked_accuracy) oa = StatsFormatter._format_accuracy(opp_accuracy) - result = StatsFormatter._format_result(row.get('result', '')) - prepared.append((circle, ta, tracked_name, tr_str, result, or_str, oa)) + prepared.append((circle, ta, name_field, tr_str, or_str, oa)) - acc_width = max(max(len(p[1]), len(p[6])) for p in prepared) - name_width = NAME_WIDTH - rating_width = max(max(len(p[3]), len(p[5])) for p in prepared) - result_width = max(len(p[4]) for p in prepared) + acc_width = max(max(len(p[1]), len(p[5])) for p in prepared) + name_width = NAME_WIDTH + 1 # +1 for the color marker glued to the name + rating_width = max(max(len(p[3]), len(p[4])) for p in prepared) lines = [] - for circle, ta, tracked_name, tr_str, result, or_str, oa in prepared: + for circle, ta, name_field, tr_str, or_str, oa in prepared: lines.append( - f"{circle} {ta:>{acc_width}} {tracked_name:<{name_width}} {tr_str:>{rating_width}} " - f"{result:^{result_width}} {or_str:>{rating_width}} {oa:>{acc_width}}" + f"{circle} {ta:>{acc_width}} {name_field:<{name_width}} {tr_str:>{rating_width}} " + f"- {or_str:>{rating_width}} {oa:>{acc_width}}" ) return "\n".join(lines)