using ChrisKaczor.FeverClient.Converters; using ChrisKaczor.FeverClient.Models; using ChrisKaczor.FeverClient.Responses; using RestSharp; using System.Text.Json; namespace ChrisKaczor.FeverClient; public class FeverClient { private readonly JsonSerializerOptions _jsonSerializerOptions; private readonly RestClient _restClient; public FeverClient(string url, string apiKey) { _jsonSerializerOptions = new JsonSerializerOptions(); _jsonSerializerOptions.Converters.Add(new EpochConverter()); _jsonSerializerOptions.Converters.Add(new BoolConverter()); _jsonSerializerOptions.Converters.Add(new CommaSeparatedListConverter()); _restClient = new RestClient(url); _restClient.AddDefaultParameter("api_key", apiKey); } private async Task PostRestRequest(string api) { var request = new RestRequest($"/fever/?api&{api}", Method.Post) { AlwaysMultipartFormData = true }; var response = await _restClient.PostAsync(request); if (response == null) throw new Exception("Failed to get response from Fever API"); if (!response.IsSuccessStatusCode) throw new Exception($"Error: {response.StatusCode} - {response.Content}"); if (response.Content == null) throw new Exception("Response content is null"); try { var responseObject = JsonSerializer.Deserialize(response.Content, _jsonSerializerOptions); if (responseObject == null) throw new Exception($"Failed to deserialize response content - {response.Content}"); return responseObject; } catch (Exception e) { throw new Exception($"Failed to deserialize response content - {response.Content}", e); } } public async Task> GetGroups() { var groupsResponse = await PostRestRequest("groups"); return groupsResponse.Groups; } public async Task> GetFeeds() { var feedsResponse = await PostRestRequest("feeds"); return feedsResponse.Feeds; } public async Task> GetFavicons() { var faviconsResponse = await PostRestRequest("favicons"); return faviconsResponse.Favicons; } public async Task> GetFeedItems(int sinceId = 1) { var feedItemsResponse = await PostRestRequest($"items&since_id={sinceId}"); return feedItemsResponse.FeedItems; } public async IAsyncEnumerable> GetAllFeedItems() { var maxId = 1; do { var response = await GetFeedItems(maxId); var feedItemList = response.ToArray(); yield return feedItemList; if (feedItemList.Length == 0) yield break; maxId = feedItemList.Max(fi => fi.Id); } while (true); } public async Task MarkFeedItemAsRead(int feedItemId) { await PostRestRequest($"mark=item&as=read&id={feedItemId}"); } }