00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015 #include "Papillon/Client"
00016
00017
00018 #include <QtDebug>
00019
00020
00021 #include "Papillon/Connection"
00022 #include "Papillon/Base/Connector"
00023 #include "Papillon/ClientStream"
00024 #include "Papillon/NetworkMessage"
00025 #include "Papillon/MimeHeader"
00026 #include "Papillon/ContactList"
00027 #include "Papillon/UserContact"
00028
00029
00030 #include "Papillon/Tasks/LoginTask"
00031 #include "Papillon/Tasks/NotifyMessageTask"
00032 #include "Papillon/Tasks/NotifyPresenceTask"
00033 #include "Papillon/Tasks/NotifyStatusMessageTask"
00034
00035 namespace Papillon
00036 {
00037
00038 class Client::Private
00039 {
00040 public:
00041 Private()
00042 : connector(0), notificationConnection(0),
00043 server( QLatin1String("messenger.hotmail.com") ), port(1863), connectionStatus(Disconnected), contactList(0), userContact(0),
00044 loginTask(0), notifyMessageTask(0), notifyPresenceTask(0), notifyStatusMessageTask(0)
00045 {}
00046
00047 Connector *connector;
00048 Connection *notificationConnection;
00049
00050 QString server;
00051 quint16 port;
00052 Papillon::Client::ConnectionStatus connectionStatus;
00053
00054 ContactList *contactList;
00055 UserContact *userContact;
00056
00057
00058 LoginTask *loginTask;
00059 NotifyMessageTask *notifyMessageTask;
00060 NotifyPresenceTask *notifyPresenceTask;
00061 NotifyStatusMessageTask *notifyStatusMessageTask;
00062 };
00063
00064 Client::Client(Connector *connector, QObject *parent)
00065 : QObject(parent), d(new Private)
00066 {
00067 d->connector = connector;
00068 d->contactList = new ContactList(this);
00069 d->userContact = new UserContact(this);
00070 }
00071
00072 Client::~Client()
00073 {
00074 delete d;
00075 }
00076
00077 Connection *Client::createConnection()
00078 {
00079 Connector *connector = d->connector->createNewConnector(this);
00080 ClientStream *clientStream = new ClientStream(connector, this);
00081 Connection *newConnection = new Connection(clientStream, this);
00082 newConnection->setClient(this);
00083
00084 return newConnection;
00085 }
00086
00087 ContactList *Client::contactList()
00088 {
00089 return d->contactList;
00090 }
00091
00092 UserContact *Client::userContact()
00093 {
00094 return d->userContact;
00095 }
00096
00097 Connection *Client::notificationConnection()
00098 {
00099 return d->notificationConnection;
00100 }
00101
00102 Papillon::Client::ConnectionStatus Client::connectionStatus() const
00103 {
00104 return d->connectionStatus;
00105 }
00106
00107 void Client::connectToServer(Papillon::Presence::Status initialPresence)
00108 {
00109
00110 Q_UNUSED(initialPresence);
00111
00112 if( !d->notificationConnection )
00113 {
00114 d->notificationConnection = createConnection();
00115 connect(d->notificationConnection, SIGNAL(connected()), this, SLOT(notificationConnected()));
00116 connect(d->notificationConnection, SIGNAL(connected()), this, SLOT(initNotificationTasks()));
00117 }
00118
00119 setConnectionStatus( Client::Connecting );
00120 d->notificationConnection->connectToServer(d->server, d->port);
00121 }
00122
00123 void Client::disconnectFromServer()
00124 {
00125 d->notificationConnection->disconnectFromServer();
00126
00127 setConnectionStatus( Client::Disconnected );
00128 }
00129
00130 void Client::setServer(const QString &server, quint16 port)
00131 {
00132
00133 if( !server.isEmpty() )
00134 d->server = server;
00135 if( port != 0 )
00136 d->port = port;
00137 }
00138
00139 void Client::initNotificationTasks()
00140 {
00141 if( !d->notifyMessageTask )
00142 {
00143 d->notifyMessageTask = new NotifyMessageTask( d->notificationConnection->rootTask() );
00144 connect(d->notifyMessageTask, SIGNAL(profileMessage(Papillon::MimeHeader)), this, SLOT(gotInitalProfile(Papillon::MimeHeader)));
00145 }
00146
00147 if( !d->notifyPresenceTask )
00148 {
00149 d->notifyPresenceTask = new NotifyPresenceTask( d->notificationConnection->rootTask() );
00150 connect(d->notifyPresenceTask, SIGNAL(contactPresenceChanged(QString, Papillon::Presence::Status )), this, SLOT(slotContactPresenceChanged(QString, Papillon::Presence::Status )));
00151 }
00152
00153 if( !d->notifyStatusMessageTask )
00154 {
00155 d->notifyStatusMessageTask = new NotifyStatusMessageTask( d->notificationConnection->rootTask() );
00156 connect(d->notifyStatusMessageTask, SIGNAL(contactStatusMessageChanged(QString, Papillon::StatusMessage)), this, SLOT(slotContactStatusMessageChanged(QString, Papillon::StatusMessage)));
00157 }
00158 }
00159
00160 void Client::notificationConnected()
00161 {
00162 setConnectionStatus( Client::Connected );
00163
00164 login();
00165 }
00166
00167 void Client::login()
00168 {
00169
00170 if( d->connectionStatus != Client::LoggedIn )
00171 {
00172
00173 d->loginTask = new LoginTask(d->notificationConnection->rootTask());
00174 connect(d->loginTask, SIGNAL(redirection(QString, quint16)), this, SLOT(loginRedirect(QString, quint16 )));
00175 connect(d->loginTask, SIGNAL(finished(Papillon::Task*)), this, SLOT(loginResult(Papillon::Task*)));
00176 d->loginTask->go(Task::AutoDelete);
00177 }
00178 }
00179
00180 void Client::loginRedirect(const QString &server, quint16 port)
00181 {
00182 qDebug() << Q_FUNC_INFO << "Redirect to" << QString("%1:%2").arg(server).arg(port);
00183
00184 d->notificationConnection->disconnectFromServer();
00185 d->notificationConnection->connectToServer(server, port);
00186 }
00187
00188 void Client::loginResult(Papillon::Task *task)
00189 {
00190 LoginTask *loginTask = static_cast<LoginTask*>(task);
00191 if( loginTask )
00192 {
00193
00194
00195 if( loginTask->loginState() == LoginTask::StateBadPassword )
00196 setConnectionStatus( Client::LoginBadPassword );
00197 else if( loginTask->loginState() != LoginTask::StateRedirection )
00198 setConnectionStatus( Client::Disconnected );
00199 }
00200 }
00201
00202 void Client::gotInitalProfile(const Papillon::MimeHeader &profileMessage)
00203 {
00204 QString passportAuthTicket = profileMessage.value( QLatin1String("MSPAuth") ).toString();
00205
00206 userContact()->setLoginCookie( passportAuthTicket );
00207
00208
00209
00210 setConnectionStatus( Client::LoggedIn );
00211
00212 qDebug() << Q_FUNC_INFO << "Received auth ticket:" << passportAuthTicket;
00213 }
00214
00215 void Client::slotContactPresenceChanged(const QString &contactId, Papillon::Presence::Status presence)
00216 {
00217 emit contactPresenceChanged(contactId, presence);
00218 }
00219
00220 void Client::slotContactStatusMessageChanged(const QString &contactId, const Papillon::StatusMessage &newStatusMessage)
00221 {
00222 emit contactStatusMessageChanged(contactId, newStatusMessage);
00223 }
00224
00225 void Client::writeCommand(NetworkMessage *command)
00226 {
00227 d->notificationConnection->send(command);
00228 }
00229
00230 void Client::setConnectionStatus(Papillon::Client::ConnectionStatus newStatus)
00231 {
00232 qDebug() << Q_FUNC_INFO << "New connection status: " << newStatus;
00233
00234 d->connectionStatus = newStatus;
00235
00236 emit connectionStatusChanged(newStatus);
00237 }
00238
00239 }
00240
00241 #include "client.moc"