Kaidan.cpp 6.83 KB
Newer Older
1
/*
2
 *  Kaidan - A user-friendly XMPP client for every device!
3
 *
4
 *  Copyright (C) 2016-2017 LNJ <git@lnj.li>
5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
 *  Copyright (C) 2016 Marzanna
 *  Copyright (C) 2016 geobra <s.g.b@gmx.de>
 *
 *  Kaidan is free software: you can redistribute it and/or modify
 *  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.
 *
 *  Kaidan is distributed in the hope that it will be useful,
 *  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 Kaidan. If not, see <http://www.gnu.org/licenses/>.
 */

22
#include "Kaidan.h"
Georg's avatar
Georg committed
23 24

#include <iostream>
25 26
// Qt
#include <QDebug>
27
#include <QDir>
28 29
#include <QSettings>
#include <QString>
30
#include <QStandardPaths>
31
#include <QTimer>
32 33
// gloox
#include <gloox/rostermanager.h>
34
#include <gloox/receipt.h>
35
// Kaidan
36
#include "RosterModel.h"
37
#include "MessageModel.h"
Georg's avatar
Georg committed
38

39
Kaidan::Kaidan(QObject *parent) : QObject(parent)
Georg's avatar
Georg committed
40
{
Marzanna's avatar
Marzanna committed
41
	connected = false;
42 43

	// setup database
44 45 46
	database = new Database();
	database->openDatabase();
	if (database->needToConvert()) database->convertDatabase();
47 48 49

	// setup components
	messageModel = new MessageModel(database->getDatabase());
50
	rosterModel = new RosterModel(database->getDatabase());
51
	xmlLogHandler = new XmlLogHandler();
52

53
	//
54
	// Load settings data
55 56
	//

57 58
	// init settings (-> "kaidan/kaidan.conf")
	settings = new QSettings(QString(APPLICATION_NAME), QString(APPLICATION_NAME));
59

60 61 62 63 64 65
	// get JID from settings
	jid = settings->value("auth/jid").toString();
	// get JID resource from settings
	jidResource = settings->value("auth/resource").toString();
	// get password from settings
	password = settings->value("auth/password").toString();
66

67
	// use Kaidan as resource, if no set
68
	if (jidResource == "") {
69 70
		jidResource = QString(APPLICATION_NAME);
		settings->setValue("auth/resource", jidResource);
71
	}
Marzanna's avatar
Marzanna committed
72 73 74 75
}

Kaidan::~Kaidan()
{
76
	if (connected) {
77
		client->disconnect();
Marzanna's avatar
Marzanna committed
78
		delete client;
Marzanna's avatar
Marzanna committed
79 80
	}

81
	delete serviceDiscoveryManager;
82
	delete messageSessionHandler;
83
	delete rosterManager;
84
	delete settings;
Marzanna's avatar
Marzanna committed
85 86
}

87 88 89
void Kaidan::mainConnect()
{
	// Create a new XMPP client
90
	client = new gloox::Client(gloox::JID(jid.toStdString()), password.toStdString());
91
	// require encryption
92
	client->setTls(gloox::TLSPolicy::TLSRequired);
93
	// set the JID resource
94 95 96 97
	client->setResource(jidResource.toStdString());

	// Connection listener
	client->registerConnectionListener(this);
98

99
	// Message receiving/sending
100 101
	messageSessionHandler = new MessageSessionHandler(client, messageModel);
	client->registerMessageSessionHandler((gloox::MessageSessionHandler*) messageSessionHandler);
102

103
	// Roster
104
	rosterManager = new RosterManager(rosterModel, client);
105

106 107 108 109
	// Presence Handler
	presenceHandler = new PresenceHandler(client);
	client->registerPresenceHandler(presenceHandler);

110 111 112
	// Service Discovery
	serviceDiscoveryManager = new ServiceDiscoveryManager(client->disco());

113 114 115
	// Register Stanza Extensions
	client->registerStanzaExtension(new gloox::Receipt(gloox::Receipt::Request));
	client->registerStanzaExtension(new gloox::Receipt(gloox::Receipt::Received));
116
	client->registerStanzaExtension(new gloox::DelayedDelivery(gloox::JID(), std::string("")));
117

118 119 120 121
	// Logging
	client->logInstance().registerLogHandler(gloox::LogLevelDebug,
		gloox::LogAreaXmlIncoming | gloox::LogAreaXmlOutgoing, xmlLogHandler);

122
	client->connect(false);
123

124 125 126 127
	// every 100 ms: fetch new packages from the socket
	QTimer *timer = new QTimer(this);
	connect(timer, SIGNAL(timeout()), this, SLOT(updateClient()));
	timer->start(100);
Georg's avatar
Georg committed
128 129
}

