Skip to content

Commit a2a4ae9

Browse files
committed
feat: support notify_file_id push notifications
For this to work we also now need to store the fileId from the sync root folder, otherwise we would never know about new files inside the configured sync root Signed-off-by: Jyrki Gadinger <[email protected]>
1 parent 4ce03af commit a2a4ae9

16 files changed

+175
-6
lines changed

src/common/syncjournaldb.cpp

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1703,6 +1703,40 @@ bool SyncJournalDb::updateLocalMetadata(const QString &filename,
17031703
return true;
17041704
}
17051705

1706+
bool SyncJournalDb::hasFileIds(const QList<qint64> &fileIds)
1707+
{
1708+
QMutexLocker locker(&_mutex);
1709+
1710+
if (!checkConnect()) {
1711+
return false;
1712+
}
1713+
1714+
QStringList fileIdStrings = {};
1715+
for (const auto &fileId : fileIds) {
1716+
fileIdStrings.append(QString::number(fileId));
1717+
}
1718+
1719+
// quick workaround for looking up pure numeric file IDs: simply `round()` that field!
1720+
// this will return the file ID as e.g. 12345.0, but that's still good enough to use it
1721+
// with the IN operator -- e.g. (12345, 1337, 29001)
1722+
SqlQuery query(
1723+
QLatin1String{"SELECT 1 FROM metadata WHERE ROUND(fileid) IN (%1) LIMIT 1;"}
1724+
.arg(fileIdStrings.join(QLatin1String{", "})).toLocal8Bit(),
1725+
_db
1726+
);
1727+
1728+
if (!query.exec()) {
1729+
qCWarning(lcDb) << "file id query failed:" << query.error();
1730+
return false;
1731+
}
1732+
1733+
if (query.next().hasData && query.intValue(0) == 1) {
1734+
return true;
1735+
}
1736+
1737+
return false;
1738+
}
1739+
17061740
Optional<SyncJournalDb::HasHydratedDehydrated> SyncJournalDb::hasHydratedOrDehydratedFiles(const QByteArray &filename)
17071741
{
17081742
QMutexLocker locker(&_mutex);

src/common/syncjournaldb.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,8 @@ class OCSYNC_EXPORT SyncJournalDb : public QObject
7474
[[nodiscard]] bool updateLocalMetadata(const QString &filename,
7575
qint64 modtime, qint64 size, quint64 inode, const SyncJournalFileLockInfo &lockInfo);
7676

77+
[[nodiscard]] bool hasFileIds(const QList<qint64> &fileIds);
78+
7779
/// Return value for hasHydratedOrDehydratedFiles()
7880
struct HasHydratedDehydrated
7981
{

src/gui/folder.cpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,7 @@ Folder::Folder(const FolderDefinition &definition,
9292

9393
connect(_accountState.data(), &AccountState::isConnectedChanged, this, &Folder::canSyncChanged);
9494
connect(_engine.data(), &SyncEngine::rootEtag, this, &Folder::etagRetrievedFromSyncEngine);
95+
connect(_engine.data(), &SyncEngine::rootFileIdReceived, this, &Folder::rootFileIdReceivedFromSyncEngine);
9596

9697
connect(_engine.data(), &SyncEngine::started, this, &Folder::slotSyncStarted, Qt::QueuedConnection);
9798
connect(_engine.data(), &SyncEngine::finished, this, &Folder::slotSyncFinished, Qt::QueuedConnection);
@@ -387,6 +388,11 @@ void Folder::etagRetrievedFromSyncEngine(const QByteArray &etag, const QDateTime
387388
_lastEtag = etag;
388389
}
389390

391+
void Folder::rootFileIdReceivedFromSyncEngine(const qint64 fileId)
392+
{
393+
qCDebug(lcFolder).nospace() << "retrieved root fileId=" << fileId;
394+
_rootFileId = fileId;
395+
}
390396

391397
void Folder::showSyncResultPopup()
392398
{
@@ -996,6 +1002,11 @@ void Folder::migrateBlackListPath(const QString &legacyPath)
9961002
}
9971003
}
9981004

1005+
bool Folder::hasFileIds(const QList<qint64>& fileIds) const
1006+
{
1007+
return fileIds.contains(_rootFileId) || journalDb()->hasFileIds(fileIds);
1008+
}
1009+
9991010
QString Folder::filePath(const QString& fileName)
10001011
{
10011012
const auto folderDir = QDir(_canonicalLocalPath);

src/gui/folder.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -309,6 +309,9 @@ class Folder : public QObject
309309
void blacklistPath(const QString &path);
310310
void migrateBlackListPath(const QString &legacyPath);
311311

312+
/// whether the current folder contains any of the passed fileIds
313+
[[nodiscard]] bool hasFileIds(const QList<qint64>& fileIds) const;
314+
312315
signals:
313316
void syncStateChange();
314317
void syncStarted();
@@ -422,6 +425,8 @@ private slots:
422425
void etagRetrieved(const QByteArray &, const QDateTime &tp);
423426
void etagRetrievedFromSyncEngine(const QByteArray &, const QDateTime &time);
424427

428+
void rootFileIdReceivedFromSyncEngine(const qint64 fileId);
429+
425430
void slotEmitFinishedDelayed();
426431

427432
void slotNewBigFolderDiscovered(const QString &, bool isExternal);
@@ -578,6 +583,9 @@ private slots:
578583
QMetaObject::Connection _officeFileLockReleaseUnlockFailure;
579584
QMetaObject::Connection _fileLockSuccess;
580585
QMetaObject::Connection _fileLockFailure;
586+
587+
/// The remote file ID of the current folder.
588+
qint64 _rootFileId = 0;
581589
};
582590
}
583591

src/gui/folderman.cpp

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2079,15 +2079,35 @@ void FolderMan::slotSetupPushNotifications(const Folder::Map &folderMap)
20792079

20802080
void FolderMan::slotProcessFilesPushNotification(Account *account)
20812081
{
2082-
qCInfo(lcFolderMan) << "Got files push notification for account" << account;
2082+
qCDebug(lcFolderMan) << "received notify_file push notification account=" << account->displayName();
20832083

20842084
for (auto folder : std::as_const(_folderMap)) {
20852085
// Just run on the folders that belong to this account
20862086
if (folder->accountState()->account() != account) {
20872087
continue;
20882088
}
20892089

2090-
qCInfo(lcFolderMan) << "Schedule folder" << folder << "for sync";
2090+
qCInfo(lcFolderMan).nospace() << "scheduling sync account=" << account->displayName() << " folder=" << folder->alias() << " reason=notify_file";
2091+
scheduleFolder(folder);
2092+
}
2093+
}
2094+
2095+
void FolderMan::slotProcessFileIdsPushNotification(Account *account, const QList<qint64> &fileIds)
2096+
{
2097+
qCDebug(lcFolderMan).nospace() << "received notify_file_id push notification account=" << account->displayName() << " fileIds=" << fileIds;
2098+
2099+
for (auto folder : std::as_const(_folderMap)) {
2100+
// Just run on the folders that belong to this account
2101+
if (folder->accountState()->account() != account) {
2102+
continue;
2103+
}
2104+
2105+
if (!folder->hasFileIds(fileIds)) {
2106+
qCDebug(lcFolderMan).nospace() << "no matching file ids, ignoring account=" << account->displayName() << " folder=" << folder->alias();
2107+
continue;
2108+
}
2109+
2110+
qCInfo(lcFolderMan).nospace() << "scheduling sync account=" << account->displayName() << " folder=" << folder->alias() << " reason=notify_file_id";
20912111
scheduleFolder(folder);
20922112
}
20932113
}
@@ -2099,6 +2119,7 @@ void FolderMan::slotConnectToPushNotifications(const AccountPtr &account)
20992119
if (pushNotificationsFilesReady(account)) {
21002120
qCInfo(lcFolderMan) << "Push notifications ready";
21012121
connect(pushNotifications, &PushNotifications::filesChanged, this, &FolderMan::slotProcessFilesPushNotification, Qt::UniqueConnection);
2122+
connect(pushNotifications, &PushNotifications::fileIdsChanged, this, &FolderMan::slotProcessFileIdsPushNotification, Qt::UniqueConnection);
21022123
}
21032124
}
21042125

