feat : complete create sitemap
							parent
							
								
									3118de0509
								
							
						
					
					
						commit
						3cba0d598a
					
				| 
						 | 
					@ -18,8 +18,9 @@
 | 
				
			||||||
  },
 | 
					  },
 | 
				
			||||||
  "SiteSettings": {
 | 
					  "SiteSettings": {
 | 
				
			||||||
    "BaseUrl": "https://api.vesmeh.com",
 | 
					    "BaseUrl": "https://api.vesmeh.com",
 | 
				
			||||||
 | 
					    "WebSiteUrl": "https://vesmeh.com",
 | 
				
			||||||
    "AdminPanelBaseUrl": "https://admin.vesmeh.com",
 | 
					    "AdminPanelBaseUrl": "https://admin.vesmeh.com",
 | 
				
			||||||
    "StorageBaseUrl": "https://storage.vesmeh.ir",
 | 
					    "StorageBaseUrl": "https://storage.vesmeh.com",
 | 
				
			||||||
    "KaveNegarApiKey": "3735494B4143727A794346457461576A2B4B6668414973424E333561505A694B",
 | 
					    "KaveNegarApiKey": "3735494B4143727A794346457461576A2B4B6668414973424E333561505A694B",
 | 
				
			||||||
    "UserSetting": {
 | 
					    "UserSetting": {
 | 
				
			||||||
      "Username": "09214802813",
 | 
					      "Username": "09214802813",
 | 
				
			||||||
| 
						 | 
					@ -30,6 +31,11 @@
 | 
				
			||||||
      "FirstName": "همه کاره",
 | 
					      "FirstName": "همه کاره",
 | 
				
			||||||
      "LastName": "سیستم"
 | 
					      "LastName": "سیستم"
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
 | 
					    "StorageSetting": {
 | 
				
			||||||
 | 
					      "AccessKey": "d37a1cc6acfea3a6f92c538ef0f6601f1edcdc9143942b6470e5d1032aa6bfe2",
 | 
				
			||||||
 | 
					      "SecretKey": "979313b7-30fb-40ff-94d8-d0390d3fa876",
 | 
				
			||||||
 | 
					      "BucketKey": "vesmeh-content"
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
    "JwtSettings": {
 | 
					    "JwtSettings": {
 | 
				
			||||||
      "SecretKey": "YAEMAMZAMAN_KHODET_NEGAHDAR_IN_KEY_BASH_nw+8E0EABj0Wg8c4mHg/bDBf5qGMhmBPb6u16DVe9/MzYva1e+/J1zImyIoQX2Lmra2kvzsIjGiwP7r3Znd_YA_JADE_NASABE_v+Ro/CDixScDv6EkpZnkBv9MFdPnSmFXNGMH9gA1BzQUoC1iSX9Aq+pMIw/cMKXI9WA==_YA_HUSEIN_SEYED_SHOHADA_BE_OMID_KHODET",
 | 
					      "SecretKey": "YAEMAMZAMAN_KHODET_NEGAHDAR_IN_KEY_BASH_nw+8E0EABj0Wg8c4mHg/bDBf5qGMhmBPb6u16DVe9/MzYva1e+/J1zImyIoQX2Lmra2kvzsIjGiwP7r3Znd_YA_JADE_NASABE_v+Ro/CDixScDv6EkpZnkBv9MFdPnSmFXNGMH9gA1BzQUoC1iSX9Aq+pMIw/cMKXI9WA==_YA_HUSEIN_SEYED_SHOHADA_BE_OMID_KHODET",
 | 
				
			||||||
      "Issuer": "Brizco",
 | 
					      "Issuer": "Brizco",
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -18,8 +18,9 @@
 | 
				
			||||||
  },
 | 
					  },
 | 
				
			||||||
  "SiteSettings": {
 | 
					  "SiteSettings": {
 | 
				
			||||||
    "BaseUrl": "http://localhost:32770",
 | 
					    "BaseUrl": "http://localhost:32770",
 | 
				
			||||||
 | 
					    "WebSiteUrl": "https://vesmeh.com",
 | 
				
			||||||
    "AdminPanelBaseUrl": "https://admin.vesmeh.com",
 | 
					    "AdminPanelBaseUrl": "https://admin.vesmeh.com",
 | 
				
			||||||
    "StorageBaseUrl": "https://storage.vesmeh.ir",
 | 
					    "StorageBaseUrl": "https://storage.vesmeh.com",
 | 
				
			||||||
    "KaveNegarApiKey": "3735494B4143727A794346457461576A2B4B6668414973424E333561505A694B",
 | 
					    "KaveNegarApiKey": "3735494B4143727A794346457461576A2B4B6668414973424E333561505A694B",
 | 
				
			||||||
    "UserSetting": {
 | 
					    "UserSetting": {
 | 
				
			||||||
      "Username": "netinashop",
 | 
					      "Username": "netinashop",
 | 
				
			||||||
| 
						 | 
					@ -30,6 +31,11 @@
 | 
				
			||||||
      "FirstName": "همه کاره",
 | 
					      "FirstName": "همه کاره",
 | 
				
			||||||
      "LastName": "سیستم"
 | 
					      "LastName": "سیستم"
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
 | 
					    "StorageSetting": {
 | 
				
			||||||
 | 
					      "AccessKey": "d37a1cc6acfea3a6f92c538ef0f6601f1edcdc9143942b6470e5d1032aa6bfe2",
 | 
				
			||||||
 | 
					      "SecretKey": "979313b7-30fb-40ff-94d8-d0390d3fa876",
 | 
				
			||||||
 | 
					      "BucketKey": "vesmeh-content"
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
    "JwtSettings": {
 | 
					    "JwtSettings": {
 | 
				
			||||||
      "SecretKey": "YAEMAMZAMAN_KHODET_NEGAHDAR_IN_KEY_BASH_nw+8E0EABj0Wg8c4mHg/bDBf5qGMhmBPb6u16DVe9/MzYva1e+/J1zImyIoQX2Lmra2kvzsIjGiwP7r3Znd_YA_JADE_NASABE_v+Ro/CDixScDv6EkpZnkBv9MFdPnSmFXNGMH9gA1BzQUoC1iSX9Aq+pMIw/cMKXI9WA==_YA_HUSEIN_SEYED_SHOHADA_BE_OMID_KHODET",
 | 
					      "SecretKey": "YAEMAMZAMAN_KHODET_NEGAHDAR_IN_KEY_BASH_nw+8E0EABj0Wg8c4mHg/bDBf5qGMhmBPb6u16DVe9/MzYva1e+/J1zImyIoQX2Lmra2kvzsIjGiwP7r3Znd_YA_JADE_NASABE_v+Ro/CDixScDv6EkpZnkBv9MFdPnSmFXNGMH9gA1BzQUoC1iSX9Aq+pMIw/cMKXI9WA==_YA_HUSEIN_SEYED_SHOHADA_BE_OMID_KHODET",
 | 
				
			||||||
      "Issuer": "Brizco",
 | 
					      "Issuer": "Brizco",
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -15,7 +15,7 @@ public class HealthController : ICarterModule
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public async Task<IResult> GetHealth([FromServices]ISiteMapService siteMapService)
 | 
					    public async Task<IResult> GetHealth([FromServices]ISiteMapService siteMapService)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        await siteMapService.CreateSiteMapAsync();
 | 
					        //await siteMapService.CreateSiteMapAsync();
 | 
				
			||||||
        var version = typeof(Program)?.Assembly.GetName()?.Version?.ToString();
 | 
					        var version = typeof(Program)?.Assembly.GetName()?.Version?.ToString();
 | 
				
			||||||
        var check = new HealthCheck
 | 
					        var check = new HealthCheck
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,273 +1,6 @@
 | 
				
			||||||
using System.IO;
 | 
					namespace NetinaShop.Core.BaseServices.Abstracts;
 | 
				
			||||||
using System.IO.Compression;
 | 
					 | 
				
			||||||
using System.IO.Pipes;
 | 
					 | 
				
			||||||
using System.Xml;
 | 
					 | 
				
			||||||
using NetinaShop.Core.Models;
 | 
					 | 
				
			||||||
using NetinaShop.Domain.Entities.Blogs;
 | 
					 | 
				
			||||||
using NetinaShop.Domain.Entities.ProductCategories;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
namespace NetinaShop.Core.BaseServices.Abstracts;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
public interface ISiteMapService : IScopedDependency
 | 
					public interface ISiteMapService : IScopedDependency
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    public Task CreateSiteMapAsync();
 | 
					    public Task CreateSiteMapAsync();
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					 | 
				
			||||||
public class SiteMapService : ISiteMapService
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    private readonly IUploadFileService _uploadFileService;
 | 
					 | 
				
			||||||
    private readonly IRepositoryWrapper _repositoryWrapper;
 | 
					 | 
				
			||||||
    private readonly SiteSettings _siteSetting;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    public SiteMapService(IOptionsSnapshot<SiteSettings> snapshot, IUploadFileService uploadFileService,IRepositoryWrapper repositoryWrapper)
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        _uploadFileService = uploadFileService;
 | 
					 | 
				
			||||||
        _repositoryWrapper = repositoryWrapper;
 | 
					 | 
				
			||||||
        _siteSetting = snapshot.Value;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    public async Task CreateSiteMapAsync()
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        XmlDocument doc = new XmlDocument();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        // XML declaration
 | 
					 | 
				
			||||||
        XmlNode declaration = doc.CreateNode(XmlNodeType.XmlDeclaration, "sitemap.xml", null);
 | 
					 | 
				
			||||||
        doc.AppendChild(declaration);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        // Root element: Catalog
 | 
					 | 
				
			||||||
        XmlElement root = doc.CreateElement("sitemapindex", "http://www.sitemaps.org/schemas/sitemap/0.9");
 | 
					 | 
				
			||||||
        doc.AppendChild(root);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        foreach (var siteMapsUId in SiteMapUIds.AllSiteMapsUIds)
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
            XmlElement siteMapElement = doc.CreateElement("sitemap", doc.DocumentElement?.NamespaceURI);
 | 
					 | 
				
			||||||
            root.AppendChild(siteMapElement);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            XmlElement id = doc.CreateElement("loc", doc.DocumentElement?.NamespaceURI);
 | 
					 | 
				
			||||||
            id.InnerText = Path.Combine(_siteSetting.StorageBaseUrl, "site-maps", $"{siteMapsUId}.gz");
 | 
					 | 
				
			||||||
            siteMapElement.AppendChild(id);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            XmlElement lastmod = doc.CreateElement("lastmod", doc.DocumentElement?.NamespaceURI);
 | 
					 | 
				
			||||||
            lastmod.InnerText = DateTime.Today.ToString("yyyy-MM-dd");
 | 
					 | 
				
			||||||
            siteMapElement.AppendChild(lastmod);
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        System.IO.MemoryStream stream = new System.IO.MemoryStream();
 | 
					 | 
				
			||||||
        XmlTextWriter writer = new XmlTextWriter(stream, System.Text.Encoding.UTF8);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        doc.WriteTo(writer);
 | 
					 | 
				
			||||||
        writer.Flush();
 | 
					 | 
				
			||||||
        byte[] byteArray = stream.ToArray();
 | 
					 | 
				
			||||||
        await _uploadFileService.UploadFileByteAsync(new FileUploadRequest
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
            FileBytes = byteArray,
 | 
					 | 
				
			||||||
            ContentType = "text/xml",
 | 
					 | 
				
			||||||
            FileName = "site-map.xml",
 | 
					 | 
				
			||||||
            FileUploadType = FileUploadType.SiteMap,
 | 
					 | 
				
			||||||
        });
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        await CreateCategoriesSiteMapsAsync();
 | 
					 | 
				
			||||||
        await CreateProductsSiteMapsAsync();
 | 
					 | 
				
			||||||
        await CreateBlogsSiteMapsAsync();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    private async Task CreateCategoriesSiteMapsAsync()
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        var siteMapsUId = SiteMapUIds.Categories;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        var categories = await _repositoryWrapper.SetRepository<ProductCategory>()
 | 
					 | 
				
			||||||
            .TableNoTracking
 | 
					 | 
				
			||||||
            .ToListAsync();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        XmlDocument doc = new XmlDocument();
 | 
					 | 
				
			||||||
        
 | 
					 | 
				
			||||||
        XmlNode declaration = doc.CreateNode(XmlNodeType.XmlDeclaration, "sitemap.xml", null);
 | 
					 | 
				
			||||||
        doc.AppendChild(declaration);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        XmlElement root = doc.CreateElement("urlset", "http://www.sitemaps.org/schemas/sitemap/0.9");
 | 
					 | 
				
			||||||
        root.SetAttribute("xmlns:image", "http://www.google.com/schemas/sitemap-image/1.1");
 | 
					 | 
				
			||||||
        doc.AppendChild(root);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        foreach (var productCategory in categories)
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
            XmlElement urlElement = doc.CreateElement("url", doc.DocumentElement?.NamespaceURI);
 | 
					 | 
				
			||||||
            root.AppendChild(urlElement);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            XmlElement loc = doc.CreateElement("loc", doc.DocumentElement?.NamespaceURI);
 | 
					 | 
				
			||||||
            loc.InnerText = Path.Combine(productCategory.Name);
 | 
					 | 
				
			||||||
            urlElement.AppendChild(loc);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            XmlElement lastmod = doc.CreateElement("lastmod", doc.DocumentElement?.NamespaceURI);
 | 
					 | 
				
			||||||
            lastmod.InnerText = productCategory.ModifiedAt == DateTime.MinValue ? productCategory.CreatedAt.ToString("yyyy-MM-dd") : productCategory.ModifiedAt.ToString("yyyy-MM-dd");
 | 
					 | 
				
			||||||
            urlElement.AppendChild(lastmod);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            XmlElement changeFeq = doc.CreateElement("changefreq", doc.DocumentElement?.NamespaceURI);
 | 
					 | 
				
			||||||
            changeFeq.InnerText = "daily";
 | 
					 | 
				
			||||||
            urlElement.AppendChild(changeFeq);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            XmlElement priority = doc.CreateElement("priority", doc.DocumentElement?.NamespaceURI);
 | 
					 | 
				
			||||||
            priority.InnerText = "0.9";
 | 
					 | 
				
			||||||
            urlElement.AppendChild(priority);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        using var siteMapStream = new MemoryStream();
 | 
					 | 
				
			||||||
        await using var siteMapWriter = new XmlTextWriter(siteMapStream, Encoding.UTF8);
 | 
					 | 
				
			||||||
        doc.WriteTo(siteMapWriter);
 | 
					 | 
				
			||||||
        siteMapWriter.Flush();
 | 
					 | 
				
			||||||
        byte[] unZipBytes = siteMapStream.ToArray();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        using (var compressedStream = new MemoryStream())
 | 
					 | 
				
			||||||
        await using (var zipStream = new GZipStream(compressedStream, CompressionMode.Compress))
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
            zipStream.Write(unZipBytes, 0, unZipBytes.Length);
 | 
					 | 
				
			||||||
            zipStream.Close();
 | 
					 | 
				
			||||||
            var siteMapArray = compressedStream.ToArray();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            await _uploadFileService.UploadFileByteAsync(new FileUploadRequest
 | 
					 | 
				
			||||||
            {
 | 
					 | 
				
			||||||
                FileBytes = siteMapArray,
 | 
					 | 
				
			||||||
                ContentType = "text/plain",
 | 
					 | 
				
			||||||
                FileName = $"{siteMapsUId}.gz",
 | 
					 | 
				
			||||||
                FileUploadType = FileUploadType.SiteMap,
 | 
					 | 
				
			||||||
            });
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    private async Task CreateProductsSiteMapsAsync()
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        var siteMapsUId = SiteMapUIds.Products;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        var products = await _repositoryWrapper.SetRepository<Product>()
 | 
					 | 
				
			||||||
            .TableNoTracking
 | 
					 | 
				
			||||||
            .ToListAsync();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        XmlDocument doc = new XmlDocument();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        XmlNode declaration = doc.CreateNode(XmlNodeType.XmlDeclaration, "sitemap.xml", null);
 | 
					 | 
				
			||||||
        doc.AppendChild(declaration);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        XmlElement root = doc.CreateElement("urlset", "http://www.sitemaps.org/schemas/sitemap/0.9");
 | 
					 | 
				
			||||||
        root.SetAttribute("xmlns:image", "http://www.google.com/schemas/sitemap-image/1.1");
 | 
					 | 
				
			||||||
        doc.AppendChild(root);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        foreach (var product in products)
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
            XmlElement urlElement = doc.CreateElement("url", doc.DocumentElement?.NamespaceURI);
 | 
					 | 
				
			||||||
            root.AppendChild(urlElement);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            XmlElement loc = doc.CreateElement("loc", doc.DocumentElement?.NamespaceURI);
 | 
					 | 
				
			||||||
            loc.InnerText = Path.Combine(product.PersianName);
 | 
					 | 
				
			||||||
            urlElement.AppendChild(loc);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            XmlElement lastmod = doc.CreateElement("lastmod", doc.DocumentElement?.NamespaceURI);
 | 
					 | 
				
			||||||
            lastmod.InnerText = product.ModifiedAt == DateTime.MinValue ? product.CreatedAt.ToString("yyyy-MM-dd") : product.ModifiedAt.ToString("yyyy-MM-dd");
 | 
					 | 
				
			||||||
            urlElement.AppendChild(lastmod);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            XmlElement changeFeq = doc.CreateElement("changefreq", doc.DocumentElement?.NamespaceURI);
 | 
					 | 
				
			||||||
            changeFeq.InnerText = "daily";
 | 
					 | 
				
			||||||
            urlElement.AppendChild(changeFeq);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            XmlElement priority = doc.CreateElement("priority", doc.DocumentElement?.NamespaceURI);
 | 
					 | 
				
			||||||
            priority.InnerText = "0.9";
 | 
					 | 
				
			||||||
            urlElement.AppendChild(priority);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        using var siteMapStream = new MemoryStream();
 | 
					 | 
				
			||||||
        await using var siteMapWriter = new XmlTextWriter(siteMapStream, Encoding.UTF8);
 | 
					 | 
				
			||||||
        doc.WriteTo(siteMapWriter);
 | 
					 | 
				
			||||||
        siteMapWriter.Flush();
 | 
					 | 
				
			||||||
        byte[] unZipBytes = siteMapStream.ToArray();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        using (var compressedStream = new MemoryStream())
 | 
					 | 
				
			||||||
        await using (var zipStream = new GZipStream(compressedStream, CompressionMode.Compress))
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
            zipStream.Write(unZipBytes, 0, unZipBytes.Length);
 | 
					 | 
				
			||||||
            zipStream.Close();
 | 
					 | 
				
			||||||
            var siteMapArray = compressedStream.ToArray();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            await _uploadFileService.UploadFileByteAsync(new FileUploadRequest
 | 
					 | 
				
			||||||
            {
 | 
					 | 
				
			||||||
                FileBytes = siteMapArray,
 | 
					 | 
				
			||||||
                ContentType = "text/plain",
 | 
					 | 
				
			||||||
                FileName = $"{siteMapsUId}.gz",
 | 
					 | 
				
			||||||
                FileUploadType = FileUploadType.SiteMap,
 | 
					 | 
				
			||||||
            });
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    private async Task CreateBlogsSiteMapsAsync()
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        var siteMapsUId = SiteMapUIds.Blogs;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        var categories = await _repositoryWrapper.SetRepository<Blog>()
 | 
					 | 
				
			||||||
            .TableNoTracking
 | 
					 | 
				
			||||||
            .ToListAsync();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        XmlDocument doc = new XmlDocument();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        XmlNode declaration = doc.CreateNode(XmlNodeType.XmlDeclaration, "sitemap.xml", null);
 | 
					 | 
				
			||||||
        doc.AppendChild(declaration);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        XmlElement root = doc.CreateElement("urlset", "http://www.sitemaps.org/schemas/sitemap/0.9");
 | 
					 | 
				
			||||||
        root.SetAttribute("xmlns:image", "http://www.google.com/schemas/sitemap-image/1.1");
 | 
					 | 
				
			||||||
        doc.AppendChild(root);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        foreach (var productCategory in categories)
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
            XmlElement urlElement = doc.CreateElement("url", doc.DocumentElement?.NamespaceURI);
 | 
					 | 
				
			||||||
            root.AppendChild(urlElement);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            XmlElement loc = doc.CreateElement("loc", doc.DocumentElement?.NamespaceURI);
 | 
					 | 
				
			||||||
            loc.InnerText = Path.Combine(productCategory.Title);
 | 
					 | 
				
			||||||
            urlElement.AppendChild(loc);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            XmlElement lastmod = doc.CreateElement("lastmod", doc.DocumentElement?.NamespaceURI);
 | 
					 | 
				
			||||||
            lastmod.InnerText = productCategory.ModifiedAt == DateTime.MinValue ? productCategory.CreatedAt.ToString("yyyy-MM-dd") : productCategory.ModifiedAt.ToString("yyyy-MM-dd");
 | 
					 | 
				
			||||||
            urlElement.AppendChild(lastmod);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            XmlElement changeFeq = doc.CreateElement("changefreq", doc.DocumentElement?.NamespaceURI);
 | 
					 | 
				
			||||||
            changeFeq.InnerText = "daily";
 | 
					 | 
				
			||||||
            urlElement.AppendChild(changeFeq);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            XmlElement priority = doc.CreateElement("priority", doc.DocumentElement?.NamespaceURI);
 | 
					 | 
				
			||||||
            priority.InnerText = "0.9";
 | 
					 | 
				
			||||||
            urlElement.AppendChild(priority);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        using var siteMapStream = new MemoryStream();
 | 
					 | 
				
			||||||
        await using var siteMapWriter = new XmlTextWriter(siteMapStream, Encoding.UTF8);
 | 
					 | 
				
			||||||
        doc.WriteTo(siteMapWriter);
 | 
					 | 
				
			||||||
        siteMapWriter.Flush();
 | 
					 | 
				
			||||||
        byte[] unZipBytes = siteMapStream.ToArray();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        using (var compressedStream = new MemoryStream())
 | 
					 | 
				
			||||||
        await using (var zipStream = new GZipStream(compressedStream, CompressionMode.Compress))
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
            zipStream.Write(unZipBytes, 0, unZipBytes.Length);
 | 
					 | 
				
			||||||
            zipStream.Close();
 | 
					 | 
				
			||||||
            var siteMapArray = compressedStream.ToArray();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            await _uploadFileService.UploadFileByteAsync(new FileUploadRequest
 | 
					 | 
				
			||||||
            {
 | 
					 | 
				
			||||||
                FileBytes = siteMapArray,
 | 
					 | 
				
			||||||
                ContentType = "text/plain",
 | 
					 | 
				
			||||||
                FileName = $"{siteMapsUId}.gz",
 | 
					 | 
				
			||||||
                FileUploadType = FileUploadType.SiteMap,
 | 
					 | 
				
			||||||
            });
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,364 @@
 | 
				
			||||||
 | 
					using NetinaShop.Core.Models;
 | 
				
			||||||
 | 
					using NetinaShop.Domain.Entities.Blogs;
 | 
				
			||||||
 | 
					using NetinaShop.Domain.Entities.ProductCategories;
 | 
				
			||||||
 | 
					using System.IO.Compression;
 | 
				
			||||||
 | 
					using System.Web;
 | 
				
			||||||
 | 
					using System.Xml;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace NetinaShop.Core.BaseServices;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					public class SiteMapService : ISiteMapService
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    private readonly IUploadFileService _uploadFileService;
 | 
				
			||||||
 | 
					    private readonly IRepositoryWrapper _repositoryWrapper;
 | 
				
			||||||
 | 
					    private readonly SiteSettings _siteSetting;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public SiteMapService(IOptionsSnapshot<SiteSettings> snapshot, IUploadFileService uploadFileService, IRepositoryWrapper repositoryWrapper)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        _uploadFileService = uploadFileService;
 | 
				
			||||||
 | 
					        _repositoryWrapper = repositoryWrapper;
 | 
				
			||||||
 | 
					        _siteSetting = snapshot.Value;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    public async Task CreateSiteMapAsync()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        XmlDocument doc = new XmlDocument();
 | 
				
			||||||
 | 
					        XmlDeclaration documentType = doc.CreateXmlDeclaration("1.0", "utf-8", null);
 | 
				
			||||||
 | 
					        doc.AppendChild(documentType);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // XML declaration
 | 
				
			||||||
 | 
					        //XmlNode declaration = doc.CreateNode(XmlNodeType.XmlDeclaration, "sitemap.xml", null);
 | 
				
			||||||
 | 
					        //doc.AppendChild(declaration);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // Root element: Catalog
 | 
				
			||||||
 | 
					        XmlElement root = doc.CreateElement("sitemapindex", "http://www.sitemaps.org/schemas/sitemap/0.9");
 | 
				
			||||||
 | 
					        doc.AppendChild(root);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        var categories = await _repositoryWrapper.SetRepository<ProductCategory>()
 | 
				
			||||||
 | 
					            .TableNoTracking
 | 
				
			||||||
 | 
					            .ToListAsync();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        foreach (var siteMapsUId in SiteMapUIds.AllSiteMapsUIds)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            XmlElement siteMapElement = doc.CreateElement("sitemap", doc.DocumentElement?.NamespaceURI);
 | 
				
			||||||
 | 
					            root.AppendChild(siteMapElement);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            XmlElement id = doc.CreateElement("loc", doc.DocumentElement?.NamespaceURI);
 | 
				
			||||||
 | 
					            id.InnerText = Path.Combine(_siteSetting.StorageBaseUrl, "site-maps", $"{siteMapsUId}.gz");
 | 
				
			||||||
 | 
					            siteMapElement.AppendChild(id);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            XmlElement lastmod = doc.CreateElement("lastmod", doc.DocumentElement?.NamespaceURI);
 | 
				
			||||||
 | 
					            lastmod.InnerText = DateTime.Today.ToString("yyyy-MM-dd");
 | 
				
			||||||
 | 
					            siteMapElement.AppendChild(lastmod);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        foreach (var category in categories)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            XmlElement siteMapElement = doc.CreateElement("sitemap", doc.DocumentElement?.NamespaceURI);
 | 
				
			||||||
 | 
					            root.AppendChild(siteMapElement);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            XmlElement id = doc.CreateElement("loc", doc.DocumentElement?.NamespaceURI);
 | 
				
			||||||
 | 
					            id.InnerText = Path.Combine(_siteSetting.StorageBaseUrl, "site-maps", $"{category.Id.ToString().ToUpper()}.gz");
 | 
				
			||||||
 | 
					            siteMapElement.AppendChild(id);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            XmlElement lastmod = doc.CreateElement("lastmod", doc.DocumentElement?.NamespaceURI);
 | 
				
			||||||
 | 
					            lastmod.InnerText = DateTime.Today.ToString("yyyy-MM-dd");
 | 
				
			||||||
 | 
					            siteMapElement.AppendChild(lastmod);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        System.IO.MemoryStream stream = new System.IO.MemoryStream();
 | 
				
			||||||
 | 
					        XmlTextWriter writer = new XmlTextWriter(stream, System.Text.Encoding.UTF8);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        doc.WriteTo(writer);
 | 
				
			||||||
 | 
					        writer.Flush();
 | 
				
			||||||
 | 
					        byte[] byteArray = stream.ToArray();
 | 
				
			||||||
 | 
					        await _uploadFileService.UploadFileByteAsync(new FileUploadRequest
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            FileBytes = byteArray,
 | 
				
			||||||
 | 
					            ContentType = "text/xml",
 | 
				
			||||||
 | 
					            FileName = "site-map.xml",
 | 
				
			||||||
 | 
					            FileUploadType = FileUploadType.SiteMap,
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        await CreateCategoriesSiteMapsAsync();
 | 
				
			||||||
 | 
					        await CreateProductsSiteMapsAsync();
 | 
				
			||||||
 | 
					        await CreateBlogsSiteMapsAsync();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    private async Task CreateCategoriesSiteMapsAsync()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        var siteMapsUId = SiteMapUIds.Categories;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        var categories = await _repositoryWrapper.SetRepository<ProductCategory>()
 | 
				
			||||||
 | 
					            .TableNoTracking
 | 
				
			||||||
 | 
					            .ToListAsync();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        XmlDocument doc = new XmlDocument();
 | 
				
			||||||
 | 
					        XmlDeclaration documentType = doc.CreateXmlDeclaration("1.0", "utf-8", null);
 | 
				
			||||||
 | 
					        doc.AppendChild(documentType);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        //XmlNode declaration = doc.CreateNode(XmlNodeType.XmlDeclaration, "sitemap.xml", null);
 | 
				
			||||||
 | 
					        //doc.AppendChild(declaration);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        XmlElement root = doc.CreateElement("urlset", "http://www.sitemaps.org/schemas/sitemap/0.9");
 | 
				
			||||||
 | 
					        root.SetAttribute("xmlns:image", "http://www.google.com/schemas/sitemap-image/1.1");
 | 
				
			||||||
 | 
					        doc.AppendChild(root);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        foreach (var productCategory in categories)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            var productUrl = $"{_siteSetting.WebSiteUrl}/categories/{productCategory.Id}/{HttpUtility.UrlEncode(productCategory.Name.Replace(' ', '-'))}";
 | 
				
			||||||
 | 
					            XmlElement urlElement = doc.CreateElement("url", doc.DocumentElement?.NamespaceURI);
 | 
				
			||||||
 | 
					            root.AppendChild(urlElement);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            XmlElement loc = doc.CreateElement("loc", doc.DocumentElement?.NamespaceURI);
 | 
				
			||||||
 | 
					            loc.InnerText = Path.Combine(productCategory.Name);
 | 
				
			||||||
 | 
					            urlElement.AppendChild(loc);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            XmlElement lastmod = doc.CreateElement("lastmod", doc.DocumentElement?.NamespaceURI);
 | 
				
			||||||
 | 
					            lastmod.InnerText = productCategory.ModifiedAt == DateTime.MinValue ? productCategory.CreatedAt.ToString("yyyy-MM-dd") : productCategory.ModifiedAt.ToString("yyyy-MM-dd");
 | 
				
			||||||
 | 
					            urlElement.AppendChild(lastmod);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            XmlElement changeFeq = doc.CreateElement("changefreq", doc.DocumentElement?.NamespaceURI);
 | 
				
			||||||
 | 
					            changeFeq.InnerText = "daily";
 | 
				
			||||||
 | 
					            urlElement.AppendChild(changeFeq);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            XmlElement priority = doc.CreateElement("priority", doc.DocumentElement?.NamespaceURI);
 | 
				
			||||||
 | 
					            priority.InnerText = "0.9";
 | 
				
			||||||
 | 
					            urlElement.AppendChild(priority);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        using var siteMapStream = new MemoryStream();
 | 
				
			||||||
 | 
					        await using var siteMapWriter = new XmlTextWriter(siteMapStream, Encoding.UTF8);
 | 
				
			||||||
 | 
					        doc.WriteTo(siteMapWriter);
 | 
				
			||||||
 | 
					        siteMapWriter.Flush();
 | 
				
			||||||
 | 
					        byte[] unZipBytes = siteMapStream.ToArray();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        using (var compressedStream = new MemoryStream())
 | 
				
			||||||
 | 
					        await using (var zipStream = new GZipStream(compressedStream, CompressionMode.Compress))
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            zipStream.Write(unZipBytes, 0, unZipBytes.Length);
 | 
				
			||||||
 | 
					            zipStream.Close();
 | 
				
			||||||
 | 
					            var siteMapArray = compressedStream.ToArray();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            await _uploadFileService.UploadFileByteAsync(new FileUploadRequest
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                FileBytes = siteMapArray,
 | 
				
			||||||
 | 
					                ContentType = "text/plain",
 | 
				
			||||||
 | 
					                FileName = $"{siteMapsUId}.gz",
 | 
				
			||||||
 | 
					                FileUploadType = FileUploadType.SiteMap,
 | 
				
			||||||
 | 
					            });
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    private async Task CreateProductsSiteMapsAsync()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        var products = await _repositoryWrapper.SetRepository<Product>()
 | 
				
			||||||
 | 
					            .TableNoTracking
 | 
				
			||||||
 | 
					            .Select(ProductMapper.ProjectToSDto)
 | 
				
			||||||
 | 
					            .ToListAsync();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        var groupedProducts = products.GroupBy(p => p.CategoryId);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        foreach (var group in groupedProducts)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            XmlDocument doc = new XmlDocument();
 | 
				
			||||||
 | 
					            XmlDeclaration documentType = doc.CreateXmlDeclaration("1.0", "utf-8", null);
 | 
				
			||||||
 | 
					            doc.AppendChild(documentType);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            //XmlNode declaration = doc.CreateNode(XmlNodeType.XmlDeclaration, "sitemap.xml", null);
 | 
				
			||||||
 | 
					            //doc.AppendChild(declaration);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            XmlElement root = doc.CreateElement("urlset", "http://www.sitemaps.org/schemas/sitemap/0.9");
 | 
				
			||||||
 | 
					            root.SetAttribute("xmlns:image", "http://www.google.com/schemas/sitemap-image/1.1");
 | 
				
			||||||
 | 
					            doc.AppendChild(root);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            foreach (var product in group)
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                var productUrl = $"{_siteSetting.WebSiteUrl}/products/{product.Id}/{HttpUtility.UrlEncode(product.PersianName.Replace(' ', '-'))}";
 | 
				
			||||||
 | 
					                XmlElement urlElement = doc.CreateElement("url", doc.DocumentElement?.NamespaceURI);
 | 
				
			||||||
 | 
					                root.AppendChild(urlElement);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                XmlElement loc = doc.CreateElement("loc", doc.DocumentElement?.NamespaceURI);
 | 
				
			||||||
 | 
					                loc.InnerText = Path.Combine(productUrl);
 | 
				
			||||||
 | 
					                urlElement.AppendChild(loc);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                XmlElement lastmod = doc.CreateElement("lastmod", doc.DocumentElement?.NamespaceURI);
 | 
				
			||||||
 | 
					                lastmod.InnerText = product.ModifiedAt == DateTime.MinValue ? product.CreatedAt.ToString("yyyy-MM-dd") : product.ModifiedAt.ToString("yyyy-MM-dd");
 | 
				
			||||||
 | 
					                urlElement.AppendChild(lastmod);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                XmlElement changeFeq = doc.CreateElement("changefreq", doc.DocumentElement?.NamespaceURI);
 | 
				
			||||||
 | 
					                changeFeq.InnerText = "daily";
 | 
				
			||||||
 | 
					                urlElement.AppendChild(changeFeq);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                XmlElement priority = doc.CreateElement("priority", doc.DocumentElement?.NamespaceURI);
 | 
				
			||||||
 | 
					                priority.InnerText = "0.9";
 | 
				
			||||||
 | 
					                urlElement.AppendChild(priority);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                if (product.MainImage != string.Empty)
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    XmlElement image = doc.CreateElement("image:image", "http://www.google.com/schemas/sitemap-image/1.1");
 | 
				
			||||||
 | 
					                    urlElement.AppendChild(image);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                    XmlElement imageLoc = doc.CreateElement("image:loc", "http://www.google.com/schemas/sitemap-image/1.1");
 | 
				
			||||||
 | 
					                    imageLoc.InnerText = $"{_siteSetting.StorageBaseUrl}/{product.MainImage.Replace("Med", "Thumb")}";
 | 
				
			||||||
 | 
					                    image.AppendChild(imageLoc);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                    XmlElement imageCaption = doc.CreateElement("image:caption", "http://www.google.com/schemas/sitemap-image/1.1");
 | 
				
			||||||
 | 
					                    imageCaption.InnerText = product.PersianName;
 | 
				
			||||||
 | 
					                    image.AppendChild(imageCaption);
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            using var siteMapStream = new MemoryStream();
 | 
				
			||||||
 | 
					            await using var siteMapWriter = new XmlTextWriter(siteMapStream, Encoding.UTF8);
 | 
				
			||||||
 | 
					            doc.WriteTo(siteMapWriter);
 | 
				
			||||||
 | 
					            siteMapWriter.Flush();
 | 
				
			||||||
 | 
					            byte[] unZipBytes = siteMapStream.ToArray();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            using (var compressedStream = new MemoryStream())
 | 
				
			||||||
 | 
					            await using (var zipStream = new GZipStream(compressedStream, CompressionMode.Compress))
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                zipStream.Write(unZipBytes, 0, unZipBytes.Length);
 | 
				
			||||||
 | 
					                zipStream.Close();
 | 
				
			||||||
 | 
					                var siteMapArray = compressedStream.ToArray();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                await _uploadFileService.UploadFileByteAsync(new FileUploadRequest
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    FileBytes = siteMapArray,
 | 
				
			||||||
 | 
					                    ContentType = "text/plain",
 | 
				
			||||||
 | 
					                    FileName = $"{group.Key.ToString().ToUpper()}.gz",
 | 
				
			||||||
 | 
					                    FileUploadType = FileUploadType.SiteMap,
 | 
				
			||||||
 | 
					                });
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    private async Task CreateBlogsSiteMapsAsync()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        var siteMapsUId = SiteMapUIds.Blogs;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        var blogs = await _repositoryWrapper.SetRepository<Blog>()
 | 
				
			||||||
 | 
					            .TableNoTracking
 | 
				
			||||||
 | 
					            .Select(BlogMapper.ProjectToSDto)
 | 
				
			||||||
 | 
					            .ToListAsync();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        XmlDocument doc = new XmlDocument();
 | 
				
			||||||
 | 
					        XmlDeclaration documentType = doc.CreateXmlDeclaration("1.0", "utf-8", null);
 | 
				
			||||||
 | 
					        doc.AppendChild(documentType);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        //XmlNode declaration = doc.CreateNode(XmlNodeType.XmlDeclaration, "sitemap.xml", null);
 | 
				
			||||||
 | 
					        //doc.AppendChild(declaration);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        XmlElement root = doc.CreateElement("urlset", "http://www.sitemaps.org/schemas/sitemap/0.9");
 | 
				
			||||||
 | 
					        root.SetAttribute("xmlns:image", "http://www.google.com/schemas/sitemap-image/1.1");
 | 
				
			||||||
 | 
					        root.SetAttribute("xmlns:news", "http://www.google.com/schemas/sitemap-news/0.9");
 | 
				
			||||||
 | 
					        doc.AppendChild(root);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        foreach (var blog in blogs)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            XmlElement urlElement = doc.CreateElement("url", doc.DocumentElement?.NamespaceURI);
 | 
				
			||||||
 | 
					            root.AppendChild(urlElement);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            XmlElement loc = doc.CreateElement("loc", doc.DocumentElement?.NamespaceURI);
 | 
				
			||||||
 | 
					            loc.InnerText = Path.Combine(blog.Title);
 | 
				
			||||||
 | 
					            urlElement.AppendChild(loc);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            XmlElement lastmod = doc.CreateElement("lastmod", doc.DocumentElement?.NamespaceURI);
 | 
				
			||||||
 | 
					            lastmod.InnerText = blog.ModifiedAt == DateTime.MinValue ? blog.CreatedAt.ToString("yyyy-MM-dd") : blog.ModifiedAt.ToString("yyyy-MM-dd");
 | 
				
			||||||
 | 
					            urlElement.AppendChild(lastmod);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            XmlElement changeFeq = doc.CreateElement("changefreq", doc.DocumentElement?.NamespaceURI);
 | 
				
			||||||
 | 
					            changeFeq.InnerText = "daily";
 | 
				
			||||||
 | 
					            urlElement.AppendChild(changeFeq);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            XmlElement priority = doc.CreateElement("priority", doc.DocumentElement?.NamespaceURI);
 | 
				
			||||||
 | 
					            priority.InnerText = "0.9";
 | 
				
			||||||
 | 
					            urlElement.AppendChild(priority);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            //Image
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            XmlElement image = doc.CreateElement("image:image", "http://www.google.com/schemas/sitemap-image/1.1");
 | 
				
			||||||
 | 
					            urlElement.AppendChild(image);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            XmlElement imageLoc = doc.CreateElement("image:loc", "http://www.google.com/schemas/sitemap-image/1.1");
 | 
				
			||||||
 | 
					            imageLoc.InnerText = $"{_siteSetting.StorageBaseUrl}/{blog.MainImage.Replace("Med", "Thumb")}";
 | 
				
			||||||
 | 
					            image.AppendChild(imageLoc);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            XmlElement imageCaption = doc.CreateElement("image:caption", "http://www.google.com/schemas/sitemap-image/1.1");
 | 
				
			||||||
 | 
					            imageCaption.InnerText = blog.Title;
 | 
				
			||||||
 | 
					            image.AppendChild(imageCaption);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            ////News
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            //XmlElement news = doc.CreateElement("news:news", "http://www.google.com/schemas/sitemap-news/0.9");
 | 
				
			||||||
 | 
					            //urlElement.AppendChild(news);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            //XmlElement newTitle = doc.CreateElement("news:title", "http://www.google.com/schemas/sitemap-news/0.9");
 | 
				
			||||||
 | 
					            //newTitle.InnerText = blog.Title;
 | 
				
			||||||
 | 
					            //news.AppendChild(newTitle);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            //XmlElement newPublificationDate = doc.CreateElement("news:publication_date", "http://www.google.com/schemas/sitemap-news/0.9");
 | 
				
			||||||
 | 
					            //newPublificationDate.InnerText = blog.CreatedAt.ToString("yyyy-MM-dd");
 | 
				
			||||||
 | 
					            //news.AppendChild(newPublificationDate);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            //XmlElement newsPublification = doc.CreateElement("news:publication", "http://www.google.com/schemas/sitemap-news/0.9");
 | 
				
			||||||
 | 
					            //news.AppendChild(newsPublification);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            //XmlElement newsPublicationName = doc.CreateElement("news:name", "http://www.google.com/schemas/sitemap-news/0.9");
 | 
				
			||||||
 | 
					            //newsPublicationName.InnerText = blog.Title;
 | 
				
			||||||
 | 
					            //newsPublification.AppendChild(newsPublicationName);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            //XmlElement newsPublicationLanq = doc.CreateElement("news:language", "http://www.google.com/schemas/sitemap-news/0.9");
 | 
				
			||||||
 | 
					            //newsPublicationLanq.InnerText = blog.CreatedAt.ToString("yyyy-MM-dd");
 | 
				
			||||||
 | 
					            //newsPublification.AppendChild(newsPublicationLanq);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        using var siteMapStream = new MemoryStream();
 | 
				
			||||||
 | 
					        await using var siteMapWriter = new XmlTextWriter(siteMapStream, Encoding.UTF8);
 | 
				
			||||||
 | 
					        doc.WriteTo(siteMapWriter);
 | 
				
			||||||
 | 
					        siteMapWriter.Flush();
 | 
				
			||||||
 | 
					        byte[] unZipBytes = siteMapStream.ToArray();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        using (var compressedStream = new MemoryStream())
 | 
				
			||||||
 | 
					        await using (var zipStream = new GZipStream(compressedStream, CompressionMode.Compress))
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            zipStream.Write(unZipBytes, 0, unZipBytes.Length);
 | 
				
			||||||
 | 
					            zipStream.Close();
 | 
				
			||||||
 | 
					            var siteMapArray = compressedStream.ToArray();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            await _uploadFileService.UploadFileByteAsync(new FileUploadRequest
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                FileBytes = siteMapArray,
 | 
				
			||||||
 | 
					                ContentType = "text/plain",
 | 
				
			||||||
 | 
					                FileName = $"{siteMapsUId}.gz",
 | 
				
			||||||
 | 
					                FileUploadType = FileUploadType.SiteMap,
 | 
				
			||||||
 | 
					            });
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -3,11 +3,10 @@ public static class SiteMapUIds
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    public const string Categories = "5709ACC29A4D42E5B6F2DFFAD2FB0018";
 | 
					    public const string Categories = "5709ACC29A4D42E5B6F2DFFAD2FB0018";
 | 
				
			||||||
    public const string Blogs = "4C2F0C2A7A3E41268702D12FDDDB837F";
 | 
					    public const string Blogs = "4C2F0C2A7A3E41268702D12FDDDB837F";
 | 
				
			||||||
    public const string Products = "E95AB3C0C4DD44FA82D77D55BD91696F";
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public static List<string> AllSiteMapsUIds => new List<string>
 | 
					    public static List<string> AllSiteMapsUIds => new List<string>
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        Categories,
 | 
					        Categories,
 | 
				
			||||||
        Blogs, Products
 | 
					        Blogs
 | 
				
			||||||
    };
 | 
					    };
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -10,5 +10,6 @@ public class BlogSDto : BaseDto<BlogSDto , Blog>
 | 
				
			||||||
    public bool IsSuggested { get; set; }
 | 
					    public bool IsSuggested { get; set; }
 | 
				
			||||||
    public Guid CategoryId { get; set; }
 | 
					    public Guid CategoryId { get; set; }
 | 
				
			||||||
    public string CategoryName { get; set; } = string.Empty;
 | 
					    public string CategoryName { get; set; } = string.Empty;
 | 
				
			||||||
    public string HeaderFileName { get; set; } = string.Empty;
 | 
					    public string MainImage { get; set; } = string.Empty;
 | 
				
			||||||
 | 
					    public DateTime ModifiedAt { get; set; }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -28,4 +28,5 @@ public class ProductSDto : BaseDto<ProductSDto, Product>
 | 
				
			||||||
    public Guid BrandId { get; set; }
 | 
					    public Guid BrandId { get; set; }
 | 
				
			||||||
    public string BrandName { get; set; } = string.Empty;
 | 
					    public string BrandName { get; set; } = string.Empty;
 | 
				
			||||||
    public string CategoryName { get; set; } = string.Empty;
 | 
					    public string CategoryName { get; set; } = string.Empty;
 | 
				
			||||||
 | 
					    public DateTime ModifiedAt { get; set; }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -56,7 +56,8 @@ namespace NetinaShop.Domain.Mappers
 | 
				
			||||||
                    Id = p8.CategoryId
 | 
					                    Id = p8.CategoryId
 | 
				
			||||||
                },
 | 
					                },
 | 
				
			||||||
                Id = p8.Id,
 | 
					                Id = p8.Id,
 | 
				
			||||||
                CreatedAt = p8.CreatedAt
 | 
					                CreatedAt = p8.CreatedAt,
 | 
				
			||||||
 | 
					                ModifiedAt = p8.ModifiedAt
 | 
				
			||||||
            }).ToList<Blog>(),
 | 
					            }).ToList<Blog>(),
 | 
				
			||||||
            Id = p7.Id,
 | 
					            Id = p7.Id,
 | 
				
			||||||
            CreatedAt = p7.CreatedAt
 | 
					            CreatedAt = p7.CreatedAt
 | 
				
			||||||
| 
						 | 
					@ -102,7 +103,8 @@ namespace NetinaShop.Domain.Mappers
 | 
				
			||||||
                IsSuggested = p16.IsSuggested,
 | 
					                IsSuggested = p16.IsSuggested,
 | 
				
			||||||
                CategoryId = p16.CategoryId,
 | 
					                CategoryId = p16.CategoryId,
 | 
				
			||||||
                CategoryName = p16.Category.Name,
 | 
					                CategoryName = p16.Category.Name,
 | 
				
			||||||
                HeaderFileName = p16.Files.Count > 0 && p16.Files.Any<BlogStorageFile>(f => f.IsHeader) ? p16.Files.FirstOrDefault<BlogStorageFile>(f => f.IsHeader).FileName : string.Empty,
 | 
					                MainImage = p16.Files.Count > 0 && p16.Files.Any<BlogStorageFile>(f => f.IsPrimary) ? p16.Files.FirstOrDefault<BlogStorageFile>(f => f.IsPrimary).FileName : string.Empty,
 | 
				
			||||||
 | 
					                ModifiedAt = p16.ModifiedAt,
 | 
				
			||||||
                Id = p16.Id,
 | 
					                Id = p16.Id,
 | 
				
			||||||
                CreatedAt = p16.CreatedAt
 | 
					                CreatedAt = p16.CreatedAt
 | 
				
			||||||
            }).ToList<BlogSDto>(),
 | 
					            }).ToList<BlogSDto>(),
 | 
				
			||||||
