feat : complete create sitemap

release
Amir Hossein Khademi 2024-04-12 18:30:10 +03:30
parent 3118de0509
commit 3cba0d598a
15 changed files with 437 additions and 306 deletions

View File

@ -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",

View File

@ -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",

View File

@ -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
{

View File

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

View File

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

View File

@ -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
};
}

View File

@ -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; }
}

View File

@ -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; }
}

View File

@ -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;
}
}
}

View File

@ -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;
}
}
}

View File

@ -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;
}
}
}

View File

@ -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
};

View File

@ -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>()

View File

@ -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
{

View File

@ -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;