From 1d6035aeb7ba7060ece2a14a5aa524fa69715160 Mon Sep 17 00:00:00 2001 From: Ilya P Date: Sun, 23 Oct 2016 13:02:44 +0300 Subject: [PATCH] - fix file Uploader - refactor file uploader - added test for file uploading --- TLSharp.Core/Requests/UploadHelper.cs | 214 ++++++++++++++------------ TLSharp.Core/TelegramClient.cs | 48 +++++- TLSharp.Tests/TLSharp.Tests.csproj | 7 +- TLSharp.Tests/TLSharpTests.cs | 50 +++++- 4 files changed, 213 insertions(+), 106 deletions(-) diff --git a/TLSharp.Core/Requests/UploadHelper.cs b/TLSharp.Core/Requests/UploadHelper.cs index 5397e67..f7d14fe 100644 --- a/TLSharp.Core/Requests/UploadHelper.cs +++ b/TLSharp.Core/Requests/UploadHelper.cs @@ -7,112 +7,130 @@ using System.Text; using System.Threading.Tasks; using TeleSharp.TL; using TeleSharp.TL.Upload; +using TLSharp.Core.Utils; + namespace TLSharp.Core.Requests { - public class UploadHelper + public static class UploadHelper { - public static async Task Uploader(string name,StreamReader reader,TelegramClient client) + private static string GetFileHash(byte[] data) { - if (reader.BaseStream.Length < 10 * 1024 * 1024) - return await SmallFileUpload(name, reader, client); + 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) + { + const long tenMb = 10 * 1024 * 1024; + return await UploadFile(name, reader, client, reader.BaseStream.Length >= tenMb); + } + + 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) + { + 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 + { + file_id = file_id, + file_part = partNumber, + bytes = part, + file_total_parts = partsCount + }); + } + else + { + await client.SendRequestAsync(new TLRequestSaveFilePart + { + file_id = file_id, + file_part = partNumber, + bytes = part + }); + } + partNumber++; + } + + if (isBigFileUpload) + { + return new TLInputFileBig + { + id = file_id, + name = name, + parts = partsCount + }; + } else - return await BigFileUpload(name, reader, client); - } - private static async Task SmallFileUpload(string name, StreamReader reader, TelegramClient client) - { - var file = new byte[reader.BaseStream.Length]; - reader.BaseStream.Read(file, 0, (int)reader.BaseStream.Length); - string hash; - using (MD5CryptoServiceProvider md5 = new MD5CryptoServiceProvider()) { - hash = Convert.ToBase64String(md5.ComputeHash(file)); - } - reader = null; - var stream = new MemoryStream(file); - Queue parts = new Queue(); - while (!(stream.Position == stream.Length)) - { - if ((stream.Length - stream.Position) > 512 *1024) + return new TLInputFile { - byte[] temp = new byte[512]; - stream.Read(temp, 0, 512 * 1024); - parts.Enqueue(temp); - } - else - { - byte[] temp = new byte[512]; - stream.Read(temp, 0, (int)(stream.Length - stream.Position)); - parts.Enqueue(temp); - } + id = file_id, + name = name, + parts = partsCount, + md5_checksum = GetFileHash(file) + }; } - stream = null; - int partnumber = 0; - long file_id = BitConverter.ToInt64(RandomByteArray(8), 0); - while (parts.Count != 0) - { - var part = parts.Dequeue(); - TLRequestSaveFilePart save = new TLRequestSaveFilePart(); - save.file_id = file_id; - save.file_part = partnumber; - save.bytes = part; - await client.SendRequestAsync(save); - partnumber++; - } - TLInputFile returnFile = new TLInputFile(); - returnFile.id = file_id; - returnFile.name = name; - returnFile.parts = parts.Count; - returnFile.md5_checksum = hash; - return returnFile; - } - private static async Task BigFileUpload(string name, StreamReader reader, TelegramClient client) - { - var file = new byte[reader.BaseStream.Length]; - reader.BaseStream.Read(file, 0, (int)reader.BaseStream.Length); - reader = null; - var stream = new MemoryStream(file); - Queue parts = new Queue(); - while (!(stream.Position == stream.Length)) - { - if ((stream.Length - stream.Position) > 512 * 1024) - { - byte[] temp = new byte[512]; - stream.Read(temp, 0, 512 * 1024); - parts.Enqueue(temp); - } - else - { - byte[] temp = new byte[512]; - stream.Read(temp, 0, (int)(stream.Length - stream.Position)); - parts.Enqueue(temp); - } - } - stream = null; - int partnumber = 0; - long file_id = BitConverter.ToInt64(RandomByteArray(8), 0); - while (parts.Count != 0) - { - var part = parts.Dequeue(); - TLRequestSaveBigFilePart save = new TLRequestSaveBigFilePart(); - save.file_id = file_id; - save.file_part = partnumber; - save.bytes = part; - save.file_total_parts = parts.Count; - await client.SendRequestAsync(save); - partnumber++; - } - TLInputFileBig returnFile = new TLInputFileBig(); - returnFile.id = file_id; - returnFile.name = name; - returnFile.parts = parts.Count; - return returnFile; - } - private static byte[] RandomByteArray(int count) - { - var temp = new byte[count]; - Random random = new Random(); - random.NextBytes(temp); - return temp; } } } diff --git a/TLSharp.Core/TelegramClient.cs b/TLSharp.Core/TelegramClient.cs index 40eefaf..587c679 100644 --- a/TLSharp.Core/TelegramClient.cs +++ b/TLSharp.Core/TelegramClient.cs @@ -2,6 +2,7 @@ using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; +using System.Web; using TeleSharp.TL; using TeleSharp.TL.Auth; using TeleSharp.TL.Contacts; @@ -10,6 +11,8 @@ using TeleSharp.TL.Messages; using TLSharp.Core.Auth; using TLSharp.Core.MTProto.Crypto; using TLSharp.Core.Network; +using TLSharp.Core.Requests; +using TLSharp.Core.Utils; namespace TLSharp.Core { @@ -53,7 +56,15 @@ namespace TLSharp.Core //set-up layer var config = new TLRequestGetConfig(); - var request = new TLRequestInitConnection() { api_id = _apiId, app_version = "1.0.0", device_model = "PC", lang_code = "en", query = config, system_version = "Win 10.0" }; + var request = new TLRequestInitConnection() + { + api_id = _apiId, + app_version = "1.0.0", + device_model = "PC", + lang_code = "en", + query = config, + system_version = "Win 10.0" + }; var invokewithLayer = new TLRequestInvokeWithLayer() { layer = 57, query = request }; await _sender.Send(invokewithLayer); await _sender.Receive(invokewithLayer); @@ -165,14 +176,12 @@ namespace TLSharp.Core if (!IsUserAuthorized()) throw new InvalidOperationException("Authorize user first!"); - long uniqueId = Convert.ToInt64((DateTime.UtcNow - new DateTime(1970, 1, 1)).TotalMilliseconds); - return await SendRequestAsync( new TLRequestSendMessage() { peer = peer, message = message, - random_id = uniqueId + random_id = Helpers.GenerateRandomLong() }); } @@ -193,6 +202,37 @@ namespace TLSharp.Core new TLRequestGetDialogs() { offset_date = 0, offset_peer = peer, limit = 100 }); } + public async Task SendUploadedPhoto(TLAbsInputPeer peer, TLAbsInputFile file, string caption) + { + return await SendRequestAsync(new TLRequestSendMedia() + { + random_id = Helpers.GenerateRandomLong(), + background = false, + clear_draft = false, + media = new TLInputMediaUploadedPhoto() { file = file, caption = caption }, + peer = peer + }); + } + + public async Task SendUploadedDocument( + TLAbsInputPeer peer, TLAbsInputFile file, string caption, string mimeType, TLVector attributes) + { + return await SendRequestAsync(new TLRequestSendMedia() + { + random_id = Helpers.GenerateRandomLong(), + background = false, + clear_draft = false, + media = new TLInputMediaUploadedDocument() + { + file = file, + caption = caption, + mime_type = mimeType, + attributes = attributes + }, + peer = peer + }); + } + private void OnUserAuthenticated(TLUser TLUser) { _session.TLUser = TLUser; diff --git a/TLSharp.Tests/TLSharp.Tests.csproj b/TLSharp.Tests/TLSharp.Tests.csproj index a30c84a..f215a0c 100644 --- a/TLSharp.Tests/TLSharp.Tests.csproj +++ b/TLSharp.Tests/TLSharp.Tests.csproj @@ -1,4 +1,4 @@ - + Debug @@ -68,6 +68,11 @@ TLSharp.Core + + + Always + + diff --git a/TLSharp.Tests/TLSharpTests.cs b/TLSharp.Tests/TLSharpTests.cs index 59607e4..00f1cc7 100644 --- a/TLSharp.Tests/TLSharpTests.cs +++ b/TLSharp.Tests/TLSharpTests.cs @@ -6,6 +6,7 @@ using System.IO; using System.Linq; using System.Threading; using System.Threading.Tasks; +using System.Web; using Microsoft.VisualStudio.TestTools.UnitTesting; using TeleSharp.TL; using TeleSharp.TL.Channels; @@ -15,6 +16,8 @@ using TLSharp.Core; using TLSharp.Core.Auth; using TLSharp.Core.MTProto; using TLSharp.Core.Network; +using TLSharp.Core.Requests; +using TLSharp.Core.Utils; namespace TLSharp.Tests { @@ -37,7 +40,7 @@ namespace TLSharp.Tests private int apiId = 0; - [TestInitialize] + [TestInitialize] public void Init() { // Setup your phone numbers in app.config @@ -117,7 +120,49 @@ namespace TLSharp.Tests await client.SendMessageAsync(new TLInputPeerChannel() { channel_id = chat.id, access_hash = chat.access_hash.Value }, "TEST MSG"); } - [TestMethod] + [TestMethod] + public async Task SendPhotoToContactTest() + { + var client = new TelegramClient(apiId, apiHash); + + await client.ConnectAsync(); + + var result = await client.GetContactsAsync(); + + var user = result.users.lists + .Where(x => x.GetType() == typeof(TLUser)) + .Cast() + .FirstOrDefault(x => x.phone == NumberToSendMessage); + + var fileResult = (TLInputFile)await client.UploadFile("cat.jpg", new StreamReader("data/cat.jpg")); + await client.SendUploadedPhoto(new TLInputPeerUser() {user_id = user.id}, fileResult, "kitty"); + } + + [TestMethod] + public async Task SendBigFileToContactTest() + { + var client = new TelegramClient(apiId, apiHash); + + await client.ConnectAsync(); + + var result = await client.GetContactsAsync(); + + var user = result.users.lists + .Where(x => x.GetType() == typeof(TLUser)) + .Cast() + .FirstOrDefault(x => x.phone == NumberToSendMessage); + + var fileResult = (TLInputFileBig)await client.UploadFile("some.zip", new StreamReader("C:\\PetProjects\\TelegramBotSample.zip")); + + await client.SendUploadedDocument( + new TLInputPeerUser() {user_id = user.id}, + fileResult, + "some zips", + "application/zip", + new TLVector()); + } + + [TestMethod] public async Task SignUpNewUser() { var client = new TelegramClient(apiId, apiHash); @@ -143,6 +188,5 @@ namespace TLSharp.Tests var result = await client.IsPhoneRegisteredAsync(NumberToAuthenticate); Assert.IsTrue(result); } - } }