From c678a790e53d0125d2dba31bd760ca9c3ce0c8d1 Mon Sep 17 00:00:00 2001 From: blue Date: Mon, 14 Oct 2019 23:18:51 +0300 Subject: [PATCH] some more methods for archive to store avatar states --- core/CMakeLists.txt | 2 +- core/archive.cpp | 188 ++++++++++++++++++++++++++++++++------------ core/archive.h | 12 ++- core/rosteritem.cpp | 15 +++- core/rosteritem.h | 5 ++ main.cpp | 1 - 6 files changed, 168 insertions(+), 55 deletions(-) diff --git a/core/CMakeLists.txt b/core/CMakeLists.txt index 46bf97a..c541ba2 100644 --- a/core/CMakeLists.txt +++ b/core/CMakeLists.txt @@ -3,7 +3,7 @@ project(squawkCORE) set(CMAKE_AUTOMOC ON) -find_package(Qt5Widgets CONFIG REQUIRED) +find_package(Qt5Core CONFIG REQUIRED) find_package(Qt5Network CONFIG REQUIRED) set(squawkCORE_SRC diff --git a/core/archive.cpp b/core/archive.cpp index 00139ac..295b04c 100644 --- a/core/archive.cpp +++ b/core/archive.cpp @@ -32,7 +32,10 @@ Core::Archive::Archive(const QString& p_jid, QObject* parent): environment(), main(), order(), - stats() + stats(), + hasAvatar(false), + avatarHash(), + avatarType() { } @@ -66,7 +69,26 @@ void Core::Archive::open(const QString& account) mdb_dbi_open(txn, "order", MDB_CREATE | MDB_INTEGERKEY, &order); mdb_dbi_open(txn, "stats", MDB_CREATE, &stats); mdb_txn_commit(txn); - fromTheBeginning = _isFromTheBeginning(); + + mdb_txn_begin(environment, NULL, 0, &txn); + try { + fromTheBeginning = getStatBoolValue("beginning", txn); + } catch (NotFound e) { + fromTheBeginning = false; + } + try { + hasAvatar = getStatBoolValue("hasAvatar", txn); + } catch (NotFound e) { + hasAvatar = false; + } + if (hasAvatar) { + avatarHash = getStatStringValue("avatarHash", txn).c_str(); + avatarType = getStatStringValue("avatarType", txn).c_str(); + } else { + avatarHash = ""; + avatarType = ""; + } + mdb_txn_abort(txn); opened = true; } } @@ -396,40 +418,6 @@ std::list Core::Archive::getBefore(int count, const QString& id return res; } -bool Core::Archive::_isFromTheBeginning() -{ - std::string strKey = "beginning"; - - MDB_val lmdbKey, lmdbData; - lmdbKey.mv_size = strKey.size(); - lmdbKey.mv_data = (char*)strKey.c_str(); - - MDB_txn *txn; - int rc; - mdb_txn_begin(environment, NULL, MDB_RDONLY, &txn); - rc = mdb_get(txn, stats, &lmdbKey, &lmdbData); - if (rc == MDB_NOTFOUND) { - mdb_txn_abort(txn); - return false; - } else if (rc) { - qDebug() <<"isFromTheBeginning error: " << mdb_strerror(rc); - mdb_txn_abort(txn); - throw NotFound(strKey, jid.toStdString()); - } else { - uint8_t value = *(uint8_t*)(lmdbData.mv_data); - bool is; - if (value == 144) { - is = false; - } else if (value == 72) { - is = true; - } else { - qDebug() <<"isFromTheBeginning error: stored value doesn't match any magic number, the answer is most probably wrong"; - } - mdb_txn_abort(txn); - return is; - } -} - bool Core::Archive::isFromTheBeginning() { if (!opened) { @@ -445,26 +433,15 @@ void Core::Archive::setFromTheBeginning(bool is) } if (fromTheBeginning != is) { fromTheBeginning = is; - const std::string& id = "beginning"; - uint8_t value = 144; - if (is) { - value = 72; - } - MDB_val lmdbKey, lmdbData; - lmdbKey.mv_size = id.size(); - lmdbKey.mv_data = (char*)id.c_str(); - lmdbData.mv_size = sizeof value; - lmdbData.mv_data = &value; MDB_txn *txn; mdb_txn_begin(environment, NULL, 0, &txn); - int rc; - rc = mdb_put(txn, stats, &lmdbKey, &lmdbData, 0); - if (rc != 0) { - qDebug() << "Couldn't store beginning key into stat database:" << mdb_strerror(rc); + bool success = setStatValue("beginning", is, txn); + if (success != 0) { mdb_txn_abort(txn); + } else { + mdb_txn_commit(txn); } - mdb_txn_commit(txn); } } @@ -508,3 +485,112 @@ void Core::Archive::printKeys() mdb_cursor_close(cursor); mdb_txn_abort(txn); } + +bool Core::Archive::getStatBoolValue(const std::string& id, MDB_txn* txn) +{ + MDB_val lmdbKey, lmdbData; + lmdbKey.mv_size = id.size(); + lmdbKey.mv_data = (char*)id.c_str(); + + int rc; + rc = mdb_get(txn, stats, &lmdbKey, &lmdbData); + if (rc == MDB_NOTFOUND) { + throw NotFound(id, jid.toStdString()); + } else if (rc) { + qDebug() << "error retrieving" << id.c_str() << "from stats db of" << jid << mdb_strerror(rc); + throw 15; //TODO proper exception + } else { + uint8_t value = *(uint8_t*)(lmdbData.mv_data); + bool is; + if (value == 144) { + is = false; + } else if (value == 72) { + is = true; + } else { + qDebug() << "error retrieving boolean stat" << id.c_str() << ": stored value doesn't match any magic number, the answer is most probably wrong"; + throw NotFound(id, jid.toStdString()); + } + return is; + } +} + +std::string Core::Archive::getStatStringValue(const std::string& id, MDB_txn* txn) +{ + MDB_cursor* cursor; + MDB_val lmdbKey, lmdbData; + lmdbKey.mv_size = id.size(); + lmdbKey.mv_data = (char*)id.c_str(); + + int rc; + rc = mdb_get(txn, stats, &lmdbKey, &lmdbData); + if (rc == MDB_NOTFOUND) { + throw NotFound(id, jid.toStdString()); + } else if (rc) { + qDebug() << "error retrieving" << id.c_str() << "from stats db of" << jid << mdb_strerror(rc); + throw 15; //TODO proper exception + } else { + std::string value((char*)lmdbData.mv_data, lmdbData.mv_size); + return value; + } +} + +bool Core::Archive::setStatValue(const std::string& id, bool value, MDB_txn* txn) +{ + uint8_t binvalue = 144; + if (value) { + binvalue = 72; + } + MDB_val lmdbKey, lmdbData; + lmdbKey.mv_size = id.size(); + lmdbKey.mv_data = (char*)id.c_str(); + lmdbData.mv_size = sizeof binvalue; + lmdbData.mv_data = &binvalue; + int rc = mdb_put(txn, stats, &lmdbKey, &lmdbData, 0); + if (rc != 0) { + qDebug() << "Couldn't store" << id.c_str() << "key into stat database:" << mdb_strerror(rc); + return false; + } + return true; +} + +bool Core::Archive::setStatValue(const std::string& id, const std::string& value, MDB_txn* txn) +{ + MDB_val lmdbKey, lmdbData; + lmdbKey.mv_size = id.size(); + lmdbKey.mv_data = (char*)id.c_str(); + lmdbData.mv_size = value.size(); + lmdbData.mv_data = (char*)value.c_str(); + int rc = mdb_put(txn, stats, &lmdbKey, &lmdbData, 0); + if (rc != 0) { + qDebug() << "Couldn't store" << id.c_str() << "key into stat database:" << mdb_strerror(rc); + return false; + } + return true; +} + +bool Core::Archive::getHasAvatar() const +{ + if (!opened) { + throw Closed("getHasAvatar", jid.toStdString()); + } + + return hasAvatar; +} + +QString Core::Archive::getAvatarHash() const +{ + if (!opened) { + throw Closed("getAvatarHash", jid.toStdString()); + } + + return avatarHash; +} + +QString Core::Archive::getAvatarType() const +{ + if (!opened) { + throw Closed("getAvatarType", jid.toStdString()); + } + + return avatarType; +} diff --git a/core/archive.h b/core/archive.h index 58a5f8d..45a7599 100644 --- a/core/archive.h +++ b/core/archive.h @@ -49,6 +49,9 @@ public: std::list getBefore(int count, const QString& id); bool isFromTheBeginning(); void setFromTheBeginning(bool is); + bool getHasAvatar() const; + QString getAvatarHash() const; + QString getAvatarType() const; public: const QString jid; @@ -131,8 +134,15 @@ private: MDB_dbi main; MDB_dbi order; MDB_dbi stats; + bool hasAvatar; + QString avatarHash; + QString avatarType; - bool _isFromTheBeginning(); + bool getStatBoolValue(const std::string& id, MDB_txn* txn); + std::string getStatStringValue(const std::string& id, MDB_txn* txn); + + bool setStatValue(const std::string& id, bool value, MDB_txn* txn); + bool setStatValue(const std::string& id, const std::string& value, MDB_txn* txn); void printOrder(); void printKeys(); }; diff --git a/core/rosteritem.cpp b/core/rosteritem.cpp index be6ceee..50b3b83 100644 --- a/core/rosteritem.cpp +++ b/core/rosteritem.cpp @@ -20,9 +20,10 @@ #include -Core::RosterItem::RosterItem(const QString& pJid, const QString& account, QObject* parent): +Core::RosterItem::RosterItem(const QString& pJid, const QString& pAccount, QObject* parent): QObject(parent), jid(pJid), + account(pAccount), name(), archiveState(empty), archive(new Archive(jid)), @@ -331,3 +332,15 @@ bool Core::RosterItem::isMuc() const { return muc; } + +QString Core::RosterItem::avatarHash() const +{ + return archive->getAvatarHash(); +} + +QString Core::RosterItem::avatarPath() const +{ + QString path(QStandardPaths::writableLocation(QStandardPaths::CacheLocation)); + path += "/" + account + "/" + jid + "/avatar." + archive->getAvatarType(); + return path; +} diff --git a/core/rosteritem.h b/core/rosteritem.h index e4284af..a2bc929 100644 --- a/core/rosteritem.h +++ b/core/rosteritem.h @@ -21,6 +21,7 @@ #include #include +#include #include @@ -58,6 +59,9 @@ public: void flushMessagesToArchive(bool finished, const QString& firstId, const QString& lastId); void requestHistory(int count, const QString& before); void requestFromEmpty(int count, const QString& before); + bool hasAvatar() const; + QString avatarHash() const; + QString avatarPath() const; signals: void nameChanged(const QString& name); @@ -67,6 +71,7 @@ signals: public: const QString jid; + const QString account; protected: QString name; diff --git a/main.cpp b/main.cpp index 6fcf6c9..0b8c9a4 100644 --- a/main.cpp +++ b/main.cpp @@ -48,7 +48,6 @@ int main(int argc, char *argv[]) QStringList shares = QStandardPaths::standardLocations(QStandardPaths::AppDataLocation); bool found = false; for (QString share : shares) { - qDebug() << share; found = myappTranslator.load(QLocale(), QLatin1String("squawk"), ".", share + "/l10n"); if (found) { break;