feat : complete create sitemap
							parent
							
								
									3118de0509
								
							
						
					
					
						commit
						3cba0d598a
					
				| 
						 | 
				
			
			@ -18,8 +18,9 @@
 | 
			
		|||
  },
 | 
			
		||||
  "SiteSettings": {
 | 
			
		||||
    "BaseUrl": "https://api.vesmeh.com",
 | 
			
		||||
    "WebSiteUrl": "https://vesmeh.com",
 | 
			
		||||
    "AdminPanelBaseUrl": "https://admin.vesmeh.com",
 | 
			
		||||
    "StorageBaseUrl": "https://storage.vesmeh.ir",
 | 
			
		||||
    "StorageBaseUrl": "https://storage.vesmeh.com",
 | 
			
		||||
    "KaveNegarApiKey": "3735494B4143727A794346457461576A2B4B6668414973424E333561505A694B",
 | 
			
		||||
    "UserSetting": {
 | 
			
		||||
      "Username": "09214802813",
 | 
			
		||||
| 
						 | 
				
			
			@ -30,6 +31,11 @@
 | 
			
		|||
      "FirstName": "همه کاره",
 | 
			
		||||
      "LastName": "سیستم"
 | 
			
		||||
    },
 | 
			
		||||
    "StorageSetting": {
 | 
			
		||||
      "AccessKey": "d37a1cc6acfea3a6f92c538ef0f6601f1edcdc9143942b6470e5d1032aa6bfe2",
 | 
			
		||||
      "SecretKey": "979313b7-30fb-40ff-94d8-d0390d3fa876",
 | 
			
		||||
      "BucketKey": "vesmeh-content"
 | 
			
		||||
    },
 | 
			
		||||
    "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",
 | 
			
		||||
      "Issuer": "Brizco",
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -18,8 +18,9 @@
 | 
			
		|||
  },
 | 
			
		||||
  "SiteSettings": {
 | 
			
		||||
    "BaseUrl": "http://localhost:32770",
 | 
			
		||||
    "WebSiteUrl": "https://vesmeh.com",
 | 
			
		||||
    "AdminPanelBaseUrl": "https://admin.vesmeh.com",
 | 
			
		||||
    "StorageBaseUrl": "https://storage.vesmeh.ir",
 | 
			
		||||
    "StorageBaseUrl": "https://storage.vesmeh.com",
 | 
			
		||||
    "KaveNegarApiKey": "3735494B4143727A794346457461576A2B4B6668414973424E333561505A694B",
 | 
			
		||||
    "UserSetting": {
 | 
			
		||||
      "Username": "netinashop",
 | 
			
		||||
| 
						 | 
				
			
			@ -30,6 +31,11 @@
 | 
			
		|||
      "FirstName": "همه کاره",
 | 
			
		||||
      "LastName": "سیستم"
 | 
			
		||||
    },
 | 
			
		||||
    "StorageSetting": {
 | 
			
		||||
      "AccessKey": "d37a1cc6acfea3a6f92c538ef0f6601f1edcdc9143942b6470e5d1032aa6bfe2",
 | 
			
		||||
      "SecretKey": "979313b7-30fb-40ff-94d8-d0390d3fa876",
 | 
			
		||||
      "BucketKey": "vesmeh-content"
 | 
			
		||||
    },
 | 
			
		||||
    "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",
 | 
			
		||||
      "Issuer": "Brizco",
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -15,7 +15,7 @@ public class HealthController : ICarterModule
 | 
			
		|||
 | 
			
		||||
    public async Task<IResult> GetHealth([FromServices]ISiteMapService siteMapService)
 | 
			
		||||
    {
 | 
			
		||||
        await siteMapService.CreateSiteMapAsync();
 | 
			
		||||
        //await siteMapService.CreateSiteMapAsync();
 | 
			
		||||
        var version = typeof(Program)?.Assembly.GetName()?.Version?.ToString();
 | 
			
		||||
        var check = new HealthCheck
 | 
			
		||||
        {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,273 +1,6 @@
 | 
			
		|||
using System.IO;
 | 
			
		||||
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;
 | 
			
		||||
namespace NetinaShop.Core.BaseServices.Abstracts;
 | 
			
		||||
 | 
			
		||||
public interface ISiteMapService : IScopedDependency
 | 
			
		||||
{
 | 
			
		||||
    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 Blogs = "4C2F0C2A7A3E41268702D12FDDDB837F";
 | 
			
		||||
    public const string Products = "E95AB3C0C4DD44FA82D77D55BD91696F";
 | 
			
		||||
 | 
			
		||||
    public static List<string> AllSiteMapsUIds => new List<string>
 | 
			
		||||
    {
 | 
			
		||||
        Categories,
 | 
			
		||||
        Blogs, Products
 | 
			
		||||
        Blogs
 | 
			
		||||
    };
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -10,5 +10,6 @@ public class BlogSDto : BaseDto<BlogSDto , Blog>
 | 
			
		|||
    public bool IsSuggested { get; set; }
 | 
			
		||||
    public Guid CategoryId { get; set; }
 | 
			
		||||
    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 string BrandName { 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.Id,
 | 
			
		||||
                CreatedAt = p8.CreatedAt
 | 
			
		||||
                CreatedAt = p8.CreatedAt,
 | 
			
		||||
                ModifiedAt = p8.ModifiedAt
 | 
			
		||||
            }).ToList<Blog>(),
 | 
			
		||||
            Id = p7.Id,
 | 
			
		||||
            CreatedAt = p7.CreatedAt
 | 
			
		||||
| 
						 | 
				
			
			@ -102,7 +103,8 @@ namespace NetinaShop.Domain.Mappers
 | 
			
		|||
                IsSuggested = p16.IsSuggested,
 | 
			
		||||
                CategoryId = p16.CategoryId,
 | 
			
		||||
                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,
 | 
			
		||||
                CreatedAt = p16.CreatedAt
 | 
			
		||||
            }).ToList<BlogSDto>(),
 | 
			
		||||
| 
						 | 
				
			
			@ -196,7 +198,8 @@ namespace NetinaShop.Domain.Mappers
 | 
			
		|||
                        Id = item.CategoryId
 | 
			
		||||
                    },
 | 
			
		||||
                    Id = item.Id,
 | 
			
		||||
                    CreatedAt = item.CreatedAt
 | 
			
		||||
                    CreatedAt = item.CreatedAt,
 | 
			
		||||
                    ModifiedAt = item.ModifiedAt
 | 
			
		||||
                });
 | 
			
		||||
                i++;
 | 
			
		||||
            }
 | 
			
		||||
