public static async Task <ThingResponse.Item> GetBoardGameAsync(this IBoardGameGeekXmlApi2Client bggClient, int id) { var request = new ThingRequest( new[] { id }, types: new[] { "boardgame" }, stats: true); ThingResponse response = await bggClient.GetThingAsync(request); return(response.Result.FirstOrDefault()); }
public static async Task <IEnumerable <ThingResponse.Item> > GetBoardGamesAsync(this IBoardGameGeekXmlApi2Client bggClient, params int[] ids) { var request = new ThingRequest( ids, types: new[] { "boardgame" }, stats: true); ThingResponse response = await bggClient.GetThingAsync(request); return(response.Result); }
public async Task <ThingResponse> GetThingAsync(ThingRequest request) { if (request == null) { throw new ArgumentNullException(nameof(request)); } bool comments = request.Comments.GetValueOrDefault(); bool ratingComments = request.RatingComments.GetValueOrDefault(); if (comments == true && ratingComments == true) { // If request is sent, and both are true, the comments will supercede the rating comments. // Figured it was best to just call this out as an error, rather than return unexpected information. throw new ArgumentException("The comments and ratingcomments properties are mutually exclusive."); } XDocument xdoc = await GetXDocumentAsync(request.RelativeUrl).ConfigureAwait(false); ThingResponse response = Map(xdoc); return(response); #region Helpers ThingResponse Map(XDocument doc) { return(new ThingResponse(MapItems(doc))); } IEnumerable <ThingResponse.Item> MapItems(XDocument document) { return(from item in xdoc.Descendants("item") let versions = item.Element("versions") let videos = item.Element("videos") select new ThingResponse.Item { Id = item.AttributeValueAsInt32("id"), Type = item.AttributeValue("type"), Thumbnail = item.ElementValue("thumbnail"), Image = item.ElementValue("image"), Name = item.Elements("name").FirstOrDefault(x => x.AttributeValue("type") == "primary")?.AttributeValue(), AlternateNames = (from n in item.Elements("name").Where(x => x.AttributeValue("type") != "primary") select n.AttributeValue()).ToList(), Description = WebUtility.HtmlDecode(item.ElementValue("description")), YearPublished = item.Element("yearpublished").AttributeValueAsNullableInt32(), ReleaseDate = item.Element("releasedate").AttributeValueAsNullableDateTime(), MinPlayers = item.Element("minplayers").AttributeValueAsInt32(), MaxPlayers = item.Element("maxplayers").AttributeValueAsInt32(), PlayingTime = item.Element("playingtime").AttributeValueAsNullableInt32(), MinPlayingTime = item.Element("minplaytime").AttributeValueAsNullableInt32(), MaxPlayingTime = item.Element("maxplaytime").AttributeValueAsNullableInt32(), MinAge = item.Element("minage").AttributeValueAsNullableInt32(), Polls = MapPolls(item).ToList(), Links = MapLinks(item).ToList(), Versions = MapVersions(versions), Videos = MapVideoCollection(videos), Statistics = MapStatistics(item.Element("statistics")), Comments = comments ? MapComments(item.Element("comments")) : null, RatingComments = ratingComments ? MapRatingComments(item.Element("comments")) : null, Marketplace = MapMarketplace(item.Element("marketplacelistings")) }); } IEnumerable <ThingResponse.Poll> MapPolls(XElement thingEl) { return(from poll in thingEl.Elements("poll") let results = poll.Elements("results") select new ThingResponse.Poll { Name = poll.AttributeValue("name"), Title = poll.AttributeValue("title"), TotalVotes = poll.AttributeValueAsInt32("totalvotes"), Results = (from r in results let res = r.Elements("result") select new ThingResponse.PollResults { NumPlayers = r.AttributeValueAsNullableInt32("numplayers"), // only found on the suggested num players Results = (from x in res select new ThingResponse.PollResult { Value = x.AttributeValue(), NumVotes = x.AttributeValueAsInt32("numvotes") }).ToList() }).ToList() }); } IEnumerable <ThingResponse.Link> MapLinks(XElement thingEl) { return(from link in thingEl.Elements("link") select new ThingResponse.Link { Type = link.AttributeValue("type"), Id = link.AttributeValueAsInt32("id"), Value = link.AttributeValue() }); } List <ThingResponse.Version> MapVersions(XElement versionsEl) { if (versionsEl == null) { return(null); } var versions = new IEnumerable <ThingResponse.Version>[] { MapBoardGameVersions(versionsEl), MapRpgItemVersion(versionsEl), MapVideoGameVersion(versionsEl), MapVideoGameCharacterVersion(versionsEl) }; return(versions.SelectMany(x => x).ToList()); } IEnumerable <ThingResponse.BoardGameVersion> MapBoardGameVersions(XElement versionsEl) { return(from v in versionsEl.Elements("item") where v.Attribute("type").Value == "boardgameversion" select new ThingResponse.BoardGameVersion { Type = v.AttributeValue("type"), Id = v.AttributeValueAsInt32("id"), Thumbnail = v.ElementValue("thumbnail"), Image = v.ElementValue("image"), Name = v.Element("name").AttributeValue(), YearPublished = v.Element("yearpublished").AttributeValueAsInt32(), ProductCode = v.Element("productcode").AttributeValue(), Width = v.Element("width").AttributeValueAsNullableDouble(), Length = v.Element("length").AttributeValueAsNullableDouble(), Depth = v.Element("depth").AttributeValueAsNullableDouble(), Weight = v.Element("weight").AttributeValueAsNullableDouble(), Links = MapLinks(v).ToList() }); } IEnumerable <ThingResponse.RpgItemVersion> MapRpgItemVersion(XElement versionsEl) { return(from v in versionsEl.XPathSelectElements("item[@type='rpgitemversion']") select new ThingResponse.RpgItemVersion { Type = v.AttributeValue("type"), Id = v.AttributeValueAsInt32("id"), Thumbnail = v.ElementValue("thumbnail"), Image = v.ElementValue("image"), Name = v.Element("name").AttributeValue(), YearPublished = v.Element("yearpublished").AttributeValueAsInt32(), Format = v.Element("format").AttributeValue(), ProductCode = v.Element("productcode").AttributeValue(), PageCount = v.Element("pagecount").AttributeValueAsNullableInt32(), Isbn10 = v.Element("isbn10").AttributeValue(), Isbn13 = v.Element("isbn13").AttributeValue(), Width = v.Element("width").AttributeValueAsNullableDouble(), Height = v.Element("height").AttributeValueAsNullableDouble(), Weight = v.Element("weight").AttributeValueAsNullableDouble(), Description = WebUtility.HtmlDecode(v.ElementValue("description")), Links = (from l in v.Elements("link") select new ThingResponse.Link { Type = l.AttributeValue("type"), Id = l.AttributeValueAsInt32("id"), Value = l.AttributeValue() }).ToList() }); } IEnumerable <ThingResponse.VideoGameVersion> MapVideoGameVersion(XElement versionsEl) { return(from v in versionsEl.XPathSelectElements("item[@type='videogameversion']") select new ThingResponse.VideoGameVersion { Type = v.AttributeValue("type"), Id = v.AttributeValueAsInt32("id"), Thumbnail = v.ElementValue("thumbnail"), Image = v.ElementValue("image"), Name = v.Element("name").AttributeValue(), ReleaseDate = v.Element("releasedate").AttributeValueAsDateTime(), Links = (from l in v.Elements("link") select new ThingResponse.Link { Type = l.AttributeValue("type"), Id = l.AttributeValueAsInt32("id"), Value = l.AttributeValue() }).ToList() }); } IEnumerable <ThingResponse.VideoGameCharacterVersion> MapVideoGameCharacterVersion(XElement versionsEl) { return(from v in versionsEl.XPathSelectElements("item[@type='vgcharacterversion']") select new ThingResponse.VideoGameCharacterVersion { Type = v.AttributeValue("type"), Id = v.AttributeValueAsInt32("id"), Thumbnail = v.ElementValue("thumbnail"), Image = v.ElementValue("image") }); } ThingResponse.VideoCollection MapVideoCollection(XElement videosEl) { if (videosEl == null) { return(null); } var videos = from v in videosEl.Elements("video") select new ThingResponse.Video { Id = v.AttributeValueAsInt32("id"), Title = v.AttributeValue("title"), Category = v.AttributeValue("category"), Language = v.AttributeValue("language"), Link = v.AttributeValue("link"), Username = v.AttributeValue("username"), UserId = v.AttributeValueAsInt32("userid"), PostDate = v.AttributeValueAsDateTime("postdate") }; int?total = videosEl.AttributeValueAsNullableInt32("total"); return(new ThingResponse.VideoCollection(videos, total)); } ThingResponse.Statistics MapStatistics(XElement statisticsEl) { if (statisticsEl == null) { return(null); } var ratingEl = statisticsEl.Element("ratings"); var statistics = new ThingResponse.Statistics { Page = statisticsEl.AttributeValueAsInt32("page"), Ratings = new ThingResponse.Ratings { UsersRated = ratingEl.Element("usersrated").AttributeValueAsNullableInt32(), Average = ratingEl.Element("average").AttributeValueAsDouble(), BayesAverage = ratingEl.Element("bayesaverage").AttributeValueAsDouble(), StandardDeviation = ratingEl.Element("stddev").AttributeValueAsNullableDouble(), Median = ratingEl.Element("median").AttributeValueAsNullableInt32(), Ranks = (from rank in ratingEl.Descendants("rank") select new ThingResponse.Rank { Type = rank.AttributeValue("type"), Id = rank.AttributeValueAsInt32("id"), Name = rank.AttributeValue("name"), FriendlyName = rank.AttributeValue("friendlyname"), Value = rank.AttributeValueAsNullableInt32(), BayesAverage = rank.AttributeValueAsDouble("bayesaverage") }).ToList(), Owned = ratingEl.Element("owned").AttributeValueAsNullableInt32(), Trading = ratingEl.Element("trading").AttributeValueAsNullableInt32(), Wanting = ratingEl.Element("wanting").AttributeValueAsNullableInt32(), Wishing = ratingEl.Element("wishing").AttributeValueAsNullableInt32(), NumComments = ratingEl.Element("numcomments").AttributeValueAsNullableInt32(), NumWeights = ratingEl.Element("numweights").AttributeValueAsNullableInt32(), AverageWeight = ratingEl.Element("averageweight").AttributeValueAsNullableDouble() } }; return(statistics); } ThingResponse.Comments MapComments(XElement commentsEl) { if (commentsEl == null) { return(null); } return(new ThingResponse.Comments( from comment in commentsEl.Elements("comment") select new ThingResponse.Comment { Username = comment.AttributeValue("username"), Rating = comment.AttributeValueAsNullableDouble("rating"), Value = comment.AttributeValue() }, commentsEl.AttributeValueAsInt32("page"), commentsEl.AttributeValueAsInt32("totalitems") )); } ThingResponse.RatingComments MapRatingComments(XElement commentsEl) { if (commentsEl == null) { return(null); } return(new ThingResponse.RatingComments( from comment in commentsEl.Elements("comment") select new ThingResponse.RatingComment { Username = comment.AttributeValue("username"), Rating = comment.AttributeValueAsInt32("rating"), Value = comment.AttributeValue() }, commentsEl.AttributeValueAsInt32("page"), commentsEl.AttributeValueAsInt32("totalitems") )); } List <ThingResponse.MarketplaceListing> MapMarketplace(XElement marketplaceEl) { if (marketplaceEl == null) { return(null); } return((from listing in marketplaceEl.Elements("listing") select new ThingResponse.MarketplaceListing { ListDate = listing.Element("listdate").AttributeValueAsDateTimeOffset(), Currency = listing.Element("price").AttributeValue("currency"), Price = listing.Element("price").AttributeValueAsDouble(), Condition = listing.Element("condition").AttributeValue(), Notes = listing.Element("notes").AttributeValue(), Link = listing.Element("link").AttributeValue("href") }).ToList()); } #endregion }