Пример #1
0
        private static AllStockRoot CreateAllStock(FullCatalog fullCatalog, ShopCatalogRoot jsonCatalog)
        {
            AllStockRoot allstock = new AllStockRoot();

            foreach (var jsonMarket in jsonCatalog.markets)
            {
                RootParsingObject market = Parsing.Model.RootParsingObject.ReadJsonMarketFromFtp(jsonMarket);
                if (market != null)
                {
                    AddMarketToAllStock(market, fullCatalog, allstock, jsonMarket);
                }
            }
            allstock.update_time = DateTime.Now;
            return(allstock);
        }
Пример #2
0
        private static AllStockOffer GetFirstActiveOffer(AllStockSize asSize, ShopCatalogRoot shopCatalog)
        {
            var bonanzaShops = shopCatalog.markets.FindAll(x => x.active_marketplace_list.Find(y => y == "bonanza") != null);

            //if (asSize.offers[0].currency != "RUB")
            //{
            //    return asSize.offers[0];
            //}
            foreach (var offer in asSize.offers)
            {
                //if (offer.currency != "RUB")
                if (bonanzaShops.Find(x => x.name == offer.stock_name) != null)
                {
                    return(offer);
                }
            }
            return(null);
        }
Пример #3
0
        private static BonanzaRoot CreateBonanzaRecords(AllStockRoot allstock, FullCatalogRoot fullCatalog)
        {
            ShopCatalogRoot shopCatalog = ShopCatalogController.LoadShopCatalogFromFtp();
            BonanzaRoot     bonanza     = new BonanzaRoot();

            foreach (var asSneaker in allstock.sneakers)
            {
                foreach (var asSize in asSneaker.sizes)
                {
                    Model.BonanzaModel.BonanzaRecord bRecord = GetBonanzaRecord(asSize, asSneaker, fullCatalog, shopCatalog);
                    if (bRecord != null)
                    {
                        bonanza.Records.Add(bRecord);
                    }
                }
            }

            return(bonanza);
        }
Пример #4
0
        public static void ValidateAllShops()
        {
            //загружаем каталог магазинов
            var shopCatalog = ShopCatalogRoot.ReadFromFtp();

            foreach (var shop in shopCatalog.markets)
            {
                RootParsingObject market = SneakerIcon.Classes.Parsing.Model.RootParsingObject.ReadJsonMarketFromFtp(shop);
                if (market != null)
                {
                    var shopValidator = new ShopValidator();
                    shopValidator.ValidateShop(market, shopCatalog);
                }
                else
                {
                    bool test = true;
                }
            }
        }
Пример #5
0
        private void ValidateShop(RootParsingObject shopParser, ShopCatalogRoot shopCatalog, string folder = _folder)
        {
            var validatedShop = new RootParsingObject();

            validatedShop.market_info = shopParser.market_info;
            //string br = "\n";
            log = DateTime.Now.ToString() + br;
            foreach (var listing in shopParser.listings)
            {
                string listingLog   = String.Empty;
                var    ValidListing = ValidateListing(listing);
                if (ValidListing != null)
                {
                    validatedShop.listings.Add(ValidListing);
                }
            }
            validatedShop.SaveLocalFile(folder);
            SaveLogShopValidate(this.log, validatedShop.market_info.name);
            //return validatedShop;
        }
Пример #6
0
        public static AllStockRoot Run()
        {
            var          jsonCatalog = ShopCatalogRoot.ReadFromFtp();
            var          fullCatalog = new FullCatalog();
            AllStockRoot allstock    = CreateAllStock(fullCatalog, jsonCatalog);

            //когда оллсток создан, нужно его прогнать и отсортировать все офферы, чтобы первым был с самой низкой ценой
            SortOffers(allstock);

            Program.Logger.Info("Артикулов в фулкаталог: " + fullCatalog.sneakers.Count);
            Program.Logger.Info("Артикулов в оллсток: " + allstock.sneakers.Count);
            Program.Logger.Info("Размеров в оллсток: " + allstock.GetCountSizes());
            Program.Logger.Info("Офферов в оллсток: " + allstock.GetCountOffers());


            //затем нужно прогнать весь оллсток и, там где нет юпс, добавить их из upcdb
            var folder = Config.GetConfig().DirectoryPathParsing + @"allstock\";

            SaveJson(allstock, "allstock.json", folder);
            return(allstock);
        }
Пример #7
0
 public ShopValidatorAllBrands()
 {
     ShopCatalog = ShopCatalogRoot.ReadFromFtp();
     SizeChart   = new SizeChartAllBrands();
     SizeChart.LoadSizeChartFromFtp();
 }
Пример #8
0
        private static Model.BonanzaModel.BonanzaRecord GetBonanzaRecord(AllStockSize asSize, AllStockSneaker asSneaker, FullCatalogRoot fullCatalog, ShopCatalogRoot shopCatalog)
        {
            var fcSneaker = fullCatalog.records.Find(x => x.sku == asSneaker.sku);

            if (fcSneaker == null)
            {
                _logger.Warn("Артикул не найден в фулкаталоге. sku:" + asSneaker.sku);
                return(null);
            }
            var bRecord = new Model.BonanzaModel.BonanzaRecord();

            //standart data
            bRecord.quantity     = 5;
            bRecord.condition    = "New with box";
            bRecord.force_update = "true";
            bRecord.brand        = fcSneaker.brand;
            //shipping
            bRecord.shipping_price   = 29;
            bRecord.shipping_type    = "flat";
            bRecord.shipping_carrier = "usps";
            bRecord.shipping_service = "EconomyShipping";
            bRecord.shipping_package = "normal";
            //bRecord.worldwide_shipping_type = "flat";
            //bRecord.worldwide_shipping_price = 29;

            bRecord.id          = asSize.sku2;
            bRecord.description = GetBonanzaRecordDescription(asSize, asSneaker, fullCatalog);
            if (bRecord.description == null)
            {
                _logger.Warn("Пустое описание. sku2:" + bRecord.id);
                return(null);
            }

            bRecord.category = GetBonanzaCategory(asSneaker.category, fcSneaker.sex);
            bRecord.width    = GetBonanzaWidth(asSneaker.category);
            bRecord.title    = GetTitle(asSneaker.brand, asSize.us, asSneaker.sku, asSneaker.title);

            //price
            var offer = GetFirstActiveOffer(asSize, shopCatalog);

            //var offer = GetNonRussianOffer(asSize); //отфильтруем русские магазы
            if (offer == null)
            {
                return(null);
            }
            bRecord.price = GetPrice(offer);
            //double priceWithMargin = offer.price_usd_with_delivery_to_usa_and_minus_vat + MARGIN_USD;
            //double priceWithFeeMinusBonanzaDelivery = (priceWithMargin * 1.18) - 29;
            //priceWithFeeMinusBonanzaDelivery = Math.Round(priceWithFeeMinusBonanzaDelivery, 2);
            //bRecord.price = priceWithFeeMinusBonanzaDelivery.ToString("F", System.Globalization.CultureInfo.CreateSpecificCulture("en-US"));

            //images
            if (fcSneaker.images.Count == 0)
            {
                _logger.Warn("Нет изображений. sku2:" + bRecord.id);
                return(null);
            }
            bRecord.image1 = fcSneaker.images[0];
            if (fcSneaker.images.Count > 1)
            {
                bRecord.image2 = fcSneaker.images[1];
            }
            if (fcSneaker.images.Count > 2)
            {
                bRecord.image3 = fcSneaker.images[2];
            }
            if (fcSneaker.images.Count > 3)
            {
                bRecord.image4 = fcSneaker.images[3];
            }


            bRecord.size    = asSize.us;
            bRecord.traits  = "[[US Size:" + asSize.us + "]] ";
            bRecord.upc     = asSize.upc;
            bRecord.MPN     = fcSneaker.sku; //это вроде не работает
            bRecord.traits += "[[MPN:" + fcSneaker.sku + "]] ";


            return(bRecord);
        }
        private static List <string> ChangeImageLinksFromShopToImagesFromOurServer(List <string> images, RootParsingObject shop, ShopCatalogRoot shopCatalog, Listing shopRecord)
        {
            var imagesFromOurServer = new List <string>();


            string host       = "http://img.sneaker-icon.ru";
            int    shopNumber = shopCatalog.markets.Find(x => x.name == shop.market_info.name).number;

            for (int i = 1; i < images.Count + 1; i++)
            {
                string url = host + "/shops/" + shopNumber + "/images/" + shopRecord.sku + "-" + i + ".jpg";

                if (NetworkUtils.UrlExists(url))
                {
                    imagesFromOurServer.Add(url);
                }
            }


            //ver2.0
            var imagesFromOurServer2 = new List <string>();

            var ftphost      = "ftp://" + Config.GetConfig().FtpHostContabo;
            var user         = Config.GetConfig().FtpUserContabo;
            var pass         = Config.GetConfig().FtpPassContabo;
            var folder       = "shops/" + shopNumber + "/images";
            var folderImages = Helper.GetFileListFromDirectory(folder, ftphost, user, pass).ToList();
            var skuImages    = folderImages.FindAll(x => x.Contains(shopRecord.sku));

            foreach (var image in skuImages)
            {
                var imageUrl = host + "/" + folder + "/" + image;
                imagesFromOurServer2.Add(imageUrl);
            }

            if (imagesFromOurServer.Count != imagesFromOurServer2.Count)
            {
                bool test = true;
            }

            return(imagesFromOurServer);
        }
 private static void UpdateFromOneMarket(Model.FullCatalog.FullCatalogRoot fullCatalogJson, Parsing.Model.RootParsingObject jsonMarket, ShopCatalogRoot shopCatalog, out int addedCount)
 {
     addedCount = 0;
     foreach (var listing in jsonMarket.listings)
     {
         var fcSneaker = fullCatalogJson.records.Find(x => x.sku.ToUpper() == listing.sku.ToUpper());
         if (fcSneaker == null)
         {
             //если фулкаталогсникер нул, значит этого кроссовка еще нет в фулкаталоге и надо его добавить
             var fcRecord = CreateFullCatalogRecordFromListing(listing, jsonMarket, shopCatalog);
             if (fcRecord != null)
             {
                 fullCatalogJson.records.Add(fcRecord);
                 addedCount++;
             }
             else
             {
                 //значит ошибка какая-то
                 bool test = true;
             }
         }
         else
         {
             //если кросс уже существуюет то смотрим что есть в листинге, если есть данные для обновления то обновляем их в кроссовке.
             //проверить, сохранятся ли данные обновления в фулкаталоге, потому что передаю просто листинг а не весь каталог
             UpdateSneaker(fcSneaker, listing);
         }
     }
 }
        /// <summary>
        /// метод ищет изображения для fullCatalogRecord во всех магазинах
        /// </summary>
        /// <param name="fcRecord">FullCatalogRecord</param>
        /// <param name="shops">Магазины с листингами в json</param>
        /// <param name="shopCatalog"></param>
        /// <returns>возвращает список ссылок на изображения с нашего сервера</returns>
        private static List <string> GetImages(FullCatalogRecord fcRecord, List <RootParsingObject> shops, ShopCatalogRoot shopCatalog)
        {
            /* Как лучше всего сделать изображения? Какие варианты?
             * - пройтись по всем магазинам, найти магазин где фоток больше всего и взять оттуда
             * - пройтись по всем магазинам и взять все фотки
             * - пройтись по магазам и взять там где 4 фотки в первую очередь (хорошо для бонанзы)
             * - сделать список магазинов по приоритетам откуда брать фотки (в первую очередь оттуда где белый фон)
             * - добавлять стайловые фотки в конце
             * - оттуда где первый кроссовок влево смотрит
             * - отсортировать магазы по кол-ву артикулов. брать в первую очередь оттуда, где артикулов больше (чтобы больше кроссовок были в едином стиле)
             * бля, вариантов куча, у каждого свои преимущества... что же делать как же быть...
             * - точно нужно отсеивать магазины с водяными знаками. сто пудов. например оверкилл
             * - можно в конец добавлять стайловые фотки если их больше 4 (тогда на бонанзу только норм фотки, а на сайт sneaker-icon.ru только качественные фотки
             * - можно еще правило что с русских сайтов берем фотки в последнюю очередь
             */
            var imagesFromOurServer = new List <string>();

            foreach (var shop in shops)
            {
                var shopRecord = shop.listings.Find(x => x.sku == fcRecord.sku);
                if (shopRecord != null)
                {
                    if (shopRecord.images.Count > 0)
                    {
                        //меняем ссылки с сайта на ссылки с нашего сервера (если они там есть), если нет ищем дальше
                        imagesFromOurServer = ChangeImageLinksFromShopToImagesFromOurServer(shopRecord.images, shop, shopCatalog, shopRecord);
                        if (imagesFromOurServer.Count == shopRecord.images.Count)
                        {
                            return(imagesFromOurServer);
                        }
                    }
                }
            }

            return(imagesFromOurServer);
        }
        /// <summary>
        /// метод обновляет принудительно все фотки в фулкаталоге на фотки из магазинов. Эти фотки берутся с нашего сервака для фоток
        /// метод проходит по всем магазинам и ищет там фотки для артикула, если они есть то загружает их.
        /// магазины отсортированы в порядке приоритета фотографи.
        /// если в магазинах нет фоток, то фотки берутся из папки для фоток, загруженных вручную
        /// </summary>
        public static void UpdateFullCatalogImages()
        {
            /*
             * Алгоритм обновления изображений:
             * берем фулкаталог
             * берем список магазинов
             * берем только магазины без водяных знаков
             * желательно чтобы кроссовки были на белом фоне (или на сером, но не стайловые),
             * стайловые можно в конце добавить. потом опять пройтись по всем магазам и в конец добавить стайловых фоток.
             * чтобы у кросса например было 4 обычных фотки и потом стайловые дальше шли
             * также можно сделать приоритет по направлению первого кроссовка
             * например чтобы в первую очередь брать фотки кросс у которых влево смотрит)
             * Если нигде кросс не найден, то искать фотки в папке images
             * туда типа вручную фотки загружаем, например для кроссовок из дисконта
             */

            var fullCatalog = LoadFullCatalogFromFtp();
            var shopCatalog = ShopCatalogRoot.ReadFromFtp();
            var shops       = new List <RootParsingObject>();
            var startTime   = DateTime.Now;

            //очищаем левые фотки
            foreach (var record in fullCatalog.records)
            {
                if (record.images.Count == 1 && string.IsNullOrWhiteSpace(record.images[0]))
                {
                    record.images = new List <string>();
                }
            }

            Program.Logger.Info("Старт. Артикулов без фотографий: " + fullCatalog.records.FindAll(x => x.images.Count == 0).Count);

            //подгружаем json всех магазинов
            foreach (var market in shopCatalog.markets)
            {
                var shop = RootParsingObject.ReadJsonMarketFromFtp(market);
                if (shop != null)
                {
                    shops.Add(shop);
                }
            }

            //отсортировали список магазинов по убыванию количества листингов
            shops.Sort(delegate(RootParsingObject shop1, RootParsingObject shop2)
                       { return(shop2.listings.Count.CompareTo(shop1.listings.Count)); });

            //делаем первый эшелон магазинов с самыми классными фотками
            var titolo       = shops.Find(x => x.market_info.name == "titolo.ch");
            var chmielna     = shops.Find(x => x.market_info.name == "chmielna20.pl");
            var asfaltgold   = shops.Find(x => x.market_info.name == "asphaltgold.de");
            var hhv          = shops.Find(x => x.market_info.name == "hhv.de");
            var streetBeat   = shops.Find(x => x.market_info.name == "street-beat.ru");
            var firstEshelon = new List <RootParsingObject>()
            {
                titolo, chmielna, asfaltgold, hhv, streetBeat
            };

            //очищаем все артикулы от фоток
            //foreach (var fcRecord in fullCatalog.records)
            //{
            //    fcRecord.images = new List<string>();
            //}
            //Program.logger.Info("Очистили от фоток. Артикулов без фотографий: " + fullCatalog.records.FindAll(x => x.images.Count == 0).Count);

            /*Теперь делаем самое главное:
             * проходимся по всему списку артикулов
             * каждый артикул проверяем на наличие в магазине
             * если он в магазине есть, смотрим, есть ли для него фотки
             * если есть то заполняем
             */

            //первый проход делаем по первому эшелону магазинов
            int i             = 0;
            int addedPhotos   = 0;
            int updatedPhotos = 0;
            int status1       = 1;
            int status2       = 1;

            Program.Logger.Info("Start FirstEshelon. Всего артикулов:" + fullCatalog.records.Count + " Артикулов без фотографий: " + fullCatalog.records.FindAll(x => x.images.Count == 0).Count);
            foreach (var fcRecord in fullCatalog.records)
            {
                if (fcRecord.sku == "724821-100")
                {
                    bool test = true;
                }

                //пропускаем артикул, если для него уже были взяты фотки с одного из сайтов эшелонов
                List <string> images = new List <string>();
                if (fcRecord.images == null)
                {
                    images = GetImages(fcRecord, firstEshelon, shopCatalog);
                }
                else if (fcRecord.images.Count == 0)
                {
                    images = GetImages(fcRecord, firstEshelon, shopCatalog);
                }
                else if (!fcRecord.images[0].Contains("img.sneaker-icon.ru"))
                {
                    images = GetImages(fcRecord, firstEshelon, shopCatalog);
                }
                else
                {
                    //если уже с нашего сервака фотка, то проверяем, с сайта эшелона или нет
                    var  image           = fcRecord.images[0];
                    bool isEshelonPhotos = false;
                    foreach (var shop in firstEshelon)
                    {
                        int shopNumber = shopCatalog.markets.Find(x => x.name == shop.market_info.name).number;
                        if (image.Contains("/shops/" + shopNumber + "/images/"))
                        {
                            isEshelonPhotos = true;
                            break;
                        }
                    }
                    if (!isEshelonPhotos)
                    {
                        images = GetImages(fcRecord, firstEshelon, shopCatalog);
                    }
                }

                if (images.Count > 0)
                {
                    fcRecord.images = images;
                    if (fcRecord.images == null)
                    {
                        addedPhotos++;
                    }
                    else
                    if (fcRecord.images.Count == 0)
                    {
                        addedPhotos++;
                    }
                    else
                    {
                        updatedPhotos++;
                    }
                }
                i++;
                if (i > 100 * status1)
                {
                    status1++;
                }
                if (status1 > status2)
                {
                    var time = DateTime.Now - startTime;
                    Program.Logger.Debug("Пройдено:" + i + " Добавлено:" + addedPhotos + " Обновлено:" + updatedPhotos + " time:" + time.Minutes);
                    status2 = status1;
                }
            }
            Program.Logger.Info("Finish FirstEshelon. Всего артикулов:" + fullCatalog.records.Count + " Артикулов без фотографий: " + fullCatalog.records.FindAll(x => x.images.Count == 0).Count);
            Program.Logger.Info("Добавлено артикулов:" + addedPhotos + " Обновлено артикулов:" + updatedPhotos);


            //теперь проходимся по всем магазинам (можно конечно первый эшелон удалить, но чет лень, всё равно фотки с изображениями пропускаем)
            Program.Logger.Info("Start AllShops. Всего артикулов:" + fullCatalog.records.Count + " Артикулов без фотографий: " + fullCatalog.records.FindAll(x => x.images.Count == 0).Count);
            i       = 0;
            status1 = 1;
            status2 = 1;
            foreach (var fcRecord in fullCatalog.records)
            {
                //пропускаем фотки у которых в имени файла уже содержится img.sneaker-icon.ru, т.е. значит что они уже были добавлены из первого эшелона или про прошлом проходе UpdateFullCatalogImages. по сути нам нужно взять только те артикулы, у которых нет фоток или у которых фотки с сайта а не с нашего сервака
                List <string> images = new List <string>();
                if (fcRecord.images == null)
                {
                    images = GetImages(fcRecord, shops, shopCatalog);
                }
                else if (fcRecord.images.Count == 0)
                {
                    images = GetImages(fcRecord, shops, shopCatalog);
                }
                else if (!fcRecord.images[0].Contains("img.sneaker-icon.ru/shops/"))
                {
                    images = GetImages(fcRecord, shops, shopCatalog);
                }

                if (images.Count > 0)
                {
                    fcRecord.images = images;
                    if (fcRecord.images == null)
                    {
                        addedPhotos++;
                    }
                    else
                    if (fcRecord.images.Count == 0)
                    {
                        addedPhotos++;
                    }
                    else
                    {
                        updatedPhotos++;
                    }
                }
                i++;
                if (i > 100 * status1)
                {
                    status1++;
                }
                if (status1 > status2)
                {
                    var time = DateTime.Now - startTime;
                    Program.Logger.Debug("Пройдено:" + i + " Добавлено:" + addedPhotos + " Обновлено:" + updatedPhotos + " time:" + time.Minutes);
                    status2 = status1;
                }
            }
            Program.Logger.Info("Finish AllShops. Всего артикулов:" + fullCatalog.records.Count + " Артикулов без фотографий: " + fullCatalog.records.FindAll(x => x.images.Count == 0).Count);
            Program.Logger.Info("Добавлено артикулов:" + addedPhotos + " Обновлено артикулов:" + updatedPhotos);

            SaveFullCatalogToFtp(fullCatalog);
        }
        private static FullCatalogRecord CreateFullCatalogRecordFromListing(Listing listing, RootParsingObject jsonMarket, ShopCatalogRoot shopCatalog)
        {
            //если нет категории то посмотреть есть ли размеры разных сеток, если есть, то определить категорию по разным размерам.
            FullCatalogRecord fcRecord = new FullCatalogRecord();

            //brand
            if (Validator.ValidateBrand(listing.brand))
            {
                fcRecord.brand = listing.brand;
            }
            else
            {
                Program.Logger.Warn("wrong brand. sku: " + listing.sku + " market: " + jsonMarket.market_info.name);
                return(null);
            }

            //sku
            var sku = listing.sku.ToUpper(); //Aa1234-001 to AA1234-001 nike sku

            if (Validator.ValidateSku(sku, listing.brand))
            {
                fcRecord.sku = sku;
            }
            else
            {
                Program.Logger.Warn("wrong sku: " + listing.sku + " market: " + jsonMarket.market_info.name);
                return(null);
            }

            //category
            if (String.IsNullOrWhiteSpace(listing.category))
            {
                //пытаемся определить категорию по размерным сеткам
                listing.GetCategory();
            }
            if (!String.IsNullOrWhiteSpace(listing.category))
            {
                if (Validator.ValidateCategory(listing.category))
                {
                    fcRecord.category = listing.category;
                    fcRecord.sex      = Helper.GetEngSexFromEngCategory(fcRecord.category);
                }
                else
                {
                    Program.Logger.Warn("FullCatalog2.CreateFullCatalogRecordFromListing. Invalid listing.category:" + listing.category + " shop:" + jsonMarket.market_info.name + " sku:" + listing.sku);
                }
            }

            //добавить валидации на эти позиции
            fcRecord.title      = listing.title;
            fcRecord.color      = listing.colorbrand;
            fcRecord.collection = listing.collection;
            fcRecord.link       = listing.url;

            //дописать смену изображений на изображения с сервера
            //fcRecord.images = listing.images;
            fcRecord.images = ChangeImageLinksFromShopToImagesFromOurServer(listing.images, jsonMarket, shopCatalog, listing);


            if (fcRecord.images.Count < listing.images.Count)
            {
                fcRecord.images = listing.images;
                Program.Logger.Warn("Wrong our Server Images. shop:" + jsonMarket.market_info.name + " sku:" + listing.sku);
            }
            else
            {
                bool test = true;
            }

            fcRecord.add_time = DateTime.Now;

            return(fcRecord);
        }
Пример #14
0
 public DbController()
 {
     log         = String.Empty;
     ShopCatalog = ShopCatalogController.LoadShopCatalogFromFtp();
 }