Marzanna's avatar
Marzanna committed
130 131
void Kaidan::mainDisconnect()
{
132
	if (connected) {
Marzanna's avatar
Marzanna committed
133 134
		client->disconnect();
	}
135
}
Georg's avatar
Georg committed
136

137
void Kaidan::onConnect()
Georg's avatar
Georg committed
138
{
139
	qDebug() << "[Connection] Connected successfully to server";
140
	// emit connected signal
Marzanna's avatar
Marzanna committed
141 142
	connected = true;
	emit connectionStateConnected();
Georg's avatar
Georg committed
143 144
}

145
void Kaidan::onDisconnect(gloox::ConnectionError error)
Marzanna's avatar
Marzanna committed
146
{
147
	qDebug() << "[Connection] Connection failed or disconnected" << error;
Marzanna's avatar
Marzanna committed
148 149 150 151
	connected = false;
	emit connectionStateDisconnected();
}

152 153 154 155 156 157 158 159 160 161 162 163 164
bool Kaidan::onTLSConnect(const gloox::CertInfo &info)
{
	// accept certificate
	qDebug() << "[Connection] Automatically accepting TLS certificate";
	return true;
}

void Kaidan::updateClient()
{
	// parse new incoming network packages; wait 0 ms for new ones
	client->recv(0);
}

Linus Jahn's avatar
Linus Jahn committed
165 166 167 168 169 170 171 172 173 174
bool Kaidan::newLoginNeeded()
{
	return (jid == "") || (password == "");
}

QString Kaidan::getJid()
{
	return jid;
}

175
void Kaidan::setJid(QString jid_)
176
{
177 178
	jid = jid_; // set new jid for mainConnect
	settings->setValue("auth/jid", jid_); // save to settings
179 180
}

Linus Jahn's avatar
Linus Jahn committed
181 182 183 184 185
QString Kaidan::getJidResource()
{
	return jidResource;
}

186
void Kaidan::setJidResource(QString jidResource_)
187
{
188 189
	jidResource = jidResource_;
	settings->setValue("auth/resource", jidResource); // save jid resource
190 191
}

Linus Jahn's avatar
Linus Jahn committed
192 193 194 195 196
QString Kaidan::getPassword()
{
	return password;
}

197 198
void Kaidan::setPassword(QString password_)
{
199 200
	password = password_; // set new password for
	settings->setValue("auth/password", password_); // save to settings
201
}
202

Linus Jahn's avatar
Linus Jahn committed
203 204 205 206 207 208 209 210 211 212 213 214 215 216
QString Kaidan::getChatPartner()
{
	return chatPartner;
}

void Kaidan::setChatPartner(QString chatPartner)
{
	// check if different
	if (this->chatPartner == chatPartner)
		return;

	// set the new chat partner
	this->chatPartner = chatPartner;

217
	// filter message for this chat partner
218
	messageModel->applyRecipientFilter(&chatPartner, &jid);
219 220

	rosterManager->setChatPartner(&chatPartner);
Linus Jahn's avatar
Linus Jahn committed
221 222 223 224 225 226

	emit chatPartnerChanged();
}

void Kaidan::sendMessage(QString jid, QString message)
{
227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244
	if (connected) {
		messageSessionHandler->getMessageHandler()->sendMessage(&(this->jid), &jid, &message);
		rosterManager->handleMessageSent(&jid, &message);
	}
}

void Kaidan::addContact(QString jid, QString nick)
{
	if (connected) {
		rosterManager->addContact(jid, nick);
	}
}

void Kaidan::removeContact(QString jid)
{
	if (connected) {
		rosterManager->removeContact(jid);
	}
Linus Jahn's avatar
Linus Jahn committed
245 246
}

247 248 249 250 251 252 253
QString Kaidan::getResourcePath(QString name_)
{
	// get the standard app data locations for current platform
	QStringList pathList = QStandardPaths::standardLocations(QStandardPaths::AppDataLocation);
	pathList << QString(DEBUG_SOURCE_PATH) + QString("/data"); // append debug directory

	// search for file in directories
254
	for (int i = 0; i < pathList.size(); i++) {
255 256 257
		// open directory
		QDir directory(pathList.at(i));
		// look up the file
258
		if (directory.exists(name_)) {
259
			// found the file, return the path
260
			return QString("file://") + directory.absoluteFilePath(name_);
261 262 263 264 265 266 267
		}
	}

	// no file found
	qWarning() << "Could NOT find media file:" << name_;
	return QString("");
}
Jonah Brüchert's avatar
Jonah Brüchert committed
268

269
RosterModel* Kaidan::getRosterModel()
270
{
271
	return rosterModel;
272
}
273 274

MessageModel* Kaidan::getMessageModel()
275
{
276
	return messageModel;
277
}
278

279 280 281 282
bool Kaidan::getConnectionState() const
{
	return connected;
}
283

284 285 286 287
QString Kaidan::getVersionString()
{
	return QString(VERSION_STRING);
}