| 
						 | 
					@ -196,7 +198,8 @@ namespace NetinaShop.Domain.Mappers
 | 
				
			||||||
                        Id = item.CategoryId
 | 
					                        Id = item.CategoryId
 | 
				
			||||||
                    },
 | 
					                    },
 | 
				
			||||||
                    Id = item.Id,
 | 
					                    Id = item.Id,
 | 
				
			||||||
                    CreatedAt = item.CreatedAt
 | 
					                    CreatedAt = item.CreatedAt,
 | 
				
			||||||
 | 
					                    ModifiedAt = item.ModifiedAt
 | 
				
			||||||
                });
 | 
					                });
 | 
				
			||||||
                i++;
 | 
					                i++;
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
| 
						 | 
					@ -233,7 +236,8 @@ namespace NetinaShop.Domain.Mappers
 | 
				
			||||||
                        Id = item.CategoryId
 | 
					                        Id = item.CategoryId
 | 
				
			||||||
                    },
 | 
					                    },
 | 
				
			||||||
                    Id = item.Id,
 | 
					                    Id = item.Id,
 | 
				
			||||||
                    CreatedAt = item.CreatedAt
 | 
					                    CreatedAt = item.CreatedAt,
 | 
				
			||||||
 | 
					                    ModifiedAt = item.ModifiedAt
 | 
				
			||||||
                });
 | 
					                });
 | 
				
			||||||
                i++;
 | 
					                i++;
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
| 
						 | 
					@ -265,7 +269,8 @@ namespace NetinaShop.Domain.Mappers
 | 
				
			||||||
                    IsSuggested = item.IsSuggested,
 | 
					                    IsSuggested = item.IsSuggested,
 | 
				
			||||||
                    CategoryId = item.CategoryId,
 | 
					                    CategoryId = item.CategoryId,
 | 
				
			||||||
                    CategoryName = item.Category == null ? null : item.Category.Name,
 | 
					                    CategoryName = item.Category == null ? null : item.Category.Name,
 | 
				
			||||||
                    HeaderFileName = item.Files.Count > 0 && item.Files.Any<BlogStorageFile>(funcMain4) ? item.Files.FirstOrDefault<BlogStorageFile>(funcMain5).FileName : string.Empty,
 | 
					                    MainImage = item.Files.Count > 0 && item.Files.Any<BlogStorageFile>(funcMain4) ? item.Files.FirstOrDefault<BlogStorageFile>(funcMain5).FileName : string.Empty,
 | 
				
			||||||
 | 
					                    ModifiedAt = item.ModifiedAt,
 | 
				
			||||||
                    Id = item.Id,
 | 
					                    Id = item.Id,
 | 
				
			||||||
                    CreatedAt = item.CreatedAt
 | 
					                    CreatedAt = item.CreatedAt
 | 
				
			||||||
                });
 | 
					                });
 | 
				
			||||||
