Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/dotnet.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
2 changes: 1 addition & 1 deletion .vscode/launch.json
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down
13 changes: 13 additions & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -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"
]
}
2 changes: 1 addition & 1 deletion PodcastIndexSharp.Example/PodcastIndexSharp.Example.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,6 @@
</ItemGroup>
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net5.0</TargetFramework>
<TargetFramework>net9.0</TargetFramework>
</PropertyGroup>
</Project>
6 changes: 3 additions & 3 deletions PodcastIndexSharp.Example/Program.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
namespace Example
namespace PodcastIndexSharp.Example
{
using System;
using System.Threading.Tasks;
Expand Down Expand Up @@ -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
Expand Down
11 changes: 5 additions & 6 deletions PodcastIndexSharp.Example/appsettings.local.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
{
"PodcastIndex": {
"UserAgent": "",
"AuthKey": "",
"Secret": ""
}
{
"PodcastIndex": {
"AuthKey": "",
"Secret": ""
}
}
1 change: 1 addition & 0 deletions PodcastIndexSharp.Test/Clients/BaseClientTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
4 changes: 2 additions & 2 deletions PodcastIndexSharp.Test/Clients/SearchClientTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ namespace PodcastIndexSharp.Test.Clients;

public class SearchClientTest : ClientTest
{
private SearchClient searchClient;
private readonly SearchClient searchClient;

public SearchClientTest()
{
Expand All @@ -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?";
Expand Down
4 changes: 3 additions & 1 deletion PodcastIndexSharp.Test/PodcastIndexSharp.Test.csproj
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<TargetFramework>net9.0</TargetFramework>
<Nullable>enable</Nullable>

<IsPackable>false</IsPackable>
Expand All @@ -13,6 +13,8 @@
<PrivateAssets>all</PrivateAssets>
</PackageReference>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.11.0" />
<PackageReference Include="System.Net.Http" Version="4.3.4" />
<PackageReference Include="System.Text.RegularExpressions" Version="4.3.1" />
<PackageReference Include="xunit" Version="2.4.1" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.3">
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
Expand Down
10 changes: 6 additions & 4 deletions PodcastIndexSharp/Clients/AddClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,13 @@ public class AddClient : BaseClient, IAddClient
{
public AddClient(PodcastIndexConfig config) : base(config) { }

public async Task<AddResponse> ByFeedUrl(string url, uint iTunesId, string chash)
public async Task<AddResponse> 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<AddResponse>("add/byfeedurl", parameters);
Expand All @@ -22,7 +23,8 @@ public async Task<AddResponse> ByFeedUrl(string url, uint iTunesId, string chash

public async Task<AddResponse> ByiTunesId(uint iTunesId)
{
var parameters = new ApiParameter[]{
var parameters = new ApiParameter[]
{
new ApiParameter("id", iTunesId)
};

Expand Down
1 change: 1 addition & 0 deletions PodcastIndexSharp/Clients/BaseClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ namespace PodcastIndexSharp.Clients
using Flurl.Http;
using PodcastIndexSharp.Exceptions;
using PodcastIndexSharp.Model;
using PodcastIndexSharp.Response;

/// <summary>
/// The Base API client that all PodcastIndex API calls use. This class should not be used directly.
Expand Down
110 changes: 89 additions & 21 deletions PodcastIndexSharp/Clients/EpisodesClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,19 +10,32 @@ public class EpisodesClient : BaseClient, IEpisodesClient
{
public EpisodesClient(PodcastIndexConfig config) : base(config) { }

public async Task<List<Episode>> ByFeedId(uint id, int max = 10, bool fulltext = false, DateTime? since = null)
public async Task<List<Episode>> 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<List<Episode>> ByFeedId(uint[] id, int max = 10, bool fulltext = false, DateTime? since = null)
public async Task<List<Episode>> 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<List<Episode>> ByFeedUrl(Uri url, int max = 10, bool fulltext = false, DateTime? since = null)
public async Task<List<Episode>> 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),
Expand All @@ -33,14 +46,20 @@ public async Task<List<Episode>> ByFeedUrl(Uri url, int max = 10, bool fulltext
return episodesResponse.Episodes;
}

public async Task<List<Episode>> ByiTunesId(uint id, int max = 10, bool fulltext = false, DateTime? since = null)
public async Task<List<Episode>> 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<Episode> ById(uint id, bool fulltext = false)
public async Task<Episode> ById(uint id, bool? fulltext = null)
{
var parameters = new ApiParameter[]{
var parameters = new ApiParameter[]
{
new ApiParameter("id", id),
new ApiParameter("fulltext", fulltext)
};
Expand All @@ -49,9 +68,15 @@ public async Task<Episode> ById(uint id, bool fulltext = false)
return episodeResponse.Episode;
}

public async Task<List<Episode>> Random(string lang = "", string category = "", string excludeCategory = "", bool fulltext = false, int max = 1)
public async Task<List<Episode>> 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),
Expand All @@ -60,12 +85,17 @@ public async Task<List<Episode>> Random(string lang = "", string category = "",
};

var episodesResponse = await SendRequest<EpisodesResponse>("episodes/random", parameters);
return episodesResponse.Episodes;
return episodesResponse.RandomEpisodes;
}

public async Task<List<Episode>> ByPodcastGUID(Guid guid, int max = 10, bool fulltext = false, DateTime? since = null)
public async Task<List<Episode>> 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),
Expand All @@ -76,29 +106,67 @@ public async Task<List<Episode>> ByPodcastGUID(Guid guid, int max = 10, bool ful
return episodesResponse.Episodes;
}

public async Task<List<Episode>> Live(int max = 10)
public async Task<List<Episode>> Live(int? max = null)
{
var parameters = new ApiParameter[]{
var parameters = new ApiParameter[]
{
new ApiParameter("max", max),
};

var episodesResponse = await SendRequest<EpisodesResponse>("episodes/live", parameters);
return episodesResponse.Episodes;
}

private async Task<List<Episode>> Episodes(string id, int max, bool fulltext, bool itunes, DateTime? since)
private async Task<List<Episode>> 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<EpisodesResponse>(
itunes ? "episodes/byitunesid" : "episodes/byfeedid",
itunes.Value ? "episodes/byitunesid" : "episodes/byfeedid",
parameters);
return episodeResponse.Episodes;
}

public async Task<Episode> 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<EpisodeResponse>("episodes/byguid", parameters);
return episodesResponse.Episode;
}
}
}
15 changes: 11 additions & 4 deletions PodcastIndexSharp/Clients/HubClient.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
namespace PodcastIndexSharp.Clients
{
using System;
using System.Threading.Tasks;
using PodcastIndexSharp.Model;
using PodcastIndexSharp.Response;
Expand All @@ -8,11 +9,17 @@ public class HubClient : BaseClient, IHubClient
{
public HubClient(PodcastIndexConfig config) : base(config) { }

public async Task<HubResponse> PubNotify(uint? id, string url)
public async Task<HubResponse> 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<HubResponse>("hub/pubnotify", parameters);
Expand Down
4 changes: 2 additions & 2 deletions PodcastIndexSharp/Clients/IAddClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,10 @@ public interface IAddClient
/// If a feed already exists, you will get its existing Feed ID returned in the response object.
/// </summary>
/// <param name="url"></param>
/// <param name="iTunesId"></param>
/// <param name="chash">MD5 hash of the title, link, feedLanguage, generator, author, ownerName, ownerEmail. Allows for easier duplicate checking.</param>
/// <param name="iTunesId"></param>
/// <returns></returns>
Task<AddResponse> ByFeedUrl(string url, uint iTunesId, string chash);
Task<AddResponse> ByFeedUrl(string url, string chash, uint? iTunesId = null);

/// <summary>
/// This call adds a podcast to the index using its iTunes ID.
Expand Down
Loading
Loading