diff --git a/src/gui/socketapi.cpp b/src/gui/socketapi.cpp index 2e78cdb017..47ecb8509c 100644 --- a/src/gui/socketapi.cpp +++ b/src/gui/socketapi.cpp @@ -56,6 +56,13 @@ // The second number should be changed when there are new features. #define MIRALL_SOCKET_API_VERSION "1.0" +static inline QString removeTrailingSlash(QString path) +{ + Q_ASSERT(path.endsWith(QLatin1Char('/'))); + path.truncate(path.length()-1); + return path; +} + namespace OCC { #define DEBUG qDebug() << "SocketApi: " @@ -142,7 +149,7 @@ void SocketApi::slotNewConnection() foreach( Folder *f, FolderMan::instance()->map() ) { if (f->canSync()) { - QString message = buildRegisterPathMessage(f->path()); + QString message = buildRegisterPathMessage(removeTrailingSlash(f->path())); sendMessage(socket, message); } } @@ -189,7 +196,7 @@ void SocketApi::slotRegisterPath( const QString& alias ) Folder *f = FolderMan::instance()->folder(alias); if (f) { - QString message = buildRegisterPathMessage(f->path()); + QString message = buildRegisterPathMessage(removeTrailingSlash(f->path())); foreach(QIODevice *socket, _listeners) { sendMessage(socket, message); } @@ -205,7 +212,7 @@ void SocketApi::slotUnregisterPath( const QString& alias ) Folder *f = FolderMan::instance()->folder(alias); if (f) - broadcastMessage(QLatin1String("UNREGISTER_PATH"), f->path(), QString::null, true ); + broadcastMessage(QLatin1String("UNREGISTER_PATH"), removeTrailingSlash(f->path()), QString::null, true ); _registeredAliases.remove(alias); } @@ -225,10 +232,11 @@ void SocketApi::slotUpdateFolderView(Folder *f) f->syncResult().status() == SyncResult::Error || f->syncResult().status() == SyncResult::SetupError ) { - broadcastMessage(QLatin1String("STATUS"), f->path() , + QString rootPath = removeTrailingSlash(f->path()); + broadcastMessage(QLatin1String("STATUS"), rootPath, f->syncEngine().syncFileStatusTracker().fileStatus("").toSocketAPIString()); - broadcastMessage(QLatin1String("UPDATE_VIEW"), f->path() ); + broadcastMessage(QLatin1String("UPDATE_VIEW"), rootPath); } else { qDebug() << "Not sending UPDATE_VIEW for" << f->alias() << "because status() is" << f->syncResult().status(); } @@ -302,8 +310,12 @@ void SocketApi::command_RETRIEVE_FILE_STATUS(const QString& argument, QIODevice* // this can happen in offline mode e.g.: nothing to worry about statusString = QLatin1String("NOP"); } else { - const QString file = QDir::cleanPath(argument).mid(syncFolder->cleanPath().length()+1); - SyncFileStatus fileStatus = syncFolder->syncEngine().syncFileStatusTracker().fileStatus(file); + QString relativePath = QDir::cleanPath(argument).mid(syncFolder->cleanPath().length()+1); + if( relativePath.endsWith(QLatin1Char('/')) ) { + relativePath.truncate(relativePath.length()-1); + qWarning() << "Removed trailing slash for directory: " << relativePath << "Status pushes won't have one."; + } + SyncFileStatus fileStatus = syncFolder->syncEngine().syncFileStatusTracker().fileStatus(relativePath); statusString = fileStatus.toSocketAPIString(); } diff --git a/src/libsync/syncfilestatustracker.cpp b/src/libsync/syncfilestatustracker.cpp index c32e4d664e..c749ae3a34 100644 --- a/src/libsync/syncfilestatustracker.cpp +++ b/src/libsync/syncfilestatustracker.cpp @@ -92,15 +92,11 @@ SyncFileItem SyncFileStatusTracker::rootSyncFileItem() return fakeRootItem; } -SyncFileStatus SyncFileStatusTracker::fileStatus(const QString& systemFileName) +SyncFileStatus SyncFileStatusTracker::fileStatus(const QString& relativePath) { - QString fileName = systemFileName.normalized(QString::NormalizationForm_C); - if( fileName.endsWith(QLatin1Char('/')) ) { - fileName.truncate(fileName.length()-1); - qDebug() << "Removed trailing slash: " << fileName; - } + Q_ASSERT(!relativePath.endsWith(QLatin1Char('/'))); - if( fileName.isEmpty() ) { + if (relativePath.isEmpty()) { // This is the root sync folder, it doesn't have an entry in the database and won't be walked by csync, so create one manually. return syncFileItemStatus(rootSyncFileItem()); } @@ -111,22 +107,22 @@ SyncFileStatus SyncFileStatusTracker::fileStatus(const QString& systemFileName) // update the exclude list at runtime and doing it statically here removes // our ability to notify changes through the fileStatusChanged signal, // it's an acceptable compromize to treat all exclude types the same. - if( _syncEngine->excludedFiles().isExcluded(_syncEngine->localPath() + fileName, + if( _syncEngine->excludedFiles().isExcluded(_syncEngine->localPath() + relativePath, _syncEngine->localPath(), _syncEngine->ignoreHiddenFiles()) ) { return SyncFileStatus(SyncFileStatus::StatusWarning); } - if ( _dirtyPaths.contains(fileName) ) + if ( _dirtyPaths.contains(relativePath) ) return SyncFileStatus::StatusSync; - SyncFileItem* item = _syncEngine->findSyncItem(fileName); + SyncFileItem* item = _syncEngine->findSyncItem(relativePath); if (item) { return syncFileItemStatus(*item); } // If we're not currently syncing that file, look it up in the database to know if it's shared - SyncJournalFileRecord rec = _syncEngine->journal()->getFileRecord(fileName); + SyncJournalFileRecord rec = _syncEngine->journal()->getFileRecord(relativePath); if (rec.isValid()) { return syncFileItemStatus(rec.toSyncFileItem()); } @@ -158,7 +154,7 @@ void SyncFileStatusTracker::slotAboutToPropagate(SyncFileItemVector& items) } else if (showWarningInSocketApi(*item)) { _syncProblems[item->_file] = SyncFileStatus::StatusWarning; } - emit fileStatusChanged(getSystemDestination(*item), syncFileItemStatus(*item)); + emit fileStatusChanged(getSystemDestination(item->destination()), syncFileItemStatus(*item)); } // Make sure to push any status that might have been resolved indirectly since the last sync @@ -170,7 +166,7 @@ void SyncFileStatusTracker::slotAboutToPropagate(SyncFileItemVector& items) SyncFileStatus::SyncFileStatusTag severity = it->second; if (severity == SyncFileStatus::StatusError) invalidateParentPaths(path); - emit fileStatusChanged(_syncEngine->localPath() + path, fileStatus(path)); + emit fileStatusChanged(getSystemDestination(path), fileStatus(path)); } } @@ -188,7 +184,7 @@ void SyncFileStatusTracker::slotItemCompleted(const SyncFileItem &item) Q_ASSERT(_syncProblems.find(item._file) == _syncProblems.end()); } - emit fileStatusChanged(getSystemDestination(item), syncFileItemStatus(item)); + emit fileStatusChanged(getSystemDestination(item.destination()), syncFileItemStatus(item)); } void SyncFileStatusTracker::slotSyncEngineRunningChanged() @@ -236,20 +232,19 @@ void SyncFileStatusTracker::invalidateParentPaths(const QString& path) QStringList splitPath = path.split('/', QString::SkipEmptyParts); for (int i = 0; i < splitPath.size(); ++i) { QString parentPath = QStringList(splitPath.mid(0, i)).join(QLatin1String("/")); - emit fileStatusChanged(_syncEngine->localPath() + parentPath, fileStatus(parentPath)); + emit fileStatusChanged(getSystemDestination(parentPath), fileStatus(parentPath)); } } -QString SyncFileStatusTracker::getSystemDestination(const SyncFileItem& item) +QString SyncFileStatusTracker::getSystemDestination(const QString& relativePath) { - QString systemFileName = _syncEngine->localPath() + item.destination(); - // the trailing slash for directories must be appended as the filenames coming in - // from the plugins have that too. Otherwise the matching entry item is not found - // in the plugin. - if( item._type == SyncFileItem::Type::Directory ) { - systemFileName += QLatin1Char('/'); + QString systemPath = _syncEngine->localPath() + relativePath; + // SyncEngine::localPath() has a trailing slash, make sure to remove it if the + // destination is empty. + if( systemPath.endsWith(QLatin1Char('/')) ) { + systemPath.truncate(systemPath.length()-1); } - return systemFileName; + return systemPath; } } diff --git a/src/libsync/syncfilestatustracker.h b/src/libsync/syncfilestatustracker.h index 4158d696d3..d141b4b178 100644 --- a/src/libsync/syncfilestatustracker.h +++ b/src/libsync/syncfilestatustracker.h @@ -35,7 +35,7 @@ class OWNCLOUDSYNC_EXPORT SyncFileStatusTracker : public QObject Q_OBJECT public: explicit SyncFileStatusTracker(SyncEngine* syncEngine); - SyncFileStatus fileStatus(const QString& systemFileName); + SyncFileStatus fileStatus(const QString& relativePath); public slots: void slotPathTouched(const QString& fileName); @@ -54,7 +54,7 @@ private: SyncFileItem rootSyncFileItem(); void invalidateParentPaths(const QString& path); - QString getSystemDestination(const SyncFileItem& syncEnginePath); + QString getSystemDestination(const QString& relativePath); SyncEngine* _syncEngine;