| 
						 | 
					@ -299,7 +304,8 @@ namespace NetinaShop.Domain.Mappers
 | 
				
			||||||
                    IsSuggested = item.IsSuggested,
 | 
					                    IsSuggested = item.IsSuggested,
 | 
				
			||||||
                    CategoryId = item.CategoryId,
 | 
					                    CategoryId = item.CategoryId,
 | 
				
			||||||
                    CategoryName = item.Category == null ? null : item.Category.Name,
 | 
					                    CategoryName = item.Category == null ? null : item.Category.Name,
 | 
				
			||||||
                    HeaderFileName = item.Files.Count > 0 && item.Files.Any<BlogStorageFile>(funcMain4) ? item.Files.FirstOrDefault<BlogStorageFile>(funcMain5).FileName : string.Empty,
 | 
					                    MainImage = item.Files.Count > 0 && item.Files.Any<BlogStorageFile>(funcMain4) ? item.Files.FirstOrDefault<BlogStorageFile>(funcMain5).FileName : string.Empty,
 | 
				
			||||||
 | 
					                    ModifiedAt = item.ModifiedAt,
 | 
				
			||||||
                    Id = item.Id,
 | 
					                    Id = item.Id,
 | 
				
			||||||
                    CreatedAt = item.CreatedAt
 | 
					                    CreatedAt = item.CreatedAt
 | 
				
			||||||
                });
 | 
					                });
 | 
				
			||||||
