private static async Task InitQueue(Dictionary <string, object> request, IDownloadFolderDecider downloadFolderDecider, Dictionary <string, object> returnVal) { isQueue = true; queueTotalSlices = (long)request["TotalSlices"]; queueSlicesFinished = 0; queuedSlicesYet = 0; queueItems = new List <Dictionary <string, object> >(); queueFinishUrl = "http://" + (request["ServerIP"] as string) + ":" + Constants.CommunicationPort + "/" + request["QueueFinishKey"] + "/finishQueue/"; filesCount = 0; queueParentDirectory = (string)request["parentDirectoryName"]; latestReceivedQueueItemGroupId = -1; totalBytesReceived = 0; returnVal.Add("QueueInitialized", "1"); requestGuid = Guid.Parse(request["Guid"] as string); senderName = (string)request["SenderName"]; /* TODO: Do this from outside of this function */ //await request.SendResponseAsync(vs); InvokeProgressEvent(0, 0, FileTransferState.QueueList); if (request.ContainsKey("QueueInfoKey")) { List <string> queueItems = await RetrieveQueueItems(request["ServerIP"] as string, request["QueueInfoKey"] as string); foreach (var item in queueItems) { var info = JsonConvert.DeserializeObject <Dictionary <string, object> >(item); await ProcessQueueItem(info, downloadFolderDecider); } } }
private static async Task BeginProcessingQueue(IDownloadFolderDecider downloadFolderDecider) { var downloadFolder = await downloadFolderDecider.DecideAsync(queueItems.Select(x => Path.GetExtension((string)x["FileName"])).ToArray()); string queueParentDirectory2 = await GetUniqueQueueParentDirectory(downloadFolder); foreach (var item in queueItems) { if ((((string)item["Directory"]).Length >= queueParentDirectory.Length) && (((string)item["Directory"]).Substring(0, queueParentDirectory.Length) == queueParentDirectory)) { if (queueParentDirectory2 != queueParentDirectory) { item["Directory"] = queueParentDirectory2 + ((string)item["Directory"]).Substring(queueParentDirectory.Length); } } else if (queueParentDirectory.Length > 0) { item["Directory"] = Path.Combine(queueParentDirectory2, (string)item["Directory"]); } } var logItems = from x in queueItems select new ReceivedFile { Name = (string)x["FileName"], Size = (long)x["FileSize"], StorePath = System.IO.Path.Combine(downloadFolder.Path, (string)x["Directory"]), }; await DataStorageProviders.HistoryManager.OpenAsync(); DataStorageProviders.HistoryManager.Add(requestGuid, DateTime.Now, senderName, new ReceivedFileCollection { Files = logItems.ToList(), StoreRootPath = System.IO.Path.Combine(downloadFolder.Path, queueParentDirectory2), }, false); DataStorageProviders.HistoryManager.Close(); foreach (var item in queueItems) { await DownloadFile(item, downloadFolder); } await DataStorageProviders.HistoryManager.OpenAsync(); DataStorageProviders.HistoryManager.ChangeCompletedStatus(requestGuid, true); DataStorageProviders.HistoryManager.Close(); await QueueProcessFinishedNotifySender(); FileTransferProgress?.Invoke(new FileTransferProgressEventArgs { CurrentPart = (ulong)queueTotalSlices, Total = (ulong)queueTotalSlices, State = FileTransferState.Finished, Guid = requestGuid, SenderName = senderName, TotalFiles = filesCount }); }
public ReceiveSessionAgent(string ip, Guid sessionKey, string senderName, IDownloadFolderDecider downloadFolderDecider, Func <string, Task <IFolder> > folderResolver) { this.ip = ip; this.sessionKey = sessionKey; this.senderName = senderName; this.downloadFolderDecider = downloadFolderDecider; this.folderResolver = folderResolver; ReceiveFinishTcs = new TaskCompletionSource <bool>(); cancellationTokenSource = new CancellationTokenSource(); }
private static async Task <Dictionary <string, object> > ProcessRequestLegacy(Dictionary <string, object> request, int fileSenderVersion, IDownloadFolderDecider downloadFolderDecider) { FileReceiver.ClearEventRegistrations(); FileReceiver.FileTransferProgress += LegacyFileReceiver_FileTransferProgress; return(await FileReceiver.ReceiveRequest(request, downloadFolderDecider)); }
public static async Task <Dictionary <string, object> > ReceiveRequest(Dictionary <string, object> request, IDownloadFolderDecider downloadFolderDecider, Func <string, Task <IFolder> > folderResolver) { try { int fileSenderVersion = 2; // FileSender v1 if (!request.ContainsKey("FileSenderVersion") || (int.Parse(request["FileSenderVersion"].ToString()) < 2)) { fileSenderVersion = 1; return(await ProcessRequestLegacy(request, fileSenderVersion, downloadFolderDecider)); } if (!request.ContainsKey("Type")) { throw new InvalidOperationException("Field 'Type' is missing from request."); } switch (request["Type"] as string) { case "QueueInit": await ProcessRequest(request, fileSenderVersion, downloadFolderDecider, folderResolver, isResume : false); return(new Dictionary <string, object>()); case "ResumeReceive": Debug.WriteLine("Received ResumeReceive request. TODO."); if (currentReceiveSessionAgent != null) { currentReceiveSessionAgent.Stop(); await Task.Delay(500); } await ProcessRequest(request, fileSenderVersion, downloadFolderDecider, folderResolver, isResume : true); return(new Dictionary <string, object>()); default: throw new InvalidOperationException($"Type '{request["Type"]}' is invalid."); } } catch (Exception ex) { FileTransferProgress?.Invoke(new FileTransfer2ProgressEventArgs { State = FileTransferState.Error, Exception = ex, }); throw ex; } }
private static async Task ProcessRequest(Dictionary <string, object> request, int fileSenderVersion, IDownloadFolderDecider downloadFolderDecider, Func <string, Task <IFolder> > folderResolver, bool isResume) { var sessionKey = Guid.Parse(request["Guid"] as string); var ip = request["ServerIP"].ToString(); var isCompatible = CompatibilityHelper.IsCompatible(fileSenderVersion, fileReceiverVersion); var senderName = request["SenderName"].ToString(); if ((!isResume) && (fileSenderVersion >= 2)) { await SendVersionCheckGetRequestAsync(ip, sessionKey, isCompatible); } if (!isCompatible) { // TODO return; } currentReceiveSessionAgent = new ReceiveSessionAgent(ip, sessionKey, senderName, downloadFolderDecider, folderResolver); currentReceiveSessionAgent.FileTransferProgress += (e) => { FileTransferProgress?.Invoke(e); }; currentReceiveSessionAgent.StartReceive(isResume); await currentReceiveSessionAgent.ReceiveFinishTcs.Task; }
private static async Task ProcessSingularFile(Dictionary <string, object> request, IDownloadFolderDecider downloadFolderDecider) { //Singular file filesCount = 1; requestGuid = Guid.Parse(request["Guid"] as string); senderName = (string)request["SenderName"]; isQueue = false; totalBytesReceived = 0; var downloadFolder = await downloadFolderDecider.DecideAsync(new string[] { Path.GetExtension((string)request["FileName"]) }); await DataStorageProviders.HistoryManager.OpenAsync(); DataStorageProviders.HistoryManager.Add(requestGuid, DateTime.Now, senderName, new ReceivedFileCollection { Files = new List <ReceivedFile>() { new ReceivedFile { Name = (string)request["FileName"], Size = (long)request["FileSize"], StorePath = System.IO.Path.Combine(downloadFolder.Path, (string)request["Directory"]), } }, StoreRootPath = System.IO.Path.Combine(downloadFolder.Path, (string)request["Directory"]), }, false, false); DataStorageProviders.HistoryManager.Close(); await DownloadFile(request, downloadFolder); await DataStorageProviders.HistoryManager.OpenAsync(); DataStorageProviders.HistoryManager.ChangeCompletedStatus(requestGuid, true); DataStorageProviders.HistoryManager.Close(); }
public static async Task <Dictionary <string, object> > ReceiveRequest(Dictionary <string, object> request, IDownloadFolderDecider downloadFolderDecider) { Dictionary <string, object> returnVal = new Dictionary <string, object>(); try { if ((request.ContainsKey("Type")) && (request["Type"] as string == "QueueInit")) { await InitQueue(request, downloadFolderDecider, returnVal); } else if ((request.ContainsKey("IsQueueItemGroup")) && (request["IsQueueItemGroup"] as string == "true")) { await ProcessQueueItemGroup(request, downloadFolderDecider); } else if ((request.ContainsKey("IsQueueItem")) && (request["IsQueueItem"] as string == "true")) { await ProcessQueueItem(request, downloadFolderDecider); } else { await ProcessSingularFile(request, downloadFolderDecider); } } catch (FailedToDownloadException) { FileTransferProgress?.Invoke(new FileTransferProgressEventArgs { Guid = requestGuid, State = FileTransferState.Error, }); } return(returnVal); }
private static async Task ProcessQueueItem(Dictionary <string, object> request, IDownloadFolderDecider downloadFolderDecider) { //Queue data details queuedSlicesYet += (int)(long)request["SlicesCount"]; queueItems.Add(request); filesCount++; if (queuedSlicesYet == queueTotalSlices) { await BeginProcessingQueue(downloadFolderDecider); } else if (queuedSlicesYet > queueTotalSlices) { Debug.WriteLine("Queued more slices than expected."); throw new Exception("Queued more slices than expected."); } }
private static async Task ProcessQueueItemGroup(Dictionary <string, object> request, IDownloadFolderDecider downloadFolderDecider) { if (queuedSlicesYet < queueTotalSlices) //Ignore if queue already started processing { int partNum = int.Parse(request["PartNum"].ToString()); Debug.WriteLine($"Received QueueItemGroup #{partNum}."); if (partNum > latestReceivedQueueItemGroupId) { latestReceivedQueueItemGroupId = partNum; var items = JsonConvert.DeserializeObject <List <string> >(request["Data"].ToString()); Debug.WriteLine($"It contains {items.Count} entries. Processing..."); foreach (var item in items) { var info = JsonConvert.DeserializeObject <Dictionary <string, object> >(item); await ProcessQueueItem(info, downloadFolderDecider); } Debug.WriteLine("Processed QueueItemGroup successfully."); } } }