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,
|
|
});
|
|
}
|
|
|
|
}
|
|
} |