UserTags implementation

main
Ogoun 6 months ago
parent 1a3354bfe4
commit a592d9243a

@ -30,7 +30,7 @@ namespace BukiVedi.App.Controllers
public async Task<ActionResult<IEnumerable<BookResponse>>> SearchByAuthor([FromRoute] string id)
{
var books = (await _library.SearchBooksByAuthor(id)).ToArray();
return Ok(books.Select(b => BookEntityMapper.Map(b)));
return Ok(await BookEntityMapper.Map(books));
}
/// <summary>

@ -38,22 +38,12 @@ namespace BukiVedi.App.Controllers
case "@favorites":
{
var books = (await _library.SearchFavoritesBooks(OperationContext.OperationInitiator.Id)).ToArray();
return Ok(books.Select(b =>
{
var bu = BookEntityMapper.Map(b);
bu.IsFavorite = true; // TODO сделать проверкой по справочнику в кеше
return bu;
}));
return Ok(await BookEntityMapper.Map(books));
}
case "@favoriteauthors":
{
var books = (await _library.SearchFavoriteAuthorsBooks(OperationContext.OperationInitiator.Id)).ToArray();
return Ok(books.Select(b =>
{
var bu = BookEntityMapper.Map(b);
bu.IsFavorite = true; // TODO сделать проверкой по справочнику в кеше
return bu;
}));
return Ok(await BookEntityMapper.Map(books));
}
case "@tagged":
{
@ -63,30 +53,25 @@ namespace BukiVedi.App.Controllers
tag = sv.ToString();
}
var books = (await _library.SearchTaggedBooks(OperationContext.OperationInitiator.Id, tag: tag!)).ToArray();
return Ok(books.Select(b => BookEntityMapper.Map(b)));
return Ok(await BookEntityMapper.Map(books));
}
case "@blocked":
{
var books = (await _library.SearchBlockedBooks(OperationContext.OperationInitiator.Id)).ToArray();
return Ok(books.Select(b =>
{
var bu = BookEntityMapper.Map(b);
bu.IsBlocked = true; // TODO сделать проверкой по справочнику в кеше
return bu;
}));
return Ok(await BookEntityMapper.Map(books));
}
case "@toread":
{
var books = (await _library.SearchToReadBooks(OperationContext.OperationInitiator.Id)).ToArray();
return Ok(books.Select(b => BookEntityMapper.Map(b)));
return Ok(await BookEntityMapper.Map(books));
}
default:
{
var books = (await _library.SearchBooks(request.Query)).ToArray();
return Ok(books.Select(b => BookEntityMapper.Map(b)));
return Ok(await BookEntityMapper.Map(books));
}
}
}

@ -1,32 +0,0 @@
using BukiVedi.Shared.Entities;
using BukiVedi.Shared.Services;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using MongoDB.Driver;
namespace BukiVedi.App.Controllers
{
[Route("api/hints")]
[ApiController]
[Authorize("authorized")]
public class HintsController
: BaseController
{
private readonly ILibrary _library;
public HintsController(ILibrary library)
: base()
{
_library = library;
}
/// <summary>
/// Список пользовательских тегов
/// </summary>
/// <returns></returns>
[HttpGet("tags")]
public async Task<ActionResult<IEnumerable<string>>> GetUserTags()
{
return Ok((await Tables.UserTag.Get(Builders<UserTag>.Filter.Eq(t => t.UserId, OperationContext.OperationInitiator.Id)))?.Select(t => t.Name));
}
}
}

