mirror of
https://github.com/Kareadita/Kavita.git
synced 2025-07-09 03:04:19 -04:00
New Feature Stats (#1179)
* When searching, search against normalized names. * Added new stat fields
This commit is contained in:
parent
fbb8934eef
commit
0622d8a874
@ -245,8 +245,7 @@ namespace API.Controllers
|
|||||||
var userId = await _unitOfWork.UserRepository.GetUserIdByUsernameAsync(User.GetUsername());
|
var userId = await _unitOfWork.UserRepository.GetUserIdByUsernameAsync(User.GetUsername());
|
||||||
var results = await _unitOfWork.SeriesRepository.GetOnDeck(userId, libraryId, userParams, filterDto);
|
var results = await _unitOfWork.SeriesRepository.GetOnDeck(userId, libraryId, userParams, filterDto);
|
||||||
|
|
||||||
var listResults = results.DistinctBy(s => s.Name).Skip((userParams.PageNumber - 1) * userParams.PageSize)
|
var listResults = results.DistinctBy(s => s.Name).Skip((userParams.PageNumber - 1) * userParams.PageSize).Take(userParams.PageSize).ToList();
|
||||||
.Take(userParams.PageSize).ToList();
|
|
||||||
var pagedList = new PagedList<SeriesDto>(listResults, listResults.Count, userParams.PageNumber, userParams.PageSize);
|
var pagedList = new PagedList<SeriesDto>(listResults, listResults.Count, userParams.PageNumber, userParams.PageSize);
|
||||||
|
|
||||||
await _unitOfWork.SeriesRepository.AddSeriesModifiers(userId, pagedList);
|
await _unitOfWork.SeriesRepository.AddSeriesModifiers(userId, pagedList);
|
||||||
|
@ -1,4 +1,6 @@
|
|||||||
namespace API.DTOs.Stats
|
using API.Entities.Enums;
|
||||||
|
|
||||||
|
namespace API.DTOs.Stats
|
||||||
{
|
{
|
||||||
public class ServerInfoDto
|
public class ServerInfoDto
|
||||||
{
|
{
|
||||||
@ -10,5 +12,39 @@
|
|||||||
public int NumOfCores { get; set; }
|
public int NumOfCores { get; set; }
|
||||||
public int NumberOfLibraries { get; set; }
|
public int NumberOfLibraries { get; set; }
|
||||||
public bool HasBookmarks { get; set; }
|
public bool HasBookmarks { get; set; }
|
||||||
|
/// <summary>
|
||||||
|
/// The site theme the install is using
|
||||||
|
/// </summary>
|
||||||
|
public string ActiveSiteTheme { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The reading mode the main user has as a preference
|
||||||
|
/// </summary>
|
||||||
|
public ReaderMode MangaReaderMode { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Number of users on the install
|
||||||
|
/// </summary>
|
||||||
|
public int NumberOfUsers { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Number of collections on the install
|
||||||
|
/// </summary>
|
||||||
|
public int NumberOfCollections { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Number of reading lists on the install (Sum of all users)
|
||||||
|
/// </summary>
|
||||||
|
public int NumberOfReadingLists { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Is OPDS enabled
|
||||||
|
/// </summary>
|
||||||
|
public bool OPDSEnabled { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Total number of files in the instance
|
||||||
|
/// </summary>
|
||||||
|
public int TotalFiles { get; set; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -37,6 +37,7 @@ public interface ILibraryRepository
|
|||||||
Task<IEnumerable<Library>> GetLibrariesForUserIdAsync(int userId);
|
Task<IEnumerable<Library>> GetLibrariesForUserIdAsync(int userId);
|
||||||
Task<LibraryType> GetLibraryTypeAsync(int libraryId);
|
Task<LibraryType> GetLibraryTypeAsync(int libraryId);
|
||||||
Task<IEnumerable<Library>> GetLibraryForIdsAsync(IList<int> libraryIds);
|
Task<IEnumerable<Library>> GetLibraryForIdsAsync(IList<int> libraryIds);
|
||||||
|
Task<int> GetTotalFiles();
|
||||||
}
|
}
|
||||||
|
|
||||||
public class LibraryRepository : ILibraryRepository
|
public class LibraryRepository : ILibraryRepository
|
||||||
@ -116,6 +117,11 @@ public class LibraryRepository : ILibraryRepository
|
|||||||
.ToListAsync();
|
.ToListAsync();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public async Task<int> GetTotalFiles()
|
||||||
|
{
|
||||||
|
return await _context.MangaFile.CountAsync();
|
||||||
|
}
|
||||||
|
|
||||||
public async Task<IEnumerable<LibraryDto>> GetLibraryDtosAsync()
|
public async Task<IEnumerable<LibraryDto>> GetLibraryDtosAsync()
|
||||||
{
|
{
|
||||||
return await _context.Library
|
return await _context.Library
|
||||||
|
@ -25,6 +25,7 @@ public interface IReadingListRepository
|
|||||||
void Remove(ReadingListItem item);
|
void Remove(ReadingListItem item);
|
||||||
void BulkRemove(IEnumerable<ReadingListItem> items);
|
void BulkRemove(IEnumerable<ReadingListItem> items);
|
||||||
void Update(ReadingList list);
|
void Update(ReadingList list);
|
||||||
|
Task<int> Count();
|
||||||
}
|
}
|
||||||
|
|
||||||
public class ReadingListRepository : IReadingListRepository
|
public class ReadingListRepository : IReadingListRepository
|
||||||
@ -43,6 +44,11 @@ public class ReadingListRepository : IReadingListRepository
|
|||||||
_context.Entry(list).State = EntityState.Modified;
|
_context.Entry(list).State = EntityState.Modified;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public async Task<int> Count()
|
||||||
|
{
|
||||||
|
return await _context.ReadingList.CountAsync();
|
||||||
|
}
|
||||||
|
|
||||||
public void Remove(ReadingListItem item)
|
public void Remove(ReadingListItem item)
|
||||||
{
|
{
|
||||||
_context.ReadingListItem.Remove(item);
|
_context.ReadingListItem.Remove(item);
|
||||||
|
@ -276,6 +276,7 @@ public class SeriesRepository : ISeriesRepository
|
|||||||
{
|
{
|
||||||
|
|
||||||
var result = new SearchResultGroupDto();
|
var result = new SearchResultGroupDto();
|
||||||
|
var searchQueryNormalized = Parser.Parser.Normalize(searchQuery);
|
||||||
|
|
||||||
var seriesIds = _context.Series
|
var seriesIds = _context.Series
|
||||||
.Where(s => libraryIds.Contains(s.LibraryId))
|
.Where(s => libraryIds.Contains(s.LibraryId))
|
||||||
@ -299,6 +300,7 @@ public class SeriesRepository : ISeriesRepository
|
|||||||
.Where(s => EF.Functions.Like(s.Name, $"%{searchQuery}%")
|
.Where(s => EF.Functions.Like(s.Name, $"%{searchQuery}%")
|
||||||
|| EF.Functions.Like(s.OriginalName, $"%{searchQuery}%")
|
|| EF.Functions.Like(s.OriginalName, $"%{searchQuery}%")
|
||||||
|| EF.Functions.Like(s.LocalizedName, $"%{searchQuery}%")
|
|| EF.Functions.Like(s.LocalizedName, $"%{searchQuery}%")
|
||||||
|
|| EF.Functions.Like(s.NormalizedName, $"%{searchQueryNormalized}%")
|
||||||
|| (hasYearInQuery && s.Metadata.ReleaseYear == yearComparison))
|
|| (hasYearInQuery && s.Metadata.ReleaseYear == yearComparison))
|
||||||
.Include(s => s.Library)
|
.Include(s => s.Library)
|
||||||
.OrderBy(s => s.SortName)
|
.OrderBy(s => s.SortName)
|
||||||
@ -317,7 +319,7 @@ public class SeriesRepository : ISeriesRepository
|
|||||||
|
|
||||||
result.Collections = await _context.CollectionTag
|
result.Collections = await _context.CollectionTag
|
||||||
.Where(s => EF.Functions.Like(s.Title, $"%{searchQuery}%")
|
.Where(s => EF.Functions.Like(s.Title, $"%{searchQuery}%")
|
||||||
|| EF.Functions.Like(s.NormalizedTitle, $"%{searchQuery}%"))
|
|| EF.Functions.Like(s.NormalizedTitle, $"%{searchQueryNormalized}%"))
|
||||||
.Where(s => s.Promoted || isAdmin)
|
.Where(s => s.Promoted || isAdmin)
|
||||||
.OrderBy(s => s.Title)
|
.OrderBy(s => s.Title)
|
||||||
.AsNoTracking()
|
.AsNoTracking()
|
||||||
|
@ -35,6 +35,14 @@ namespace API.Entities
|
|||||||
/// on next load
|
/// on next load
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string BookScrollId { get; set; }
|
public string BookScrollId { get; set; }
|
||||||
|
/// <summary>
|
||||||
|
/// When this was first created
|
||||||
|
/// </summary>
|
||||||
|
public DateTime Created { get; set; }
|
||||||
|
/// <summary>
|
||||||
|
/// Last date this was updated
|
||||||
|
/// </summary>
|
||||||
|
public DateTime LastModified { get; set; }
|
||||||
|
|
||||||
// Relationships
|
// Relationships
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -45,14 +53,5 @@ namespace API.Entities
|
|||||||
/// User this progress belongs to
|
/// User this progress belongs to
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public int AppUserId { get; set; }
|
public int AppUserId { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// When this was first created
|
|
||||||
/// </summary>
|
|
||||||
public DateTime Created { get; set; }
|
|
||||||
/// <summary>
|
|
||||||
/// Last date this was updated
|
|
||||||
/// </summary>
|
|
||||||
public DateTime LastModified { get; set; }
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -5,6 +5,7 @@ using System.Runtime.InteropServices;
|
|||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using API.Data;
|
using API.Data;
|
||||||
using API.DTOs.Stats;
|
using API.DTOs.Stats;
|
||||||
|
using API.DTOs.Theme;
|
||||||
using API.Entities.Enums;
|
using API.Entities.Enums;
|
||||||
using Flurl.Http;
|
using Flurl.Http;
|
||||||
using Kavita.Common.EnvironmentInfo;
|
using Kavita.Common.EnvironmentInfo;
|
||||||
@ -100,6 +101,12 @@ public class StatsService : IStatsService
|
|||||||
{
|
{
|
||||||
var installId = await _unitOfWork.SettingsRepository.GetSettingAsync(ServerSettingKey.InstallId);
|
var installId = await _unitOfWork.SettingsRepository.GetSettingAsync(ServerSettingKey.InstallId);
|
||||||
var installVersion = await _unitOfWork.SettingsRepository.GetSettingAsync(ServerSettingKey.InstallVersion);
|
var installVersion = await _unitOfWork.SettingsRepository.GetSettingAsync(ServerSettingKey.InstallVersion);
|
||||||
|
|
||||||
|
var firstAdminUser = (await _unitOfWork.UserRepository.GetAdminUsersAsync()).First();
|
||||||
|
var firstAdminUserPref = (await _unitOfWork.UserRepository.GetPreferencesAsync(firstAdminUser.UserName));
|
||||||
|
|
||||||
|
var activeTheme = firstAdminUserPref.Theme ?? Seed.DefaultThemes.First(t => t.IsDefault);
|
||||||
|
|
||||||
var serverInfo = new ServerInfoDto
|
var serverInfo = new ServerInfoDto
|
||||||
{
|
{
|
||||||
InstallId = installId.Value,
|
InstallId = installId.Value,
|
||||||
@ -109,7 +116,14 @@ public class StatsService : IStatsService
|
|||||||
IsDocker = new OsInfo(Array.Empty<IOsVersionAdapter>()).IsDocker,
|
IsDocker = new OsInfo(Array.Empty<IOsVersionAdapter>()).IsDocker,
|
||||||
NumOfCores = Math.Max(Environment.ProcessorCount, 1),
|
NumOfCores = Math.Max(Environment.ProcessorCount, 1),
|
||||||
HasBookmarks = (await _unitOfWork.UserRepository.GetAllBookmarksAsync()).Any(),
|
HasBookmarks = (await _unitOfWork.UserRepository.GetAllBookmarksAsync()).Any(),
|
||||||
NumberOfLibraries = (await _unitOfWork.LibraryRepository.GetLibrariesAsync()).Count()
|
NumberOfLibraries = (await _unitOfWork.LibraryRepository.GetLibrariesAsync()).Count(),
|
||||||
|
ActiveSiteTheme = activeTheme.Name,
|
||||||
|
NumberOfCollections = (await _unitOfWork.CollectionTagRepository.GetAllTagsAsync()).Count(),
|
||||||
|
NumberOfReadingLists = await _unitOfWork.ReadingListRepository.Count(),
|
||||||
|
OPDSEnabled = (await _unitOfWork.SettingsRepository.GetSettingsDtoAsync()).EnableOpds,
|
||||||
|
NumberOfUsers = (await _unitOfWork.UserRepository.GetAllUsers()).Count(),
|
||||||
|
TotalFiles = await _unitOfWork.LibraryRepository.GetTotalFiles(),
|
||||||
|
MangaReaderMode = firstAdminUserPref.ReaderMode
|
||||||
};
|
};
|
||||||
|
|
||||||
return serverInfo;
|
return serverInfo;
|
||||||
|
6
UI/Web/package-lock.json
generated
6
UI/Web/package-lock.json
generated
@ -10498,7 +10498,8 @@
|
|||||||
"dependencies": {
|
"dependencies": {
|
||||||
"ansi-regex": {
|
"ansi-regex": {
|
||||||
"version": "5.0.0",
|
"version": "5.0.0",
|
||||||
"resolved": "",
|
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz",
|
||||||
|
"integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"strip-ansi": {
|
"strip-ansi": {
|
||||||
@ -10703,7 +10704,8 @@
|
|||||||
"dependencies": {
|
"dependencies": {
|
||||||
"ansi-regex": {
|
"ansi-regex": {
|
||||||
"version": "5.0.0",
|
"version": "5.0.0",
|
||||||
"resolved": "",
|
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz",
|
||||||
|
"integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"ansi-styles": {
|
"ansi-styles": {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user