From: Janne Koschinski Date: Tue, 8 May 2018 20:17:38 +0000 (-0500) Subject: Implement sender realname/avatarurl storage X-Git-Tag: travis-deploy-test~117 X-Git-Url: https://git.quassel-irc.org/?p=quassel.git;a=commitdiff_plain;h=20f446a492d8e681156423f0dc3637db78c45bae;hp=458c3278a4b9102bcc470d48816fac379492a588 Implement sender realname/avatarurl storage - Store sender realname and avatarurl in database - Guard protocol changes behind feature flag 'RichMessages' - Avatar URLs are not actually stored yet, as we do not implement METADATA yet. This is not yet used in Quassel itself, but third-party clients including QuasselDroid use this to provide more context in messages and allow for realname-based fallback avatar fetching to work in the chat message backlog. Incorporates suggestions from @mamarley. Closes GH-351. --- diff --git a/src/common/message.cpp b/src/common/message.cpp index 34990c64..061f16e5 100644 --- a/src/common/message.cpp +++ b/src/common/message.cpp @@ -26,24 +26,31 @@ #include -Message::Message(const BufferInfo &bufferInfo, Type type, const QString &contents, const QString &sender, const QString &senderPrefixes, Flags flags) +Message::Message(const BufferInfo &bufferInfo, Type type, const QString &contents, const QString &sender, + const QString &senderPrefixes, const QString &realName, const QString &avatarUrl, Flags flags) : _timestamp(QDateTime::currentDateTime().toUTC()), _bufferInfo(bufferInfo), _contents(contents), _sender(sender), _senderPrefixes(senderPrefixes), + _realName(realName), + _avatarUrl(avatarUrl), _type(type), _flags(flags) { } -Message::Message(const QDateTime &ts, const BufferInfo &bufferInfo, Type type, const QString &contents, const QString &sender, const QString &senderPrefixes, Flags flags) +Message::Message(const QDateTime &ts, const BufferInfo &bufferInfo, Type type, const QString &contents, + const QString &sender, const QString &senderPrefixes, const QString &realName, + const QString &avatarUrl, Flags flags) : _timestamp(ts), _bufferInfo(bufferInfo), _contents(contents), _sender(sender), _senderPrefixes(senderPrefixes), + _realName(realName), + _avatarUrl(avatarUrl), _type(type), _flags(flags) { @@ -72,6 +79,11 @@ QDataStream &operator<<(QDataStream &out, const Message &msg) if (SignalProxy::current()->targetPeer()->hasFeature(Quassel::Feature::SenderPrefixes)) out << msg.senderPrefixes().toUtf8(); + if (SignalProxy::current()->targetPeer()->hasFeature(Quassel::Feature::RichMessages)) { + out << msg.realName().toUtf8(); + out << msg.avatarUrl().toUtf8(); + } + out << msg.contents().toUtf8(); return out; } @@ -113,6 +125,15 @@ QDataStream &operator>>(QDataStream &in, Message &msg) in >> senderPrefixes; msg._senderPrefixes = QString::fromUtf8(senderPrefixes); + QByteArray realName; + QByteArray avatarUrl; + if (SignalProxy::current()->sourcePeer()->hasFeature(Quassel::Feature::RichMessages)) { + in >> realName; + in >> avatarUrl; + } + msg._realName = QString::fromUtf8(realName); + msg._avatarUrl = QString::fromUtf8(avatarUrl); + QByteArray contents; in >> contents; msg._contents = QString::fromUtf8(contents); @@ -126,7 +147,9 @@ QDebug operator<<(QDebug dbg, const Message &msg) dbg.nospace() << qPrintable(QString("Message(MsgId:")) << msg.msgId() << qPrintable(QString(",")) << msg.timestamp() << qPrintable(QString(", Type:")) << msg.type() + << qPrintable(QString(", RealName:")) << msg.realName() + << qPrintable(QString(", AvatarURL:")) << msg.avatarUrl() << qPrintable(QString(", Flags:")) << msg.flags() << qPrintable(QString(")")) - << msg.sender() << ":" << msg.contents(); + << msg.senderPrefixes() << msg.sender() << ":" << msg.contents(); return dbg; } diff --git a/src/common/message.h b/src/common/message.h index 79e25cf5..45a8286f 100644 --- a/src/common/message.h +++ b/src/common/message.h @@ -68,10 +68,11 @@ public: Q_DECLARE_FLAGS(Flags, Flag) Message(const BufferInfo &bufferInfo = BufferInfo(), Type type = Plain, const QString &contents = {}, - const QString &sender = {}, const QString &senderPrefixes = {}, Flags flags = None); + const QString &sender = {}, const QString &senderPrefixes = {}, const QString &realName = {}, + const QString &avatarUrl = {}, Flags flags = None); Message(const QDateTime &ts, const BufferInfo &buffer = BufferInfo(), Type type = Plain, const QString &contents = {}, const QString &sender = {}, const QString &senderPrefixes = {}, - Flags flags = None); + const QString &realName = {}, const QString &avatarUrl = {}, Flags flags = None); inline static Message ChangeOfDay(const QDateTime &day) { return Message(day, BufferInfo(), DayChange); } inline const MsgId &msgId() const { return _msgId; } @@ -83,6 +84,8 @@ public: inline const QString &contents() const { return _contents; } inline const QString &sender() const { return _sender; } inline const QString &senderPrefixes() const { return _senderPrefixes; } + inline const QString &realName() const { return _realName; } + inline const QString &avatarUrl() const { return _avatarUrl; } inline Type type() const { return _type; } inline Flags flags() const { return _flags; } inline void setFlags(Flags flags) { _flags = flags; } @@ -99,6 +102,8 @@ private: QString _contents; QString _sender; QString _senderPrefixes; + QString _realName; + QString _avatarUrl; Type _type; Flags _flags; diff --git a/src/common/quassel.h b/src/common/quassel.h index aa155e88..fd91f9a3 100644 --- a/src/common/quassel.h +++ b/src/common/quassel.h @@ -132,6 +132,7 @@ public: RemoteDisconnect, ///< Allow this peer to be remotely disconnected ExtendedFeatures, ///< Extended features LongMessageTime, ///< Serialize message time as 64-bit + RichMessages, ///< Real Name and Avatar URL in backlog #if QT_VERSION >= 0x050500 EcdsaCertfpKeys, ///< ECDSA keys for CertFP in identities #endif diff --git a/src/core/SQL/PostgreSQL/insert_sender.sql b/src/core/SQL/PostgreSQL/insert_sender.sql index f7d89ad2..bb385db2 100644 --- a/src/core/SQL/PostgreSQL/insert_sender.sql +++ b/src/core/SQL/PostgreSQL/insert_sender.sql @@ -1,3 +1,3 @@ -INSERT INTO sender (sender) -VALUES ($1) +INSERT INTO sender (sender, realname, avatarurl) +VALUES ($1, $2, $3) RETURNING senderid diff --git a/src/core/SQL/PostgreSQL/migrate_write_sender.sql b/src/core/SQL/PostgreSQL/migrate_write_sender.sql index bf953cd3..f1ac46bd 100644 --- a/src/core/SQL/PostgreSQL/migrate_write_sender.sql +++ b/src/core/SQL/PostgreSQL/migrate_write_sender.sql @@ -1,2 +1,2 @@ -INSERT INTO sender (senderid, sender) -VALUES (?, ?) +INSERT INTO sender (senderid, sender, realname, avatarurl) +VALUES (?, ?, ?, ?) diff --git a/src/core/SQL/PostgreSQL/select_messagesAll.sql b/src/core/SQL/PostgreSQL/select_messagesAll.sql index 0ee372ab..5109f680 100644 --- a/src/core/SQL/PostgreSQL/select_messagesAll.sql +++ b/src/core/SQL/PostgreSQL/select_messagesAll.sql @@ -1,4 +1,4 @@ -SELECT messageid, bufferid, time, type, flags, sender, senderprefixes, message +SELECT messageid, bufferid, time, type, flags, sender, senderprefixes, realname, avatarurl, message FROM backlog JOIN sender ON backlog.senderid = sender.senderid WHERE backlog.bufferid IN (SELECT bufferid FROM buffer WHERE userid = :userid) diff --git a/src/core/SQL/PostgreSQL/select_messagesAllNew.sql b/src/core/SQL/PostgreSQL/select_messagesAllNew.sql index 9f815452..827a94ec 100644 --- a/src/core/SQL/PostgreSQL/select_messagesAllNew.sql +++ b/src/core/SQL/PostgreSQL/select_messagesAllNew.sql @@ -1,4 +1,4 @@ -SELECT messageid, bufferid, time, type, flags, sender, senderprefixes, message +SELECT messageid, bufferid, time, type, flags, sender, senderprefixes, realname, avatarurl, message FROM backlog JOIN sender ON backlog.senderid = sender.senderid WHERE backlog.bufferid IN (SELECT bufferid FROM buffer WHERE userid = :userid) diff --git a/src/core/SQL/PostgreSQL/select_messagesNewerThan.sql b/src/core/SQL/PostgreSQL/select_messagesNewerThan.sql index 621fd0a4..7736daf2 100644 --- a/src/core/SQL/PostgreSQL/select_messagesNewerThan.sql +++ b/src/core/SQL/PostgreSQL/select_messagesNewerThan.sql @@ -1,4 +1,4 @@ -SELECT messageid, time, type, flags, sender, senderprefixes, message +SELECT messageid, time, type, flags, sender, senderprefixes, realname, avatarurl, message FROM backlog JOIN sender ON backlog.senderid = sender.senderid WHERE backlog.messageid >= $1 diff --git a/src/core/SQL/PostgreSQL/select_messagesNewestK.sql b/src/core/SQL/PostgreSQL/select_messagesNewestK.sql index e7059287..7faba9bf 100644 --- a/src/core/SQL/PostgreSQL/select_messagesNewestK.sql +++ b/src/core/SQL/PostgreSQL/select_messagesNewestK.sql @@ -1,4 +1,4 @@ -SELECT messageid, time, type, flags, sender, senderprefixes, message +SELECT messageid, time, type, flags, sender, senderprefixes, realname, avatarurl, message FROM backlog JOIN sender ON backlog.senderid = sender.senderid WHERE bufferid = $1 diff --git a/src/core/SQL/PostgreSQL/select_messagesRange.sql b/src/core/SQL/PostgreSQL/select_messagesRange.sql index a95c23c0..4b7de10c 100644 --- a/src/core/SQL/PostgreSQL/select_messagesRange.sql +++ b/src/core/SQL/PostgreSQL/select_messagesRange.sql @@ -1,4 +1,4 @@ -SELECT messageid, time, type, flags, sender, senderprefixes, message +SELECT messageid, time, type, flags, sender, senderprefixes, realname, avatarurl, message FROM backlog JOIN sender ON backlog.senderid = sender.senderid WHERE backlog.messageid >= $1 diff --git a/src/core/SQL/PostgreSQL/select_senderid.sql b/src/core/SQL/PostgreSQL/select_senderid.sql index b0b3ed3c..63b124c5 100644 --- a/src/core/SQL/PostgreSQL/select_senderid.sql +++ b/src/core/SQL/PostgreSQL/select_senderid.sql @@ -1,3 +1,3 @@ SELECT senderid FROM sender -WHERE sender = $1 +WHERE sender = $1 AND realname = $2 AND avatarurl = $3 diff --git a/src/core/SQL/PostgreSQL/setup_010_sender.sql b/src/core/SQL/PostgreSQL/setup_010_sender.sql index 0e9cdf1b..08542919 100644 --- a/src/core/SQL/PostgreSQL/setup_010_sender.sql +++ b/src/core/SQL/PostgreSQL/setup_010_sender.sql @@ -1,4 +1,6 @@ CREATE TABLE sender ( -- THE SENDER OF IRC MESSAGES senderid serial NOT NULL PRIMARY KEY, - sender varchar(128) UNIQUE NOT NULL -) + sender varchar(128) NOT NULL, + realname TEXT, + avatarurl TEXT +); diff --git a/src/core/SQL/PostgreSQL/setup_140_sender_idx.sql b/src/core/SQL/PostgreSQL/setup_140_sender_idx.sql new file mode 100644 index 00000000..3aa66a13 --- /dev/null +++ b/src/core/SQL/PostgreSQL/setup_140_sender_idx.sql @@ -0,0 +1 @@ +CREATE UNIQUE INDEX sender_sender_realname_avatarurl_uindex ON sender(sender, realname, avatarurl); diff --git a/src/core/SQL/PostgreSQL/version/27/upgrade_000_update_sender_add_realname.sql b/src/core/SQL/PostgreSQL/version/27/upgrade_000_update_sender_add_realname.sql new file mode 100644 index 00000000..c95ca274 --- /dev/null +++ b/src/core/SQL/PostgreSQL/version/27/upgrade_000_update_sender_add_realname.sql @@ -0,0 +1 @@ +ALTER TABLE sender ADD realname TEXT NULL; diff --git a/src/core/SQL/PostgreSQL/version/27/upgrade_010_update_sender_add_avatarurl.sql b/src/core/SQL/PostgreSQL/version/27/upgrade_010_update_sender_add_avatarurl.sql new file mode 100644 index 00000000..4fb6e435 --- /dev/null +++ b/src/core/SQL/PostgreSQL/version/27/upgrade_010_update_sender_add_avatarurl.sql @@ -0,0 +1 @@ +ALTER TABLE sender ADD avatarurl TEXT NULL; diff --git a/src/core/SQL/PostgreSQL/version/27/upgrade_020_update_sender_add_new_constraint.sql b/src/core/SQL/PostgreSQL/version/27/upgrade_020_update_sender_add_new_constraint.sql new file mode 100644 index 00000000..3aa66a13 --- /dev/null +++ b/src/core/SQL/PostgreSQL/version/27/upgrade_020_update_sender_add_new_constraint.sql @@ -0,0 +1 @@ +CREATE UNIQUE INDEX sender_sender_realname_avatarurl_uindex ON sender(sender, realname, avatarurl); diff --git a/src/core/SQL/PostgreSQL/version/27/upgrade_030_upgrade_sender_drop_old_constraint.sql b/src/core/SQL/PostgreSQL/version/27/upgrade_030_upgrade_sender_drop_old_constraint.sql new file mode 100644 index 00000000..0f63c9ee --- /dev/null +++ b/src/core/SQL/PostgreSQL/version/27/upgrade_030_upgrade_sender_drop_old_constraint.sql @@ -0,0 +1 @@ +ALTER TABLE sender DROP CONSTRAINT sender_sender_key; diff --git a/src/core/SQL/SQLite/insert_sender.sql b/src/core/SQL/SQLite/insert_sender.sql index 0e84f63c..63633c44 100644 --- a/src/core/SQL/SQLite/insert_sender.sql +++ b/src/core/SQL/SQLite/insert_sender.sql @@ -1,2 +1,2 @@ -INSERT INTO sender (sender) -VALUES (:sender) \ No newline at end of file +INSERT INTO sender (sender, realname, avatarurl) +VALUES (:sender, :realname, :avatarurl) diff --git a/src/core/SQL/SQLite/migrate_read_sender.sql b/src/core/SQL/SQLite/migrate_read_sender.sql index 9cd5ce12..53f03816 100644 --- a/src/core/SQL/SQLite/migrate_read_sender.sql +++ b/src/core/SQL/SQLite/migrate_read_sender.sql @@ -1,5 +1,4 @@ -SELECT senderid, sender +SELECT senderid, sender, realname, avatarurl FROM sender WHERE senderid > ? AND senderid <= ? ORDER BY senderid ASC - diff --git a/src/core/SQL/SQLite/select_messagesAll.sql b/src/core/SQL/SQLite/select_messagesAll.sql index 2fb1cdb7..60957d51 100644 --- a/src/core/SQL/SQLite/select_messagesAll.sql +++ b/src/core/SQL/SQLite/select_messagesAll.sql @@ -1,4 +1,4 @@ -SELECT messageid, bufferid, time, type, flags, sender, senderprefixes, message +SELECT messageid, bufferid, time, type, flags, sender, senderprefixes, realname, avatarurl, message FROM backlog JOIN sender ON backlog.senderid = sender.senderid WHERE backlog.bufferid IN (SELECT bufferid FROM buffer WHERE userid = :userid) diff --git a/src/core/SQL/SQLite/select_messagesAllNew.sql b/src/core/SQL/SQLite/select_messagesAllNew.sql index f6a54718..098b4fea 100644 --- a/src/core/SQL/SQLite/select_messagesAllNew.sql +++ b/src/core/SQL/SQLite/select_messagesAllNew.sql @@ -1,4 +1,4 @@ -SELECT messageid, bufferid, time, type, flags, sender, senderprefixes, message +SELECT messageid, bufferid, time, type, flags, sender, senderprefixes, realname, avatarurl, message FROM backlog JOIN sender ON backlog.senderid = sender.senderid WHERE backlog.bufferid IN (SELECT bufferid FROM buffer WHERE userid = :userid) diff --git a/src/core/SQL/SQLite/select_messagesNewerThan.sql b/src/core/SQL/SQLite/select_messagesNewerThan.sql index 8129c445..5040b9e2 100644 --- a/src/core/SQL/SQLite/select_messagesNewerThan.sql +++ b/src/core/SQL/SQLite/select_messagesNewerThan.sql @@ -1,4 +1,4 @@ -SELECT messageid, time, type, flags, sender, senderprefixes, message +SELECT messageid, time, type, flags, sender, senderprefixes, realname, avatarurl, message FROM backlog JOIN sender ON backlog.senderid = sender.senderid WHERE backlog.messageid >= :firstmsg diff --git a/src/core/SQL/SQLite/select_messagesNewestK.sql b/src/core/SQL/SQLite/select_messagesNewestK.sql index 18105db4..eb4af1f2 100644 --- a/src/core/SQL/SQLite/select_messagesNewestK.sql +++ b/src/core/SQL/SQLite/select_messagesNewestK.sql @@ -1,4 +1,4 @@ -SELECT messageid, time, type, flags, sender, senderprefixes, message +SELECT messageid, time, type, flags, sender, senderprefixes, realname, avatarurl, message FROM backlog JOIN sender ON backlog.senderid = sender.senderid WHERE bufferid = :bufferid diff --git a/src/core/SQL/SQLite/select_messagesRange.sql b/src/core/SQL/SQLite/select_messagesRange.sql index dc6e6179..f78cf8d3 100644 --- a/src/core/SQL/SQLite/select_messagesRange.sql +++ b/src/core/SQL/SQLite/select_messagesRange.sql @@ -1,4 +1,4 @@ -SELECT messageid, time, type, flags, sender, senderprefixes, message +SELECT messageid, time, type, flags, sender, senderprefixes, realname, avatarurl, message FROM backlog JOIN sender ON backlog.senderid = sender.senderid WHERE bufferid = :bufferid diff --git a/src/core/SQL/SQLite/setup_010_sender.sql b/src/core/SQL/SQLite/setup_010_sender.sql index 4e7251e7..c35041d5 100644 --- a/src/core/SQL/SQLite/setup_010_sender.sql +++ b/src/core/SQL/SQLite/setup_010_sender.sql @@ -1,6 +1,6 @@ CREATE TABLE sender ( -- THE SENDER OF IRC MESSAGES senderid INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, - sender TEXT UNIQUE NOT NULL -) - - + sender TEXT NOT NULL, + realname TEXT, + avatarurl TEXT +); diff --git a/src/core/SQL/SQLite/setup_150_sender_idx.sql b/src/core/SQL/SQLite/setup_150_sender_idx.sql new file mode 100644 index 00000000..fec1fec9 --- /dev/null +++ b/src/core/SQL/SQLite/setup_150_sender_idx.sql @@ -0,0 +1 @@ +CREATE UNIQUE INDEX sender_index ON sender(sender, realname, avatarurl); diff --git a/src/core/SQL/SQLite/version/29/upgrade_000_create_sender_tmp.sql b/src/core/SQL/SQLite/version/29/upgrade_000_create_sender_tmp.sql new file mode 100644 index 00000000..25c1df2a --- /dev/null +++ b/src/core/SQL/SQLite/version/29/upgrade_000_create_sender_tmp.sql @@ -0,0 +1 @@ +CREATE TABLE sender_tmp (senderid INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, sender TEXT NOT NULL, realname TEXT, avatarurl TEXT); diff --git a/src/core/SQL/SQLite/version/29/upgrade_010_copy_sender_sender_tmp.sql b/src/core/SQL/SQLite/version/29/upgrade_010_copy_sender_sender_tmp.sql new file mode 100644 index 00000000..5400092c --- /dev/null +++ b/src/core/SQL/SQLite/version/29/upgrade_010_copy_sender_sender_tmp.sql @@ -0,0 +1 @@ +INSERT INTO sender_tmp SELECT senderid, sender, NULL as realname, NULL as avatarurl FROM sender; diff --git a/src/core/SQL/SQLite/version/29/upgrade_020_drop_sender.sql b/src/core/SQL/SQLite/version/29/upgrade_020_drop_sender.sql new file mode 100644 index 00000000..7e893013 --- /dev/null +++ b/src/core/SQL/SQLite/version/29/upgrade_020_drop_sender.sql @@ -0,0 +1 @@ +DROP TABLE sender; diff --git a/src/core/SQL/SQLite/version/29/upgrade_030_rename_sender_tmp_sender.sql b/src/core/SQL/SQLite/version/29/upgrade_030_rename_sender_tmp_sender.sql new file mode 100644 index 00000000..e03b21ec --- /dev/null +++ b/src/core/SQL/SQLite/version/29/upgrade_030_rename_sender_tmp_sender.sql @@ -0,0 +1 @@ +ALTER TABLE sender_tmp RENAME TO sender; diff --git a/src/core/SQL/SQLite/version/29/upgrade_040_update_sender_add_realname_avatarurl.sql b/src/core/SQL/SQLite/version/29/upgrade_040_update_sender_add_realname_avatarurl.sql new file mode 100644 index 00000000..fec1fec9 --- /dev/null +++ b/src/core/SQL/SQLite/version/29/upgrade_040_update_sender_add_realname_avatarurl.sql @@ -0,0 +1 @@ +CREATE UNIQUE INDEX sender_index ON sender(sender, realname, avatarurl); diff --git a/src/core/abstractsqlstorage.cpp b/src/core/abstractsqlstorage.cpp index 947c1bae..4ecf623b 100644 --- a/src/core/abstractsqlstorage.cpp +++ b/src/core/abstractsqlstorage.cpp @@ -584,3 +584,13 @@ bool AbstractSqlMigrationReader::transferMo(MigrationObject moType, T &mo) qDebug() << "Done."; return true; } + +uint qHash(const SenderData &key) { + return qHash(QString(key.sender + "\n" + key.realname + "\n" + key.avatarurl)); +} + +bool operator==(const SenderData &a, const SenderData &b) { + return a.sender == b.sender && + a.realname == b.realname && + a.avatarurl == b.avatarurl; +} diff --git a/src/core/abstractsqlstorage.h b/src/core/abstractsqlstorage.h index 2a59fbfa..2e572307 100644 --- a/src/core/abstractsqlstorage.h +++ b/src/core/abstractsqlstorage.h @@ -118,6 +118,14 @@ private: QHash _connectionPool; }; +struct SenderData { + QString sender; + QString realname; + QString avatarurl; + + friend uint qHash(const SenderData &key); + friend bool operator==(const SenderData &a, const SenderData &b); +}; // ======================================== // AbstractSqlStorage::Connection @@ -155,6 +163,8 @@ public: struct SenderMO { int senderId; QString sender; + QString realname; + QString avatarurl; SenderMO() : senderId(0) {} }; diff --git a/src/core/coresession.cpp b/src/core/coresession.cpp index 249690c4..df9061d3 100644 --- a/src/core/coresession.cpp +++ b/src/core/coresession.cpp @@ -385,8 +385,9 @@ void CoreSession::processMessages() Q_ASSERT(!createBuffer); bufferInfo = Core::bufferInfo(user(), rawMsg.networkId, BufferInfo::StatusBuffer, ""); } - Message msg(bufferInfo, rawMsg.type, rawMsg.text, rawMsg.sender, - senderPrefixes(rawMsg.sender, bufferInfo), rawMsg.flags); + Message msg(bufferInfo, rawMsg.type, rawMsg.text, rawMsg.sender, senderPrefixes(rawMsg.sender, bufferInfo), + realName(rawMsg.sender, rawMsg.networkId), avatarUrl(rawMsg.sender, rawMsg.networkId), + rawMsg.flags); if(Core::storeMessage(msg)) emit displayMsg(msg); } @@ -410,8 +411,9 @@ void CoreSession::processMessages() } bufferInfoCache[rawMsg.networkId][rawMsg.target] = bufferInfo; } - Message msg(bufferInfo, rawMsg.type, rawMsg.text, rawMsg.sender, - senderPrefixes(rawMsg.sender, bufferInfo), rawMsg.flags); + Message msg(bufferInfo, rawMsg.type, rawMsg.text, rawMsg.sender, senderPrefixes(rawMsg.sender, bufferInfo), + realName(rawMsg.sender, rawMsg.networkId), avatarUrl(rawMsg.sender, rawMsg.networkId), + rawMsg.flags); messages << msg; } @@ -427,8 +429,9 @@ void CoreSession::processMessages() // add the StatusBuffer to the Cache in case there are more Messages for the original target bufferInfoCache[rawMsg.networkId][rawMsg.target] = bufferInfo; } - Message msg(bufferInfo, rawMsg.type, rawMsg.text, rawMsg.sender, - senderPrefixes(rawMsg.sender, bufferInfo), rawMsg.flags); + Message msg(bufferInfo, rawMsg.type, rawMsg.text, rawMsg.sender, senderPrefixes(rawMsg.sender, bufferInfo), + realName(rawMsg.sender, rawMsg.networkId), avatarUrl(rawMsg.sender, rawMsg.networkId), + rawMsg.flags); messages << msg; } @@ -463,6 +466,33 @@ QString CoreSession::senderPrefixes(const QString &sender, const BufferInfo &buf return currentNetwork->modesToPrefixes(modes); } +QString CoreSession::realName(const QString &sender, NetworkId networkId) const +{ + CoreNetwork *currentNetwork = network(networkId); + if (!currentNetwork) { + return {}; + } + + IrcUser *currentUser = currentNetwork->ircUser(nickFromMask(sender)); + if (!currentUser) { + return {}; + } + + return currentUser->realName(); +} + +QString CoreSession::avatarUrl(const QString &sender, NetworkId networkId) const +{ + Q_UNUSED(sender); + Q_UNUSED(networkId); + // Currently we do not have a way to retrieve this value yet. + // + // This likely will require implementing IRCv3's METADATA spec. + // See https://ircv3.net/irc/ + // And https://blog.irccloud.com/avatars/ + return ""; +} + Protocol::SessionState CoreSession::sessionState() const { QVariantList bufferInfos; diff --git a/src/core/coresession.h b/src/core/coresession.h index 9967f802..72843a5f 100644 --- a/src/core/coresession.h +++ b/src/core/coresession.h @@ -241,6 +241,20 @@ private: * @param bufferInfo The BufferInfo object of the buffer */ QString senderPrefixes(const QString &sender, const BufferInfo &bufferInfo) const; + + /** + * This method obtains the realname of the message's sender. + * @param sender The hostmask of the sender + * @param networkId The network the user is on + */ + QString realName(const QString &sender, NetworkId networkId) const; + + /** + * This method obtains the avatar of the message's sender. + * @param sender The hostmask of the sender + * @param networkId The network the user is on + */ + QString avatarUrl(const QString &sender, NetworkId networkId) const; QList _messageQueue; bool _processMessages; CoreIgnoreListManager _ignoreListManager; diff --git a/src/core/postgresqlstorage.cpp b/src/core/postgresqlstorage.cpp index 73771499..3c15b2c0 100644 --- a/src/core/postgresqlstorage.cpp +++ b/src/core/postgresqlstorage.cpp @@ -1542,7 +1542,11 @@ bool PostgreSqlStorage::logMessage(Message &msg) return false; } - QSqlQuery getSenderIdQuery = executePreparedQuery("select_senderid", msg.sender(), db); + QVariantList senderParams; + senderParams << msg.sender() + << msg.realName() + << msg.avatarUrl(); + QSqlQuery getSenderIdQuery = executePreparedQuery("select_senderid", senderParams, db); int senderId; if (getSenderIdQuery.first()) { senderId = getSenderIdQuery.value(0).toInt(); @@ -1551,11 +1555,11 @@ bool PostgreSqlStorage::logMessage(Message &msg) // it's possible that the sender was already added by another thread // since the insert might fail we're setting a savepoint savePoint("sender_sp1", db); - QSqlQuery addSenderQuery = executePreparedQuery("insert_sender", msg.sender(), db); + QSqlQuery addSenderQuery = executePreparedQuery("insert_sender", senderParams, db); if (addSenderQuery.lastError().isValid()) { rollbackSavePoint("sender_sp1", db); - getSenderIdQuery = executePreparedQuery("select_senderid", msg.sender(), db); + getSenderIdQuery = executePreparedQuery("select_senderid", senderParams, db); watchQuery(getSenderIdQuery); getSenderIdQuery.first(); senderId = getSenderIdQuery.value(0).toInt(); @@ -1605,28 +1609,34 @@ bool PostgreSqlStorage::logMessages(MessageList &msgs) } QList senderIdList; - QHash senderIds; + QHash senderIds; QSqlQuery addSenderQuery; QSqlQuery selectSenderQuery;; for (int i = 0; i < msgs.count(); i++) { - const QString &sender = msgs.at(i).sender(); + auto &msg = msgs.at(i); + SenderData sender = { msg.sender(), msg.realName(), msg.avatarUrl() }; if (senderIds.contains(sender)) { senderIdList << senderIds[sender]; continue; } - selectSenderQuery = executePreparedQuery("select_senderid", sender, db); + QVariantList senderParams; + senderParams << sender.sender + << sender.realname + << sender.avatarurl; + + selectSenderQuery = executePreparedQuery("select_senderid", senderParams, db); if (selectSenderQuery.first()) { senderIdList << selectSenderQuery.value(0).toInt(); senderIds[sender] = selectSenderQuery.value(0).toInt(); } else { savePoint("sender_sp", db); - addSenderQuery = executePreparedQuery("insert_sender", sender, db); + addSenderQuery = executePreparedQuery("insert_sender", senderParams, db); if (addSenderQuery.lastError().isValid()) { // seems it was inserted meanwhile... by a different thread rollbackSavePoint("sender_sp", db); - selectSenderQuery = executePreparedQuery("select_senderid", sender, db); + selectSenderQuery = executePreparedQuery("select_senderid", senderParams, db); watchQuery(selectSenderQuery); selectSenderQuery.first(); senderIdList << selectSenderQuery.value(0).toInt(); @@ -1730,9 +1740,11 @@ QList PostgreSqlStorage::requestMsgs(UserId user, BufferId bufferId, Ms Message msg(timestamp, bufferInfo, (Message::Type)query.value(2).toUInt(), - query.value(6).toString(), + query.value(8).toString(), query.value(4).toString(), query.value(5).toString(), + query.value(6).toString(), + query.value(7).toString(), (Message::Flags)query.value(3).toUInt()); msg.setMsgId(query.value(0).toInt()); messagelist << msg; @@ -1783,9 +1795,11 @@ QList PostgreSqlStorage::requestAllMsgs(UserId user, MsgId first, MsgId Message msg(timestamp, bufferInfoHash[query.value(1).toInt()], (Message::Type)query.value(3).toUInt(), - query.value(7).toString(), + query.value(9).toString(), query.value(5).toString(), query.value(6).toString(), + query.value(7).toString(), + query.value(8).toString(), (Message::Flags)query.value(4).toUInt()); msg.setMsgId(query.value(0).toInt()); messagelist << msg; @@ -2060,6 +2074,8 @@ bool PostgreSqlMigrationWriter::writeMo(const SenderMO &sender) { bindValue(0, sender.senderId); bindValue(1, sender.sender); + bindValue(2, sender.realname); + bindValue(3, sender.avatarurl); return exec(); } diff --git a/src/core/sql.qrc b/src/core/sql.qrc index b8fc95e8..96de7f6b 100644 --- a/src/core/sql.qrc +++ b/src/core/sql.qrc @@ -81,6 +81,7 @@ ./SQL/PostgreSQL/setup_110_alter_sender_seq.sql ./SQL/PostgreSQL/setup_120_alter_messageid_seq.sql ./SQL/PostgreSQL/setup_130_function_lastmsgid.sql + ./SQL/PostgreSQL/setup_140_sender_idx.sql ./SQL/PostgreSQL/update_backlog_bufferid.sql ./SQL/PostgreSQL/update_buffer_bufferactivity.sql ./SQL/PostgreSQL/update_buffer_cipher.sql @@ -118,6 +119,10 @@ ./SQL/PostgreSQL/version/24/upgrade_000_alter_buffer_add_bufferactivity.sql ./SQL/PostgreSQL/version/25/upgrade_000_alter_buffer_add_cipher.sql ./SQL/PostgreSQL/version/26/upgrade_000_alter_buffer_add_highlightcount.sql + ./SQL/PostgreSQL/version/27/upgrade_000_update_sender_add_realname.sql + ./SQL/PostgreSQL/version/27/upgrade_010_update_sender_add_avatarurl.sql + ./SQL/PostgreSQL/version/27/upgrade_020_update_sender_add_new_constraint.sql + ./SQL/PostgreSQL/version/27/upgrade_030_upgrade_sender_drop_old_constraint.sql ./SQL/SQLite/delete_backlog_by_uid.sql ./SQL/SQLite/delete_backlog_for_buffer.sql ./SQL/SQLite/delete_backlog_for_network.sql @@ -201,6 +206,7 @@ ./SQL/SQLite/setup_120_user_setting.sql ./SQL/SQLite/setup_130_identity.sql ./SQL/SQLite/setup_140_identity_nick.sql + ./SQL/SQLite/setup_150_sender_idx.sql ./SQL/SQLite/update_backlog_bufferid.sql ./SQL/SQLite/update_buffer_bufferactivity.sql ./SQL/SQLite/update_buffer_cipher.sql @@ -311,5 +317,10 @@ ./SQL/SQLite/version/26/upgrade_000_create_buffer_idx.sql ./SQL/SQLite/version/27/upgrade_000_alter_buffer_add_cipher.sql ./SQL/SQLite/version/28/upgrade_000_alter_buffer_add_highlightcount.sql + ./SQL/SQLite/version/29/upgrade_000_create_sender_tmp.sql + ./SQL/SQLite/version/29/upgrade_010_copy_sender_sender_tmp.sql + ./SQL/SQLite/version/29/upgrade_020_drop_sender.sql + ./SQL/SQLite/version/29/upgrade_030_rename_sender_tmp_sender.sql + ./SQL/SQLite/version/29/upgrade_040_update_sender_add_realname_avatarurl.sql diff --git a/src/core/sqlitestorage.cpp b/src/core/sqlitestorage.cpp index d71dd3c1..76666796 100644 --- a/src/core/sqlitestorage.cpp +++ b/src/core/sqlitestorage.cpp @@ -1720,6 +1720,8 @@ bool SqliteStorage::logMessage(Message &msg) QSqlQuery addSenderQuery(db); addSenderQuery.prepare(queryString("insert_sender")); addSenderQuery.bindValue(":sender", msg.sender()); + addSenderQuery.bindValue(":realname", msg.realName()); + addSenderQuery.bindValue(":avatarurl", msg.avatarUrl()); safeExec(addSenderQuery); safeExec(logMessageQuery); error = !watchQuery(logMessageQuery); @@ -1757,17 +1759,20 @@ bool SqliteStorage::logMessages(MessageList &msgs) db.transaction(); { - QSet senders; + QSet senders; QSqlQuery addSenderQuery(db); addSenderQuery.prepare(queryString("insert_sender")); lockForWrite(); for (int i = 0; i < msgs.count(); i++) { - const QString &sender = msgs.at(i).sender(); + auto &msg = msgs.at(i); + SenderData sender = { msg.sender(), msg.realName(), msg.avatarUrl() }; if (senders.contains(sender)) continue; senders << sender; - addSenderQuery.bindValue(":sender", sender); + addSenderQuery.bindValue(":sender", sender.sender); + addSenderQuery.bindValue(":realname", sender.realname); + addSenderQuery.bindValue(":avatarurl", sender.avatarurl); safeExec(addSenderQuery); } } @@ -1869,9 +1874,11 @@ QList SqliteStorage::requestMsgs(UserId user, BufferId bufferId, MsgId Message msg(QDateTime::fromTime_t(query.value(1).toInt()), bufferInfo, (Message::Type)query.value(2).toUInt(), - query.value(6).toString(), + query.value(8).toString(), query.value(4).toString(), query.value(5).toString(), + query.value(6).toString(), + query.value(7).toString(), (Message::Flags)query.value(3).toUInt()); msg.setMsgId(query.value(0).toInt()); messagelist << msg; @@ -1924,9 +1931,11 @@ QList SqliteStorage::requestAllMsgs(UserId user, MsgId first, MsgId las Message msg(QDateTime::fromTime_t(query.value(2).toInt()), bufferInfoHash[query.value(1).toInt()], (Message::Type)query.value(3).toUInt(), - query.value(7).toString(), + query.value(9).toString(), query.value(5).toString(), query.value(6).toString(), + query.value(7).toString(), + query.value(8).toString(), (Message::Flags)query.value(4).toUInt()); msg.setMsgId(query.value(0).toInt()); messagelist << msg; @@ -2215,6 +2224,8 @@ bool SqliteMigrationReader::readMo(SenderMO &sender) sender.senderId = value(0).toInt(); sender.sender = value(1).toString(); + sender.realname = value(2).toString(); + sender.avatarurl = value(3).toString(); return true; }