public async Task <Product> GetProductAsync(ResourceUri productUri)
        {
            using (var log = RequestLogger.Current.BeginJungoLog(this))
            {
                try
                {
                    var uri             = Billboard.ResolveExpandAll(productUri.Uri);
                    var productResponse = await Client.GetCacheableAsync <ProductResponse>(uri).ConfigureAwait(false);

                    if (productResponse == null)
                    {
                        return(null);
                    }

                    var prod = productResponse.Product;
                    await SupplyRecentInventoryStatusAsync(new[] { prod }).ConfigureAwait(false);

                    return(prod);
                }
                catch (Exception exc)
                {
                    throw log.LogException(exc);
                }
            }
        }
        public async Task <IEnumerable <ProductBrief> > GetProductBriefsAsync()
        {
            using (var log = RequestLogger.Current.BeginJungoLog(this))
            {
                try
                {
                    var billboard = await Billboard.GetAsync(Client).ConfigureAwait(false);

                    var uri           = Billboard.ResolveExpand(billboard.Products, Billboard.Templates.ExpandProductIdQueryValue);
                    var prodsResponse = await Client.GetCacheableAsync <ProductsResponse>(uri).ConfigureAwait(false);

                    if (prodsResponse == null || prodsResponse.Products == null ||
                        prodsResponse.Products.Product == null)
                    {
                        return(new ProductBrief[0]);
                    }
                    return(prodsResponse.Products.Product.Select(p => new ProductBrief
                    {
                        Id = p.Id,
                        Uri = p.Uri,
                        Relation = p.Relation,
                        DisplayName = p.DisplayName,
                        ThumbnailImage = p.ThumbnailImage
                    }));
                }
                catch (Exception exc)
                {
                    throw log.LogException(exc);
                }
            }
        }
Exemple #3
0
        public async Task <Offers> GetOffersForCartAsync(string popName)
        {
            using (var log = RequestLogger.Current.BeginJungoLog(this))
            {
                OffersResponse offersResponse;

                try
                {
                    var billboard = await Billboard.GetAsync(Client).ConfigureAwait(false);

                    var cartPopOffersUri = Billboard.ResolveTemplate(billboard.Cart,
                                                                     Billboard.Templates.PopOffersSegment,
                                                                     new { pop = popName });
                    // hitting cart resource for offers returns baby offers, even if use expand=all
                    offersResponse =
                        (await Client.GetCacheableAsync <OffersResponse>(cartPopOffersUri).ConfigureAwait(false));
                    if (offersResponse == null || offersResponse.Offers == null || offersResponse.Offers.Offer == null)
                    {
                        return(null);
                    }
                }
                catch (Exception exc)
                {
                    throw log.LogException(exc);
                }

                var offers = offersResponse.Offers;
                // expand each baby offer to papa offer in parallel
                var offerGet = new Task <OfferResponse> [offers.Offer.Length];
                for (var idx = 0; idx < offers.Offer.Length; idx++)
                {
                    offerGet[idx] =
                        Client.GetCacheableAsync <OfferResponse>(Billboard.ResolveExpandAll(offers.Offer[idx].Uri));
                }

                var exceptions = new List <Exception>();
                // wait for all
                for (var idx = 0; idx < offerGet.Length; idx++)
                {
                    try
                    {
                        var offerResponse = await offerGet[idx].ConfigureAwait(false);
                        if (offerResponse != null)
                        {
                            offers.Offer[idx] = offerResponse.Offer;
                            await SupplyRecentInventoryStatusAsync(offers.Offer[idx]).ConfigureAwait(false);
                        }
                    }
                    catch (Exception exc)
                    {
                        exceptions.Add(exc);
                    }
                }
                if (exceptions.Any())
                {
                    throw log.LogException(new AggregateException(exceptions));
                }
                return(offers);
            }
        }
