Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions app.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@

logging.basicConfig(level=logging.INFO)

from commands import IngTranscribeCommand, IngGPTCommand
from commands import IngTranscribeCommand, IngGPTCommand, ExportChatCommand

from control import ClientHandler, ClientFactory
import typer
Expand Down Expand Up @@ -45,9 +45,9 @@ def add_client(session: str):
:return: None
"""
new_client = {
"session_name": session,
"commands": ["IngTranscribeCommand", "IngGPTCommand"]
}
"session_name": session,
"commands": ["IngTranscribeCommand", "IngGPTCommand", "ExportChatCommand"]
}
client_data.append(new_client)
# save json
with open(clients_file_path, 'w') as f:
Expand Down
1 change: 1 addition & 0 deletions commands/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,5 @@

from commands.ing_transcribe import IngTranscribeCommand
from .ing_gpt import IngGPTCommand
from .export_chat import ExportChatCommand

61 changes: 61 additions & 0 deletions commands/export_chat.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
from .base import Command
import time
import datetime


class ExportChatCommand(Command):
"""Export chat history to a text file."""
command_name = "/export"
aliases = ["export"]

async def execute(self):
peer_id = self.event.message.peer_id
progress = await self.client_handler.send_message(peer_id, "Starting export...")
try:
text = await self._collect_messages(peer_id, progress)
await self.client_handler.edit_message(peer_id, progress.id, "Sending export...")
await self.client_handler.send_text_as_file(peer_id, text, "chat_export.txt", reply_to=self.event.message.id)
finally:
await self.client_handler.delete_message(peer_id, progress.id)
await self.client_handler.delete_message(peer_id, self.event.message.id)

async def _collect_messages(self, peer_id, progress_message):
client = self.client_handler.client
total = (await client.get_messages(peer_id, limit=0)).total
count = 0
last_update = time.time()
current_day = None
lines = []
async for msg in client.iter_messages(peer_id, reverse=True):
count += 1
if msg.text and not msg.text.startswith(self.command_name):
date = msg.date.astimezone()
day = date.strftime('%Y-%m-%d')
if day != current_day:
lines.append(f"\n{day}\n")
current_day = day
sender = await msg.get_sender()
name_parts = []
if getattr(sender, 'first_name', None):
name_parts.append(sender.first_name)
if getattr(sender, 'last_name', None):
name_parts.append(sender.last_name)
name = ' '.join(name_parts)
username = f"@{sender.username}" if getattr(sender, 'username', None) else ''
header = f"{name} [{username}] - {date.strftime('%H:%M')}" if username else f"{name} - {date.strftime('%H:%M')}"
lines.append(header)
lines.append(msg.text)
lines.append("")
now = time.time()
if now - last_update >= 5:
percent = count / total * 100 if total else 0
bar = self._progress_bar(percent)
await self.client_handler.edit_message(peer_id, progress_message.id,
f"Exporting {bar} {percent:.1f}% ({count}/{total})")
last_update = now
return "\n".join(lines)

@staticmethod
def _progress_bar(percent, length=20):
filled = int(length * percent / 100)
return '[' + '=' * filled + ' ' * (length - filled) + ']'