src/gui/folderman.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -329,6 +329,7 @@ private slots:
329329

330330
void slotSetupPushNotifications(const OCC::Folder::Map &);
331331
void slotProcessFilesPushNotification(OCC::Account *account);
332+
void slotProcessFileIdsPushNotification(OCC::Account *account, const QList<qint64> &fileIds);
332333
void slotConnectToPushNotifications(const OCC::AccountPtr &account);
333334

334335
void slotLeaveShare(const QString &localFile, const QByteArray &folderToken = {});

src/libsync/discovery.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2235,6 +2235,7 @@ DiscoverySingleDirectoryJob *ProcessDirectoryJob::startAsyncServerQuery()
22352235
}
22362236

22372237
connect(serverJob, &DiscoverySingleDirectoryJob::etag, this, &ProcessDirectoryJob::etag);
2238+
connect(serverJob, &DiscoverySingleDirectoryJob::rootFileIdReceived, this, &ProcessDirectoryJob::rootFileIdReceived);
22382239
connect(serverJob, &DiscoverySingleDirectoryJob::setfolderQuota, this, &ProcessDirectoryJob::setFolderQuota);
22392240
_discoveryData->_currentlyActiveJobs++;
22402241
_pendingAsyncJobs++;

src/libsync/discovery.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -305,6 +305,7 @@ class ProcessDirectoryJob : public QObject
305305
void finished();
306306
// The root etag of this directory was fetched
307307
void etag(const QByteArray &, const QDateTime &time);
308+
void rootFileIdReceived(const qint64 fileId);
308309