Exemple #4
0
        private async Task <Cart> InternalGetCartAsync()
        {
            var billboard = await Billboard.GetAsync(Client).ConfigureAwait(false);

            var cartUri = Billboard.ResolveExpandAll(billboard.Cart);

            return((await Client.GetAsync <CartResponse>(cartUri).ConfigureAwait(false)).Cart);
        }
        public ResourceUri GetProductUri(long productId)
        {
            var billboard = Billboard.GetAsync(Client).Result;

            return(new ResourceUri
            {
                Uri = Billboard.ResolveTemplate(billboard.Products, Billboard.Templates.IdSegment, new { id = productId })
            });
        }
        public ResourceUri GetCategoryUri(long categoryId)
        {
            var billboard = Billboard.GetAsync(Client).Result;

            return(new ResourceUri
            {
                Uri = Billboard.ResolveTemplate(billboard.Categories, Billboard.Templates.IdSegment, new { id = categoryId })
            });
        }
        private string FormLimitedPublicTokenUri(ResourceAccessBillboard billboard)
        {
            var queryParms = string.IsNullOrEmpty(SessionToken)
                ? new { client_id = ApiKey }
                : (object)new { client_id = ApiKey, dr_session_token = SessionToken };

            return(Billboard.ResolveTemplate(billboard.Token.Uri, Billboard.Templates.LimitedPublicTokenQuery,
                                             queryParms));
        }
Exemple #8
0
 public static async Task<Billboard> GetAsync(IClient client)
 {
     if (_current != null) return _current;
     var uriConfig = ConfigLoader.Get<ShopperApiUriConfig>();
     _current = new Billboard
     {
         RawBillboard = (await client.GetCacheableAsync<ShopperApiBillboard>(uriConfig.BillboardUri).ConfigureAwait(false)).V1
     };
     return _current;
 }
        public static async Task <Billboard> GetAsync(IClient client)
        {
            if (_current != null)
            {
                return(_current);
            }
            var uriConfig = ConfigLoader.Get <ShopperApiUriConfig>();

            _current = new Billboard
            {
                RawBillboard = (await client.GetCacheableAsync <ShopperApiBillboard>(uriConfig.BillboardUri).ConfigureAwait(false)).V1
            };
            return(_current);
        }
Exemple #10
0
        private async Task <PointOfPromotion> InternalGetPointOfPromotionAsync(string popName)
        {
            var billboard = await Billboard.GetAsync(Client).ConfigureAwait(false);

            var popUri = Billboard.ResolveTemplate(billboard.PointOfPromotions, Billboard.Templates.IdSegment,
                                                   new { id = popName });
            PointOfPromotion pop = null;
            var popResponse      = (await Client.GetCacheableAsync <PointOfPromotionResponse>(popUri).ConfigureAwait(false));

            if (popResponse != null)
            {
                pop = popResponse.PointOfPromotion;
            }
            return(pop);
        }
Exemple #11
0
 public async Task <Offers> GetOffersAsync(ResourceUri productUri)
 {
     using (var log = RequestLogger.Current.BeginJungoLog(this))
     {
         try
         {
             var prodOffersUri =
                 Billboard.ResolveExpandAll(productUri.Uri + Billboard.Templates.ProductOffersSegment);
             return(await InternalGetOffersForOfferUri(prodOffersUri).ConfigureAwait(false));
         }
         catch (Exception exc)
         {
             throw log.LogException(exc);
         }
     }
 }
Exemple #12
0
        public async Task <Cart> ApplyCouponAsync(string coupon)
        {
            using (var log = RequestLogger.Current.BeginJungoLog(this))
            {
                try
                {
                    var billboard = await Billboard.GetAsync(Client).ConfigureAwait(false);

                    var applyCouponUri = Billboard.ResolveTemplate(billboard.Cart, Billboard.Templates.ApplyCouponQuery,
                                                                   new { promoCode = coupon, expand = Billboard.Templates.ExpandAllQueryValue });
                    return((await Client.PostAsync <CartResponse>(applyCouponUri).ConfigureAwait(false)).Cart);
                }
                catch (Exception exc)
                {
                    throw log.LogException(exc);
                }
            }
        }
Exemple #13
0
        public async Task <Cart> UpdateLineItemQuantityAsync(string lineItemUri, int quantity)
        {
            using (var log = RequestLogger.Current.BeginJungoLog(this))
            {
                try
                {
                    var qtyUri = Billboard.ResolveTemplate(lineItemUri, Billboard.Templates.ChangeQuantityQuery,
                                                           new { quantity });
                    await Client.PostForInfoAsync(qtyUri).ConfigureAwait(false);

                    return(await InternalGetCartAsync().ConfigureAwait(false));
                }
                catch (Exception exc)
                {
                    throw log.LogException(exc);
                }
            }
        }
        public async Task <Category> GetCategoryAsync(ResourceUri categoryUri)
        {
            using (var log = RequestLogger.Current.BeginJungoLog(this))
            {
                try
                {
                    var uri = Billboard.ResolveExpandAll(categoryUri.Uri);
                    var categoriesResponse =
                        await Client.GetCacheableAsync <CategoriesResponse>(uri).ConfigureAwait(false);

                    return(categoriesResponse == null ? null : categoriesResponse.Category);
                }
                catch (Exception exc)
                {
                    throw log.LogException(exc);
                }
            }
        }
Exemple #15
0
        public async Task <Cart> AddProductToCartAsync(long productId, int quantity = 1, long offerId = 0)
        {
            using (var log = RequestLogger.Current.BeginJungoLog(this))
            {
                try
                {
                    var billboard = await Billboard.GetAsync(Client).ConfigureAwait(false);

                    object parameters;
                    if (quantity > 1 && offerId > 0)
                    {
                        parameters = new { productId, quantity, offerId }
                    }
                    ;
                    else if (quantity > 1)
                    {
                        parameters = new { productId, quantity }
                    }
                    ;
                    else if (offerId > 0)
                    {
                        parameters = new { productId, offerId }
                    }
                    ;
                    else
                    {
                        parameters = new { productId }
                    };
                    var addProductToCartLink = new AddProductToCartLink
                    {
                        CartUri =
                            Billboard.ResolveTemplate(billboard.Cart, Billboard.Templates.AddProductToCartQuery,
                                                      parameters)
                    };

                    return(await AddProductToCartAsync(addProductToCartLink).ConfigureAwait(false));
                }
                catch (Exception exc)
                {
                    throw log.LogException(exc);
                }
            }
        }
Exemple #16
0
        public async Task <Offers> GetOffersAsync()
        {
            using (var log = RequestLogger.Current.BeginJungoLog(this))
            {
                try
                {
                    var billboard = await Billboard.GetAsync(Client).ConfigureAwait(false);

                    var offersUri = Billboard.ResolveExpandAll(billboard.Offers);
                    var offers    = await InternalGetOffersForOfferUri(offersUri).ConfigureAwait(false);

                    return(offers);
                }
                catch (Exception exc)
                {
                    throw log.LogException(exc);
                }
            }
        }
        public async Task <IEnumerable <Product> > GetProductsAsync(IEnumerable <long> productIds)
        {
            using (var log = RequestLogger.Current.BeginJungoLog(this))
            {
                try
                {
                    var ids = productIds.ToArray();
                    if (!ids.Any())
                    {
                        return(new Product[0]);
                    }

                    var idsStr = ids[0].ToString(CultureInfo.InvariantCulture);
                    for (var idsIdx = 1; idsIdx < ids.Length; idsIdx++)
                    {
                        idsStr += "," + ids[idsIdx].ToString(CultureInfo.InvariantCulture);
                    }

                    var billboard = await Billboard.GetAsync(Client).ConfigureAwait(false);

                    var uri = Billboard.ResolveTemplate(billboard.Products, Billboard.Templates.MultipleProductQuery,
                                                        new { productIds = idsStr, expand = Billboard.Templates.ExpandAllQueryValue });

                    var prodsResp = await Client.GetCacheableAsync <ProductsResponse>(uri).ConfigureAwait(false);

                    if (prodsResp == null || prodsResp.Products == null || prodsResp.Products.Product == null)
                    {
                        return(new Product[0]);
                    }

                    await SupplyRecentInventoryStatusAsync(prodsResp.Products.Product).ConfigureAwait(false);

                    await SupplyRecentInventoryStatusAsync(prodsResp.Products.Product.Where(p => p.Variations != null).SelectMany(p => p.Variations.Product)).ConfigureAwait(false);

                    return(prodsResp.Products.Product);
                }
                catch (Exception exc)
                {
                    throw log.LogException(exc);
                }
            }
        }
Exemple #18
0
        public async Task <Offers> GetOffersAsync(string popName)
        {
            using (var log = RequestLogger.Current.BeginJungoLog(this))
            {
                try
                {
                    var pop = await InternalGetPointOfPromotionAsync(popName).ConfigureAwait(false);

                    if (pop == null || pop.Offers == null || String.IsNullOrEmpty(pop.Offers.Uri))
                    {
                        return(null);
                    }
                    var offersUri = Billboard.ResolveExpandAll(pop.Offers.Uri);
                    return(await InternalGetOffersForOfferUri(offersUri).ConfigureAwait(false));
                }
                catch (Exception exc)
                {
                    throw log.LogException(exc);
                }
            }
        }
