mucs initial, just display; archive fixes
This commit is contained in:
parent
30c59fbb91
commit
eda96e138d
19 changed files with 626 additions and 43 deletions
128
core/account.cpp
128
core/account.cpp
|
@ -16,11 +16,14 @@ Account::Account(const QString& p_login, const QString& p_server, const QString&
|
|||
groups(),
|
||||
cm(new QXmppCarbonManager()),
|
||||
am(new QXmppMamManager()),
|
||||
mm(new QXmppMucManager()),
|
||||
bm(new QXmppBookmarkManager()),
|
||||
contacts(),
|
||||
maxReconnectTimes(0),
|
||||
reconnectTimes(0),
|
||||
queuedContacts(),
|
||||
outOfRosterContacts()
|
||||
outOfRosterContacts(),
|
||||
mucInfo()
|
||||
{
|
||||
config.setUser(p_login);
|
||||
config.setDomain(p_server);
|
||||
|
@ -52,6 +55,12 @@ Account::Account(const QString& p_login, const QString& p_server, const QString&
|
|||
QObject::connect(am, SIGNAL(archivedMessageReceived(const QString&, const QXmppMessage&)), this, SLOT(onMamMessageReceived(const QString&, const QXmppMessage&)));
|
||||
QObject::connect(am, SIGNAL(resultsRecieved(const QString&, const QXmppResultSetReply&, bool)),
|
||||
this, SLOT(onMamResultsReceived(const QString&, const QXmppResultSetReply&, bool)));
|
||||
|
||||
client.addExtension(mm);
|
||||
QObject::connect(mm, SIGNAL(roomAdded(QXmppMucRoom*)), this, SLOT(onMucRoomAdded(QXmppMucRoom*)));
|
||||
|
||||
client.addExtension(bm);
|
||||
QObject::connect(bm, SIGNAL(bookmarksReceived(const QXmppBookmarkSet&)), this, SLOT(bookmarksReceived(const QXmppBookmarkSet&)));
|
||||
}
|
||||
|
||||
Account::~Account()
|
||||
|
@ -59,6 +68,11 @@ Account::~Account()
|
|||
for (std::map<QString, Contact*>::const_iterator itr = contacts.begin(), end = contacts.end(); itr != end; ++itr) {
|
||||
delete itr->second;
|
||||
}
|
||||
|
||||
delete bm;
|
||||
delete mm;
|
||||
delete am;
|
||||
delete cm;
|
||||
}
|
||||
|
||||
Shared::ConnectionState Core::Account::getState() const
|
||||
|
@ -433,6 +447,7 @@ void Core::Account::sendMessage(const Shared::Message& data)
|
|||
msg.setType(static_cast<QXmppMessage::Type>(data.getType())); //it is safe here, my type is compatible
|
||||
|
||||
std::map<QString, Contact*>::const_iterator itr = contacts.find(data.getPenPalJid());
|
||||
|
||||
itr->second->appendMessageToArchive(data);
|
||||
|
||||
client.sendPacket(msg);
|
||||
|
@ -846,3 +861,114 @@ void Core::Account::addContactRequest(const QString& jid, const QString& name, c
|
|||
qDebug() << "An attempt to add contact " << jid << " to account " << name << " but the account is not in the connected state, skipping";
|
||||
}
|
||||
}
|
||||
|
||||
void Core::Account::onMucRoomAdded(QXmppMucRoom* room)
|
||||
{
|
||||
qDebug() << "room" << room->jid() << "added with name" << room->name() << ", account" << getName() << "joined:" << room->isJoined();
|
||||
}
|
||||
|
||||
void Core::Account::bookmarksReceived(const QXmppBookmarkSet& bookmarks)
|
||||
{
|
||||
QList<QXmppBookmarkConference> conferences = bookmarks.conferences();
|
||||
for (QList<QXmppBookmarkConference>::const_iterator itr = conferences.begin(), end = conferences.end(); itr != end; ++itr) {
|
||||
const QXmppBookmarkConference& c = *itr;
|
||||
|
||||
QString jid = c.jid();
|
||||
std::pair<std::map<QString, MucInfo>::iterator, bool> mi = mucInfo.insert(std::make_pair(jid, MucInfo(c.autoJoin(), false, jid, c.name(), c.nickName())));
|
||||
if (mi.second) {
|
||||
const MucInfo& info = mi.first->second;
|
||||
QXmppMucRoom* room = mm->addRoom(jid);
|
||||
|
||||
QObject::connect(room, SIGNAL(joined()), this, SLOT(onMucJoined()));
|
||||
QObject::connect(room, SIGNAL(left()), this, SLOT(onMucLeft()));
|
||||
QObject::connect(room, SIGNAL(nameChanged(const QString&)), this, SLOT(onMucNameChanged(const QString&)));
|
||||
QObject::connect(room, SIGNAL(nickNameChanged(const QString&)), this, SLOT(onMucNickNameChanged(const QString&)));
|
||||
QObject::connect(room, SIGNAL(error(const QXmppStanza::Error&)), this, SLOT(onMucError(const QXmppStanza::Error&)));
|
||||
QObject::connect(room, SIGNAL(messageReceived(const QXmppMessage&)), this, SLOT(onMucMessage(const QXmppMessage&)));
|
||||
|
||||
emit addRoom(jid, {
|
||||
{"autoJoin", info.autoJoin},
|
||||
{"joined", false},
|
||||
{"nick", info.nick},
|
||||
{"name", info.name}
|
||||
});
|
||||
|
||||
room->setNickName(info.nick == "" ? getName() : info.nick);
|
||||
if (info.autoJoin) {
|
||||
room->join();
|
||||
}
|
||||
} else {
|
||||
qDebug() << "Received a bookmark to a MUC " << jid << " which is already booked by another bookmark, skipping";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Core::Account::onMucJoined()
|
||||
{
|
||||
QXmppMucRoom* room = static_cast<QXmppMucRoom*>(sender());
|
||||
QString jid = room->jid();
|
||||
std::map<QString, MucInfo>::iterator itr = mucInfo.find(jid);
|
||||
if (itr != mucInfo.end()) {
|
||||
itr->second.joined = true;
|
||||
emit changeRoom(jid, {
|
||||
{"joined", true}
|
||||
});
|
||||
} else {
|
||||
qDebug() << "Seems like account" << getName() << "joined room" << jid << ", but the info about that room wasn't found, skipping";
|
||||
}
|
||||
}
|
||||
|
||||
void Core::Account::onMucLeft()
|
||||
{
|
||||
QXmppMucRoom* room = static_cast<QXmppMucRoom*>(sender());
|
||||
QString jid = room->jid();
|
||||
std::map<QString, MucInfo>::iterator itr = mucInfo.find(jid);
|
||||
if (itr != mucInfo.end()) {
|
||||
itr->second.joined = false;
|
||||
emit changeRoom(jid, {
|
||||
{"joined", false}
|
||||
});
|
||||
} else {
|
||||
qDebug() << "Seems like account" << getName() << "left room" << jid << ", but the info about that room wasn't found, skipping";
|
||||
}
|
||||
}
|
||||
|
||||
void Core::Account::onMucNameChanged(const QString& roomName)
|
||||
{
|
||||
QXmppMucRoom* room = static_cast<QXmppMucRoom*>(sender());
|
||||
QString jid = room->jid();
|
||||
std::map<QString, MucInfo>::iterator itr = mucInfo.find(jid);
|
||||
if (itr != mucInfo.end()) {
|
||||
itr->second.name = roomName;
|
||||
emit changeRoom(jid, {
|
||||
{"name", roomName}
|
||||
});
|
||||
} else {
|
||||
qDebug() << "Account" << getName() << "received an event about room" << jid << "name change, but the info about that room wasn't found, skipping";
|
||||
}
|
||||
}
|
||||
|
||||
void Core::Account::onMucNickNameChanged(const QString& nickName)
|
||||
{
|
||||
QXmppMucRoom* room = static_cast<QXmppMucRoom*>(sender());
|
||||
QString jid = room->jid();
|
||||
std::map<QString, MucInfo>::iterator itr = mucInfo.find(jid);
|
||||
if (itr != mucInfo.end()) {
|
||||
itr->second.nick = nickName;
|
||||
emit changeRoom(jid, {
|
||||
{"nick", nickName}
|
||||
});
|
||||
} else {
|
||||
qDebug() << "Account" << getName() << "received an event about his nick name change in room" << jid << ", but the info about that room wasn't found, skipping";
|
||||
}
|
||||
}
|
||||
|
||||
void Core::Account::onMucError(const QXmppStanza::Error& error)
|
||||
{
|
||||
qDebug() << "MUC error";
|
||||
}
|
||||
|
||||
void Core::Account::onMucMessage(const QXmppMessage& message)
|
||||
{
|
||||
qDebug() << "Muc message";
|
||||
}
|
||||
|
|
|
@ -8,7 +8,10 @@
|
|||
#include <QXmppRosterManager.h>
|
||||
#include <QXmppCarbonManager.h>
|
||||
#include <QXmppMamManager.h>
|
||||
#include <QXmppMucManager.h>
|
||||
#include <QXmppClient.h>
|
||||
#include <QXmppBookmarkManager.h>
|
||||
#include <QXmppBookmarkSet.h>
|
||||
#include "../global.h"
|
||||
#include "contact.h"
|
||||
|
||||
|
@ -18,6 +21,7 @@ namespace Core
|
|||
class Account : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
class MucInfo;
|
||||
public:
|
||||
Account(const QString& p_login, const QString& p_server, const QString& p_password, const QString& p_name, QObject* parent = 0);
|
||||
~Account();
|
||||
|
@ -54,6 +58,9 @@ signals:
|
|||
void availabilityChanged(int);
|
||||
void addGroup(const QString& name);
|
||||
void removeGroup(const QString& name);
|
||||
void addRoom(const QString& jid, const QMap<QString, QVariant>& data);
|
||||
void changeRoom(const QString& jid, const QMap<QString, QVariant>& data);
|
||||
void removeRoom(const QString& jid);
|
||||
void addContact(const QString& jid, const QString& group, const QMap<QString, QVariant>& data);
|
||||
void removeContact(const QString& jid);
|
||||
void removeContact(const QString& jid, const QString& group);
|
||||
|
@ -74,12 +81,15 @@ private:
|
|||
std::map<QString, std::set<QString>> groups;
|
||||
QXmppCarbonManager* cm;
|
||||
QXmppMamManager* am;
|
||||
QXmppMucManager* mm;
|
||||
QXmppBookmarkManager* bm;
|
||||
std::map<QString, Contact*> contacts;
|
||||
unsigned int maxReconnectTimes;
|
||||
unsigned int reconnectTimes;
|
||||
|
||||
std::map<QString, QString> queuedContacts;
|
||||
std::set<QString> outOfRosterContacts;
|
||||
std::map<QString, MucInfo> mucInfo;
|
||||
|
||||
private slots:
|
||||
void onClientConnected();
|
||||
|
@ -101,6 +111,16 @@ private slots:
|
|||
void onMamMessageReceived(const QString& bareJid, const QXmppMessage& message);
|
||||
void onMamResultsReceived(const QString &queryId, const QXmppResultSetReply &resultSetReply, bool complete);
|
||||
|
||||
void onMucRoomAdded(QXmppMucRoom* room);
|
||||
void onMucJoined();
|
||||
void onMucLeft();
|
||||
void onMucNameChanged(const QString& roomName);
|
||||
void onMucNickNameChanged(const QString& nickName);
|
||||
void onMucError(const QXmppStanza::Error& error);
|
||||
void onMucMessage(const QXmppMessage& message);
|
||||
|
||||
void bookmarksReceived(const QXmppBookmarkSet& bookmarks);
|
||||
|
||||
void onContactGroupAdded(const QString& group);
|
||||
void onContactGroupRemoved(const QString& group);
|
||||
void onContactNameChanged(const QString& name);
|
||||
|
@ -119,8 +139,28 @@ private:
|
|||
void initializeMessage(Shared::Message& target, const QXmppMessage& source, bool outgoing = false, bool forwarded = false, bool guessing = false) const;
|
||||
Shared::SubscriptionState castSubscriptionState(QXmppRosterIq::Item::SubscriptionType qs) const;
|
||||
void logMessage(const QXmppMessage& msg, const QString& reason = "Message wasn't handled: ");
|
||||
|
||||
|
||||
class MucInfo {
|
||||
public:
|
||||
MucInfo(bool p_al, bool p_jo, const QString& p_jid, const QString& p_name, const QString& p_nick):
|
||||
autoJoin(p_al),
|
||||
joined(p_jo),
|
||||
jid(p_jid),
|
||||
name(p_name),
|
||||
nick(p_nick),
|
||||
removed(false) {}
|
||||
|
||||
bool autoJoin;
|
||||
bool joined;
|
||||
QString jid;
|
||||
QString name;
|
||||
QString nick;
|
||||
bool removed;
|
||||
};
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
|
||||
#endif // CORE_ACCOUNT_H
|
||||
|
|
|
@ -31,7 +31,8 @@ Core::Archive::Archive(const QString& p_jid, QObject* parent):
|
|||
fromTheBeginning(false),
|
||||
environment(),
|
||||
main(),
|
||||
order()
|
||||
order(),
|
||||
stats()
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -55,14 +56,14 @@ void Core::Archive::open(const QString& account)
|
|||
}
|
||||
}
|
||||
|
||||
mdb_env_set_maxdbs(environment, 3);
|
||||
mdb_env_set_maxdbs(environment, 4);
|
||||
mdb_env_open(environment, path.toStdString().c_str(), 0, 0664);
|
||||
|
||||
MDB_txn *txn;
|
||||
mdb_txn_begin(environment, NULL, 0, &txn);
|
||||
mdb_dbi_open(txn, "main", MDB_CREATE, &main);
|
||||
mdb_dbi_open(txn, "order", MDB_CREATE | MDB_INTEGERKEY, &order);
|
||||
mdb_dbi_open(txn, "order", MDB_CREATE, &stats);
|
||||
mdb_dbi_open(txn, "stats", MDB_CREATE, &stats);
|
||||
mdb_txn_commit(txn);
|
||||
fromTheBeginning = _isFromTheBeginning();
|
||||
opened = true;
|
||||
|
@ -135,6 +136,7 @@ void Core::Archive::clear()
|
|||
mdb_txn_begin(environment, NULL, 0, &txn);
|
||||
mdb_drop(txn, main, 0);
|
||||
mdb_drop(txn, order, 0);
|
||||
mdb_drop(txn, stats, 0);
|
||||
mdb_txn_commit(txn);
|
||||
}
|
||||
|
||||
|
@ -201,6 +203,32 @@ QString Core::Archive::newestId()
|
|||
}
|
||||
}
|
||||
|
||||
QString Core::Archive::oldestId()
|
||||
{
|
||||
if (!opened) {
|
||||
throw Closed("oldestId", jid.toStdString());
|
||||
}
|
||||
MDB_txn *txn;
|
||||
int rc;
|
||||
rc = mdb_txn_begin(environment, NULL, MDB_RDONLY, &txn);
|
||||
MDB_cursor* cursor;
|
||||
rc = mdb_cursor_open(txn, order, &cursor);
|
||||
MDB_val lmdbKey, lmdbData;
|
||||
|
||||
rc = mdb_cursor_get(cursor, &lmdbKey, &lmdbData, MDB_FIRST);
|
||||
if (rc) {
|
||||
qDebug() << "Error geting oldestId " << mdb_strerror(rc);
|
||||
mdb_cursor_close(cursor);
|
||||
mdb_txn_abort(txn);
|
||||
throw Empty(jid.toStdString());
|
||||
} else {
|
||||
std::string sId((char*)lmdbData.mv_data, lmdbData.mv_size);
|
||||
mdb_cursor_close(cursor);
|
||||
mdb_txn_abort(txn);
|
||||
return sId.c_str();
|
||||
}
|
||||
}
|
||||
|
||||
Shared::Message Core::Archive::oldest()
|
||||
{
|
||||
return getElement(oldestId());
|
||||
|
@ -264,33 +292,6 @@ unsigned int Core::Archive::addElements(const std::list<Shared::Message>& messag
|
|||
return success;
|
||||
}
|
||||
|
||||
|
||||
QString Core::Archive::oldestId()
|
||||
{
|
||||
if (!opened) {
|
||||
throw Closed("oldestId", jid.toStdString());
|
||||
}
|
||||
MDB_txn *txn;
|
||||
int rc;
|
||||
rc = mdb_txn_begin(environment, NULL, MDB_RDONLY, &txn);
|
||||
MDB_cursor* cursor;
|
||||
rc = mdb_cursor_open(txn, order, &cursor);
|
||||
MDB_val lmdbKey, lmdbData;
|
||||
|
||||
rc = mdb_cursor_get(cursor, &lmdbKey, &lmdbData, MDB_FIRST);
|
||||
if (rc) {
|
||||
qDebug() << "Error geting oldestId " << mdb_strerror(rc);
|
||||
mdb_cursor_close(cursor);
|
||||
mdb_txn_abort(txn);
|
||||
throw Empty(jid.toStdString());
|
||||
} else {
|
||||
std::string sId((char*)lmdbData.mv_data, lmdbData.mv_size);
|
||||
mdb_cursor_close(cursor);
|
||||
mdb_txn_abort(txn);
|
||||
return sId.c_str();
|
||||
}
|
||||
}
|
||||
|
||||
long unsigned int Core::Archive::size() const
|
||||
{
|
||||
if (!opened) {
|
||||
|
@ -422,6 +423,7 @@ bool Core::Archive::_isFromTheBeginning()
|
|||
} else {
|
||||
qDebug() <<"isFromTheBeginning error: stored value doesn't match any magic number, the answer is most probably wrong";
|
||||
}
|
||||
mdb_txn_abort(txn);
|
||||
return is;
|
||||
}
|
||||
}
|
||||
|
@ -460,6 +462,7 @@ void Core::Archive::setFromTheBeginning(bool is)
|
|||
qDebug() << "Couldn't store beginning key into stat database:" << mdb_strerror(rc);
|
||||
mdb_txn_abort(txn);
|
||||
}
|
||||
mdb_txn_commit(txn);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -266,6 +266,7 @@ void Core::Contact::flushMessagesToArchive(bool finished, const QString& firstId
|
|||
hisoryCache.clear();
|
||||
}
|
||||
|
||||
bool wasEmpty = false;
|
||||
switch (archiveState) {
|
||||
case beginning:
|
||||
if (finished) {
|
||||
|
@ -288,9 +289,10 @@ void Core::Contact::flushMessagesToArchive(bool finished, const QString& firstId
|
|||
}
|
||||
break;
|
||||
case empty:
|
||||
wasEmpty = true;
|
||||
archiveState = end;
|
||||
case end:
|
||||
if (finished) {
|
||||
if (finished && (added > 0 || !wasEmpty)) {
|
||||
archiveState = complete;
|
||||
archive->setFromTheBeginning(true);
|
||||
}
|
||||
|
|
|
@ -102,6 +102,13 @@ void Core::Squawk::addAccount(const QString& login, const QString& server, const
|
|||
connect(acc, SIGNAL(responseArchive(const QString&, const std::list<Shared::Message>&)),
|
||||
this, SLOT(onAccountResponseArchive(const QString&, const std::list<Shared::Message>&)));
|
||||
|
||||
connect(acc, SIGNAL(addRoom(const QString&, const QMap<QString, QVariant>&)),
|
||||
this, SLOT(onAccountAddRoom(const QString&, const QMap<QString, QVariant>&)));
|
||||
connect(acc, SIGNAL(changeRoom(const QString&, const QMap<QString, QVariant>&)),
|
||||
this, SLOT(onAccountChangeRoom(const QString&, const QMap<QString, QVariant>&)));
|
||||
connect(acc, SIGNAL(removeRoom(const QString&)), this, SLOT(onAccountRemoveRoom(const QString&)));
|
||||
|
||||
|
||||
QMap<QString, QVariant> map = {
|
||||
{"login", login},
|
||||
{"server", server},
|
||||
|
@ -376,3 +383,21 @@ void Core::Squawk::addContactRequest(const QString& account, const QString& jid,
|
|||
|
||||
itr->second->addContactRequest(jid, name, groups);
|
||||
}
|
||||
|
||||
void Core::Squawk::onAccountAddRoom(const QString jid, const QMap<QString, QVariant>& data)
|
||||
{
|
||||
Account* acc = static_cast<Account*>(sender());
|
||||
emit addRoom(acc->getName(), jid, data);
|
||||
}
|
||||
|
||||
void Core::Squawk::onAccountChangeRoom(const QString jid, const QMap<QString, QVariant>& data)
|
||||
{
|
||||
Account* acc = static_cast<Account*>(sender());
|
||||
emit changeRoom(acc->getName(), jid, data);
|
||||
}
|
||||
|
||||
void Core::Squawk::onAccountRemoveRoom(const QString jid)
|
||||
{
|
||||
Account* acc = static_cast<Account*>(sender());
|
||||
emit removeRoom(acc->getName(), jid);
|
||||
}
|
||||
|
|
|
@ -37,6 +37,9 @@ signals:
|
|||
void stateChanged(int state);
|
||||
void accountMessage(const QString& account, const Shared::Message& data);
|
||||
void responseArchive(const QString& account, const QString& jid, const std::list<Shared::Message>& list);
|
||||
void addRoom(const QString& account, const QString jid, const QMap<QString, QVariant>& data);
|
||||
void changeRoom(const QString& account, const QString jid, const QMap<QString, QVariant>& data);
|
||||
void removeRoom(const QString& account, const QString jid);
|
||||
|
||||
public slots:
|
||||
void start();
|
||||
|
@ -79,6 +82,9 @@ private slots:
|
|||
void onAccountRemovePresence(const QString& jid, const QString& name);
|
||||
void onAccountMessage(const Shared::Message& data);
|
||||
void onAccountResponseArchive(const QString& jid, const std::list<Shared::Message>& list);
|
||||
void onAccountAddRoom(const QString jid, const QMap<QString, QVariant>& data);
|
||||
void onAccountChangeRoom(const QString jid, const QMap<QString, QVariant>& data);
|
||||
void onAccountRemoveRoom(const QString jid);
|
||||
};
|
||||
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue