Skip to content

Commit

Permalink
Moved Utils to SearchUtils class
Browse files Browse the repository at this point in the history
  • Loading branch information
UnidentifiedX committed Aug 21, 2024
1 parent ded3356 commit f6a87bb
Show file tree
Hide file tree
Showing 2 changed files with 95 additions and 78 deletions.
85 changes: 85 additions & 0 deletions src/YTSearch.NET/Utils/SearchUtils.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Text;
using System.Text.Json.Nodes;
using YTSearch.NET.Models;

namespace YTSearch.NET.Utils
{
internal static class SearchUtils
{
internal static int? KMBToInt(string? kmb)
{
if (kmb == null) return null;

try
{
if (kmb.ToLower().Contains('k'))
{
return (int)(float.Parse(kmb.ToLower().Replace("k", "")) * 1000);
}
else if (kmb.ToLower().Contains('m'))
{
return (int)(float.Parse(kmb.ToLower().Replace("m", "")) * 1000000);
}
else if (kmb.ToLower().Contains('b'))
{
return (int)(float.Parse(kmb.ToLower().Replace("b", "")) * 1000000000);
}
else
{
return int.Parse(kmb);
}
}
catch
{
return null;
}
}

internal static TimeSpan ParseVideoLength(string? timespan)
{
var output = TimeSpan.Zero;
if (timespan != null)
{
try
{
switch (timespan.Split(':').Length)
{
case 1:
output = TimeSpan.ParseExact(timespan, "%s", CultureInfo.InvariantCulture);
break;
case 2:
output = TimeSpan.ParseExact(timespan, @"m\:ss", CultureInfo.InvariantCulture);
break;
default:
output = TimeSpan.ParseExact(timespan, "g", CultureInfo.InvariantCulture);
break;
}
}
catch
{
output = TimeSpan.Zero;
}
}

return output;
}

internal static Thumbnail[] ParseThumbnails(JsonNode? jsonNode)
{
var thumbnails = new List<Thumbnail>();
jsonNode?.AsArray().ToList().ForEach(thumbnail =>
{
var width = (int?)thumbnail?["width"];
var height = (int?)thumbnail?["height"];
var url = (string?)thumbnail?["url"];
thumbnails.Add(new Thumbnail(width, height, url));
});

return thumbnails.ToArray();
}
}
}
88 changes: 10 additions & 78 deletions src/YTSearch.NET/YouTubeSearchClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
using System.Threading.Tasks;
using System.Web;
using YTSearch.NET.Models;
using YTSearch.NET.Utils;

