diff options
Diffstat (limited to 'OpenSubtitlesHandler')
| -rw-r--r-- | OpenSubtitlesHandler/Interfaces/IMethodResponse.cs | 30 | ||||
| -rw-r--r-- | OpenSubtitlesHandler/MovieHasher.cs | 42 | ||||
| -rw-r--r-- | OpenSubtitlesHandler/OpenSubtitlesHandler.csproj | 23 | ||||
| -rw-r--r-- | OpenSubtitlesHandler/OpenSubtitlesHandler.nuget.targets | 6 | ||||
| -rw-r--r-- | OpenSubtitlesHandler/Utilities.cs | 78 | ||||
| -rw-r--r-- | OpenSubtitlesHandler/XML-RPC/XmlRpcGenerator.cs | 126 | ||||
| -rw-r--r-- | OpenSubtitlesHandler/project.json | 17 |
7 files changed, 180 insertions, 142 deletions
diff --git a/OpenSubtitlesHandler/Interfaces/IMethodResponse.cs b/OpenSubtitlesHandler/Interfaces/IMethodResponse.cs index b8e24f12b..9c05e357b 100644 --- a/OpenSubtitlesHandler/Interfaces/IMethodResponse.cs +++ b/OpenSubtitlesHandler/Interfaces/IMethodResponse.cs @@ -37,17 +37,17 @@ namespace OpenSubtitlesHandler protected double seconds; protected string status; - protected virtual void LoadAttributes() + protected void LoadAttributes() { - foreach (Attribute attr in Attribute.GetCustomAttributes(this.GetType())) - { - if (attr.GetType() == typeof(MethodResponseDescription)) - { - this.name = ((MethodResponseDescription)attr).Name; - this.message = ((MethodResponseDescription)attr).Message; - break; - } - } + //foreach (Attribute attr in Attribute.GetCustomAttributes(this.GetType())) + //{ + // if (attr.GetType() == typeof(MethodResponseDescription)) + // { + // this.name = ((MethodResponseDescription)attr).Name; + // this.message = ((MethodResponseDescription)attr).Message; + // break; + // } + //} } [Description("The name of this response"), Category("MethodResponse")] @@ -59,4 +59,14 @@ namespace OpenSubtitlesHandler [Description("The status"), Category("MethodResponse")] public string Status { get { return status; } set { status = value; } } } + + public class DescriptionAttribute : Attribute + { + public DescriptionAttribute(string text) { } + } + + public class CategoryAttribute : Attribute + { + public CategoryAttribute(string text) { } + } } diff --git a/OpenSubtitlesHandler/MovieHasher.cs b/OpenSubtitlesHandler/MovieHasher.cs index 89301191f..57be9ab28 100644 --- a/OpenSubtitlesHandler/MovieHasher.cs +++ b/OpenSubtitlesHandler/MovieHasher.cs @@ -8,29 +8,31 @@ namespace OpenSubtitlesHandler { public static byte[] ComputeMovieHash(Stream input) { - long lhash, streamsize; - streamsize = input.Length; - lhash = streamsize; - - long i = 0; - byte[] buffer = new byte[sizeof(long)]; - while (i < 65536 / sizeof(long) && (input.Read(buffer, 0, sizeof(long)) > 0)) + using (input) { - i++; - lhash += BitConverter.ToInt64(buffer, 0); - } + long lhash, streamsize; + streamsize = input.Length; + lhash = streamsize; - input.Position = Math.Max(0, streamsize - 65536); - i = 0; - while (i < 65536 / sizeof(long) && (input.Read(buffer, 0, sizeof(long)) > 0)) - { - i++; - lhash += BitConverter.ToInt64(buffer, 0); + long i = 0; + byte[] buffer = new byte[sizeof(long)]; + while (i < 65536 / sizeof(long) && (input.Read(buffer, 0, sizeof(long)) > 0)) + { + i++; + lhash += BitConverter.ToInt64(buffer, 0); + } + + input.Position = Math.Max(0, streamsize - 65536); + i = 0; + while (i < 65536 / sizeof(long) && (input.Read(buffer, 0, sizeof(long)) > 0)) + { + i++; + lhash += BitConverter.ToInt64(buffer, 0); + } + byte[] result = BitConverter.GetBytes(lhash); + Array.Reverse(result); + return result; } - input.Close(); - byte[] result = BitConverter.GetBytes(lhash); - Array.Reverse(result); - return result; } public static string ToHexadecimal(byte[] bytes) diff --git a/OpenSubtitlesHandler/OpenSubtitlesHandler.csproj b/OpenSubtitlesHandler/OpenSubtitlesHandler.csproj index 683c166dc..54e14e3e3 100644 --- a/OpenSubtitlesHandler/OpenSubtitlesHandler.csproj +++ b/OpenSubtitlesHandler/OpenSubtitlesHandler.csproj @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="utf-8"?> -<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> +<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" /> <PropertyGroup> <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration> @@ -9,9 +9,12 @@ <AppDesignerFolder>Properties</AppDesignerFolder> <RootNamespace>OpenSubtitlesHandler</RootNamespace> <AssemblyName>OpenSubtitlesHandler</AssemblyName> - <TargetFrameworkVersion>v4.5</TargetFrameworkVersion> <FileAlignment>512</FileAlignment> <SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\</SolutionDir> + <ProjectTypeGuids>{786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids> + <TargetFrameworkProfile>Profile7</TargetFrameworkProfile> + <TargetFrameworkVersion>v4.5</TargetFrameworkVersion> + <MinimumVisualStudioVersion>11.0</MinimumVisualStudioVersion> </PropertyGroup> <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' "> <DebugSymbols>true</DebugSymbols> @@ -36,15 +39,6 @@ <WarningLevel>4</WarningLevel> </PropertyGroup> <ItemGroup> - <Reference Include="System" /> - <Reference Include="System.Core" /> - <Reference Include="System.Xml.Linq" /> - <Reference Include="System.Data.DataSetExtensions" /> - <Reference Include="Microsoft.CSharp" /> - <Reference Include="System.Data" /> - <Reference Include="System.Xml" /> - </ItemGroup> - <ItemGroup> <Compile Include="Console\OSHConsole.cs" /> <Compile Include="Interfaces\IMethodResponse.cs" /> <Compile Include="Interfaces\MethodResponseAttr.cs" /> @@ -118,7 +112,10 @@ <ItemGroup> <Content Include="XML-RPC\Docs\XML-RPC.txt" /> </ItemGroup> - <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" /> + <ItemGroup> + <None Include="project.json" /> + </ItemGroup> + <Import Project="$(MSBuildExtensionsPath32)\Microsoft\Portable\$(TargetFrameworkVersion)\Microsoft.Portable.CSharp.targets" /> <!-- To modify your build process, add your task inside one of the targets below and uncomment it. Other similar extension points exist, see Microsoft.Common.targets. <Target Name="BeforeBuild"> @@ -126,4 +123,4 @@ <Target Name="AfterBuild"> </Target> --> -</Project> +</Project>
\ No newline at end of file diff --git a/OpenSubtitlesHandler/OpenSubtitlesHandler.nuget.targets b/OpenSubtitlesHandler/OpenSubtitlesHandler.nuget.targets new file mode 100644 index 000000000..e69ce0e64 --- /dev/null +++ b/OpenSubtitlesHandler/OpenSubtitlesHandler.nuget.targets @@ -0,0 +1,6 @@ +<?xml version="1.0" encoding="utf-8" standalone="no"?> +<Project ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <Target Name="EmitMSBuildWarning" BeforeTargets="Build"> + <Warning Text="Packages containing MSBuild targets and props files cannot be fully installed in projects targeting multiple frameworks. The MSBuild targets and props files have been ignored." /> + </Target> +</Project>
\ No newline at end of file diff --git a/OpenSubtitlesHandler/Utilities.cs b/OpenSubtitlesHandler/Utilities.cs index 9a90462f6..3fe606c78 100644 --- a/OpenSubtitlesHandler/Utilities.cs +++ b/OpenSubtitlesHandler/Utilities.cs @@ -20,10 +20,11 @@ using System; using System.Collections.Generic; using System.Text; using System.IO; -using System.Security.Cryptography; using System.Threading; using System.Threading.Tasks; using MediaBrowser.Common.Net; +using MediaBrowser.Model.Cryptography; +using MediaBrowser.Model.Text; namespace OpenSubtitlesHandler { @@ -32,50 +33,36 @@ namespace OpenSubtitlesHandler /// </summary> public sealed class Utilities { + public static ICryptoProvider CryptographyProvider { get; set; } + public static IHttpClient HttpClient { get; set; } + public static ITextEncoding EncodingHelper { get; set; } + private const string XML_RPC_SERVER = "https://api.opensubtitles.org/xml-rpc"; /// <summary> /// Compute movie hash /// </summary> - /// <param name="fileName">The complete media file path</param> /// <returns>The hash as Hexadecimal string</returns> - public static string ComputeHash(string fileName) + public static string ComputeHash(Stream stream) { - byte[] hash = MovieHasher.ComputeMovieHash(File.OpenRead(fileName)); + byte[] hash = MovieHasher.ComputeMovieHash(stream); return MovieHasher.ToHexadecimal(hash); } /// <summary> - /// Compute md5 for a file - /// </summary> - /// <param name="filename">The complete file path</param> - /// <returns>MD5 of the file</returns> - public static string ComputeMd5(string filename) - { - var md5 = MD5.Create(); - var sb = new StringBuilder(); - Stream str = new FileStream(filename, FileMode.Open, FileAccess.Read); - - foreach (var b in md5.ComputeHash(str)) - sb.Append(b.ToString("x2").ToLower()); - str.Close(); - return sb.ToString(); - } - /// <summary> /// Decompress data using GZip /// </summary> /// <param name="dataToDecompress">The stream that hold the data</param> /// <returns>Bytes array of decompressed data</returns> public static byte[] Decompress(Stream dataToDecompress) { - MemoryStream target = new MemoryStream(); - - using (System.IO.Compression.GZipStream decompressionStream = new System.IO.Compression.GZipStream(dataToDecompress, - System.IO.Compression.CompressionMode.Decompress)) + using (MemoryStream target = new MemoryStream()) { - decompressionStream.CopyTo(target); + using (System.IO.Compression.GZipStream decompressionStream = new System.IO.Compression.GZipStream(dataToDecompress, System.IO.Compression.CompressionMode.Decompress)) + { + decompressionStream.CopyTo(target); + } + return target.ToArray(); } - return target.GetBuffer(); - } /// <summary> @@ -122,35 +109,30 @@ namespace OpenSubtitlesHandler /// <summary> /// Handle server response stream and decode it as given encoding string. /// </summary> - /// <param name="responseStream">The response stream. Expects a stream that doesn't support seek.</param> - /// <param name="encoding">The encoding that should be used to decode buffer</param> /// <returns>The string of the stream after decode using given encoding</returns> - public static string GetStreamString(Stream responseStream, Encoding encoding) + public static string GetStreamString(Stream responseStream) { - // Handle response, should be XML text. - List<byte> data = new List<byte>(); - while (true) + using (responseStream) { - int r = responseStream.ReadByte(); - if (r < 0) - break; - data.Add((byte)r); + // Handle response, should be XML text. + List<byte> data = new List<byte>(); + 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); } - responseStream.Close(); - return encoding.GetString(data.ToArray()); } - /// <summary> - /// Handle server response stream and decode it as ASCII encoding string. - /// </summary> - /// <param name="responseStream">The response stream. Expects a stream that doesn't support seek.</param> - /// <returns>The string of the stream after decode using ASCII encoding</returns> - public static string GetStreamString(Stream responseStream) + + public static byte[] GetASCIIBytes(string text) { - return GetStreamString(responseStream, Encoding.ASCII); + return EncodingHelper.GetASCIIEncoding().GetBytes(text); } - public static IHttpClient HttpClient { get; set; } - /// <summary> /// Send a request to the server /// </summary> diff --git a/OpenSubtitlesHandler/XML-RPC/XmlRpcGenerator.cs b/OpenSubtitlesHandler/XML-RPC/XmlRpcGenerator.cs index c39917e29..06fc945a8 100644 --- a/OpenSubtitlesHandler/XML-RPC/XmlRpcGenerator.cs +++ b/OpenSubtitlesHandler/XML-RPC/XmlRpcGenerator.cs @@ -22,6 +22,8 @@ using System.Text; using System.Collections.Generic; using System.IO; using System.Xml; +using OpenSubtitlesHandler; + namespace XmlRpcHandler { /// <summary> @@ -55,40 +57,41 @@ namespace XmlRpcHandler using (var ms = new MemoryStream()) { - XmlWriter XMLwrt = XmlWriter.Create(ms, sett); - // Let's write the methods - foreach (XmlRpcMethodCall method in methods) + using (XmlWriter XMLwrt = XmlWriter.Create(ms, sett)) { - XMLwrt.WriteStartElement("methodCall");//methodCall - XMLwrt.WriteStartElement("methodName");//methodName - XMLwrt.WriteString(method.Name); - XMLwrt.WriteEndElement();//methodName - XMLwrt.WriteStartElement("params");//params - // Write values - foreach (IXmlRpcValue p in method.Parameters) + // Let's write the methods + foreach (XmlRpcMethodCall method in methods) { - XMLwrt.WriteStartElement("param");//param - if (p is XmlRpcValueBasic) - { - WriteBasicValue(XMLwrt, (XmlRpcValueBasic)p); - } - else if (p is XmlRpcValueStruct) - { - WriteStructValue(XMLwrt, (XmlRpcValueStruct)p); - } - else if (p is XmlRpcValueArray) + XMLwrt.WriteStartElement("methodCall");//methodCall + XMLwrt.WriteStartElement("methodName");//methodName + XMLwrt.WriteString(method.Name); + XMLwrt.WriteEndElement();//methodName + XMLwrt.WriteStartElement("params");//params + // Write values + foreach (IXmlRpcValue p in method.Parameters) { - WriteArrayValue(XMLwrt, (XmlRpcValueArray)p); + XMLwrt.WriteStartElement("param");//param + if (p is XmlRpcValueBasic) + { + WriteBasicValue(XMLwrt, (XmlRpcValueBasic)p); + } + else if (p is XmlRpcValueStruct) + { + WriteStructValue(XMLwrt, (XmlRpcValueStruct)p); + } + else if (p is XmlRpcValueArray) + { + WriteArrayValue(XMLwrt, (XmlRpcValueArray)p); + } + XMLwrt.WriteEndElement();//param } - XMLwrt.WriteEndElement();//param - } - XMLwrt.WriteEndElement();//params - XMLwrt.WriteEndElement();//methodCall + XMLwrt.WriteEndElement();//params + XMLwrt.WriteEndElement();//methodCall + } + XMLwrt.Flush(); + return ms.ToArray(); } - XMLwrt.Flush(); - XMLwrt.Close(); - return ms.ToArray(); } } /// <summary> @@ -102,27 +105,34 @@ namespace XmlRpcHandler XmlReaderSettings sett = new XmlReaderSettings(); sett.DtdProcessing = DtdProcessing.Ignore; sett.IgnoreWhitespace = true; - MemoryStream str = new MemoryStream(Encoding.ASCII.GetBytes(xmlResponse)); + MemoryStream str; if (xmlResponse.Contains(@"encoding=""utf-8""")) { str = new MemoryStream(Encoding.UTF8.GetBytes(xmlResponse)); } - XmlReader XMLread = XmlReader.Create(str, sett); - - XmlRpcMethodCall call = new XmlRpcMethodCall("methodResponse"); - // Read parameters - while (XMLread.Read()) + else { - if (XMLread.Name == "param" && XMLread.IsStartElement()) + str = new MemoryStream(Utilities.GetASCIIBytes(xmlResponse)); + } + using (str) + { + using (XmlReader XMLread = XmlReader.Create(str, sett)) { - IXmlRpcValue val = ReadValue(XMLread); - if (val != null) - call.Parameters.Add(val); + XmlRpcMethodCall call = new XmlRpcMethodCall("methodResponse"); + // Read parameters + while (XMLread.Read()) + { + if (XMLread.Name == "param" && XMLread.IsStartElement()) + { + IXmlRpcValue val = ReadValue(XMLread); + if (val != null) + call.Parameters.Add(val); + } + } + methods.Add(call); + return methods.ToArray(); } } - methods.Add(call); - XMLread.Close(); - return methods.ToArray(); } private static void WriteBasicValue(XmlWriter XMLwrt, XmlRpcValueBasic val) @@ -231,33 +241,42 @@ namespace XmlRpcHandler XMLwrt.WriteEndElement();//value } private static readonly CultureInfo UsCulture = new CultureInfo("en-US"); + + private static string ReadString(XmlReader reader) + { + if (reader.NodeType == XmlNodeType.Element) + { + return reader.ReadElementContentAsString(); + } + return reader.ReadContentAsString(); + } - private static IXmlRpcValue ReadValue(XmlReader xmlReader) + private static IXmlRpcValue ReadValue(XmlReader xmlReader, bool skipRead = false) { - while (xmlReader.Read()) + while (skipRead || xmlReader.Read()) { if (xmlReader.Name == "value" && xmlReader.IsStartElement()) { xmlReader.Read(); if (xmlReader.Name == "string" && xmlReader.IsStartElement()) { - return new XmlRpcValueBasic(xmlReader.ReadString(), XmlRpcBasicValueType.String); + return new XmlRpcValueBasic(ReadString(xmlReader), XmlRpcBasicValueType.String); } else if (xmlReader.Name == "int" && xmlReader.IsStartElement()) { - return new XmlRpcValueBasic(int.Parse(xmlReader.ReadString(), UsCulture), XmlRpcBasicValueType.Int); + return new XmlRpcValueBasic(int.Parse(ReadString(xmlReader), UsCulture), XmlRpcBasicValueType.Int); } else if (xmlReader.Name == "boolean" && xmlReader.IsStartElement()) { - return new XmlRpcValueBasic(xmlReader.ReadString() == "1", XmlRpcBasicValueType.Boolean); + return new XmlRpcValueBasic(ReadString(xmlReader) == "1", XmlRpcBasicValueType.Boolean); } else if (xmlReader.Name == "double" && xmlReader.IsStartElement()) { - return new XmlRpcValueBasic(double.Parse(xmlReader.ReadString(), UsCulture), XmlRpcBasicValueType.Double); + return new XmlRpcValueBasic(double.Parse(ReadString(xmlReader), UsCulture), XmlRpcBasicValueType.Double); } else if (xmlReader.Name == "dateTime.iso8601" && xmlReader.IsStartElement()) { - string date = xmlReader.ReadString(); + string date = ReadString(xmlReader); int year = int.Parse(date.Substring(0, 4), UsCulture); int month = int.Parse(date.Substring(4, 2), UsCulture); int day = int.Parse(date.Substring(6, 2), UsCulture); @@ -269,7 +288,7 @@ namespace XmlRpcHandler } else if (xmlReader.Name == "base64" && xmlReader.IsStartElement()) { - return new XmlRpcValueBasic(BitConverter.ToInt64(Convert.FromBase64String(xmlReader.ReadString()), 0) + return new XmlRpcValueBasic(BitConverter.ToInt64(Convert.FromBase64String(ReadString(xmlReader)), 0) , XmlRpcBasicValueType.Double); } else if (xmlReader.Name == "struct" && xmlReader.IsStartElement()) @@ -282,9 +301,9 @@ namespace XmlRpcHandler { XmlRpcStructMember member = new XmlRpcStructMember("", null); xmlReader.Read();// read name - member.Name = xmlReader.ReadString(); + member.Name = ReadString(xmlReader); - IXmlRpcValue val = ReadValue(xmlReader); + IXmlRpcValue val = ReadValue(xmlReader, true); if (val != null) { member.Data = val; @@ -319,6 +338,11 @@ namespace XmlRpcHandler } } else break; + + if (skipRead) + { + return null; + } } return null; } diff --git a/OpenSubtitlesHandler/project.json b/OpenSubtitlesHandler/project.json new file mode 100644 index 000000000..fbbe9eaf3 --- /dev/null +++ b/OpenSubtitlesHandler/project.json @@ -0,0 +1,17 @@ +{ + "frameworks":{ + "netstandard1.6":{ + "dependencies":{ + "NETStandard.Library":"1.6.0", + } + }, + ".NETPortable,Version=v4.5,Profile=Profile7":{ + "buildOptions": { + "define": [ ] + }, + "frameworkAssemblies":{ + + } + } + } +}
\ No newline at end of file |