309310
private slots:
310311
void setFolderQuota(const FolderQuota &folderQuota);

src/libsync/discoveryphase.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -613,8 +613,17 @@ void DiscoverySingleDirectoryJob::directoryListingIteratedSlot(const QString &fi
613613
_localFileId = map.value(QStringLiteral("fileid")).toUtf8();
614614
}
615615
if (map.contains("id")) {
616+
// this is from the "oc:id" property, the format is e.g. "00000002oc123xyz987e"
616617
_fileId = map.value("id").toUtf8();
617618
}
619+
if (map.contains("fileid")) {
620+
// this is from the "oc:fileid" property, this is the plain ID without any special format (e.g. "2")
621+
bool ok = false;
622+
if (qint64 numericFileId = map.value("fileid").toLongLong(&ok); ok) {
623+
qCDebug(lcDiscovery).nospace() << "received numericFileId=" << numericFileId;
624+
emit rootFileIdReceived(numericFileId);
625+
}
626+
}
618627
if (map.contains("is-encrypted") && map.value("is-encrypted") == QStringLiteral("1")) {
619628
_encryptionStatusCurrent = SyncFileItem::EncryptionStatus::EncryptedMigratedV2_0;
620629
Q_ASSERT(!_fileId.isEmpty());

src/libsync/discoveryphase.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -186,6 +186,7 @@ class DiscoverySingleDirectoryJob : public QObject
186186
void etag(const QByteArray &, const QDateTime &time);
187187
void finished(const OCC::HttpResult<QVector<OCC::RemoteInfo>> &result);
188188
void setfolderQuota(const FolderQuota &folderQuota);
189+
void rootFileIdReceived(const qint64 fileId);
189190

190191
private slots:
191192
void directoryListingIteratedSlot(const QString &, const QMap<QString, QString> &);

0 commit comments

Comments
 (0)