@ -0,0 +1,59 @@
using BukiVedi.App.Requests;
using BukiVedi.Shared.Entities;
using BukiVedi.Shared.Services;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using MongoDB.Driver;
namespace BukiVedi.App.Controllers
{
[Authorize("authorized")]
[ApiController]
[Route("api/tags")]
public class TagsController
: BaseController
{
/// <summary>
/// Добавление тега для книги
/// </summary>
/// <returns>Ok</returns>
[HttpPost]
public async Task<IActionResult> AppendTag([FromBody] AppendTagRequest request)
{
if (request != null && string.IsNullOrWhiteSpace(request.Name) == false && await Tables.Books.ExistById(request.BookId))
{
var name = request.Name.Trim().ToLowerInvariant();
var tagFilter = Builders<UserTag>.Filter.And(Builders<UserTag>.Filter.Eq(t => t.BookId, request.BookId), Builders<UserTag>.Filter.Eq(t => t.Name, name));
if (false == await Tables.UserTag.Exists(tagFilter))
{
await Tables.UserTag.Write(new UserTag { BookId = request.BookId, Name = name, UserId = OperationContext.OperationInitiator.Id });
}
}
return Ok();
}
/// <summary>
/// Удаление тега для книги
/// </summary>
/// <returns>Ok</returns>
[HttpDelete("id")]
public async Task<ActionResult<bool>> RemoveTag([FromRoute] string id)
{
if (string.IsNullOrWhiteSpace(id) == false && await Tables.UserTag.ExistById(id))
{
return Ok(await Tables.UserTag.TryRemoveById(id));
}
return Ok(false);
}
/// <summary>
/// Список пользовательских тегов
/// </summary>
/// <returns></returns>
[HttpGet]
public async Task<ActionResult<IEnumerable<string>>> GetUserTags()
{
return Ok((await Tables.UserTag.Get(Builders<UserTag>.Filter.Eq(t => t.UserId, OperationContext.OperationInitiator.Id)))?.Select(t => t.Name));
}
}
}

@ -0,0 +1,8 @@
namespace BukiVedi.App.Requests
{
public class AppendTagRequest
{
public string BookId { get; set; }
public string Name { get; set; }
}
}

@ -62,7 +62,7 @@
/// <summary>
/// Теги(массив объектов с полями id; имя тега)
/// </summary>
public TagInfo[] Tags { get; set; }
public IEnumerable<TagInfo> Tags { get; set; }
/// <summary>
/// Год издания
/// </summary>

@ -1,22 +1,42 @@
using BukiVedi.App.Responces;
using BukiVedi.Shared.Entities;
using BukiVedi.Shared.Services;
using MongoDB.Driver;
namespace BukiVedi.App.Services.Mappers
{
public class BookEntityMapper
{
public static BookResponse Map(BookEntity book)
public static async Task<IEnumerable<BookResponse>> Map(IEnumerable<BookEntity> books)
{
return new BookResponse
var booksIds = books.Select(x => x.Id).ToList();
var tags_list = (await Tables.UserTag.Get(Builders<UserTag>.Filter.In(t => t.BookId, booksIds)));
var tags = new Dictionary<string, List<TagInfo>>();
foreach (var t in tags_list)
{
Authors = book.Authors.Select(a => new AuthorInfo { Id = a.Id, Name = a.Name }).ToArray(),
Description = book.Description,
Format = book.Format,
Id = book.Id,
Genres = new GenreInfo[1] { new GenreInfo { Id = book.Genre.Id, Name = book.Genre.Code } },
Title = book.Title,
Year = book.Year,
};
if (tags.TryGetValue(t.BookId, out var list)) { list.Add(new TagInfo { Id = t.Id, Name = t.Name }); }
else
{
tags.Add(t.BookId,
new List<TagInfo>
{
new TagInfo { Id = t.Id, Name = t.Name }
});
}
}
return books.Select(book =>
new BookResponse
{
Authors = book.Authors.Select(a => new AuthorInfo { Id = a.Id, Name = a.Name }).ToArray(),
Description = book.Description,
Format = book.Format,
Id = book.Id,
Genres = new GenreInfo[1] { new GenreInfo { Id = book.Genre.Id, Name = book.Genre.Code } },
Title = book.Title,
Year = book.Year,
Tags = tags.ContainsKey(book.Id) ? tags[book.Id] : null!
});
}
}
}