namespace YTSearch.NET
{
Expand Down Expand Up @@ -47,8 +48,8 @@ public async Task<YouTubeVideoSearchResult> SearchYoutubeVideoAsync(string query

var title = (string?)video?["title"]?["runs"]?[0]?["text"];
var videoId = (string?)video?["videoId"];
var thumbnails = ParseThumbnails(video?["thumbnail"]?["thumbnails"]);
var length = ParseVideoLength((string?)video?["lengthText"]?["simpleText"]);
var thumbnails = SearchUtils.ParseThumbnails(video?["thumbnail"]?["thumbnails"]);
var length = SearchUtils.ParseVideoLength((string?)video?["lengthText"]?["simpleText"]);
var author = (string?)video?["ownerText"]?["runs"]?[0]?["text"];
int? views = int.TryParse(((string?)video?["viewCountText"]?["simpleText"])?.Replace(",", "")?.Replace("views", ""), out int parsed) ? parsed : (int?)null; // (int?) cast to target netstandard2.1
var published = (string?)video?["publishedTimeText"]?["simpleText"];
Expand Down Expand Up @@ -83,7 +84,7 @@ public async Task<YouTubeChannelSearchResult> SearchYouTubeChannelAsync(string q

var channelId = (string?)channel?["channelId"];
var name = (string?)channel?["title"]?["simpleText"];
var thumbnails = ParseThumbnails(channel?["thumbnail"]?["thumbnails"]);
var thumbnails = SearchUtils.ParseThumbnails(channel?["thumbnail"]?["thumbnails"]);
var descriptionSnippet = channel?["descriptionSnippet"]?["runs"]?[0]?["text"];

// YouTube does this weird thing where they send subscriber count in the view/video count text, so we have to check for them
Expand All @@ -92,16 +93,16 @@ public async Task<YouTubeChannelSearchResult> SearchYouTubeChannelAsync(string q

if ((string?)channel?["videoCountText"]?["simpleText"] != null && ((string?)channel?["videoCountText"]?["simpleText"]).Contains("subscriber"))

Check warning on line 94 in src/YTSearch.NET/YouTubeSearchClient.cs

View workflow job for this annotation

GitHub Actions / build (6.0)

Dereference of a possibly null reference.

Check warning on line 94 in src/YTSearch.NET/YouTubeSearchClient.cs

View workflow job for this annotation

GitHub Actions / build (6.0)

Dereference of a possibly null reference.

Check warning on line 94 in src/YTSearch.NET/YouTubeSearchClient.cs

View workflow job for this annotation

GitHub Actions / build (6.0)

Dereference of a possibly null reference.
{
subscriberCount = KMBToInt(((string?)channel?["videoCountText"]?["simpleText"])?.Split(' ')[0]);
subscriberCount = SearchUtils.KMBToInt(((string?)channel?["videoCountText"]?["simpleText"])?.Split(' ')[0]);
}
else
{
subscriberCount = KMBToInt(((string?)channel?["subscriberCountText"]?["simpleText"])?.Split(' ')[0]);
subscriberCount = SearchUtils.KMBToInt(((string?)channel?["subscriberCountText"]?["simpleText"])?.Split(' ')[0]);
}

if ((string?)channel?["videoCountText"]?["runs"]?[0]?["text"] != null && ((string?)channel?["videoCountText"]?["runs"]?[0]?["text"]).Contains("video"))

Check warning on line 103 in src/YTSearch.NET/YouTubeSearchClient.cs

View workflow job for this annotation

GitHub Actions / build (6.0)

Dereference of a possibly null reference.

Check warning on line 103 in src/YTSearch.NET/YouTubeSearchClient.cs

View workflow job for this annotation

GitHub Actions / build (6.0)

Dereference of a possibly null reference.

Check warning on line 103 in src/YTSearch.NET/YouTubeSearchClient.cs

View workflow job for this annotation

GitHub Actions / build (6.0)

Dereference of a possibly null reference.
{
videoCount = KMBToInt(((string?)channel?["videoCountText"]?["runs"]?[0]?["text"])?.Split(' ')[0]);
videoCount = SearchUtils.KMBToInt(((string?)channel?["videoCountText"]?["runs"]?[0]?["text"])?.Split(' ')[0]);
}

searchResults.Add(new SearchedYouTubeChannel(channelId, name, thumbnails, descriptionSnippet, videoCount, subscriberCount));
Expand Down Expand Up @@ -138,7 +139,7 @@ public async Task<YouTubeVideoQueryResult> GetVideoMetadataAsync(Uri uri)

var title = (string?)videoDetail?["title"];
var videoId = (string?)videoDetail?["videoId"];
var thumbnails = ParseThumbnails(videoDetail?["thumbnail"]?["thumbnails"]);
var thumbnails = SearchUtils.ParseThumbnails(videoDetail?["thumbnail"]?["thumbnails"]);
var length = TimeSpan.FromSeconds(int.Parse((string?)videoDetail?["lengthSeconds"]));
var author = (string?)videoDetail?["author"];
var views = int.Parse((string?)videoDetail?["viewCount"]);
Expand Down Expand Up @@ -179,77 +180,8 @@ public async Task<YouTubeVideoQueryResult> GetVideoMetadataAsync(Uri uri)

}
#endregion
#region Channel Metadata

private static Thumbnail[] ParseThumbnails(JsonNode? jsonNode)
{
var thumbnails = new List<Thumbnail>();
jsonNode?.AsArray().ToList().ForEach(thumbnail =>
{
var width = (int?)thumbnail?["width"];
var height = (int?)thumbnail?["height"];
var url = (string?)thumbnail?["url"];
thumbnails.Add(new Thumbnail(width, height, url));
});

return thumbnails.ToArray();
}

private static TimeSpan ParseVideoLength(string? timespan)
{
var output = TimeSpan.Zero;
if (timespan != null)
{
try
{
switch (timespan.Split(':').Length)
{
case 1:
output = TimeSpan.ParseExact(timespan, "%s", CultureInfo.InvariantCulture);
break;
case 2:
output = TimeSpan.ParseExact(timespan, @"m\:ss", CultureInfo.InvariantCulture);
break;
default:
output = TimeSpan.ParseExact(timespan, "g", CultureInfo.InvariantCulture);
break;
}
}
catch
{
output = TimeSpan.Zero;
}
}

return output;
}

private static int? KMBToInt(string? kmb)
{
if(kmb == null) return null;

try
{
if (kmb.ToLower().Contains('k'))
{
return (int)(float.Parse(kmb.ToLower().Replace("k", "")) * 1000);
}
else if (kmb.ToLower().Contains('m'))
{
return (int)(float.Parse(kmb.ToLower().Replace("m", "")) * 1000000);
}
else if (kmb.ToLower().Contains('b'))
{
return (int)(float.Parse(kmb.ToLower().Replace("b", "")) * 1000000000);
}
else
{
return int.Parse(kmb);
}
}
catch
{
return null;
}
}
#endregion
}
}

0 comments on commit f6a87bb

Please sign in to comment.