aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.github/workflows/ci-codeql-analysis.yml6
-rw-r--r--.github/workflows/ci-openapi.yml8
-rw-r--r--.github/workflows/ci-tests.yml12
-rw-r--r--Emby.Server.Implementations/Images/CollectionFolderImageProvider.cs18
-rw-r--r--Emby.Server.Implementations/Images/DynamicImageProvider.cs8
-rw-r--r--Emby.Server.Implementations/Library/LibraryManager.cs4
-rw-r--r--Emby.Server.Implementations/Library/Resolvers/Audio/AudioResolver.cs6
-rw-r--r--Emby.Server.Implementations/Library/Resolvers/Audio/MusicAlbumResolver.cs2
-rw-r--r--Emby.Server.Implementations/Library/Resolvers/Audio/MusicArtistResolver.cs2
-rw-r--r--Emby.Server.Implementations/Library/Resolvers/Books/BookResolver.cs2
-rw-r--r--Emby.Server.Implementations/Library/Resolvers/Movies/MovieResolver.cs34
-rw-r--r--Emby.Server.Implementations/Library/Resolvers/PhotoAlbumResolver.cs4
-rw-r--r--Emby.Server.Implementations/Library/Resolvers/PhotoResolver.cs4
-rw-r--r--Emby.Server.Implementations/Library/Resolvers/PlaylistResolver.cs2
-rw-r--r--Emby.Server.Implementations/Library/Resolvers/TV/EpisodeResolver.cs2
-rw-r--r--Emby.Server.Implementations/Library/Resolvers/TV/SeriesResolver.cs4
-rw-r--r--Emby.Server.Implementations/Library/UserDataManager.cs47
-rw-r--r--Emby.Server.Implementations/Library/UserViewManager.cs22
-rw-r--r--Emby.Server.Implementations/LiveTv/LiveTvManager.cs2
-rw-r--r--Emby.Server.Implementations/Localization/Core/ab.json1
-rw-r--r--Emby.Server.Implementations/Localization/Core/fil.json3
-rw-r--r--Emby.Server.Implementations/Localization/Core/nb.json4
-rw-r--r--Emby.Server.Implementations/Localization/Core/tr.json2
-rw-r--r--Emby.Server.Implementations/Playlists/PlaylistsFolder.cs2
-rw-r--r--Jellyfin.Api/Controllers/GenresController.cs4
-rw-r--r--Jellyfin.Api/Controllers/ItemUpdateController.cs2
-rw-r--r--Jellyfin.Api/Controllers/ItemsController.cs68
-rw-r--r--Jellyfin.Api/Controllers/LibraryController.cs18
-rw-r--r--Jellyfin.Data/Enums/CollectionType.cs57
-rw-r--r--Jellyfin.Server.Implementations/Devices/DeviceManager.cs25
-rw-r--r--MediaBrowser.Controller/Entities/BaseItem.cs2
-rw-r--r--MediaBrowser.Controller/Entities/UserView.cs18
-rw-r--r--MediaBrowser.Controller/Entities/UserViewBuilder.cs68
-rw-r--r--MediaBrowser.Controller/Library/IUserDataManager.cs9
-rw-r--r--MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs26
-rw-r--r--MediaBrowser.Model/Devices/DeviceInfo.cs2
-rw-r--r--MediaBrowser.Model/Dto/UpdateUserItemDataDto.cs76
-rw-r--r--MediaBrowser.Model/Entities/UserDataSaveReason.cs7
-rw-r--r--tests/Jellyfin.Server.Implementations.Tests/Library/AudioResolverTests.cs2
-rw-r--r--tests/Jellyfin.Server.Implementations.Tests/Library/EpisodeResolverTest.cs4
40 files changed, 396 insertions, 193 deletions
diff --git a/.github/workflows/ci-codeql-analysis.yml b/.github/workflows/ci-codeql-analysis.yml
index b35a79efc..89f9c59d7 100644
--- a/.github/workflows/ci-codeql-analysis.yml
+++ b/.github/workflows/ci-codeql-analysis.yml
@@ -27,11 +27,11 @@ jobs:
dotnet-version: '8.0.x'
- name: Initialize CodeQL
- uses: github/codeql-action/init@c0d1daa7f7e14667747d73a7dbbe8c074bc8bfe2 # v2.22.9
+ uses: github/codeql-action/init@b374143c1149a9115d881581d29b8390bbcbb59c # v3.22.11
with:
languages: ${{ matrix.language }}
queries: +security-extended
- name: Autobuild
- uses: github/codeql-action/autobuild@c0d1daa7f7e14667747d73a7dbbe8c074bc8bfe2 # v2.22.9
+ uses: github/codeql-action/autobuild@b374143c1149a9115d881581d29b8390bbcbb59c # v3.22.11
- name: Perform CodeQL Analysis
- uses: github/codeql-action/analyze@c0d1daa7f7e14667747d73a7dbbe8c074bc8bfe2 # v2.22.9
+ uses: github/codeql-action/analyze@b374143c1149a9115d881581d29b8390bbcbb59c # v3.22.11
diff --git a/.github/workflows/ci-openapi.yml b/.github/workflows/ci-openapi.yml
index 7d6667794..5ff9820cb 100644
--- a/.github/workflows/ci-openapi.yml
+++ b/.github/workflows/ci-openapi.yml
@@ -25,7 +25,7 @@ jobs:
- name: Generate openapi.json
run: dotnet test tests/Jellyfin.Server.Integration.Tests/Jellyfin.Server.Integration.Tests.csproj -c Release --filter "Jellyfin.Server.Integration.Tests.OpenApiSpecTests"
- name: Upload openapi.json
- uses: actions/upload-artifact@a8a3f3ad30e3422c9c7b888a15615d19a852ae32 # v3.1.3
+ uses: actions/upload-artifact@c7d193f32edcb7bfad88892161225aeda64e9392 # v4.0.0
with:
name: openapi-head
retention-days: 14
@@ -59,7 +59,7 @@ jobs:
- name: Generate openapi.json
run: dotnet test tests/Jellyfin.Server.Integration.Tests/Jellyfin.Server.Integration.Tests.csproj -c Release --filter "Jellyfin.Server.Integration.Tests.OpenApiSpecTests"
- name: Upload openapi.json
- uses: actions/upload-artifact@a8a3f3ad30e3422c9c7b888a15615d19a852ae32 # v3.1.3
+ uses: actions/upload-artifact@c7d193f32edcb7bfad88892161225aeda64e9392 # v4.0.0
with:
name: openapi-base
retention-days: 14
@@ -78,12 +78,12 @@ jobs:
- openapi-base
steps:
- name: Download openapi-head
- uses: actions/download-artifact@9bc31d5ccc31df68ecc42ccf4149144866c47d8a # v3.0.2
+ uses: actions/download-artifact@7a1cd3216ca9260cd8022db641d960b1db4d1be4 # v4.0.0
with:
name: openapi-head
path: openapi-head
- name: Download openapi-base
- uses: actions/download-artifact@9bc31d5ccc31df68ecc42ccf4149144866c47d8a # v3.0.2
+ uses: actions/download-artifact@7a1cd3216ca9260cd8022db641d960b1db4d1be4 # v4.0.0
with:
name: openapi-base
path: openapi-base
diff --git a/.github/workflows/ci-tests.yml b/.github/workflows/ci-tests.yml
index 5a0125f5f..0dacbc5c6 100644
--- a/.github/workflows/ci-tests.yml
+++ b/.github/workflows/ci-tests.yml
@@ -19,9 +19,9 @@ jobs:
runs-on: "${{ matrix.os }}"
steps:
- - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4
+ - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
- - uses: actions/setup-dotnet@4d6c8fcf3c8f7a60068d26b594648e99df24cee3 # v4
+ - uses: actions/setup-dotnet@4d6c8fcf3c8f7a60068d26b594648e99df24cee3 # v4.0.0
with:
dotnet-version: ${{ env.SDK_VERSION }}
@@ -34,7 +34,7 @@ jobs:
--verbosity minimal
- name: Merge code coverage results
- uses: danielpalme/ReportGenerator-GitHub-Action@4d510cbed8a05af5aefea46c7fd6e05b95844c89 # 5
+ uses: danielpalme/ReportGenerator-GitHub-Action@4d510cbed8a05af5aefea46c7fd6e05b95844c89 # 5.2.0
with:
reports: "**/coverage.cobertura.xml"
targetdir: "merged/"
@@ -42,9 +42,3 @@ jobs:
# TODO - which action / tool to use to publish code coverage results?
# - name: Publish code coverage results
-
- - name: Publish OpenAPI Artifact
- uses: actions/upload-artifact@a8a3f3ad30e3422c9c7b888a15615d19a852ae32 # v3
- with:
- name: "OpenAPI Spec"
- path: "tests/Jellyfin.Server.Integration.Tests/bin/Release/net*/openapi.json"
diff --git a/Emby.Server.Implementations/Images/CollectionFolderImageProvider.cs b/Emby.Server.Implementations/Images/CollectionFolderImageProvider.cs
index 6e8f77977..34c722e41 100644
--- a/Emby.Server.Implementations/Images/CollectionFolderImageProvider.cs
+++ b/Emby.Server.Implementations/Images/CollectionFolderImageProvider.cs
@@ -32,26 +32,26 @@ namespace Emby.Server.Implementations.Images
switch (viewType)
{
- case CollectionType.Movies:
+ case CollectionType.movies:
includeItemTypes = new[] { BaseItemKind.Movie };
break;
- case CollectionType.TvShows:
+ case CollectionType.tvshows:
includeItemTypes = new[] { BaseItemKind.Series };
break;
- case CollectionType.Music:
+ case CollectionType.music:
includeItemTypes = new[] { BaseItemKind.MusicAlbum };
break;
- case CollectionType.MusicVideos:
+ case CollectionType.musicvideos:
includeItemTypes = new[] { BaseItemKind.MusicVideo };
break;
- case CollectionType.Books:
+ case CollectionType.books:
includeItemTypes = new[] { BaseItemKind.Book, BaseItemKind.AudioBook };
break;
- case CollectionType.BoxSets:
+ case CollectionType.boxsets:
includeItemTypes = new[] { BaseItemKind.BoxSet };
break;
- case CollectionType.HomeVideos:
- case CollectionType.Photos:
+ case CollectionType.homevideos:
+ case CollectionType.photos:
includeItemTypes = new[] { BaseItemKind.Video, BaseItemKind.Photo };
break;
default:
@@ -59,7 +59,7 @@ namespace Emby.Server.Implementations.Images
break;
}
- var recursive = viewType != CollectionType.Playlists;
+ var recursive = viewType != CollectionType.playlists;
return view.GetItemList(new InternalItemsQuery
{
diff --git a/Emby.Server.Implementations/Images/DynamicImageProvider.cs b/Emby.Server.Implementations/Images/DynamicImageProvider.cs
index 5de53df73..6b2ae23b3 100644
--- a/Emby.Server.Implementations/Images/DynamicImageProvider.cs
+++ b/Emby.Server.Implementations/Images/DynamicImageProvider.cs
@@ -36,7 +36,7 @@ namespace Emby.Server.Implementations.Images
var view = (UserView)item;
var isUsingCollectionStrip = IsUsingCollectionStrip(view);
- var recursive = isUsingCollectionStrip && view?.ViewType is not null && view.ViewType != CollectionType.BoxSets && view.ViewType != CollectionType.Playlists;
+ var recursive = isUsingCollectionStrip && view?.ViewType is not null && view.ViewType != CollectionType.boxsets && view.ViewType != CollectionType.playlists;
var result = view.GetItemList(new InternalItemsQuery
{
@@ -114,9 +114,9 @@ namespace Emby.Server.Implementations.Images
{
CollectionType[] collectionStripViewTypes =
{
- CollectionType.Movies,
- CollectionType.TvShows,
- CollectionType.Playlists
+ CollectionType.movies,
+ CollectionType.tvshows,
+ CollectionType.playlists
};
return view?.ViewType is not null && collectionStripViewTypes.Contains(view.ViewType.Value);
diff --git a/Emby.Server.Implementations/Library/LibraryManager.cs b/Emby.Server.Implementations/Library/LibraryManager.cs
index f40177fa7..a79ffd9cb 100644
--- a/Emby.Server.Implementations/Library/LibraryManager.cs
+++ b/Emby.Server.Implementations/Library/LibraryManager.cs
@@ -1514,7 +1514,7 @@ namespace Emby.Server.Implementations.Library
{
if (item is UserView view)
{
- if (view.ViewType == CollectionType.LiveTv)
+ if (view.ViewType == CollectionType.livetv)
{
return new[] { view.Id };
}
@@ -1543,7 +1543,7 @@ namespace Emby.Server.Implementations.Library
}
// Handle grouping
- if (user is not null && view.ViewType != CollectionType.Unknown && UserView.IsEligibleForGrouping(view.ViewType)
+ if (user is not null && view.ViewType != CollectionType.unknown && UserView.IsEligibleForGrouping(view.ViewType)
&& user.GetPreference(PreferenceKind.GroupedFolders).Length > 0)
{
return GetUserRootFolder()
diff --git a/Emby.Server.Implementations/Library/Resolvers/Audio/AudioResolver.cs b/Emby.Server.Implementations/Library/Resolvers/Audio/AudioResolver.cs
index ac423ed09..dbf05c1db 100644
--- a/Emby.Server.Implementations/Library/Resolvers/Audio/AudioResolver.cs
+++ b/Emby.Server.Implementations/Library/Resolvers/Audio/AudioResolver.cs
@@ -61,7 +61,7 @@ namespace Emby.Server.Implementations.Library.Resolvers.Audio
List<FileSystemMetadata> files,
CollectionType? collectionType)
{
- if (collectionType == CollectionType.Books)
+ if (collectionType == CollectionType.books)
{
return ResolveMultipleAudio(parent, files, true);
}
@@ -80,7 +80,7 @@ namespace Emby.Server.Implementations.Library.Resolvers.Audio
var collectionType = args.GetCollectionType();
- var isBooksCollectionType = collectionType == CollectionType.Books;
+ var isBooksCollectionType = collectionType == CollectionType.books;
if (args.IsDirectory)
{
@@ -112,7 +112,7 @@ namespace Emby.Server.Implementations.Library.Resolvers.Audio
MediaBrowser.Controller.Entities.Audio.Audio item = null;
- var isMusicCollectionType = collectionType == CollectionType.Music;
+ var isMusicCollectionType = collectionType == CollectionType.music;
// Use regular audio type for mixed libraries, owned items and music
if (isMixedCollectionType ||
diff --git a/Emby.Server.Implementations/Library/Resolvers/Audio/MusicAlbumResolver.cs b/Emby.Server.Implementations/Library/Resolvers/Audio/MusicAlbumResolver.cs
index 06e292f4c..0bfb7fbe6 100644
--- a/Emby.Server.Implementations/Library/Resolvers/Audio/MusicAlbumResolver.cs
+++ b/Emby.Server.Implementations/Library/Resolvers/Audio/MusicAlbumResolver.cs
@@ -55,7 +55,7 @@ namespace Emby.Server.Implementations.Library.Resolvers.Audio
protected override MusicAlbum Resolve(ItemResolveArgs args)
{
var collectionType = args.GetCollectionType();
- var isMusicMediaFolder = collectionType == CollectionType.Music;
+ var isMusicMediaFolder = collectionType == CollectionType.music;
// If there's a collection type and it's not music, don't allow it.
if (!isMusicMediaFolder)
diff --git a/Emby.Server.Implementations/Library/Resolvers/Audio/MusicArtistResolver.cs b/Emby.Server.Implementations/Library/Resolvers/Audio/MusicArtistResolver.cs
index 7d6f97b12..1bdae7f62 100644
--- a/Emby.Server.Implementations/Library/Resolvers/Audio/MusicArtistResolver.cs
+++ b/Emby.Server.Implementations/Library/Resolvers/Audio/MusicArtistResolver.cs
@@ -65,7 +65,7 @@ namespace Emby.Server.Implementations.Library.Resolvers.Audio
var collectionType = args.GetCollectionType();
- var isMusicMediaFolder = collectionType == CollectionType.Music;
+ var isMusicMediaFolder = collectionType == CollectionType.music;
// If there's a collection type and it's not music, it can't be a music artist
if (!isMusicMediaFolder)
diff --git a/Emby.Server.Implementations/Library/Resolvers/Books/BookResolver.cs b/Emby.Server.Implementations/Library/Resolvers/Books/BookResolver.cs
index b76bfe427..464a548ab 100644
--- a/Emby.Server.Implementations/Library/Resolvers/Books/BookResolver.cs
+++ b/Emby.Server.Implementations/Library/Resolvers/Books/BookResolver.cs
@@ -23,7 +23,7 @@ namespace Emby.Server.Implementations.Library.Resolvers.Books
var collectionType = args.GetCollectionType();
// Only process items that are in a collection folder containing books
- if (collectionType != CollectionType.Books)
+ if (collectionType != CollectionType.books)
{
return null;
}
diff --git a/Emby.Server.Implementations/Library/Resolvers/Movies/MovieResolver.cs b/Emby.Server.Implementations/Library/Resolvers/Movies/MovieResolver.cs
index 50fd8b877..1a210e3cc 100644
--- a/Emby.Server.Implementations/Library/Resolvers/Movies/MovieResolver.cs
+++ b/Emby.Server.Implementations/Library/Resolvers/Movies/MovieResolver.cs
@@ -31,11 +31,11 @@ namespace Emby.Server.Implementations.Library.Resolvers.Movies
private static readonly CollectionType[] _validCollectionTypes = new[]
{
- CollectionType.Movies,
- CollectionType.HomeVideos,
- CollectionType.MusicVideos,
- CollectionType.TvShows,
- CollectionType.Photos
+ CollectionType.movies,
+ CollectionType.homevideos,
+ CollectionType.musicvideos,
+ CollectionType.tvshows,
+ CollectionType.photos
};
/// <summary>
@@ -100,12 +100,12 @@ namespace Emby.Server.Implementations.Library.Resolvers.Movies
Video movie = null;
var files = args.GetActualFileSystemChildren().ToList();
- if (collectionType == CollectionType.MusicVideos)
+ if (collectionType == CollectionType.musicvideos)
{
movie = FindMovie<MusicVideo>(args, args.Path, args.Parent, files, DirectoryService, collectionType, false);
}
- if (collectionType == CollectionType.HomeVideos)
+ if (collectionType == CollectionType.homevideos)
{
movie = FindMovie<Video>(args, args.Path, args.Parent, files, DirectoryService, collectionType, false);
}
@@ -126,7 +126,7 @@ namespace Emby.Server.Implementations.Library.Resolvers.Movies
movie = FindMovie<Movie>(args, args.Path, args.Parent, files, DirectoryService, collectionType, true);
}
- if (collectionType == CollectionType.Movies)
+ if (collectionType == CollectionType.movies)
{
movie = FindMovie<Movie>(args, args.Path, args.Parent, files, DirectoryService, collectionType, true);
}
@@ -147,17 +147,17 @@ namespace Emby.Server.Implementations.Library.Resolvers.Movies
Video item = null;
- if (collectionType == CollectionType.MusicVideos)
+ if (collectionType == CollectionType.musicvideos)
{
item = ResolveVideo<MusicVideo>(args, false);
}
// To find a movie file, the collection type must be movies or boxsets
- else if (collectionType == CollectionType.Movies)
+ else if (collectionType == CollectionType.movies)
{
item = ResolveVideo<Movie>(args, true);
}
- else if (collectionType == CollectionType.HomeVideos || collectionType == CollectionType.Photos)
+ else if (collectionType == CollectionType.homevideos || collectionType == CollectionType.photos)
{
item = ResolveVideo<Video>(args, false);
}
@@ -195,12 +195,12 @@ namespace Emby.Server.Implementations.Library.Resolvers.Movies
return null;
}
- if (collectionType is CollectionType.MusicVideos)
+ if (collectionType is CollectionType.musicvideos)
{
return ResolveVideos<MusicVideo>(parent, files, true, collectionType, false);
}
- if (collectionType == CollectionType.HomeVideos || collectionType == CollectionType.Photos)
+ if (collectionType == CollectionType.homevideos || collectionType == CollectionType.photos)
{
return ResolveVideos<Video>(parent, files, false, collectionType, false);
}
@@ -221,12 +221,12 @@ namespace Emby.Server.Implementations.Library.Resolvers.Movies
return ResolveVideos<Movie>(parent, files, false, collectionType, true);
}
- if (collectionType == CollectionType.Movies)
+ if (collectionType == CollectionType.movies)
{
return ResolveVideos<Movie>(parent, files, true, collectionType, true);
}
- if (collectionType == CollectionType.TvShows)
+ if (collectionType == CollectionType.tvshows)
{
return ResolveVideos<Episode>(parent, files, false, collectionType, true);
}
@@ -403,7 +403,7 @@ namespace Emby.Server.Implementations.Library.Resolvers.Movies
var multiDiscFolders = new List<FileSystemMetadata>();
var libraryOptions = args.LibraryOptions;
- var supportPhotos = collectionType == CollectionType.HomeVideos && libraryOptions.EnablePhotos;
+ var supportPhotos = collectionType == CollectionType.homevideos && libraryOptions.EnablePhotos;
var photos = new List<FileSystemMetadata>();
// Search for a folder rip
@@ -459,7 +459,7 @@ namespace Emby.Server.Implementations.Library.Resolvers.Movies
var result = ResolveVideos<T>(parent, fileSystemEntries, SupportsMultiVersion, collectionType, parseName) ??
new MultiItemResolverResult();
- var isPhotosCollection = collectionType == CollectionType.HomeVideos || collectionType == CollectionType.Photos;
+ var isPhotosCollection = collectionType == CollectionType.homevideos || collectionType == CollectionType.photos;
if (!isPhotosCollection && result.Items.Count == 1)
{
var videoPath = result.Items[0].Path;
diff --git a/Emby.Server.Implementations/Library/Resolvers/PhotoAlbumResolver.cs b/Emby.Server.Implementations/Library/Resolvers/PhotoAlbumResolver.cs
index 29d540700..c0b00caaf 100644
--- a/Emby.Server.Implementations/Library/Resolvers/PhotoAlbumResolver.cs
+++ b/Emby.Server.Implementations/Library/Resolvers/PhotoAlbumResolver.cs
@@ -46,8 +46,8 @@ namespace Emby.Server.Implementations.Library.Resolvers
// Must be an image file within a photo collection
var collectionType = args.GetCollectionType();
- if (collectionType == CollectionType.Photos
- || (collectionType == CollectionType.HomeVideos && args.LibraryOptions.EnablePhotos))
+ if (collectionType == CollectionType.photos
+ || (collectionType == CollectionType.homevideos && args.LibraryOptions.EnablePhotos))
{
if (HasPhotos(args))
{
diff --git a/Emby.Server.Implementations/Library/Resolvers/PhotoResolver.cs b/Emby.Server.Implementations/Library/Resolvers/PhotoResolver.cs
index d166ac37f..0934555b2 100644
--- a/Emby.Server.Implementations/Library/Resolvers/PhotoResolver.cs
+++ b/Emby.Server.Implementations/Library/Resolvers/PhotoResolver.cs
@@ -61,8 +61,8 @@ namespace Emby.Server.Implementations.Library.Resolvers
// Must be an image file within a photo collection
var collectionType = args.CollectionType;
- if (collectionType == CollectionType.Photos
- || (collectionType == CollectionType.HomeVideos && args.LibraryOptions.EnablePhotos))
+ if (collectionType == CollectionType.photos
+ || (collectionType == CollectionType.homevideos && args.LibraryOptions.EnablePhotos))
{
if (IsImageFile(args.Path, _imageProcessor))
{
diff --git a/Emby.Server.Implementations/Library/Resolvers/PlaylistResolver.cs b/Emby.Server.Implementations/Library/Resolvers/PlaylistResolver.cs
index d4b3722c9..a50435ae6 100644
--- a/Emby.Server.Implementations/Library/Resolvers/PlaylistResolver.cs
+++ b/Emby.Server.Implementations/Library/Resolvers/PlaylistResolver.cs
@@ -23,7 +23,7 @@ namespace Emby.Server.Implementations.Library.Resolvers
private CollectionType?[] _musicPlaylistCollectionTypes =
{
null,
- CollectionType.Music
+ CollectionType.music
};
/// <inheritdoc/>
diff --git a/Emby.Server.Implementations/Library/Resolvers/TV/EpisodeResolver.cs b/Emby.Server.Implementations/Library/Resolvers/TV/EpisodeResolver.cs
index 8274881be..5fd23c9f5 100644
--- a/Emby.Server.Implementations/Library/Resolvers/TV/EpisodeResolver.cs
+++ b/Emby.Server.Implementations/Library/Resolvers/TV/EpisodeResolver.cs
@@ -50,7 +50,7 @@ namespace Emby.Server.Implementations.Library.Resolvers.TV
// If the parent is a Season or Series and the parent is not an extras folder, then this is an Episode if the VideoResolver returns something
// Also handle flat tv folders
if (season is not null
- || args.GetCollectionType() == CollectionType.TvShows
+ || args.GetCollectionType() == CollectionType.tvshows
|| args.HasParent<Series>())
{
var episode = ResolveVideo<Episode>(args, false);
diff --git a/Emby.Server.Implementations/Library/Resolvers/TV/SeriesResolver.cs b/Emby.Server.Implementations/Library/Resolvers/TV/SeriesResolver.cs
index 2ae1138a5..1484c34bc 100644
--- a/Emby.Server.Implementations/Library/Resolvers/TV/SeriesResolver.cs
+++ b/Emby.Server.Implementations/Library/Resolvers/TV/SeriesResolver.cs
@@ -60,11 +60,11 @@ namespace Emby.Server.Implementations.Library.Resolvers.TV
var seriesInfo = Naming.TV.SeriesResolver.Resolve(_namingOptions, args.Path);
var collectionType = args.GetCollectionType();
- if (collectionType == CollectionType.TvShows)
+ if (collectionType == CollectionType.tvshows)
{
// TODO refactor into separate class or something, this is copied from LibraryManager.GetConfiguredContentType
var configuredContentType = args.GetConfiguredContentType();
- if (configuredContentType != CollectionType.TvShows)
+ if (configuredContentType != CollectionType.tvshows)
{
return new Series
{
diff --git a/Emby.Server.Implementations/Library/UserDataManager.cs b/Emby.Server.Implementations/Library/UserDataManager.cs
index a0a90b129..8beeb8041 100644
--- a/Emby.Server.Implementations/Library/UserDataManager.cs
+++ b/Emby.Server.Implementations/Library/UserDataManager.cs
@@ -81,6 +81,53 @@ namespace Emby.Server.Implementations.Library
});
}
+ public void SaveUserData(User user, BaseItem item, UpdateUserItemDataDto userDataDto, UserDataSaveReason reason)
+ {
+ ArgumentNullException.ThrowIfNull(user);
+ ArgumentNullException.ThrowIfNull(item);
+ ArgumentNullException.ThrowIfNull(reason);
+ ArgumentNullException.ThrowIfNull(userDataDto);
+
+ var userData = GetUserData(user, item);
+
+ if (userDataDto.PlaybackPositionTicks.HasValue)
+ {
+ userData.PlaybackPositionTicks = userDataDto.PlaybackPositionTicks.Value;
+ }
+
+ if (userDataDto.PlayCount.HasValue)
+ {
+ userData.PlayCount = userDataDto.PlayCount.Value;
+ }
+
+ if (userDataDto.IsFavorite.HasValue)
+ {
+ userData.IsFavorite = userDataDto.IsFavorite.Value;
+ }
+
+ if (userDataDto.Likes.HasValue)
+ {
+ userData.Likes = userDataDto.Likes.Value;
+ }
+
+ if (userDataDto.Played.HasValue)
+ {
+ userData.Played = userDataDto.Played.Value;
+ }
+
+ if (userDataDto.LastPlayedDate.HasValue)
+ {
+ userData.LastPlayedDate = userDataDto.LastPlayedDate.Value;
+ }
+
+ if (userDataDto.Rating.HasValue)
+ {
+ userData.Rating = userDataDto.Rating.Value;
+ }
+
+ SaveUserData(user, item, userData, reason, CancellationToken.None);
+ }
+
/// <summary>
/// Save the provided user data for the given user. Batch operation. Does not fire any events or update the cache.
/// </summary>
diff --git a/Emby.Server.Implementations/Library/UserViewManager.cs b/Emby.Server.Implementations/Library/UserViewManager.cs
index 113370fc3..1d662ed8d 100644
--- a/Emby.Server.Implementations/Library/UserViewManager.cs
+++ b/Emby.Server.Implementations/Library/UserViewManager.cs
@@ -64,7 +64,7 @@ namespace Emby.Server.Implementations.Library
var folderViewType = collectionFolder?.CollectionType;
// Playlist library requires special handling because the folder only references user playlists
- if (folderViewType == CollectionType.Playlists)
+ if (folderViewType == CollectionType.playlists)
{
var items = folder.GetItemList(new InternalItemsQuery(user)
{
@@ -99,14 +99,14 @@ namespace Emby.Server.Implementations.Library
}
}
- foreach (var viewType in new[] { CollectionType.Movies, CollectionType.TvShows })
+ foreach (var viewType in new[] { CollectionType.movies, CollectionType.tvshows })
{
var parents = groupedFolders.Where(i => i.CollectionType == viewType || i.CollectionType is null)
.ToList();
if (parents.Count > 0)
{
- var localizationKey = viewType == CollectionType.TvShows
+ var localizationKey = viewType == CollectionType.tvshows
? "TvShows"
: "Movies";
@@ -117,7 +117,7 @@ namespace Emby.Server.Implementations.Library
if (_config.Configuration.EnableFolderView)
{
var name = _localizationManager.GetLocalizedString("Folders");
- list.Add(_libraryManager.GetNamedView(name, CollectionType.Folders, string.Empty));
+ list.Add(_libraryManager.GetNamedView(name, CollectionType.folders, string.Empty));
}
if (query.IncludeExternalContent)
@@ -279,7 +279,7 @@ namespace Emby.Server.Implementations.Library
var isPlayed = request.IsPlayed;
- if (parents.OfType<ICollectionFolder>().Any(i => i.CollectionType == CollectionType.Music))
+ if (parents.OfType<ICollectionFolder>().Any(i => i.CollectionType == CollectionType.music))
{
isPlayed = null;
}
@@ -305,11 +305,11 @@ namespace Emby.Server.Implementations.Library
var hasCollectionType = parents.OfType<UserView>().ToArray();
if (hasCollectionType.Length > 0)
{
- if (hasCollectionType.All(i => i.CollectionType == CollectionType.Movies))
+ if (hasCollectionType.All(i => i.CollectionType == CollectionType.movies))
{
includeItemTypes = new[] { BaseItemKind.Movie };
}
- else if (hasCollectionType.All(i => i.CollectionType == CollectionType.TvShows))
+ else if (hasCollectionType.All(i => i.CollectionType == CollectionType.tvshows))
{
includeItemTypes = new[] { BaseItemKind.Episode };
}
@@ -324,18 +324,18 @@ namespace Emby.Server.Implementations.Library
{
switch (parent.CollectionType)
{
- case CollectionType.Books:
+ case CollectionType.books:
mediaTypes.Add(MediaType.Book);
mediaTypes.Add(MediaType.Audio);
break;
- case CollectionType.Music:
+ case CollectionType.music:
mediaTypes.Add(MediaType.Audio);
break;
- case CollectionType.Photos:
+ case CollectionType.photos:
mediaTypes.Add(MediaType.Photo);
mediaTypes.Add(MediaType.Video);
break;
- case CollectionType.HomeVideos:
+ case CollectionType.homevideos:
mediaTypes.Add(MediaType.Photo);
mediaTypes.Add(MediaType.Video);
break;
diff --git a/Emby.Server.Implementations/LiveTv/LiveTvManager.cs b/Emby.Server.Implementations/LiveTv/LiveTvManager.cs
index dd427c736..db06e4784 100644
--- a/Emby.Server.Implementations/LiveTv/LiveTvManager.cs
+++ b/Emby.Server.Implementations/LiveTv/LiveTvManager.cs
@@ -2168,7 +2168,7 @@ namespace Emby.Server.Implementations.LiveTv
public Folder GetInternalLiveTvFolder(CancellationToken cancellationToken)
{
var name = _localization.GetLocalizedString("HeaderLiveTV");
- return _libraryManager.GetNamedView(name, CollectionType.LiveTv, name);
+ return _libraryManager.GetNamedView(name, CollectionType.livetv, name);
}
public async Task<TunerHostInfo> SaveTunerHost(TunerHostInfo info, bool dataSourceChanged = true)
diff --git a/Emby.Server.Implementations/Localization/Core/ab.json b/Emby.Server.Implementations/Localization/Core/ab.json
new file mode 100644
index 000000000..0967ef424
--- /dev/null
+++ b/Emby.Server.Implementations/Localization/Core/ab.json
@@ -0,0 +1 @@
+{}
diff --git a/Emby.Server.Implementations/Localization/Core/fil.json b/Emby.Server.Implementations/Localization/Core/fil.json
index 88a4a358e..55ee1abaa 100644
--- a/Emby.Server.Implementations/Localization/Core/fil.json
+++ b/Emby.Server.Implementations/Localization/Core/fil.json
@@ -124,5 +124,6 @@
"TaskKeyframeExtractor": "Tagabunot ng Keyframe",
"TaskKeyframeExtractorDescription": "Nagbubunot ng keyframe mula sa mga bidyo upang makabuo ng mas tumpak na HLS playlist. Maaaring matagal ito gawin.",
"External": "External",
- "TaskRefreshTrickplayImages": "Gumawa ng Trickplay na Imahe"
+ "TaskRefreshTrickplayImages": "Gumawa ng Trickplay na Imahe",
+ "TaskRefreshTrickplayImagesDescription": "Nanggagawa ng mga trickplay prebiyu para sa mga bidyo sa pinaganang mga aklatan."
}
diff --git a/Emby.Server.Implementations/Localization/Core/nb.json b/Emby.Server.Implementations/Localization/Core/nb.json
index 5c7dec7ef..0362c2417 100644
--- a/Emby.Server.Implementations/Localization/Core/nb.json
+++ b/Emby.Server.Implementations/Localization/Core/nb.json
@@ -124,5 +124,7 @@
"TaskKeyframeExtractorDescription": "Trekker ut nøkkelbilder fra videofiler for å skape mere nøyaktige HLS-spillelister. Denne oppgaven kan ta lang tid.",
"TaskKeyframeExtractor": "Nøkkelbilde-uttrekker",
"External": "Ekstern",
- "HearingImpaired": "Hørselshemmet"
+ "HearingImpaired": "Hørselshemmet",
+ "TaskRefreshTrickplayImages": "Generer Trickplay bilder",
+ "TaskRefreshTrickplayImagesDescription": "Oppretter trickplay-forhåndsvisninger for videoer i aktiverte biblioteker."
}
diff --git a/Emby.Server.Implementations/Localization/Core/tr.json b/Emby.Server.Implementations/Localization/Core/tr.json
index a4877f4b5..6a04115fa 100644
--- a/Emby.Server.Implementations/Localization/Core/tr.json
+++ b/Emby.Server.Implementations/Localization/Core/tr.json
@@ -89,7 +89,7 @@
"UserPolicyUpdatedWithName": "{0} için kullanıcı politikası güncellendi",
"UserStartedPlayingItemWithValues": "{0}, {2} cihazında {1} izliyor",
"UserStoppedPlayingItemWithValues": "{0}, {2} cihazında {1} izlemeyi bitirdi",
- "ValueHasBeenAddedToLibrary": "Medya kütüphanenize {0} eklendi",
+ "ValueHasBeenAddedToLibrary": "{0} medya kütüphanenize eklendi",
"ValueSpecialEpisodeName": "Özel - {0}",
"VersionNumber": "Sürüm {0}",
"TaskCleanCache": "Önbellek Dizinini Temizle",
diff --git a/Emby.Server.Implementations/Playlists/PlaylistsFolder.cs b/Emby.Server.Implementations/Playlists/PlaylistsFolder.cs
index 5c616d534..f65d609c7 100644
--- a/Emby.Server.Implementations/Playlists/PlaylistsFolder.cs
+++ b/Emby.Server.Implementations/Playlists/PlaylistsFolder.cs
@@ -25,7 +25,7 @@ namespace Emby.Server.Implementations.Playlists
public override bool SupportsInheritedParentImages => false;
[JsonIgnore]
- public override CollectionType? CollectionType => Jellyfin.Data.Enums.CollectionType.Playlists;
+ public override CollectionType? CollectionType => Jellyfin.Data.Enums.CollectionType.playlists;
protected override IEnumerable<BaseItem> GetEligibleChildrenForRecursiveChildren(User user)
{
diff --git a/Jellyfin.Api/Controllers/GenresController.cs b/Jellyfin.Api/Controllers/GenresController.cs
index 062e1062d..6cb1993e4 100644
--- a/Jellyfin.Api/Controllers/GenresController.cs
+++ b/Jellyfin.Api/Controllers/GenresController.cs
@@ -131,8 +131,8 @@ public class GenresController : BaseJellyfinApiController
QueryResult<(BaseItem, ItemCounts)> result;
if (parentItem is ICollectionFolder parentCollectionFolder
- && (parentCollectionFolder.CollectionType == CollectionType.Music
- || parentCollectionFolder.CollectionType == CollectionType.MusicVideos))
+ && (parentCollectionFolder.CollectionType == CollectionType.music
+ || parentCollectionFolder.CollectionType == CollectionType.musicvideos))
{
result = _libraryManager.GetMusicGenres(query);
}
diff --git a/Jellyfin.Api/Controllers/ItemUpdateController.cs b/Jellyfin.Api/Controllers/ItemUpdateController.cs
index 4e5ed60d5..9800248c6 100644
--- a/Jellyfin.Api/Controllers/ItemUpdateController.cs
+++ b/Jellyfin.Api/Controllers/ItemUpdateController.cs
@@ -171,7 +171,7 @@ public class ItemUpdateController : BaseJellyfinApiController
info.ContentTypeOptions = GetContentTypeOptions(true).ToArray();
info.ContentType = configuredContentType;
- if (inheritedContentType is null || inheritedContentType == CollectionType.TvShows)
+ if (inheritedContentType is null || inheritedContentType == CollectionType.tvshows)
{
info.ContentTypeOptions = info.ContentTypeOptions
.Where(i => string.IsNullOrWhiteSpace(i.Value)
diff --git a/Jellyfin.Api/Controllers/ItemsController.cs b/Jellyfin.Api/Controllers/ItemsController.cs
index 4e46e808a..a1fc8e11b 100644
--- a/Jellyfin.Api/Controllers/ItemsController.cs
+++ b/Jellyfin.Api/Controllers/ItemsController.cs
@@ -34,6 +34,7 @@ public class ItemsController : BaseJellyfinApiController
private readonly IDtoService _dtoService;
private readonly ILogger<ItemsController> _logger;
private readonly ISessionManager _sessionManager;
+ private readonly IUserDataManager _userDataRepository;
/// <summary>
/// Initializes a new instance of the <see cref="ItemsController"/> class.
@@ -44,13 +45,15 @@ public class ItemsController : BaseJellyfinApiController
/// <param name="dtoService">Instance of the <see cref="IDtoService"/> interface.</param>
/// <param name="logger">Instance of the <see cref="ILogger"/> interface.</param>
/// <param name="sessionManager">Instance of the <see cref="ISessionManager"/> interface.</param>
+ /// <param name="userDataRepository">Instance of the <see cref="IUserDataManager"/> interface.</param>
public ItemsController(
IUserManager userManager,
ILibraryManager libraryManager,
ILocalizationManager localization,
IDtoService dtoService,
ILogger<ItemsController> logger,
- ISessionManager sessionManager)
+ ISessionManager sessionManager,
+ IUserDataManager userDataRepository)
{
_userManager = userManager;
_libraryManager = libraryManager;
@@ -58,6 +61,7 @@ public class ItemsController : BaseJellyfinApiController
_dtoService = dtoService;
_logger = logger;
_sessionManager = sessionManager;
+ _userDataRepository = userDataRepository;
}
/// <summary>
@@ -275,7 +279,7 @@ public class ItemsController : BaseJellyfinApiController
collectionType = hasCollectionType.CollectionType;
}
- if (collectionType == CollectionType.Playlists)
+ if (collectionType == CollectionType.playlists)
{
recursive = true;
includeItemTypes = new[] { BaseItemKind.Playlist };
@@ -881,4 +885,64 @@ public class ItemsController : BaseJellyfinApiController
itemsResult.TotalRecordCount,
returnItems);
}
+
+ /// <summary>
+ /// Get Item User Data.
+ /// </summary>
+ /// <param name="userId">The user id.</param>
+ /// <param name="itemId">The item id.</param>
+ /// <response code="200">return item user data.</response>
+ /// <response code="404">Item is not found.</response>
+ /// <returns>Return <see cref="UserItemDataDto"/>.</returns>
+ [HttpGet("Users/{userId}/Items/{itemId}/UserData")]
+ [ProducesResponseType(StatusCodes.Status200OK)]
+ [ProducesResponseType(StatusCodes.Status404NotFound)]
+ public ActionResult<UserItemDataDto> GetItemUserData(
+ [FromRoute, Required] Guid userId,
+ [FromRoute, Required] Guid itemId)
+ {
+ if (!RequestHelpers.AssertCanUpdateUser(_userManager, User, userId, true))
+ {
+ return StatusCode(StatusCodes.Status403Forbidden, "User is not allowed to view this item user data.");
+ }
+
+ var user = _userManager.GetUserById(userId) ?? throw new ResourceNotFoundException();
+ var item = _libraryManager.GetItemById(itemId);
+
+ return (item == null) ? NotFound() : _userDataRepository.GetUserDataDto(item, user);
+ }
+
+ /// <summary>
+ /// Update Item User Data.
+ /// </summary>
+ /// <param name="userId">The user id.</param>
+ /// <param name="itemId">The item id.</param>
+ /// <param name="userDataDto">New user data object.</param>
+ /// <response code="200">return updated user item data.</response>
+ /// <response code="404">Item is not found.</response>
+ /// <returns>Return <see cref="UserItemDataDto"/>.</returns>
+ [HttpPost("Users/{userId}/Items/{itemId}/UserData")]
+ [ProducesResponseType(StatusCodes.Status200OK)]
+ [ProducesResponseType(StatusCodes.Status404NotFound)]
+ public ActionResult<UserItemDataDto> UpdateItemUserData(
+ [FromRoute, Required] Guid userId,
+ [FromRoute, Required] Guid itemId,
+ [FromBody, Required] UpdateUserItemDataDto userDataDto)
+ {
+ if (!RequestHelpers.AssertCanUpdateUser(_userManager, User, userId, true))
+ {
+ return StatusCode(StatusCodes.Status403Forbidden, "User is not allowed to update this item user data.");
+ }
+
+ var user = _userManager.GetUserById(userId) ?? throw new ResourceNotFoundException();
+ var item = _libraryManager.GetItemById(itemId);
+ if (item == null)
+ {
+ return NotFound();
+ }
+
+ _userDataRepository.SaveUserData(user, item, userDataDto, UserDataSaveReason.UpdateUserData);
+
+ return _userDataRepository.GetUserDataDto(item, user);
+ }
}
diff --git a/Jellyfin.Api/Controllers/LibraryController.cs b/Jellyfin.Api/Controllers/LibraryController.cs
index af9a93719..de057bbab 100644
--- a/Jellyfin.Api/Controllers/LibraryController.cs
+++ b/Jellyfin.Api/Controllers/LibraryController.cs
@@ -927,15 +927,15 @@ public class LibraryController : BaseJellyfinApiController
{
return contentType switch
{
- CollectionType.BoxSets => new[] { "BoxSet" },
- CollectionType.Playlists => new[] { "Playlist" },
- CollectionType.Movies => new[] { "Movie" },
- CollectionType.TvShows => new[] { "Series", "Season", "Episode" },
- CollectionType.Books => new[] { "Book" },
- CollectionType.Music => new[] { "MusicArtist", "MusicAlbum", "Audio", "MusicVideo" },
- CollectionType.HomeVideos => new[] { "Video", "Photo" },
- CollectionType.Photos => new[] { "Video", "Photo" },
- CollectionType.MusicVideos => new[] { "MusicVideo" },
+ CollectionType.boxsets => new[] { "BoxSet" },
+ CollectionType.playlists => new[] { "Playlist" },
+ CollectionType.movies => new[] { "Movie" },
+ CollectionType.tvshows => new[] { "Series", "Season", "Episode" },
+ CollectionType.books => new[] { "Book" },
+ CollectionType.music => new[] { "MusicArtist", "MusicAlbum", "Audio", "MusicVideo" },
+ CollectionType.homevideos => new[] { "Video", "Photo" },
+ CollectionType.photos => new[] { "Video", "Photo" },
+ CollectionType.musicvideos => new[] { "MusicVideo" },
_ => new[] { "Series", "Season", "Episode", "Movie" }
};
}
diff --git a/Jellyfin.Data/Enums/CollectionType.cs b/Jellyfin.Data/Enums/CollectionType.cs
index e2044a0bc..e3d3b07af 100644
--- a/Jellyfin.Data/Enums/CollectionType.cs
+++ b/Jellyfin.Data/Enums/CollectionType.cs
@@ -1,3 +1,4 @@
+#pragma warning disable SA1300 // The name of a C# element does not begin with an upper-case letter. - disabled due to legacy requirement.
using Jellyfin.Data.Attributes;
namespace Jellyfin.Data.Enums;
@@ -10,155 +11,155 @@ public enum CollectionType
/// <summary>
/// Unknown collection.
/// </summary>
- Unknown = 0,
+ unknown = 0,
/// <summary>
/// Movies collection.
/// </summary>
- Movies = 1,
+ movies = 1,
/// <summary>
/// Tv shows collection.
/// </summary>
- TvShows = 2,
+ tvshows = 2,
/// <summary>
/// Music collection.
/// </summary>
- Music = 3,
+ music = 3,
/// <summary>
/// Music videos collection.
/// </summary>
- MusicVideos = 4,
+ musicvideos = 4,
/// <summary>
/// Trailers collection.
/// </summary>
- Trailers = 5,
+ trailers = 5,
/// <summary>
/// Home videos collection.
/// </summary>
- HomeVideos = 6,
+ homevideos = 6,
/// <summary>
/// Box sets collection.
/// </summary>
- BoxSets = 7,
+ boxsets = 7,
/// <summary>
/// Books collection.
/// </summary>
- Books = 8,
+ books = 8,
/// <summary>
/// Photos collection.
/// </summary>
- Photos = 9,
+ photos = 9,
/// <summary>
/// Live tv collection.
/// </summary>
- LiveTv = 10,
+ livetv = 10,
/// <summary>
/// Playlists collection.
/// </summary>
- Playlists = 11,
+ playlists = 11,
/// <summary>
/// Folders collection.
/// </summary>
- Folders = 12,
+ folders = 12,
/// <summary>
/// Tv show series collection.
/// </summary>
[OpenApiIgnoreEnum]
- TvShowSeries = 101,
+ tvshowseries = 101,
/// <summary>
/// Tv genres collection.
/// </summary>
[OpenApiIgnoreEnum]
- TvGenres = 102,
+ tvgenres = 102,
/// <summary>
/// Tv genre collection.
/// </summary>
[OpenApiIgnoreEnum]
- TvGenre = 103,
+ tvgenre = 103,
/// <summary>
/// Tv latest collection.
/// </summary>
[OpenApiIgnoreEnum]
- TvLatest = 104,
+ tvlatest = 104,
/// <summary>
/// Tv next up collection.
/// </summary>
[OpenApiIgnoreEnum]
- TvNextUp = 105,
+ tvnextup = 105,
/// <summary>
/// Tv resume collection.
/// </summary>
[OpenApiIgnoreEnum]
- TvResume = 106,
+ tvresume = 106,
/// <summary>
/// Tv favorite series collection.
/// </summary>
[OpenApiIgnoreEnum]
- TvFavoriteSeries = 107,
+ tvfavoriteseries = 107,
/// <summary>
/// Tv favorite episodes collection.
/// </summary>
[OpenApiIgnoreEnum]
- TvFavoriteEpisodes = 108,
+ tvfavoriteepisodes = 108,
/// <summary>
/// Latest movies collection.
/// </summary>
[OpenApiIgnoreEnum]
- MovieLatest = 109,
+ movielatest = 109,
/// <summary>
/// Movies to resume collection.
/// </summary>
[OpenApiIgnoreEnum]
- MovieResume = 110,
+ movieresume = 110,
/// <summary>
/// Movie movie collection.
/// </summary>
[OpenApiIgnoreEnum]
- MovieMovies = 111,
+ moviemovies = 111,
/// <summary>
/// Movie collections collection.
/// </summary>
[OpenApiIgnoreEnum]
- MovieCollections = 112,
+ moviecollection = 112,
/// <summary>
/// Movie favorites collection.
/// </summary>
[OpenApiIgnoreEnum]
- MovieFavorites = 113,
+ moviefavorites = 113,
/// <summary>
/// Movie genres collection.
/// </summary>
[OpenApiIgnoreEnum]
- MovieGenres = 114,
+ moviegenres = 114,
/// <summary>
/// Movie genre collection.
/// </summary>
[OpenApiIgnoreEnum]
- MovieGenre = 115
+ moviegenre = 115
}
diff --git a/Jellyfin.Server.Implementations/Devices/DeviceManager.cs b/Jellyfin.Server.Implementations/Devices/DeviceManager.cs
index a4b4c1959..d8eee1246 100644
--- a/Jellyfin.Server.Implementations/Devices/DeviceManager.cs
+++ b/Jellyfin.Server.Implementations/Devices/DeviceManager.cs
@@ -110,21 +110,21 @@ namespace Jellyfin.Server.Implementations.Devices
/// <inheritdoc />
public async Task<DeviceInfo?> GetDevice(string id)
{
- Device? device;
var dbContext = await _dbProvider.CreateDbContextAsync().ConfigureAwait(false);
await using (dbContext.ConfigureAwait(false))
{
- device = await dbContext.Devices
+ var device = await dbContext.Devices
.Where(d => d.DeviceId == id)
.OrderByDescending(d => d.DateLastActivity)
.Include(d => d.User)
+ .SelectMany(d => dbContext.DeviceOptions.Where(o => o.DeviceId == d.DeviceId).DefaultIfEmpty(), (d, o) => new { Device = d, Options = o })
.FirstOrDefaultAsync()
.ConfigureAwait(false);
- }
- var deviceInfo = device is null ? null : ToDeviceInfo(device);
+ var deviceInfo = device is null ? null : ToDeviceInfo(device.Device, device.Options);
- return deviceInfo;
+ return deviceInfo;
+ }
}
/// <inheritdoc />
@@ -172,15 +172,15 @@ namespace Jellyfin.Server.Implementations.Devices
var dbContext = await _dbProvider.CreateDbContextAsync().ConfigureAwait(false);
await using (dbContext.ConfigureAwait(false))
{
- IAsyncEnumerable<Device> sessions = dbContext.Devices
+ var sessions = dbContext.Devices
.Include(d => d.User)
.OrderByDescending(d => d.DateLastActivity)
.ThenBy(d => d.DeviceId)
+ .SelectMany(d => dbContext.DeviceOptions.Where(o => o.DeviceId == d.DeviceId).DefaultIfEmpty(), (d, o) => new { Device = d, Options = o })
.AsAsyncEnumerable();
-
if (supportsSync.HasValue)
{
- sessions = sessions.Where(i => GetCapabilities(i.DeviceId).SupportsSync == supportsSync.Value);
+ sessions = sessions.Where(i => GetCapabilities(i.Device.DeviceId).SupportsSync == supportsSync.Value);
}
if (userId.HasValue)
@@ -191,10 +191,10 @@ namespace Jellyfin.Server.Implementations.Devices
throw new ResourceNotFoundException();
}
- sessions = sessions.Where(i => CanAccessDevice(user, i.DeviceId));
+ sessions = sessions.Where(i => CanAccessDevice(user, i.Device.DeviceId));
}
- var array = await sessions.Select(device => ToDeviceInfo(device)).ToArrayAsync().ConfigureAwait(false);
+ var array = await sessions.Select(device => ToDeviceInfo(device.Device, device.Options)).ToArrayAsync().ConfigureAwait(false);
return new QueryResult<DeviceInfo>(array);
}
@@ -226,7 +226,7 @@ namespace Jellyfin.Server.Implementations.Devices
|| !GetCapabilities(deviceId).SupportsPersistentIdentifier;
}
- private DeviceInfo ToDeviceInfo(Device authInfo)
+ private DeviceInfo ToDeviceInfo(Device authInfo, DeviceOptions? options = null)
{
var caps = GetCapabilities(authInfo.DeviceId);
@@ -239,7 +239,8 @@ namespace Jellyfin.Server.Implementations.Devices
LastUserName = authInfo.User.Username,
Name = authInfo.DeviceName,
DateLastActivity = authInfo.DateLastActivity,
- IconUrl = caps.IconUrl
+ IconUrl = caps.IconUrl,
+ CustomName = options?.CustomName,
};
}
}
diff --git a/MediaBrowser.Controller/Entities/BaseItem.cs b/MediaBrowser.Controller/Entities/BaseItem.cs
index 98485f9a8..7c04fcbfc 100644
--- a/MediaBrowser.Controller/Entities/BaseItem.cs
+++ b/MediaBrowser.Controller/Entities/BaseItem.cs
@@ -724,7 +724,7 @@ namespace MediaBrowser.Controller.Entities
if (this is IHasCollectionType view)
{
- if (view.CollectionType == CollectionType.LiveTv)
+ if (view.CollectionType == CollectionType.livetv)
{
return true;
}
diff --git a/MediaBrowser.Controller/Entities/UserView.cs b/MediaBrowser.Controller/Entities/UserView.cs
index 1f94cf767..eb026deb4 100644
--- a/MediaBrowser.Controller/Entities/UserView.cs
+++ b/MediaBrowser.Controller/Entities/UserView.cs
@@ -19,19 +19,19 @@ namespace MediaBrowser.Controller.Entities
{
private static readonly CollectionType?[] _viewTypesEligibleForGrouping =
{
- Jellyfin.Data.Enums.CollectionType.Movies,
- Jellyfin.Data.Enums.CollectionType.TvShows,
+ Jellyfin.Data.Enums.CollectionType.movies,
+ Jellyfin.Data.Enums.CollectionType.tvshows,
null
};
private static readonly CollectionType?[] _originalFolderViewTypes =
{
- Jellyfin.Data.Enums.CollectionType.Books,
- Jellyfin.Data.Enums.CollectionType.MusicVideos,
- Jellyfin.Data.Enums.CollectionType.HomeVideos,
- Jellyfin.Data.Enums.CollectionType.Photos,
- Jellyfin.Data.Enums.CollectionType.Music,
- Jellyfin.Data.Enums.CollectionType.BoxSets
+ Jellyfin.Data.Enums.CollectionType.books,
+ Jellyfin.Data.Enums.CollectionType.musicvideos,
+ Jellyfin.Data.Enums.CollectionType.homevideos,
+ Jellyfin.Data.Enums.CollectionType.photos,
+ Jellyfin.Data.Enums.CollectionType.music,
+ Jellyfin.Data.Enums.CollectionType.boxsets
};
public static ITVSeriesManager TVSeriesManager { get; set; }
@@ -161,7 +161,7 @@ namespace MediaBrowser.Controller.Entities
return true;
}
- return collectionFolder.CollectionType == Jellyfin.Data.Enums.CollectionType.Playlists;
+ return collectionFolder.CollectionType == Jellyfin.Data.Enums.CollectionType.playlists;
}
public static bool IsEligibleForGrouping(Folder folder)
diff --git a/MediaBrowser.Controller/Entities/UserViewBuilder.cs b/MediaBrowser.Controller/Entities/UserViewBuilder.cs
index 42431c832..a3525c862 100644
--- a/MediaBrowser.Controller/Entities/UserViewBuilder.cs
+++ b/MediaBrowser.Controller/Entities/UserViewBuilder.cs
@@ -58,58 +58,58 @@ namespace MediaBrowser.Controller.Entities
switch (viewType)
{
- case CollectionType.Folders:
+ case CollectionType.folders:
return GetResult(_libraryManager.GetUserRootFolder().GetChildren(user, true), query);
- case CollectionType.TvShows:
+ case CollectionType.tvshows:
return GetTvView(queryParent, user, query);
- case CollectionType.Movies:
+ case CollectionType.movies:
return GetMovieFolders(queryParent, user, query);
- case CollectionType.TvShowSeries:
+ case CollectionType.tvshowseries:
return GetTvSeries(queryParent, user, query);
- case CollectionType.TvGenres:
+ case CollectionType.tvgenres:
return GetTvGenres(queryParent, user, query);
- case CollectionType.TvGenre:
+ case CollectionType.tvgenre:
return GetTvGenreItems(queryParent, displayParent, user, query);
- case CollectionType.TvResume:
+ case CollectionType.tvresume:
return GetTvResume(queryParent, user, query);
- case CollectionType.TvNextUp:
+ case CollectionType.tvnextup:
return GetTvNextUp(queryParent, query);
- case CollectionType.TvLatest:
+ case CollectionType.tvlatest:
return GetTvLatest(queryParent, user, query);
- case CollectionType.MovieFavorites:
+ case CollectionType.moviefavorites:
return GetFavoriteMovies(queryParent, user, query);
- case CollectionType.MovieLatest:
+ case CollectionType.movielatest:
return GetMovieLatest(queryParent, user, query);
- case CollectionType.MovieGenres:
+ case CollectionType.moviegenres:
return GetMovieGenres(queryParent, user, query);
- case CollectionType.MovieGenre:
+ case CollectionType.moviegenre:
return GetMovieGenreItems(queryParent, displayParent, user, query);
- case CollectionType.MovieResume:
+ case CollectionType.movieresume:
return GetMovieResume(queryParent, user, query);
- case CollectionType.MovieMovies:
+ case CollectionType.moviemovies:
return GetMovieMovies(queryParent, user, query);
- case CollectionType.MovieCollections:
+ case CollectionType.moviecollection:
return GetMovieCollections(user, query);
- case CollectionType.TvFavoriteEpisodes:
+ case CollectionType.tvfavoriteepisodes:
return GetFavoriteEpisodes(queryParent, user, query);
- case CollectionType.TvFavoriteSeries:
+ case CollectionType.tvfavoriteseries:
return GetFavoriteSeries(queryParent, user, query);
default:
@@ -146,12 +146,12 @@ namespace MediaBrowser.Controller.Entities
var list = new List<BaseItem>
{
- GetUserView(CollectionType.MovieResume, "HeaderContinueWatching", "0", parent),
- GetUserView(CollectionType.MovieLatest, "Latest", "1", parent),
- GetUserView(CollectionType.MovieMovies, "Movies", "2", parent),
- GetUserView(CollectionType.MovieCollections, "Collections", "3", parent),
- GetUserView(CollectionType.MovieFavorites, "Favorites", "4", parent),
- GetUserView(CollectionType.MovieGenres, "Genres", "5", parent)
+ GetUserView(CollectionType.movieresume, "HeaderContinueWatching", "0", parent),
+ GetUserView(CollectionType.movielatest, "Latest", "1", parent),
+ GetUserView(CollectionType.moviemovies, "Movies", "2", parent),
+ GetUserView(CollectionType.moviecollection, "Collections", "3", parent),
+ GetUserView(CollectionType.moviefavorites, "Favorites", "4", parent),
+ GetUserView(CollectionType.moviegenres, "Genres", "5", parent)
};
return GetResult(list, query);
@@ -264,7 +264,7 @@ namespace MediaBrowser.Controller.Entities
}
})
.Where(i => i is not null)
- .Select(i => GetUserViewWithName(CollectionType.MovieGenre, i.SortName, parent));
+ .Select(i => GetUserViewWithName(CollectionType.moviegenre, i.SortName, parent));
return GetResult(genres, query);
}
@@ -303,13 +303,13 @@ namespace MediaBrowser.Controller.Entities
var list = new List<BaseItem>
{
- GetUserView(CollectionType.TvResume, "HeaderContinueWatching", "0", parent),
- GetUserView(CollectionType.TvNextUp, "HeaderNextUp", "1", parent),
- GetUserView(CollectionType.TvLatest, "Latest", "2", parent),
- GetUserView(CollectionType.TvShowSeries, "Shows", "3", parent),
- GetUserView(CollectionType.TvFavoriteSeries, "HeaderFavoriteShows", "4", parent),
- GetUserView(CollectionType.TvFavoriteEpisodes, "HeaderFavoriteEpisodes", "5", parent),
- GetUserView(CollectionType.TvGenres, "Genres", "6", parent)
+ GetUserView(CollectionType.tvresume, "HeaderContinueWatching", "0", parent),
+ GetUserView(CollectionType.tvnextup, "HeaderNextUp", "1", parent),
+ GetUserView(CollectionType.tvlatest, "Latest", "2", parent),
+ GetUserView(CollectionType.tvshowseries, "Shows", "3", parent),
+ GetUserView(CollectionType.tvfavoriteseries, "HeaderFavoriteShows", "4", parent),
+ GetUserView(CollectionType.tvfavoriteepisodes, "HeaderFavoriteEpisodes", "5", parent),
+ GetUserView(CollectionType.tvgenres, "Genres", "6", parent)
};
return GetResult(list, query);
@@ -330,7 +330,7 @@ namespace MediaBrowser.Controller.Entities
private QueryResult<BaseItem> GetTvNextUp(Folder parent, InternalItemsQuery query)
{
- var parentFolders = GetMediaFolders(parent, query.User, new[] { CollectionType.TvShows });
+ var parentFolders = GetMediaFolders(parent, query.User, new[] { CollectionType.tvshows });
var result = _tvSeriesManager.GetNextUp(
new NextUpQuery
@@ -392,7 +392,7 @@ namespace MediaBrowser.Controller.Entities
}
})
.Where(i => i is not null)
- .Select(i => GetUserViewWithName(CollectionType.TvGenre, i.SortName, parent));
+ .Select(i => GetUserViewWithName(CollectionType.tvgenre, i.SortName, parent));
return GetResult(genres, query);
}
diff --git a/MediaBrowser.Controller/Library/IUserDataManager.cs b/MediaBrowser.Controller/Library/IUserDataManager.cs
index 034c40591..43cccfc65 100644
--- a/MediaBrowser.Controller/Library/IUserDataManager.cs
+++ b/MediaBrowser.Controller/Library/IUserDataManager.cs
@@ -35,6 +35,15 @@ namespace MediaBrowser.Controller.Library
void SaveUserData(User user, BaseItem item, UserItemData userData, UserDataSaveReason reason, CancellationToken cancellationToken);
+ /// <summary>
+ /// Save the provided user data for the given user.
+ /// </summary>
+ /// <param name="user">The user.</param>
+ /// <param name="item">The item.</param>
+ /// <param name="userDataDto">The reason for updating the user data.</param>
+ /// <param name="reason">The reason.</param>
+ void SaveUserData(User user, BaseItem item, UpdateUserItemDataDto userDataDto, UserDataSaveReason reason);
+
UserItemData GetUserData(User user, BaseItem item);
UserItemData GetUserData(Guid userId, BaseItem item);
diff --git a/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs b/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs
index 46fd1ae47..6a16d421c 100644
--- a/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs
+++ b/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs
@@ -3343,7 +3343,7 @@ namespace MediaBrowser.Controller.MediaEncoding
// [0:s]scale=s=1280x720
var subSwScaleFilter = GetCustomSwScaleFilter(inW, inH, reqW, reqH, reqMaxW, reqMaxH);
subFilters.Add(subSwScaleFilter);
- overlayFilters.Add("overlay=eof_action=endall:shortest=1:repeatlast=0");
+ overlayFilters.Add("overlay=eof_action=pass:repeatlast=0");
}
return (mainFilters, subFilters, overlayFilters);
@@ -3520,7 +3520,7 @@ namespace MediaBrowser.Controller.MediaEncoding
}
subFilters.Add("hwupload=derive_device=cuda");
- overlayFilters.Add("overlay_cuda=eof_action=endall:shortest=1:repeatlast=0");
+ overlayFilters.Add("overlay_cuda=eof_action=pass:repeatlast=0");
}
}
else
@@ -3529,7 +3529,7 @@ namespace MediaBrowser.Controller.MediaEncoding
{
var subSwScaleFilter = GetCustomSwScaleFilter(inW, inH, reqW, reqH, reqMaxW, reqMaxH);
subFilters.Add(subSwScaleFilter);
- overlayFilters.Add("overlay=eof_action=endall:shortest=1:repeatlast=0");
+ overlayFilters.Add("overlay=eof_action=pass:repeatlast=0");
}
}
@@ -3718,7 +3718,7 @@ namespace MediaBrowser.Controller.MediaEncoding
}
subFilters.Add("hwupload=derive_device=opencl");
- overlayFilters.Add("overlay_opencl=eof_action=endall:shortest=1:repeatlast=0");
+ overlayFilters.Add("overlay_opencl=eof_action=pass:repeatlast=0");
overlayFilters.Add("hwmap=derive_device=d3d11va:reverse=1");
overlayFilters.Add("format=d3d11");
}
@@ -3729,7 +3729,7 @@ namespace MediaBrowser.Controller.MediaEncoding
{
var subSwScaleFilter = GetCustomSwScaleFilter(inW, inH, reqW, reqH, reqMaxW, reqMaxH);
subFilters.Add(subSwScaleFilter);
- overlayFilters.Add("overlay=eof_action=endall:shortest=1:repeatlast=0");
+ overlayFilters.Add("overlay=eof_action=pass:repeatlast=0");
}
}
@@ -3964,7 +3964,7 @@ namespace MediaBrowser.Controller.MediaEncoding
: string.Empty;
var overlayQsvFilter = string.Format(
CultureInfo.InvariantCulture,
- "overlay_qsv=eof_action=endall:shortest=1:repeatlast=0{0}",
+ "overlay_qsv=eof_action=pass:repeatlast=0{0}",
overlaySize);
overlayFilters.Add(overlayQsvFilter);
}
@@ -3975,7 +3975,7 @@ namespace MediaBrowser.Controller.MediaEncoding
{
var subSwScaleFilter = GetCustomSwScaleFilter(inW, inH, reqW, reqH, reqMaxW, reqMaxH);
subFilters.Add(subSwScaleFilter);
- overlayFilters.Add("overlay=eof_action=endall:shortest=1:repeatlast=0");
+ overlayFilters.Add("overlay=eof_action=pass:repeatlast=0");
}
}
@@ -4180,7 +4180,7 @@ namespace MediaBrowser.Controller.MediaEncoding
: string.Empty;
var overlayQsvFilter = string.Format(
CultureInfo.InvariantCulture,
- "overlay_qsv=eof_action=endall:shortest=1:repeatlast=0{0}",
+ "overlay_qsv=eof_action=pass:repeatlast=0{0}",
overlaySize);
overlayFilters.Add(overlayQsvFilter);
}
@@ -4191,7 +4191,7 @@ namespace MediaBrowser.Controller.MediaEncoding
{
var subSwScaleFilter = GetCustomSwScaleFilter(inW, inH, reqW, reqH, reqMaxW, reqMaxH);
subFilters.Add(subSwScaleFilter);
- overlayFilters.Add("overlay=eof_action=pass:shortest=1:repeatlast=0");
+ overlayFilters.Add("overlay=eof_action=pass:repeatlast=0");
}
}
@@ -4445,7 +4445,7 @@ namespace MediaBrowser.Controller.MediaEncoding
: string.Empty;
var overlayVaapiFilter = string.Format(
CultureInfo.InvariantCulture,
- "overlay_vaapi=eof_action=endall:shortest=1:repeatlast=0{0}",
+ "overlay_vaapi=eof_action=pass:repeatlast=0{0}",
overlaySize);
overlayFilters.Add(overlayVaapiFilter);
}
@@ -4456,7 +4456,7 @@ namespace MediaBrowser.Controller.MediaEncoding
{
var subSwScaleFilter = GetCustomSwScaleFilter(inW, inH, reqW, reqH, reqMaxW, reqMaxH);
subFilters.Add(subSwScaleFilter);
- overlayFilters.Add("overlay=eof_action=pass:shortest=1:repeatlast=0");
+ overlayFilters.Add("overlay=eof_action=pass:repeatlast=0");
if (isVaapiEncoder)
{
@@ -4616,7 +4616,7 @@ namespace MediaBrowser.Controller.MediaEncoding
subFilters.Add("hwupload=derive_device=vulkan");
subFilters.Add("format=vulkan");
- overlayFilters.Add("overlay_vulkan=eof_action=endall:shortest=1:repeatlast=0");
+ overlayFilters.Add("overlay_vulkan=eof_action=pass:repeatlast=0");
if (isSwEncoder)
{
@@ -4817,7 +4817,7 @@ namespace MediaBrowser.Controller.MediaEncoding
{
var subSwScaleFilter = GetCustomSwScaleFilter(inW, inH, reqW, reqH, reqMaxW, reqMaxH);
subFilters.Add(subSwScaleFilter);
- overlayFilters.Add("overlay=eof_action=pass:shortest=1:repeatlast=0");
+ overlayFilters.Add("overlay=eof_action=pass:repeatlast=0");
if (isVaapiEncoder)
{
diff --git a/MediaBrowser.Model/Devices/DeviceInfo.cs b/MediaBrowser.Model/Devices/DeviceInfo.cs
index 7a1c7a738..4962992a0 100644
--- a/MediaBrowser.Model/Devices/DeviceInfo.cs
+++ b/MediaBrowser.Model/Devices/DeviceInfo.cs
@@ -15,6 +15,8 @@ namespace MediaBrowser.Model.Devices
public string Name { get; set; }
+ public string CustomName { get; set; }
+
/// <summary>
/// Gets or sets the access token.
/// </summary>
diff --git a/MediaBrowser.Model/Dto/UpdateUserItemDataDto.cs b/MediaBrowser.Model/Dto/UpdateUserItemDataDto.cs
new file mode 100644
index 000000000..7bfedf973
--- /dev/null
+++ b/MediaBrowser.Model/Dto/UpdateUserItemDataDto.cs
@@ -0,0 +1,76 @@
+using System;
+
+namespace MediaBrowser.Model.Dto
+{
+ /// <summary>
+ /// This is used by the api to get information about a item user data.
+ /// </summary>
+ public class UpdateUserItemDataDto
+ {
+ /// <summary>
+ /// Gets or sets the rating.
+ /// </summary>
+ /// <value>The rating.</value>
+ public double? Rating { get; set; }
+
+ /// <summary>
+ /// Gets or sets the played percentage.
+ /// </summary>
+ /// <value>The played percentage.</value>
+ public double? PlayedPercentage { get; set; }
+
+ /// <summary>
+ /// Gets or sets the unplayed item count.
+ /// </summary>
+ /// <value>The unplayed item count.</value>
+ public int? UnplayedItemCount { get; set; }
+
+ /// <summary>
+ /// Gets or sets the playback position ticks.
+ /// </summary>
+ /// <value>The playback position ticks.</value>
+ public long? PlaybackPositionTicks { get; set; }
+
+ /// <summary>
+ /// Gets or sets the play count.
+ /// </summary>
+ /// <value>The play count.</value>
+ public int? PlayCount { get; set; }
+
+ /// <summary>
+ /// Gets or sets a value indicating whether this instance is favorite.
+ /// </summary>
+ /// <value><c>true</c> if this instance is favorite; otherwise, <c>false</c>.</value>
+ public bool? IsFavorite { get; set; }
+
+ /// <summary>
+ /// Gets or sets a value indicating whether this <see cref="UpdateUserItemDataDto" /> is likes.
+ /// </summary>
+ /// <value><c>null</c> if [likes] contains no value, <c>true</c> if [likes]; otherwise, <c>false</c>.</value>
+ public bool? Likes { get; set; }
+
+ /// <summary>
+ /// Gets or sets the last played date.
+ /// </summary>
+ /// <value>The last played date.</value>
+ public DateTime? LastPlayedDate { get; set; }
+
+ /// <summary>
+ /// Gets or sets a value indicating whether this <see cref="UserItemDataDto" /> is played.
+ /// </summary>
+ /// <value><c>true</c> if played; otherwise, <c>false</c>.</value>
+ public bool? Played { get; set; }
+
+ /// <summary>
+ /// Gets or sets the key.
+ /// </summary>
+ /// <value>The key.</value>
+ public string? Key { get; set; }
+
+ /// <summary>
+ /// Gets or sets the item identifier.
+ /// </summary>
+ /// <value>The item identifier.</value>
+ public string? ItemId { get; set; }
+ }
+}
diff --git a/MediaBrowser.Model/Entities/UserDataSaveReason.cs b/MediaBrowser.Model/Entities/UserDataSaveReason.cs
index 20404e6f4..b8e73a98c 100644
--- a/MediaBrowser.Model/Entities/UserDataSaveReason.cs
+++ b/MediaBrowser.Model/Entities/UserDataSaveReason.cs
@@ -33,6 +33,11 @@ namespace MediaBrowser.Model.Entities
/// <summary>
/// The import.
/// </summary>
- Import = 6
+ Import = 6,
+
+ /// <summary>
+ /// API call updated item user data.
+ /// </summary>
+ UpdateUserData = 7,
}
}
diff --git a/tests/Jellyfin.Server.Implementations.Tests/Library/AudioResolverTests.cs b/tests/Jellyfin.Server.Implementations.Tests/Library/AudioResolverTests.cs
index 16202aea9..5aa7c04f6 100644
--- a/tests/Jellyfin.Server.Implementations.Tests/Library/AudioResolverTests.cs
+++ b/tests/Jellyfin.Server.Implementations.Tests/Library/AudioResolverTests.cs
@@ -63,7 +63,7 @@ public class AudioResolverTests
null,
Mock.Of<ILibraryManager>())
{
- CollectionType = CollectionType.Books,
+ CollectionType = CollectionType.books,
FileInfo = new FileSystemMetadata
{
FullName = parent,
diff --git a/tests/Jellyfin.Server.Implementations.Tests/Library/EpisodeResolverTest.cs b/tests/Jellyfin.Server.Implementations.Tests/Library/EpisodeResolverTest.cs
index 92bac722b..cc2e47c33 100644
--- a/tests/Jellyfin.Server.Implementations.Tests/Library/EpisodeResolverTest.cs
+++ b/tests/Jellyfin.Server.Implementations.Tests/Library/EpisodeResolverTest.cs
@@ -29,7 +29,7 @@ namespace Jellyfin.Server.Implementations.Tests.Library
null)
{
Parent = parent,
- CollectionType = CollectionType.TvShows,
+ CollectionType = CollectionType.tvshows,
FileInfo = new FileSystemMetadata
{
FullName = "All My Children/Season 01/Extras/All My Children S01E01 - Behind The Scenes.mkv"
@@ -52,7 +52,7 @@ namespace Jellyfin.Server.Implementations.Tests.Library
null)
{
Parent = series,
- CollectionType = CollectionType.TvShows,
+ CollectionType = CollectionType.tvshows,
FileInfo = new FileSystemMetadata
{
FullName = "Extras/Extras S01E01.mkv"