-
Notifications
You must be signed in to change notification settings - Fork 70
Add web viewer feature for browsing downloaded messages #23
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -4,10 +4,23 @@ | |||||||||||||||||||||||||||||||||||||||||||||||
| import argparse | ||||||||||||||||||||||||||||||||||||||||||||||||
| import multiprocessing | ||||||||||||||||||||||||||||||||||||||||||||||||
| import mimetypes | ||||||||||||||||||||||||||||||||||||||||||||||||
| import sys | ||||||||||||||||||||||||||||||||||||||||||||||||
| import subprocess | ||||||||||||||||||||||||||||||||||||||||||||||||
| import webbrowser | ||||||||||||||||||||||||||||||||||||||||||||||||
| from helpers.TeleTexter import send_telegram_message | ||||||||||||||||||||||||||||||||||||||||||||||||
| from helpers.TeleViewer import process_messages | ||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||
| try: | ||||||||||||||||||||||||||||||||||||||||||||||||
| # Ensure Windows console can handle UTF-8 output (emojis, non-ASCII) | ||||||||||||||||||||||||||||||||||||||||||||||||
| if hasattr(sys.stdout, "reconfigure"): | ||||||||||||||||||||||||||||||||||||||||||||||||
| sys.stdout.reconfigure(encoding="utf-8") | ||||||||||||||||||||||||||||||||||||||||||||||||
| if hasattr(sys.stderr, "reconfigure"): | ||||||||||||||||||||||||||||||||||||||||||||||||
| sys.stderr.reconfigure(encoding="utf-8") | ||||||||||||||||||||||||||||||||||||||||||||||||
| except Exception: | ||||||||||||||||||||||||||||||||||||||||||||||||
| # Best-effort; continue if not supported | ||||||||||||||||||||||||||||||||||||||||||||||||
| pass | ||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||
| def parse_dict(title, dictionary): | ||||||||||||||||||||||||||||||||||||||||||||||||
| result = f"{title}:\n" | ||||||||||||||||||||||||||||||||||||||||||||||||
| for key, value in dictionary.items(): | ||||||||||||||||||||||||||||||||||||||||||||||||
|
|
@@ -165,8 +178,9 @@ def main(bot_token, chat_id): | |||||||||||||||||||||||||||||||||||||||||||||||
| print("4. Delete all messages from the malicious telegram channel that are sent within 24 hours\n") | ||||||||||||||||||||||||||||||||||||||||||||||||
| print("5. Get approximate number of messages on the malicious telegram channel") | ||||||||||||||||||||||||||||||||||||||||||||||||
| print("6. Download ALL messages from the malicious telegram channel") | ||||||||||||||||||||||||||||||||||||||||||||||||
| print("7. Send a file to the malicious telegram channel\n") | ||||||||||||||||||||||||||||||||||||||||||||||||
| print("8. EXIT") | ||||||||||||||||||||||||||||||||||||||||||||||||
| print("7. Send a file to the malicious telegram channel") | ||||||||||||||||||||||||||||||||||||||||||||||||
| print("8. Launch web viewer to browse downloaded messages\n") | ||||||||||||||||||||||||||||||||||||||||||||||||
| print("9. EXIT") | ||||||||||||||||||||||||||||||||||||||||||||||||
| choice = input("\nEnter your choice: ") | ||||||||||||||||||||||||||||||||||||||||||||||||
| if choice == '1': | ||||||||||||||||||||||||||||||||||||||||||||||||
| offset = None # Variable to keep track of the last update ID | ||||||||||||||||||||||||||||||||||||||||||||||||
|
|
@@ -262,21 +276,52 @@ def main(bot_token, chat_id): | |||||||||||||||||||||||||||||||||||||||||||||||
| else: | ||||||||||||||||||||||||||||||||||||||||||||||||
| print("Error: Unable to send file: ", response.get("description")) | ||||||||||||||||||||||||||||||||||||||||||||||||
| elif choice == '8': | ||||||||||||||||||||||||||||||||||||||||||||||||
| try: | ||||||||||||||||||||||||||||||||||||||||||||||||
| print("\n[*] Starting web viewer server...") | ||||||||||||||||||||||||||||||||||||||||||||||||
| print("[*] The web viewer will open in your default browser.") | ||||||||||||||||||||||||||||||||||||||||||||||||
| print("[*] Server will run on http://localhost:5000") | ||||||||||||||||||||||||||||||||||||||||||||||||
| print("[*] Press Ctrl+C in the web viewer terminal to stop the server.\n") | ||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||
| # Launch web viewer in a separate process | ||||||||||||||||||||||||||||||||||||||||||||||||
| if sys.platform == 'win32': | ||||||||||||||||||||||||||||||||||||||||||||||||
| # On Windows, create a new console window to show Flask output | ||||||||||||||||||||||||||||||||||||||||||||||||
| viewer_process = subprocess.Popen( | ||||||||||||||||||||||||||||||||||||||||||||||||
| [sys.executable, 'web_viewer.py'], | ||||||||||||||||||||||||||||||||||||||||||||||||
| creationflags=subprocess.CREATE_NEW_CONSOLE | ||||||||||||||||||||||||||||||||||||||||||||||||
| ) | ||||||||||||||||||||||||||||||||||||||||||||||||
| else: | ||||||||||||||||||||||||||||||||||||||||||||||||
| # On Unix-like systems, run in background | ||||||||||||||||||||||||||||||||||||||||||||||||
| viewer_process = subprocess.Popen( | ||||||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+288
to
+294
|
||||||||||||||||||||||||||||||||||||||||||||||||
| viewer_process = subprocess.Popen( | |
| [sys.executable, 'web_viewer.py'], | |
| creationflags=subprocess.CREATE_NEW_CONSOLE | |
| ) | |
| else: | |
| # On Unix-like systems, run in background | |
| viewer_process = subprocess.Popen( | |
| subprocess.Popen( | |
| [sys.executable, 'web_viewer.py'], | |
| creationflags=subprocess.CREATE_NEW_CONSOLE | |
| ) | |
| else: | |
| # On Unix-like systems, run in background | |
| subprocess.Popen( |
Copilot
AI
Nov 19, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This assignment to 'viewer_process' is unnecessary as it is redefined before this value is used.
Copilot
AI
Nov 19, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The subprocess is started but never properly managed or cleaned up. The viewer_process handle is created but not stored or tracked, so there's no way to stop the server gracefully when the main program exits. Consider storing the process handle and implementing cleanup in a finally block or exit handler.
Copilot
AI
Nov 19, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The code uses time.sleep(2) to wait for the Flask server to start before opening the browser. This is a race condition - on slow systems or under heavy load, 2 seconds might not be enough for Flask to start listening. Consider implementing a more robust check (e.g., polling the server with HTTP requests) or increasing the delay, or handling the case where the browser opens before the server is ready.
| # Wait a moment for server to start, then open browser | |
| time.sleep(2) | |
| webbrowser.open('http://localhost:5000') | |
| print("[*] Web viewer launched! Check the new window for the server.") | |
| # Wait for server to start by polling the endpoint | |
| server_url = 'http://localhost:5000' | |
| max_wait = 10 # seconds | |
| poll_interval = 0.5 # seconds | |
| waited = 0 | |
| while waited < max_wait: | |
| try: | |
| response = requests.get(server_url) | |
| if response.status_code == 200: | |
| webbrowser.open(server_url) | |
| print("[*] Web viewer launched! Check the new window for the server.") | |
| break | |
| except requests.exceptions.ConnectionError: | |
| pass | |
| time.sleep(poll_interval) | |
| waited += poll_interval | |
| else: | |
| print("[!] Web viewer server did not start within expected time. Please check for errors.") |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -2,3 +2,5 @@ Pyrogram==2.0.106 | |
| python-dotenv==1.0.0 | ||
| requests==2.31.0 | ||
| tgcrypto | ||
| Flask==3.0.0 | ||
| flask-cors==4.0.0 | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[nitpick] On Windows,
subprocess.CREATE_NEW_CONSOLEis used, but this flag requires importing it from subprocess. The code importssubprocessbut doesn't explicitly import the constant. While it's accessible assubprocess.CREATE_NEW_CONSOLE, be aware this is only available on Windows. The code should work as-is since it's inside a platform check, but consider adding a comment about Windows-specific behavior.