370 lines
		
	
	
		
			15 KiB
		
	
	
	
		
			C#
		
	
	
			
		
		
	
	
			370 lines
		
	
	
		
			15 KiB
		
	
	
	
		
			C#
		
	
	
| using System.IO.Compression;
 | |
| using System.Web;
 | |
| using System.Xml;
 | |
| using Netina.Common.Models.Api;
 | |
| using Netina.Core.Abstracts;
 | |
| using Netina.Core.BaseServices.Abstracts;
 | |
| using Netina.Core.Models;
 | |
| using Netina.Domain.Entities.Blogs;
 | |
| using Netina.Domain.Entities.ProductCategories;
 | |
| using Netina.Domain.Entities.Products;
 | |
| using Netina.Domain.Models.Settings;
 | |
| using Netina.Repository.Repositories.Base.Contracts;
 | |
| 
 | |
| namespace Netina.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,
 | |
|             });
 | |
|         }
 | |
| 
 | |
|     }
 | |
| } |