| 
						 | 
					@ -311,12 +317,12 @@ namespace NetinaShop.Domain.Mappers
 | 
				
			||||||
        
 | 
					        
 | 
				
			||||||
        private static bool funcMain4(BlogStorageFile f)
 | 
					        private static bool funcMain4(BlogStorageFile f)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            return f.IsHeader;
 | 
					            return f.IsPrimary;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        
 | 
					        
 | 
				
			||||||
        private static bool funcMain5(BlogStorageFile f)
 | 
					        private static bool funcMain5(BlogStorageFile f)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            return f.IsHeader;
 | 
					            return f.IsPrimary;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -150,7 +150,8 @@ namespace NetinaShop.Domain.Mappers
 | 
				
			||||||
                    Id = p17.CategoryId
 | 
					                    Id = p17.CategoryId
 | 
				
			||||||
                },
 | 
					                },
 | 
				
			||||||
                Id = p17.Id,
 | 
					                Id = p17.Id,
 | 
				
			||||||
                CreatedAt = p17.CreatedAt
 | 
					                CreatedAt = p17.CreatedAt,
 | 
				
			||||||
 | 
					                ModifiedAt = p17.ModifiedAt
 | 
				
			||||||
            };
 | 
					            };
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        public static Blog AdaptTo(this BlogSDto p18, Blog p19)
 | 
					        public static Blog AdaptTo(this BlogSDto p18, Blog p19)
 | 
				
			||||||
| 
						 | 
					@ -171,6 +172,7 @@ namespace NetinaShop.Domain.Mappers
 | 
				
			||||||
            result.Category = funcMain5(new Never(), result.Category, p18);
 | 
					            result.Category = funcMain5(new Never(), result.Category, p18);
 | 
				
			||||||
            result.Id = p18.Id;
 | 
					            result.Id = p18.Id;
 | 
				
			||||||
            result.CreatedAt = p18.CreatedAt;
 | 
					            result.CreatedAt = p18.CreatedAt;
 | 
				
			||||||
 | 
					            result.ModifiedAt = p18.ModifiedAt;
 | 
				
			||||||
            return result;
 | 
					            return result;
 | 
				
			||||||
            
 | 
					            
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
| 
						 | 
					@ -186,7 +188,8 @@ namespace NetinaShop.Domain.Mappers
 | 
				
			||||||
                IsSuggested = p22.IsSuggested,
 | 
					                IsSuggested = p22.IsSuggested,
 | 
				
			||||||
                CategoryId = p22.CategoryId,
 | 
					                CategoryId = p22.CategoryId,
 | 
				
			||||||
                CategoryName = p22.Category == null ? null : p22.Category.Name,
 | 
					                CategoryName = p22.Category == null ? null : p22.Category.Name,
 | 
				
			||||||
                HeaderFileName = p22.Files.Count > 0 && p22.Files.Any<BlogStorageFile>(funcMain6) ? p22.Files.FirstOrDefault<BlogStorageFile>(funcMain7).FileName : string.Empty,
 | 
					                MainImage = p22.Files.Count > 0 && p22.Files.Any<BlogStorageFile>(funcMain6) ? p22.Files.FirstOrDefault<BlogStorageFile>(funcMain7).FileName : string.Empty,
 | 
				
			||||||
 | 
					                ModifiedAt = p22.ModifiedAt,
 | 
				
			||||||
                Id = p22.Id,
 | 
					                Id = p22.Id,
 | 
				
			||||||
                CreatedAt = p22.CreatedAt
 | 
					                CreatedAt = p22.CreatedAt
 | 
				
			||||||
            };
 | 
					            };
 | 
				
			||||||
