Email Version availability (#2345)
This commit is contained in:
parent
d1157e90c4
commit
bcb75ed241
8 changed files with 137 additions and 39 deletions
|
|
@ -42,12 +42,13 @@ public class ServerController : BaseApiController
|
|||
private readonly IUnitOfWork _unitOfWork;
|
||||
private readonly IEasyCachingProviderFactory _cachingProviderFactory;
|
||||
private readonly ILocalizationService _localizationService;
|
||||
private readonly IEmailService _emailService;
|
||||
|
||||
public ServerController(ILogger<ServerController> logger,
|
||||
IBackupService backupService, IArchiveService archiveService, IVersionUpdaterService versionUpdaterService, IStatsService statsService,
|
||||
ICleanupService cleanupService, IScannerService scannerService, IAccountService accountService,
|
||||
ITaskScheduler taskScheduler, IUnitOfWork unitOfWork, IEasyCachingProviderFactory cachingProviderFactory,
|
||||
ILocalizationService localizationService)
|
||||
ILocalizationService localizationService, IEmailService emailService)
|
||||
{
|
||||
_logger = logger;
|
||||
_backupService = backupService;
|
||||
|
|
@ -61,6 +62,7 @@ public class ServerController : BaseApiController
|
|||
_unitOfWork = unitOfWork;
|
||||
_cachingProviderFactory = cachingProviderFactory;
|
||||
_localizationService = localizationService;
|
||||
_emailService = emailService;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
@ -270,5 +272,22 @@ public class ServerController : BaseApiController
|
|||
return Ok();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the KavitaEmail version for non-default instances
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
[Authorize("RequireAdminRole")]
|
||||
[HttpGet("email-version")]
|
||||
public async Task<ActionResult<string?>> GetEmailVersion()
|
||||
{
|
||||
var emailServiceUrl = (await _unitOfWork.SettingsRepository.GetSettingAsync(ServerSettingKey.EmailServiceUrl))
|
||||
.Value;
|
||||
|
||||
if (emailServiceUrl.Equals(EmailService.DefaultApiUrl)) return Ok(null);
|
||||
|
||||
return Ok(await _emailService.GetVersion(emailServiceUrl));
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -26,6 +26,7 @@ public interface IEmailService
|
|||
Task<EmailTestResultDto> TestConnectivity(string emailUrl, string adminEmail, bool sendEmail);
|
||||
Task<bool> IsDefaultEmailService();
|
||||
Task SendEmailChangeEmail(ConfirmationEmailDto data);
|
||||
Task<string?> GetVersion(string emailUrl);
|
||||
}
|
||||
|
||||
public class EmailService : IEmailService
|
||||
|
|
@ -94,6 +95,34 @@ public class EmailService : IEmailService
|
|||
}
|
||||
}
|
||||
|
||||
public async Task<string> GetVersion(string emailUrl)
|
||||
{
|
||||
try
|
||||
{
|
||||
var settings = await _unitOfWork.SettingsRepository.GetSettingsDtoAsync();
|
||||
var response = await $"{emailUrl}/api/about/version"
|
||||
.WithHeader("Accept", "application/json")
|
||||
.WithHeader("User-Agent", "Kavita")
|
||||
.WithHeader("x-api-key", "MsnvA2DfQqxSK5jh")
|
||||
.WithHeader("x-kavita-version", BuildInfo.Version)
|
||||
.WithHeader("x-kavita-installId", settings.InstallId)
|
||||
.WithHeader("Content-Type", "application/json")
|
||||
.WithTimeout(TimeSpan.FromSeconds(10))
|
||||
.GetStringAsync();
|
||||
|
||||
if (!string.IsNullOrEmpty(response))
|
||||
{
|
||||
return response.Replace("\"", string.Empty);
|
||||
}
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public async Task SendConfirmationEmail(ConfirmationEmailDto data)
|
||||
{
|
||||
var emailLink = (await _unitOfWork.SettingsRepository.GetSettingAsync(ServerSettingKey.EmailServiceUrl)).Value;
|
||||
|
|
|
|||
|
|
@ -651,9 +651,10 @@ public class SeriesService : ISeriesService
|
|||
{
|
||||
var series = await _unitOfWork.SeriesRepository.GetSeriesByIdAsync(seriesId, SeriesIncludes.Metadata | SeriesIncludes.Library);
|
||||
if (series == null) throw new KavitaException(await _localizationService.Translate(userId, "series-doesnt-exist"));
|
||||
var libraryIds = _unitOfWork.LibraryRepository.GetLibraryIdsForUserIdAsync(userId);
|
||||
if (!libraryIds.Contains(series.LibraryId)) //// TODO: Rewrite this to use a new method which checks permissions all in the DB to be streamlined and less memory
|
||||
if (!(await _unitOfWork.UserRepository.HasAccessToSeries(userId, seriesId)))
|
||||
{
|
||||
throw new UnauthorizedAccessException("user-no-access-library-from-series");
|
||||
}
|
||||
if (series?.Metadata.PublicationStatus is not (PublicationStatus.OnGoing or PublicationStatus.Ended) || series.Library.Type == LibraryType.Book)
|
||||
{
|
||||
return new NextExpectedChapterDto()
|
||||
|
|
@ -670,18 +671,32 @@ public class SeriesService : ISeriesService
|
|||
.ToList();
|
||||
|
||||
// Calculate the time differences between consecutive chapters
|
||||
var timeDifferences = chapters
|
||||
.Select((chapter, index) => new
|
||||
// var timeDifferences = chapters
|
||||
// .Select((chapter, index) => new
|
||||
// {
|
||||
// ChapterNumber = chapter.Number,
|
||||
// VolumeNumber = chapter.Volume.Number,
|
||||
// TimeDifference = index == 0 ? TimeSpan.Zero : (chapter.CreatedUtc - chapters.ElementAt(index - 1).CreatedUtc)
|
||||
// })
|
||||
// .ToList();
|
||||
// Quantize time differences: Chapters created within an hour from each other will be treated as one time delta
|
||||
var timeDifferences = new List<TimeSpan>();
|
||||
DateTime? previousChapterTime = null;
|
||||
foreach (var chapter in chapters)
|
||||
{
|
||||
if (previousChapterTime.HasValue && (chapter.CreatedUtc - previousChapterTime.Value) <= TimeSpan.FromHours(1))
|
||||
{
|
||||
ChapterNumber = chapter.Number,
|
||||
VolumeNumber = chapter.Volume.Number,
|
||||
TimeDifference = index == 0 ? TimeSpan.Zero : (chapter.CreatedUtc - chapters.ElementAt(index - 1).CreatedUtc)
|
||||
})
|
||||
.ToList();
|
||||
continue; // Skip this chapter if it's within an hour of the previous one
|
||||
}
|
||||
timeDifferences.Add(chapter.CreatedUtc - previousChapterTime ?? TimeSpan.Zero);
|
||||
previousChapterTime = chapter.CreatedUtc;
|
||||
}
|
||||
|
||||
// Calculate the average time difference between chapters
|
||||
// var averageTimeDifference = timeDifferences
|
||||
// .Average(td => td.TimeDifference.TotalDays);
|
||||
var averageTimeDifference = timeDifferences
|
||||
.Average(td => td.TimeDifference.TotalDays);
|
||||
.Average(td => td.TotalDays);
|
||||
|
||||
// Calculate the forecast for when the next chapter is expected
|
||||
var nextChapterExpected = chapters.Any()
|
||||
|
|
@ -693,8 +708,8 @@ public class SeriesService : ISeriesService
|
|||
nextChapterExpected = DateTime.UtcNow + TimeSpan.FromDays(averageTimeDifference);
|
||||
}
|
||||
|
||||
var lastChapter = timeDifferences.Last();
|
||||
float.TryParse(lastChapter.ChapterNumber, NumberStyles.Number, CultureInfo.InvariantCulture,
|
||||
var lastChapter = chapters.Last();
|
||||
float.TryParse(lastChapter.Number, NumberStyles.Number, CultureInfo.InvariantCulture,
|
||||
out var lastChapterNumber);
|
||||
|
||||
var result = new NextExpectedChapterDto()
|
||||
|
|
@ -708,7 +723,7 @@ public class SeriesService : ISeriesService
|
|||
if (lastChapterNumber > 0)
|
||||
{
|
||||
result.ChapterNumber = lastChapterNumber + 1;
|
||||
result.VolumeNumber = lastChapter.VolumeNumber;
|
||||
result.VolumeNumber = lastChapter.Volume.Number;
|
||||
result.Title = series.Library.Type switch
|
||||
{
|
||||
LibraryType.Manga => await _localizationService.Translate(userId, "chapter-num",
|
||||
|
|
@ -722,8 +737,8 @@ public class SeriesService : ISeriesService
|
|||
}
|
||||
else
|
||||
{
|
||||
result.VolumeNumber = lastChapter.VolumeNumber + 1;
|
||||
result.Title = await _localizationService.Translate(userId, "vol-num",
|
||||
result.VolumeNumber = lastChapter.Volume.Number + 1;
|
||||
result.Title = await _localizationService.Translate(userId, "volume-num",
|
||||
new object[] {result.VolumeNumber});
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -238,21 +238,8 @@ public class Startup
|
|||
|
||||
logger.LogInformation("Running Migrations");
|
||||
|
||||
// v0.7.2
|
||||
await MigrateLoginRoles.Migrate(unitOfWork, userManager, logger);
|
||||
|
||||
// v0.7.3
|
||||
await MigrateRemoveWebPSettingRows.Migrate(unitOfWork, logger);
|
||||
|
||||
// v0.7.4
|
||||
await MigrateDisableScrobblingOnComicLibraries.Migrate(unitOfWork, dataContext, logger);
|
||||
|
||||
// v0.7.6
|
||||
await MigrateExistingRatings.Migrate(dataContext, logger);
|
||||
|
||||
// v0.7.9
|
||||
await MigrateUserLibrarySideNavStream.Migrate(unitOfWork, dataContext, logger);
|
||||
await MigrateDashboardStreamNamesToLocaleKeys.Migrate(unitOfWork, dataContext, logger);
|
||||
|
||||
// Update the version in the DB after all migrations are run
|
||||
var installVersion = await unitOfWork.SettingsRepository.GetSettingAsync(ServerSettingKey.InstallVersion);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue