Api/Netina.Core/BaseServices/SiteMapService.cs

539 lines
22 KiB
C#

using System.IO.Compression;
using System.Xml;
using Netina.Core.Models;
using Netina.Domain.Entities.Blogs;
using Netina.Domain.Entities.Brands;
using Netina.Domain.Entities.ProductCategories;
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 productCategories = await _repositoryWrapper.SetRepository<ProductCategory>()
.TableNoTracking
.ToListAsync();
var blogCategories= await _repositoryWrapper.SetRepository<BlogCategory>()
.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 blogCategory in blogCategories)
{
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", $"{blogCategory.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);
}
foreach (var productCategory in productCategories)
{
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", $"{productCategory.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();
await CreateBrandsSiteMapsAsync();
await CreateBlogCategoriesSiteMapsAsync();
}
private async Task CreateBrandsSiteMapsAsync()
{
var siteMapsUId = SiteMapUIds.Brands;
var brands = await _repositoryWrapper.SetRepository<Brand>()
.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 brand in brands)
{
var productUrl = $"{_siteSetting.WebSiteUrl}/brands/{brand.Id}/{brand.Slug}";
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 = brand.ModifiedAt == DateTime.MinValue ? brand.CreatedAt.ToString("yyyy-MM-dd") : brand.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 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}/{productCategory.Slug}";
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 = 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}/{product.Slug}";
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 blogs = await _repositoryWrapper.SetRepository<Blog>()
.TableNoTracking
.Select(BlogMapper.ProjectToSDto)
.ToListAsync();
var groupedProducts = blogs.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");
//root.SetAttribute("xmlns:news", "http://www.google.com/schemas/sitemap-news/0.9");
doc.AppendChild(root);
foreach (var blog in group)
{
XmlElement urlElement = doc.CreateElement("url", doc.DocumentElement?.NamespaceURI);
root.AppendChild(urlElement);
XmlElement loc = doc.CreateElement("loc", doc.DocumentElement?.NamespaceURI);
loc.InnerText = Path.Combine($"{_siteSetting.WebSiteUrl}/blogs/{blog.Id}/{blog.Slug}");
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
if (blog.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}/{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 = $"{group.Key.ToString().ToUpper()}.gz",
FileUploadType = FileUploadType.SiteMap,
});
}
}
}
private async Task CreateBlogCategoriesSiteMapsAsync()
{
var siteMapsUId = SiteMapUIds.BlogCategories;
var blogCategories = await _repositoryWrapper.SetRepository<BlogCategory>()
.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");
root.SetAttribute("xmlns:news", "http://www.google.com/schemas/sitemap-news/0.9");
doc.AppendChild(root);
foreach (var blogCategory in blogCategories)
{
XmlElement urlElement = doc.CreateElement("url", doc.DocumentElement?.NamespaceURI);
root.AppendChild(urlElement);
XmlElement loc = doc.CreateElement("loc", doc.DocumentElement?.NamespaceURI);
loc.InnerText = Path.Combine($"{_siteSetting.WebSiteUrl}/blogs/{blogCategory.Id}/{blogCategory.Slug}");
urlElement.AppendChild(loc);
XmlElement lastmod = doc.CreateElement("lastmod", doc.DocumentElement?.NamespaceURI);
lastmod.InnerText = blogCategory.ModifiedAt == DateTime.MinValue ? blogCategory.CreatedAt.ToString("yyyy-MM-dd") : blogCategory.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,
});
}
}
}