Example #1
0
        public ActionResult ConnectionSelect(GridCommand command, bool isForExport)
        {
            var model = new GridModel <ConnectionModel>();

            ConnectionCache.ControllingData().UpdatePersistedConnections();

            var connections = _connectorService.GetConnections(isForExport, command.Page - 1, command.PageSize);

            model.Data  = connections;
            model.Total = connections.TotalCount;

            return(new JsonResult {
                Data = model
            });
        }
Example #2
0
        protected override bool AuthorizeCore(HttpContextBase httpContext)
        {
            httpContext.Response.Clear();
            httpContext.Response.Cache.SetCacheability(HttpCacheability.NoCache);

            _result = ShopConnectorAuthResult.FailedForUnknownReason;

            var controllingData = ConnectionCache.ControllingData();
            var now             = DateTime.UtcNow;

            try
            {
                _result = IsAuthenticated(httpContext, now, controllingData);
            }
            catch (Exception ex)
            {
                ex.Dump();
            }

            if (_result == ShopConnectorAuthResult.Success)
            {
                var response = httpContext.Response;

                response.AddHeader(ShopConnectorCore.Header.Version, controllingData.Version);
                response.AddHeader(ShopConnectorCore.Header.Date, now.ToString("o"));
            }
            else
            {
                var headers = httpContext.Response.Headers;

                headers.Add("WWW-Authenticate", ShopConnectorCore.Header.WwwAuthenticate);

                headers.Add(ShopConnectorCore.Header.Date, now.ToString("o"));

                headers.Add(ShopConnectorCore.Header.AuthResultId, ((int)_result).ToString());
                headers.Add(ShopConnectorCore.Header.AuthResultDescription, _result.ToString());

                if (controllingData.LogUnauthorized)
                {
                    LogUnauthorized(httpContext);
                }
            }

            return(_result == ShopConnectorAuthResult.Success);
        }
        //[HttpPost]
        //public void Notification()
        //{
        //	//_connectorService.ProcessNotification();
        //}

        public ActionResult About()
        {
            string errorMsg   = null;
            var    fileSystem = new ShopConnectorFileSystem("Export");
            var    path       = fileSystem.GetFullFilePath(string.Concat("about-", Guid.NewGuid().ToString(), ".xml"));

            var publicKey       = Request.Headers[ShopConnectorCore.Header.PublicKey];
            var controllingData = ConnectionCache.ControllingData();
            var connection      = controllingData.Connections.FirstOrDefault(x => x.PublicKey == publicKey && x.IsForExport);

            using (var fileStream = new FileStream(path, FileMode.Create, FileAccess.Write))
                using (var writer = XmlWriter.Create(fileStream, ShopConnectorService.DefaultSettings))
                {
                    try
                    {
                        var model = _connectorService.CreateAboutModel(connection);

                        writer.WriteStartElement("Content");
                        writer.WriteElementString("AppVersion", model.AppVersion);
                        writer.WriteElementString("UtcTime", model.UtcTime.ToString("o"));
                        writer.WriteElementString("ConnectorVersion", model.ConnectorVersion);
                        writer.WriteElementString("StoreName", model.StoreName);
                        writer.WriteElementString("StoreUrl", model.StoreUrl);
                        writer.WriteElementString("StoreCount", model.StoreCount.ToString());
                        writer.WriteElementString("CompanyName", model.CompanyName);
                        writer.WriteElementString("StoreLogoUrl", model.StoreLogoUrl);
                        writer.WriteElementString("UpdatedProductsCount", model.UpdatedProductsCount.NaIfEmpty());

                        writer.WriteStartElement("Manufacturers");
                        foreach (var manu in model.AvailableManufacturers)
                        {
                            writer.WriteStartElement("Manufacturer");
                            writer.WriteElementString("Name", manu.Text);
                            writer.WriteElementString("Id", manu.Value);
                            writer.WriteEndElement(); // Manufacturer
                        }
                        writer.WriteEndElement();     // Manufacturers

                        writer.WriteStartElement("Categories");
                        foreach (var category in model.AvailableCategories)
                        {
                            writer.WriteStartElement("Category");
                            writer.WriteElementString("Name", category.Text);
                            writer.WriteElementString("Id", category.Value);
                            writer.WriteEndElement(); // Category
                        }
                        writer.WriteEndElement();     // Categories

                        writer.WriteEndElement();     // Content
                    }
                    catch (Exception ex)
                    {
                        errorMsg = ex.Message;
                    }
                }

            if (errorMsg.HasValue())
            {
                Response.AddHeader("Sm-ShopConnector-ErrorMessageShort", errorMsg);
            }
            if (connection != null)
            {
                Response.AddHeader("Sm-ShopConnector-RequestCount", connection.RequestCount.ToString());
                Response.AddHeader("Sm-ShopConnector-LastRequest", connection.LastRequestUtc.HasValue ? connection.LastRequestUtc.Value.ToString("o") : "");
                Response.AddHeader("Sm-ShopConnector-LastProductCall", connection.LastProductCallUtc.HasValue ? connection.LastProductCallUtc.Value.ToString("o") : "");
            }

            ShopConnectorFileSystem.CleanupDirectories();

            Response.BufferOutput = false; // !!
            var finalStream = new FileStream(path, FileMode.Open);

            return(new FileStreamResult(finalStream, MediaTypeNames.Text.Xml));
        }
        public ActionResult ProductData(ProductDataModel model)
        {
            // Ids are transmitted as a string (for backward compatibility) but model property is an int array.
            var rawManuIds = Request.QueryString["FilterManufacturerIds"] as string;

            model.FilterManufacturerIds = rawManuIds.ToIntArray();

            var cancellation = new CancellationTokenSource(TimeSpan.FromHours(_shopConnectorSettings.MaxHoursToExport));
            var context      = new ShopConnectorExportContext
            {
                Model       = model,
                PublicKey   = Request.Headers[ShopConnectorCore.Header.PublicKey],
                CategoryIds = new HashSet <int>()
            };

            // Important: first products, then categories.
            var productResult  = _connectorService.Export(context, cancellation.Token, ShopConnectorProductXmlExportProvider.SystemName);
            var categoryResult = _connectorService.Export(context, cancellation.Token, ShopConnectorCategoryXmlExportProvider.SystemName);

            var productPath  = productResult.GetFilePath();
            var categoryPath = categoryResult.GetFilePath();

            if (!productResult.Succeeded || !categoryResult.Succeeded)
            {
                return(ShopConnectorError(HttpStatusCode.InternalServerError, T("Admin.Common.UnknownError"), productResult.LastError.HasValue() ? productResult.LastError : categoryResult.LastError));
            }


            // Create compound XML file.
            var    fileSystem    = new ShopConnectorFileSystem("Export");
            var    path          = fileSystem.GetFullFilePath(string.Concat("data-", Guid.NewGuid().ToString(), ".xml"));
            string errorMsg      = null;
            var    cSuccess      = 0;
            var    cFailure      = 0;
            var    cTotalRecords = 0;
            var    pSuccess      = 0;
            var    pFailure      = 0;
            var    pTotalRecords = 0;

            using (var fileStream = new ExportFileStream(new FileStream(path, FileMode.Create, FileAccess.Write)))
                using (var writer = XmlWriter.Create(fileStream, ShopConnectorService.DefaultSettings))
                {
                    try
                    {
                        writer.WriteStartElement("Content");
                        writer.WriteStartElement("Categories");
                        writer.WriteAttributeString("Version", SmartStoreVersion.CurrentVersion);
                        if (categoryPath.HasValue())
                        {
                            var nodeNames = new string[] { "Category", "Success", "Failure", "TotalRecords" };
                            using (var reader = XmlReader.Create(categoryPath, new XmlReaderSettings {
                                CheckCharacters = false
                            }))
                            {
                                if (reader.ReadToFollowing("Categories"))
                                {
                                    using (var categories = reader.ReadSubtree())
                                    {
                                        var siblingDepth = categories.Depth + 1;
                                        while (!categories.EOF)
                                        {
                                            if (categories.Depth == siblingDepth && categories.NodeType == XmlNodeType.Element && nodeNames.Contains(categories.Name))
                                            {
                                                var name = categories.Name;
                                                var val  = categories.ReadOuterXml(); // Must be last categories statement cause of cursor position.
                                                switch (name)
                                                {
                                                case "Category":
                                                    writer.WriteRaw(val);
                                                    break;

                                                case "Success":
                                                    cSuccess = val.EmptyNull().Replace("<Success>", "").Replace("</Success>", "").ToInt();
                                                    break;

                                                case "Failure":
                                                    cFailure = val.EmptyNull().Replace("<Failure>", "").Replace("</Failure>", "").ToInt();
                                                    break;

                                                case "TotalRecords":
                                                    cTotalRecords = val.EmptyNull().Replace("<TotalRecords>", "").Replace("</TotalRecords>", "").ToInt();
                                                    break;
                                                }
                                            }
                                            else
                                            {
                                                categories.Read();
                                            }
                                        }
                                    }
                                }
                            }
                        }
                        writer.WriteEndElement(); // Categories

                        writer.WriteStartElement("Products");
                        writer.WriteAttributeString("Version", SmartStoreVersion.CurrentVersion);
                        if (productPath.HasValue())
                        {
                            var nodeNames = new string[] { "Product", "Success", "Failure", "TotalRecords" };
                            using (var reader = XmlReader.Create(productPath, new XmlReaderSettings {
                                CheckCharacters = false
                            }))
                            {
                                if (reader.ReadToFollowing("Products"))
                                {
                                    using (var products = reader.ReadSubtree())
                                    {
                                        var siblingDepth = products.Depth + 1;
                                        while (!products.EOF)
                                        {
                                            if (products.Depth == siblingDepth && products.NodeType == XmlNodeType.Element && nodeNames.Contains(products.Name))
                                            {
                                                var name = products.Name;
                                                var val  = products.ReadOuterXml();
                                                switch (name)
                                                {
                                                case "Product":
                                                    writer.WriteRaw(val);
                                                    break;

                                                case "Success":
                                                    pSuccess = val.EmptyNull().Replace("<Success>", "").Replace("</Success>", "").ToInt();
                                                    break;

                                                case "Failure":
                                                    pFailure = val.EmptyNull().Replace("<Failure>", "").Replace("</Failure>", "").ToInt();
                                                    break;

                                                case "TotalRecords":
                                                    pTotalRecords = val.EmptyNull().Replace("<TotalRecords>", "").Replace("</TotalRecords>", "").ToInt();
                                                    break;
                                                }
                                            }
                                            else
                                            {
                                                products.Read();
                                            }
                                        }
                                    }
                                }
                            }
                        }
                        writer.WriteEndElement(); // Products
                        writer.WriteEndElement(); // Content
                    }
                    catch (Exception ex)
                    {
                        errorMsg = ex.Message;
                    }
                }

            if (errorMsg.HasValue())
            {
                Response.AddHeader("Sm-ShopConnector-ErrorMessageShort", errorMsg);
            }

            Response.AddHeader("Sm-ShopConnector-Category", string.Join(",", cSuccess, cFailure, cTotalRecords));
            Response.AddHeader("Sm-ShopConnector-Product", string.Join(",", pSuccess, pFailure, pTotalRecords));

            var publicKey       = Request.Headers[ShopConnectorCore.Header.PublicKey];
            var controllingData = ConnectionCache.ControllingData();
            var connection      = controllingData.Connections.FirstOrDefault(x => x.PublicKey == publicKey && x.IsForExport);

            if (connection != null)
            {
                Response.AddHeader("Sm-ShopConnector-RequestCount", connection.RequestCount.ToString());
                Response.AddHeader("Sm-ShopConnector-LastRequest", connection.LastRequestUtc.HasValue ? connection.LastRequestUtc.Value.ToString("o") : "");
                Response.AddHeader("Sm-ShopConnector-LastProductCall", connection.LastProductCallUtc.HasValue ? connection.LastProductCallUtc.Value.ToString("o") : "");
            }

            ShopConnectorFileSystem.CleanupDirectories();

            Response.BufferOutput = false; // !!
            var finalStream = new FileStream(path, FileMode.Open);

            return(new FileStreamResult(finalStream, MediaTypeNames.Text.Xml));
        }
        public ActionResult ProductData(ProductDataModel model)
        {
            string val;
            var    fetchFrom = _connectorService.ConvertDateTime(model.FetchFromDate, false);

            var context = new ShopConnectorRequestContext
            {
                ActionMethod = "ProductData"
            };

            try
            {
                if (model.DataFileName.IsEmpty())
                {
                    var controllingData = ConnectionCache.ControllingData();
                    var connection      = controllingData.Connections.FirstOrDefault(x => x.Id == model.Id);

                    model.DataFileName = connection.Url.EmptyNull().Replace("https://", "").Replace("http://", "").Replace("/", "");
                }

                context.RequestContent.Add("FetchFrom", fetchFrom.HasValue ? fetchFrom.Value.ToString("o") : "");
                context.RequestContent.Add("FilterManufacturerIds", string.Join(",", model.FilterManufacturerIds ?? new int[0]));
                context.RequestContent.Add("FilterCategoryId", model.FilterCategoryId.EmptyNull());
                context.RequestContent.Add("DataFileName", model.DataFileName.EmptyNull());

                if (!_connectorService.SendRequest(context, model.Id))
                {
                    return(new ShopConnectorOperationResult(context));
                }

                var cStats = context.Headers.TryGetValue("Sm-ShopConnector-Category", out val)
                    ? val.ToIntArray()
                    : new int[] { 0, 0, 0 };

                var pStats = context.Headers.TryGetValue("Sm-ShopConnector-Product", out val)
                    ? val.ToIntArray()
                    : new int[] { 0, 0, 0 };

                string message = null;

                if ((cStats[0] == 0 && pStats[0] == 0) || ShopConnectorFileSystem.GetFileSize(context.ResponsePath) == 0)
                {
                    // Avoid empty files.
                    FileSystemHelper.DeleteFile(context.ResponsePath);

                    message = T("Plugins.SmartStore.ShopConnector.NoContent");
                }
                else
                {
                    message = T("Plugins.SmartStore.ShopConnector.ProcessingResult",
                                cStats[2].ToString("N0"), cStats[0].ToString("N0"), cStats[1].ToString("N0"),
                                pStats[2].ToString("N0"), pStats[0].ToString("N0"), pStats[1].ToString("N0"));

                    var stats = new ShopConnectorImportStats("Product");
                    stats.Add(new ImportStats.FileStats
                    {
                        Name          = Path.GetFileName(context.ResponsePath),
                        CategoryCount = cStats[0],
                        ProductCount  = pStats[0]
                    });
                }

                context.ResponseModel = new OperationResultModel(message, false);
            }
            catch (Exception ex)
            {
                context.ResponseModel = new OperationResultModel(ex);
            }

            return(new ShopConnectorOperationResult(context));
        }
Example #6
0
        protected override void Export(ExportExecuteContext context)
        {
            var categoryIds = context.CustomProperties["CategoryIds"] as HashSet <int>;
            var storeIds    = new HashSet <int>(context.CustomProperties["StoreIds"] as int[]);
            var domain      = context.CustomProperties["Domain"] as string;

            var categoryToStoreMappings = GetCategoryToStoreMappings();

            var allCategoryIds = _categoryRepository.TableUntracked
                                 .Where(x => !x.Deleted)
                                 .Select(x => new { x.Id, x.ParentCategoryId })
                                 .ToDictionary(x => x.Id, x => x.ParentCategoryId);

            using (var writer = XmlWriter.Create(context.DataStream, ShopConnectorService.DefaultSettings))
            {
                var helper = new ExportXmlHelper(writer, true);
                helper.Exclude = ExportXmlExclude.Category;

                writer.WriteStartElement("Content");
                writer.WriteStartElement("Products");
                writer.WriteAttributeString("Version", SmartStoreVersion.CurrentVersion);

                while (context.Abort == DataExchangeAbortion.None && context.DataSegmenter.ReadNextSegment())
                {
                    var segment     = context.DataSegmenter.CurrentSegment;
                    var skuMappings = new Dictionary <int, string>();

                    if (domain.HasValue())
                    {
                        var productIds = segment.Select(x => (int)((dynamic)x).Id).ToArray();
                        var mappings   = _shopConnectorService.Value.GetSkuMappingsByProductIds(domain, productIds);
                        skuMappings = mappings.ToDictionarySafe(x => x.ProductId, x => x.Sku);
                    }

                    foreach (dynamic product in segment)
                    {
                        if (context.Abort != DataExchangeAbortion.None)
                        {
                            break;
                        }

                        try
                        {
                            Product entity = product.Entity;

                            // SKU mapping.
                            if (skuMappings.TryGetValue(entity.Id, out var sku))
                            {
                                product.Sku = sku;
                            }

                            helper.WriteProduct(product, "Product");

                            if (product.ProductCategories != null)
                            {
                                foreach (dynamic productCategory in product.ProductCategories)
                                {
                                    if (productCategory.Category != null)
                                    {
                                        var categoryId = (int)productCategory.Category.Id;

                                        if (IsCategoryAllowed(categoryId, storeIds, allCategoryIds, categoryToStoreMappings))
                                        {
                                            IncludeIdAndAllParentIds(categoryId, categoryIds, allCategoryIds);
                                        }
                                    }
                                }
                            }

                            ++context.RecordsSucceeded;
                        }
                        catch (OutOfMemoryException)
                        {
                            context.Abort = DataExchangeAbortion.Hard;
                            throw;
                        }
                        catch (Exception ex)
                        {
                            context.RecordException(ex, (int)product.Id);
                        }
                    }
                }

                writer.WriteElementString("Success", context.RecordsSucceeded.ToString());
                writer.WriteElementString("Failure", context.RecordsFailed.ToString());
                writer.WriteElementString("TotalRecords", context.DataSegmenter.TotalRecords.ToString());

                writer.WriteEndElement();   // Products
                writer.WriteEndElement();   // Content

                var publicKey       = (string)context.CustomProperties[ShopConnectorCore.Header.PublicKey];
                var controllingData = ConnectionCache.ControllingData();
                var connection      = controllingData.Connections.FirstOrDefault(x => x.PublicKey == publicKey && x.IsForExport);
                if (connection != null)
                {
                    connection.LastProductCallUtc = DateTime.UtcNow;
                    ConnectionCache.ControllingData().ConnectionsUpdated = true;
                }
            }
        }