diff --git a/Library.Encyclopedia.API/Controllers/EncylopediaController.cs b/Library.Encyclopedia.API/Controllers/EncylopediaController.cs
index 8d264b4..70a47ba 100644
--- a/Library.Encyclopedia.API/Controllers/EncylopediaController.cs
+++ b/Library.Encyclopedia.API/Controllers/EncylopediaController.cs
@@ -6,6 +6,7 @@
using Library.Encyclopedia.Entity.Models.External;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
+using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Logging;
using System;
using System.Collections.Generic;
@@ -28,10 +29,10 @@ public class EncylopediaController : ControllerBase
///
///
///
- public EncylopediaController(ILogger logger, IApplicationDbContext dbContext)
+ public EncylopediaController(ILogger logger, IApplicationDbContext dbContext, IConfiguration configuration)
{
_logger = logger;
- this.mainDataAccess = new MainDataAccess(dbContext);
+ this.mainDataAccess = new MainDataAccess(dbContext, configuration);
}
///
@@ -39,18 +40,19 @@ public EncylopediaController(ILogger logger, IApplication
///
///
///
- ///
+ ///
///
///
[HttpGet]
public async Task Get(string query,
int offset = 0,
- int size = 10,
+ int limit = 10,
+ int previewSize = 50,
bool asc = true)
{
try
{
- var response = await mainDataAccess.GetAsync(query, offset, size, asc);
+ var response = await mainDataAccess.GetAsync(query, offset, limit, previewSize, asc);
if (response == null)
{
return StatusCode(204);
@@ -72,18 +74,18 @@ public async Task Get(string query,
///
///
///
- ///
+ ///
///
///
[HttpGet("category")]
public async Task GetByCategory(string category,
int offset = 0,
- int size = 10,
+ int limit = 10,
bool asc = true)
{
try
{
- var response = await mainDataAccess.GetByCategoryAsync(category, offset, size, asc);
+ var response = await mainDataAccess.GetByCategoryAsync(category, offset, limit, asc);
if (response == null)
{
@@ -106,18 +108,18 @@ public async Task GetByCategory(string category,
///
///
///
- ///
+ ///
///
///
[HttpGet("alphabet")]
public async Task GetByStartingAlphabet(char alphabet,
int offset = 0,
- int size = 10,
+ int limit = 10,
bool asc = true)
{
try
{
- var response = await mainDataAccess.GetByAlphabetAsync(alphabet, offset, size, asc);
+ var response = await mainDataAccess.GetByAlphabetAsync(alphabet, offset, limit, asc);
if (response == null)
{
diff --git a/Library.Encyclopedia.API/appsettings.json b/Library.Encyclopedia.API/appsettings.json
index 8d02394..7b695ce 100644
--- a/Library.Encyclopedia.API/appsettings.json
+++ b/Library.Encyclopedia.API/appsettings.json
@@ -6,6 +6,7 @@
"Microsoft.Hosting.Lifetime": "Information"
}
},
+ "App-Base-Url": "http://localhost:4200",
"AllowedHosts": "*",
"ConnectionStrings": {
"DefaultConnection": "Server=localhost;Database=Encyclopedia;User=root;Password=root"
diff --git a/Library.Encyclopedia.DataAccess/DataAccess/MainDataAccess.cs b/Library.Encyclopedia.DataAccess/DataAccess/MainDataAccess.cs
index 3374177..dba1a0b 100644
--- a/Library.Encyclopedia.DataAccess/DataAccess/MainDataAccess.cs
+++ b/Library.Encyclopedia.DataAccess/DataAccess/MainDataAccess.cs
@@ -3,6 +3,7 @@
using Library.Encyclopedia.Entity.Models;
using Library.Encyclopedia.Entity.Models.External;
using Microsoft.EntityFrameworkCore;
+using Microsoft.Extensions.Configuration;
using System;
using System.Collections.Generic;
using System.IO;
@@ -10,41 +11,48 @@
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
+using System.Web;
namespace Library.Encyclopedia.DataAccess.DataAccess
{
public class MainDataAccess : IMainDataAccess
{
private IApplicationDbContext _dbcontext;
- public MainDataAccess(IApplicationDbContext dbcontext)
+ private string APP_BASE_URL;
+
+ public MainDataAccess(IApplicationDbContext dbcontext, IConfiguration configuration)
{
+ APP_BASE_URL = configuration.GetSection("App-Base-Url").Value;
_dbcontext = dbcontext;
}
#region GET
- async Task IMainDataAccess.GetAsync(string query, int offset, int pagesize, bool ascending)
+ async Task IMainDataAccess.GetAsync(string query, int offset, int pagesize, int previewSize, bool ascending)
{
- query = query.ToLower();
- var temp = _dbcontext.Main.Where(s => s.Description.ToLower().Contains(query) || s.Title.ToLower().Contains(query))
+ // random cleanup
+ //await CleanUpData();
+
+ query = query != null ? query.ToLower() : string.Empty;
+ var temp = _dbcontext.Main.Where(s => s.RawDescription.ToLower().Contains(query) || s.Title.ToLower().Contains(query))
.Skip(offset)
- .Take(pagesize);
+ .Take(pagesize)
+ .Include(s => s.Links);
IEnumerable data;
if (ascending)
data = await temp.OrderBy(s => s.Title)
- .ThenBy(s => s.Description)
+ .ThenBy(s => s.RawDescription)
.ToListAsync();
else
data = await temp.OrderByDescending(s => s.Title)
- .ThenByDescending(s => s.Description)
+ .ThenByDescending(s => s.RawDescription)
.ToListAsync();
- var total = await _dbcontext.Main.CountAsync(s => s.Description.ToLower().Contains(query) || s.Title.ToLower().Contains(query));
+ var total = await _dbcontext.Main.CountAsync(s => s.RawDescription.ToLower().Contains(query) || s.Title.ToLower().Contains(query));
+
+ MainMinimizedExternalCollection result = new MainMinimizedExternalCollection(data.MinimizeWithQuery(query, previewSize), total);
- MainMinimizedExternalCollection result = new MainMinimizedExternalCollection(data.Minimize(), total);
- // random cleanup
- await CleanUpData();
return result;
}
@@ -60,10 +68,10 @@ async Task IMainDataAccess.GetByCategoryAsync(s
IEnumerable data;
if (ascending)
data = temp.OrderBy(s => s.Title)
- .ThenBy(s => s.Description);
+ .ThenBy(s => s.RawDescription);
else
data = temp.OrderByDescending(s => s.Title)
- .ThenByDescending(s => s.Description);
+ .ThenByDescending(s => s.RawDescription);
var total = rawData.Count(s => s.Category.ToLower().Split(',', StringSplitOptions.None).Contains(category));
@@ -82,11 +90,11 @@ async Task IMainDataAccess.GetByAlphabetAsync(c
IEnumerable data;
if (ascending)
data = await temp.OrderBy(s => s.Title)
- .ThenBy(s => s.Description)
+ .ThenBy(s => s.RawDescription)
.ToListAsync();
else
data = await temp.OrderByDescending(s => s.Title)
- .ThenByDescending(s => s.Description)
+ .ThenByDescending(s => s.RawDescription)
.ToListAsync();
var total = await _dbcontext.Main.CountAsync(s => s.Title.ToLower().StartsWith(alph));
@@ -98,7 +106,20 @@ async Task IMainDataAccess.GetByAlphabetAsync(c
async Task IMainDataAccess.GetAsync(Guid id)
{
- return await _dbcontext.Main.Include(s => s.Files).Include(s => s.Links).FirstOrDefaultAsync(s => s.Id == id);
+ Main item = await _dbcontext.Main.Include(s => s.Files).Include(s => s.Links).FirstOrDefaultAsync(s => s.Id == id);
+
+ // replace links in item
+ while (item.RichDescription.IndexOf("$$$") != -1)
+ {
+ var startIndex = item.RichDescription.IndexOf("$$$") + 3;
+ var endIndex = item.RichDescription.Substring(startIndex).IndexOf("$$$");
+
+ var referenceid = item.RichDescription.Substring(startIndex, endIndex);
+
+ item.RichDescription= item.RichDescription.Replace($"$$${referenceid}$$$", $"{item.Links.FirstOrDefault(s => s.ReferenceId.ToString() == referenceid).Description}");
+ }
+
+ return item;
}
#endregion
@@ -124,7 +145,10 @@ public async Task UpdateAsync(Guid id, MainUpdateModel model)
if (entry != null)
{
entry.Title = model.Title;
- entry.Description = model.Description;
+ entry.RichDescription = model.RichDescription;
+
+ // TODO : do conversion on raw description
+
entry.Category = model.Category;
_dbcontext.Main.Update(entry);
@@ -172,19 +196,18 @@ public async Task CleanUpData()
{
string searchStartString = "";
- var links = new List();
+ var allLinks = new List();
var allData = await _dbcontext.Main.ToListAsync();
- //using StreamWriter file = new StreamWriter(@"C:\temp\temp.txt", append: true);
foreach (var item in allData)
{
- if (item.Description != null)
+ if (item.RichDescription != null)
{
// Extract start indices
List startIndexes = new List();
for (int index = 0; ; index += searchStartString.Length)
{
- index = item.Description.IndexOf(searchStartString, index);
+ index = item.RichDescription.IndexOf(searchStartString, index);
if (index != -1)
startIndexes.Add(index);
else break;
@@ -194,32 +217,32 @@ public async Task CleanUpData()
List endIndexes = new List();
for (int index = 0; ; index += searchEndString.Length)
{
- index = item.Description.IndexOf(searchEndString, index);
+ index = item.RichDescription.IndexOf(searchEndString, index);
if (index != -1)
endIndexes.Add(index);
else break;
}
//
- var newDesc = new string(item.Description);
+ var newDesc = new string(item.RichDescription);
+ var links = new List();
+
for (int i = 0; i < startIndexes.Count; i++)
{
- string value = item.Description.Substring(startIndexes[i], endIndexes[i] - startIndexes[i] + searchEndString.Length);
+ string value = item.RichDescription.Substring(startIndexes[i], endIndexes[i] - startIndexes[i] + searchEndString.Length);
if (value.Contains("http://"))
{
var id = value.Substring(value.IndexOf("id=") + 3, 36);
var desc = value.Substring(value.IndexOf(">") + 1, value.IndexOf("<", value.IndexOf(">")) - value.IndexOf(">") - 1);
- //await file.WriteLineAsync($"id = {id} | Description = {desc}");
-
newDesc = newDesc.Replace(value, $"$$${id}$$$");
- //await file.WriteLineAsync($"new description = {newDesc}");
// add to links list
links.Add(new Links
{
Id = Guid.NewGuid(),
- MainId = Guid.Parse(id),
+ MainId = item.Id,
+ ReferenceId = Guid.Parse(id),
Link = value,
Description = desc,
IsInternal = true
@@ -228,18 +251,54 @@ public async Task CleanUpData()
}
// update the description
- item.Description = newDesc;
+ item.RichDescription = newDesc;
+ // update the links array
+ item.Links = links;
+ allLinks.AddRange(links);
}
}
// add to the links table
- await _dbcontext.Links.AddRangeAsync(links);
-
+ await _dbcontext.Links.AddRangeAsync(allLinks);
// update the main data
_dbcontext.Main.UpdateRange(allData);
+ await _dbcontext.SaveChanges();
+ allData = await _dbcontext.Main.Include(s => s.Links).ToListAsync();
+
+ foreach (var item in allData)
+ {
+ var temp = new string(item.RichDescription);
+
+ if (!string.IsNullOrEmpty(temp))
+ {
+ // replace the links
+ if (item.Links != null && item.Links.Any())
+ {
+ foreach (var link in item.Links)
+ {
+ var identifier = $"$$${link.ReferenceId}$$$";
+ temp = temp.Replace(identifier, link.Description);
+ }
+ }
+
+ item.RawDescription = temp;
+
+ // replace the HTML tags
+ item.RawDescription = StripHTML(item.RawDescription, true);
+ }
+ }
+ // update the main data
+ _dbcontext.Main.UpdateRange(allData);
await _dbcontext.SaveChanges();
}
+
+ public static string StripHTML(string HTMLText, bool decode = true)
+ {
+ Regex reg = new Regex("<[^>]+>", RegexOptions.IgnoreCase);
+ var stripped = reg.Replace(HTMLText, "");
+ return decode ? HttpUtility.HtmlDecode(stripped) : stripped;
+ }
#endregion
}
}
\ No newline at end of file
diff --git a/Library.Encyclopedia.Entity/Interfaces/IMainDataAccess.cs b/Library.Encyclopedia.Entity/Interfaces/IMainDataAccess.cs
index cc8c6eb..e50686d 100644
--- a/Library.Encyclopedia.Entity/Interfaces/IMainDataAccess.cs
+++ b/Library.Encyclopedia.Entity/Interfaces/IMainDataAccess.cs
@@ -9,7 +9,7 @@ namespace Library.Encyclopedia.Entity.Interfaces
public interface IMainDataAccess
{
#region GET
- public Task GetAsync(string query, int offset, int pagesize, bool ascending);
+ public Task GetAsync(string query, int offset, int pagesize, int previewSize, bool ascending);
public Task GetByCategoryAsync(string category, int offset, int pagesize, bool ascending);
public Task GetByAlphabetAsync(char startingAlphabet, int offset, int pagesize, bool ascending);
public Task GetAsync(Guid id);
diff --git a/Library.Encyclopedia.Entity/Models/External/MainMinimizedExternal.cs b/Library.Encyclopedia.Entity/Models/External/MainMinimizedExternal.cs
index 7aca354..df21a9e 100644
--- a/Library.Encyclopedia.Entity/Models/External/MainMinimizedExternal.cs
+++ b/Library.Encyclopedia.Entity/Models/External/MainMinimizedExternal.cs
@@ -8,8 +8,7 @@ public class MainMinimizedExternal
{
public Guid Id { get; set; }
public string Title { get; set; }
- public string Description { get; set; }
- public string Category { get; set; }
+ public string Preview { get; set; }
}
public class MainMinimizedExternalCollection : QueryExternalModel
{
diff --git a/Library.Encyclopedia.Entity/Models/External/MainUpdateModel.cs b/Library.Encyclopedia.Entity/Models/External/MainUpdateModel.cs
index 225404b..90bbab1 100644
--- a/Library.Encyclopedia.Entity/Models/External/MainUpdateModel.cs
+++ b/Library.Encyclopedia.Entity/Models/External/MainUpdateModel.cs
@@ -3,7 +3,8 @@
public class MainUpdateModel
{
public string Title { get; set; }
- public string Description { get; set; }
+ public string RawDescription { get; set; }
+ public string RichDescription { get; set; }
public string Category { get; set; }
}
}
\ No newline at end of file
diff --git a/Library.Encyclopedia.Entity/Models/Links.cs b/Library.Encyclopedia.Entity/Models/Links.cs
index 0d2eb11..d75f55d 100644
--- a/Library.Encyclopedia.Entity/Models/Links.cs
+++ b/Library.Encyclopedia.Entity/Models/Links.cs
@@ -10,6 +10,8 @@ public class Links
[Required]
public Guid MainId { get; set; }
[Required]
+ public Guid ReferenceId { get; set; }
+ [Required]
public string Link { get; set; }
public string Description { get; set; }
[Required]
diff --git a/Library.Encyclopedia.Entity/Models/Main.cs b/Library.Encyclopedia.Entity/Models/Main.cs
index bc6bf11..9109bca 100644
--- a/Library.Encyclopedia.Entity/Models/Main.cs
+++ b/Library.Encyclopedia.Entity/Models/Main.cs
@@ -12,7 +12,9 @@ public class Main
[Required]
[StringLength(1024)]
public string Title { get; set; }
- public string Description { get; set; }
+ public string RichDescription { get; set; }
+ public string RawDescription { get; set; }
+
[StringLength(256)]
public string Category { get; set; }
@@ -22,15 +24,73 @@ public class Main
public static class MainExtensions
{
+ public static MainMinimizedExternal MinimizeWithQuery(this Main main, string query, int previewText_maxlength)
+ {
+ if (!string.IsNullOrEmpty(query))
+ {
+ int indexOfQuery = main.RawDescription.IndexOf(query, StringComparison.OrdinalIgnoreCase);
+
+ // find the complete word
+ if (indexOfQuery != -1)
+ {
+ for (int i = indexOfQuery; i >= 0; i--)
+ {
+ if (char.IsSeparator(main.RawDescription[i]))
+ {
+ indexOfQuery = i;
+ break;
+ }
+ }
+ }
+
+ int lengthOfPreviewText = indexOfQuery == -1
+ ? Math.Min(previewText_maxlength, main.RawDescription.Length)
+ : Math.Min(previewText_maxlength, main.RawDescription.Length - indexOfQuery);
+
+ return new MainMinimizedExternal
+ {
+ Id = main.Id,
+ Preview = indexOfQuery == -1
+ ? main.RawDescription.Length > previewText_maxlength
+ ? main.RawDescription.Substring(0, lengthOfPreviewText) + " ..."
+ : main.RawDescription.Substring(0, lengthOfPreviewText)
+ : main.RawDescription.Length - indexOfQuery > previewText_maxlength
+ ? " ... " + main.RawDescription.Substring(indexOfQuery, lengthOfPreviewText) + " ..."
+ : main.RawDescription.Length > previewText_maxlength
+ ? " ... " + main.RawDescription.Substring(main.RawDescription.Length - previewText_maxlength, previewText_maxlength)
+ : main.RawDescription,
+ Title = main.Title
+ };
+ }
+ else
+ {
+ int lengthOfPreviewText = Math.Min(previewText_maxlength, main.RawDescription.Length);
+ return new MainMinimizedExternal
+ {
+ Id = main.Id,
+ Preview = main.RawDescription.Length > previewText_maxlength
+ ? main.RawDescription.Substring(0, lengthOfPreviewText) + " ..."
+ : main.RawDescription.Substring(0, lengthOfPreviewText),
+ Title = main.Title
+ };
+ }
+ }
public static MainMinimizedExternal Minimize(this Main main)
{
- return new MainMinimizedExternal {
+ return new MainMinimizedExternal
+ {
Id = main.Id,
- Category = main.Category,
- Description = main.Description,
+ Preview = main.RawDescription,
Title = main.Title
};
}
+ public static IEnumerable MinimizeWithQuery(this IEnumerable collection, string query, int previewText_maxlength)
+ {
+ foreach (var item in collection)
+ {
+ yield return MinimizeWithQuery(item, query, previewText_maxlength);
+ }
+ }
public static IEnumerable Minimize(this IEnumerable collection)
{
foreach (var item in collection)