| 
						 | 
					@ -207,7 +210,8 @@ namespace NetinaShop.Domain.Mappers
 | 
				
			||||||
            result.IsSuggested = p23.IsSuggested;
 | 
					            result.IsSuggested = p23.IsSuggested;
 | 
				
			||||||
            result.CategoryId = p23.CategoryId;
 | 
					            result.CategoryId = p23.CategoryId;
 | 
				
			||||||
            result.CategoryName = p23.Category == null ? null : p23.Category.Name;
 | 
					            result.CategoryName = p23.Category == null ? null : p23.Category.Name;
 | 
				
			||||||
            result.HeaderFileName = p23.Files.Count > 0 && p23.Files.Any<BlogStorageFile>(funcMain6) ? p23.Files.FirstOrDefault<BlogStorageFile>(funcMain7).FileName : string.Empty;
 | 
					            result.MainImage = p23.Files.Count > 0 && p23.Files.Any<BlogStorageFile>(funcMain6) ? p23.Files.FirstOrDefault<BlogStorageFile>(funcMain7).FileName : string.Empty;
 | 
				
			||||||
 | 
					            result.ModifiedAt = p23.ModifiedAt;
 | 
				
			||||||
            result.Id = p23.Id;
 | 
					            result.Id = p23.Id;
 | 
				
			||||||
            result.CreatedAt = p23.CreatedAt;
 | 
					            result.CreatedAt = p23.CreatedAt;
 | 
				
			||||||
            return result;
 | 
					            return result;
 | 
				
			||||||
| 
						 | 
					@ -223,7 +227,8 @@ namespace NetinaShop.Domain.Mappers
 | 
				
			||||||
            IsSuggested = p25.IsSuggested,
 | 
					            IsSuggested = p25.IsSuggested,
 | 
				
			||||||
            CategoryId = p25.CategoryId,
 | 
					            CategoryId = p25.CategoryId,
 | 
				
			||||||
            CategoryName = p25.Category.Name,
 | 
					            CategoryName = p25.Category.Name,
 | 
				
			||||||
            HeaderFileName = p25.Files.Count > 0 && p25.Files.Any<BlogStorageFile>(f => f.IsHeader) ? p25.Files.FirstOrDefault<BlogStorageFile>(f => f.IsHeader).FileName : string.Empty,
 | 
					            MainImage = p25.Files.Count > 0 && p25.Files.Any<BlogStorageFile>(f => f.IsPrimary) ? p25.Files.FirstOrDefault<BlogStorageFile>(f => f.IsPrimary).FileName : string.Empty,
 | 
				
			||||||
 | 
					            ModifiedAt = p25.ModifiedAt,
 | 
				
			||||||
            Id = p25.Id,
 | 
					            Id = p25.Id,
 | 
				
			||||||
            CreatedAt = p25.CreatedAt
 | 
					            CreatedAt = p25.CreatedAt
 | 
				
			||||||
        };
 | 
					        };
 | 
				
			||||||
| 
						 | 
					@ -362,12 +367,12 @@ namespace NetinaShop.Domain.Mappers
 | 
				
			||||||
        
 | 
					        
 | 
				
			||||||
        private static bool funcMain6(BlogStorageFile f)
 | 
					        private static bool funcMain6(BlogStorageFile f)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            return f.IsHeader;
 | 
					            return f.IsPrimary;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        
 | 
					        
 | 
				
			||||||
        private static bool funcMain7(BlogStorageFile f)
 | 
					        private static bool funcMain7(BlogStorageFile f)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            return f.IsHeader;
 | 
					            return f.IsPrimary;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -157,7 +157,6 @@ namespace NetinaShop.Domain.Mappers
 | 
				
			||||||
                Description = p20.Description,
 | 
					                Description = p20.Description,
 | 
				
			||||||
                HasSpecialPage = p20.HasSpecialPage,
 | 
					                HasSpecialPage = p20.HasSpecialPage,
 | 
				
			||||||
                PageUrl = p20.PageUrl,
 | 
					                PageUrl = p20.PageUrl,
 | 
				
			||||||
                HeaderFileName = p20.Files.Count > 0 && p20.Files.Any<BrandStorageFile>(funcMain5) ? p20.Files.FirstOrDefault<BrandStorageFile>(funcMain6).FileName : string.Empty,
 | 
					 | 
				
			||||||
                Id = p20.Id,
 | 
					                Id = p20.Id,
 | 
				
			||||||
                CreatedAt = p20.CreatedAt
 | 
					                CreatedAt = p20.CreatedAt
 | 
				
			||||||
            };
 | 
					            };
 | 
				
			||||||
| 
						 | 
					@ -175,7 +174,6 @@ namespace NetinaShop.Domain.Mappers
 | 
				
			||||||
            result.Description = p21.Description;
 | 
					            result.Description = p21.Description;
 | 
				
			||||||
            result.HasSpecialPage = p21.HasSpecialPage;
 | 
					            result.HasSpecialPage = p21.HasSpecialPage;
 | 
				
			||||||
            result.PageUrl = p21.PageUrl;
 | 
					            result.PageUrl = p21.PageUrl;
 | 
				
			||||||
            result.HeaderFileName = p21.Files.Count > 0 && p21.Files.Any<BrandStorageFile>(funcMain5) ? p21.Files.FirstOrDefault<BrandStorageFile>(funcMain6).FileName : string.Empty;
 | 
					 | 
				
			||||||
            result.Id = p21.Id;
 | 
					            result.Id = p21.Id;
 | 
				
			||||||
            result.CreatedAt = p21.CreatedAt;
 | 
					            result.CreatedAt = p21.CreatedAt;
 | 
				
			||||||
            return result;
 | 
					            return result;
 | 
				
			||||||
| 
						 | 
					@ -188,7 +186,6 @@ namespace NetinaShop.Domain.Mappers
 | 
				
			||||||
            Description = p23.Description,
 | 
					            Description = p23.Description,
 | 
				
			||||||
            HasSpecialPage = p23.HasSpecialPage,
 | 
					            HasSpecialPage = p23.HasSpecialPage,
 | 
				
			||||||
            PageUrl = p23.PageUrl,
 | 
					            PageUrl = p23.PageUrl,
 | 
				
			||||||
            HeaderFileName = p23.Files.Count > 0 && p23.Files.Any<BrandStorageFile>(f => f.IsHeader) ? p23.Files.FirstOrDefault<BrandStorageFile>(f => f.IsHeader).FileName : string.Empty,
 | 
					 | 
				
			||||||
            Id = p23.Id,
 | 
					            Id = p23.Id,
 | 
				
			||||||
            CreatedAt = p23.CreatedAt
 | 
					            CreatedAt = p23.CreatedAt
 | 
				
			||||||
        };
 | 
					        };
 | 
				
			||||||
| 
						 | 
					@ -314,15 +311,5 @@ namespace NetinaShop.Domain.Mappers
 | 
				
			||||||
            return result;
 | 
					            return result;
 | 
				
			||||||
            
 | 
					            
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        
 | 
					 | 
				
			||||||
        private static bool funcMain5(BrandStorageFile f)
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
            return f.IsHeader;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        
 | 
					 | 
				
			||||||
        private static bool funcMain6(BrandStorageFile f)
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
            return f.IsHeader;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -274,7 +274,8 @@ namespace NetinaShop.Domain.Mappers
 | 
				
			||||||
                    Id = p37.CategoryId
 | 
					                    Id = p37.CategoryId
 | 
				
			||||||
                },
 | 
					                },
 | 
				
			||||||
                Id = p37.Id,
 | 
					                Id = p37.Id,
 | 
				
			||||||
                CreatedAt = p37.CreatedAt
 | 
					                CreatedAt = p37.CreatedAt,
 | 
				
			||||||
 | 
					                ModifiedAt = p37.ModifiedAt
 | 
				
			||||||
            };
 | 
					            };
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        public static Product AdaptTo(this ProductSDto p38, Product p39)
 | 
					        public static Product AdaptTo(this ProductSDto p38, Product p39)
 | 
				
			||||||
| 
						 | 
					@ -306,6 +307,7 @@ namespace NetinaShop.Domain.Mappers
 | 
				
			||||||
            result.Category = funcMain16(new Never(), result.Category, p38);
 | 
					            result.Category = funcMain16(new Never(), result.Category, p38);
 | 
				
			||||||
            result.Id = p38.Id;
 | 
					            result.Id = p38.Id;
 | 
				
			||||||
            result.CreatedAt = p38.CreatedAt;
 | 
					            result.CreatedAt = p38.CreatedAt;
 | 
				
			||||||
 | 
					            result.ModifiedAt = p38.ModifiedAt;
 | 
				
			||||||
            return result;
 | 
					            return result;
 | 
				
			||||||
            
 | 
					            
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
| 
						 | 
					@ -333,6 +335,7 @@ namespace NetinaShop.Domain.Mappers
 | 
				
			||||||
                BrandId = p44.BrandId,
 | 
					                BrandId = p44.BrandId,
 | 
				
			||||||
                BrandName = p44.Brand == null ? null : p44.Brand.PersianName,
 | 
					                BrandName = p44.Brand == null ? null : p44.Brand.PersianName,
 | 
				
			||||||
                CategoryName = p44.Category == null ? null : p44.Category.Name,
 | 
					                CategoryName = p44.Category == null ? null : p44.Category.Name,
 | 
				
			||||||
 | 
					                ModifiedAt = p44.ModifiedAt,
 | 
				
			||||||
                Id = p44.Id,
 | 
					                Id = p44.Id,
 | 
				
			||||||
                CreatedAt = p44.CreatedAt
 | 
					                CreatedAt = p44.CreatedAt
 | 
				
			||||||
            };
 | 
					            };
 | 
				
			||||||
| 
						 | 
					@ -365,6 +368,7 @@ namespace NetinaShop.Domain.Mappers
 | 
				
			||||||
            result.BrandId = p45.BrandId;
 | 
					            result.BrandId = p45.BrandId;
 | 
				
			||||||
            result.BrandName = p45.Brand == null ? null : p45.Brand.PersianName;
 | 
					            result.BrandName = p45.Brand == null ? null : p45.Brand.PersianName;
 | 
				
			||||||
            result.CategoryName = p45.Category == null ? null : p45.Category.Name;
 | 
					            result.CategoryName = p45.Category == null ? null : p45.Category.Name;
 | 
				
			||||||
 | 
					            result.ModifiedAt = p45.ModifiedAt;
 | 
				
			||||||
            result.Id = p45.Id;
 | 
					            result.Id = p45.Id;
 | 
				
			||||||
            result.CreatedAt = p45.CreatedAt;
 | 
					            result.CreatedAt = p45.CreatedAt;
 | 
				
			||||||
            return result;
 | 
					            return result;
 | 
				
			||||||
| 
						 | 
					@ -392,6 +396,7 @@ namespace NetinaShop.Domain.Mappers
 | 
				
			||||||
            BrandId = p47.BrandId,
 | 
					            BrandId = p47.BrandId,
 | 
				
			||||||
            BrandName = p47.Brand == null ? null : p47.Brand.PersianName,
 | 
					            BrandName = p47.Brand == null ? null : p47.Brand.PersianName,
 | 
				
			||||||
            CategoryName = p47.Category == null ? null : p47.Category.Name,
 | 
					            CategoryName = p47.Category == null ? null : p47.Category.Name,
 | 
				
			||||||
 | 
					            ModifiedAt = p47.ModifiedAt,
 | 
				
			||||||
            Id = p47.Id,
 | 
					            Id = p47.Id,
 | 
				
			||||||
            CreatedAt = p47.CreatedAt
 | 
					            CreatedAt = p47.CreatedAt
 | 
				
			||||||
        };
 | 
					        };
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -7,11 +7,11 @@ public class MapsterRegister : IRegister
 | 
				
			||||||
    public void Register(TypeAdapterConfig config)
 | 
					    public void Register(TypeAdapterConfig config)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        config.NewConfig<Blog, BlogSDto>()
 | 
					        config.NewConfig<Blog, BlogSDto>()
 | 
				
			||||||
            .Map("HeaderFileName", o => o.Files.Count > 0 && o.Files.Any(f=>f.IsHeader) ? o.Files.FirstOrDefault(f=>f.IsHeader)!.FileName : string.Empty)
 | 
					            .Map("MainImage", o => o.Files.Count > 0 && o.Files.Any(f=>f.IsPrimary) ? o.Files.FirstOrDefault(f=>f.IsPrimary)!.FileName : string.Empty)
 | 
				
			||||||
            .TwoWays();
 | 
					            .TwoWays();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        config.NewConfig<Brand, BrandSDto>()
 | 
					        config.NewConfig<Brand, BrandSDto>()
 | 
				
			||||||
            .Map("HeaderFileName", o => o.Files.Count > 0 && o.Files.Any(f => f.IsHeader) ? o.Files.FirstOrDefault(f => f.IsHeader)!.FileName : string.Empty)
 | 
					            .Map("MainImage", o => o.Files.Count > 0 && o.Files.Any(f => f.IsHeader) ? o.Files.FirstOrDefault(f => f.IsHeader)!.FileName : string.Empty)
 | 
				
			||||||
            .TwoWays();
 | 
					            .TwoWays();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        config.NewConfig<OrderDelivery, OrderDeliverySDto>()
 | 
					        config.NewConfig<OrderDelivery, OrderDeliverySDto>()
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -4,11 +4,13 @@ public class SiteSettings
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    public JwtSettings JwtSettings { get; set; } = new JwtSettings();
 | 
					    public JwtSettings JwtSettings { get; set; } = new JwtSettings();
 | 
				
			||||||
    public string BaseUrl { get; set; } = string.Empty;
 | 
					    public string BaseUrl { get; set; } = string.Empty;
 | 
				
			||||||
 | 
					    public string WebSiteUrl { get; set; } = string.Empty;  
 | 
				
			||||||
    public string AdminPanelBaseUrl { get; set; } = string.Empty;
 | 
					    public string AdminPanelBaseUrl { get; set; } = string.Empty;
 | 
				
			||||||
    public string StorageBaseUrl { get; set; } = string.Empty;
 | 
					    public string StorageBaseUrl { get; set; } = string.Empty;
 | 
				
			||||||
    public RedisSettings MasterRedisConfiguration { get; set; } = new RedisSettings();
 | 
					    public RedisSettings MasterRedisConfiguration { get; set; } = new RedisSettings();
 | 
				
			||||||
    public UserSetting UserSetting { get; set; } = new UserSetting();
 | 
					    public UserSetting UserSetting { get; set; } = new UserSetting();
 | 
				
			||||||
    public string KaveNegarApiKey { get; set; } = string.Empty;
 | 
					    public string KaveNegarApiKey { get; set; } = string.Empty;
 | 
				
			||||||
 | 
					    public StorageSettings StorageSetting { get; set; } = new StorageSettings();
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
public class RedisSettings
 | 
					public class RedisSettings
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
| 
						 | 
					@ -18,6 +20,12 @@ public class RedisSettings
 | 
				
			||||||
    public int Port { get; set; }
 | 
					    public int Port { get; set; }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					public class StorageSettings
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    public string AccessKey { get; set; } = string.Empty;
 | 
				
			||||||
 | 
					    public string SecretKey { get; set; } = string.Empty;
 | 
				
			||||||
 | 
					    public string BucketKey { get; set; } = string.Empty;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
public class JwtSettings
 | 
					public class JwtSettings
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -6,10 +6,20 @@ namespace NetinaShop.Infrastructure.Services;
 | 
				
			||||||
public class StorageService : IStorageService
 | 
					public class StorageService : IStorageService
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    private IAmazonS3? _s3Client;
 | 
					    private IAmazonS3? _s3Client;
 | 
				
			||||||
    private string _bucketName = "vesmeh-content";
 | 
					    private readonly string _bucketName;
 | 
				
			||||||
 | 
					    private readonly string _accessKey;
 | 
				
			||||||
 | 
					    private readonly string _secretKey;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public StorageService(IOptionsSnapshot<SiteSettings> snapshot)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        _accessKey = snapshot.Value.StorageSetting.AccessKey;
 | 
				
			||||||
 | 
					        _bucketName = snapshot.Value.StorageSetting.BucketKey;
 | 
				
			||||||
 | 
					        _secretKey = snapshot.Value.StorageSetting.SecretKey;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    private IAmazonS3 GetClientAsync()
 | 
					    private IAmazonS3 GetClientAsync()
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        var awsCredentials = new Amazon.Runtime.BasicAWSCredentials("979313b7-30fb-40ff-94d8-d0390d3fa876", "d37a1cc6acfea3a6f92c538ef0f6601f1edcdc9143942b6470e5d1032aa6bfe2");
 | 
					        var awsCredentials = new Amazon.Runtime.BasicAWSCredentials(secretKey: _secretKey, accessKey: _accessKey);
 | 
				
			||||||
        var config = new AmazonS3Config { ServiceURL = "https://s3.ir-thr-at1.arvanstorage.ir" };
 | 
					        var config = new AmazonS3Config { ServiceURL = "https://s3.ir-thr-at1.arvanstorage.ir" };
 | 
				
			||||||
        _s3Client = new AmazonS3Client(awsCredentials, config);
 | 
					        _s3Client = new AmazonS3Client(awsCredentials, config);
 | 
				
			||||||
        return _s3Client;
 | 
					        return _s3Client;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in New Issue