| 
						 | 
				
			
			@ -233,7 +236,8 @@ namespace NetinaShop.Domain.Mappers
 | 
			
		|||
                        Id = item.CategoryId
 | 
			
		||||
                    },
 | 
			
		||||
                    Id = item.Id,
 | 
			
		||||
                    CreatedAt = item.CreatedAt
 | 
			
		||||
                    CreatedAt = item.CreatedAt,
 | 
			
		||||
                    ModifiedAt = item.ModifiedAt
 | 
			
		||||
                });
 | 
			
		||||
                i++;
 | 
			
		||||
            }
 | 
			
		||||
| 
						 | 
				
			
			@ -265,7 +269,8 @@ namespace NetinaShop.Domain.Mappers
 | 
			
		|||
                    IsSuggested = item.IsSuggested,
 | 
			
		||||
                    CategoryId = item.CategoryId,
 | 
			
		||||
                    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,
 | 
			
		||||
                    CreatedAt = item.CreatedAt
 | 
			
		||||
                });
 | 
			
		||||
| 
						 | 
				
			
			@ -299,7 +304,8 @@ namespace NetinaShop.Domain.Mappers
 | 
			
		|||
                    IsSuggested = item.IsSuggested,
 | 
			
		||||
                    CategoryId = item.CategoryId,
 | 
			
		||||
                    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,
 | 
			
		||||
                    CreatedAt = item.CreatedAt
 | 
			
		||||
                });
 | 
			
		||||
| 
						 | 
				
			
			@ -311,12 +317,12 @@ namespace NetinaShop.Domain.Mappers
 | 
			
		|||
        
 | 
			
		||||
        private static bool funcMain4(BlogStorageFile f)
 | 
			
		||||
        {
 | 
			
		||||
            return f.IsHeader;
 | 
			
		||||
            return f.IsPrimary;
 | 
			
		||||
        }
 | 
			
		||||
        
 | 
			
		||||
        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.Id,
 | 
			
		||||
                CreatedAt = p17.CreatedAt
 | 
			
		||||
                CreatedAt = p17.CreatedAt,
 | 
			
		||||
                ModifiedAt = p17.ModifiedAt
 | 
			
		||||
            };
 | 
			
		||||
        }
 | 
			
		||||
        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.Id = p18.Id;
 | 
			
		||||
            result.CreatedAt = p18.CreatedAt;
 | 
			
		||||
            result.ModifiedAt = p18.ModifiedAt;
 | 
			
		||||
            return result;
 | 
			
		||||
            
 | 
			
		||||
        }
 | 
			
		||||
| 
						 | 
				
			
			@ -186,7 +188,8 @@ namespace NetinaShop.Domain.Mappers
 | 
			
		|||
                IsSuggested = p22.IsSuggested,
 | 
			
		||||
                CategoryId = p22.CategoryId,
 | 
			
		||||
                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,
 | 
			
		||||
                CreatedAt = p22.CreatedAt
 | 
			
		||||
            };
 | 
			
		||||
| 
						 | 
				
			
			@ -207,7 +210,8 @@ namespace NetinaShop.Domain.Mappers
 | 
			
		|||
            result.IsSuggested = p23.IsSuggested;
 | 
			
		||||
            result.CategoryId = p23.CategoryId;
 | 
			
		||||
            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.CreatedAt = p23.CreatedAt;
 | 
			
		||||
            return result;
 | 
			
		||||
| 
						 | 
				
			
			@ -223,7 +227,8 @@ namespace NetinaShop.Domain.Mappers
 | 
			
		|||
            IsSuggested = p25.IsSuggested,
 | 
			
		||||
            CategoryId = p25.CategoryId,
 | 
			
		||||
            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,
 | 
			
		||||
            CreatedAt = p25.CreatedAt
 | 
			
		||||
        };
 | 
			
		||||
| 
						 | 
				
			
			@ -362,12 +367,12 @@ namespace NetinaShop.Domain.Mappers
 | 
			
		|||
        
 | 
			
		||||
        private static bool funcMain6(BlogStorageFile f)
 | 
			
		||||
        {
 | 
			
		||||
            return f.IsHeader;
 | 
			
		||||
            return f.IsPrimary;
 | 
			
		||||
        }
 | 
			
		||||
        
 | 
			
		||||
        private static bool funcMain7(BlogStorageFile f)
 | 
			
		||||
        {
 | 
			
		||||
            return f.IsHeader;
 | 
			
		||||
            return f.IsPrimary;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -157,7 +157,6 @@ namespace NetinaShop.Domain.Mappers
 | 
			
		|||
                Description = p20.Description,
 | 
			
		||||
                HasSpecialPage = p20.HasSpecialPage,
 | 
			
		||||
                PageUrl = p20.PageUrl,
 | 
			
		||||
                HeaderFileName = p20.Files.Count > 0 && p20.Files.Any<BrandStorageFile>(funcMain5) ? p20.Files.FirstOrDefault<BrandStorageFile>(funcMain6).FileName : string.Empty,
 | 
			
		||||
                Id = p20.Id,
 | 
			
		||||
                CreatedAt = p20.CreatedAt
 | 
			
		||||
            };
 | 
			
		||||
| 
						 | 
				
			
			@ -175,7 +174,6 @@ namespace NetinaShop.Domain.Mappers
 | 
			
		|||
            result.Description = p21.Description;
 | 
			
		||||
            result.HasSpecialPage = p21.HasSpecialPage;
 | 
			
		||||
            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.CreatedAt = p21.CreatedAt;
 | 
			
		||||
            return result;
 | 
			
		||||
| 
						 | 
				
			
			@ -188,7 +186,6 @@ namespace NetinaShop.Domain.Mappers
 | 
			
		|||
            Description = p23.Description,
 | 
			
		||||
            HasSpecialPage = p23.HasSpecialPage,
 | 
			
		||||
            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,
 | 
			
		||||
            CreatedAt = p23.CreatedAt
 | 
			
		||||
        };
 | 
			
		||||
| 
						 | 
				
			
			@ -314,15 +311,5 @@ namespace NetinaShop.Domain.Mappers
 | 
			
		|||
            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.Id,
 | 
			
		||||
                CreatedAt = p37.CreatedAt
 | 
			
		||||
                CreatedAt = p37.CreatedAt,
 | 
			
		||||
                ModifiedAt = p37.ModifiedAt
 | 
			
		||||
            };
 | 
			
		||||
        }
 | 
			
		||||
        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.Id = p38.Id;
 | 
			
		||||
            result.CreatedAt = p38.CreatedAt;
 | 
			
		||||
            result.ModifiedAt = p38.ModifiedAt;
 | 
			
		||||
            return result;
 | 
			
		||||
            
 | 
			
		||||
        }
 | 
			
		||||
| 
						 | 
				
			
			@ -333,6 +335,7 @@ namespace NetinaShop.Domain.Mappers
 | 
			
		|||
                BrandId = p44.BrandId,
 | 
			
		||||
                BrandName = p44.Brand == null ? null : p44.Brand.PersianName,
 | 
			
		||||
                CategoryName = p44.Category == null ? null : p44.Category.Name,
 | 
			
		||||
                ModifiedAt = p44.ModifiedAt,
 | 
			
		||||
                Id = p44.Id,
 | 
			
		||||
                CreatedAt = p44.CreatedAt
 | 
			
		||||
            };
 | 
			
		||||
| 
						 | 
				
			
			@ -365,6 +368,7 @@ namespace NetinaShop.Domain.Mappers
 | 
			
		|||
            result.BrandId = p45.BrandId;
 | 
			
		||||
            result.BrandName = p45.Brand == null ? null : p45.Brand.PersianName;
 | 
			
		||||
            result.CategoryName = p45.Category == null ? null : p45.Category.Name;
 | 
			
		||||
            result.ModifiedAt = p45.ModifiedAt;
 | 
			
		||||
            result.Id = p45.Id;
 | 
			
		||||
            result.CreatedAt = p45.CreatedAt;
 | 
			
		||||
            return result;
 | 
			
		||||
| 
						 | 
				
			
			@ -392,6 +396,7 @@ namespace NetinaShop.Domain.Mappers
 | 
			
		|||
            BrandId = p47.BrandId,
 | 
			
		||||
            BrandName = p47.Brand == null ? null : p47.Brand.PersianName,
 | 
			
		||||
            CategoryName = p47.Category == null ? null : p47.Category.Name,
 | 
			
		||||
            ModifiedAt = p47.ModifiedAt,
 | 
			
		||||
            Id = p47.Id,
 | 
			
		||||
            CreatedAt = p47.CreatedAt
 | 
			
		||||
        };
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -7,11 +7,11 @@ public class MapsterRegister : IRegister
 | 
			
		|||
    public void Register(TypeAdapterConfig config)
 | 
			
		||||
    {
 | 
			
		||||
        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();
 | 
			
		||||
 | 
			
		||||
        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();
 | 
			
		||||
 | 
			
		||||
        config.NewConfig<OrderDelivery, OrderDeliverySDto>()
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -4,11 +4,13 @@ public class SiteSettings
 | 
			
		|||
{
 | 
			
		||||
    public JwtSettings JwtSettings { get; set; } = new JwtSettings();
 | 
			
		||||
    public string BaseUrl { get; set; } = string.Empty;
 | 
			
		||||
    public string WebSiteUrl { get; set; } = string.Empty;  
 | 
			
		||||
    public string AdminPanelBaseUrl { get; set; } = string.Empty;
 | 
			
		||||
    public string StorageBaseUrl { get; set; } = string.Empty;
 | 
			
		||||
    public RedisSettings MasterRedisConfiguration { get; set; } = new RedisSettings();
 | 
			
		||||
    public UserSetting UserSetting { get; set; } = new UserSetting();
 | 
			
		||||
    public string KaveNegarApiKey { get; set; } = string.Empty;
 | 
			
		||||
    public StorageSettings StorageSetting { get; set; } = new StorageSettings();
 | 
			
		||||
}
 | 
			
		||||
public class RedisSettings
 | 
			
		||||
{
 | 
			
		||||
| 
						 | 
				
			
			@ -18,6 +20,12 @@ public class RedisSettings
 | 
			
		|||
    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
 | 
			
		||||
{
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -6,10 +6,20 @@ namespace NetinaShop.Infrastructure.Services;
 | 
			
		|||
public class StorageService : IStorageService
 | 
			
		||||
{
 | 
			
		||||
    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()
 | 
			
		||||
    {
 | 
			
		||||
        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" };
 | 
			
		||||
        _s3Client = new AmazonS3Client(awsCredentials, config);
 | 
			
		||||
        return _s3Client;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue