2020-08-10 15:17:29 +03:00
/*
Copyright ( C ) 2020 Sebastian J . Wolf
This file is part of Fernschreiber .
2020-08-13 18:08:14 +03:00
Fernschreiber is free software : you can redistribute it and / or modify
2020-08-10 15:17:29 +03:00
it under the terms of the GNU General Public License as published by
the Free Software Foundation , either version 3 of the License , or
( at your option ) any later version .
2020-08-13 18:08:14 +03:00
Fernschreiber is distributed in the hope that it will be useful ,
2020-08-10 15:17:29 +03:00
but WITHOUT ANY WARRANTY ; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
GNU General Public License for more details .
You should have received a copy of the GNU General Public License
along with Fernschreiber . If not , see < http : //www.gnu.org/licenses/>.
*/
# include "tdlibwrapper.h"
2020-08-13 00:51:09 +03:00
# include "tdlibsecrets.h"
# include <QDir>
# include <QLocale>
# include <QSysInfo>
# include <QSettings>
2020-08-10 15:17:29 +03:00
TDLibWrapper : : TDLibWrapper ( QObject * parent ) : QObject ( parent )
{
qDebug ( ) < < " [TDLibWrapper] Initializing TD Lib... " ;
this - > tdLibClient = td_json_client_create ( ) ;
2020-08-10 21:17:13 +03:00
this - > tdLibReceiver = new TDLibReceiver ( this - > tdLibClient , this ) ;
2020-08-12 11:50:01 +03:00
2020-08-13 00:51:09 +03:00
QString tdLibDatabaseDirectoryPath = QStandardPaths : : writableLocation ( QStandardPaths : : AppDataLocation ) + " /tdlib " ;
QDir tdLibDatabaseDirectory ( tdLibDatabaseDirectoryPath ) ;
if ( ! tdLibDatabaseDirectory . exists ( ) ) {
tdLibDatabaseDirectory . mkpath ( tdLibDatabaseDirectoryPath ) ;
}
2020-08-12 11:50:01 +03:00
connect ( this - > tdLibReceiver , SIGNAL ( versionDetected ( QString ) ) , this , SLOT ( handleVersionDetected ( QString ) ) ) ;
connect ( this - > tdLibReceiver , SIGNAL ( authorizationStateChanged ( QString ) ) , this , SLOT ( handleAuthorizationStateChanged ( QString ) ) ) ;
2020-08-13 00:51:09 +03:00
connect ( this - > tdLibReceiver , SIGNAL ( optionUpdated ( QString , QVariant ) ) , this , SLOT ( handleOptionUpdated ( QString , QVariant ) ) ) ;
2020-08-13 01:20:28 +03:00
connect ( this - > tdLibReceiver , SIGNAL ( connectionStateChanged ( QString ) ) , this , SLOT ( handleConnectionStateChanged ( QString ) ) ) ;
2020-08-13 18:08:14 +03:00
connect ( this - > tdLibReceiver , SIGNAL ( userUpdated ( QVariantMap ) ) , this , SLOT ( handleUserUpdated ( QVariantMap ) ) ) ;
2020-08-22 15:06:26 +03:00
connect ( this - > tdLibReceiver , SIGNAL ( userStatusUpdated ( QString , QVariantMap ) ) , this , SLOT ( handleUserStatusUpdated ( QString , QVariantMap ) ) ) ;
2020-08-14 11:33:42 +03:00
connect ( this - > tdLibReceiver , SIGNAL ( fileUpdated ( QVariantMap ) ) , this , SLOT ( handleFileUpdated ( QVariantMap ) ) ) ;
2020-08-16 18:38:51 +03:00
connect ( this - > tdLibReceiver , SIGNAL ( newChatDiscovered ( QVariantMap ) ) , this , SLOT ( handleNewChatDiscovered ( QVariantMap ) ) ) ;
2020-08-17 00:31:20 +03:00
connect ( this - > tdLibReceiver , SIGNAL ( unreadMessageCountUpdated ( QVariantMap ) ) , this , SLOT ( handleUnreadMessageCountUpdated ( QVariantMap ) ) ) ;
connect ( this - > tdLibReceiver , SIGNAL ( unreadChatCountUpdated ( QVariantMap ) ) , this , SLOT ( handleUnreadChatCountUpdated ( QVariantMap ) ) ) ;
2020-08-20 15:58:32 +03:00
connect ( this - > tdLibReceiver , SIGNAL ( chatLastMessageUpdated ( QString , QString , QVariantMap ) ) , this , SLOT ( handleChatLastMessageUpdated ( QString , QString , QVariantMap ) ) ) ;
2020-08-20 01:24:24 +03:00
connect ( this - > tdLibReceiver , SIGNAL ( chatOrderUpdated ( QString , QString ) ) , this , SLOT ( handleChatOrderUpdated ( QString , QString ) ) ) ;
2020-08-21 00:56:21 +03:00
connect ( this - > tdLibReceiver , SIGNAL ( chatReadInboxUpdated ( QString , int ) ) , this , SLOT ( handleChatReadInboxUpdated ( QString , int ) ) ) ;
2020-08-21 19:03:51 +03:00
connect ( this - > tdLibReceiver , SIGNAL ( basicGroupUpdated ( QString , QVariantMap ) ) , this , SLOT ( handleBasicGroupUpdated ( QString , QVariantMap ) ) ) ;
connect ( this - > tdLibReceiver , SIGNAL ( superGroupUpdated ( QString , QVariantMap ) ) , this , SLOT ( handleSuperGroupUpdated ( QString , QVariantMap ) ) ) ;
connect ( this - > tdLibReceiver , SIGNAL ( chatOnlineMemberCountUpdated ( QString , int ) ) , this , SLOT ( handleChatOnlineMemberCountUpdated ( QString , int ) ) ) ;
2020-08-22 18:30:02 +03:00
connect ( this - > tdLibReceiver , SIGNAL ( messagesReceived ( QVariantList ) ) , this , SLOT ( handleMessagesReceived ( QVariantList ) ) ) ;
2020-08-12 11:50:01 +03:00
2020-08-10 21:17:13 +03:00
this - > tdLibReceiver - > start ( ) ;
2020-08-14 11:33:42 +03:00
this - > setLogVerbosityLevel ( ) ;
2020-08-10 15:17:29 +03:00
}
TDLibWrapper : : ~ TDLibWrapper ( )
{
qDebug ( ) < < " [TDLibWrapper] Destroying TD Lib... " ;
2020-08-10 21:17:13 +03:00
this - > tdLibReceiver - > setActive ( false ) ;
while ( this - > tdLibReceiver - > isRunning ( ) ) {
QCoreApplication : : processEvents ( QEventLoop : : AllEvents , 1000 ) ;
}
2020-08-10 15:17:29 +03:00
td_json_client_destroy ( this - > tdLibClient ) ;
}
2020-08-13 00:51:09 +03:00
void TDLibWrapper : : sendRequest ( const QVariantMap & requestObject )
{
qDebug ( ) < < " [TDLibWrapper] Sending request to TD Lib, object type name: " < < requestObject . value ( " @type " ) . toString ( ) ;
QJsonDocument requestDocument = QJsonDocument : : fromVariant ( requestObject ) ;
td_json_client_send ( this - > tdLibClient , requestDocument . toJson ( ) . constData ( ) ) ;
}
2020-08-12 11:50:01 +03:00
QString TDLibWrapper : : getVersion ( )
{
return this - > version ;
}
2020-08-13 00:51:09 +03:00
TDLibWrapper : : AuthorizationState TDLibWrapper : : getAuthorizationState ( )
2020-08-12 11:50:01 +03:00
{
return this - > authorizationState ;
}
2020-08-13 01:20:28 +03:00
TDLibWrapper : : ConnectionState TDLibWrapper : : getConnectionState ( )
{
return this - > connectionState ;
}
2020-08-13 11:15:26 +03:00
void TDLibWrapper : : setAuthenticationPhoneNumber ( const QString & phoneNumber )
{
qDebug ( ) < < " [TDLibWrapper] Set authentication phone number " < < phoneNumber ;
QVariantMap requestObject ;
requestObject . insert ( " @type " , " setAuthenticationPhoneNumber " ) ;
requestObject . insert ( " phone_number " , phoneNumber ) ;
QVariantMap phoneNumberSettings ;
phoneNumberSettings . insert ( " allow_flash_call " , false ) ;
phoneNumberSettings . insert ( " is_current_phone_number " , true ) ;
requestObject . insert ( " settings " , phoneNumberSettings ) ;
this - > sendRequest ( requestObject ) ;
}
2020-08-13 16:35:43 +03:00
void TDLibWrapper : : setAuthenticationCode ( const QString & authenticationCode )
{
qDebug ( ) < < " [TDLibWrapper] Set authentication code " < < authenticationCode ;
QVariantMap requestObject ;
requestObject . insert ( " @type " , " checkAuthenticationCode " ) ;
requestObject . insert ( " code " , authenticationCode ) ;
this - > sendRequest ( requestObject ) ;
}
2020-08-13 23:32:35 +03:00
void TDLibWrapper : : getChats ( )
{
qDebug ( ) < < " [TDLibWrapper] Getting chats " ;
QVariantMap requestObject ;
requestObject . insert ( " @type " , " getChats " ) ;
2020-08-16 18:38:51 +03:00
requestObject . insert ( " limit " , 5 ) ;
2020-08-13 23:32:35 +03:00
this - > sendRequest ( requestObject ) ;
}
2020-08-14 11:33:42 +03:00
void TDLibWrapper : : downloadFile ( const QString & fileId )
{
qDebug ( ) < < " [TDLibWrapper] Downloading file " < < fileId ;
QVariantMap requestObject ;
requestObject . insert ( " @type " , " downloadFile " ) ;
requestObject . insert ( " file_id " , fileId ) ;
requestObject . insert ( " synchronous " , false ) ;
requestObject . insert ( " offset " , 0 ) ;
requestObject . insert ( " limit " , 0 ) ;
requestObject . insert ( " priority " , 1 ) ;
this - > sendRequest ( requestObject ) ;
}
2020-08-21 15:47:08 +03:00
void TDLibWrapper : : openChat ( const QString & chatId )
{
qDebug ( ) < < " [TDLibWrapper] Opening chat " < < chatId ;
QVariantMap requestObject ;
requestObject . insert ( " @type " , " openChat " ) ;
requestObject . insert ( " chat_id " , chatId ) ;
this - > sendRequest ( requestObject ) ;
}
void TDLibWrapper : : closeChat ( const QString & chatId )
{
qDebug ( ) < < " [TDLibWrapper] Closing chat " < < chatId ;
QVariantMap requestObject ;
requestObject . insert ( " @type " , " closeChat " ) ;
requestObject . insert ( " chat_id " , chatId ) ;
this - > sendRequest ( requestObject ) ;
}
2020-08-22 18:30:02 +03:00
void TDLibWrapper : : getChatHistory ( const QString & chatId , const qlonglong & fromMessageId , const int & offset , const int & limit , const bool & onlyLocal )
{
qDebug ( ) < < " [TDLibWrapper] Retrieving chat history " < < chatId < < fromMessageId < < offset < < limit < < onlyLocal ;
QVariantMap requestObject ;
requestObject . insert ( " @type " , " getChatHistory " ) ;
requestObject . insert ( " chat_id " , chatId ) ;
requestObject . insert ( " from_message_id " , fromMessageId ) ;
requestObject . insert ( " offset " , offset ) ;
requestObject . insert ( " limit " , limit ) ;
requestObject . insert ( " only_local " , onlyLocal ) ;
this - > sendRequest ( requestObject ) ;
}
2020-08-23 00:05:45 +03:00
void TDLibWrapper : : viewMessage ( const QString & chatId , const QString & messageId )
{
qDebug ( ) < < " [TDLibWrapper] Mark message as viewed " < < chatId < < messageId ;
QVariantMap requestObject ;
requestObject . insert ( " @type " , " viewMessages " ) ;
requestObject . insert ( " chat_id " , chatId ) ;
requestObject . insert ( " force_read " , false ) ;
QVariantList messageIds ;
messageIds . append ( messageId ) ;
requestObject . insert ( " message_ids " , messageIds ) ;
this - > sendRequest ( requestObject ) ;
}
2020-08-13 23:32:35 +03:00
QVariantMap TDLibWrapper : : getUserInformation ( )
{
return this - > userInformation ;
}
2020-08-16 18:38:51 +03:00
QVariantMap TDLibWrapper : : getUserInformation ( const QString & userId )
{
qDebug ( ) < < " [TDLibWrapper] Returning user information for ID " < < userId ;
2020-08-20 01:24:24 +03:00
return this - > allUsers . value ( userId ) . toMap ( ) ;
2020-08-16 18:38:51 +03:00
}
2020-08-17 00:31:20 +03:00
QVariantMap TDLibWrapper : : getUnreadMessageInformation ( )
{
return this - > unreadMessageInformation ;
}
QVariantMap TDLibWrapper : : getUnreadChatInformation ( )
{
return this - > unreadChatInformation ;
}
2020-08-21 19:03:51 +03:00
QVariantMap TDLibWrapper : : getBasicGroup ( const QString & groupId )
{
qDebug ( ) < < " [TDLibWrapper] Returning basic group information for ID " < < groupId ;
return this - > basicGroups . value ( groupId ) . toMap ( ) ;
}
QVariantMap TDLibWrapper : : getSuperGroup ( const QString & groupId )
{
qDebug ( ) < < " [TDLibWrapper] Returning super group information for ID " < < groupId ;
return this - > superGroups . value ( groupId ) . toMap ( ) ;
}
2020-08-12 11:50:01 +03:00
void TDLibWrapper : : handleVersionDetected ( const QString & version )
{
this - > version = version ;
emit versionDetected ( version ) ;
}
void TDLibWrapper : : handleAuthorizationStateChanged ( const QString & authorizationState )
{
2020-08-13 01:20:28 +03:00
if ( authorizationState = = " authorizationStateClosed " ) {
2020-08-13 00:51:09 +03:00
this - > authorizationState = AuthorizationState : : Closed ;
}
if ( authorizationState = = " authorizationStateClosing " ) {
this - > authorizationState = AuthorizationState : : Closing ;
}
if ( authorizationState = = " authorizationStateLoggingOut " ) {
this - > authorizationState = AuthorizationState : : LoggingOut ;
}
if ( authorizationState = = " authorizationStateReady " ) {
2020-08-13 11:15:26 +03:00
this - > authorizationState = AuthorizationState : : AuthorizationReady ;
2020-08-13 00:51:09 +03:00
}
if ( authorizationState = = " authorizationStateWaitCode " ) {
this - > authorizationState = AuthorizationState : : WaitCode ;
}
if ( authorizationState = = " authorizationStateWaitEncryptionKey " ) {
this - > setEncryptionKey ( ) ;
this - > authorizationState = AuthorizationState : : WaitEncryptionKey ;
}
if ( authorizationState = = " authorizationStateWaitOtherDeviceConfirmation " ) {
this - > authorizationState = AuthorizationState : : WaitOtherDeviceConfirmation ;
}
if ( authorizationState = = " authorizationStateWaitPassword " ) {
this - > authorizationState = AuthorizationState : : WaitPassword ;
}
if ( authorizationState = = " authorizationStateWaitPhoneNumber " ) {
this - > authorizationState = AuthorizationState : : WaitPhoneNumber ;
}
if ( authorizationState = = " authorizationStateWaitRegistration " ) {
this - > authorizationState = AuthorizationState : : WaitRegistration ;
}
if ( authorizationState = = " authorizationStateWaitTdlibParameters " ) {
this - > setInitialParameters ( ) ;
this - > authorizationState = AuthorizationState : : WaitTdlibParameters ;
}
emit authorizationStateChanged ( this - > authorizationState ) ;
}
void TDLibWrapper : : handleOptionUpdated ( const QString & optionName , const QVariant & optionValue )
{
this - > options . insert ( optionName , optionValue ) ;
emit optionUpdated ( optionName , optionValue ) ;
2020-08-20 01:24:24 +03:00
if ( optionName = = " my_id " ) {
emit ownUserIdFound ( optionValue . toString ( ) ) ;
}
2020-08-13 00:51:09 +03:00
}
2020-08-13 01:20:28 +03:00
void TDLibWrapper : : handleConnectionStateChanged ( const QString & connectionState )
{
if ( connectionState = = " connectionStateConnecting " ) {
this - > connectionState = ConnectionState : : Connecting ;
}
if ( connectionState = = " connectionStateConnectingToProxy " ) {
this - > connectionState = ConnectionState : : ConnectingToProxy ;
}
if ( connectionState = = " connectionStateReady " ) {
2020-08-13 11:15:26 +03:00
this - > connectionState = ConnectionState : : ConnectionReady ;
2020-08-13 01:20:28 +03:00
}
if ( connectionState = = " connectionStateUpdating " ) {
this - > connectionState = ConnectionState : : Updating ;
}
if ( connectionState = = " connectionStateWaitingForNetwork " ) {
this - > connectionState = ConnectionState : : WaitingForNetwork ;
}
emit connectionStateChanged ( this - > connectionState ) ;
}
2020-08-13 18:08:14 +03:00
void TDLibWrapper : : handleUserUpdated ( const QVariantMap & userInformation )
{
2020-08-16 18:38:51 +03:00
QString updatedUserId = userInformation . value ( " id " ) . toString ( ) ;
if ( updatedUserId = = this - > options . value ( " my_id " ) . toString ( ) ) {
2020-08-13 18:08:14 +03:00
qDebug ( ) < < " [TDLibWrapper] Own user information updated :) " ;
this - > userInformation = userInformation ;
}
2020-08-20 01:24:24 +03:00
qDebug ( ) < < " [TDLibWrapper] User information updated: " < < userInformation . value ( " username " ) . toString ( ) < < userInformation . value ( " first_name " ) . toString ( ) < < userInformation . value ( " last_name " ) . toString ( ) ;
this - > allUsers . insert ( updatedUserId , userInformation ) ;
2020-08-21 19:03:51 +03:00
emit userUpdated ( updatedUserId , userInformation ) ;
2020-08-13 18:08:14 +03:00
}
2020-08-22 15:06:26 +03:00
void TDLibWrapper : : handleUserStatusUpdated ( const QString & userId , const QVariantMap & userStatusInformation )
{
if ( userId = = this - > options . value ( " my_id " ) . toString ( ) ) {
qDebug ( ) < < " [TDLibWrapper] Own user status information updated :) " ;
this - > userInformation . insert ( " status " , userStatusInformation ) ;
}
qDebug ( ) < < " [TDLibWrapper] User status information updated: " < < userId < < userStatusInformation . value ( " @type " ) . toString ( ) ;
QVariantMap updatedUserInformation = this - > allUsers . value ( userId ) . toMap ( ) ;
updatedUserInformation . insert ( " status " , userStatusInformation ) ;
this - > allUsers . insert ( userId , updatedUserInformation ) ;
emit userUpdated ( userId , updatedUserInformation ) ;
}
2020-08-16 18:38:51 +03:00
void TDLibWrapper : : handleFileUpdated ( const QVariantMap & fileInformation )
{
emit fileUpdated ( fileInformation . value ( " id " ) . toInt ( ) , fileInformation ) ;
}
void TDLibWrapper : : handleNewChatDiscovered ( const QVariantMap & chatInformation )
2020-08-14 11:33:42 +03:00
{
2020-08-16 18:38:51 +03:00
QString chatId = chatInformation . value ( " id " ) . toString ( ) ;
this - > chats . insert ( chatId , chatInformation ) ;
emit newChatDiscovered ( chatId , chatInformation ) ;
2020-08-14 11:33:42 +03:00
}
2020-08-17 00:31:20 +03:00
void TDLibWrapper : : handleUnreadMessageCountUpdated ( const QVariantMap & messageCountInformation )
{
2020-08-18 00:44:37 +03:00
if ( messageCountInformation . value ( " chat_list_type " ) . toString ( ) = = " chatListMain " ) {
this - > unreadMessageInformation = messageCountInformation ;
emit unreadMessageCountUpdated ( messageCountInformation ) ;
}
2020-08-17 00:31:20 +03:00
}
void TDLibWrapper : : handleUnreadChatCountUpdated ( const QVariantMap & chatCountInformation )
{
2020-08-18 00:44:37 +03:00
if ( chatCountInformation . value ( " chat_list_type " ) . toString ( ) = = " chatListMain " ) {
this - > unreadChatInformation = chatCountInformation ;
emit unreadChatCountUpdated ( chatCountInformation ) ;
}
2020-08-17 00:31:20 +03:00
}
2020-08-20 15:58:32 +03:00
void TDLibWrapper : : handleChatLastMessageUpdated ( const QString & chatId , const QString & order , const QVariantMap & lastMessage )
2020-08-20 01:24:24 +03:00
{
2020-08-20 15:58:32 +03:00
emit chatLastMessageUpdated ( chatId , order , lastMessage ) ;
2020-08-20 01:24:24 +03:00
}
void TDLibWrapper : : handleChatOrderUpdated ( const QString & chatId , const QString & order )
{
emit chatOrderUpdated ( chatId , order ) ;
}
2020-08-21 00:56:21 +03:00
void TDLibWrapper : : handleChatReadInboxUpdated ( const QString & chatId , const int & unreadCount )
{
emit chatReadInboxUpdated ( chatId , unreadCount ) ;
}
2020-08-21 19:03:51 +03:00
void TDLibWrapper : : handleBasicGroupUpdated ( const QString & groupId , const QVariantMap & groupInformation )
{
this - > basicGroups . insert ( groupId , groupInformation ) ;
emit basicGroupUpdated ( groupId , groupInformation ) ;
}
void TDLibWrapper : : handleSuperGroupUpdated ( const QString & groupId , const QVariantMap & groupInformation )
{
this - > superGroups . insert ( groupId , groupInformation ) ;
emit superGroupUpdated ( groupId , groupInformation ) ;
}
void TDLibWrapper : : handleChatOnlineMemberCountUpdated ( const QString & chatId , const int & onlineMemberCount )
{
emit chatOnlineMemberCountUpdated ( chatId , onlineMemberCount ) ;
}
2020-08-22 18:30:02 +03:00
void TDLibWrapper : : handleMessagesReceived ( const QVariantList & messages )
{
emit messagesReceived ( messages ) ;
}
2020-08-13 00:51:09 +03:00
void TDLibWrapper : : setInitialParameters ( )
{
qDebug ( ) < < " [TDLibWrapper] Sending initial parameters to TD Lib " ;
QVariantMap requestObject ;
requestObject . insert ( " @type " , " setTdlibParameters " ) ;
QVariantMap initialParameters ;
initialParameters . insert ( " api_id " , TDLIB_API_ID ) ;
initialParameters . insert ( " api_hash " , TDLIB_API_HASH ) ;
initialParameters . insert ( " database_directory " , QStandardPaths : : writableLocation ( QStandardPaths : : AppDataLocation ) + " /tdlib " ) ;
2020-08-13 18:08:14 +03:00
initialParameters . insert ( " use_file_database " , true ) ;
initialParameters . insert ( " use_chat_info_database " , true ) ;
2020-08-13 00:51:09 +03:00
initialParameters . insert ( " use_message_database " , true ) ;
initialParameters . insert ( " use_secret_chats " , false ) ;
initialParameters . insert ( " system_language_code " , QLocale : : system ( ) . name ( ) ) ;
QSettings hardwareSettings ( " /etc/hw-release " , QSettings : : NativeFormat ) ;
initialParameters . insert ( " device_model " , hardwareSettings . value ( " NAME " , " Unknown Mobile Device " ) . toString ( ) ) ;
initialParameters . insert ( " system_version " , QSysInfo : : prettyProductName ( ) ) ;
initialParameters . insert ( " application_version " , " 0.1 " ) ;
requestObject . insert ( " parameters " , initialParameters ) ;
this - > sendRequest ( requestObject ) ;
}
void TDLibWrapper : : setEncryptionKey ( )
{
qDebug ( ) < < " [TDLibWrapper] Setting database encryption key " ;
QVariantMap requestObject ;
requestObject . insert ( " @type " , " checkDatabaseEncryptionKey " ) ;
// see https://github.com/tdlib/td/issues/188#issuecomment-379536139
requestObject . insert ( " encryption_key " , " " ) ;
this - > sendRequest ( requestObject ) ;
2020-08-12 11:50:01 +03:00
}
2020-08-14 11:33:42 +03:00
void TDLibWrapper : : setLogVerbosityLevel ( )
{
qDebug ( ) < < " [TDLibWrapper] Setting log verbosity level to something less chatty " ;
QVariantMap requestObject ;
requestObject . insert ( " @type " , " setLogVerbosityLevel " ) ;
requestObject . insert ( " new_verbosity_level " , 2 ) ;
this - > sendRequest ( requestObject ) ;
}