mirror of
https://github.com/avitoras/telegram-tui.git
synced 2025-07-27 11:20:31 +00:00
Добавлен логин, а также теперь все строки в файлах не превышают лимит в 79 символов (PEP 8)
This commit is contained in:
parent
38625d929b
commit
051add865a
102
app/app.py
102
app/app.py
@ -1,91 +1,15 @@
|
||||
from telethon import TelegramClient, events
|
||||
from telethon.errors import SessionPasswordNeededError
|
||||
from textual.app import App, ComposeResult
|
||||
from textual.containers import Horizontal, VerticalScroll, Vertical
|
||||
from textual.widgets import Static, Footer, Label, Input, Button
|
||||
from textual.screen import Screen
|
||||
from textual.events import Event
|
||||
from widgets.chat import Chat
|
||||
from widgets.dialog import Dialog
|
||||
from textual.screen import Screen
|
||||
#from telegram.client import TelegramClientWrapper
|
||||
from tokens import api_id, api_hash
|
||||
|
||||
class ChatScreen(Screen):
|
||||
"""Класс экрана чатов, он же основной экран приложения"""
|
||||
|
||||
def __init__(self, name = None, id = None, classes = None, telegram_client = None):
|
||||
super().__init__(name, id, classes)
|
||||
self.telegram_client = telegram_client
|
||||
self.telegram_client.on(events.NewMessage())(self.update_chat_list)
|
||||
|
||||
def on_mount(self):
|
||||
self.chat_container = self.query_one("#main_container").query_one("#chats").query_one("#chat_container")
|
||||
|
||||
self.limit = 100
|
||||
for i in range(self.limit):
|
||||
chat = Chat(id=f"chat-{i + 1}", notify_func=self.notify)
|
||||
self.chat_container.mount(chat)
|
||||
#self.mount_chats(limit=25)
|
||||
|
||||
def mount_chats(self, limit: int):
|
||||
self.limit = limit
|
||||
chats_amount = len(self.chat_container.query(Chat))
|
||||
if limit > chats_amount:
|
||||
for i in range(limit - chats_amount):
|
||||
chat = Chat(id=f"chat-{i + 1 + (limit - chats_amount)}")
|
||||
self.chat_container.mount(chat)
|
||||
elif not (limit == chats_amount):
|
||||
for i in range(chats_amount - limit):
|
||||
self.chat_container.query(Chat).last().remove()
|
||||
|
||||
async def update_chat_list(self):
|
||||
dialogs = await self.telegram_client.get_dialogs(limit=self.limit)
|
||||
|
||||
for i in range(len(dialogs)):
|
||||
chat = self.chat_container.query_one(f"#chat-{i + 1}")
|
||||
chat.username = str(dialogs[i].name)
|
||||
chat.msg = str(dialogs[i].message.message)
|
||||
chat.peer_id = dialogs[i].id
|
||||
#self.notify("Новое сообщение") #колхоз дебаг
|
||||
|
||||
def compose(self) -> ComposeResult:
|
||||
yield Footer()
|
||||
with Horizontal(id="main_container"):
|
||||
with Horizontal(id="chats"):
|
||||
yield VerticalScroll(Static(id="chat_container"))
|
||||
#TODO: сделать кнопку чтобы прогрузить больше чатов, это оптимизация
|
||||
|
||||
yield Dialog()
|
||||
|
||||
class AuthScreen(Screen):
|
||||
"""Это будет классом экрана логина"""
|
||||
|
||||
def __init__(self, name = None, id = None, classes = None, telegram_client: TelegramClient | None = None):
|
||||
super().__init__(name, id, classes)
|
||||
self.client = telegram_client
|
||||
self.ac = self.query_one("#auth_container")
|
||||
|
||||
def compose(self):
|
||||
with Vertical(id="auth_container"):
|
||||
yield Label("Добро пожаловать в Telegram TUI")
|
||||
yield Input(placeholder="Номер телефона", id="phone")
|
||||
yield Input(placeholder="Код", id="code", disabled=True)
|
||||
yield Input(placeholder="Пароль", id="password", password=True, disabled=True)
|
||||
|
||||
async def on_submit(self, event: Input.Submitted) -> None:
|
||||
if event.button.id == "phone":
|
||||
await self.client.send_code_request(event.value)
|
||||
for i in ("#phone", "#password"):
|
||||
self.ac.query_one(i).disabled = True
|
||||
self.ac.query_one("#code").disabled = False
|
||||
elif event.button.id == "code":
|
||||
await self.client.sign_in(event.value)
|
||||
for i in ("#phone", "#code"):
|
||||
self.ac.query_one(i).disabled = True
|
||||
self.ac.query_one("#password").disabled = False
|
||||
elif event.button.id == "password":
|
||||
await self.client.sign_in(event.value)
|
||||
for i in ("#phone", "#password"):
|
||||
self.ac.query_one(i).disabled = True
|
||||
self.ac.query_one("#code").disabled = True
|
||||
from screens.auth_screen import AuthScreen
|
||||
from screens.chat_screen import ChatScreen
|
||||
|
||||
class TelegramTUI(App):
|
||||
"""Класс приложения"""
|
||||
@ -93,23 +17,19 @@ class TelegramTUI(App):
|
||||
CSS_PATH = "../tcss/style.tcss"
|
||||
#SCREENS = {"chats": ChatScreen}
|
||||
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
|
||||
async def on_mount(self) -> None:
|
||||
self.telegram_client = TelegramClient("user", api_id, api_hash)
|
||||
await self.telegram_client.start()
|
||||
await self.telegram_client.connect()
|
||||
|
||||
chat_screen = ChatScreen(telegram_client=self.telegram_client)
|
||||
self.install_screen(chat_screen, name="chats")
|
||||
|
||||
if not await self.telegram_client.is_user_authorized():
|
||||
auth_screen = AuthScreen(telegram_client=self.telegram_client)
|
||||
self.install_screen(auth_screen, name="auth")
|
||||
self.push_screen("auth")
|
||||
|
||||
"""chat_screen = ChatScreen(telegram_client=self.telegram_client)
|
||||
self.install_screen(chat_screen, name="chats")
|
||||
self.push_screen("chats")
|
||||
await self.telegram_client.start()
|
||||
await chat_screen.update_chat_list()"""
|
||||
else:
|
||||
self.push_screen("chats")
|
||||
|
||||
async def on_exit_app(self):
|
||||
await self.telegram_client.disconnect()
|
||||
|
56
screens/auth_screen.py
Normal file
56
screens/auth_screen.py
Normal file
@ -0,0 +1,56 @@
|
||||
from textual.screen import Screen
|
||||
from textual.widgets import Label, Input
|
||||
from textual.containers import Vertical
|
||||
from telethon import TelegramClient
|
||||
from telethon.errors import SessionPasswordNeededError
|
||||
|
||||
class AuthScreen(Screen):
|
||||
"""Класс логина в аккаунт"""
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
name = None,
|
||||
id = None,
|
||||
classes = None,
|
||||
telegram_client: TelegramClient | None = None
|
||||
):
|
||||
super().__init__(name, id, classes)
|
||||
self.client = telegram_client
|
||||
|
||||
def on_mount(self):
|
||||
self.ac = self.query_one("#auth_container")
|
||||
|
||||
def compose(self):
|
||||
with Vertical(id="auth_container"):
|
||||
yield Label("Добро пожаловать в Telegram TUI")
|
||||
yield Input(placeholder="Номер телефона", id="phone")
|
||||
yield Input(placeholder="Код", id="code", disabled=True)
|
||||
yield Input(
|
||||
placeholder="Пароль",
|
||||
id="password",
|
||||
password=True,
|
||||
disabled=True
|
||||
)
|
||||
|
||||
async def on_input_submitted(self, event: Input.Submitted) -> None:
|
||||
if event.input.id == "phone":
|
||||
self.phone = event.value
|
||||
self.ac.query_one("#phone").disabled = True
|
||||
self.ac.query_one("#code").disabled = False
|
||||
await self.client.send_code_request(phone=self.phone)
|
||||
elif event.input.id == "code":
|
||||
try:
|
||||
self.code = event.value
|
||||
self.ac.query_one("#code").disabled = True
|
||||
await self.client.sign_in(phone=self.phone, code=self.code)
|
||||
self.app.pop_screen()
|
||||
self.app.push_screen("chats")
|
||||
except SessionPasswordNeededError:
|
||||
self.ac.query_one("#code").disabled = True
|
||||
self.ac.query_one("#password").disabled = False
|
||||
elif event.input.id == "password":
|
||||
self.password = event.value
|
||||
await self.client.sign_in(password=self.password)
|
||||
await self.client.start()
|
||||
self.app.pop_screen()
|
||||
self.app.push_screen("chats")
|
64
screens/chat_screen.py
Normal file
64
screens/chat_screen.py
Normal file
@ -0,0 +1,64 @@
|
||||
from textual.screen import Screen
|
||||
from textual.widgets import Footer, Static
|
||||
from textual.containers import Horizontal, VerticalScroll
|
||||
from telethon import TelegramClient, events
|
||||
from widgets.dialog import Dialog
|
||||
from widgets.chat import Chat
|
||||
|
||||
class ChatScreen(Screen):
|
||||
"""Класс экрана чатов, он же основной экран приложения"""
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
name = None,
|
||||
id = None,
|
||||
classes = None,
|
||||
telegram_client: TelegramClient | None = None
|
||||
):
|
||||
super().__init__(name, id, classes)
|
||||
self.telegram_client = telegram_client
|
||||
self.telegram_client.on(events.NewMessage())(self.update_chat_list)
|
||||
|
||||
async def on_mount(self):
|
||||
self.chat_container = self\
|
||||
.query_one("#main_container")\
|
||||
.query_one("#chats")\
|
||||
.query_one("#chat_container")
|
||||
|
||||
self.limit = 100
|
||||
for i in range(self.limit):
|
||||
chat = Chat(id=f"chat-{i + 1}", notify_func=self.notify)
|
||||
self.chat_container.mount(chat)
|
||||
#self.mount_chats(limit=25)
|
||||
|
||||
await self.update_chat_list()
|
||||
|
||||
def mount_chats(self, limit: int):
|
||||
self.limit = limit
|
||||
chats_amount = len(self.chat_container.query(Chat))
|
||||
if limit > chats_amount:
|
||||
for i in range(limit - chats_amount):
|
||||
chat = Chat(id=f"chat-{i + 1 + (limit - chats_amount)}")
|
||||
self.chat_container.mount(chat)
|
||||
elif not (limit == chats_amount):
|
||||
for i in range(chats_amount - limit):
|
||||
self.chat_container.query(Chat).last().remove()
|
||||
|
||||
async def update_chat_list(self):
|
||||
dialogs = await self.telegram_client.get_dialogs(limit=self.limit)
|
||||
|
||||
for i in range(len(dialogs)):
|
||||
chat = self.chat_container.query_one(f"#chat-{i + 1}")
|
||||
chat.username = str(dialogs[i].name)
|
||||
chat.msg = str(dialogs[i].message.message)
|
||||
chat.peer_id = dialogs[i].id
|
||||
#self.notify("Новое сообщение") #колхоз дебаг
|
||||
|
||||
def compose(self):
|
||||
yield Footer()
|
||||
with Horizontal(id="main_container"):
|
||||
with Horizontal(id="chats"):
|
||||
yield VerticalScroll(Static(id="chat_container"))
|
||||
#TODO: сделать кнопку чтобы прогрузить больше чатов
|
||||
|
||||
yield Dialog()
|
@ -1,3 +1,8 @@
|
||||
"""
|
||||
ЭТОТ ФАЙЛ БОЛЬШЕ НЕ ИСПОЛЬЗУЕТСЯ
|
||||
СКОРО УДАЛИМ
|
||||
"""
|
||||
|
||||
from telethon import TelegramClient, events, utils
|
||||
|
||||
class TelegramClientWrapper:
|
||||
|
@ -1,2 +1,4 @@
|
||||
api_hash = 111
|
||||
api_id = 11
|
||||
"""Получите свои API-ключи на https://my.telegram.org/apps"""
|
||||
|
||||
api_id = 12345
|
||||
api_hash = "0123456789abcdef"
|
@ -10,8 +10,20 @@ class Chat(Widget):
|
||||
msg = Reactive(" ", recompose=True)
|
||||
peer_id = Reactive(0)
|
||||
|
||||
def __init__(self, name: str | None = None, notify_func = None, id: str | None = None, classes: str | None = None, disabled: bool = False):
|
||||
super().__init__(name=str(name), id=id, classes=classes, disabled=disabled)
|
||||
def __init__(
|
||||
self,
|
||||
name: str | None = None,
|
||||
notify_func = None,
|
||||
id: str | None = None,
|
||||
classes: str | None = None,
|
||||
disabled: bool = False
|
||||
):
|
||||
super().__init__(
|
||||
name=str(name),
|
||||
id=id,
|
||||
classes=classes,
|
||||
disabled=disabled
|
||||
)
|
||||
self.notify = notify_func
|
||||
|
||||
def _on_click(self):
|
||||
|
@ -15,9 +15,15 @@ class Dialog(Widget):
|
||||
yield Message(message="привет, я ыплыжлп", is_me=True)
|
||||
yield Message(message="о, дщытрапшщцрущ", is_me=False)
|
||||
yield Message(message="ДАТОУШЩАРШЩУРЩША!!!!", is_me=False)
|
||||
# должно быть примерно is_me = message.from_id == client.get_peer_id("me")
|
||||
# должно быть примерно
|
||||
# is_me = message.from_id == client.get_peer_id("me")
|
||||
|
||||
# но я могу ошибаться, я это фиш если что
|
||||
#TODO: сделать кнопку чтобы прогрузить больше сообщений, но при этом чтобы при перезаходе в чат оставались прогруженными только 10 сообщений, а остальные декомпоузились
|
||||
|
||||
#TODO: сделать кнопку чтобы прогрузить больше сообщений,
|
||||
#но при этом чтобы при перезаходе в чат оставались
|
||||
#прогруженными только 10 сообщений,
|
||||
#а остальные декомпоузились
|
||||
|
||||
with Horizontal(id="input_place"):
|
||||
yield Input(placeholder="Сообщение", id="msg_input")
|
||||
|
@ -5,7 +5,15 @@ from textual.widget import Widget
|
||||
class Message(Widget):
|
||||
"""Класс виджета сообщений для окна диалога"""
|
||||
|
||||
def __init__(self, name=None, message=None, is_me=None, id=None, classes=None, disabled=False):
|
||||
def __init__(
|
||||
self,
|
||||
name=None,
|
||||
message=None,
|
||||
is_me=None,
|
||||
id=None,
|
||||
classes=None,
|
||||
disabled=False
|
||||
):
|
||||
super().__init__(name=name, id=id, classes=classes, disabled=disabled)
|
||||
self.message = message
|
||||
self.is_me = is_me
|
||||
|
Loading…
x
Reference in New Issue
Block a user