private List <DownloadablePart> GetItemParts(int size, DownloadableItem item) { //var chunkSize = Constants.DownloadChunkSize; var chunkSize = size > 1024 * 1024 ? 1024 * 128 : 1024 * 32; var parts = new List <DownloadablePart>(); var partsCount = size / chunkSize + (size % chunkSize > 0 ? 1 : 0); for (var i = 0; i < partsCount; i++) { var part = new DownloadablePart(item, i * chunkSize, size == 0 ? 0 : chunkSize, i); var partName = item.InputDocumentLocation.GetPartFileName(part.Number); //string.Format("document{0}_{1}_{2}.dat", item.InputDocumentLocation.Id, item.InputDocumentLocation.AccessHash, part.Number); var partLength = FileUtils.GetLocalFileLength(partName); if (partLength >= 0) { var isCompletePart = (part.Number + 1 == partsCount) || partLength == part.Limit; part.Status = isCompletePart ? PartStatus.Processed : PartStatus.Ready; } parts.Add(part); } return(parts); }
protected override List <DownloadablePart> GetItemParts(TLInt size, DownloadableItem item) { var chunkSize = size.Value > 1024 * 1024 ? Constants.DownloadedBigChunkSize : Constants.DownloadedChunkSize; var parts = new List <DownloadablePart>(); var partsCount = size.Value / chunkSize + (size.Value % chunkSize > 0 ? 1 : 0); var step = partsCount / 25; for (var i = 0; i < partsCount; i++) { var part = new DownloadablePart(item, new TLInt(i * chunkSize), size.Value == 0 ? new TLInt(1024 * 1024) : new TLInt(chunkSize), i); var partName = item.InputLocation.GetPartFileName(part.Number, "document"); var partLength = FileUtils.GetLocalFileLength(partName); if (partLength >= 0) { var isCompletePart = (part.Number + 1 == partsCount) || partLength == part.Limit.Value; part.Status = isCompletePart ? PartStatus.Processed : PartStatus.Ready; } part.NotifyProgress = part.Status == PartStatus.Ready && (step == 0 || i % step == 0); parts.Add(part); } return(parts); }
private List <DownloadablePart> GetItemParts(TLInt size, DownloadableItem item) { var chunkSize = Constants.DownloadedChunkSize; var parts = new List <DownloadablePart>(); var partsCount = size.Value / chunkSize + (size.Value % chunkSize > 0 ? 1 : 0); for (var i = 0; i < partsCount; i++) { var part = new DownloadablePart(item, new TLInt(i * chunkSize), size.Value == 0 ? new TLInt(0) : new TLInt(chunkSize), i); parts.Add(part); } return(parts); }
private List <DownloadablePart> GetItemParts(int size, DownloadableItem item) { var chunkSize = Constants.DownloadChunkSize; var parts = new List <DownloadablePart>(); var partsCount = size / chunkSize + (size % chunkSize > 0 ? 1 : 0); for (var i = 0; i < partsCount; i++) { var part = new DownloadablePart(item, i * chunkSize, chunkSize, i); parts.Add(part); } return(parts); }
protected virtual List <DownloadablePart> GetItemParts(TLInt size, DownloadableItem item) { var chunkSize = size.Value > 1024 * 1024? Constants.DownloadedBigChunkSize : Constants.DownloadedChunkSize; var parts = new List <DownloadablePart>(); var partsCount = size.Value / chunkSize + ((size.Value % chunkSize > 0 || size.Value == 0) ? 1 : 0); for (var i = 0; i < partsCount; i++) { var part = new DownloadablePart(item, new TLInt(i * chunkSize), size.Value == 0 ? new TLInt(1024 * 1024) : new TLInt(chunkSize), i); parts.Add(part); } return(parts); }
protected void ProcessFilePart(DownloadablePart part, TLInt dcId, TLInputFileLocationBase location, out bool canceled) { do { TLRPCError error; TLFileBase result; if (part.ParentItem.CdnRedirect != null) { TLCdnFileReuploadNeeded cdnFileReuploadNeeded; bool tokenInvalid; result = GetCdnFile(part.ParentItem.CdnRedirect, part.Offset, part.Limit, out cdnFileReuploadNeeded, out error, out canceled, out tokenInvalid); if (cdnFileReuploadNeeded != null) { ReuploadFile(part.ParentItem.CdnRedirect, dcId, cdnFileReuploadNeeded.RequestToken, out error, out canceled, out tokenInvalid); } if (tokenInvalid) { lock (_itemsSyncRoot) { part.ParentItem.CdnRedirect = null; } continue; } } else { result = GetFile(dcId, location, part.Offset, part.Limit, out error, out canceled); var fileCdnRedirect = result as TLFileCdnRedirect; if (fileCdnRedirect != null) { lock (_itemsSyncRoot) { part.ParentItem.CdnRedirect = fileCdnRedirect; } continue; } } part.File = result as TLFile; if (canceled) { return; } } while (part.File == null); }
private List <DownloadablePart> GetItemParts(int size, DownloadableItem item) { //var chunkSize = Constants.DownloadChunkSize; var chunkSize = size > 1024 * 1024 ? 1024 * 128 : 1024 * 32; var parts = new List <DownloadablePart>(); var partsCount = size / chunkSize + 1; for (var i = 0; i < partsCount; i++) { //var part = new DownloadablePart(item, i * chunkSize, size == 0 ? 0 : chunkSize); var part = new DownloadablePart(item, i * chunkSize, chunkSize, i); parts.Add(part); } return(parts); }
private List <DownloadablePart> GetItemParts(TLInt size, DownloadableItem item) { var chunkSize = Constants.DownloadedChunkSize; var parts = new List <DownloadablePart>(); var partsCount = size.Value / chunkSize + (size.Value % chunkSize > 0 ? 1 : 0); for (var i = 0; i < partsCount; i++) { var part = new DownloadablePart(item, new TLInt(i * chunkSize), size.Value == 0 ? new TLInt(0) : new TLInt(chunkSize), i); var partName = string.Format("document{0}_{1}_{2}.dat", item.InputDocumentLocation.Id, item.InputDocumentLocation.AccessHash, part.Number); var partLength = FileUtils.GetLocalFileLength(partName); if (partLength >= 0) { var isCompletePart = (part.Number + 1 == partsCount) || partLength == part.Limit.Value; part.Status = isCompletePart ? PartStatus.Processed : PartStatus.Ready; } parts.Add(part); } return(parts); }
private void OnDownloading(object state) { DownloadablePart part = null; lock (_itemsSyncRoot) { for (var i = 0; i < _items.Count; i++) { var item = _items[i]; if (item.Canceled) { _items.RemoveAt(i--); try { //_eventAggregator.Publish(new UploadingCanceledEventArgs(item)); } catch (Exception e) { TLUtils.WriteException(e); } } } foreach (var item in _items) { part = item.Parts.FirstOrDefault(x => x.Status == PartStatus.Ready); if (part != null) { part.Status = PartStatus.Processing; break; } } } if (part == null) { var currentWorker = (Worker)state; currentWorker.Stop(); return; } var partName = part.ParentItem.InputLocation.GetPartFileName(part.Number, "video"); bool canceled; ProcessFilePart(part, part.ParentItem.DCId, part.ParentItem.InputLocation, out canceled); if (canceled) { lock (_itemsSyncRoot) { part.ParentItem.Canceled = true; part.Status = PartStatus.Processed; _items.Remove(part.ParentItem); } return; } //part.File = GetFile(part.ParentItem.DCId, (TLInputFileLocationBase)part.ParentItem.InputVideoLocation, part.Offset, part.Limit); //while (part.File == null) //{ // part.File = GetFile(part.ParentItem.DCId, (TLInputFileLocationBase)part.ParentItem.InputVideoLocation, part.Offset, part.Limit); //} // indicate progress // indicate complete bool isComplete; bool isCanceled; var progress = 0.0; lock (_itemsSyncRoot) { part.Status = PartStatus.Processed; FileUtils.CheckMissingPart(_itemsSyncRoot, part, partName); isCanceled = part.ParentItem.Canceled; isComplete = part.ParentItem.Parts.All(x => x.Status == PartStatus.Processed); if (!isComplete) { var downloadedCount = part.ParentItem.Parts.Count(x => x.Status == PartStatus.Processed); var count = part.ParentItem.Parts.Count; progress = downloadedCount / (double)count; } else { _items.Remove(part.ParentItem); } } if (!isCanceled) { if (isComplete) { var fileName = part.ParentItem.InputLocation.GetFileName("video", ".mp4"); var getPartName = new Func <DownloadablePart, string>(x => x.ParentItem.InputLocation.GetPartFileName(x.Number, "video")); FileUtils.MergePartsToFile(getPartName, part.ParentItem.Parts, fileName); part.ParentItem.IsoFileName = fileName; _eventAggregator.Publish(part.ParentItem); } else { _eventAggregator.Publish(new ProgressChangedEventArgs(part.ParentItem, progress)); } } }
private void OnDownloading(object state) { DownloadablePart part = null; lock (_itemsSyncRoot) { for (var i = 0; i < _items.Count; i++) { var item = _items[i]; if (item.IsCancelled) { _items.RemoveAt(i--); try { //_eventAggregator.Publish(new UploadingCanceledEventArgs(item)); } catch (Exception e) { TLUtils.WriteException(e); } } } foreach (var item in _items) { part = item.Parts.FirstOrDefault(x => x.Status == PartStatus.Ready); if (part != null) { part.Status = PartStatus.Processing; break; } } } if (part == null) { var currentWorker = (Worker)state; currentWorker.Stop(); return; } var partName = part.ParentItem.InputDocumentLocation.GetPartFileName(part.Number);//string.Format("document{0}_{1}_{2}.dat", part.ParentItem.InputDocumentLocation.Id, part.ParentItem.InputDocumentLocation.AccessHash, part.Number); TLRPCError error; bool canceled; do { TLUploadFileBase result; if (part.ParentItem.CdnRedirect != null) { result = GetCdnFile(part.ParentItem.CdnRedirect, part.ParentItem.DCId, part.ParentItem.InputDocumentLocation, part.Offset, part.Limit, out error, out canceled); } else { result = GetFile(part.ParentItem.DCId, part.ParentItem.InputDocumentLocation, part.Offset, part.Limit, out error, out canceled); } if (result is TLUploadFileCdnRedirect redirect) { part.ParentItem.CdnRedirect = redirect; continue; } else { part.File = result as TLUploadFile; } if (canceled) { lock (_itemsSyncRoot) { part.ParentItem.IsCancelled = true; part.Status = PartStatus.Processed; _items.Remove(part.ParentItem); } return; } } while (part.File == null); // indicate progress // indicate complete bool isComplete; bool isCanceled; var progress = 0.0; lock (_itemsSyncRoot) { part.Status = PartStatus.Processed; if (!part.ParentItem.SuppressMerge) { FileUtils.CheckMissingPart(_itemsSyncRoot, part, partName); } isCanceled = part.ParentItem.IsCancelled; isComplete = part.ParentItem.Parts.All(x => x.Status == PartStatus.Processed); if (!isComplete) { var downloadedCount = part.ParentItem.Parts.Count(x => x.Status == PartStatus.Processed); var count = part.ParentItem.Parts.Count; progress = downloadedCount / (double)count; } else { //var id = part.ParentItem.InputDocumentLocation.Id; //var accessHash = part.ParentItem.InputDocumentLocation.AccessHash; //var fileExtension = Path.GetExtension(part.ParentItem.FileName.ToString()); //var fileName = string.Format("document{0}_{1}{2}", id, accessHash, fileExtension); //if (fileName.EndsWith(".mp4")) //{ // Logs.Log.SyncWrite("FileManager.IsComplete " + fileName + " hash=" + part.ParentItem.GetHashCode()); //} _items.Remove(part.ParentItem); } } if (!isCanceled) { if (isComplete) { //var id = part.ParentItem.InputDocumentLocation.Id; //var accessHash = part.ParentItem.InputDocumentLocation.AccessHash; //var version = part.ParentItem.InputDocumentLocation.Version; var fileExtension = Path.GetExtension(part.ParentItem.FileName.ToString()); var fileName = GetFileName(part.ParentItem.InputDocumentLocation, fileExtension); Func <DownloadablePart, string> getPartName = x => part.ParentItem.InputDocumentLocation.GetPartFileName(x.Number); if (!part.ParentItem.SuppressMerge) { FileUtils.MergePartsToFile(getPartName, part.ParentItem.Parts, fileName); } part.ParentItem.IsoFileName = fileName; if (part.ParentItem.Callback != null) { //Execute.BeginOnThreadPool(() => //{ // part.ParentItem.Callback(part.ParentItem); // if (part.ParentItem.Callbacks != null) // { // foreach (var callback in part.ParentItem.Callbacks) // { // callback?.Invoke(part.ParentItem); // } // } //}); part.ParentItem.Progress.Report(1.0); part.ParentItem.Callback.TrySetResult(part.ParentItem); } else { Execute.BeginOnThreadPool(() => _eventAggregator.Publish(part.ParentItem)); } _statsService.IncrementReceivedItemsCount(_mtProtoService.NetworkType, _dataType, 1); } else { if (part.ParentItem.Callback != null) { part.ParentItem.Progress.Report(progress); } else { Execute.BeginOnThreadPool(() => _eventAggregator.Publish(new DownloadProgressChangedEventArgs(part.ParentItem, progress))); } } } }
private void OnDownloading(object state) { DownloadablePart part = null; lock (_itemsSyncRoot) { for (var i = 0; i < _items.Count; i++) { var item = _items[i]; if (item.Canceled) { _items.RemoveAt(i--); try { //_eventAggregator.Publish(new UploadingCanceledEventArgs(item)); } catch (Exception e) { TLUtils.WriteException(e); } } } foreach (var item in _items) { part = item.Parts.FirstOrDefault(x => x.Status == PartStatus.Ready); if (part != null) { part.Status = PartStatus.Processing; break; } } } if (part == null) { var currentWorker = (Worker)state; currentWorker.Stop(); return; } var partName = string.Format("audio{0}_{1}_{2}.dat", part.ParentItem.InputAudioLocation.Id, part.ParentItem.InputAudioLocation.AccessHash, part.Number); var isLastPart = part.Number + 1 == part.ParentItem.Parts.Count; var partLength = FileUtils.GetLocalFileLength(partName); var partExists = partLength >= 0; var isCorrectPartLength = isLastPart || partLength == part.Limit.Value; if (!partExists || !isCorrectPartLength) { part.File = GetFile(part.ParentItem.DCId, part.ParentItem.InputAudioLocation, part.Offset, part.Limit); while (part.File == null) { part.File = GetFile(part.ParentItem.DCId, part.ParentItem.InputAudioLocation, part.Offset, part.Limit); } part.Status = PartStatus.Processed; FileUtils.CheckMissingPart(_itemsSyncRoot, part, partName); } // indicate progress // indicate complete bool isComplete; bool isCanceled; var progress = 0.0; lock (_itemsSyncRoot) { part.Status = PartStatus.Processed; isCanceled = part.ParentItem.Canceled; isComplete = part.ParentItem.Parts.All(x => x.Status == PartStatus.Processed); if (!isComplete) { var downloadedCount = part.ParentItem.Parts.Count(x => x.Status == PartStatus.Processed); var count = part.ParentItem.Parts.Count; progress = downloadedCount / (double)count; } else { _items.Remove(part.ParentItem); } } if (!isCanceled) { if (isComplete) { var id = part.ParentItem.InputAudioLocation.Id; var accessHash = part.ParentItem.InputAudioLocation.AccessHash; var fileName = string.Format("audio{0}_{1}.mp3", id, accessHash); var getPartName = new Func <DownloadablePart, string>(x => string.Format("audio{0}_{1}_{2}.dat", id, accessHash, x.Number)); FileUtils.MergePartsToFile(getPartName, part.ParentItem.Parts, fileName); part.ParentItem.IsoFileName = fileName; Execute.BeginOnThreadPool(() => _eventAggregator.Publish(part.ParentItem)); } else { Execute.BeginOnThreadPool(() => _eventAggregator.Publish(new ProgressChangedEventArgs(part.ParentItem, progress))); } } }
private void OnDownloading(object state) { DownloadablePart part = null; lock (_itemsSyncRoot) { for (var i = 0; i < _items.Count; i++) { var item = _items[i]; if (item.IsCancelled) { _items.RemoveAt(i--); try { //_eventAggregator.Publish(new UploadingCanceledEventArgs(item)); } catch (Exception e) { TLUtils.WriteException(e); } } } foreach (var item in _items) { part = item.Parts.FirstOrDefault(x => x.Status == PartStatus.Ready); if (part != null) { part.Status = PartStatus.Processing; break; } } } if (part == null) { var currentWorker = (Worker)state; currentWorker.Stop(); return; } var partName = part.ParentItem.InputEncryptedFileLocation.GetPartFileName(part.Number); var partLength = FileUtils.GetLocalFileLength(partName); var partExists = partLength > 0; var isLastPart = part.Number + 1 == part.ParentItem.Parts.Count; var isCorrectPartLength = isLastPart || partLength == part.Limit; if (!partExists || !isCorrectPartLength) { part.File = GetFile(part.ParentItem.DCId, part.ParentItem.InputEncryptedFileLocation, part.Offset, part.Limit) as TLUploadFile; while (part.File == null) { part.File = GetFile(part.ParentItem.DCId, part.ParentItem.InputEncryptedFileLocation, part.Offset, part.Limit) as TLUploadFile; } } // indicate progress // indicate complete bool isComplete; bool isCanceled; var progress = 0.0; lock (_itemsSyncRoot) { part.Status = PartStatus.Processed; FileUtils.CheckMissingPart(_itemsSyncRoot, part, partName); isCanceled = part.ParentItem.IsCancelled; isComplete = part.ParentItem.Parts.All(x => x.Status == PartStatus.Processed); if (!isComplete) { var downloadedCount = part.ParentItem.Parts.Count(x => x.Status == PartStatus.Processed); var count = part.ParentItem.Parts.Count; progress = downloadedCount / (double)count; } else { _items.Remove(part.ParentItem); } } if (!isCanceled) { if (isComplete) { var fileName = part.ParentItem.InputEncryptedFileLocation.GetFileName(); var getPartFileName = new Func <DownloadablePart, string>(p => p.ParentItem.InputEncryptedFileLocation.GetPartFileName(p.Number)); FileUtils.MergePartsToFile(getPartFileName, part.ParentItem.Parts, fileName); part.ParentItem.IsoFileName = fileName; if (part.ParentItem.Callback != null) { part.ParentItem.Progress.Report(1.0); part.ParentItem.Callback.TrySetResult(part.ParentItem); } else { Execute.BeginOnThreadPool(() => _eventAggregator.Publish(part.ParentItem)); } _statsService.IncrementReceivedItemsCount(_mtProtoService.NetworkType, _dataType, 1); } else { if (part.ParentItem.Callback != null) { part.ParentItem.Progress.Report(progress); } else { Execute.BeginOnThreadPool(() => _eventAggregator.Publish(new DownloadProgressChangedEventArgs(part.ParentItem, progress))); } } } }
private void OnDownloading(object state) { DownloadablePart part = null; lock (_itemsSyncRoot) { for (var i = 0; i < _items.Count; i++) { var item = _items[i]; if (item.Canceled) { _items.RemoveAt(i--); try { //_eventAggregator.Publish(new UploadingCanceledEventArgs(item)); } catch (Exception e) { TLUtils.WriteException(e); } } } foreach (var item in _items) { part = item.Parts.FirstOrDefault(x => x.Status == PartStatus.Ready); if (part != null) { part.Status = PartStatus.Processing; break; } } } if (part == null) { var currentWorker = (Worker)state; currentWorker.Stop(); return; } var partName = part.ParentItem.InputLocation.GetPartFileName(part.Number, "document"); bool canceled; ProcessFilePart(part, part.ParentItem.DCId, part.ParentItem.InputLocation, out canceled); if (canceled) { lock (_itemsSyncRoot) { part.ParentItem.Canceled = true; part.Status = PartStatus.Processed; _items.Remove(part.ParentItem); } return; } //part.File = GetFile(part.ParentItem.DCId, part.ParentItem.InputDocumentLocation, part.Offset, part.Limit); //while (part.File == null) //{ // part.File = GetFile(part.ParentItem.DCId, part.ParentItem.InputDocumentLocation, part.Offset, part.Limit); //} // indicate progress // indicate complete bool isComplete; bool isCanceled; var progress = 0.0; lock (_itemsSyncRoot) { part.Status = PartStatus.Processed; if (!part.ParentItem.SuppressMerge) { FileUtils.CheckMissingPart(_itemsSyncRoot, part, partName); } isCanceled = part.ParentItem.Canceled; isComplete = part.ParentItem.Parts.All(x => x.Status == PartStatus.Processed); if (!isComplete) { var downloadedCount = part.ParentItem.Parts.Count(x => x.Status == PartStatus.Processed); var count = part.ParentItem.Parts.Count; progress = downloadedCount / (double)count; } else { //var id = part.ParentItem.InputDocumentLocation.Id; //var accessHash = part.ParentItem.InputDocumentLocation.AccessHash; //var fileExtension = Path.GetExtension(part.ParentItem.FileName.ToString()); //var fileName = string.Format("document{0}_{1}{2}", id, accessHash, fileExtension); //if (fileName.EndsWith(".mp4")) //{ // Logs.Log.SyncWrite("FileManager.IsComplete " + fileName + " hash=" + part.ParentItem.GetHashCode()); //} _items.Remove(part.ParentItem); } } if (!isCanceled) { if (isComplete) { //var id = part.ParentItem.InputDocumentLocation.Id; //var accessHash = part.ParentItem.InputDocumentLocation.AccessHash; //var version = part.ParentItem.InputDocumentLocation.Version; var fileExtension = Path.GetExtension(part.ParentItem.FileName.ToString()); var fileName = part.ParentItem.InputLocation.GetFileName("document", fileExtension); Func <DownloadablePart, string> getPartName = x => part.ParentItem.InputLocation.GetPartFileName(x.Number, "document"); if (!part.ParentItem.SuppressMerge) { FileUtils.MergePartsToFile(getPartName, part.ParentItem.Parts, fileName); } part.ParentItem.IsoFileName = fileName; if (part.ParentItem.Callback != null) { Execute.BeginOnThreadPool(() => { part.ParentItem.Callback(part.ParentItem); if (part.ParentItem.Callbacks != null) { foreach (var callback in part.ParentItem.Callbacks) { callback.SafeInvoke(part.ParentItem); } } }); } else { Execute.BeginOnThreadPool(() => _eventAggregator.Publish(part.ParentItem)); } } else { if (part.NotifyProgress) { Execute.BeginOnThreadPool(() => _eventAggregator.Publish(new ProgressChangedEventArgs(part.ParentItem, progress))); } } } }
private void OnDownloading(object state) { DownloadablePart part = null; lock (_itemsSyncRoot) { for (var i = 0; i < _items.Count; i++) { var item = _items[i]; if (item.IsCancelled) { _items.RemoveAt(i--); try { _eventAggregator.Publish(new DownloadingCanceledEventArgs(item)); } catch (Exception e) { TLUtils.WriteException(e); } } } foreach (var item in _items) { part = item.Parts.FirstOrDefault(x => x.Status == PartStatus.Ready); if (part != null) { part.Status = PartStatus.Processing; break; } } } if (part == null) { var currentWorker = (Worker)state; currentWorker.Stop(); return; } TLRPCError error; bool canceled; do { TLUploadFileBase result; if (part.ParentItem.CdnRedirect != null) { result = GetCdnFile(part.ParentItem.CdnRedirect, part.ParentItem.Location, part.Offset, part.Limit, out error, out canceled); } else { result = GetFile(part.ParentItem.Location, part.Offset, part.Limit, out error, out canceled); } if (result is TLUploadFileCdnRedirect redirect) { part.ParentItem.CdnRedirect = redirect; continue; } else { part.File = result as TLUploadFile; } if (canceled) { lock (_itemsSyncRoot) { part.ParentItem.IsCancelled = true; part.Status = PartStatus.Processed; _items.Remove(part.ParentItem); } return; } } while (part.File == null); // indicate progress // indicate complete bool isComplete; bool isCanceled; var progress = 0.0; lock (_itemsSyncRoot) { part.Status = PartStatus.Processed; var data = part.File.Bytes; if (data.Length < part.Limit && (part.Number + 1) != part.ParentItem.Parts.Count) { var complete = part.ParentItem.Parts.All(x => x.Status == PartStatus.Processed); if (!complete) { var emptyBufferSize = part.Limit - data.Length; var position = data.Length; var missingPart = new DownloadablePart(part.ParentItem, position, emptyBufferSize, -part.Number); var currentItemIndex = part.ParentItem.Parts.IndexOf(part); part.ParentItem.Parts.Insert(currentItemIndex + 1, missingPart); } } else if (data.Length == part.Limit && (part.Number + 1) == part.ParentItem.Parts.Count) { var currentItemIndex = part.ParentItem.Parts.IndexOf(part); var missingPart = new DownloadablePart(part.ParentItem, part.Offset + part.Limit, part.Limit, currentItemIndex + 1); part.ParentItem.Parts.Insert(currentItemIndex + 1, missingPart); } isCanceled = part.ParentItem.IsCancelled; isComplete = part.ParentItem.Parts.All(x => x.Status == PartStatus.Processed); if (!isComplete) { var downloadedCount = part.ParentItem.Parts.Count(x => x.Status == PartStatus.Processed); var count = part.ParentItem.Parts.Count; progress = (double)downloadedCount / count; } else { _items.Remove(part.ParentItem); } } if (!isCanceled) { if (isComplete) { byte[] bytes = { }; foreach (var p in part.ParentItem.Parts) { bytes = TLUtils.Combine(bytes, p.File.Bytes); } //part.ParentItem.Location.Buffer = bytes; var fileName = String.Format("{0}_{1}_{2}.jpg", part.ParentItem.Location.VolumeId, part.ParentItem.Location.LocalId, part.ParentItem.Location.Secret); FileUtils.WriteTemporaryBites(fileName, bytes); if (part.ParentItem.Callback != null) { part.ParentItem.Progress.Report(1.0); part.ParentItem.Callback.TrySetResult(part.ParentItem); } else { part.ParentItem.Action?.Invoke(part.ParentItem); Execute.BeginOnThreadPool(() => _eventAggregator.Publish(part.ParentItem)); } _statsService.IncrementReceivedItemsCount(_mtProtoService.NetworkType, _dataType, 1); } else { if (part.ParentItem.Callback != null) { part.ParentItem.Progress.Report(progress); } else { Execute.BeginOnThreadPool(() => _eventAggregator.Publish(new DownloadProgressChangedEventArgs(part.ParentItem, progress))); } } } }
private void OnDownloading(object state) { DownloadablePart part = null; lock (_itemsSyncRoot) { for (var i = 0; i < _items.Count; i++) { var item = _items[i]; if (item.Canceled) { _items.RemoveAt(i--); try { _eventAggregator.Publish(new DownloadingCanceledEventArgs(item)); } catch (Exception e) { TLUtils.WriteException(e); } } } foreach (var item in _items) { part = item.Parts.FirstOrDefault(x => x.Status == PartStatus.Ready); if (part != null) { part.Status = PartStatus.Processing; break; } } } if (part == null) { var currentWorker = (Worker)state; currentWorker.Stop(); return; } bool canceled; ProcessFilePart(part, part.ParentItem.DCId, part.ParentItem.InputLocation, out canceled); if (canceled) { lock (_itemsSyncRoot) { part.ParentItem.Canceled = true; part.Status = PartStatus.Processed; _items.Remove(part.ParentItem); } return; } // indicate progress // indicate complete bool isComplete; bool isCanceled; var progress = 0.0; lock (_itemsSyncRoot) { part.Status = PartStatus.Processed; var data = part.File.Bytes.Data; if (data.Length < part.Limit.Value && (part.Number + 1) != part.ParentItem.Parts.Count) { var complete = part.ParentItem.Parts.All(x => x.Status == PartStatus.Processed); if (!complete) { var emptyBufferSize = part.Limit.Value - data.Length; var position = data.Length; var missingPart = new DownloadablePart(part.ParentItem, new TLInt(position), new TLInt(emptyBufferSize), -part.Number); var currentItemIndex = part.ParentItem.Parts.IndexOf(part); part.ParentItem.Parts.Insert(currentItemIndex + 1, missingPart); } } isCanceled = part.ParentItem.Canceled; isComplete = part.ParentItem.Parts.All(x => x.Status == PartStatus.Processed); if (!isComplete) { var downloadedCount = part.ParentItem.Parts.Count(x => x.Status == PartStatus.Processed); var count = part.ParentItem.Parts.Count; progress = (double)downloadedCount / count; } else { _items.Remove(part.ParentItem); } } if (!isCanceled) { if (isComplete) { byte[] bytes = { }; foreach (var p in part.ParentItem.Parts) { bytes = TLUtils.Combine(bytes, p.File.Bytes.Data); } //part.ParentItem.Location.Buffer = bytes; var fileName = part.ParentItem.FileName.ToString(); StringLocker.Lock(fileName, () => FileUtils.WriteBytes(fileName, bytes)); if (part.ParentItem.Callback != null) { Execute.BeginOnThreadPool(() => { part.ParentItem.Callback.SafeInvoke(part.ParentItem); if (part.ParentItem.Callbacks != null) { foreach (var callback in part.ParentItem.Callbacks) { callback.SafeInvoke(part.ParentItem); } } }); } else { Execute.BeginOnThreadPool(() => _eventAggregator.Publish(part.ParentItem)); } } else { //Execute.BeginOnThreadPool(() => _eventAggregator.Publish(new ProgressChangedEventArgs(part.ParentItem, progress))); } } }
private void OnDownloading(object state) { DownloadablePart part = null; lock (_itemsSyncRoot) { for (var i = 0; i < _items.Count; i++) { var item = _items[i]; if (item.IsCancelled) { _items.RemoveAt(i--); try { _eventAggregator.Publish(new DownloadingCanceledEventArgs(item)); } catch (Exception e) { TLUtils.WriteException(e); } } } foreach (var item in _items) { part = item.Parts.FirstOrDefault(x => x.Status == PartStatus.Ready); if (part != null) { part.Status = PartStatus.Processing; break; } } } if (part == null) { var currentWorker = (Worker)state; currentWorker.Stop(); return; } TLRPCError error; bool canceled; do { TLUploadFileBase result; if (part.ParentItem.CdnRedirect != null) { result = GetCdnFile(part.ParentItem.CdnRedirect, part.ParentItem.Location, part.Offset, part.Limit, out error, out canceled); } else { result = GetFile(part.ParentItem.Location, part.Offset, part.Limit, out error, out canceled); } if (result is TLUploadFileCdnRedirect redirect) { part.ParentItem.CdnRedirect = redirect; part.ParentItem.CdnHashes = redirect.CdnFileHashes.ToDictionary(x => x.Offset, x => x); continue; } else { part.File = result as TLUploadFile; } if (canceled) { lock (_itemsSyncRoot) { part.ParentItem.IsCancelled = true; part.Status = PartStatus.Processed; _items.Remove(part.ParentItem); } return; } } while (part.File == null); // indicate progress // indicate complete bool isComplete; bool isCanceled; var progress = 0.0; lock (_itemsSyncRoot) { part.Status = PartStatus.Processed; var data = part.File.Bytes; if (data.Length < part.Limit && (part.Number + 1) != part.ParentItem.Parts.Count) { var complete = part.ParentItem.Parts.All(x => x.Status == PartStatus.Processed); if (!complete) { var emptyBufferSize = part.Limit - data.Length; var position = data.Length; var missingPart = new DownloadablePart(part.ParentItem, position, emptyBufferSize, -part.Number); var currentItemIndex = part.ParentItem.Parts.IndexOf(part); part.ParentItem.Parts.Insert(currentItemIndex + 1, missingPart); } } else if (data.Length == part.Limit && (part.Number + 1) == part.ParentItem.Parts.Count) { var currentItemIndex = part.ParentItem.Parts.IndexOf(part); var missingPart = new DownloadablePart(part.ParentItem, part.Offset + part.Limit, part.Limit, currentItemIndex + 1); part.ParentItem.Parts.Insert(currentItemIndex + 1, missingPart); } isCanceled = part.ParentItem.IsCancelled; isComplete = part.ParentItem.Parts.All(x => x.Status == PartStatus.Processed); if (!isComplete) { var downloadedCount = part.ParentItem.Parts.Count(x => x.Status == PartStatus.Processed); var count = part.ParentItem.Parts.Count; progress = (double)downloadedCount / count; } else { _items.Remove(part.ParentItem); } } if (!isCanceled) { if (isComplete) { byte[] bytes = { }; foreach (var p in part.ParentItem.Parts) { var partBytes = p.File.Bytes; var redirect = part.ParentItem.CdnRedirect; if (redirect != null) { var iv = redirect.EncryptionIV; var counter = p.Offset / 16; iv[15] = (byte)(counter & 0xFF); iv[14] = (byte)((counter >> 8) & 0xFF); iv[13] = (byte)((counter >> 16) & 0xFF); iv[12] = (byte)((counter >> 24) & 0xFF); var key = CryptographicBuffer.CreateFromByteArray(redirect.EncryptionKey); var ecount_buf = new byte[0]; var num = 0u; partBytes = Utils.AES_ctr128_encrypt(partBytes, key, ref iv, ref ecount_buf, ref num); redirect.EncryptionIV = iv; //TLCdnFileHash hash; //if (!part.ParentItem.CdnHashes.TryGetValue(p.Offset, out hash)) //{ // var hashes = GetCdnFileHashes(redirect, part.ParentItem.Location, p.Offset, out TLRPCError er, out bool yolo); // if (hashes != null) // { // foreach (var item in hashes) // { // part.ParentItem.CdnHashes[item.Offset] = item; // } // part.ParentItem.CdnHashes.TryGetValue(p.Offset, out hash); // } //} //if (hash != null) //{ // var sha256 = Utils.ComputeSHA256(partBytes); // if (!sha256.SequenceEqual(hash.Hash)) // { // lock (_itemsSyncRoot) // { // part.ParentItem.IsCancelled = true; // part.Status = PartStatus.Processed; // _items.Remove(part.ParentItem); // } // Debug.WriteLine("HASH DOESN'T MATCH"); // return; // } //} } bytes = TLUtils.Combine(bytes, partBytes); } //part.ParentItem.Location.Buffer = bytes; var fileName = String.Format("{0}_{1}_{2}.jpg", part.ParentItem.Location.VolumeId, part.ParentItem.Location.LocalId, part.ParentItem.Location.Secret); FileUtils.WriteTemporaryBites(fileName, bytes); if (part.ParentItem.Callback != null) { part.ParentItem.Progress.Report(1.0); part.ParentItem.Callback.TrySetResult(part.ParentItem); } else { part.ParentItem.Action?.Invoke(part.ParentItem); Execute.BeginOnThreadPool(() => _eventAggregator.Publish(part.ParentItem)); } _statsService.IncrementReceivedItemsCount(_protoService.NetworkType, _dataType, 1); } else { if (part.ParentItem.Callback != null) { part.ParentItem.Progress.Report(progress); } else { Execute.BeginOnThreadPool(() => _eventAggregator.Publish(new DownloadProgressChangedEventArgs(part.ParentItem, progress))); } } } }
private void OnDownloading(object state) { DownloadablePart part = null; lock (_itemsSyncRoot) { for (var i = 0; i < _items.Count; i++) { var item = _items[i]; if (item.Canceled) { _items.RemoveAt(i--); try { _eventAggregator.Publish(new DownloadingCanceledEventArgs(item)); } catch (Exception e) { TLUtils.WriteException(e); } } } foreach (var item in _items) { part = item.Parts.FirstOrDefault(x => x.Status == PartStatus.Ready); if (part != null) { part.Status = PartStatus.Processing; break; } } } if (part == null) { var currentWorker = (Worker)state; currentWorker.Stop(); return; } part.File = GetFile(part.ParentItem.Location, part.Offset, part.Limit); while (part.File == null) { part.File = GetFile(part.ParentItem.Location, part.Offset, part.Limit); } part.Status = PartStatus.Processed; var data = part.File.Bytes.Data; if (data.Length < part.Limit.Value && (part.Number + 1) != part.ParentItem.Parts.Count) { lock (_itemsSyncRoot) { var complete = part.ParentItem.Parts.All(x => x.Status == PartStatus.Processed); if (!complete) { var emptyBufferSize = part.Limit.Value - data.Length; var position = data.Length; var missingPart = new DownloadablePart(part.ParentItem, new TLInt(position), new TLInt(emptyBufferSize), -part.Number); var currentItemIndex = part.ParentItem.Parts.IndexOf(part); part.ParentItem.Parts.Insert(currentItemIndex + 1, missingPart); } } } // indicate progress // indicate complete bool isComplete; bool isCanceled; var progress = 0.0; lock (_itemsSyncRoot) { part.Status = PartStatus.Processed; isCanceled = part.ParentItem.Canceled; isComplete = part.ParentItem.Parts.All(x => x.Status == PartStatus.Processed); if (!isComplete) { var downloadedCount = part.ParentItem.Parts.Count(x => x.Status == PartStatus.Processed); var count = part.ParentItem.Parts.Count; progress = downloadedCount / count; } else { _items.Remove(part.ParentItem); } } if (!isCanceled) { if (isComplete) { byte[] bytes = { }; foreach (var p in part.ParentItem.Parts) { bytes = TLUtils.Combine(bytes, p.File.Bytes.Data); } //part.ParentItem.Location.Buffer = bytes; var fileName = String.Format("{0}_{1}_{2}.jpg", part.ParentItem.Location.VolumeId, part.ParentItem.Location.LocalId, part.ParentItem.Location.Secret); FileUtils.WriteBytes(fileName, bytes); _eventAggregator.Publish(part.ParentItem); } else { _eventAggregator.Publish(new ProgressChangedEventArgs(part.ParentItem, progress)); } } }