Detect renames and removes in read only Shared directory, restore files.

This fixes bug #1386
This commit is contained in:
Klaas Freitag 2014-02-04 15:01:10 +01:00
parent 72a6b00919
commit ae5c9a29f6
2 changed files with 69 additions and 2 deletions

View file

@ -62,7 +62,7 @@ void PropagateItemJob::done(SyncFileItem::Status status, const QString &errorStr
// Blacklisting
int retries = 0;
if( _item._httpErrorCode == 403 || _item._httpErrorCode == 413 || _item._httpErrorCode == 415 ) {
if( _item._httpErrorCode == 403 ||_item._httpErrorCode == 413 || _item._httpErrorCode == 415 ) {
qDebug() << "Fatal Error condition" << _item._httpErrorCode << ", forbid retry!";
retries = -1;
} else {
@ -99,6 +99,37 @@ void PropagateItemJob::done(SyncFileItem::Status status, const QString &errorStr
emit finished(status);
}
bool PropagateItemJob::checkForProblemsWithShared()
{
QString errorString = QString::fromUtf8(ne_get_error(_propagator->_session));
int httpStatusCode = errorString.mid(0, errorString.indexOf(QChar(' '))).toInt();
if( httpStatusCode == 403 && _propagator->isInSharedDirectory(_item._file )) {
// the file was removed locally from a read only Shared sync
// the file is gone locally and it should be recovered.
SyncFileItem downloadItem(_item);
downloadItem._instruction = CSYNC_INSTRUCTION_SYNC;
downloadItem._dir = SyncFileItem::Down;
_restoreJob.reset(new PropagateDownloadFile(_propagator, downloadItem));
connect(_restoreJob.data(), SIGNAL(completed(SyncFileItem)),
this, SLOT(slotRestoreJobCompleted(SyncFileItem)));
_restoreJob->start();
return true;
}
return false;
}
void PropagateItemJob::slotRestoreJobCompleted(const SyncFileItem& item )
{
if( item._status == SyncFileItem::Success ) {
done( SyncFileItem::SoftError, tr("The file was removed from a read only share. The file has been restored."));
} else {
done( item._status, tr("A file was removed from a read only share, but restoring failed: %1").arg(item._errorString) );
}
}
// compare two files with given filename and return true if they have the same content
static bool fileEquals(const QString &fn1, const QString &fn2) {
QFile f1(fn1);
@ -191,10 +222,16 @@ void PropagateRemoteRemove::start()
emit progress(Progress::StartDelete, _item, 0, _item._size);
qDebug() << "** DELETE " << uri.data();
int rc = ne_delete(_propagator->_session, uri.data());
if( checkForProblemsWithShared() ) {
return;
}
/* Ignore the error 404, it means it is already deleted */
if (updateErrorFromSession(rc, 0, 404)) {
return;
}
_propagator->_journal->deleteFileRecord(_item._originalFile, _item._isDirectory);
_propagator->_journal->commit("Remote Remove");
done(SyncFileItem::Success);
@ -866,13 +903,17 @@ void PropagateRemoteRename::start()
qDebug() << "MOVE on Server: " << uri1.data() << "->" << uri2.data();
int rc = ne_move(_propagator->_session, 1, uri1.data(), uri2.data());
if( checkForProblemsWithShared()) {
return;
}
if (updateErrorFromSession(rc)) {
return;
}
updateMTimeAndETag(uri2.data(), _item._modtime);
emit progress(Progress::EndRename, _item, _item._size, _item._size);
}
_propagator->_journal->deleteFileRecord(_item._originalFile);
@ -1037,6 +1078,21 @@ void OwncloudPropagator::overallTransmissionSizeChanged(qint64 change)
emit progressChanged(change);
}
bool OwncloudPropagator::isInSharedDirectory(const QString& file)
{
bool re = false;
if( _remoteDir.contains("remote.php/webdav/Shared") ) {
// The Shared directory is synced as its own sync connection
re = true;
} else {
if( file.startsWith("Shared/") ) {
// The whole ownCloud is synced and Shared is always a top dir
re = true;
}
}
return re;
}
void PropagateDirectory::start()
{
_current = -1;
@ -1076,4 +1132,5 @@ void PropagateDirectory::proceedNext(SyncFileItem::Status status)
}
}
}

View file

@ -115,14 +115,23 @@ protected:
*/
void limitBandwidth(qint64 progress, qint64 limit);
bool checkForProblemsWithShared();
QElapsedTimer _lastTime;
qint64 _lastProgress;
int _httpStatusCode;
SyncFileItem _item;
protected slots:
void slotRestoreJobCompleted(const SyncFileItem& );
private:
QScopedPointer<PropagateItemJob> _restoreJob;
public:
PropagateItemJob(OwncloudPropagator* propagator, const SyncFileItem &item)
: PropagatorJob(propagator), _lastProgress(0), _httpStatusCode(0), _item(item) {}
};
// Dummy job that just mark it as completed and ignored.
@ -171,6 +180,7 @@ public:
void overallTransmissionSizeChanged( qint64 change );
bool isInSharedDirectory(const QString& file);
signals:
void completed(const SyncFileItem &);
void progress(Progress::Kind kind, const SyncFileItem&, quint64 bytes, quint64 total);