Fix auto refresh dates calculation (#479)

This commit is contained in:
Zoe Roux 2024-05-06 20:20:38 +02:00 committed by GitHub
commit 6c880b0909
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
10 changed files with 1451 additions and 27 deletions

View File

@ -27,16 +27,13 @@ public interface IRefreshable
/// </summary> /// </summary>
public DateTime? NextMetadataRefresh { get; set; } public DateTime? NextMetadataRefresh { get; set; }
public static DateTime ComputeNextRefreshDate(DateOnly? airDate) public static DateTime ComputeNextRefreshDate(DateOnly airDate)
{ {
if (airDate is null) int days = DateOnly.FromDateTime(DateTime.UtcNow).DayNumber - airDate.DayNumber;
return DateTime.UtcNow.AddDays(1);
int days = airDate.Value.DayNumber - DateOnly.FromDateTime(DateTime.UtcNow).DayNumber;
return days switch return days switch
{ {
<= 7 => DateTime.UtcNow.AddDays(1), <= 4 => DateTime.UtcNow.AddDays(1),
<= 21 => DateTime.UtcNow.AddDays(5), <= 21 => DateTime.UtcNow.AddDays(14),
_ => DateTime.UtcNow.AddMonths(2) _ => DateTime.UtcNow.AddMonths(2)
}; };
} }

View File

@ -92,7 +92,9 @@ public class EpisodeRepository(
.FirstOrDefaultAsync(); .FirstOrDefaultAsync();
} }
resource.NextMetadataRefresh ??= IRefreshable.ComputeNextRefreshDate(resource.ReleaseDate); resource.NextMetadataRefresh ??= IRefreshable.ComputeNextRefreshDate(
resource.ReleaseDate ?? DateOnly.FromDateTime(resource.AddedDate)
);
await thumbnails.DownloadImages(resource); await thumbnails.DownloadImages(resource);
} }

View File

@ -16,6 +16,7 @@
// You should have received a copy of the GNU General Public License // You should have received a copy of the GNU General Public License
// along with Kyoo. If not, see <https://www.gnu.org/licenses/>. // along with Kyoo. If not, see <https://www.gnu.org/licenses/>.
using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Threading.Tasks; using System.Threading.Tasks;
@ -74,7 +75,9 @@ public class MovieRepository(
resource.StudioId = (await studios.CreateIfNotExists(resource.Studio)).Id; resource.StudioId = (await studios.CreateIfNotExists(resource.Studio)).Id;
resource.Studio = null; resource.Studio = null;
} }
resource.NextMetadataRefresh ??= IRefreshable.ComputeNextRefreshDate(resource.AirDate); resource.NextMetadataRefresh ??= IRefreshable.ComputeNextRefreshDate(
resource.AirDate ?? DateOnly.FromDateTime(resource.AddedDate)
);
await thumbnails.DownloadImages(resource); await thumbnails.DownloadImages(resource);
} }
} }

View File

@ -77,7 +77,9 @@ public class SeasonRepository(
throw new ValidationException("Missing show id"); throw new ValidationException("Missing show id");
// This is storred in db so it needs to be set before every create/edit (and before events) // This is storred in db so it needs to be set before every create/edit (and before events)
resource.ShowSlug = (await shows.Get(resource.ShowId)).Slug; resource.ShowSlug = (await shows.Get(resource.ShowId)).Slug;
resource.NextMetadataRefresh ??= IRefreshable.ComputeNextRefreshDate(resource.StartDate); resource.NextMetadataRefresh ??= IRefreshable.ComputeNextRefreshDate(
resource.StartDate ?? DateOnly.FromDateTime(resource.AddedDate)
);
await thumbnails.DownloadImages(resource); await thumbnails.DownloadImages(resource);
} }
} }

View File

