From ded33569bdc65f58aeb9be05a8d16c58037e5e37 Mon Sep 17 00:00:00 2001
From: UnidentifiedX <80146445+UnidentifiedX@users.noreply.github.com>
Date: Wed, 21 Aug 2024 19:00:09 +0800
Subject: [PATCH 1/3] restructured codebase to make future updates easier
---
src/YTSearch.NET.TestConsole/Program.cs | 2 ++
src/YTSearch.NET/{ => Models}/SearchedYouTubeChannel.cs | 3 +--
src/YTSearch.NET/{ => Models}/SearchedYouTubeVideo.cs | 9 ++++-----
.../{ => Models}/YouTubeChannelSearchResult.cs | 4 ++--
src/YTSearch.NET/{ => Models}/YouTubeSearchResult.cs | 2 +-
.../{BaseYouTubeVideo.cs => Models/YouTubeVideoBase.cs} | 9 ++++-----
src/YTSearch.NET/{ => Models}/YouTubeVideoQueryResult.cs | 0
.../{ => Models}/YouTubeVideoSearchResult.cs | 6 +++---
src/YTSearch.NET/QueriedYouTubeVideo.cs | 4 ++--
9 files changed, 19 insertions(+), 20 deletions(-)
rename src/YTSearch.NET/{ => Models}/SearchedYouTubeChannel.cs (94%)
rename src/YTSearch.NET/{ => Models}/SearchedYouTubeVideo.cs (74%)
rename src/YTSearch.NET/{ => Models}/YouTubeChannelSearchResult.cs (80%)
rename src/YTSearch.NET/{ => Models}/YouTubeSearchResult.cs (94%)
rename src/YTSearch.NET/{BaseYouTubeVideo.cs => Models/YouTubeVideoBase.cs} (90%)
rename src/YTSearch.NET/{ => Models}/YouTubeVideoQueryResult.cs (100%)
rename src/YTSearch.NET/{ => Models}/YouTubeVideoSearchResult.cs (82%)
diff --git a/src/YTSearch.NET.TestConsole/Program.cs b/src/YTSearch.NET.TestConsole/Program.cs
index ad141f0..42cc8e6 100644
--- a/src/YTSearch.NET.TestConsole/Program.cs
+++ b/src/YTSearch.NET.TestConsole/Program.cs
@@ -14,6 +14,8 @@ static async Task Main(string[] args)
//var a = await client.SearchYouTubeChannelAsync("rick astley");
var a = await client.GetVideoMetadataAsync("qUeud6DvOWI");
+ //var a = (await client.SearchYoutubeVideoAsync("never gonna give you up")).Results.First().Url;
+ //var a = (await client.SearchYoutubeVideoAsync("beautiful girls"));
Debugger.Break();
diff --git a/src/YTSearch.NET/SearchedYouTubeChannel.cs b/src/YTSearch.NET/Models/SearchedYouTubeChannel.cs
similarity index 94%
rename from src/YTSearch.NET/SearchedYouTubeChannel.cs
rename to src/YTSearch.NET/Models/SearchedYouTubeChannel.cs
index 8915739..3ab56fc 100644
--- a/src/YTSearch.NET/SearchedYouTubeChannel.cs
+++ b/src/YTSearch.NET/Models/SearchedYouTubeChannel.cs
@@ -4,9 +4,8 @@
using System.Text;
using System.Text.Json.Nodes;
using System.Threading.Tasks;
-using YTSearch.NET.Models;
-namespace YTSearch.NET
+namespace YTSearch.NET.Models
{
public class SearchedYouTubeChannel
{
diff --git a/src/YTSearch.NET/SearchedYouTubeVideo.cs b/src/YTSearch.NET/Models/SearchedYouTubeVideo.cs
similarity index 74%
rename from src/YTSearch.NET/SearchedYouTubeVideo.cs
rename to src/YTSearch.NET/Models/SearchedYouTubeVideo.cs
index 45f7e67..24379c5 100644
--- a/src/YTSearch.NET/SearchedYouTubeVideo.cs
+++ b/src/YTSearch.NET/Models/SearchedYouTubeVideo.cs
@@ -1,14 +1,13 @@
using System;
-using YTSearch.NET.Models;
-namespace YTSearch.NET
+namespace YTSearch.NET.Models
{
///
- /// Class SearchedYoutubeVideo inherits from and shows extra video information extracted from video searchess
+ /// Class SearchedYoutubeVideo inherits from and shows extra video information extracted from video searchess
///
- public class SearchedYouTubeVideo : BaseYouTubeVideo
+ public class SearchedYouTubeVideo : YouTubeVideoBase
{
- public SearchedYouTubeVideo(string? title, string? videoId, Thumbnail[] thumbnails, TimeSpan length, string? author, int? views, string? published)
+ public SearchedYouTubeVideo(string? title, string? videoId, Thumbnail[] thumbnails, TimeSpan length, string? author, int? views, string? published)
: base(title, videoId, thumbnails, length, author, views)
{
Published = published;
diff --git a/src/YTSearch.NET/YouTubeChannelSearchResult.cs b/src/YTSearch.NET/Models/YouTubeChannelSearchResult.cs
similarity index 80%
rename from src/YTSearch.NET/YouTubeChannelSearchResult.cs
rename to src/YTSearch.NET/Models/YouTubeChannelSearchResult.cs
index cc04723..7180abd 100644
--- a/src/YTSearch.NET/YouTubeChannelSearchResult.cs
+++ b/src/YTSearch.NET/Models/YouTubeChannelSearchResult.cs
@@ -1,10 +1,10 @@
using System.Collections.Generic;
-namespace YTSearch.NET
+namespace YTSearch.NET.Models
{
public class YouTubeChannelSearchResult : YouTubeSearchResult
{
- public YouTubeChannelSearchResult(string query, string url, ICollection results)
+ public YouTubeChannelSearchResult(string query, string url, ICollection results)
: base(query, url)
{
Results = results;
diff --git a/src/YTSearch.NET/YouTubeSearchResult.cs b/src/YTSearch.NET/Models/YouTubeSearchResult.cs
similarity index 94%
rename from src/YTSearch.NET/YouTubeSearchResult.cs
rename to src/YTSearch.NET/Models/YouTubeSearchResult.cs
index 37f3e4c..9251d72 100644
--- a/src/YTSearch.NET/YouTubeSearchResult.cs
+++ b/src/YTSearch.NET/Models/YouTubeSearchResult.cs
@@ -4,7 +4,7 @@
using System.Text;
using System.Threading.Tasks;
-namespace YTSearch.NET
+namespace YTSearch.NET.Models
{
public abstract class YouTubeSearchResult
{
diff --git a/src/YTSearch.NET/BaseYouTubeVideo.cs b/src/YTSearch.NET/Models/YouTubeVideoBase.cs
similarity index 90%
rename from src/YTSearch.NET/BaseYouTubeVideo.cs
rename to src/YTSearch.NET/Models/YouTubeVideoBase.cs
index 5fbb00c..e4e8968 100644
--- a/src/YTSearch.NET/BaseYouTubeVideo.cs
+++ b/src/YTSearch.NET/Models/YouTubeVideoBase.cs
@@ -1,15 +1,14 @@
using System;
-using YTSearch.NET.Models;
-namespace YTSearch.NET
+namespace YTSearch.NET.Models
{
///
/// Abstract class BaseYouTubeVideo shows basic extracted information for a YouTube video
///
-
- public abstract class BaseYouTubeVideo
+
+ public abstract class YouTubeVideoBase
{
- public BaseYouTubeVideo(string? title, string? videoId, Thumbnail[] thumbnails, TimeSpan length, string? author, int? views)
+ public YouTubeVideoBase(string? title, string? videoId, Thumbnail[] thumbnails, TimeSpan length, string? author, int? views)
{
Title = title;
VideoId = videoId;
diff --git a/src/YTSearch.NET/YouTubeVideoQueryResult.cs b/src/YTSearch.NET/Models/YouTubeVideoQueryResult.cs
similarity index 100%
rename from src/YTSearch.NET/YouTubeVideoQueryResult.cs
rename to src/YTSearch.NET/Models/YouTubeVideoQueryResult.cs
diff --git a/src/YTSearch.NET/YouTubeVideoSearchResult.cs b/src/YTSearch.NET/Models/YouTubeVideoSearchResult.cs
similarity index 82%
rename from src/YTSearch.NET/YouTubeVideoSearchResult.cs
rename to src/YTSearch.NET/Models/YouTubeVideoSearchResult.cs
index f109b5c..63d83a7 100644
--- a/src/YTSearch.NET/YouTubeVideoSearchResult.cs
+++ b/src/YTSearch.NET/Models/YouTubeVideoSearchResult.cs
@@ -1,6 +1,6 @@
using System.Collections.Generic;
-namespace YTSearch.NET
+namespace YTSearch.NET.Models
{
public class YouTubeVideoSearchResult : YouTubeSearchResult
{
@@ -8,8 +8,8 @@ public class YouTubeVideoSearchResult : YouTubeSearchResult
///
/// Search result class
///
- public YouTubeVideoSearchResult(string query, string url, ICollection results)
- :base(query, url)
+ public YouTubeVideoSearchResult(string query, string url, ICollection results)
+ : base(query, url)
{
Results = results;
}
diff --git a/src/YTSearch.NET/QueriedYouTubeVideo.cs b/src/YTSearch.NET/QueriedYouTubeVideo.cs
index a395219..41e2b2f 100644
--- a/src/YTSearch.NET/QueriedYouTubeVideo.cs
+++ b/src/YTSearch.NET/QueriedYouTubeVideo.cs
@@ -4,9 +4,9 @@
namespace YTSearch.NET
{
///
- /// Class QueriedYouTubeVideo inherits from and shows extra video information extracted from a YouTube video
+ /// Class QueriedYouTubeVideo inherits from and shows extra video information extracted from a YouTube video
///
- public class QueriedYouTubeVideo : BaseYouTubeVideo
+ public class QueriedYouTubeVideo : YouTubeVideoBase
{
public QueriedYouTubeVideo(string? title, string? videoId, Thumbnail[] thumbnails, TimeSpan length, string? author, int? views, string[]? keywords, string? description, bool? isCrawlable, bool? isRatingEnabled, bool? isPrivate, bool? isLiveContent, DateTime publishedDate, DateTime uploadedDate, bool? isFamilyFriendly, string[]? availableCountries, bool? isUnlisted, string? category)
: base(title, videoId, thumbnails, length, author, views)
From f6a87bb0f2d8a2c0982d83a014121b1a32da3036 Mon Sep 17 00:00:00 2001
From: UnidentifiedX <80146445+UnidentifiedX@users.noreply.github.com>
Date: Wed, 21 Aug 2024 20:25:46 +0800
Subject: [PATCH 2/3] Moved Utils to SearchUtils class
---
src/YTSearch.NET/Utils/SearchUtils.cs | 85 ++++++++++++++++++++++++
src/YTSearch.NET/YouTubeSearchClient.cs | 88 +++----------------------
2 files changed, 95 insertions(+), 78 deletions(-)
create mode 100644 src/YTSearch.NET/Utils/SearchUtils.cs
diff --git a/src/YTSearch.NET/Utils/SearchUtils.cs b/src/YTSearch.NET/Utils/SearchUtils.cs
new file mode 100644
index 0000000..44df577
--- /dev/null
+++ b/src/YTSearch.NET/Utils/SearchUtils.cs
@@ -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();
+ 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();
+ }
+ }
+}
diff --git a/src/YTSearch.NET/YouTubeSearchClient.cs b/src/YTSearch.NET/YouTubeSearchClient.cs
index 2825551..89d80ad 100644
--- a/src/YTSearch.NET/YouTubeSearchClient.cs
+++ b/src/YTSearch.NET/YouTubeSearchClient.cs
@@ -10,6 +10,7 @@
using System.Threading.Tasks;
using System.Web;
using YTSearch.NET.Models;
+using YTSearch.NET.Utils;
namespace YTSearch.NET
{
@@ -47,8 +48,8 @@ public async Task 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"];
@@ -83,7 +84,7 @@ public async Task 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
@@ -92,16 +93,16 @@ public async Task SearchYouTubeChannelAsync(string q
if ((string?)channel?["videoCountText"]?["simpleText"] != null && ((string?)channel?["videoCountText"]?["simpleText"]).Contains("subscriber"))
{
- 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"))
{
- 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));
@@ -138,7 +139,7 @@ public async Task 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"]);
@@ -179,77 +180,8 @@ public async Task GetVideoMetadataAsync(Uri uri)
}
#endregion
+ #region Channel Metadata
- private static Thumbnail[] ParseThumbnails(JsonNode? jsonNode)
- {
- var thumbnails = new List();
- 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
}
}
\ No newline at end of file
From abc028c4fa7eafe0c9cfe701d4d8aa501ff5a4ba Mon Sep 17 00:00:00 2001
From: UnidentifiedX
Date: Fri, 23 Aug 2024 11:45:28 +0800
Subject: [PATCH 3/3] updated tests
---
src/YTSearch.NET.Tests/YouTubeSearchTests.cs | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/YTSearch.NET.Tests/YouTubeSearchTests.cs b/src/YTSearch.NET.Tests/YouTubeSearchTests.cs
index 4062fc9..56cd359 100644
--- a/src/YTSearch.NET.Tests/YouTubeSearchTests.cs
+++ b/src/YTSearch.NET.Tests/YouTubeSearchTests.cs
@@ -32,7 +32,7 @@ public async Task SearchYoutube_TitleSearchWithoutFlags_CorrectVideoDetails()
Assert.That(a.Url, Is.EqualTo("https://www.youtube.com/watch?v=dQw4w9WgXcQ"));
Assert.That(a.Length, Is.EqualTo(TimeSpan.FromSeconds(213)));
Assert.That(a.Author, Is.EqualTo("Rick Astley"));
- Assert.That(a.Published, Is.EqualTo("13 years ago"));
+ Assert.That(a.Published, Is.EqualTo("14 years ago"));
});
}
}