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);
        }
Example #3
0
        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
        }