finally launches again, started contact abstraction in server

This commit is contained in:
Blue 2019-04-17 23:08:56 +03:00
parent 7f2657a5b6
commit 7aa519c4ad
8 changed files with 162 additions and 71 deletions

View File

@ -12,6 +12,7 @@ set(squawkCORE_SRC
squawk.cpp squawk.cpp
account.cpp account.cpp
archive.cpp archive.cpp
contact.cpp
) )
# Tell CMake to create the helloworld executable # Tell CMake to create the helloworld executable

View File

@ -14,7 +14,8 @@ Account::Account(const QString& p_login, const QString& p_server, const QString&
state(Shared::disconnected), state(Shared::disconnected),
groups(), groups(),
cm(new QXmppCarbonManager()), cm(new QXmppCarbonManager()),
am(new QXmppMamManager()) am(new QXmppMamManager()),
contacts()
{ {
config.setUser(p_login); config.setUser(p_login);
config.setDomain(p_server); config.setDomain(p_server);
@ -216,6 +217,12 @@ void Core::Account::onRosterItemRemoved(const QString& bareJid)
void Core::Account::addedAccount(const QString& jid) void Core::Account::addedAccount(const QString& jid)
{ {
QXmppRosterManager& rm = client.rosterManager(); QXmppRosterManager& rm = client.rosterManager();
std::map<QString, Contact*>::const_iterator itr = contacts.find(jid);
if (itr == contacts.end()) {
}
QXmppRosterIq::Item re = rm.getRosterEntry(jid); QXmppRosterIq::Item re = rm.getRosterEntry(jid);
QSet<QString> gr = re.groups(); QSet<QString> gr = re.groups();
unsigned int state = re.subscriptionType(); unsigned int state = re.subscriptionType();

View File

@ -10,6 +10,7 @@
#include <qxmpp/QXmppMamManager.h> #include <qxmpp/QXmppMamManager.h>
#include <qxmpp/QXmppClient.h> #include <qxmpp/QXmppClient.h>
#include "../global.h" #include "../global.h"
#include "contact.h"
namespace Core namespace Core
{ {
@ -65,6 +66,7 @@ private:
std::map<QString, std::set<QString>> groups; std::map<QString, std::set<QString>> groups;
QXmppCarbonManager* cm; QXmppCarbonManager* cm;
QXmppMamManager* am; QXmppMamManager* am;
std::map<QString, Contact*> contacts;
private slots: private slots:
void onClientConnected(); void onClientConnected();

View File

@ -32,16 +32,17 @@ Core::Archive::Archive(const QString& p_jid, QObject* parent):
main(), main(),
order() order()
{ {
mdb_env_create(&environment);
} }
Core::Archive::~Archive() Core::Archive::~Archive()
{ {
close();
} }
void Core::Archive::open(const QString& account) void Core::Archive::open(const QString& account)
{ {
if (!opened) { if (!opened) {
mdb_env_create(&environment);
QString path(QStandardPaths::writableLocation(QStandardPaths::CacheLocation)); QString path(QStandardPaths::writableLocation(QStandardPaths::CacheLocation));
path += "/" + account + "/" + jid; path += "/" + account + "/" + jid;
QDir cache(path); QDir cache(path);
@ -56,28 +57,25 @@ void Core::Archive::open(const QString& account)
mdb_env_set_maxdbs(environment, 2); mdb_env_set_maxdbs(environment, 2);
mdb_env_open(environment, path.toStdString().c_str(), 0, 0664); mdb_env_open(environment, path.toStdString().c_str(), 0, 0664);
int rc;
MDB_txn *txn; MDB_txn *txn;
rc = mdb_txn_begin(environment, NULL, 0, &txn); mdb_txn_begin(environment, NULL, 0, &txn);
if (rc) { mdb_dbi_open(txn, "main", MDB_CREATE, &main);
qDebug() << "opening transaction error " << mdb_strerror(rc); mdb_dbi_open(txn, "order", MDB_CREATE | MDB_INTEGERKEY, &order);
} mdb_txn_commit(txn);
rc = mdb_dbi_open(txn, "main", MDB_CREATE, &main);
if (rc) {
qDebug() << "main opening error " << mdb_strerror(rc);
}
rc = mdb_dbi_open(txn, "order", MDB_CREATE | MDB_INTEGERKEY, &order);
if (rc) {
qDebug() << "order opening error " << mdb_strerror(rc);
}
rc = mdb_txn_commit(txn);
if (rc) {
qDebug() << "opening commit transaction error " << mdb_strerror(rc);
}
opened = true; opened = true;
} }
} }
void Core::Archive::close()
{
if (opened) {
mdb_dbi_close(environment, order);
mdb_dbi_close(environment, main);
mdb_env_close(environment);
opened = false;
}
}
void Core::Archive::addElement(const Shared::Message& message) void Core::Archive::addElement(const Shared::Message& message)
{ {
if (!opened) { if (!opened) {
@ -89,12 +87,9 @@ void Core::Archive::addElement(const Shared::Message& message)
quint64 stamp = message.getTime().toMSecsSinceEpoch(); quint64 stamp = message.getTime().toMSecsSinceEpoch();
const std::string& id = message.getId().toStdString(); const std::string& id = message.getId().toStdString();
qDebug() << "inserting element with id " << id.c_str();
qDebug() << "data size is " << ba.size();
MDB_val lmdbKey, lmdbData; MDB_val lmdbKey, lmdbData;
lmdbKey.mv_size = id.size(); lmdbKey.mv_size = id.size();
lmdbKey.mv_data = (uint8_t*)id.c_str(); lmdbKey.mv_data = (char*)id.c_str();
lmdbData.mv_size = ba.size(); lmdbData.mv_size = ba.size();
lmdbData.mv_data = (uint8_t*)ba.data(); lmdbData.mv_data = (uint8_t*)ba.data();
MDB_txn *txn; MDB_txn *txn;
@ -141,20 +136,15 @@ Shared::Message Core::Archive::getElement(const QString& id)
throw Closed("getElement", jid.toStdString()); throw Closed("getElement", jid.toStdString());
} }
qDebug() << "getting an element with id " << id.toStdString().c_str(); std::string strKey = id.toStdString();
MDB_val lmdbKey, lmdbData; MDB_val lmdbKey, lmdbData;
lmdbKey.mv_size = id.toStdString().size(); lmdbKey.mv_size = strKey.size();
lmdbKey.mv_data = (uint8_t*)id.toStdString().c_str(); lmdbKey.mv_data = (char*)strKey.c_str();
MDB_txn *txn; MDB_txn *txn;
int rc; int rc;
rc = mdb_txn_begin(environment, NULL, MDB_RDONLY, &txn); mdb_txn_begin(environment, NULL, MDB_RDONLY, &txn);
if (rc) {
qDebug() <<"Get error: " << mdb_strerror(rc);
mdb_txn_abort(txn);
throw NotFound(id.toStdString(), jid.toStdString());
}
rc = mdb_get(txn, main, &lmdbKey, &lmdbData); rc = mdb_get(txn, main, &lmdbKey, &lmdbData);
if (rc) { if (rc) {
qDebug() <<"Get error: " << mdb_strerror(rc); qDebug() <<"Get error: " << mdb_strerror(rc);
@ -191,16 +181,15 @@ QString Core::Archive::newestId()
rc = mdb_cursor_get(cursor, &lmdbKey, &lmdbData, MDB_LAST); rc = mdb_cursor_get(cursor, &lmdbKey, &lmdbData, MDB_LAST);
if (rc) { if (rc) {
std::string sId((char*)lmdbData.mv_data, lmdbData.mv_size);
mdb_cursor_close(cursor);
mdb_txn_abort(txn);
qDebug() << "newest id is " << sId.c_str();
return sId.c_str();
} else {
qDebug() << "Error geting newestId " << mdb_strerror(rc); qDebug() << "Error geting newestId " << mdb_strerror(rc);
mdb_cursor_close(cursor); mdb_cursor_close(cursor);
mdb_txn_abort(txn); mdb_txn_abort(txn);
throw new Empty(jid.toStdString()); throw new 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();
} }
} }
@ -223,21 +212,23 @@ QString Core::Archive::oldestId()
rc = mdb_cursor_get(cursor, &lmdbKey, &lmdbData, MDB_FIRST); rc = mdb_cursor_get(cursor, &lmdbKey, &lmdbData, MDB_FIRST);
if (rc) { if (rc) {
std::string sId((char*)lmdbData.mv_data, lmdbData.mv_size);
mdb_cursor_close(cursor);
mdb_txn_abort(txn);
qDebug() << "oldest id is " << sId.c_str();
return sId.c_str();
} else {
qDebug() << "Error geting oldestId " << mdb_strerror(rc); qDebug() << "Error geting oldestId " << mdb_strerror(rc);
mdb_cursor_close(cursor); mdb_cursor_close(cursor);
mdb_txn_abort(txn); mdb_txn_abort(txn);
throw new Empty(jid.toStdString()); throw new 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 long unsigned int Core::Archive::size() const
{ {
if (!opened) {
throw Closed("size", jid.toStdString());
}
MDB_txn *txn; MDB_txn *txn;
int rc; int rc;
rc = mdb_txn_begin(environment, NULL, MDB_RDONLY, &txn); rc = mdb_txn_begin(environment, NULL, MDB_RDONLY, &txn);

View File

@ -34,6 +34,7 @@ public:
~Archive(); ~Archive();
void open(const QString& account); void open(const QString& account);
void close();
void addElement(const Shared::Message& message); void addElement(const Shared::Message& message);
Shared::Message getElement(const QString& id); Shared::Message getElement(const QString& id);

57
core/contact.cpp Normal file
View File

@ -0,0 +1,57 @@
/*
* <one line to give the program's name and a brief idea of what it does.>
* Copyright (C) 2019 Yury Gubich <blue@macaw.me>
*
* This program 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.
*
* This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "contact.h"
Core::Contact::Contact(const QString& pJid, const QString& account, QObject* parent):
QObject(parent),
jid(pJid),
name(),
groups(),
state(empty),
archive(new Archive(jid))
{
archive->open(account);
}
Core::Contact::~Contact()
{
delete archive;
}
Core::Contact::ArchiveState Core::Contact::getArchiveState() const
{
return state;
}
QSet<QString> Core::Contact::getGroups() const
{
return groups;
}
QString Core::Contact::getName() const
{
return name;
}
void Core::Contact::setName(const QString& n)
{
if (name != n) {
name = n;
}
}

59
core/contact.h Normal file
View File

@ -0,0 +1,59 @@
/*
* <one line to give the program's name and a brief idea of what it does.>
* Copyright (C) 2019 Yury Gubich <blue@macaw.me>
*
* This program 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.
*
* This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef CORE_CONTACT_H
#define CORE_CONTACT_H
#include <QObject>
#include <QSet>
#include "archive.h"
namespace Core {
class Contact : public QObject
{
Q_OBJECT
public:
enum ArchiveState {
empty, //have no messages stored for this contact
chunk, //have some chunk of history, don't have the beginning nor have the end
beginning, //have the history from the very beginning, don't have the end
end, //have the history to the end, but don't have the beginning
complete //have full history locally stored
};
Contact(const QString& pJid, const QString& account, QObject* parent = 0);
~Contact();
ArchiveState getArchiveState() const;
QString getName() const;
void setName(const QString& n);
QSet<QString> getGroups() const;
public:
const QString jid;
private:
QString name;
QSet<QString> groups;
ArchiveState state;
Archive* archive;
};
}
#endif // CORE_CONTACT_H

View File

@ -5,7 +5,6 @@
#include <QtCore/QThread> #include <QtCore/QThread>
#include <QtCore/QObject> #include <QtCore/QObject>
#include <QSettings> #include <QSettings>
#include "core/archive.h"
int main(int argc, char *argv[]) int main(int argc, char *argv[])
{ {
@ -57,32 +56,6 @@ int main(int argc, char *argv[])
//qDebug() << QStandardPaths::writableLocation(QStandardPaths::CacheLocation); //qDebug() << QStandardPaths::writableLocation(QStandardPaths::CacheLocation);
Core::Archive ar("test1@macaw.me");
ar.open("Test");
Shared::Message msg1;
msg1.generateRandomId();
msg1.setBody("oldest");
msg1.setTime(QDateTime::currentDateTime().addDays(-7));
Shared::Message msg2;
msg2.generateRandomId();
msg2.setBody("Middle");
msg2.setTime(QDateTime::currentDateTime().addDays(-4));
Shared::Message msg3;
msg3.generateRandomId();
msg3.setBody("newest");
msg3.setTime(QDateTime::currentDateTime());
ar.addElement(msg2);
ar.addElement(msg3);
ar.addElement(msg1);
Shared::Message d0 = ar.getElement(msg1.getId());
Shared::Message d1 = ar.newest();
Shared::Message d2 = ar.oldest();
qDebug() << d1.getBody() << ", " << d2.getBody();
coreThread->start(); coreThread->start();
int result = app.exec(); int result = app.exec();