From 536329909d7b6af1ee53affecf169af293698073 Mon Sep 17 00:00:00 2001 From: Bobby Burden III Date: Sat, 28 Dec 2024 08:04:04 -0500 Subject: [PATCH] Update dependencies, add GUID based methods Cleanup, use null arguments and improved defaults Fix failing example, cleanup Version bump to 2.0.0 Bump dotnet version to 9 in CI Bump Test project to dotnet9 --- .github/workflows/dotnet.yml | 2 +- .vscode/launch.json | 2 +- .vscode/settings.json | 13 +++ .../PodcastIndexSharp.Example.csproj | 2 +- PodcastIndexSharp.Example/Program.cs | 6 +- .../appsettings.local.json | 11 +- .../Clients/BaseClientTest.cs | 1 + .../Clients/SearchClientTest.cs | 4 +- .../PodcastIndexSharp.Test.csproj | 4 +- PodcastIndexSharp/Clients/AddClient.cs | 10 +- PodcastIndexSharp/Clients/BaseClient.cs | 1 + PodcastIndexSharp/Clients/EpisodesClient.cs | 110 ++++++++++++++---- PodcastIndexSharp/Clients/HubClient.cs | 15 ++- PodcastIndexSharp/Clients/IAddClient.cs | 4 +- PodcastIndexSharp/Clients/IEpisodesClient.cs | 104 +++++++++++------ PodcastIndexSharp/Clients/IHubClient.cs | 3 +- PodcastIndexSharp/Clients/IPodcastsClient.cs | 18 ++- PodcastIndexSharp/Clients/IRecentClient.cs | 28 ++++- PodcastIndexSharp/Clients/ISearchClient.cs | 24 +++- PodcastIndexSharp/Clients/IValueClient.cs | 19 +++ PodcastIndexSharp/Clients/PodcastsClient.cs | 42 +++++-- PodcastIndexSharp/Clients/RecentClient.cs | 48 ++++++-- PodcastIndexSharp/Clients/SearchClient.cs | 49 +++++--- PodcastIndexSharp/Clients/ValueClient.cs | 21 ++++ .../Enums/PodcastNamespaceTag.cs | 15 +++ .../JsonConverters/UnixTimestampConverter.cs | 4 +- PodcastIndexSharp/Model/ApiParemeter.cs | 4 +- PodcastIndexSharp/Model/Category.cs | 2 +- PodcastIndexSharp/Model/Episode.cs | 30 ++--- PodcastIndexSharp/Model/FeedBase.cs | 2 +- PodcastIndexSharp/Model/FeedMeta.cs | 10 +- PodcastIndexSharp/Model/Funding.cs | 4 +- PodcastIndexSharp/Model/Podcast.cs | 22 ++-- PodcastIndexSharp/Model/Soundbite.cs | 10 +- PodcastIndexSharp/Model/Value.cs | 4 +- PodcastIndexSharp/Model/ValueDestination.cs | 6 +- PodcastIndexSharp/Model/ValueModel.cs | 6 +- PodcastIndexSharp/PodcastIndexConfig.cs | 4 +- PodcastIndexSharp/PodcastIndexSharp.csproj | 4 +- .../Response/AbstractResponse.cs | 8 +- .../Response/CategoriesListResponse.cs | 2 +- PodcastIndexSharp/Response/DeadResponse.cs | 2 +- PodcastIndexSharp/Response/EpisodeResponse.cs | 2 +- .../Response/EpisodesResponse.cs | 4 +- PodcastIndexSharp/Response/PodcastResponse.cs | 2 +- .../Response/RecentEpisodesResponse.cs | 2 +- .../Response/SoundbitesResponse.cs | 2 +- PodcastIndexSharp/Response/StatsResponse.cs | 2 +- .../Response/TrendingResponse.cs | 2 +- PodcastIndexSharp/Response/ValueResponse.cs | 2 +- 50 files changed, 503 insertions(+), 195 deletions(-) create mode 100644 PodcastIndexSharp/Enums/PodcastNamespaceTag.cs diff --git a/.github/workflows/dotnet.yml b/.github/workflows/dotnet.yml index 438c615..339eb01 100644 --- a/.github/workflows/dotnet.yml +++ b/.github/workflows/dotnet.yml @@ -16,7 +16,7 @@ jobs: - name: Setup .NET uses: actions/setup-dotnet@v2 with: - dotnet-version: 6.0.x + dotnet-version: 9.0.x - name: Restore dependencies run: dotnet restore - name: Build diff --git a/.vscode/launch.json b/.vscode/launch.json index 2914429..86cc8f5 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -6,7 +6,7 @@ "type": "coreclr", "request": "launch", "preLaunchTask": "build", - "program": "${workspaceFolder}/PodcastIndexSharp.Example/bin/Debug/net5.0/PodcastIndexSharp.Example.dll", + "program": "${workspaceFolder}/PodcastIndexSharp.Example/bin/Debug/net9.0/PodcastIndexSharp.Example.dll", "args": [], "cwd": "${workspaceFolder}/PodcastIndexSharp.Example", "console": "internalConsole", diff --git a/.vscode/settings.json b/.vscode/settings.json index 7182de4..da73240 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -5,13 +5,26 @@ "dotnet-test-explorer.testArguments": "/p:CollectCoverage=true /p:CoverletOutputFormat=lcov /p:CoverletOutput=./TestResults/lcov.info", "dotnet-test-explorer.testProjectPath": "**/*.Test.csproj", "cSpell.words": [ + "aponly", + "byepisodeguid", "byfeedid", "byfeedurl", + "byguid", + "byid", "byitunesid", + "bymedium", + "byperson", + "bypodcastguid", + "bytag", + "byterm", + "bytitle", "chash", "fulltext", "itunesid", + "newfeeds", "Newtonsoft", + "newvaluefeeds", + "podcastguid", "pubnotify" ] } \ No newline at end of file diff --git a/PodcastIndexSharp.Example/PodcastIndexSharp.Example.csproj b/PodcastIndexSharp.Example/PodcastIndexSharp.Example.csproj index 6b84524..1e0ded2 100644 --- a/PodcastIndexSharp.Example/PodcastIndexSharp.Example.csproj +++ b/PodcastIndexSharp.Example/PodcastIndexSharp.Example.csproj @@ -21,6 +21,6 @@ Exe - net5.0 + net9.0 diff --git a/PodcastIndexSharp.Example/Program.cs b/PodcastIndexSharp.Example/Program.cs index f3da97a..a5a2503 100644 --- a/PodcastIndexSharp.Example/Program.cs +++ b/PodcastIndexSharp.Example/Program.cs @@ -1,4 +1,4 @@ -namespace Example +namespace PodcastIndexSharp.Example { using System; using System.Threading.Tasks; @@ -77,11 +77,11 @@ static async Task RunExamples(IPodcastIndex podcastIndex) Console.WriteLine($"Episode by ID: Episode ID {episodeId} is number \"{episode.EpisodeNumber}\" in Podcast title \"{episode.FeedTitle}\""); // Get a Random Episode - var randomEpisodes = await podcastIndex.Episodes().Random("", "", "", false, 1); + var randomEpisodes = await podcastIndex.Episodes().Random(); Console.WriteLine($"Random Episode: Episode with number \"{randomEpisodes[0].Title}\" in Feed \"{randomEpisodes[0].FeedTitle}\" found."); // Get some recent episodes - var recentEpisodes = await podcastIndex.Recent().Episodes("", false, 1); + var recentEpisodes = await podcastIndex.Recent().Episodes(max: 1); Console.WriteLine($"Recent Episodes: The most recent episode is in Feed \"{recentEpisodes[0].FeedTitle}\""); // Recent Feeds diff --git a/PodcastIndexSharp.Example/appsettings.local.json b/PodcastIndexSharp.Example/appsettings.local.json index 9c12ef7..37af0a4 100644 --- a/PodcastIndexSharp.Example/appsettings.local.json +++ b/PodcastIndexSharp.Example/appsettings.local.json @@ -1,7 +1,6 @@ -{ - "PodcastIndex": { - "UserAgent": "", - "AuthKey": "", - "Secret": "" - } +{ + "PodcastIndex": { + "AuthKey": "", + "Secret": "" + } } \ No newline at end of file diff --git a/PodcastIndexSharp.Test/Clients/BaseClientTest.cs b/PodcastIndexSharp.Test/Clients/BaseClientTest.cs index c3fa3c1..c752d09 100644 --- a/PodcastIndexSharp.Test/Clients/BaseClientTest.cs +++ b/PodcastIndexSharp.Test/Clients/BaseClientTest.cs @@ -5,6 +5,7 @@ namespace PodcastIndexSharp.Test.Clients; using Flurl.Http; using PodcastIndexSharp.Clients; using PodcastIndexSharp.Exceptions; +using PodcastIndexSharp.Response; using Xunit; internal class ExposedBaseClient : BaseClient diff --git a/PodcastIndexSharp.Test/Clients/SearchClientTest.cs b/PodcastIndexSharp.Test/Clients/SearchClientTest.cs index 42db9dc..30814ea 100644 --- a/PodcastIndexSharp.Test/Clients/SearchClientTest.cs +++ b/PodcastIndexSharp.Test/Clients/SearchClientTest.cs @@ -7,7 +7,7 @@ namespace PodcastIndexSharp.Test.Clients; public class SearchClientTest : ClientTest { - private SearchClient searchClient; + private readonly SearchClient searchClient; public SearchClientTest() { @@ -22,7 +22,7 @@ public SearchClientTest() [InlineData("testQuery", Enums.SearchByTermValues.any, false, false, "q=testQuery&val=any")] [InlineData("testQuery", null, true, false, "q=testQuery&clean=")] [InlineData("testQuery", null, false, true, "q=testQuery&fulltext=")] - [InlineData("testQuery", Enums.SearchByTermValues.hive, true, true, "q=testQuery&val=hive&clean=&fulltext=")] + [InlineData("testQuery", Enums.SearchByTermValues.hive, true, true, "q=testQuery&clean=&fulltext=&val=hive")] public async Task TestPodcastsSearch(string query, Enums.SearchByTermValues? value, bool clean, bool fulltext, string param) { var baseUrl = "https://example.com/search/byterm?"; diff --git a/PodcastIndexSharp.Test/PodcastIndexSharp.Test.csproj b/PodcastIndexSharp.Test/PodcastIndexSharp.Test.csproj index 9f3eaa4..1f1174b 100644 --- a/PodcastIndexSharp.Test/PodcastIndexSharp.Test.csproj +++ b/PodcastIndexSharp.Test/PodcastIndexSharp.Test.csproj @@ -1,7 +1,7 @@ - net6.0 + net9.0 enable false @@ -13,6 +13,8 @@ all + + runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/PodcastIndexSharp/Clients/AddClient.cs b/PodcastIndexSharp/Clients/AddClient.cs index 73abc9f..7ab44ff 100644 --- a/PodcastIndexSharp/Clients/AddClient.cs +++ b/PodcastIndexSharp/Clients/AddClient.cs @@ -8,12 +8,13 @@ public class AddClient : BaseClient, IAddClient { public AddClient(PodcastIndexConfig config) : base(config) { } - public async Task ByFeedUrl(string url, uint iTunesId, string chash) + public async Task ByFeedUrl(string url, string chash, uint? iTunesId = null) { - var parameters = new ApiParameter[]{ + var parameters = new ApiParameter[] + { new ApiParameter("url", url), + new ApiParameter("chash", chash), new ApiParameter("itunesid", iTunesId), - new ApiParameter("chash", chash) }; var addResponse = await SendRequest("add/byfeedurl", parameters); @@ -22,7 +23,8 @@ public async Task ByFeedUrl(string url, uint iTunesId, string chash public async Task ByiTunesId(uint iTunesId) { - var parameters = new ApiParameter[]{ + var parameters = new ApiParameter[] + { new ApiParameter("id", iTunesId) }; diff --git a/PodcastIndexSharp/Clients/BaseClient.cs b/PodcastIndexSharp/Clients/BaseClient.cs index e4ff771..5461455 100644 --- a/PodcastIndexSharp/Clients/BaseClient.cs +++ b/PodcastIndexSharp/Clients/BaseClient.cs @@ -9,6 +9,7 @@ namespace PodcastIndexSharp.Clients using Flurl.Http; using PodcastIndexSharp.Exceptions; using PodcastIndexSharp.Model; + using PodcastIndexSharp.Response; /// /// The Base API client that all PodcastIndex API calls use. This class should not be used directly. diff --git a/PodcastIndexSharp/Clients/EpisodesClient.cs b/PodcastIndexSharp/Clients/EpisodesClient.cs index 42a5a92..f536f02 100644 --- a/PodcastIndexSharp/Clients/EpisodesClient.cs +++ b/PodcastIndexSharp/Clients/EpisodesClient.cs @@ -10,19 +10,32 @@ public class EpisodesClient : BaseClient, IEpisodesClient { public EpisodesClient(PodcastIndexConfig config) : base(config) { } - public async Task> ByFeedId(uint id, int max = 10, bool fulltext = false, DateTime? since = null) + public async Task> ByFeedId( + uint id, + int? max = null, + bool? fulltext = null, + DateTime? since = null) { - return await Episodes(id.ToString(), max, fulltext, false, since); + return await Episodes(id.ToString(), max, fulltext, false, since, null); } - public async Task> ByFeedId(uint[] id, int max = 10, bool fulltext = false, DateTime? since = null) + public async Task> ByFeedId( + uint[] id, + int? max = null, + bool? fulltext = null, + DateTime? since = null) { - return await Episodes(string.Join(",", id), max, fulltext, false, since); + return await Episodes(string.Join(",", id), max, fulltext, false, since, null); } - public async Task> ByFeedUrl(Uri url, int max = 10, bool fulltext = false, DateTime? since = null) + public async Task> ByFeedUrl( + Uri url, + int? max = null, + bool? fulltext = null, + DateTime? since = null) { - var parameters = new ApiParameter[]{ + var parameters = new ApiParameter[] + { new ApiParameter("url", url), new ApiParameter("max", max), new ApiParameter("since", since), @@ -33,14 +46,20 @@ public async Task> ByFeedUrl(Uri url, int max = 10, bool fulltext return episodesResponse.Episodes; } - public async Task> ByiTunesId(uint id, int max = 10, bool fulltext = false, DateTime? since = null) + public async Task> ByiTunesId( + uint id, + int? max = null, + bool? fulltext = null, + DateTime? since = null, + Uri? enclosure = null) { - return await Episodes(id.ToString(), max, fulltext, true, since); + return await Episodes(id.ToString(), max, fulltext, true, since, enclosure); } - public async Task ById(uint id, bool fulltext = false) + public async Task ById(uint id, bool? fulltext = null) { - var parameters = new ApiParameter[]{ + var parameters = new ApiParameter[] + { new ApiParameter("id", id), new ApiParameter("fulltext", fulltext) }; @@ -49,9 +68,15 @@ public async Task ById(uint id, bool fulltext = false) return episodeResponse.Episode; } - public async Task> Random(string lang = "", string category = "", string excludeCategory = "", bool fulltext = false, int max = 1) + public async Task> Random( + string? lang = null, + string? category = null, + string? excludeCategory = null, + bool? fulltext = null, + int? max = null) { - var parameters = new ApiParameter[]{ + var parameters = new ApiParameter[] + { new ApiParameter("lang", lang), new ApiParameter("max", max), new ApiParameter("category", category), @@ -60,12 +85,17 @@ public async Task> Random(string lang = "", string category = "", }; var episodesResponse = await SendRequest("episodes/random", parameters); - return episodesResponse.Episodes; + return episodesResponse.RandomEpisodes; } - public async Task> ByPodcastGUID(Guid guid, int max = 10, bool fulltext = false, DateTime? since = null) + public async Task> ByPodcastGUID( + Guid guid, + int? max = null, + bool? fulltext = null, + DateTime? since = null) { - var parameters = new ApiParameter[]{ + var parameters = new ApiParameter[] + { new ApiParameter("guid", guid), new ApiParameter("max", max), new ApiParameter("since", since), @@ -76,9 +106,10 @@ public async Task> ByPodcastGUID(Guid guid, int max = 10, bool ful return episodesResponse.Episodes; } - public async Task> Live(int max = 10) + public async Task> Live(int? max = null) { - var parameters = new ApiParameter[]{ + var parameters = new ApiParameter[] + { new ApiParameter("max", max), }; @@ -86,19 +117,56 @@ public async Task> Live(int max = 10) return episodesResponse.Episodes; } - private async Task> Episodes(string id, int max, bool fulltext, bool itunes, DateTime? since) + private async Task> Episodes( + string id, + int? max, + bool? fulltext, + bool? itunes, + DateTime? since, + Uri? enclosure) { - var parameters = new ApiParameter[]{ + var parameters = new ApiParameter[] + { new ApiParameter("id", id), new ApiParameter("max", max), new ApiParameter("since", since), - new ApiParameter("fulltext", fulltext) + new ApiParameter("fulltext", fulltext), + new ApiParameter("enclosure", enclosure) }; + itunes ??= false; + var episodeResponse = await SendRequest( - itunes ? "episodes/byitunesid" : "episodes/byfeedid", + itunes.Value ? "episodes/byitunesid" : "episodes/byfeedid", parameters); return episodeResponse.Episodes; } + + public async Task ByGUID( + Guid guid, + string? feedUrl = null, + string? feedId = null, + Guid? podcastGUID = null, + bool? fulltext = null) + { + if (feedUrl == null && feedId == null && podcastGUID == null) + { + throw new ArgumentException( + "At least one of the following must be provided: feedUrl, feedId, podcastGUID" + ); + } + + var parameters = new ApiParameter[] + { + new ApiParameter("guid", guid), + new ApiParameter("fulltext", fulltext), + new ApiParameter("feedUrl", feedUrl), + new ApiParameter("feedId", feedId), + new ApiParameter("podcastguid", podcastGUID) + }; + + var episodesResponse = await SendRequest("episodes/byguid", parameters); + return episodesResponse.Episode; + } } } \ No newline at end of file diff --git a/PodcastIndexSharp/Clients/HubClient.cs b/PodcastIndexSharp/Clients/HubClient.cs index 6ec313b..abe2a41 100644 --- a/PodcastIndexSharp/Clients/HubClient.cs +++ b/PodcastIndexSharp/Clients/HubClient.cs @@ -1,5 +1,6 @@ namespace PodcastIndexSharp.Clients { + using System; using System.Threading.Tasks; using PodcastIndexSharp.Model; using PodcastIndexSharp.Response; @@ -8,11 +9,17 @@ public class HubClient : BaseClient, IHubClient { public HubClient(PodcastIndexConfig config) : base(config) { } - public async Task PubNotify(uint? id, string url) + public async Task PubNotify(uint? id = null, Uri? url = null) { - var parameters = new ApiParameter[]{ - new ApiParameter("id", id), - new ApiParameter("url", url) + if (id == null && url == null) + { + throw new ArgumentException("Either the id or the url is required."); + } + + var parameters = new ApiParameter[] + { + new ApiParameter("url", url), + new ApiParameter("id", id) }; var hubResponse = await SendRequest("hub/pubnotify", parameters); diff --git a/PodcastIndexSharp/Clients/IAddClient.cs b/PodcastIndexSharp/Clients/IAddClient.cs index 2cd458e..7eb57ae 100644 --- a/PodcastIndexSharp/Clients/IAddClient.cs +++ b/PodcastIndexSharp/Clients/IAddClient.cs @@ -10,10 +10,10 @@ public interface IAddClient /// If a feed already exists, you will get its existing Feed ID returned in the response object. /// /// - /// /// MD5 hash of the title, link, feedLanguage, generator, author, ownerName, ownerEmail. Allows for easier duplicate checking. + /// /// - Task ByFeedUrl(string url, uint iTunesId, string chash); + Task ByFeedUrl(string url, string chash, uint? iTunesId = null); /// /// This call adds a podcast to the index using its iTunes ID. diff --git a/PodcastIndexSharp/Clients/IEpisodesClient.cs b/PodcastIndexSharp/Clients/IEpisodesClient.cs index 7944f0c..0bf5170 100644 --- a/PodcastIndexSharp/Clients/IEpisodesClient.cs +++ b/PodcastIndexSharp/Clients/IEpisodesClient.cs @@ -18,20 +18,20 @@ public interface IEpisodesClient /// /// Return items since the specified time. /// - Task> ByFeedId(uint id, int max = 10, bool fulltext = false, DateTime? since = null); + Task> ByFeedId(uint id, int? max = null, bool? fulltext = null, DateTime? since = null); /// /// Find details about one or more episodes of a podcast. /// /// A list of PodcastIndex Feed IDs to search for. - /// Maximum number of results to return. Must be >= 1 and <= 1000 /// /// If present, return the full text value of any text fields (ex: description).
/// If not provided, field value is truncated to 100 words. /// /// Return items since the specified time. + /// Maximum number of results to return. Must be >= 1 and <= 1000 /// - Task> ByFeedId(uint[] id, int max = 10, bool fulltext = false, DateTime? since = null); + Task> ByFeedId(uint[] id, int? max = null, bool? fulltext = null, DateTime? since = null); /// /// Find details about one or more episodes of a podcast.
@@ -46,7 +46,26 @@ public interface IEpisodesClient /// /// Return items since the specified time. /// - Task> ByFeedUrl(Uri url, int max = 10, bool fulltext = false, DateTime? since = null); + Task> ByFeedUrl(Uri url, int? max = null, bool? fulltext = null, DateTime? since = null); + + /// + /// Returns episodes known for a podcast by the Podcast GUID. + /// + /// + /// The GUID from the `podcast:guid` tag in the feed. + /// + /// + /// Maximum number of results to return. >=1 and <= 1000 + /// + /// + /// If present, return the full text value of any text fields (ex: description).
+ /// If not provided, field value is truncated to 100 words. + /// + /// + /// Return items since the specified time. + /// + /// + Task> ByPodcastGUID(Guid guid, int? max = null, bool? fulltext = null, DateTime? since = null); /// /// Find details about one or more episodes of a podcast. @@ -58,8 +77,14 @@ public interface IEpisodesClient /// If not provided, field value is truncated to 100 words. /// /// Return items since the specified time. + /// The URL for the episode enclosure to get the information for. /// - Task> ByiTunesId(uint id, int max = 10, bool fulltext = false, DateTime? since = null); + Task> ByiTunesId( + uint id, + int? max = null, + bool? fulltext = null, + DateTime? since = null, + Uri? enclosure = null); /// /// Find details about one episode of a podcast.
@@ -70,7 +95,39 @@ public interface IEpisodesClient /// If not provided, field value is truncated to 100 words. /// /// - Task ById(uint id, bool fulltext = false); + Task ById(uint id, bool? fulltext = false); + + /// + /// Get all the metadata for a single episode by passing its guid and the feed id or URL.
+ /// The feedId, feedUrl, or podcastGUID must be provided. + ///
+ /// The guid value for the episode to retrieve. + /// The feed URL + /// The PodcastIndex Feed ID + /// + /// The GUID from the podcast:guid tag in the feed. + /// This value is a unique, global identifier for the podcast. + /// + /// + /// If true, return the full text value of any text fields (ex: description). + /// If false, field value is truncated to 100 words. + /// + /// + Task ByGUID( + Guid guid, + string? feedUrl = null, + string? feedId = null, + Guid? podcastGUID = null, + bool? fulltext = null); + + /// + /// Get all episodes that have been found in the "podcast:liveitem" from the feeds + /// + /// + /// Maximum number of results to return. >=1 and <= 1000 + /// + /// + Task> Live(int? max = null); /// /// This call returns a random batch of episodes, in no specific order. @@ -100,34 +157,11 @@ public interface IEpisodesClient /// /// Maximum number of results to return. >=1 and <= 1000 /// - Task> Random(string lang = "", string category = "", string excludeCategory = "", bool fulltext = false, int max = 1); - - /// - /// Returns episodes known for a podcast by the Podcast GUID. - /// - /// - /// The GUID from the `podcast:guid` tag in the feed. - /// - /// - /// Maximum number of results to return. >=1 and <= 1000 - /// - /// - /// If present, return the full text value of any text fields (ex: description).
- /// If not provided, field value is truncated to 100 words. - /// - /// - /// Return items since the specified time. - /// - /// - Task> ByPodcastGUID(Guid guid, int max = 10, bool fulltext = false, DateTime? since = null); - - /// - /// Get all episodes that have been found in the "podcast:liveitem" from the feeds - /// - /// - /// Maximum number of results to return. >=1 and <= 1000 - /// - /// - Task> Live(int max = 10); + Task> Random( + string? lang = null, + string? category = null, + string? excludeCategory = null, + bool? fulltext = null, + int? max = null); } } \ No newline at end of file diff --git a/PodcastIndexSharp/Clients/IHubClient.cs b/PodcastIndexSharp/Clients/IHubClient.cs index b63f78d..87e932d 100644 --- a/PodcastIndexSharp/Clients/IHubClient.cs +++ b/PodcastIndexSharp/Clients/IHubClient.cs @@ -1,5 +1,6 @@ namespace PodcastIndexSharp.Clients { + using System; using System.Threading.Tasks; using PodcastIndexSharp.Response; @@ -12,6 +13,6 @@ public interface IHubClient /// The PodcastIndex Feed ID /// Podcast feed URL /// - Task PubNotify(uint? id, string url); + Task PubNotify(uint? id = null, Uri? url = null); } } \ No newline at end of file diff --git a/PodcastIndexSharp/Clients/IPodcastsClient.cs b/PodcastIndexSharp/Clients/IPodcastsClient.cs index 1824841..205c8e0 100644 --- a/PodcastIndexSharp/Clients/IPodcastsClient.cs +++ b/PodcastIndexSharp/Clients/IPodcastsClient.cs @@ -40,13 +40,22 @@ public interface IPodcastsClient /// Task ByGUID(Guid guid); + /// + /// This call returns all feeds that support the specified podcast namespace tag. + /// + /// The tag value to search for. + /// Maximum number of results to return. + /// The starting point of the results. + /// + Task> ByTag(PodcastNamespaceTag tag, int? max = null, int? startAt = null); + /// /// This call returns all feeds marked with the specified medium tag value. /// /// The medium value to search for. /// Maximum number of results to return. /// - Task> ByMedium(PodcastMedium medium, int max = 10); + Task> ByMedium(PodcastMedium medium, int? max = null); /// /// Find details about a Podcast and its feed.
@@ -74,7 +83,12 @@ public interface IPodcastsClient /// The `category` and `excludeCategory` filters can be used together to fine tune a very specific result set. /// /// - Task> Trending(int max = 10, string lang = null, string category = null, string excludeCategory = null, DateTime? since = null); + Task> Trending( + int? max = null, + string? lang = null, + string? category = null, + string? excludeCategory = null, + DateTime? since = null); /// /// This call returns all feeds that have been marked dead. diff --git a/PodcastIndexSharp/Clients/IRecentClient.cs b/PodcastIndexSharp/Clients/IRecentClient.cs index 712dec4..683ba33 100644 --- a/PodcastIndexSharp/Clients/IRecentClient.cs +++ b/PodcastIndexSharp/Clients/IRecentClient.cs @@ -26,7 +26,11 @@ public interface IRecentClient /// /// Maximum number of results to return. >=1 and <= 1000 /// - Task> Episodes(string exclude = "", bool fulltext = false, int max = 10, int? beforeId = null); + Task> Episodes( + string? exclude = null, + bool? fulltext = null, + int? max = null, + int? beforeId = null); /// /// This call returns the most recent max feeds, in reverse chronological order. @@ -53,21 +57,35 @@ public interface IRecentClient /// /// Maximum number of results to return. >= 1 and <= 1000 /// - Task> Podcasts(string lang = "", string category = "", string excludeCategory = "", int max = 10, DateTime? since = null); + Task> Podcasts( + string? lang = null, + string? category = null, + string? excludeCategory = null, + int? max = null, + DateTime? since = null); /// /// This call returns every new feed added to the index over the past 24 hours in reverse chronological order. /// - /// Return items since the specified time. /// Maximum number of results to return. >= 1 and <= 1000 + /// Return items since the specified time. + /// If true, return the results in descending order. + /// + Task> NewPodcasts(int? max = null, DateTime? since = null, bool? descending = null); + + /// + /// This call returns feeds that have added a value tag in reverse chronological order. + /// + /// + /// /// - Task> NewPodcasts(int max = 10, DateTime? since = null); + Task> NewValueFeeds(int? max = null, DateTime? since = null); /// /// This call returns the most recent max soundbites that the index has discovered. /// /// Maximum number of soundbites to return. >=1 and <= 1000 /// - Task> Soundbites(int max = 10); + Task> Soundbites(int? max = null); } } \ No newline at end of file diff --git a/PodcastIndexSharp/Clients/ISearchClient.cs b/PodcastIndexSharp/Clients/ISearchClient.cs index df7ab08..286e09b 100644 --- a/PodcastIndexSharp/Clients/ISearchClient.cs +++ b/PodcastIndexSharp/Clients/ISearchClient.cs @@ -25,7 +25,11 @@ public interface ISearchClient /// If not provided, field value is truncated to 100 words. /// /// - Task> Podcasts(string query, SearchByTermValues? values = null, bool clean = false, bool fulltext = false); + Task> Podcasts( + string query, + SearchByTermValues? values = null, + bool? clean = null, + bool? fulltext = null); /// /// This call returns all of the feeds where the title of the feed matches the search term (ignores case). @@ -38,7 +42,12 @@ public interface ISearchClient /// /// If true, include similar matches in search response /// - Task> PodcastsByTitle(string query, SearchByTermValues? value = null, bool clean = false, bool fulltext = false, bool similar = false); + Task> PodcastsByTitle( + string query, + SearchByTermValues? value = null, + bool? clean = null, + bool? fulltext = null, + bool? similar = null); /// /// This call returns all of the feeds that match the search terms in the title, author or owner of the where the medium is music. @@ -56,7 +65,13 @@ public interface ISearchClient /// If true, return the full text value of any text fields (ex: description). If false, field value is truncated to 100 words. /// /// - Task> MusicPodcasts(string query, SearchByTermValues? value = null, bool iTunesOnly = false, int max = 10, bool clean = false, bool fulltext = false); + Task> MusicPodcasts( + string query, + SearchByTermValues? value = null, + bool? iTunesOnly = null, + int? max = null, + bool? clean = null, + bool? fulltext = null); /// /// This call returns all of the episodes where the specified person is mentioned. @@ -66,7 +81,8 @@ public interface ISearchClient /// If true, return the full text value of any text fields (ex: description). /// If false, field value is truncated to 100 words. /// + /// Maximum number of results to return. /// - Task> EpisodesByPerson(string person, bool fulltext = false); + Task> EpisodesByPerson(string person, bool? fulltext = null, int? max = null); } } \ No newline at end of file diff --git a/PodcastIndexSharp/Clients/IValueClient.cs b/PodcastIndexSharp/Clients/IValueClient.cs index 23afb52..0fb788d 100644 --- a/PodcastIndexSharp/Clients/IValueClient.cs +++ b/PodcastIndexSharp/Clients/IValueClient.cs @@ -23,5 +23,24 @@ public interface IValueClient /// Podcast feed URL. /// Task ByFeedUrl(Uri url); + + /// + /// The podcast's "Value for Value" information
+ /// This call returns the information for supporting the podcast via one of the "Value for Value" + /// methods from podcast GUID. + ///
+ /// + /// + Task ByFeedGUID(Guid guid); + + /// + /// The podcast's "Value for Value" information
+ /// This call returns the information for supporting the podcast episode via one of the "Value for Value" + /// methods from podcast GUID and the episode GUID. + ///
+ /// + /// + /// + Task ByEpisodeGUID(Guid podcastGUID, Guid episodeGUID); } } \ No newline at end of file diff --git a/PodcastIndexSharp/Clients/PodcastsClient.cs b/PodcastIndexSharp/Clients/PodcastsClient.cs index e4af6ce..0e56aec 100644 --- a/PodcastIndexSharp/Clients/PodcastsClient.cs +++ b/PodcastIndexSharp/Clients/PodcastsClient.cs @@ -13,7 +13,8 @@ public PodcastsClient(PodcastIndexConfig config) : base(config) { } public async Task ByFeedId(uint id) { - var parameters = new ApiParameter[]{ + var parameters = new ApiParameter[] + { new ApiParameter("id", id) }; @@ -23,7 +24,8 @@ public async Task ByFeedId(uint id) public async Task ByFeedUrl(System.Uri url) { - var parameters = new ApiParameter[]{ + var parameters = new ApiParameter[] + { new ApiParameter("url", url) }; @@ -33,7 +35,8 @@ public async Task ByFeedUrl(System.Uri url) public async Task ByiTunesId(uint id) { - var parameters = new ApiParameter[]{ + var parameters = new ApiParameter[] + { new ApiParameter("id", id) }; @@ -41,9 +44,15 @@ public async Task ByiTunesId(uint id) return podcastResponse.Podcast; } - public async Task> Trending(int max = 10, string lang = null, string category = null, string excludeCategory = null, DateTime? since = null) + public async Task> Trending( + int? max = null, + string? lang = null, + string? category = null, + string? excludeCategory = null, + DateTime? since = null) { - var parameters = new ApiParameter[]{ + var parameters = new ApiParameter[] + { new ApiParameter("max", max), new ApiParameter("since", since), new ApiParameter("lang", lang), @@ -63,7 +72,8 @@ public async Task> Dead() public async Task ByGUID(Guid guid) { - var parameters = new ApiParameter[]{ + var parameters = new ApiParameter[] + { new ApiParameter("guid", guid) }; @@ -71,9 +81,25 @@ public async Task ByGUID(Guid guid) return podcastResponse.Podcast; } - public async Task> ByMedium(PodcastMedium medium, int max = 10) + public async Task> ByTag(PodcastNamespaceTag tag, int? max = null, int? startAt = null) { - var parameters = new ApiParameter[]{ + var parameters = new ApiParameter[] + { + new ApiParameter(tag == PodcastNamespaceTag.Value + ? "podcast-value" + : "podcast-valueTimeSplit", true), + new ApiParameter("max", max), + new ApiParameter("startAt", startAt) + }; + + var feedsResponse = await SendRequest("podcasts/bytag", parameters); + return feedsResponse.Podcasts; + } + + public async Task> ByMedium(PodcastMedium medium, int? max = null) + { + var parameters = new ApiParameter[] + { new ApiParameter("medium", medium), new ApiParameter("max", max) }; diff --git a/PodcastIndexSharp/Clients/RecentClient.cs b/PodcastIndexSharp/Clients/RecentClient.cs index 95fa37c..59f0ca8 100644 --- a/PodcastIndexSharp/Clients/RecentClient.cs +++ b/PodcastIndexSharp/Clients/RecentClient.cs @@ -10,22 +10,35 @@ public class RecentClient : BaseClient, IRecentClient { public RecentClient(PodcastIndexConfig config) : base(config) { } - public async Task> Episodes(string exclude = "", bool fulltext = false, int max = 10, int? beforeId = null) + public async Task> Episodes( + string? exclude = null, + bool? fulltext = null, + int? max = null, + int? beforeId = null) { - var parameters = new ApiParameter[]{ + var parameters = new ApiParameter[] + { new ApiParameter("max", max), new ApiParameter("excludeString", exclude), - new ApiParameter("before", beforeId), new ApiParameter("fulltext", fulltext), + new ApiParameter("beforeId", beforeId), }; - var recentEpisodesResponse = await SendRequest("recent/episodes", parameters); + var recentEpisodesResponse = await SendRequest( + "recent/episodes", parameters + ); return recentEpisodesResponse.Episodes; } - public async Task> Podcasts(string lang = "", string category = "", string excludeCategory = "'", int max = 10, DateTime? since = null) + public async Task> Podcasts( + string? lang = null, + string? category = null, + string? excludeCategory = null, + int? max = null, + DateTime? since = null) { - var parameters = new ApiParameter[]{ + var parameters = new ApiParameter[] + { new ApiParameter("max", max), new ApiParameter("lang", lang), new ApiParameter("category", category), @@ -37,25 +50,40 @@ public async Task> Podcasts(string lang = "", string category = "" return feedsResponse.Podcasts; } - public async Task> NewPodcasts(int max = 10, DateTime? since = null) + public async Task> NewPodcasts(int? max = null, DateTime? since = null, bool? descending = null) { - var parameters = new ApiParameter[]{ + var parameters = new ApiParameter[] + { new ApiParameter("max", max), new ApiParameter("since", since), + new ApiParameter("desc", descending) }; var feedsResponse = await SendRequest("recent/newfeeds", parameters); return feedsResponse.Podcasts; } - public async Task> Soundbites(int max = 10) + public async Task> Soundbites(int? max = null) { - var parameters = new ApiParameter[]{ + var parameters = new ApiParameter[] + { new ApiParameter("max", max), }; var soundbitesResponse = await SendRequest("recent/soundbites", parameters); return soundbitesResponse.Soundbites; } + + public async Task> NewValueFeeds(int? max = null, DateTime? since = null) + { + var parameters = new ApiParameter[] + { + new ApiParameter("max", max), + new ApiParameter("since", since), + }; + + var feedsResponse = await SendRequest("recent/newvaluefeeds", parameters); + return feedsResponse.Podcasts; + } } } \ No newline at end of file diff --git a/PodcastIndexSharp/Clients/SearchClient.cs b/PodcastIndexSharp/Clients/SearchClient.cs index dc75dc6..535c60e 100644 --- a/PodcastIndexSharp/Clients/SearchClient.cs +++ b/PodcastIndexSharp/Clients/SearchClient.cs @@ -10,52 +10,73 @@ public class SearchClient : BaseClient, ISearchClient { public SearchClient(PodcastIndexConfig config) : base(config) { } - public async Task> Podcasts(string query, SearchByTermValues? value = null, bool clean = false, bool fulltext = false) + public async Task> Podcasts( + string query, + SearchByTermValues? value = null, + bool? clean = null, + bool? fulltext = null) { - var parameters = new ApiParameter[] { + var parameters = new ApiParameter[] + { new ApiParameter("q", query), - new ApiParameter("val", value), new ApiParameter("clean", clean), - new ApiParameter("fulltext", fulltext) + new ApiParameter("fulltext", fulltext), + new ApiParameter("val", value ?? SearchByTermValues.any) }; var feedResponse = await SendRequest("search/byterm", parameters); return feedResponse.Podcasts; } - public async Task> EpisodesByPerson(string person, bool fulltext = false) + public async Task> EpisodesByPerson(string person, bool? fulltext = null, int? max = null) { - var parameters = new ApiParameter[] { + var parameters = new ApiParameter[] + { new ApiParameter("q", person), - new ApiParameter("fulltext", fulltext) + new ApiParameter("fulltext", fulltext), + new ApiParameter("max", max) }; var episodeResponse = await SendRequest("search/byperson", parameters); return episodeResponse.Episodes; } - public async Task> PodcastsByTitle(string query, SearchByTermValues? value = null, bool clean = false, bool fulltext = false, bool similar = false) + public async Task> PodcastsByTitle( + string query, + SearchByTermValues? value = null, + bool? clean = null, + bool? fulltext = null, + bool? similar = null) { - var parameters = new ApiParameter[] { + var parameters = new ApiParameter[] + { new ApiParameter("q", query), - new ApiParameter("val", value), new ApiParameter("clean", clean), new ApiParameter("fulltext", fulltext), - new ApiParameter("similar", similar) + new ApiParameter("similar", similar), + new ApiParameter("val", value ?? SearchByTermValues.any) }; var feedResponse = await SendRequest("search/bytitle", parameters); return feedResponse.Podcasts; } - public async Task> MusicPodcasts(string query, SearchByTermValues? value = null, bool iTunesOnly = false, int max = 10, bool clean = false, bool fulltext = false) + public async Task> MusicPodcasts( + string query, + SearchByTermValues? value = null, + bool? iTunesOnly = null, + int? max = null, + bool? clean = null, + bool? fulltext = null) { - var parameters = new ApiParameter[] { + var parameters = new ApiParameter[] + { new ApiParameter("q", query), - new ApiParameter("val", value), new ApiParameter("aponly", iTunesOnly), new ApiParameter("clean", clean), new ApiParameter("fulltext", fulltext), + new ApiParameter("val", value), + new ApiParameter("max", max) }; var feedResponse = await SendRequest("search/music/byterm", parameters); diff --git a/PodcastIndexSharp/Clients/ValueClient.cs b/PodcastIndexSharp/Clients/ValueClient.cs index a9d5f24..6e8b6dc 100644 --- a/PodcastIndexSharp/Clients/ValueClient.cs +++ b/PodcastIndexSharp/Clients/ValueClient.cs @@ -24,5 +24,26 @@ public async Task ByFeedUrl(Uri url) var valueResponse = await SendRequest("value/byfeedurl", parameters); return valueResponse.Value; } + + public async Task ByFeedGUID(Guid guid) + { + var parameters = new ApiParameter[] { new ApiParameter("guid", guid) }; + + var valueResponse = await SendRequest("value/bypodcastguid", parameters); + return valueResponse.Value; + } + + public async Task ByEpisodeGUID(Guid podcastGUID, Guid episodeGUID) + { + var parameters = new ApiParameter[] + { + new ApiParameter("podcastguid", podcastGUID), + new ApiParameter("episodeguid", episodeGUID) + }; + + var valueResponse = await SendRequest("value/byepisodeguid", parameters); + return valueResponse.Value; + } + } } \ No newline at end of file diff --git a/PodcastIndexSharp/Enums/PodcastNamespaceTag.cs b/PodcastIndexSharp/Enums/PodcastNamespaceTag.cs new file mode 100644 index 0000000..24816dc --- /dev/null +++ b/PodcastIndexSharp/Enums/PodcastNamespaceTag.cs @@ -0,0 +1,15 @@ +namespace PodcastIndexSharp.Enums +{ + public enum PodcastNamespaceTag + { + /// + /// podcast:value + /// + Value = 0, + + /// + /// podcast:valueTimeSplit + /// + ValueTimeSplit = 1, + } +} \ No newline at end of file diff --git a/PodcastIndexSharp/JsonConverters/UnixTimestampConverter.cs b/PodcastIndexSharp/JsonConverters/UnixTimestampConverter.cs index 26764a0..0304818 100644 --- a/PodcastIndexSharp/JsonConverters/UnixTimestampConverter.cs +++ b/PodcastIndexSharp/JsonConverters/UnixTimestampConverter.cs @@ -10,7 +10,7 @@ public override bool CanConvert(Type objectType) return typeof(DateTime).IsAssignableFrom(objectType); } - public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) + public override object ReadJson(JsonReader reader, Type objectType, object? existingValue, JsonSerializer serializer) { var timestamp = serializer.Deserialize(reader); var dateTime = new DateTime(1970, 1, 1, 0, 0, 0, 0, System.DateTimeKind.Utc); @@ -18,7 +18,7 @@ public override object ReadJson(JsonReader reader, Type objectType, object exist return dateTime.AddSeconds(timestamp).ToLocalTime(); } - public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) + public override void WriteJson(JsonWriter writer, object? value, JsonSerializer serializer) { throw new NotImplementedException(); } diff --git a/PodcastIndexSharp/Model/ApiParemeter.cs b/PodcastIndexSharp/Model/ApiParemeter.cs index 390efd8..d61c3cb 100644 --- a/PodcastIndexSharp/Model/ApiParemeter.cs +++ b/PodcastIndexSharp/Model/ApiParemeter.cs @@ -7,9 +7,9 @@ public class ApiParameter { public string Name { get; set; } - public object Value { get; set; } + public object? Value { get; set; } - public ApiParameter(string name, object value) + public ApiParameter(string name, object? value) { Name = name; Value = value; diff --git a/PodcastIndexSharp/Model/Category.cs b/PodcastIndexSharp/Model/Category.cs index 1e9c1cf..7335976 100644 --- a/PodcastIndexSharp/Model/Category.cs +++ b/PodcastIndexSharp/Model/Category.cs @@ -4,6 +4,6 @@ public class Category { public uint? Id { get; set; } - public string Name { get; set; } + public string Name { get; set; } = null!; } } \ No newline at end of file diff --git a/PodcastIndexSharp/Model/Episode.cs b/PodcastIndexSharp/Model/Episode.cs index 6bf0c92..d97be40 100644 --- a/PodcastIndexSharp/Model/Episode.cs +++ b/PodcastIndexSharp/Model/Episode.cs @@ -9,13 +9,13 @@ public class Episode { public long Id { get; set; } - public string Title { get; set; } + public string Title { get; set; } = null!; - public Uri Link { get; set; } + public Uri Link { get; set; } = null!; - public string Description { get; set; } + public string Description { get; set; } = null!; - public string Guid { get; set; } + public string Guid { get; set; } = null!; [JsonConverter(typeof(UnixTimestampConverter))] public DateTime DatePublished { get; set; } @@ -23,9 +23,9 @@ public class Episode [JsonConverter(typeof(UnixTimestampConverter))] public DateTime DateCrawled { get; set; } - public Uri EnclosureUrl { get; set; } + public Uri EnclosureUrl { get; set; } = null!; - public string EnclosureType { get; set; } + public string EnclosureType { get; set; } = null!; public long EnclosureLength { get; set; } @@ -36,28 +36,28 @@ public class Episode [JsonProperty("Episode")] public int? EpisodeNumber { get; set; } - public string EpisodeType { get; set; } + public string EpisodeType { get; set; } = null!; public int? Season { get; set; } - public Uri Image { get; set; } + public Uri Image { get; set; } = null!; public int? FeedItunesId { get; set; } - public Uri FeedImage { get; set; } + public Uri FeedImage { get; set; } = null!; public int? FeedId { get; set; } - public Uri FeedUrl { get; set; } + public Uri FeedUrl { get; set; } = null!; - public string FeedAuthor { get; set; } + public string FeedAuthor { get; set; } = null!; - public string FeedTitle { get; set; } + public string FeedTitle { get; set; } = null!; - public string FeedLanguage { get; set; } + public string FeedLanguage { get; set; } = null!; - public Uri ChaptersUrl { get; set; } + public Uri ChaptersUrl { get; set; } = null!; - public Uri TranscriptUrl { get; set; } + public Uri TranscriptUrl { get; set; } = null!; } } \ No newline at end of file diff --git a/PodcastIndexSharp/Model/FeedBase.cs b/PodcastIndexSharp/Model/FeedBase.cs index f03ec38..ce34ddb 100644 --- a/PodcastIndexSharp/Model/FeedBase.cs +++ b/PodcastIndexSharp/Model/FeedBase.cs @@ -6,6 +6,6 @@ public class FeedBase { public int Id { get; set; } - public Uri Url { get; set; } + public Uri Url { get; set; } = null!; } } \ No newline at end of file diff --git a/PodcastIndexSharp/Model/FeedMeta.cs b/PodcastIndexSharp/Model/FeedMeta.cs index b6905a8..6370391 100644 --- a/PodcastIndexSharp/Model/FeedMeta.cs +++ b/PodcastIndexSharp/Model/FeedMeta.cs @@ -4,14 +4,14 @@ namespace PodcastIndexSharp.Model public class FeedMeta : FeedBase { - public string Title { get; set; } + public string Title { get; set; } = null!; - public string Author { get; set; } + public string Author { get; set; } = null!; - public uint? iTunesId { get; set; } + public uint? iTunesId { get; set; } = null!; - public string Language { get; set; } + public string Language { get; set; } = null!; - public Dictionary Categories { get; set; } + public Dictionary Categories { get; set; } = null!; } } \ No newline at end of file diff --git a/PodcastIndexSharp/Model/Funding.cs b/PodcastIndexSharp/Model/Funding.cs index 768cfc7..0475750 100644 --- a/PodcastIndexSharp/Model/Funding.cs +++ b/PodcastIndexSharp/Model/Funding.cs @@ -4,8 +4,8 @@ namespace PodcastIndexSharp.Model public class Funding { - public Uri URL { get; set; } + public Uri URL { get; set; } = null!; - public string Message { get; set; } + public string Message { get; set; } = null!; } } \ No newline at end of file diff --git a/PodcastIndexSharp/Model/Podcast.cs b/PodcastIndexSharp/Model/Podcast.cs index 0a21896..3003212 100644 --- a/PodcastIndexSharp/Model/Podcast.cs +++ b/PodcastIndexSharp/Model/Podcast.cs @@ -8,17 +8,17 @@ namespace PodcastIndexSharp.Model public class Podcast : FeedMeta { - public Uri OriginalUrl { get; set; } + public Uri OriginalUrl { get; set; } = null!; - public Uri Link { get; set; } + public Uri Link { get; set; } = null!; - public string Description { get; set; } + public string Description { get; set; } = null!; - public string OwnerName { get; set; } + public string OwnerName { get; set; } = null!; - public Uri Image { get; set; } + public Uri Image { get; set; } = null!; - public Uri Artwork { get; set; } + public Uri Artwork { get; set; } = null!; [JsonConverter(typeof(UnixTimestampConverter))] public DateTime LastUpdateTime { get; set; } @@ -37,17 +37,17 @@ public class Podcast : FeedMeta public HttpStatusCode LastHttpStatus { get; set; } - public string ContentType { get; set; } + public string ContentType { get; set; } = null!; public int? TrendScore { get; set; } - public string Generator { get; set; } + public string Generator { get; set; } = null!; public FeedType Type { get; set; } public int? Dead { get; set; } - public string Chash { get; set; } + public string Chash { get; set; } = null!; public int? EpisodeCount { get; set; } @@ -59,8 +59,8 @@ public class Podcast : FeedMeta public long? ImageUrlHash { get; set; } - public Value Value { get; set; } + public Value Value { get; set; } = null!; - public Funding Funding { get; set; } + public Funding Funding { get; set; } = null!; } } \ No newline at end of file diff --git a/PodcastIndexSharp/Model/Soundbite.cs b/PodcastIndexSharp/Model/Soundbite.cs index 1a1c32f..a0d92ad 100644 --- a/PodcastIndexSharp/Model/Soundbite.cs +++ b/PodcastIndexSharp/Model/Soundbite.cs @@ -4,9 +4,9 @@ namespace PodcastIndexSharp.Model public class Soundbite { - public Uri EnclosureUrl { get; set; } + public Uri EnclosureUrl { get; set; } = null!; - public string Title { get; set; } + public string Title { get; set; } = null!; public int StartTime { get; set; } @@ -14,11 +14,11 @@ public class Soundbite public long EpisodeId { get; set; } - public string EpisodeTitle { get; set; } + public string EpisodeTitle { get; set; } = null!; - public string FeedTitle { get; set; } + public string FeedTitle { get; set; } = null!; - public Uri FeedUrl { get; set; } + public Uri FeedUrl { get; set; } = null!; public int FeedId { get; set; } } diff --git a/PodcastIndexSharp/Model/Value.cs b/PodcastIndexSharp/Model/Value.cs index 3f4bc39..c2203d5 100644 --- a/PodcastIndexSharp/Model/Value.cs +++ b/PodcastIndexSharp/Model/Value.cs @@ -4,8 +4,8 @@ namespace PodcastIndexSharp.Model public class Value { - public ValueModel Model { get; set; } + public ValueModel Model { get; set; } = null!; - public List Suggested { get; set; } + public List Suggested { get; set; } = null!; } } \ No newline at end of file diff --git a/PodcastIndexSharp/Model/ValueDestination.cs b/PodcastIndexSharp/Model/ValueDestination.cs index 7a4e549..9cc9a7e 100644 --- a/PodcastIndexSharp/Model/ValueDestination.cs +++ b/PodcastIndexSharp/Model/ValueDestination.cs @@ -2,11 +2,11 @@ namespace PodcastIndexSharp.Model { public class ValueDestination { - public string Name { get; set; } + public string Name { get; set; } = null!; - public string Address { get; set; } + public string Address { get; set; } = null!; - public string Type { get; set; } + public string Type { get; set; } = null!; public int Split { get; set; } diff --git a/PodcastIndexSharp/Model/ValueModel.cs b/PodcastIndexSharp/Model/ValueModel.cs index 382cfb7..a8eeca3 100644 --- a/PodcastIndexSharp/Model/ValueModel.cs +++ b/PodcastIndexSharp/Model/ValueModel.cs @@ -2,10 +2,10 @@ namespace PodcastIndexSharp.Model { public class ValueModel { - public string Type { get; set; } + public string Type { get; set; } = null!; - public string Method { get; set; } + public string Method { get; set; } = null!; - public string Suggested { get; set; } + public string Suggested { get; set; } = null!; } } \ No newline at end of file diff --git a/PodcastIndexSharp/PodcastIndexConfig.cs b/PodcastIndexSharp/PodcastIndexConfig.cs index d698faf..7944515 100644 --- a/PodcastIndexSharp/PodcastIndexConfig.cs +++ b/PodcastIndexSharp/PodcastIndexConfig.cs @@ -8,8 +8,8 @@ public class PodcastIndexConfig public string UserAgent { get; set; } = "PodcastIndexSharp"; - public string AuthKey { get; set; } + public string AuthKey { get; set; } = null!; - public string Secret { get; set; } + public string Secret { get; set; } = null!; } } \ No newline at end of file diff --git a/PodcastIndexSharp/PodcastIndexSharp.csproj b/PodcastIndexSharp/PodcastIndexSharp.csproj index d9b1c64..facc33c 100644 --- a/PodcastIndexSharp/PodcastIndexSharp.csproj +++ b/PodcastIndexSharp/PodcastIndexSharp.csproj @@ -4,7 +4,7 @@ netstandard2.1 PodcastIndexSharp package-icon.png - 1.1.0 + 2.0.0 Bobby Burden III brb3 .NET Standard client library for interacting with the PodcastIndex.org API. @@ -12,6 +12,7 @@ git MIT podcast,podcastindex + enable @@ -20,6 +21,7 @@ + diff --git a/PodcastIndexSharp/Response/AbstractResponse.cs b/PodcastIndexSharp/Response/AbstractResponse.cs index 1d64d7c..8dadfac 100644 --- a/PodcastIndexSharp/Response/AbstractResponse.cs +++ b/PodcastIndexSharp/Response/AbstractResponse.cs @@ -1,11 +1,11 @@ -namespace PodcastIndexSharp +namespace PodcastIndexSharp.Response { public abstract class AbstractResponse { - public string Status { get; set; } + public string Status { get; set; } = null!; - public object Query { get; set; } + public object Query { get; set; } = null!; - public string Description { get; set; } + public string Description { get; set; } = null!; } } \ No newline at end of file diff --git a/PodcastIndexSharp/Response/CategoriesListResponse.cs b/PodcastIndexSharp/Response/CategoriesListResponse.cs index 6c24c17..411b6bf 100644 --- a/PodcastIndexSharp/Response/CategoriesListResponse.cs +++ b/PodcastIndexSharp/Response/CategoriesListResponse.cs @@ -7,7 +7,7 @@ namespace PodcastIndexSharp.Response public class CategoriesListResponse : AbstractResponse { [JsonProperty("feeds")] - public List Categories { get; set; } + public List Categories { get; set; } = new List(); public int Count { get; set; } } diff --git a/PodcastIndexSharp/Response/DeadResponse.cs b/PodcastIndexSharp/Response/DeadResponse.cs index 051f598..922435d 100644 --- a/PodcastIndexSharp/Response/DeadResponse.cs +++ b/PodcastIndexSharp/Response/DeadResponse.cs @@ -9,7 +9,7 @@ namespace PodcastIndexSharp.Response public class DeadResponse : AbstractResponse { [JsonProperty("feeds")] - public List Podcasts { get; set; } + public List Podcasts { get; set; } = new List(); public int Count { get; set; } diff --git a/PodcastIndexSharp/Response/EpisodeResponse.cs b/PodcastIndexSharp/Response/EpisodeResponse.cs index f08d874..6c01516 100644 --- a/PodcastIndexSharp/Response/EpisodeResponse.cs +++ b/PodcastIndexSharp/Response/EpisodeResponse.cs @@ -4,6 +4,6 @@ namespace PodcastIndexSharp.Response public class EpisodeResponse : AbstractResponse { - public Episode Episode { get; set; } + public Episode Episode { get; set; } = null!; } } \ No newline at end of file diff --git a/PodcastIndexSharp/Response/EpisodesResponse.cs b/PodcastIndexSharp/Response/EpisodesResponse.cs index 6c7b796..8203e00 100644 --- a/PodcastIndexSharp/Response/EpisodesResponse.cs +++ b/PodcastIndexSharp/Response/EpisodesResponse.cs @@ -8,7 +8,7 @@ public class EpisodesResponse : AbstractResponse { // This is used so that `items` and `episodes` can be supported in the JSON response. // Note that "/episodes/random" and "/episodes/byfeedid" use an otherwise similar structure. - private List _episodes; + private List _episodes = new List(); [JsonProperty("items")] public List Episodes @@ -18,7 +18,7 @@ public List Episodes } [JsonProperty("episodes")] - public List RandomEpisodes { get; set; } + public List RandomEpisodes { get; set; } = new List(); public int Count { get; set; } } diff --git a/PodcastIndexSharp/Response/PodcastResponse.cs b/PodcastIndexSharp/Response/PodcastResponse.cs index 45d7ecb..85b7559 100644 --- a/PodcastIndexSharp/Response/PodcastResponse.cs +++ b/PodcastIndexSharp/Response/PodcastResponse.cs @@ -6,6 +6,6 @@ namespace PodcastIndexSharp.Response public class PodcastResponse : AbstractResponse { [JsonProperty("feed")] - public Podcast Podcast { get; set; } + public Podcast Podcast { get; set; } = null!; } } \ No newline at end of file diff --git a/PodcastIndexSharp/Response/RecentEpisodesResponse.cs b/PodcastIndexSharp/Response/RecentEpisodesResponse.cs index 55f77fa..ffeeddb 100644 --- a/PodcastIndexSharp/Response/RecentEpisodesResponse.cs +++ b/PodcastIndexSharp/Response/RecentEpisodesResponse.cs @@ -7,6 +7,6 @@ namespace PodcastIndexSharp.Response public class RecentEpisodesResponse : AbstractResponse { [JsonProperty("items")] - public List Episodes { get; set; } + public List Episodes { get; set; } = new List(); } } \ No newline at end of file diff --git a/PodcastIndexSharp/Response/SoundbitesResponse.cs b/PodcastIndexSharp/Response/SoundbitesResponse.cs index 4111361..e649db0 100644 --- a/PodcastIndexSharp/Response/SoundbitesResponse.cs +++ b/PodcastIndexSharp/Response/SoundbitesResponse.cs @@ -7,7 +7,7 @@ namespace PodcastIndexSharp.Response public class SoundbitesResponse : AbstractResponse { [JsonProperty("items")] - public List Soundbites { get; set; } + public List Soundbites { get; set; } = new List(); public int Count { get; set; } } diff --git a/PodcastIndexSharp/Response/StatsResponse.cs b/PodcastIndexSharp/Response/StatsResponse.cs index 2c23463..a2ca6d9 100644 --- a/PodcastIndexSharp/Response/StatsResponse.cs +++ b/PodcastIndexSharp/Response/StatsResponse.cs @@ -4,6 +4,6 @@ namespace PodcastIndexSharp.Response public class StatsResponse : AbstractResponse { - public Stats Stats { get; set; } + public Stats Stats { get; set; } = null!; } } \ No newline at end of file diff --git a/PodcastIndexSharp/Response/TrendingResponse.cs b/PodcastIndexSharp/Response/TrendingResponse.cs index e7b8fd0..d45a6c0 100644 --- a/PodcastIndexSharp/Response/TrendingResponse.cs +++ b/PodcastIndexSharp/Response/TrendingResponse.cs @@ -9,7 +9,7 @@ namespace PodcastIndexSharp.Response public class TrendingResponse : AbstractResponse { [JsonProperty("feeds")] - public List Podcasts { get; set; } + public List Podcasts { get; set; } = new List(); public int Count { get; set; } diff --git a/PodcastIndexSharp/Response/ValueResponse.cs b/PodcastIndexSharp/Response/ValueResponse.cs index d61484a..408c30f 100644 --- a/PodcastIndexSharp/Response/ValueResponse.cs +++ b/PodcastIndexSharp/Response/ValueResponse.cs @@ -4,6 +4,6 @@ namespace PodcastIndexSharp.Response public class ValueResponse : AbstractResponse { - public Value Value { get; set; } + public Value Value { get; set; } = null!; } } \ No newline at end of file