/* This file is part of OpenSubtitles Handler A library that handle OpenSubtitles.org XML-RPC methods. Copyright © Ala Ibrahim Hadid 2013 This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ using System; using System.Collections.Generic; using System.Text; using System.IO; using System.Threading; using System.Threading.Tasks; using MediaBrowser.Common.Net; using MediaBrowser.Model.Cryptography; using MediaBrowser.Model.Text; namespace OpenSubtitlesHandler { /// /// Include helper methods. All member are statics. /// public sealed class Utilities { public static ICryptoProvider CryptographyProvider { get; set; } public static IHttpClient HttpClient { get; set; } public static ITextEncoding EncodingHelper { get; set; } private static string XML_RPC_SERVER = "https://api.opensubtitles.org/xml-rpc"; //private static string XML_RPC_SERVER = "https://92.240.234.122/xml-rpc"; private static string HostHeader = "api.opensubtitles.org:443"; /// /// Compute movie hash /// /// The hash as Hexadecimal string public static string ComputeHash(Stream stream) { byte[] hash = MovieHasher.ComputeMovieHash(stream); return MovieHasher.ToHexadecimal(hash); } /// /// Decompress data using GZip /// /// The stream that hold the data /// Bytes array of decompressed data public static byte[] Decompress(Stream dataToDecompress) { using (MemoryStream target = new MemoryStream()) { using (System.IO.Compression.GZipStream decompressionStream = new System.IO.Compression.GZipStream(dataToDecompress, System.IO.Compression.CompressionMode.Decompress)) { decompressionStream.CopyTo(target); } return target.ToArray(); } } /// /// Compress data using GZip (the retunred buffer will be WITHOUT HEADER) /// /// The stream that hold the data /// Bytes array of compressed data WITHOUT HEADER bytes public static byte[] Compress(Stream dataToCompress) { /*using (var compressed = new MemoryStream()) { using (var compressor = new System.IO.Compression.GZipStream(compressed, System.IO.Compression.CompressionMode.Compress)) { dataToCompress.CopyTo(compressor); } // Get the compressed bytes only after closing the GZipStream return compressed.ToArray(); }*/ //using (var compressedOutput = new MemoryStream()) //{ // using (var compressedStream = new ZlibStream(compressedOutput, // Ionic.Zlib.CompressionMode.Compress, // CompressionLevel.Default, false)) // { // var buffer = new byte[4096]; // int byteCount; // do // { // byteCount = dataToCompress.Read(buffer, 0, buffer.Length); // if (byteCount > 0) // { // compressedStream.Write(buffer, 0, byteCount); // } // } while (byteCount > 0); // } // return compressedOutput.ToArray(); //} throw new NotImplementedException(); } /// /// Handle server response stream and decode it as given encoding string. /// /// The string of the stream after decode using given encoding public static string GetStreamString(Stream responseStream) { using (responseStream) { // Handle response, should be XML text. List data = new List(); while (true) { int r = responseStream.ReadByte(); if (r < 0) break; data.Add((byte)r); } var bytes = data.ToArray(); return EncodingHelper.GetASCIIEncoding().GetString(bytes, 0, bytes.Length); } } public static byte[] GetASCIIBytes(string text) { return EncodingHelper.GetASCIIEncoding().GetBytes(text); } /// /// Send a request to the server /// /// The request buffer to send as bytes array. /// The user agent value. /// Response of the server or stream of error message as string started with 'ERROR:' keyword. public static Stream SendRequest(byte[] request, string userAgent) { return SendRequestAsync(request, userAgent, CancellationToken.None).Result; } public static async Task SendRequestAsync(byte[] request, string userAgent, CancellationToken cancellationToken) { var options = new HttpRequestOptions { RequestContentBytes = request, RequestContentType = "text/xml", UserAgent = userAgent, Host = HostHeader, Url = XML_RPC_SERVER, // Response parsing will fail with this enabled EnableHttpCompression = false, CancellationToken = cancellationToken, BufferContent = false }; if (string.IsNullOrEmpty(options.UserAgent)) { options.UserAgent = "xmlrpc-epi-php/0.2 (PHP)"; } var result = await HttpClient.Post(options).ConfigureAwait(false); return result.Content; } } }