@ -16,6 +16,7 @@
// You should have received a copy of the GNU General Public License // You should have received a copy of the GNU General Public License
// along with Kyoo. If not, see <https://www.gnu.org/licenses/>. // along with Kyoo. If not, see <https://www.gnu.org/licenses/>.
using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Threading.Tasks; using System.Threading.Tasks;
@ -74,7 +75,9 @@ public class ShowRepository(
resource.StudioId = (await studios.CreateIfNotExists(resource.Studio)).Id; resource.StudioId = (await studios.CreateIfNotExists(resource.Studio)).Id;
resource.Studio = null; resource.Studio = null;
} }
resource.NextMetadataRefresh ??= IRefreshable.ComputeNextRefreshDate(resource.StartAir); resource.NextMetadataRefresh ??= IRefreshable.ComputeNextRefreshDate(
resource.StartAir ?? DateOnly.FromDateTime(resource.AddedDate)
);
await thumbnails.DownloadImages(resource); await thumbnails.DownloadImages(resource);
} }
} }

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,33 @@
using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable
namespace Kyoo.Postgresql.Migrations
{
/// <inheritdoc />
public partial class FixSeasonMetadataId : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
// language=PostgreSQL
migrationBuilder.Sql(
"""
update seasons as s set external_id = (
SELECT jsonb_build_object(
'themoviedatabase', jsonb_build_object(
'DataId', sh.external_id->'themoviedatabase'->'DataId',
'Link', s.external_id->'themoviedatabase'->'Link'
)
)
FROM shows AS sh
WHERE sh.id = s.show_id
);
"""
);
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder) { }
}
}

View File

@ -377,7 +377,7 @@ class TheMovieDatabase(Provider):
end_air=None, end_air=None,
external_id={ external_id={
self.name: MetadataID( self.name: MetadataID(
season["id"], show_id,
f"https://www.themoviedb.org/tv/{show_id}/season/{season['season_number']}", f"https://www.themoviedb.org/tv/{show_id}/season/{season['season_number']}",
) )
}, },

View File

@ -1,6 +1,7 @@
package src package src
import ( import (
"cmp"
"fmt" "fmt"
"strings" "strings"
@ -14,7 +15,7 @@ import (
// //
// this code is addapted from https://github.com/jellyfin/jellyfin/blob/master/Jellyfin.Api/Helpers/HlsCodecStringHelpers.cs // this code is addapted from https://github.com/jellyfin/jellyfin/blob/master/Jellyfin.Api/Helpers/HlsCodecStringHelpers.cs
func GetMimeCodec(mi *mediainfo.File, kind mediainfo.StreamKind, i int) *string { func GetMimeCodec(mi *mediainfo.File, kind mediainfo.StreamKind, i int) *string {
codec := Or( codec := cmp.Or(
mi.Parameter(kind, i, "InternetMediaType"), mi.Parameter(kind, i, "InternetMediaType"),
mi.Parameter(kind, i, "Format"), mi.Parameter(kind, i, "Format"),
) )

View File

@ -1,6 +1,7 @@
package src package src
import ( import (
"cmp"
"encoding/base64" "encoding/base64"
"encoding/json" "encoding/json"
"fmt" "fmt"
@ -140,19 +141,6 @@ func ParseTime(str string) float32 {
return (hours*60.+minutes)*60. + seconds + ms/1000. return (hours*60.+minutes)*60. + seconds + ms/1000.
} }
// Stolen from the cmp.Or code that is not yet released
// Or returns the first of its arguments that is not equal to the zero value.
// If no argument is non-zero, it returns the zero value.
func Or[T comparable](vals ...T) T {
var zero T
for _, val := range vals {
if val != zero {
return val
}
}
return zero
}
func Map[T, U any](ts []T, f func(T, int) U) []U { func Map[T, U any](ts []T, f func(T, int) U) []U {
us := make([]U, len(ts)) us := make([]U, len(ts))
for i := range ts { for i := range ts {
@ -268,7 +256,7 @@ func getInfo(path string) (*MediaInfo, error) {
Width: ParseUint(mi.Parameter(mediainfo.StreamVideo, i, "Width")), Width: ParseUint(mi.Parameter(mediainfo.StreamVideo, i, "Width")),
Height: ParseUint(mi.Parameter(mediainfo.StreamVideo, i, "Height")), Height: ParseUint(mi.Parameter(mediainfo.StreamVideo, i, "Height")),
Bitrate: ParseUint( Bitrate: ParseUint(
Or( cmp.Or(
mi.Parameter(mediainfo.StreamVideo, i, "BitRate"), mi.Parameter(mediainfo.StreamVideo, i, "BitRate"),
mi.Parameter(mediainfo.StreamVideo, i, "OverallBitRate"), mi.Parameter(mediainfo.StreamVideo, i, "OverallBitRate"),
mi.Parameter(mediainfo.StreamVideo, i, "BitRate_Nominal"), mi.Parameter(mediainfo.StreamVideo, i, "BitRate_Nominal"),