using System; using System.Collections.Generic; using System.IO; using System.Security.Cryptography; using System.Text; using System.Threading; using System.Threading.Tasks; using TeleSharp.TL; using TeleSharp.TL.Upload; namespace TLSharp.Core.Utils { public static class UploadHelper { private static string GetFileHash(byte[] data) { string md5_checksum; using (var md5 = MD5.Create()) { var hash = md5.ComputeHash(data); var hashResult = new StringBuilder(hash.Length * 2); foreach (byte t in hash) hashResult.Append(t.ToString("x2")); md5_checksum = hashResult.ToString(); } return md5_checksum; } public static async Task UploadFile(this TelegramClient client, string name, StreamReader reader) { return await UploadFile(client, name, reader, CancellationToken.None).ConfigureAwait(false); } public static async Task UploadFile(this TelegramClient client, string name, StreamReader reader, CancellationToken token) { const long tenMb = 10 * 1024 * 1024; return await UploadFile(name, reader, client, reader.BaseStream.Length >= tenMb, token).ConfigureAwait(false); } private static byte[] GetFile(StreamReader reader) { var file = new byte[reader.BaseStream.Length]; using (reader) { reader.BaseStream.Read(file, 0, (int)reader.BaseStream.Length); } return file; } private static Queue GetFileParts(byte[] file) { var fileParts = new Queue(); const int maxFilePart = 512 * 1024; using (var stream = new MemoryStream(file)) { while (stream.Position != stream.Length) { if ((stream.Length - stream.Position) > maxFilePart) { var temp = new byte[maxFilePart]; stream.Read(temp, 0, maxFilePart); fileParts.Enqueue(temp); } else { var length = stream.Length - stream.Position; var temp = new byte[length]; stream.Read(temp, 0, (int)(length)); fileParts.Enqueue(temp); } } } return fileParts; } private static async Task UploadFile(string name, StreamReader reader, TelegramClient client, bool isBigFileUpload, CancellationToken token) { token.ThrowIfCancellationRequested(); var file = GetFile(reader); var fileParts = GetFileParts(file); int partNumber = 0; int partsCount = fileParts.Count; long file_id = BitConverter.ToInt64(Helpers.GenerateRandomBytes(8), 0); while (fileParts.Count != 0) { var part = fileParts.Dequeue(); if (isBigFileUpload) { await client.SendRequestAsync(new TLRequestSaveBigFilePart { FileId = file_id, FilePart = partNumber, Bytes = part, FileTotalParts = partsCount }, token).ConfigureAwait(false); } else { await client.SendRequestAsync(new TLRequestSaveFilePart { FileId = file_id, FilePart = partNumber, Bytes = part }, token).ConfigureAwait(false); } partNumber++; } if (isBigFileUpload) { return new TLInputFileBig { Id = file_id, Name = name, Parts = partsCount }; } return new TLInputFile { Id = file_id, Name = name, Parts = partsCount, Md5Checksum = GetFileHash(file) }; } } }