@ -233,9 +233,25 @@
]
},
{
"ContainingType": "BukiVedi.App.Controllers.HintsController",
"ContainingType": "BukiVedi.App.Controllers.TagsController",
"Method": "AppendTag",
"RelativePath": "api/tags",
"HttpMethod": "POST",
"IsController": true,
"Order": 0,
"Parameters": [
{
"Name": "request",
"Type": "BukiVedi.App.Requests.AppendTagRequest",
"IsRequired": true
}
],
"ReturnTypes": []
},
{
"ContainingType": "BukiVedi.App.Controllers.TagsController",
"Method": "GetUserTags",
"RelativePath": "api/hints/tags",
"RelativePath": "api/tags",
"HttpMethod": "GET",
"IsController": true,
"Order": 0,
@ -251,5 +267,31 @@
"StatusCode": 200
}
]
},
{
"ContainingType": "BukiVedi.App.Controllers.TagsController",
"Method": "RemoveTag",
"RelativePath": "api/tags/id",
"HttpMethod": "DELETE",
"IsController": true,
"Order": 0,
"Parameters": [
{
"Name": "id",
"Type": "System.String",
"IsRequired": false
}
],
"ReturnTypes": [
{
"Type": "System.Boolean",
"MediaTypes": [
"text/plain",
"application/json",
"text/json"
],
"StatusCode": 200
}
]
}
]

@ -14,7 +14,7 @@ using System.Reflection;
[assembly: System.Reflection.AssemblyCompanyAttribute("BukiVedi.App")]
[assembly: System.Reflection.AssemblyConfigurationAttribute("Debug")]
[assembly: System.Reflection.AssemblyFileVersionAttribute("1.0.0.0")]
[assembly: System.Reflection.AssemblyInformationalVersionAttribute("1.0.0+a3d0f6854da43e4751a466c4aad31306f23988f4")]
[assembly: System.Reflection.AssemblyInformationalVersionAttribute("1.0.0+1a3354bfe43b1cd0f3b6881ad9e749c9d0575d87")]
[assembly: System.Reflection.AssemblyProductAttribute("BukiVedi.App")]
[assembly: System.Reflection.AssemblyTitleAttribute("BukiVedi.App")]
[assembly: System.Reflection.AssemblyVersionAttribute("1.0.0.0")]

@ -1 +1 @@
e5a3d294f67b6f7db5ed4106b1e0779f1ab92391b34c7101aef3389c854bc7ea
b9e5179c1e29c1c145152c4bd263b32b05a8e7759f4db3ae908c9f5d8deb49ec

@ -1 +1 @@
4c4f32f8e585faf173948396d852ab461832b5dd36928e2eae2b6a67ddba0a04
411769ab7f33e006bcf2fe23bf29c7beabc4c95916c9c9d86b53e1439516e4a3

@ -25,9 +25,9 @@ namespace BukiVedi.Shared
Task<T> ModifyOne(FilterDefinition<T> filter, UpdateDefinition<T> update);
Task<UpdateResult> Modify(FilterDefinition<T> filter, UpdateDefinition<T> update);
Task<T> ReWrite(T record);
internal Task<bool> TryRemove(T obj);
internal Task<bool> TryRemove(FilterDefinition<T> filter);
internal Task<bool> TryRemoveById(string id);
Task<bool> TryRemove(T obj);
Task<bool> TryRemove(FilterDefinition<T> filter);
Task<bool> TryRemoveById(string id);
internal Task Drop();
}
}

@ -67,11 +67,6 @@
},
"runtimeIdentifierGraphPath": "C:\\Program Files\\dotnet\\sdk\\8.0.200/PortableRuntimeIdentifierGraph.json"
}
},
"runtimes": {
"linux-x64": {
"#import": []
}
}
},
"G:\\Documents\\GitHub\\BukiVedi\\src\\BukiVedi.Shared\\BukiVedi.Shared.csproj": {
@ -163,11 +158,6 @@
},
"runtimeIdentifierGraphPath": "C:\\Program Files\\dotnet\\sdk\\8.0.200/PortableRuntimeIdentifierGraph.json"
}
},
"runtimes": {
"linux-x64": {
"#import": []
}
}
},
"G:\\Documents\\GitHub\\BukiVedi\\src\\Vendors\\LemmaGen_v3.0_PrebuiltFull\\LemmaSharpPrebuilt\\LemmaSharpPrebuilt.csproj": {
@ -293,11 +283,6 @@
},
"runtimeIdentifierGraphPath": "C:\\Program Files\\dotnet\\sdk\\8.0.200/PortableRuntimeIdentifierGraph.json"
}
},
"runtimes": {
"linux-x64": {
"#import": []
}
}
}
}

