using System; using System.Collections; using System.Collections.Generic; using System.IO; using System.Net.Http; using System.Security.Cryptography; using System.Threading; using System.Threading.Tasks; using System.Web; using Newtonsoft.Json; namespace Tesses.CMS.Client { public class TessesCMSClient { private static HttpClient CreateHttpClient() { HttpClientHandler httpClientHandler=new HttpClientHandler(); httpClientHandler.AllowAutoRedirect=true; httpClientHandler.UseCookies=true; HttpClient client=new HttpClient(httpClientHandler); return client; } internal HttpClient client; internal string rooturl; public HttpClient Client => client; public string RootUrl => $"{rooturl}/"; public TessesCMSClient(string url,HttpClient client) { this.client = client; rooturl = url.TrimEnd('/'); } public TessesCMSClient(HttpClient client) : this("https://tessesstudios.com/",client) { } public TessesCMSClient(string url) : this(url,CreateHttpClient()) { } public TessesCMSClient() : this(CreateHttpClient()) { } public async Task DownloadFileAsync(string url,string dest,CancellationToken token=default,IProgress progress=null) { using(var f = File.Create(dest)) await DownloadFileAsync(url,f,token,progress); } public async Task DownloadFileAsync(string url,Stream dest,CancellationToken token=default,IProgress progress=null) { long offset=0; long total=0; if(dest.CanSeek) { offset=dest.Length; dest.Seek(offset,SeekOrigin.Begin); } HttpRequestMessage message=new HttpRequestMessage(HttpMethod.Get,url); if(offset > 0) { message.Headers.Range=new System.Net.Http.Headers.RangeHeaderValue(offset,null); } var resp=await client.SendAsync(message); if(resp.StatusCode == System.Net.HttpStatusCode.RequestedRangeNotSatisfiable) return; resp.EnsureSuccessStatusCode(); total = resp.StatusCode == System.Net.HttpStatusCode.PartialContent ? resp.Content.Headers.ContentLength.GetValueOrDefault() + offset : resp.Content.Headers.ContentLength.GetValueOrDefault(); int read=0; byte[] buffer=new byte[1024]; using(var srcStrm = await resp.Content.ReadAsStreamAsync()) do { if(token.IsCancellationRequested) return; read = await srcStrm.ReadAsync(buffer,0,buffer.Length,token); if(token.IsCancellationRequested) return; await dest.WriteAsync(buffer,0,read,token); offset += read; if(total > 0) progress?.Report((double)offset / (double)read); } while(read>0); resp.Dispose(); } public MovieClient Movies => new MovieClient(this); public UserClient Users => new UserClient(this); } public class UserClient { TessesCMSClient client; internal UserClient(TessesCMSClient client) { this.client = client; } public async Task LogoutAsync() { await client.client.GetStringAsync($"{client.rooturl}/logout"); } public async Task LoginAsync(string email,string password) { Dictionary us=new Dictionary(); us.Add("email",email); us.Add("password",password); using(var res=await client.client.PostAsync($"{client.rooturl}/login", new FormUrlEncodedContent(us))) return res.StatusCode != System.Net.HttpStatusCode.Unauthorized; } } public class MovieClient { TessesCMSClient client; internal MovieClient(TessesCMSClient client) { this.client = client; } public async IAsyncEnumerable GetMoviesAsync(string user) { foreach(var item in JsonConvert.DeserializeObject>(await client.client.GetStringAsync($"{client.rooturl}/api/v1/GetMovies?user={HttpUtility.UrlDecode(user)}"))) { yield return item; } } public async Task GetMovieContentMetadataAsync(string user,string movie) { return JsonConvert.DeserializeObject(await client.client.GetStringAsync($"{client.rooturl.TrimEnd('/')}/api/v1/MovieFile?movie={movie}&user={user}&type=json")); } public async Task DownloadMovieAsync(string user,string movie,string dest,CancellationToken token=default,IProgress progress=null) { await client.DownloadFileAsync($"{client.rooturl.TrimEnd('/')}/content/{user}/movie/{movie}/{movie}.mp4",dest,token,progress); } public async Task DownloadMovieAsync(string user,string movie,Stream dest,CancellationToken token=default,IProgress progress=null) { await client.DownloadFileAsync($"{client.rooturl.TrimEnd('/')}/content/{user}/movie/{movie}/{movie}.mp4",dest,token,progress); } } }