private async Task <bool> DoDelete(FileEntryItem item, bool suppressCleanup) { if (m_options.Dryrun) { Logging.Log.WriteDryrunMessage(LOGTAG, "WouldDeleteRemoteFile", "Would delete remote file: {0}, size: {1}", item.RemoteFilename, Library.Utility.Utility.FormatSizeString(item.Size)); return(true); } await m_stats.SendEventAsync(BackendActionType.Delete, BackendEventType.Started, item.RemoteFilename, item.Size); string result = null; try { m_backend.Delete(item.RemoteFilename); } catch (Exception ex) { var isFileMissingException = ex is Library.Interface.FileMissingException || ex is System.IO.FileNotFoundException; var wr = ex as System.Net.WebException == null ? null : (ex as System.Net.WebException).Response as System.Net.HttpWebResponse; if (isFileMissingException || (wr != null && wr.StatusCode == System.Net.HttpStatusCode.NotFound)) { Logging.Log.WriteWarningMessage(LOGTAG, "DeleteRemoteFileFailed", ex, LC.L("Delete operation failed for {0} with FileNotFound, listing contents", item.RemoteFilename)); bool success = false; try { success = !m_backend.List().Select(x => x.Name).Contains(item.RemoteFilename); } catch { } if (success) { Logging.Log.WriteInformationMessage(LOGTAG, "DeleteRemoteFileSuccess", LC.L("Listing indicates file {0} is deleted correctly", item.RemoteFilename)); return(true); } } result = ex.ToString(); throw; } finally { await m_database.LogRemoteOperationAsync("delete", item.RemoteFilename, result); } await m_database.UpdateRemoteVolumeAsync(item.RemoteFilename, RemoteVolumeState.Deleted, -1, null, suppressCleanup, TimeSpan.FromHours(2)); await m_stats.SendEventAsync(BackendActionType.Delete, BackendEventType.Completed, item.RemoteFilename, item.Size); return(true); }
public async Task UploadFileAsync(VolumeWriterBase item, Func <string, Task <IndexVolumeWriter> > createIndexFile = null) { var fe = new FileEntryItem(BackendActionType.Put, item.RemoteFilename); fe.SetLocalfilename(item.LocalFilename); var tcs = new TaskCompletionSource <bool>(); var backgroundhashAndEncrypt = Task.Run(() => { fe.Encrypt(m_options); return(fe.UpdateHashAndSize(m_options)); }); await RunOnMain(async() => { try { await DoWithRetry(fe, async() => { if (fe.IsRetry) { await RenameFileAfterErrorAsync(fe).ConfigureAwait(false); } // Make sure the encryption and hashing has completed await backgroundhashAndEncrypt.ConfigureAwait(false); return(await DoPut(fe).ConfigureAwait(false)); }).ConfigureAwait(false); if (createIndexFile != null) { var ix = await createIndexFile(fe.RemoteFilename).ConfigureAwait(false); var indexFile = new FileEntryItem(BackendActionType.Put, ix.RemoteFilename); indexFile.SetLocalfilename(ix.LocalFilename); await m_database.UpdateRemoteVolumeAsync(indexFile.RemoteFilename, RemoteVolumeState.Uploading, -1, null); await DoWithRetry(indexFile, async() => { if (indexFile.IsRetry) { await RenameFileAfterErrorAsync(indexFile).ConfigureAwait(false); } var res = await DoPut(indexFile).ConfigureAwait(false); // Register that the index file is tracking the block file await m_database.AddIndexBlockLinkAsync( ix.VolumeID, await m_database.GetRemoteVolumeIDAsync(fe.RemoteFilename) ).ConfigureAwait(false); return(res); }); } tcs.TrySetResult(true); } catch (Exception ex) { if (ex is System.Threading.ThreadAbortException) { tcs.TrySetCanceled(); } else { tcs.TrySetException(ex); } } }); await tcs.Task.ConfigureAwait(false); }