mirror of
https://github.com/tiennm99/export-telegram-group-members.git
synced 2026-10-11 03:13:26 +00:00
feat(compare): render git diff style output
This commit is contained in:
1 parent
10298f4f5e
commit
24bf801656
2 files changed
+53
-20
No files matched your search
@@ -49,7 +49,8 @@ If `time1` and `time2` are omitted, the command compares the latest two crawls f
|
|||||||
python compare.py <group_id>
|
python compare.py <group_id>
|
||||||
```
|
```
|
||||||
|
|
||||||
The output lists members added in `time2` and removed since `time1`.
|
The output uses a git-diff-style view: removed members are prefixed with `-`,
|
||||||
|
added members are prefixed with `+`, and the hunk header shows member counts.
|
||||||
|
|
||||||
## Configuration
|
## Configuration
|
||||||
|
|
||||||
|
|||||||
+51
-19
@@ -1,6 +1,11 @@
|
|||||||
import argparse
|
import argparse
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
|
RESET = '\033[0m'
|
||||||
|
GREEN = '\033[32m'
|
||||||
|
RED = '\033[31m'
|
||||||
|
CYAN = '\033[36m'
|
||||||
|
|
||||||
|
|
||||||
def parse_args():
|
def parse_args():
|
||||||
parser = argparse.ArgumentParser(
|
parser = argparse.ArgumentParser(
|
||||||
@@ -48,38 +53,65 @@ def print_summary(group_id, before_record, after_record, added, removed):
|
|||||||
title = after_record.get('title') or before_record.get('title') or ''
|
title = after_record.get('title') or before_record.get('title') or ''
|
||||||
before_members = before_record.get('members', [])
|
before_members = before_record.get('members', [])
|
||||||
after_members = after_record.get('members', [])
|
after_members = after_record.get('members', [])
|
||||||
|
before_time = before_record.get('time')
|
||||||
|
after_time = after_record.get('time')
|
||||||
|
label = f'{title} ({group_id})' if title else str(group_id)
|
||||||
|
|
||||||
print(f'group: {title} ({group_id})' if title else f'group: {group_id}')
|
print(f'diff --telegram-group "{label}"')
|
||||||
print(f'before: {before_record.get("time")} ({len(before_members)} members)')
|
print(color(f'--- crawl/{before_time}', RED))
|
||||||
print(f'after: {after_record.get("time")} ({len(after_members)} members)')
|
print(color(f'+++ crawl/{after_time}', GREEN))
|
||||||
|
print(color(
|
||||||
|
f'@@ members: {len(before_members)} -> {len(after_members)} '
|
||||||
|
f'(+{len(added)} -{len(removed)}) @@',
|
||||||
|
CYAN,
|
||||||
|
))
|
||||||
print()
|
print()
|
||||||
|
|
||||||
print(f'added: {len(added)}')
|
widths = column_widths([*removed, *added])
|
||||||
for member in added:
|
|
||||||
print(f'+ {format_member(member)}')
|
|
||||||
|
|
||||||
print()
|
|
||||||
print(f'removed: {len(removed)}')
|
|
||||||
for member in removed:
|
for member in removed:
|
||||||
print(f'- {format_member(member)}')
|
print(color(format_member_row('-', member, widths), RED))
|
||||||
|
for member in added:
|
||||||
|
print(color(format_member_row('+', member, widths), GREEN))
|
||||||
|
|
||||||
if not added and not removed:
|
if not added and not removed:
|
||||||
print()
|
print(' no membership changes.')
|
||||||
print('no membership changes.')
|
|
||||||
|
|
||||||
|
|
||||||
def format_member(member):
|
def color(text, code):
|
||||||
parts = [str(member.get('id'))]
|
if not sys.stdout.isatty():
|
||||||
|
return text
|
||||||
|
return f'{code}{text}{RESET}'
|
||||||
|
|
||||||
|
|
||||||
|
def member_columns(member):
|
||||||
username = member.get('username')
|
username = member.get('username')
|
||||||
full_name = ' '.join(
|
full_name = ' '.join(
|
||||||
part for part in [member.get('first_name'), member.get('last_name')]
|
part for part in [member.get('first_name'), member.get('last_name')]
|
||||||
if part
|
if part
|
||||||
)
|
)
|
||||||
if username:
|
return [
|
||||||
parts.append(f'@{username}')
|
str(member.get('id')),
|
||||||
if full_name:
|
f'@{username}' if username else '',
|
||||||
parts.append(full_name)
|
full_name,
|
||||||
return ' | '.join(parts)
|
]
|
||||||
|
|
||||||
|
|
||||||
|
def column_widths(members):
|
||||||
|
widths = [2, 8, 4]
|
||||||
|
for member in members:
|
||||||
|
for index, value in enumerate(member_columns(member)):
|
||||||
|
widths[index] = max(widths[index], len(value))
|
||||||
|
return widths
|
||||||
|
|
||||||
|
|
||||||
|
def format_member_row(prefix, member, widths):
|
||||||
|
member_id, username, full_name = member_columns(member)
|
||||||
|
return (
|
||||||
|
f'{prefix} '
|
||||||
|
f'{member_id:<{widths[0]}} '
|
||||||
|
f'{username:<{widths[1]}} '
|
||||||
|
f'{full_name:<{widths[2]}}'
|
||||||
|
).rstrip()
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
|
|||||||
Reference in new issue
Block a user