2024-04-16 20:01:34 +03:30
|
|
|
|
using MediatR;
|
2024-02-15 10:39:00 +03:30
|
|
|
|
using Microsoft.EntityFrameworkCore;
|
2024-04-23 12:09:32 +03:30
|
|
|
|
using Microsoft.IdentityModel.Tokens;
|
2024-04-16 20:01:34 +03:30
|
|
|
|
using Netina.Domain.CommandQueries.Commands;
|
|
|
|
|
|
using Netina.Domain.Dtos.ScraperDtos.Response;
|
|
|
|
|
|
using Netina.Domain.Dtos.SmallDtos;
|
|
|
|
|
|
using Netina.Domain.Entities.Brands;
|
|
|
|
|
|
using Netina.Domain.Entities.ProductCategories;
|
|
|
|
|
|
using Netina.Repository.Repositories.Base.Contracts;
|
2024-02-15 10:39:00 +03:30
|
|
|
|
|
2024-04-16 20:01:34 +03:30
|
|
|
|
namespace Netina.Infrastructure.Services.Scrapers;
|
2024-02-15 10:39:00 +03:30
|
|
|
|
|
|
|
|
|
|
public class DigikalaScraper : IDigikalaScraper
|
|
|
|
|
|
{
|
|
|
|
|
|
private readonly IRestApiWrapper _apiWrapper;
|
|
|
|
|
|
private readonly IRepositoryWrapper _repositoryWrapper;
|
|
|
|
|
|
private readonly IMediator _mediator;
|
|
|
|
|
|
private readonly IUploadFileService _uploadFileService;
|
|
|
|
|
|
|
2024-04-20 16:05:03 +03:30
|
|
|
|
public DigikalaScraper(IRestApiWrapper apiWrapper, IRepositoryWrapper repositoryWrapper, IMediator mediator, IUploadFileService uploadFileService)
|
2024-02-15 10:39:00 +03:30
|
|
|
|
{
|
|
|
|
|
|
_apiWrapper = apiWrapper;
|
|
|
|
|
|
_repositoryWrapper = repositoryWrapper;
|
|
|
|
|
|
_mediator = mediator;
|
|
|
|
|
|
_uploadFileService = uploadFileService;
|
|
|
|
|
|
}
|
|
|
|
|
|
public async Task<List<ScraperProductDto>> GetProductsByNameAsync(string productName)
|
|
|
|
|
|
{
|
|
|
|
|
|
var products = await _apiWrapper.DigikalaRestApi.SearchProductAsync(productName);
|
|
|
|
|
|
return products.data.products.Select(s => new ScraperProductDto
|
|
|
|
|
|
{
|
|
|
|
|
|
PersianName = s.title_fa,
|
|
|
|
|
|
EnglishName = s.title_en,
|
|
|
|
|
|
MainImage = s.images.main.url.First(),
|
|
|
|
|
|
//Cost = long.TryParse(s.default_variant.price.rrp_price,out long result) ? result : 0,
|
|
|
|
|
|
ScraperId = s.id.ToString(),
|
|
|
|
|
|
ScraperUrl = $"https://digikala.com/{s.url.uri}"
|
|
|
|
|
|
}).ToList();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public async Task<bool> AddProductToShopAsync(string productId, string productName, CancellationToken cancellationToken = default)
|
|
|
|
|
|
{
|
|
|
|
|
|
var response = await _apiWrapper.DigikalaRestApi.GetProductAsync(productId);
|
2024-04-20 16:05:03 +03:30
|
|
|
|
var digiProduct = response.data;
|
|
|
|
|
|
var newSummery = digiProduct.seo.description.Replace("فروشگاه اینترنتی دیجی\u200cکالا", "فروشگاه اینترنتی وسمه");
|
|
|
|
|
|
|
2024-02-15 10:39:00 +03:30
|
|
|
|
var specifications = new List<SpecificationSDto>();
|
|
|
|
|
|
foreach (var specification in digiProduct.product.specifications)
|
|
|
|
|
|
{
|
|
|
|
|
|
foreach (var attribute in specification.attributes)
|
|
|
|
|
|
{
|
|
|
|
|
|
specifications.Add(new SpecificationSDto { Value = string.Join(",", attribute.values), Title = attribute.title });
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
using var httClient = new HttpClient();
|
|
|
|
|
|
var imageBytes = await httClient.GetByteArrayAsync(digiProduct.product.images.main.url.FirstOrDefault(), cancellationToken);
|
|
|
|
|
|
var imageBase64 = Convert.ToBase64String(imageBytes);
|
|
|
|
|
|
var uploadFile = new FileUploadRequest
|
|
|
|
|
|
{
|
|
|
|
|
|
StringBaseFile = imageBase64,
|
|
|
|
|
|
FileName = digiProduct.product.title_fa.Replace(" ", "_") + ".jpg",
|
|
|
|
|
|
FileUploadType = FileUploadType.Image,
|
|
|
|
|
|
ContentType = "image/jpeg"
|
|
|
|
|
|
};
|
|
|
|
|
|
var uploadResponse = await _uploadFileService.UploadImageAsync(uploadFile);
|
|
|
|
|
|
var files = new List<StorageFileSDto>
|
|
|
|
|
|
{
|
|
|
|
|
|
new StorageFileSDto
|
|
|
|
|
|
{
|
|
|
|
|
|
FileLocation = uploadResponse.FileLocation,
|
|
|
|
|
|
FileName = uploadResponse.FileName,
|
|
|
|
|
|
IsPrimary = true,
|
|
|
|
|
|
}
|
|
|
|
|
|
};
|
2024-04-20 16:05:03 +03:30
|
|
|
|
var nonBrand = await _repositoryWrapper.SetRepository<Brand>()
|
|
|
|
|
|
.TableNoTracking
|
|
|
|
|
|
.FirstOrDefaultAsync(b => b.PersianName == "بدون برند", cancellationToken);
|
|
|
|
|
|
if (nonBrand == null)
|
2024-02-15 10:39:00 +03:30
|
|
|
|
{
|
2024-04-20 16:05:03 +03:30
|
|
|
|
nonBrand = Brand.Create("بدون برند" , "NoBrand","محصولات بدون برند",false,string.Empty);
|
|
|
|
|
|
_repositoryWrapper.SetRepository<Brand>()
|
|
|
|
|
|
.Add(nonBrand);
|
|
|
|
|
|
await _repositoryWrapper.SaveChangesAsync(cancellationToken);
|
2024-02-15 10:39:00 +03:30
|
|
|
|
}
|
|
|
|
|
|
|
2024-04-20 16:05:03 +03:30
|
|
|
|
var nonCat = await _repositoryWrapper.SetRepository<ProductCategory>()
|
|
|
|
|
|
.TableNoTracking
|
|
|
|
|
|
.FirstOrDefaultAsync(b => b.Name == "دسته بندی نشده", cancellationToken);
|
|
|
|
|
|
if (nonCat == null)
|
|
|
|
|
|
{
|
|
|
|
|
|
nonCat = ProductCategory.Create("دسته بندی نشده", "محصولات بدون دسته بندی", false);
|
|
|
|
|
|
_repositoryWrapper.SetRepository<ProductCategory>()
|
|
|
|
|
|
.Add(nonCat);
|
|
|
|
|
|
await _repositoryWrapper.SaveChangesAsync(cancellationToken);
|
|
|
|
|
|
}
|
2024-02-15 10:39:00 +03:30
|
|
|
|
|
2024-04-23 12:09:32 +03:30
|
|
|
|
if (digiProduct.product.title_en.IsNullOrEmpty())
|
|
|
|
|
|
digiProduct.product.title_en = digiProduct.product.title_fa;
|
2024-04-22 13:33:39 +03:30
|
|
|
|
|
2024-04-20 16:05:03 +03:30
|
|
|
|
var request = new CreateProductCommand(digiProduct.product.title_fa, digiProduct.product.title_en,
|
|
|
|
|
|
newSummery,
|
|
|
|
|
|
string.Empty, string.Empty, string.Empty, true, 0,
|
|
|
|
|
|
0, 0, false
|
2024-08-07 16:15:53 +03:30
|
|
|
|
, 5, false, nonBrand.Id, nonCat.Id, new DiscountSDto(), specifications, files,new Dictionary<string, string>(),new Dictionary<string, string>());
|
2024-04-20 16:05:03 +03:30
|
|
|
|
await _mediator.Send(request, cancellationToken);
|
2024-02-15 10:39:00 +03:30
|
|
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|