Merged develop into main
This commit is contained in:
commit
8a19c1da9e
103 changed files with 1242 additions and 900 deletions
|
@ -95,7 +95,7 @@ namespace API.Controllers
|
|||
var settings = await _unitOfWork.SettingsRepository.GetSettingsDtoAsync();
|
||||
if (!settings.EnableAuthentication && !registerDto.IsAdmin)
|
||||
{
|
||||
_logger.LogInformation("User {UserName} is being registered as non-admin with no server authentication. Using default password.", registerDto.Username);
|
||||
_logger.LogInformation("User {UserName} is being registered as non-admin with no server authentication. Using default password", registerDto.Username);
|
||||
registerDto.Password = AccountService.DefaultPassword;
|
||||
}
|
||||
|
||||
|
|
|
@ -17,6 +17,7 @@ using API.Interfaces.Services;
|
|||
using API.Services;
|
||||
using Kavita.Common;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
||||
namespace API.Controllers
|
||||
{
|
||||
|
@ -48,7 +49,6 @@ namespace API.Controllers
|
|||
_cacheService = cacheService;
|
||||
_readerService = readerService;
|
||||
|
||||
|
||||
_xmlSerializer = new XmlSerializer(typeof(Feed));
|
||||
_xmlOpenSearchSerializer = new XmlSerializer(typeof(OpenSearchDescription));
|
||||
|
||||
|
@ -62,18 +62,18 @@ namespace API.Controllers
|
|||
if (!(await _unitOfWork.SettingsRepository.GetSettingsDtoAsync()).EnableOpds)
|
||||
return BadRequest("OPDS is not enabled on this server");
|
||||
var feed = CreateFeed("Kavita", string.Empty, apiKey);
|
||||
feed.Id = "root";
|
||||
SetFeedId(feed, "root");
|
||||
feed.Entries.Add(new FeedEntry()
|
||||
{
|
||||
Id = "inProgress",
|
||||
Title = "In Progress",
|
||||
Id = "onDeck",
|
||||
Title = "On Deck",
|
||||
Content = new FeedEntryContent()
|
||||
{
|
||||
Text = "Browse by In Progress"
|
||||
Text = "Browse by On Deck"
|
||||
},
|
||||
Links = new List<FeedLink>()
|
||||
{
|
||||
CreateLink(FeedLinkRelation.SubSection, FeedLinkType.AtomNavigation, Prefix + $"{apiKey}/in-progress"),
|
||||
CreateLink(FeedLinkRelation.SubSection, FeedLinkType.AtomNavigation, Prefix + $"{apiKey}/on-deck"),
|
||||
}
|
||||
});
|
||||
feed.Entries.Add(new FeedEntry()
|
||||
|
@ -140,9 +140,8 @@ namespace API.Controllers
|
|||
return BadRequest("OPDS is not enabled on this server");
|
||||
var userId = await GetUser(apiKey);
|
||||
var libraries = await _unitOfWork.LibraryRepository.GetLibrariesForUserIdAsync(userId);
|
||||
|
||||
var feed = CreateFeed("All Libraries", $"{apiKey}/libraries", apiKey);
|
||||
|
||||
SetFeedId(feed, "libraries");
|
||||
foreach (var library in libraries)
|
||||
{
|
||||
feed.Entries.Add(new FeedEntry()
|
||||
|
@ -181,7 +180,7 @@ namespace API.Controllers
|
|||
|
||||
|
||||
var feed = CreateFeed("All Collections", $"{apiKey}/collections", apiKey);
|
||||
|
||||
SetFeedId(feed, "collections");
|
||||
foreach (var tag in tags)
|
||||
{
|
||||
feed.Entries.Add(new FeedEntry()
|
||||
|
@ -198,14 +197,6 @@ namespace API.Controllers
|
|||
});
|
||||
}
|
||||
|
||||
if (tags.Count == 0)
|
||||
{
|
||||
feed.Entries.Add(new FeedEntry()
|
||||
{
|
||||
Title = "Nothing here",
|
||||
});
|
||||
}
|
||||
|
||||
return CreateXmlResult(SerializeXml(feed));
|
||||
}
|
||||
|
||||
|
@ -243,6 +234,7 @@ namespace API.Controllers
|
|||
});
|
||||
|
||||
var feed = CreateFeed(tag.Title + " Collection", $"{apiKey}/collections/{collectionId}", apiKey);
|
||||
SetFeedId(feed, $"collections-{collectionId}");
|
||||
AddPagination(feed, series, $"{Prefix}{apiKey}/collections/{collectionId}");
|
||||
|
||||
foreach (var seriesDto in series)
|
||||
|
@ -269,7 +261,7 @@ namespace API.Controllers
|
|||
|
||||
|
||||
var feed = CreateFeed("All Reading Lists", $"{apiKey}/reading-list", apiKey);
|
||||
|
||||
SetFeedId(feed, "reading-list");
|
||||
foreach (var readingListDto in readingLists)
|
||||
{
|
||||
feed.Entries.Add(new FeedEntry()
|
||||
|
@ -304,6 +296,7 @@ namespace API.Controllers
|
|||
}
|
||||
|
||||
var feed = CreateFeed(readingList.Title + " Reading List", $"{apiKey}/reading-list/{readingListId}", apiKey);
|
||||
SetFeedId(feed, $"reading-list-{readingListId}");
|
||||
|
||||
var items = (await _unitOfWork.ReadingListRepository.GetReadingListItemDtosByIdAsync(readingListId, userId)).ToList();
|
||||
foreach (var item in items)
|
||||
|
@ -320,16 +313,6 @@ namespace API.Controllers
|
|||
});
|
||||
}
|
||||
|
||||
if (items.Count == 0)
|
||||
{
|
||||
feed.Entries.Add(new FeedEntry()
|
||||
{
|
||||
Title = "Nothing here",
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
|
||||
return CreateXmlResult(SerializeXml(feed));
|
||||
}
|
||||
|
||||
|
@ -355,6 +338,7 @@ namespace API.Controllers
|
|||
}, _filterDto);
|
||||
|
||||
var feed = CreateFeed(library.Name, $"{apiKey}/libraries/{libraryId}", apiKey);
|
||||
SetFeedId(feed, $"library-{library.Name}");
|
||||
AddPagination(feed, series, $"{Prefix}{apiKey}/libraries/{libraryId}");
|
||||
|
||||
foreach (var seriesDto in series)
|
||||
|
@ -379,6 +363,7 @@ namespace API.Controllers
|
|||
}, _filterDto);
|
||||
|
||||
var feed = CreateFeed("Recently Added", $"{apiKey}/recently-added", apiKey);
|
||||
SetFeedId(feed, "recently-added");
|
||||
AddPagination(feed, recentlyAdded, $"{Prefix}{apiKey}/recently-added");
|
||||
|
||||
foreach (var seriesDto in recentlyAdded)
|
||||
|
@ -386,21 +371,12 @@ namespace API.Controllers
|
|||
feed.Entries.Add(CreateSeries(seriesDto, apiKey));
|
||||
}
|
||||
|
||||
if (recentlyAdded.Count == 0)
|
||||
{
|
||||
feed.Entries.Add(new FeedEntry()
|
||||
{
|
||||
Title = "Nothing here",
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
return CreateXmlResult(SerializeXml(feed));
|
||||
}
|
||||
|
||||
[HttpGet("{apiKey}/in-progress")]
|
||||
[HttpGet("{apiKey}/on-deck")]
|
||||
[Produces("application/xml")]
|
||||
public async Task<IActionResult> GetInProgress(string apiKey, [FromQuery] int pageNumber = 1)
|
||||
public async Task<IActionResult> GetOnDeck(string apiKey, [FromQuery] int pageNumber = 1)
|
||||
{
|
||||
if (!(await _unitOfWork.SettingsRepository.GetSettingsDtoAsync()).EnableOpds)
|
||||
return BadRequest("OPDS is not enabled on this server");
|
||||
|
@ -410,29 +386,22 @@ namespace API.Controllers
|
|||
PageNumber = pageNumber,
|
||||
PageSize = 20
|
||||
};
|
||||
var results = await _unitOfWork.SeriesRepository.GetInProgress(userId, 0, userParams, _filterDto);
|
||||
var results = await _unitOfWork.SeriesRepository.GetOnDeck(userId, 0, userParams, _filterDto);
|
||||
var listResults = results.DistinctBy(s => s.Name).Skip((userParams.PageNumber - 1) * userParams.PageSize)
|
||||
.Take(userParams.PageSize).ToList();
|
||||
var pagedList = new PagedList<SeriesDto>(listResults, listResults.Count, userParams.PageNumber, userParams.PageSize);
|
||||
|
||||
Response.AddPaginationHeader(pagedList.CurrentPage, pagedList.PageSize, pagedList.TotalCount, pagedList.TotalPages);
|
||||
|
||||
var feed = CreateFeed("In Progress", $"{apiKey}/in-progress", apiKey);
|
||||
AddPagination(feed, pagedList, $"{Prefix}{apiKey}/in-progress");
|
||||
var feed = CreateFeed("On Deck", $"{apiKey}/on-deck", apiKey);
|
||||
SetFeedId(feed, "on-deck");
|
||||
AddPagination(feed, pagedList, $"{Prefix}{apiKey}/on-deck");
|
||||
|
||||
foreach (var seriesDto in pagedList)
|
||||
{
|
||||
feed.Entries.Add(CreateSeries(seriesDto, apiKey));
|
||||
}
|
||||
|
||||
if (pagedList.Count == 0)
|
||||
{
|
||||
feed.Entries.Add(new FeedEntry()
|
||||
{
|
||||
Title = "Nothing here",
|
||||
});
|
||||
}
|
||||
|
||||
return CreateXmlResult(SerializeXml(feed));
|
||||
}
|
||||
|
||||
|
@ -456,7 +425,7 @@ namespace API.Controllers
|
|||
var series = await _unitOfWork.SeriesRepository.SearchSeries(libraries.Select(l => l.Id).ToArray(), query);
|
||||
|
||||
var feed = CreateFeed(query, $"{apiKey}/series?query=" + query, apiKey);
|
||||
|
||||
SetFeedId(feed, "search-series");
|
||||
foreach (var seriesDto in series)
|
||||
{
|
||||
feed.Entries.Add(CreateSeries(seriesDto, apiKey));
|
||||
|
@ -465,6 +434,11 @@ namespace API.Controllers
|
|||
return CreateXmlResult(SerializeXml(feed));
|
||||
}
|
||||
|
||||
private static void SetFeedId(Feed feed, string id)
|
||||
{
|
||||
feed.Id = id;
|
||||
}
|
||||
|
||||
[HttpGet("{apiKey}/search")]
|
||||
[Produces("application/xml")]
|
||||
public async Task<IActionResult> GetSearchDescriptor(string apiKey)
|
||||
|
@ -498,6 +472,7 @@ namespace API.Controllers
|
|||
var series = await _unitOfWork.SeriesRepository.GetSeriesDtoByIdAsync(seriesId, userId);
|
||||
var volumes = await _unitOfWork.VolumeRepository.GetVolumesDtoAsync(seriesId, userId);
|
||||
var feed = CreateFeed(series.Name + " - Volumes", $"{apiKey}/series/{series.Id}", apiKey);
|
||||
SetFeedId(feed, $"series-{series.Id}");
|
||||
feed.Links.Add(CreateLink(FeedLinkRelation.Image, FeedLinkType.Image, $"/api/image/series-cover?seriesId={seriesId}"));
|
||||
foreach (var volumeDto in volumes)
|
||||
{
|
||||
|
@ -521,6 +496,7 @@ namespace API.Controllers
|
|||
_chapterSortComparer);
|
||||
|
||||
var feed = CreateFeed(series.Name + " - Volume " + volume.Name + " - Chapters ", $"{apiKey}/series/{seriesId}/volume/{volumeId}", apiKey);
|
||||
SetFeedId(feed, $"series-{series.Id}-volume-{volume.Id}-chapters");
|
||||
foreach (var chapter in chapters)
|
||||
{
|
||||
feed.Entries.Add(new FeedEntry()
|
||||
|
@ -551,6 +527,7 @@ namespace API.Controllers
|
|||
var files = await _unitOfWork.ChapterRepository.GetFilesForChapterAsync(chapterId);
|
||||
|
||||
var feed = CreateFeed(series.Name + " - Volume " + volume.Name + " - Chapters ", $"{apiKey}/series/{seriesId}/volume/{volumeId}/chapter/{chapterId}", apiKey);
|
||||
SetFeedId(feed, $"series-{series.Id}-volume-{volume.Id}-chapter-{chapter.Id}-files");
|
||||
foreach (var mangaFile in files)
|
||||
{
|
||||
feed.Entries.Add(CreateChapter(seriesId, volumeId, chapterId, mangaFile, series, volume, chapter, apiKey));
|
||||
|
|
|
@ -180,7 +180,7 @@ namespace API.Controllers
|
|||
|
||||
if (series == null) return BadRequest("Series does not exist");
|
||||
|
||||
if (series.Name != updateSeries.Name && await _unitOfWork.SeriesRepository.DoesSeriesNameExistInLibrary(updateSeries.Name))
|
||||
if (series.Name != updateSeries.Name && await _unitOfWork.SeriesRepository.DoesSeriesNameExistInLibrary(updateSeries.Name, series.Format))
|
||||
{
|
||||
return BadRequest("A series already exists in this library with this name. Series Names must be unique to a library.");
|
||||
}
|
||||
|
@ -230,12 +230,19 @@ namespace API.Controllers
|
|||
return Ok(series);
|
||||
}
|
||||
|
||||
[HttpPost("in-progress")]
|
||||
public async Task<ActionResult<IEnumerable<SeriesDto>>> GetInProgress(FilterDto filterDto, [FromQuery] UserParams userParams, [FromQuery] int libraryId = 0)
|
||||
/// <summary>
|
||||
/// Fetches series that are on deck aka have progress on them.
|
||||
/// </summary>
|
||||
/// <param name="filterDto"></param>
|
||||
/// <param name="userParams"></param>
|
||||
/// <param name="libraryId">Default of 0 meaning all libraries</param>
|
||||
/// <returns></returns>
|
||||
[HttpPost("on-deck")]
|
||||
public async Task<ActionResult<IEnumerable<SeriesDto>>> GetOnDeck(FilterDto filterDto, [FromQuery] UserParams userParams, [FromQuery] int libraryId = 0)
|
||||
{
|
||||
// NOTE: This has to be done manually like this due to the DistinctBy requirement
|
||||
var userId = await _unitOfWork.UserRepository.GetUserIdByUsernameAsync(User.GetUsername());
|
||||
var results = await _unitOfWork.SeriesRepository.GetInProgress(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)
|
||||
.Take(userParams.PageSize).ToList();
|
||||
|
|
|
@ -26,10 +26,11 @@ namespace API.Controllers
|
|||
private readonly IArchiveService _archiveService;
|
||||
private readonly ICacheService _cacheService;
|
||||
private readonly IVersionUpdaterService _versionUpdaterService;
|
||||
private readonly IStatsService _statsService;
|
||||
|
||||
public ServerController(IHostApplicationLifetime applicationLifetime, ILogger<ServerController> logger, IConfiguration config,
|
||||
IBackupService backupService, IArchiveService archiveService, ICacheService cacheService,
|
||||
IVersionUpdaterService versionUpdaterService)
|
||||
IVersionUpdaterService versionUpdaterService, IStatsService statsService)
|
||||
{
|
||||
_applicationLifetime = applicationLifetime;
|
||||
_logger = logger;
|
||||
|
@ -38,6 +39,7 @@ namespace API.Controllers
|
|||
_archiveService = archiveService;
|
||||
_cacheService = cacheService;
|
||||
_versionUpdaterService = versionUpdaterService;
|
||||
_statsService = statsService;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -84,9 +86,9 @@ namespace API.Controllers
|
|||
/// </summary>
|
||||
/// <returns></returns>
|
||||
[HttpGet("server-info")]
|
||||
public ActionResult<ServerInfoDto> GetVersion()
|
||||
public async Task<ActionResult<ServerInfoDto>> GetVersion()
|
||||
{
|
||||
return Ok(StatsService.GetServerInfo());
|
||||
return Ok(await _statsService.GetServerInfo());
|
||||
}
|
||||
|
||||
[HttpGet("logs")]
|
||||
|
|
|
@ -1,39 +0,0 @@
|
|||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using API.DTOs.Stats;
|
||||
using API.Interfaces.Services;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
||||
namespace API.Controllers
|
||||
{
|
||||
public class StatsController : BaseApiController
|
||||
{
|
||||
private readonly ILogger<StatsController> _logger;
|
||||
private readonly IStatsService _statsService;
|
||||
|
||||
public StatsController(ILogger<StatsController> logger, IStatsService statsService)
|
||||
{
|
||||
_logger = logger;
|
||||
_statsService = statsService;
|
||||
}
|
||||
|
||||
[AllowAnonymous]
|
||||
[HttpPost("client-info")]
|
||||
public async Task<IActionResult> AddClientInfo([FromBody] ClientInfoDto clientInfoDto)
|
||||
{
|
||||
try
|
||||
{
|
||||
await _statsService.RecordClientInfo(clientInfoDto);
|
||||
|
||||
return Ok();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.LogError(ex, "Error updating the usage statistics");
|
||||
throw;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue