Skip to content
Merged
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
2 changes: 2 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,8 @@ add_library(tg-cli-lib
src/controllers/AuthController.cpp
src/controllers/GetChatsController.cpp
src/controllers/SendMessageController.cpp
src/controllers/ChatHistoryController.cpp
src/facade/TgClientFacade.cpp
)

target_include_directories(tg-cli-lib
Expand Down
37 changes: 16 additions & 21 deletions main/main.cpp
Original file line number Diff line number Diff line change
@@ -1,25 +1,20 @@
#include "../src/tgClient/ITgClient.hpp"
#include "../src/tgClient/TgClientTdlib.hpp"
// main/main.cpp
#include <iostream>

int main() {
TgClientTdlib a = TgClientTdlib();
auto temp = a.check_status();
#include "../src/tgClient/TgClientTdlib.hpp"
#include "../src/facade/TgClientFacade.h"

int main(int argc, char** argv) {
try {
TgClientTdlib client;
TgClientFacade facade(client);

std::cout << "waitingPhone " << (temp == TgClientTdlib::AuthState::WaitingPhone) << std::endl;
std::cout << "WaitingCode " << (temp == TgClientTdlib::AuthState::WaitingCode) << std::endl;
std::cout << "WaitingPassword " << (temp == TgClientTdlib::AuthState::WaitingPassword) << std::endl;
std::cout << "WaitingParameters " << (temp == TgClientTdlib::AuthState::WaitingTdlibParameters) << std::endl;
std::cout << "Ready " << (temp == TgClientTdlib::AuthState::Ready) << std::endl;
std::cout << "LogginOut " << (temp == TgClientTdlib::AuthState::LoggingOut) << std::endl;
std::cout << "error " << (temp == TgClientTdlib::AuthState::Error) << std::endl;
enum class AuthState {
WaitingPhone,
WaitingCode,
WaitingPassword,
WaitingTdlibParameters,
Ready,
LoggingOut,
Error,
};
return facade.run(argc, argv);
} catch (const std::exception& e) {
std::cerr << "[tgcli] fatal error: " << e.what() << "\n";
return 1;
} catch (...) {
std::cerr << "[tgcli] fatal error: unknown exception\n";
return 1;
}
}
102 changes: 44 additions & 58 deletions src/controllers/AuthController.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
#include "AuthController.h"
#include <iostream>
#include <stdexcept>
#include <algorithm>

// Конструктор
AuthController::AuthController(ITgClient& client)
Expand All @@ -11,6 +12,8 @@ AuthController::AuthController(ITgClient& client)
update_status();
}

AuthController::~AuthController() = default;

void AuthController::update_status() {
try {
current_state_ = client_.check_status();
Expand All @@ -28,83 +31,66 @@ bool AuthController::is_authorized() const {
return current_state_ == ITgClient::AuthState::Ready;
}

bool AuthController::login(const std::string& phone_number, const std::string& code) {

// 1. Проверяем текущее состояние
void AuthController::enter_phone(const std::string& phone_number) {
update_status();

// 2. Если уже авторизованы - ничего не делаем
if (is_authorized()) {
std::cerr << "[AuthController] Already authorized\n";
return true;
if (current_state_ != ITgClient::AuthState::WaitingPhone) {
throw std::logic_error("[AuthController] Cannot enter phone in current state");
}

// 3. Обрабатываем в зависимости от состояния

if (phone_number.empty()) {
throw std::invalid_argument("Phone number is required");
}

try {
switch (current_state_) {
case ITgClient::AuthState::WaitingPhone:
// Требуется номер телефона
if (phone_number.empty()) {
throw std::invalid_argument("Phone number is required");
}

// if (!validatePhoneNumber(phone_number)) {
// throw std::invalid_argument("Invalid phone number format");
// }

std::cout << "[AuthController] Sending phone number...\n";
client_.enter_phone_number(phone_number);
break;

case ITgClient::AuthState::WaitingCode:
// Требуется код подтверждения
if (code.empty()) {
throw std::invalid_argument("Auth code is required");
}

// if (!validateCode(code)) {
// throw std::invalid_argument("Invalid code format");
// }

std::cout << "[AuthController] Sending auth code...\n";
client_.enter_message_code(code);
break;

case ITgClient::AuthState::Ready:
return true;

case ITgClient::AuthState::LoggingOut:
throw std::runtime_error("Cannot login while logging out");

case ITgClient::AuthState::Error:
throw std::runtime_error("In error state, cannot login");

default:
throw std::runtime_error("Unknown auth state");
}

// 4. Обновляем состояние после отправки
std::cout << "[AuthController] Sending phone number...\n";
client_.enter_phone_number(phone_number);
update_status();
} catch (const std::exception& e) {
std::cerr << "[AuthController] enter_phone error: " << e.what() << "\n";
current_state_ = ITgClient::AuthState::Error;
throw;
}
}

void AuthController::enter_code(const std::string& code) {
update_status();

if (current_state_ != ITgClient::AuthState::WaitingCode) {
throw std::logic_error("[AuthController] Cannot enter code in current state");
}

if (code.empty()) {
throw std::invalid_argument("Auth code is required");
}

try {
std::cout << "[AuthController] Sending auth code...\n";
client_.enter_message_code(code);
update_status();
return true;

} catch (const std::exception& e) {
std::cerr << "[AuthController] Login error: " << e.what() << "\n";
std::cerr << "[AuthController] enter_code error: " << e.what() << "\n";
current_state_ = ITgClient::AuthState::Error;
return false;
throw;
}
}

void AuthController::logout() {
update_status();
try {
if (!is_authorized() && get_auth_state() != ITgClient::AuthState::LoggingOut) {
if (current_state_ == ITgClient::AuthState::LoggingOut) {
std::cout << "[AuthController] Already logging out\n";
return;
}
if (!is_authorized()) {
std::cout << "[AuthController] Not authorized, nothing to logout\n";
return;
}

client_.log_out();
update_status();
} catch (const std::exception& e) {
std::cerr << "[AuthController] Login error: " << e.what() << "\n";
std::cerr << "[AuthController] Logout error: " << e.what() << "\n";
current_state_ = ITgClient::AuthState::Error;
return;
}
Expand Down
12 changes: 6 additions & 6 deletions src/controllers/AuthController.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,14 +19,14 @@ class AuthController {
public:
explicit AuthController(ITgClient& client);

// Запрет копирования
AuthController(const AuthController&) = delete;
AuthController& operator=(const AuthController&) = delete;
//AuthController(const AuthController&) = default
//AuthController& operator=(const AuthController&) = default;

~AuthController() = default;
~AuthController();

void enter_phone(const std::string& phone_number);
void enter_code(const std::string& code);

// Основные методы
bool login(const std::string& phone_number, const std::string& code = "");
void logout();
bool is_authorized() const;
ITgClient::AuthState get_auth_state() const;
Expand Down
29 changes: 29 additions & 0 deletions src/controllers/ChatHistoryController.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@


#include "ChatHistoryController.h"

ChatHistoryController::ChatHistoryController(ITgClient& client)
: tgClient(client), target_chat_id("") {}

void ChatHistoryController::set_target_chat_id(const std::string& chatId) {
target_chat_id = chatId;
}

std::string ChatHistoryController::get_target_chat_id() const {
return target_chat_id;
}

void ChatHistoryController::clear_target_chat_id() {
target_chat_id.clear();
}

std::vector<ITgClient::Message> ChatHistoryController::get_target_chat_history(int limit) {
if (target_chat_id.empty()) {
return {};
}
return tgClient.get_chat_history(target_chat_id, limit);
}

std::vector<ITgClient::Message> ChatHistoryController::get_chat_history(const std::string& chatId, int limit) {
return tgClient.get_chat_history(chatId, limit);
}
29 changes: 29 additions & 0 deletions src/controllers/ChatHistoryController.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
#pragma once
#include <string>
#include <vector>
#include "../tgClient/ITgClient.hpp"

class ChatHistoryController {
private:
ITgClient& tgClient;
std::string target_chat_id;

public:
explicit ChatHistoryController(ITgClient& client);

ChatHistoryController(const ChatHistoryController&) = delete;
ChatHistoryController& operator=(const ChatHistoryController) = delete;

~ChatHistoryController() = default;

void set_target_chat_id(const std::string& chatId);

std::string get_target_chat_id() const;

void clear_target_chat_id();

std::vector<ITgClient::Message> get_target_chat_history(int limit = 20);

std::vector<ITgClient::Message> get_chat_history(const std::string& chatId, int limit = 20);

};
Loading