Exemple #19
0
        public async Task <IEnumerable <string> > GetPointOfPromotionNamesAsync()
        {
            using (var log = RequestLogger.Current.BeginJungoLog(this))
            {
                try
                {
                    var billboard = await Billboard.GetAsync(Client).ConfigureAwait(false);

                    var popsResponse =
                        (await Client.GetCacheableAsync <PointOfPromotionsResponse>(billboard.PointOfPromotions)
                         .ConfigureAwait(false));
                    return(popsResponse == null || popsResponse.PointOfPromotions == null ||
                           popsResponse.PointOfPromotions.PointOfPromotion == null
                        ? new string[0]
                        : popsResponse.PointOfPromotions.PointOfPromotion.Select(p => p.Id));
                }
                catch (Exception exc)
                {
                    throw log.LogException(exc);
                }
            }
        }
        public async Task <Categories> GetCategoriesAsync()
        {
            using (var log = RequestLogger.Current.BeginJungoLog(this))
            {
                try
                {
                    //todo: recursive (and let's do it in parallel, please)
                    var billboard = await Billboard.GetAsync(Client).ConfigureAwait(false);

                    var response =
                        await
                        Client.GetCacheableAsync <Category>(Billboard.ResolveExpandAll(billboard.Categories))
                        .ConfigureAwait(false);

                    return(response.Categories);
                }
                catch (Exception exc)
                {
                    throw log.LogException(exc);
                }
            }
        }
        public async Task <Products> GetProductsForCategoryAsync(Category category, PagingOptions options)
        {
            using (var log = RequestLogger.Current.BeginJungoLog(this))
            {
                try
                {
                    var uri          = Billboard.ResolvePagingOptions(category.Products.Uri, options);
                    var prodResponse = await Client.GetCacheableAsync <ProductsResponse>(uri).ConfigureAwait(false);

                    if (prodResponse == null)
                    {
                        return(null);
                    }
                    var catProds = prodResponse.Products;
                    catProds.Product = (await GetProductsAsync(catProds.Product).ConfigureAwait(false)).ToArray();
                    return(catProds);
                }
                catch (Exception exc)
                {
                    throw log.LogException(exc);
                }
            }
        }
        public async Task AuthenticateForLimitedPublicAsync(bool forCartManagement)
        {
            if (forCartManagement && string.IsNullOrEmpty(SessionToken))
            {
                var sessionTokenUri      = Billboard.GetSessionTokenUri();
                var sessionTokenResponse = await GetAsync <SessionToken>(sessionTokenUri).ConfigureAwait(false);

                if (sessionTokenResponse != null)
                {
                    SessionToken = sessionTokenResponse.session_token;
                }
            }
            var billboard = await Billboard.GetResourceAccessAsync(this).ConfigureAwait(false);

            var tokenUri = FormLimitedPublicTokenUri(billboard);
            var log      = BeginLog("POST", tokenUri);
            var response = await PostLimitedPublicTokenRequestAsync(tokenUri).ConfigureAwait(false);

            LogResponse(log, response);
            await ThrowIfFailAsync(response, log).ConfigureAwait(false);

            EndLog(log, String.Empty);
            await SetTokensAsync(response).ConfigureAwait(false);
        }
        private async Task <HttpResponseMessage> RetryIfTokenExpired(Func <Task <HttpResponseMessage> > req)
        {
            // BEWARE: Don't call any higher-level Get or Post here which might themselves do a retry.
            var response = await req().ConfigureAwait(false);

            if (response.StatusCode != HttpStatusCode.Unauthorized ||
                _httpClient.DefaultRequestHeaders.Authorization == null ||
                string.IsNullOrEmpty(RefreshToken))
            {
                return(response);
            }

            // perhaps bearer token is expired
            var billboard = await Billboard.GetResourceAccessAsync(this).ConfigureAwait(false);

            if (SessionToken == null)
            {
                // since no session token is involved, try to use refresh token to get new bearer token
                var refreshUri = Billboard.ResolveTemplate(billboard.Token.Uri, Billboard.Templates.RefreshTokenQuery,
                                                           new { client_id = ApiKey, refresh_token = RefreshToken });
                _httpClient.DefaultRequestHeaders.Authorization = null;
                response = await _httpClient.PostAsync(refreshUri, null).ConfigureAwait(false);

                if (response.StatusCode != HttpStatusCode.OK && response.StatusCode != HttpStatusCode.Unauthorized)
                {
                    return(response);
                }
                if (response.StatusCode == HttpStatusCode.Unauthorized)
                {
                    // refresh token might be expired; start over
                    response = await PostLimitedPublicTokenRequestAsync(FormLimitedPublicTokenUri(billboard)).ConfigureAwait(false);

                    if (response.StatusCode != HttpStatusCode.OK)
                    {
                        return(response);
                    }
                }
            }
            else
            {
                // todo: when we implement shopper authentication, if we have a shopper, this needs to be the shopper token request, not limited public
                // if used a session token to get bearer token, unfortunately refresh token is doo doo
                // start over with existing session token if have one
                if (!string.IsNullOrEmpty(SessionToken))
                {
                    response = await PostLimitedPublicTokenRequestAsync(FormLimitedPublicTokenUri(billboard)).ConfigureAwait(false);
                }
                if (response.StatusCode == HttpStatusCode.Unauthorized)
                {
                    // perhaps session token is expired; need to get a new session token
                    // our thoughts and prayers go out to the poor shopper who is now going to lose their cart contents
                    var sessionTokenUri = Billboard.GetSessionTokenUri();
                    var json            = await GetStringAsync(sessionTokenUri, true /*no retry!*/).ConfigureAwait(false);

                    if (!string.IsNullOrEmpty(json))
                    {
                        var sessionTokenResponse = JsonConvert.DeserializeObject <SessionToken>(json);
                        if (sessionTokenResponse != null)
                        {
                            SessionToken = sessionTokenResponse.session_token;
                        }
                    }
                    response = await PostLimitedPublicTokenRequestAsync(FormLimitedPublicTokenUri(billboard)).ConfigureAwait(false);

                    if (response.StatusCode != HttpStatusCode.OK)
                    {
                        return(response);
                    }
                }
            }

            // whew!!! we got reauthorized
            await SetTokensAsync(response).ConfigureAwait(false);

            // replay request
            return(await req().ConfigureAwait(false));
        }
        public async Task <ProductsWithRanking> GetProductsByKeywordAsync(string keyword, PagingOptions options)
        {
            using (var log = RequestLogger.Current.BeginJungoLog(this))
            {
                ProductsWithRanking kwProds;
                try
                {
                    var billboard = await Billboard.GetAsync(Client).ConfigureAwait(false);

                    // nudge, nudge: gives us back a baby srch result, not the full ProductWithRanking
                    var kwUri = Billboard.ResolveTemplate(billboard.Products, Billboard.Templates.ProductsKeywordQuery,
                                                          new { keyword, pageNumber = options.Page, pageSize = options.PageSize, sort = options.Sort });
                    var response =
                        await Client.GetCacheableAsync <ProductsWithRankingResponse>(kwUri).ConfigureAwait(false);

                    if (response == null || response.Products == null || response.Products.Product == null)
                    {
                        return new ProductsWithRanking {
                                   Product = new ProductWithRanking[0]
                        }
                    }
                    ;
                    kwProds = response.Products;
                }
                catch (Exception exc)
                {
                    throw log.LogException(exc);
                }

                // fire up parallel calls to get papa products
                var prods = new Task <Product> [kwProds.Product.Length];
                for (var idx = 0; idx < kwProds.Product.Length; idx++)
                {
                    prods[idx] = GetProductAsync(kwProds.Product[idx]);
                }
                // wait for all
                // put papa prods into keywords response
                var exceptions = new List <Exception>();
                for (var idx = 0; idx < prods.Length; idx++)
                {
                    try
                    {
                        var response = await prods[idx].ConfigureAwait(false);

                        if (response != null)
                        {
                            kwProds.Product[idx].InjectFrom(response);
                        }
                    }
                    catch (Exception exc)
                    {
                        exceptions.Add(exc);
                    }
                }
                if (exceptions.Any())
                {
                    throw log.LogException(new AggregateException(exceptions));
                }
                return(kwProds);
            }
        }