@ -14,7 +14,7 @@ using System.Reflection;
[assembly: System.Reflection.AssemblyCompanyAttribute("BukiVedi.Shared")]
[assembly: System.Reflection.AssemblyConfigurationAttribute("Debug")]
[assembly: System.Reflection.AssemblyFileVersionAttribute("1.0.0.0")]
[assembly: System.Reflection.AssemblyInformationalVersionAttribute("1.0.0+a3d0f6854da43e4751a466c4aad31306f23988f4")]
[assembly: System.Reflection.AssemblyInformationalVersionAttribute("1.0.0+1a3354bfe43b1cd0f3b6881ad9e749c9d0575d87")]
[assembly: System.Reflection.AssemblyProductAttribute("BukiVedi.Shared")]
[assembly: System.Reflection.AssemblyTitleAttribute("BukiVedi.Shared")]
[assembly: System.Reflection.AssemblyVersionAttribute("1.0.0.0")]

@ -1 +1 @@
2dd5b54c18e88209da1a71d5242ff522bc0fd3a0e6546e22e8f2e147cbf052ea
4349296b5681078306e6f8a7c49c392998f27e3710ca922dd7193cecfc1ea515

@ -359,332 +359,6 @@
"bin/placeholder/ZeroLevel.dll": {}
}
}
},
"net8.0/linux-x64": {
"AWSSDK.Core/3.7.100.14": {
"type": "package",
"compile": {
"lib/netcoreapp3.1/AWSSDK.Core.dll": {
"related": ".pdb;.xml"
}
},
"runtime": {
"lib/netcoreapp3.1/AWSSDK.Core.dll": {
"related": ".pdb;.xml"
}
}
},
"AWSSDK.SecurityToken/3.7.100.14": {
"type": "package",
"dependencies": {
"AWSSDK.Core": "[3.7.100.14, 4.0.0)"
},
"compile": {
"lib/netcoreapp3.1/AWSSDK.SecurityToken.dll": {
"related": ".pdb;.xml"
}
},
"runtime": {
"lib/netcoreapp3.1/AWSSDK.SecurityToken.dll": {
"related": ".pdb;.xml"
}
}
},
"DnsClient/1.6.1": {
"type": "package",
"dependencies": {
"Microsoft.Win32.Registry": "5.0.0"
},
"compile": {
"lib/net5.0/DnsClient.dll": {
"related": ".xml"
}
},
"runtime": {
"lib/net5.0/DnsClient.dll": {
"related": ".xml"
}
}
},
"FB2Library/1.3.3": {
"type": "package",
"compile": {
"lib/net6.0/FB2Library.dll": {}
},
"runtime": {
"lib/net6.0/FB2Library.dll": {}
}
},
"Microsoft.Extensions.Logging.Abstractions/2.0.0": {
"type": "package",
"compile": {
"lib/netstandard2.0/Microsoft.Extensions.Logging.Abstractions.dll": {
"related": ".xml"
}
},
"runtime": {
"lib/netstandard2.0/Microsoft.Extensions.Logging.Abstractions.dll": {
"related": ".xml"
}
}
},
"Microsoft.NETCore.Platforms/5.0.0": {
"type": "package",
"compile": {
"lib/netstandard1.0/_._": {}
},
"runtime": {
"lib/netstandard1.0/_._": {}
}
},
"Microsoft.Win32.Registry/5.0.0": {
"type": "package",
"dependencies": {
"System.Security.AccessControl": "5.0.0",
"System.Security.Principal.Windows": "5.0.0"
},
"compile": {
"ref/netstandard2.0/Microsoft.Win32.Registry.dll": {
"related": ".xml"
}
},
"runtime": {
"lib/netstandard2.0/Microsoft.Win32.Registry.dll": {
"related": ".xml"
}
}
},
"MongoDB.Bson/2.24.0": {
"type": "package",
"dependencies": {
"System.Memory": "4.5.5",
"System.Runtime.CompilerServices.Unsafe": "5.0.0"
},
"compile": {
"lib/netstandard2.1/MongoDB.Bson.dll": {
"related": ".xml"
}
},
"runtime": {
"lib/netstandard2.1/MongoDB.Bson.dll": {
"related": ".xml"
}
}
},
"MongoDB.Driver/2.24.0": {
"type": "package",
"dependencies": {
"Microsoft.Extensions.Logging.Abstractions": "2.0.0",
"MongoDB.Bson": "2.24.0",
"MongoDB.Driver.Core": "2.24.0",
"MongoDB.Libmongocrypt": "1.8.2"
},
"compile": {
"lib/netstandard2.1/MongoDB.Driver.dll": {
"related": ".xml"
}
},
"runtime": {
"lib/netstandard2.1/MongoDB.Driver.dll": {
"related": ".xml"
}
}
},
"MongoDB.Driver.Core/2.24.0": {
"type": "package",
"dependencies": {
"AWSSDK.SecurityToken": "3.7.100.14",
"DnsClient": "1.6.1",
"Microsoft.Extensions.Logging.Abstractions": "2.0.0",
"MongoDB.Bson": "2.24.0",
"MongoDB.Libmongocrypt": "1.8.2",
"SharpCompress": "0.30.1",
"Snappier": "1.0.0",
"System.Buffers": "4.5.1",
"ZstdSharp.Port": "0.7.3"
},
"compile": {
"lib/netstandard2.1/MongoDB.Driver.Core.dll": {
"related": ".xml"
}
},
"runtime": {
"lib/netstandard2.1/MongoDB.Driver.Core.dll": {
"related": ".xml"
}
}
},
"MongoDB.Libmongocrypt/1.8.2": {
"type": "package",
"compile": {
"lib/netstandard2.1/MongoDB.Libmongocrypt.dll": {}
},
"runtime": {
"lib/netstandard2.1/MongoDB.Libmongocrypt.dll": {}
},
"native": {
"runtimes/linux/native/libmongocrypt.so": {}
},
"contentFiles": {
"contentFiles/any/any/_._": {
"buildAction": "None",
"codeLanguage": "any",
"copyToOutput": false
}
},
"build": {
"build/_._": {}
}
},
"SharpCompress/0.30.1": {
"type": "package",
"compile": {
"lib/net5.0/SharpCompress.dll": {}
},
"runtime": {
"lib/net5.0/SharpCompress.dll": {}
}
},
"Snappier/1.0.0": {
"type": "package",
"compile": {
"lib/net5.0/Snappier.dll": {
"related": ".xml"
}
},
"runtime": {
"lib/net5.0/Snappier.dll": {
"related": ".xml"
}
}
},
"System.Buffers/4.5.1": {
"type": "package",
"compile": {
"ref/netcoreapp2.0/_._": {}
},
"runtime": {
"lib/netcoreapp2.0/_._": {}
}
},
"System.Memory/4.5.5": {
"type": "package",
"compile": {
"ref/netcoreapp2.1/_._": {}
},
"runtime": {
"lib/netcoreapp2.1/_._": {}
}
},
"System.Runtime.CompilerServices.Unsafe/5.0.0": {
"type": "package",
"compile": {
"ref/netstandard2.1/System.Runtime.CompilerServices.Unsafe.dll": {
"related": ".xml"
}
},
"runtime": {
"lib/netcoreapp2.0/System.Runtime.CompilerServices.Unsafe.dll": {
"related": ".xml"
}
}
},
"System.Security.AccessControl/5.0.0": {
"type": "package",
"dependencies": {
"Microsoft.NETCore.Platforms": "5.0.0",
"System.Security.Principal.Windows": "5.0.0"
},
"compile": {
"ref/netstandard2.0/System.Security.AccessControl.dll": {
"related": ".xml"
}
},
"runtime": {
"lib/netstandard2.0/System.Security.AccessControl.dll": {
"related": ".xml"
}
}
},
"System.Security.Principal.Windows/5.0.0": {
"type": "package",
"compile": {
"ref/netcoreapp3.0/System.Security.Principal.Windows.dll": {
"related": ".xml"
}
},
"runtime": {
"runtimes/unix/lib/netcoreapp2.1/System.Security.Principal.Windows.dll": {
"related": ".xml"
}
}
},
"ZstdSharp.Port/0.7.3": {
"type": "package",
"compile": {
"lib/net7.0/ZstdSharp.dll": {}
},
"runtime": {
"lib/net7.0/ZstdSharp.dll": {}
}
},
"LemmaSharp/1.0.0": {
"type": "project",
"compile": {
"bin/placeholder/LemmaSharp.dll": {}
},
"runtime": {
"bin/placeholder/LemmaSharp.dll": {}
}
},
"LemmaSharpPrebuilt/1.0.0": {
"type": "project",
"dependencies": {
"LemmaSharp": "1.0.0"
},
"compile": {
"bin/placeholder/LemmaSharpPrebuilt.dll": {}
},
"runtime": {
"bin/placeholder/LemmaSharpPrebuilt.dll": {}
}
},
"LemmaSharpPrebuiltFull/1.0.0": {
"type": "project",
"dependencies": {
"LemmaSharp": "1.0.0",
"LemmaSharpPrebuilt": "1.0.0"
},
"compile": {
"bin/placeholder/LemmaSharpPrebuiltFull.dll": {}
},
"runtime": {
"bin/placeholder/LemmaSharpPrebuiltFull.dll": {}
}
},
"Sleopok.Engine/1.0.0": {
"type": "project",
"framework": ".NETCoreApp,Version=v8.0",
"dependencies": {
"ZeroLevel": "3.4.0.8"
},
"compile": {
"bin/placeholder/Sleopok.Engine.dll": {}
},
"runtime": {
"bin/placeholder/Sleopok.Engine.dll": {}
}
},
"ZeroLevel/3.4.0.8": {
"type": "project",
"framework": ".NETCoreApp,Version=v8.0",
"compile": {
"bin/placeholder/ZeroLevel.dll": {}
},
"runtime": {
"bin/placeholder/ZeroLevel.dll": {}
}
}
}
},
"libraries": {
@ -1313,11 +987,6 @@
},
"runtimeIdentifierGraphPath": "C:\\Program Files\\dotnet\\sdk\\8.0.200/PortableRuntimeIdentifierGraph.json"
}
},
"runtimes": {
"linux-x64": {
"#import": []
}
}
}
}

