diff --git a/src/NzbDrone.Core.Test/ParserTests/ParseUtilFixture.cs b/src/NzbDrone.Core.Test/ParserTests/ParseUtilFixture.cs new file mode 100644 index 000000000..88ad41303 --- /dev/null +++ b/src/NzbDrone.Core.Test/ParserTests/ParseUtilFixture.cs @@ -0,0 +1,24 @@ +using FluentAssertions; +using NUnit.Framework; +using NzbDrone.Core.Parser; +using NzbDrone.Core.Test.Framework; + +namespace NzbDrone.Core.Test.ParserTests +{ + [TestFixture] + public class ParseUtilFixture : CoreTest + { + [TestCase("1023.4 KB", 1047961)] + [TestCase("1023.4 MB", 1073112704)] + [TestCase("1,023.4 MB", 1073112704)] + [TestCase("1.023,4 MB", 1073112704)] + [TestCase("1 023,4 MB", 1073112704)] + [TestCase("1.023.4 MB", 1073112704)] + [TestCase("1023.4 GB", 1098867408896)] + [TestCase("1023.4 TB", 1125240226709504)] + public void should_parse_size(string stringSize, long size) + { + ParseUtil.GetBytes(stringSize).Should().Be(size); + } + } +} diff --git a/src/NzbDrone.Core/Indexers/Definitions/Anidub.cs b/src/NzbDrone.Core/Indexers/Definitions/Anidub.cs index 8905fddb4..d656f9ce4 100644 --- a/src/NzbDrone.Core/Indexers/Definitions/Anidub.cs +++ b/src/NzbDrone.Core/Indexers/Definitions/Anidub.cs @@ -405,7 +405,7 @@ namespace NzbDrone.Core.Indexers.Definitions const string SizeSelector = ".list.down > .red"; var sizeStr = tabNode.QuerySelector(SizeSelector).TextContent; - return ReleaseInfo.GetBytes(sizeStr); + return ParseUtil.GetBytes(sizeStr); } private string GetReleaseLink(AngleSharp.Dom.IElement tabNode) diff --git a/src/NzbDrone.Core/Indexers/Definitions/AnimeTorrents.cs b/src/NzbDrone.Core/Indexers/Definitions/AnimeTorrents.cs index 600205049..0e0b59de6 100644 --- a/src/NzbDrone.Core/Indexers/Definitions/AnimeTorrents.cs +++ b/src/NzbDrone.Core/Indexers/Definitions/AnimeTorrents.cs @@ -276,7 +276,7 @@ namespace NzbDrone.Core.Indexers.Definitions } var sizeStr = row.QuerySelector("td:nth-of-type(6)").TextContent; - release.Size = ReleaseInfo.GetBytes(sizeStr); + release.Size = ParseUtil.GetBytes(sizeStr); var connections = row.QuerySelector("td:nth-of-type(8)").TextContent.Trim().Split("/".ToCharArray(), StringSplitOptions.RemoveEmptyEntries); diff --git a/src/NzbDrone.Core/Indexers/Definitions/Animedia.cs b/src/NzbDrone.Core/Indexers/Definitions/Animedia.cs index 855c6dade..cb4980a5d 100644 --- a/src/NzbDrone.Core/Indexers/Definitions/Animedia.cs +++ b/src/NzbDrone.Core/Indexers/Definitions/Animedia.cs @@ -210,7 +210,7 @@ namespace NzbDrone.Core.Indexers.Definitions private long getReleaseSize(AngleSharp.Dom.IElement tr) { var sizeStr = tr.QuerySelector("div.tracker_info_left").TextContent; - return ReleaseInfo.GetBytes(SizeInfoQueryRegex.Match(sizeStr).Groups[1].Value.Trim()); + return ParseUtil.GetBytes(SizeInfoQueryRegex.Match(sizeStr).Groups[1].Value.Trim()); } private DateTime getReleaseDate(AngleSharp.Dom.IElement tr) diff --git a/src/NzbDrone.Core/Indexers/Definitions/Anthelion.cs b/src/NzbDrone.Core/Indexers/Definitions/Anthelion.cs index 80189259b..b52b49a14 100644 --- a/src/NzbDrone.Core/Indexers/Definitions/Anthelion.cs +++ b/src/NzbDrone.Core/Indexers/Definitions/Anthelion.cs @@ -242,7 +242,7 @@ namespace NzbDrone.Core.Indexers.Definitions var files = ParseUtil.CoerceInt(row.QuerySelector("td:nth-child(3)").TextContent); var publishDate = DateTimeUtil.FromTimeAgo(row.QuerySelector("td:nth-child(4)").TextContent); - var size = ReleaseInfo.GetBytes(row.QuerySelector("td:nth-child(5)").FirstChild.TextContent); + var size = ParseUtil.GetBytes(row.QuerySelector("td:nth-child(5)").FirstChild.TextContent); var grabs = ParseUtil.CoerceInt(row.QuerySelector("td:nth-child(6)").TextContent); var seeders = ParseUtil.CoerceInt(row.QuerySelector("td:nth-child(7)").TextContent); var leechers = ParseUtil.CoerceInt(row.QuerySelector("td:nth-child(8)").TextContent); diff --git a/src/NzbDrone.Core/Indexers/Definitions/BB.cs b/src/NzbDrone.Core/Indexers/Definitions/BB.cs index 5934fd4d3..ac722626c 100644 --- a/src/NzbDrone.Core/Indexers/Definitions/BB.cs +++ b/src/NzbDrone.Core/Indexers/Definitions/BB.cs @@ -279,7 +279,7 @@ namespace NzbDrone.Core.Indexers.Definitions release.PublishDate = DateTimeUtil.FromTimeAgo(dateStr); var sizeStr = row.Children[4].TextContent; - release.Size = ReleaseInfo.GetBytes(sizeStr); + release.Size = ParseUtil.GetBytes(sizeStr); release.Files = ParseUtil.CoerceInt(row.Children[2].TextContent.Trim()); release.Seeders = ParseUtil.CoerceInt(row.Children[7].TextContent.Trim()); diff --git a/src/NzbDrone.Core/Indexers/Definitions/BakaBT.cs b/src/NzbDrone.Core/Indexers/Definitions/BakaBT.cs index a9e0e601d..a24077037 100644 --- a/src/NzbDrone.Core/Indexers/Definitions/BakaBT.cs +++ b/src/NzbDrone.Core/Indexers/Definitions/BakaBT.cs @@ -15,6 +15,7 @@ using NzbDrone.Core.Configuration; using NzbDrone.Core.Indexers.Exceptions; using NzbDrone.Core.IndexerSearch.Definitions; using NzbDrone.Core.Messaging.Events; +using NzbDrone.Core.Parser; using NzbDrone.Core.Parser.Model; using NzbDrone.Core.Validation; @@ -342,7 +343,7 @@ namespace NzbDrone.Core.Indexers.Definitions release.MinimumSeedTime = 172800; // 48 hours var size = row.QuerySelector(".size").TextContent; - release.Size = ReleaseInfo.GetBytes(size); + release.Size = ParseUtil.GetBytes(size); //22 Jul 15 var dateStr = row.QuerySelector(".added").TextContent.Replace("'", string.Empty); diff --git a/src/NzbDrone.Core/Indexers/Definitions/BinSearch.cs b/src/NzbDrone.Core/Indexers/Definitions/BinSearch.cs index b1eab50c4..dd51ae064 100644 --- a/src/NzbDrone.Core/Indexers/Definitions/BinSearch.cs +++ b/src/NzbDrone.Core/Indexers/Definitions/BinSearch.cs @@ -194,7 +194,7 @@ namespace NzbDrone.Core.Indexers.Definitions { Guid = guid, Title = parsedTitle.Groups["title"].Value, - Size = ReleaseInfo.GetBytes(string.Format("{0} {1}", size.Groups["size"].Value, size.Groups["unit"].Value)), + Size = ParseUtil.GetBytes(string.Format("{0} {1}", size.Groups["size"].Value, size.Groups["unit"].Value)), PublishDate = publishDate, Categories = new List { NewznabStandardCategory.Other }, InfoUrl = infoUrl, diff --git a/src/NzbDrone.Core/Indexers/Definitions/Cardigann/CardigannParser.cs b/src/NzbDrone.Core/Indexers/Definitions/Cardigann/CardigannParser.cs index 57d4e469f..525e67410 100644 --- a/src/NzbDrone.Core/Indexers/Definitions/Cardigann/CardigannParser.cs +++ b/src/NzbDrone.Core/Indexers/Definitions/Cardigann/CardigannParser.cs @@ -209,7 +209,7 @@ namespace NzbDrone.Core.Indexers.Cardigann value = release.Categories.ToString(); break; case "size": - release.Size = ReleaseInfo.GetBytes(value); + release.Size = ParseUtil.GetBytes(value); value = release.Size.ToString(); break; case "leechers": diff --git a/src/NzbDrone.Core/Indexers/Definitions/GazelleGames.cs b/src/NzbDrone.Core/Indexers/Definitions/GazelleGames.cs index b69cf9595..0a85320d2 100644 --- a/src/NzbDrone.Core/Indexers/Definitions/GazelleGames.cs +++ b/src/NzbDrone.Core/Indexers/Definitions/GazelleGames.cs @@ -361,7 +361,7 @@ namespace NzbDrone.Core.Indexers.Definitions var details = _settings.BaseUrl + qDetailsLink.GetAttribute("href"); var grabs = ParseUtil.CoerceInt(qGrabs.TextContent); var leechers = ParseUtil.CoerceInt(qLeechers.TextContent); - var size = ReleaseInfo.GetBytes(sizeString); + var size = ParseUtil.GetBytes(sizeString); var release = new TorrentInfo { diff --git a/src/NzbDrone.Core/Indexers/Definitions/HDSpace.cs b/src/NzbDrone.Core/Indexers/Definitions/HDSpace.cs index de83b0fa5..e4742cc0e 100644 --- a/src/NzbDrone.Core/Indexers/Definitions/HDSpace.cs +++ b/src/NzbDrone.Core/Indexers/Definitions/HDSpace.cs @@ -276,7 +276,7 @@ namespace NzbDrone.Core.Indexers.Definitions //"July 11, 2015, 13:34:09", "Today|Yesterday at 20:04:23" release.PublishDate = DateTimeUtil.FromUnknown(dateStr); var sizeStr = row.Children[5].TextContent; - release.Size = ReleaseInfo.GetBytes(sizeStr); + release.Size = ParseUtil.GetBytes(sizeStr); release.Seeders = ParseUtil.CoerceInt(row.Children[7].TextContent); release.Peers = ParseUtil.CoerceInt(row.Children[8].TextContent) + release.Seeders; var grabs = row.QuerySelector("td:nth-child(10)").TextContent; diff --git a/src/NzbDrone.Core/Indexers/Definitions/HDTorrents.cs b/src/NzbDrone.Core/Indexers/Definitions/HDTorrents.cs index 4c860d812..f206e3a3e 100644 --- a/src/NzbDrone.Core/Indexers/Definitions/HDTorrents.cs +++ b/src/NzbDrone.Core/Indexers/Definitions/HDTorrents.cs @@ -259,7 +259,7 @@ namespace NzbDrone.Core.Indexers.Definitions var link = new Uri(_settings.BaseUrl + row.Children[4].FirstElementChild.GetAttribute("href")); var description = row.Children[2].QuerySelector("span").TextContent; - var size = ReleaseInfo.GetBytes(row.Children[7].TextContent); + var size = ParseUtil.GetBytes(row.Children[7].TextContent); var dateTag = row.Children[6].FirstElementChild; var dateString = string.Join(" ", dateTag.Attributes.Select(attr => attr.Name)); diff --git a/src/NzbDrone.Core/Indexers/Definitions/IPTorrents.cs b/src/NzbDrone.Core/Indexers/Definitions/IPTorrents.cs index 31d651112..445a0980a 100644 --- a/src/NzbDrone.Core/Indexers/Definitions/IPTorrents.cs +++ b/src/NzbDrone.Core/Indexers/Definitions/IPTorrents.cs @@ -304,7 +304,7 @@ namespace NzbDrone.Core.Indexers.Definitions // Torrents - Category column == Icons var cat = _categories.MapTrackerCatToNewznab(catIcon.GetAttribute("href").Substring(1)); - var size = ReleaseInfo.GetBytes(row.Children[5].TextContent); + var size = ParseUtil.GetBytes(row.Children[5].TextContent); var colIndex = 6; int? files = null; diff --git a/src/NzbDrone.Core/Indexers/Definitions/ImmortalSeed.cs b/src/NzbDrone.Core/Indexers/Definitions/ImmortalSeed.cs index 77b81d1fc..29224d5a6 100644 --- a/src/NzbDrone.Core/Indexers/Definitions/ImmortalSeed.cs +++ b/src/NzbDrone.Core/Indexers/Definitions/ImmortalSeed.cs @@ -280,7 +280,7 @@ namespace NzbDrone.Core.Indexers.Definitions release.PublishDate = DateTime.ParseExact(dateString, "yyyy-MM-dd hh:mm tt", CultureInfo.InvariantCulture); var sizeStr = row.QuerySelector("td:nth-of-type(5)").TextContent.Trim(); - release.Size = ReleaseInfo.GetBytes(sizeStr); + release.Size = ParseUtil.GetBytes(sizeStr); release.Seeders = ParseUtil.CoerceInt(row.QuerySelector("td:nth-of-type(7)").TextContent.Trim()); release.Peers = ParseUtil.CoerceInt(row.QuerySelector("td:nth-of-type(8)").TextContent.Trim()) + release.Seeders; diff --git a/src/NzbDrone.Core/Indexers/Definitions/MyAnonamouse.cs b/src/NzbDrone.Core/Indexers/Definitions/MyAnonamouse.cs index 02d30567b..eb7f716ea 100644 --- a/src/NzbDrone.Core/Indexers/Definitions/MyAnonamouse.cs +++ b/src/NzbDrone.Core/Indexers/Definitions/MyAnonamouse.cs @@ -360,7 +360,7 @@ namespace NzbDrone.Core.Indexers.Definitions release.Seeders = item.Seeders; release.Peers = item.Leechers + release.Seeders; var size = item.Size; - release.Size = ReleaseInfo.GetBytes(size); + release.Size = ParseUtil.GetBytes(size); release.DownloadVolumeFactor = item.Free ? 0 : 1; release.UploadVolumeFactor = 1; diff --git a/src/NzbDrone.Core/Indexers/Definitions/Nebulance.cs b/src/NzbDrone.Core/Indexers/Definitions/Nebulance.cs index 7776608fa..71327650c 100644 --- a/src/NzbDrone.Core/Indexers/Definitions/Nebulance.cs +++ b/src/NzbDrone.Core/Indexers/Definitions/Nebulance.cs @@ -224,7 +224,7 @@ namespace NzbDrone.Core.Indexers.Definitions var link = _settings.BaseUrl + row.QuerySelector("a[href*='action=download']").GetAttribute("href"); var qColSize = row.QuerySelector("td:nth-child(3)"); - var size = ReleaseInfo.GetBytes(qColSize.Children[0].TextContent); + var size = ParseUtil.GetBytes(qColSize.Children[0].TextContent); var files = ParseUtil.CoerceInt(qColSize.Children[1].TextContent.Split(':')[1].Trim()); var qPublishdate = row.QuerySelector("td:nth-child(4) span"); diff --git a/src/NzbDrone.Core/Indexers/Definitions/PreToMe.cs b/src/NzbDrone.Core/Indexers/Definitions/PreToMe.cs index f0d69065f..4033a23f2 100644 --- a/src/NzbDrone.Core/Indexers/Definitions/PreToMe.cs +++ b/src/NzbDrone.Core/Indexers/Definitions/PreToMe.cs @@ -342,7 +342,7 @@ namespace NzbDrone.Core.Indexers.Definitions var dateStr = Regex.Replace(row.Children[5].InnerHtml, @"\", " "); var publishDate = DateTimeUtil.FromTimeAgo(dateStr); var files = ParseUtil.CoerceInt(row.Children[3].TextContent); - var size = ReleaseInfo.GetBytes(row.Children[7].TextContent); + var size = ParseUtil.GetBytes(row.Children[7].TextContent); var grabs = ParseUtil.CoerceInt(row.Children[8].TextContent); var seeders = ParseUtil.CoerceInt(row.Children[9].TextContent); var leechers = ParseUtil.CoerceInt(row.Children[10].TextContent); diff --git a/src/NzbDrone.Core/Indexers/Definitions/RevolutionTT.cs b/src/NzbDrone.Core/Indexers/Definitions/RevolutionTT.cs index 41e66ba09..f3bb2e387 100644 --- a/src/NzbDrone.Core/Indexers/Definitions/RevolutionTT.cs +++ b/src/NzbDrone.Core/Indexers/Definitions/RevolutionTT.cs @@ -281,7 +281,7 @@ namespace NzbDrone.Core.Indexers.Definitions var dateString = row.QuerySelector("td:nth-child(6) nobr").TextContent.Trim(); var publishDate = DateTime.ParseExact(dateString, "yyyy-MM-ddHH:mm:ss", CultureInfo.InvariantCulture); - var size = ReleaseInfo.GetBytes(row.QuerySelector("td:nth-child(7)").InnerHtml.Split('<').First().Trim()); + var size = ParseUtil.GetBytes(row.QuerySelector("td:nth-child(7)").InnerHtml.Split('<').First().Trim()); var files = ParseUtil.GetLongFromString(row.QuerySelector("td:nth-child(7) > a").TextContent); var grabs = ParseUtil.GetLongFromString(row.QuerySelector("td:nth-child(8)").TextContent); var seeders = ParseUtil.CoerceInt(row.QuerySelector("td:nth-child(9)").TextContent); diff --git a/src/NzbDrone.Core/Indexers/Definitions/RuTracker.cs b/src/NzbDrone.Core/Indexers/Definitions/RuTracker.cs index 408c7ad83..3717a04f7 100644 --- a/src/NzbDrone.Core/Indexers/Definitions/RuTracker.cs +++ b/src/NzbDrone.Core/Indexers/Definitions/RuTracker.cs @@ -1672,7 +1672,7 @@ namespace NzbDrone.Core.Indexers.Definitions private long GetSizeOfRelease(in IElement row) { var qSize = row.QuerySelector("td.tor-size"); - var size = ReleaseInfo.GetBytes(qSize.GetAttribute("data-ts_text")); + var size = ParseUtil.GetBytes(qSize.GetAttribute("data-ts_text")); return size; } diff --git a/src/NzbDrone.Core/Indexers/Definitions/SceneTime.cs b/src/NzbDrone.Core/Indexers/Definitions/SceneTime.cs index 12649f599..890881000 100644 --- a/src/NzbDrone.Core/Indexers/Definitions/SceneTime.cs +++ b/src/NzbDrone.Core/Indexers/Definitions/SceneTime.cs @@ -254,7 +254,7 @@ namespace NzbDrone.Core.Indexers.Definitions DownloadUrl = string.Format("{0}/download.php/{1}/download.torrent", _settings.BaseUrl, torrentId), Guid = details, PublishDate = DateTimeUtil.FromTimeAgo(qDescCol.ChildNodes.Last().TextContent), - Size = ReleaseInfo.GetBytes(sizeStr), + Size = ParseUtil.GetBytes(sizeStr), Seeders = seeders, Peers = ParseUtil.CoerceInt(row.Children[leechersIndex].TextContent.Trim()) + seeders, DownloadVolumeFactor = row.QuerySelector("font > b:contains(Freeleech)") != null ? 0 : 1, diff --git a/src/NzbDrone.Core/Indexers/Definitions/TVVault.cs b/src/NzbDrone.Core/Indexers/Definitions/TVVault.cs index 48958a972..fd796d284 100644 --- a/src/NzbDrone.Core/Indexers/Definitions/TVVault.cs +++ b/src/NzbDrone.Core/Indexers/Definitions/TVVault.cs @@ -256,7 +256,7 @@ namespace NzbDrone.Core.Indexers.Definitions var files = ParseUtil.CoerceInt(row.QuerySelector("td:nth-child(3)").TextContent); var publishDate = DateTimeUtil.FromTimeAgo(row.QuerySelector("td:nth-child(4)").TextContent); - var size = ReleaseInfo.GetBytes(row.QuerySelector("td:nth-child(5)").FirstChild.TextContent); + var size = ParseUtil.GetBytes(row.QuerySelector("td:nth-child(5)").FirstChild.TextContent); var grabs = ParseUtil.CoerceInt(row.QuerySelector("td:nth-child(6)").TextContent); var seeders = ParseUtil.CoerceInt(row.QuerySelector("td:nth-child(7)").TextContent); var leechers = ParseUtil.CoerceInt(row.QuerySelector("td:nth-child(8)").TextContent); diff --git a/src/NzbDrone.Core/Indexers/Definitions/TorrentSeeds.cs b/src/NzbDrone.Core/Indexers/Definitions/TorrentSeeds.cs index d27850ec9..c164c8d28 100644 --- a/src/NzbDrone.Core/Indexers/Definitions/TorrentSeeds.cs +++ b/src/NzbDrone.Core/Indexers/Definitions/TorrentSeeds.cs @@ -314,7 +314,7 @@ namespace NzbDrone.Core.Indexers.Definitions var qColumns = row.QuerySelectorAll("td"); release.Files = ParseUtil.CoerceInt(qColumns[3].TextContent); release.PublishDate = DateTimeUtil.FromUnknown(qColumns[5].TextContent); - release.Size = ReleaseInfo.GetBytes(qColumns[6].TextContent); + release.Size = ParseUtil.GetBytes(qColumns[6].TextContent); release.Grabs = ParseUtil.CoerceInt(qColumns[7].TextContent.Replace("Times", "")); release.Seeders = ParseUtil.CoerceInt(qColumns[8].TextContent); release.Peers = ParseUtil.CoerceInt(qColumns[9].TextContent) + release.Seeders; diff --git a/src/NzbDrone.Core/Indexers/Definitions/ZonaQ.cs b/src/NzbDrone.Core/Indexers/Definitions/ZonaQ.cs index 9ae731a0f..328ca8aef 100644 --- a/src/NzbDrone.Core/Indexers/Definitions/ZonaQ.cs +++ b/src/NzbDrone.Core/Indexers/Definitions/ZonaQ.cs @@ -355,7 +355,7 @@ namespace NzbDrone.Core.Indexers.Definitions var publishDateStr = row.Children[4].InnerHtml.Split('>').Last(); var publishDate = DateTime.ParseExact(publishDateStr, "dd/MM/yyyy", CultureInfo.InvariantCulture); - var size = ReleaseInfo.GetBytes(row.Children[5].TextContent.Replace(".", "").Replace(",", ".")); + var size = ParseUtil.GetBytes(row.Children[5].TextContent.Replace(".", "").Replace(",", ".")); var seeders = ParseUtil.CoerceInt(row.Children[6].TextContent); var leechers = ParseUtil.CoerceInt(row.Children[7].TextContent); var grabs = ParseUtil.CoerceInt(row.Children[8].TextContent); diff --git a/src/NzbDrone.Core/Parser/Model/ReleaseInfo.cs b/src/NzbDrone.Core/Parser/Model/ReleaseInfo.cs index 3642dc7e6..c2f023b60 100644 --- a/src/NzbDrone.Core/Parser/Model/ReleaseInfo.cs +++ b/src/NzbDrone.Core/Parser/Model/ReleaseInfo.cs @@ -99,47 +99,5 @@ namespace NzbDrone.Core.Parser.Model return ToString(); } } - - public static long GetBytes(string str) - { - var valStr = new string(str.Where(c => char.IsDigit(c) || c == '.').ToArray()); - var unit = new string(str.Where(char.IsLetter).ToArray()); - var val = ParseUtil.CoerceFloat(valStr); - return GetBytes(unit, val); - } - - public static long GetBytes(string unit, float value) - { - unit = unit.Replace("i", "").ToLowerInvariant(); - if (unit.Contains("kb")) - { - return BytesFromKB(value); - } - - if (unit.Contains("mb")) - { - return BytesFromMB(value); - } - - if (unit.Contains("gb")) - { - return BytesFromGB(value); - } - - if (unit.Contains("tb")) - { - return BytesFromTB(value); - } - - return (long)value; - } - - public static long BytesFromTB(float tb) => BytesFromGB(tb * 1024f); - - public static long BytesFromGB(float gb) => BytesFromMB(gb * 1024f); - - public static long BytesFromMB(float mb) => BytesFromKB(mb * 1024f); - - public static long BytesFromKB(float kb) => (long)(kb * 1024f); } } diff --git a/src/NzbDrone.Core/Parser/ParseUtil.cs b/src/NzbDrone.Core/Parser/ParseUtil.cs index cdf651476..c157bf3dc 100644 --- a/src/NzbDrone.Core/Parser/ParseUtil.cs +++ b/src/NzbDrone.Core/Parser/ParseUtil.cs @@ -18,10 +18,20 @@ namespace NzbDrone.Core.Parser public static string NormalizeMultiSpaces(string s) => new Regex(@"\s+").Replace(NormalizeSpace(s), " "); - public static string NormalizeNumber(string s) => - NormalizeSpace(s) - .Replace("-", "0") - .Replace(",", ""); + public static string NormalizeNumber(string s) + { + s = (s.Length == 0) ? "0" : s.Replace(",", "."); + + s = NormalizeSpace(s).Replace("-", "0"); + + if (s.Count(c => c == '.') > 1) + { + var lastOcc = s.LastIndexOf('.'); + s = s.Substring(0, lastOcc).Replace(".", string.Empty) + s.Substring(lastOcc); + } + + return s; + } public static string RemoveInvalidXmlChars(string text) => string.IsNullOrEmpty(text) ? "" : InvalidXmlChars.Replace(text, ""); @@ -98,5 +108,47 @@ namespace NzbDrone.Core.Parser var qs = QueryHelpers.ParseQuery(qsStr); return qs[argument].FirstOrDefault(); } + + public static long GetBytes(string str) + { + var valStr = new string(str.Where(c => char.IsDigit(c) || c == '.' || c == ',').ToArray()); + var unit = new string(str.Where(char.IsLetter).ToArray()); + var val = CoerceFloat(valStr); + return GetBytes(unit, val); + } + + public static long GetBytes(string unit, float value) + { + unit = unit.Replace("i", "").ToLowerInvariant(); + if (unit.Contains("kb")) + { + return BytesFromKB(value); + } + + if (unit.Contains("mb")) + { + return BytesFromMB(value); + } + + if (unit.Contains("gb")) + { + return BytesFromGB(value); + } + + if (unit.Contains("tb")) + { + return BytesFromTB(value); + } + + return (long)value; + } + + public static long BytesFromTB(float tb) => BytesFromGB(tb * 1024f); + + public static long BytesFromGB(float gb) => BytesFromMB(gb * 1024f); + + public static long BytesFromMB(float mb) => BytesFromKB(mb * 1024f); + + public static long BytesFromKB(float kb) => (long)(kb * 1024f); } }