private static void UpdateSneaker(FullCatalogRecord fcSneaker, Listing listing) { //category var category = fcSneaker.category; if (string.IsNullOrWhiteSpace(category)) { category = listing.GetCategory(); if (category != null) { fcSneaker.category = category; } } //images }
private static bool GetImages(FullCatalogRecord fcSneaker, Model.BonanzaModel.BonanzaRecord bRecord) { if (fcSneaker.images.Count == 0) { _logger.Warn("Нет изображений. sku2:" + fcSneaker.sku); return(false); } 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]; } return(true); }
/// <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); }
private static AvitoAd GetAdFromSneaker(Listing sneaker, FullCatalogRecord fcSneaker, DateTime startTime, int position, int count) { AvitoAd Ad = new AvitoAd(); if (fcSneaker == null) { _logger.Warn("is not exist in fullcatalog sku:" + sneaker.sku); return(null); } _logger.Info("sku: " + sneaker.sku + " title: " + fcSneaker.title); if (String.IsNullOrWhiteSpace(sneaker.category)) { _logger.Warn("Skip sneaker. Reason: category is empty"); return(null); } else if (sneaker.category == "kids") { _logger.Info("skip sneaker. Reason: kids category"); return(null); } if (sneaker.sizes == null) { _logger.Warn("Skip sneaker. Reason: sizes is empty"); return(null); } if (sneaker.sizes.Count == 0) { _logger.Warn("Skip sneaker. Reason: sizes is empty. Sku:" + sneaker.sku); return(null); } if (fcSneaker.images == null) { _logger.Warn("Skip sneaker. Reason: images is empty. Sku: " + sneaker.sku); return(null); } else if (fcSneaker.images.Count == 0) { _logger.Warn("Skip sneaker. Reason: images is empty. Sku: " + sneaker.sku); return(null); } Ad.Id = sneaker.sku; //DateBegin /* нужно все объявления размазать на месяц (ну пусть будет на 30 дней). * допустим если у меня есть 3000 объявлений то это значит что нужно постить по 100 в день * Постить будем допустим с 7.00 утра 23.59. Получается 17 часов. это 61200 секунд. * Получается объявление нужно постить каждые 612 секунд, начиная с 7 утра * * В сутках 24 часа, это 86400 секунд. * В 30 днях 2 592 000 секунд * То есть если у нас есть 3000 объявлений, значит начиная с текущего момента нужно постить объявление каждые 864 секунды */ double delay = 2592000 / count * position; //todo сделать распределение на 10 часов а не 24 var intDelay = (int)delay; //Ad.DateBegin = startTime.AddSeconds(intDelay); //todo datebegin можно определить только после того, как известно точное кол-во выгружаемых позиций (с учетом отфильтрованных невалидных) //Ad.DateBegin = startTime; Ad.DateBegin = GetDateBegin(startTime, count, position, DaysPeriod, EndHour, StartHour); Ad.ManagerName = "Роман"; Ad.ContactPhone = "88002001121"; Ad.AllowEmail = "Да"; //Ad.Region = "Самарская область"; Ad.City = "Москва"; //goods type var category = fcSneaker.category; if (category == "men") { Ad.Category = "Одежда, обувь, аксессуары"; Ad.GoodsType = "Мужская одежда"; } else if (category == "women") { Ad.Category = "Одежда, обувь, аксессуары"; Ad.GoodsType = "Женская одежда"; } else if (category == "kids") { _logger.Info("skip sneaker. Reason: kids category"); return(null); } else { _logger.Warn("null or wrong category"); return(null); } Ad.Apparel = "Обувь"; //size //буду брать случайный русский размер из списка размеров, нужно будет округлить до целого var rnd2 = new Random().Next(sneaker.sizes.Count - 1); //todo брать только артикулы у которых 3 или больше размеров в наличии var sizeUsAllStock = sneaker.sizes[rnd2]; var sizeAllStock = new Size(sneaker.brand, sneaker.category, sizeUsAllStock.us, null, null, null, null); var sizeFromSizeChart = SizeChart.GetSizeStatic(sizeAllStock); if (sizeFromSizeChart == null) { Ad.Size = "Без размера"; } else { var ruSize = sizeFromSizeChart.ru.Replace(".", ","); double doubleRuSize = 0; if (Double.TryParse(ruSize, out doubleRuSize)) { Ad.Size = Math.Round(doubleRuSize, 0).ToString(); } else { Ad.Size = "Без размера"; } } if (Ad.Size == "Без размера") { _logger.Error("Wrong size: " + sizeUsAllStock.us); return(null); //if (sneaker.category == "men") // Ad.Size = "42"; //else if (sneaker.category == "women") // Ad.Size = "37"; //else if (sneaker.category == "kids") // Ad.Size = "35"; } //title var type = string.Empty; if (!string.IsNullOrWhiteSpace(fcSneaker.type)) { type = fcSneaker.type + " "; } Ad.Title = "Новые " + type + sneaker.title.ToLower(); if (Ad.Title.Length > 50) { Ad.Title = Ad.Title.Substring(0, 50); } Ad.Title = Helper.UpperFirstCharInWord(Ad.Title); //description var br = "\n"; var desc = "<![CDATA[" + br; if (fcSneaker.type == null) { fcSneaker.type = String.Empty; } desc += "<p>Новые оригинальные " + fcSneaker.type.ToLower() + " " + sneaker.title.ToUpper() + "</p>" + br; desc += "<p>Артикул: " + sneaker.sku + "</p>" + br; desc += "<p>В оригинальной упаковке Nike.</p>" + br; desc += "<p>БЕСПЛАТНАЯ доставка по Москве в день заказа или на следующий день</p>" + br; desc += "<p>Работаем 7 дней в неделю, без праздников и выходных</p>" + br; desc += "<p>Доставка по России 3-5 дней компанией СДЭК.</p>" + br; desc += "<p>Стоимость доставки по РФ - 300 рублей.</p>" + br; desc += "<p>Доставка по РФ только по 100% предоплате, наложенным платежом не отправляем</p>" + br; desc += "<p>Работаем с 2014 года, более 4000 моделей в ассортименте. Можете перейти в магазин авито (страница Контакты), потом на сайт и в группу Вконтакте, чтобы убедиться в том, что мы ПРОДАЕМ ТОЛЬКО ОРИГИНАЛЬНУЮ ОБУВЬ. НИКАКИХ ПОДДЕЛОК И РЕПЛИК!</p>" + br; desc += "<p>В нашей группе Вконтакте более 70 реальных отзывов от клиентов!</p>" + br; desc += "<p>Размеры в наличии:</p>" + br; desc += "<ul>" + br; foreach (var size in sneaker.sizes) { var scSize = SizeChart.GetSizeStatic(new Size(sneaker.brand, sneaker.category, size.us, null, null, null, null)); if (scSize != null) { desc += "<li>" + scSize.GetAllSizeString() + "</li>" + br; } } desc += "</ul>" + br; desc += "<p>Уточняйте наличие размеров.</p>" + br; desc += "<p>Если размера нет в наличии, возможно его можно привезти под заказ. Срок поставки товара под заказ: 7-10 дней. </p>" + br; desc += "<p>Sneaker Icon - это большой выбор оригинальной брендовой обуви Nike и Jordan. Кроссовки, кеды, бутсы, футзалки, шиповки, сланцы, ботинки и другие типы обуви</p>" + br; desc += "<p>БОЛЬШИЕ РАЗМЕРЫ: доставляем под заказ обувь до 55 размера, а также обувь двойной полноты стопы и другие редкие модели и размеры</p>" + br; desc += "<p>ДЛЯ СПОРТИВНЫХ КОМАНД: подбираем полные комплекты обуви, одежды и сопутствующих товаров для спортивных команд</p>" + br; desc += "<p>ДЛЯ ОПТОВИКОВ: отправляем в регионы оптом брендовую обувь, одежду и аксессуары по оптовым ценам.</p>" + br; desc += "<p>Звоните или пишите в сообщения Авито по всем вопросам</p>" + br; desc += "]]>"; Ad.Description = desc; //price Ad.Price = (int)sneaker.price + MARGIN; Ad.Images = fcSneaker.images; return(Ad); }
private static AvitoAd GetAdFromSneaker(Model.AllStock.AllStockSneaker sneaker, FullCatalogRecord fcSneaker, DateTime startTime, int position, int count) { AvitoAd Ad = new AvitoAd(); if (fcSneaker.images == null) { return(null); } if (fcSneaker.images.Count == 0) { return(null); } if (String.IsNullOrWhiteSpace(sneaker.category)) { return(null); } if (sneaker.sizes == null) { return(null); } if (sneaker.sizes.Count == 0) { return(null); } Ad.Id = sneaker.sku; //DateBegin /* нужно все объявления размазать на месяц (ну пусть будет на 30 дней). * допустим если у меня есть 3000 объявлений то это значит что нужно постить по 100 в день * Постить будем допустим с 7.00 утра 23.59. Получается 17 часов. это 61200 секунд. * Получается объявление нужно постить каждые 612 секунд, начиная с 7 утра * * В сутках 24 часа, это 86400 секунд. * В 30 днях 2 592 000 секунд * То есть если у нас есть 3000 объявлений, значит начиная с текущего момента нужно постить объявление каждые 864 секунды */ double delay = 2592000 / count * position; var intDelay = (int)delay; //Ad.DateBegin = startTime.AddSeconds(intDelay); Ad.DateBegin = startTime; Ad.ManagerName = "Евгений"; Ad.ContactPhone = "88002001121"; Ad.AllowEmail = "Да"; Ad.Region = "Москва"; //goods type if (sneaker.category == "men") { Ad.Category = "Одежда, обувь, аксессуары"; Ad.GoodsType = "Мужская одежда"; } else if (sneaker.category == "women") { Ad.Category = "Одежда, обувь, аксессуары"; Ad.GoodsType = "Женская одежда"; } else if (sneaker.category == "kids") { Ad.Category = "Детская одежда и обувь"; var rnd = new Random().NextDouble(); if (rnd > 0.5) { Ad.GoodsType = "Для девочек"; } else { Ad.GoodsType = "Для мальчиков"; } } Ad.Apparel = "Обувь"; //size //буду брать случайный русский размер из списка размеров, нужно будет округлить до целого var rnd2 = new Random().Next(sneaker.sizes.Count - 1); var sizeUsAllStock = sneaker.sizes[rnd2]; var sizeAllStock = new Size(sneaker.brand, sneaker.category, sizeUsAllStock.us, null, null, null, null); var sizeFromSizeChart = SizeChart.GetSizeStatic(sizeAllStock); if (sizeFromSizeChart == null) { Ad.Size = "Без размера"; } else { var ruSize = sizeFromSizeChart.ru.Replace(".", ","); double doubleRuSize = 0; if (Double.TryParse(ruSize, out doubleRuSize)) { Ad.Size = Math.Round(doubleRuSize, 0).ToString(); } else { Ad.Size = "Без размера"; } } if (Ad.Size == "Без размера") { if (sneaker.category == "men") { Ad.Size = "42"; } else if (sneaker.category == "women") { Ad.Size = "37"; } else if (sneaker.category == "kids") { Ad.Size = "35"; } } //title Ad.Title = "Новые оригинальные " + sneaker.title.ToUpper() + " " + sneaker.sku; if (Ad.Title.Length > 50) { Ad.Title = Ad.Title.Substring(0, 50); } //Ad.Title = Ad.Title.ToLower(); //description var br = "\n"; var desc = "<![CDATA[" + br; if (fcSneaker.type == null) { fcSneaker.type = String.Empty; } desc += "<p>Новые оригинальные " + fcSneaker.type.ToLower() + " " + sneaker.title.ToUpper() + "</p>" + br; desc += "<p>Артикул: " + sneaker.sku + "</p>" + br; desc += "<p>В оригинальной упаковке Nike.</p>" + br; desc += "<p>БЕСПЛАТНАЯ доставка по Москве</p>" + br; desc += "<p>Доставка по России 3-5 дней компанией СДЭК.</p>" + br; desc += "<p>Стоимость доставки по РФ - 300 рублей.</p>" + br; desc += "<p>Доставка в регионы только по 100% предоплате, наложенным платежом не отправляем</p>" + br; desc += "<p>Работаем с 2012 года, более 4000 моделей в ассортименте. Можете перейти в магазин авито (страница Контакты), потом на сайт и в группу Вконтакте, чтобы убедиться в том, что мы продаем только оригинальную обувь. Никаких подделок и реплик!</p>" + br; desc += "<p>В нашей группе Вконтакте более 70 реальных отзывов от клиентов!</p>" + br; desc += "<p>Размеры в наличии:</p>" + br; desc += "<ul>" + br; foreach (var size in sneaker.sizes) { var scSize = SizeChart.GetSizeStatic(new Size(sneaker.brand, sneaker.category, size.us, null, null, null, null)); var priceSize = size.offers[0].price_usd_with_delivery_to_usa_and_minus_vat; var priceSizeRub = (int)CurrencyRate.ConvertCurrency("USD", "RUB", priceSize) + MARGIN; if (scSize != null) { desc += "<li>" + scSize.GetAllSizeString() + ". Цена:" + priceSizeRub + "</li>" + br; } } desc += "</ul>" + br; desc += "<p>Уточняйте наличие размеров.</p>" + br; desc += "<p>Если размера нет в наличии, можем его привезти под заказ. Срок поставки товара под заказ: 7-10 дней. </p>" + br; desc += "<p>Sneaker Icon - это большой выбор оригинальной брендовой обуви Nike и Jordan. Кроссовки, кеды, бутсы, футзалки, шиповки, сланцы, ботинки и другие типы обуви</p>" + br; desc += "<p>Звоните или пишите в сообщения Авито по всем вопросам</p>" + br; desc += "]]>"; Ad.Description = desc; //price var priceUsd = sneaker.GetMinPrice(); var priceRub = CurrencyRate.ConvertCurrency("USD", "RUB", priceUsd); var pricetest = (int)priceRub + MARGIN; Ad.Price = (int)Math.Round(priceRub, 0) + MARGIN; Ad.Images = fcSneaker.images; return(Ad); }
public static string DetectCategoryFromTitle(FullCatalogRecord record) { return(DetectCategoryFromTitle(record.title, record.brand)); }
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); }