using System.Xml.Linq; namespace AnimeAnnouncer.Torrents { public record NyaaRssItem( String Title, String Published, String Category, String CategoryID, String Size, String Link, String Description, String PostID); /// /// Reads Nyaa RSS feeds and downloads the .torrent files they link to. /// public class NyaaRssReader { private readonly HttpClient httpClient; public NyaaRssReader(HttpClient? httpClient = null) { this.httpClient = httpClient ?? new HttpClient(); } /// /// Converts a Nyaa search URL into its RSS equivalent, if it isn't one already. /// public static String ToRssUrl(String url) { return url.Contains("rss") ? url : url + "&page=rss"; } public async Task> ReadAsync(String url) { var response = await httpClient.GetStringAsync(ToRssUrl(url)); return Parse(response); } public static List Parse(String rssXml) { XDocument doc = XDocument.Parse(rssXml); XNamespace nyaaNS = doc.Root!.GetNamespaceOfPrefix("nyaa") ?? XNamespace.None; return (from item in doc.Descendants("channel").Elements("item") select new NyaaRssItem( Title: item.Element("title")?.Value ?? String.Empty, Published: item.Element("pubDate")?.Value ?? String.Empty, Category: item.Element(nyaaNS + "category")?.Value ?? String.Empty, CategoryID: item.Element(nyaaNS + "categoryId")?.Value ?? String.Empty, Size: item.Element(nyaaNS + "size")?.Value ?? String.Empty, Link: item.Element("link")?.Value ?? String.Empty, Description: item.Element("description")?.Value ?? String.Empty, PostID: item.Element("guid")?.Value ?? String.Empty )).ToList(); } public Task DownloadTorrentAsync(NyaaRssItem item) { return httpClient.GetByteArrayAsync(item.Link); } } }