@ -1,6 +1,6 @@
{
"version": 2,
"dgSpecHash": "PH28x1HAQv9f0NTmNqx7WpXX82izLpORxxiImmQTk9jKk/yc9Yni4anyFP84qZadoYiyIhJezrcd+gCGU9cUwA==",
"dgSpecHash": "YVwM+KO4mWGH6B1BXss/L3tLASd1EDkcdE0fSC9tmlDJYRd8v5KkEYaBZw9w1Pjlc6cFAx0UOnW6xgMSuFnyQg==",
"success": true,
"projectFilePath": "G:\\Documents\\GitHub\\BukiVedi\\src\\BukiVedi.Shared\\BukiVedi.Shared.csproj",
"expectedPackageFiles": [

@ -14,7 +14,7 @@ using System.Reflection;
[assembly: System.Reflection.AssemblyCompanyAttribute("TitleReader")]
[assembly: System.Reflection.AssemblyConfigurationAttribute("Debug")]
[assembly: System.Reflection.AssemblyFileVersionAttribute("1.0.0.0")]
[assembly: System.Reflection.AssemblyInformationalVersionAttribute("1.0.0+a3d0f6854da43e4751a466c4aad31306f23988f4")]
[assembly: System.Reflection.AssemblyInformationalVersionAttribute("1.0.0+1a3354bfe43b1cd0f3b6881ad9e749c9d0575d87")]
[assembly: System.Reflection.AssemblyProductAttribute("TitleReader")]
[assembly: System.Reflection.AssemblyTitleAttribute("TitleReader")]
[assembly: System.Reflection.AssemblyVersionAttribute("1.0.0.0")]

@ -1 +1 @@
bb1821fe2cb7b9fa9228f61c79c42670de63950df37dc8a32cd1652c3c4b559c
77a6c1edef6ad7a4d85724e4cbb6b2f35ed2ee54d591989ab3b1fe5cd12d4bf5

Loading…
Cancel
Save

Powered by TurnKey Linux.