< Summary - Jellyfin

Information
Class: MediaBrowser.Controller.Playlists.Playlist
Assembly: MediaBrowser.Controller
File(s): /srv/git/jellyfin/MediaBrowser.Controller/Playlists/Playlist.cs
Line coverage
12%
Covered lines: 12
Uncovered lines: 84
Coverable lines: 96
Total lines: 276
Line coverage: 12.5%
Branch coverage
0%
Covered branches: 0
Total branches: 30
Branch coverage: 0%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Coverage history

Coverage history 0 25 50 75 100

Metrics

File(s)

/srv/git/jellyfin/MediaBrowser.Controller/Playlists/Playlist.cs

#LineLine coverage
 1#nullable disable
 2
 3#pragma warning disable CS1591
 4
 5using System;
 6using System.Collections.Generic;
 7using System.IO;
 8using System.Linq;
 9using System.Text.Json.Serialization;
 10using System.Threading;
 11using System.Threading.Tasks;
 12using Jellyfin.Data;
 13using Jellyfin.Data.Enums;
 14using Jellyfin.Database.Implementations.Entities;
 15using Jellyfin.Database.Implementations.Enums;
 16using MediaBrowser.Controller.Dto;
 17using MediaBrowser.Controller.Entities;
 18using MediaBrowser.Controller.Entities.Audio;
 19using MediaBrowser.Controller.Providers;
 20using MediaBrowser.Model.Entities;
 21
 22namespace MediaBrowser.Controller.Playlists
 23{
 24    public class Playlist : Folder, IHasShares
 25    {
 126        public static readonly IReadOnlyList<string> SupportedExtensions =
 127        [
 128            ".m3u",
 129            ".m3u8",
 130            ".pls",
 131            ".wpl",
 132            ".zpl"
 133        ];
 34
 135        public Playlist()
 36        {
 137            Shares = [];
 138            OpenAccess = false;
 139        }
 40
 41        public Guid OwnerUserId { get; set; }
 42
 43        public bool OpenAccess { get; set; }
 44
 45        public IReadOnlyList<PlaylistUserPermissions> Shares { get; set; }
 46
 47        [JsonIgnore]
 048        public bool IsFile => IsPlaylistFile(Path);
 49
 50        [JsonIgnore]
 51        public override string ContainingFolderPath
 52        {
 53            get
 54            {
 055                var path = Path;
 56
 057                if (IsPlaylistFile(path))
 58                {
 059                    return System.IO.Path.GetDirectoryName(path);
 60                }
 61
 062                return path;
 63            }
 64        }
 65
 66        [JsonIgnore]
 067        protected override bool FilterLinkedChildrenPerUser => true;
 68
 69        [JsonIgnore]
 070        public override bool SupportsInheritedParentImages => false;
 71
 72        [JsonIgnore]
 073        public override bool SupportsPlayedStatus => MediaType == Jellyfin.Data.Enums.MediaType.Video;
 74
 75        [JsonIgnore]
 076        public override bool AlwaysScanInternalMetadataPath => true;
 77
 78        [JsonIgnore]
 079        public override bool SupportsCumulativeRunTimeTicks => true;
 80
 81        [JsonIgnore]
 082        public override bool IsPreSorted => true;
 83
 84        public MediaType PlaylistMediaType { get; set; }
 85
 86        [JsonIgnore]
 087        public override MediaType MediaType => PlaylistMediaType;
 88
 89        [JsonIgnore]
 90        private bool IsSharedItem
 91        {
 92            get
 93            {
 094                var path = Path;
 95
 096                if (string.IsNullOrEmpty(path))
 97                {
 098                    return false;
 99                }
 100
 0101                return FileSystem.ContainsSubPath(ConfigurationManager.ApplicationPaths.DataPath, path);
 102            }
 103        }
 104
 105        public static bool IsPlaylistFile(string path)
 106        {
 107            // The path will sometimes be a directory and "Path.HasExtension" returns true if the name contains a '.' (d
 0108            return System.IO.Path.HasExtension(path) && !Directory.Exists(path);
 109        }
 110
 111        public void SetMediaType(MediaType? value)
 112        {
 0113            PlaylistMediaType = value ?? MediaType.Unknown;
 0114        }
 115
 116        public override double GetDefaultPrimaryImageAspectRatio()
 117        {
 0118            return 1;
 119        }
 120
 121        public override bool IsAuthorizedToDelete(User user, List<Folder> allCollectionFolders)
 122        {
 0123            return true;
 124        }
 125
 126        public override bool IsSaveLocalMetadataEnabled()
 127        {
 0128            return true;
 129        }
 130
 131        protected override List<BaseItem> LoadChildren()
 132        {
 133            // Save a trip to the database
 0134            return [];
 135        }
 136
 137        protected override Task ValidateChildrenInternal(IProgress<double> progress, bool recursive, bool refreshChildMe
 138        {
 0139            return Task.CompletedTask;
 140        }
 141
 142        public override IReadOnlyList<BaseItem> GetChildren(User user, bool includeLinkedChildren, InternalItemsQuery qu
 143        {
 0144            return GetPlayableItems(user, query);
 145        }
 146
 147        protected override IReadOnlyList<BaseItem> GetNonCachedChildren(IDirectoryService directoryService)
 148        {
 0149            return [];
 150        }
 151
 152        public override IReadOnlyList<BaseItem> GetRecursiveChildren(User user, InternalItemsQuery query, out int totalC
 153        {
 0154            var items = GetPlayableItems(user, query);
 0155            totalCount = items.Count;
 0156            return items;
 157        }
 158
 159        public IReadOnlyList<Tuple<LinkedChild, BaseItem>> GetManageableItems()
 160        {
 0161            return GetLinkedChildrenInfos();
 162        }
 163
 164        private IReadOnlyList<BaseItem> GetPlayableItems(User user, InternalItemsQuery query)
 165        {
 0166            query ??= new InternalItemsQuery(user);
 167
 0168            query.IsFolder = false;
 169
 0170            return base.GetChildren(user, true, query);
 171        }
 172
 173        public static IReadOnlyList<BaseItem> GetPlaylistItems(IEnumerable<BaseItem> inputItems, User user, DtoOptions o
 174        {
 0175            if (user is not null)
 176            {
 0177                inputItems = inputItems.Where(i => i.IsVisible(user));
 178            }
 179
 0180            var list = new List<BaseItem>();
 181
 0182            foreach (var item in inputItems)
 183            {
 0184                var playlistItems = GetPlaylistItems(item, user, options);
 0185                list.AddRange(playlistItems);
 186            }
 187
 0188            return list;
 189        }
 190
 191        private static IEnumerable<BaseItem> GetPlaylistItems(BaseItem item, User user, DtoOptions options)
 192        {
 0193            if (item is MusicGenre musicGenre)
 194            {
 0195                return LibraryManager.GetItemList(new InternalItemsQuery(user)
 0196                {
 0197                    Recursive = true,
 0198                    IncludeItemTypes = [BaseItemKind.Audio],
 0199                    GenreIds = [musicGenre.Id],
 0200                    OrderBy = [(ItemSortBy.AlbumArtist, SortOrder.Ascending), (ItemSortBy.Album, SortOrder.Ascending), (
 0201                    DtoOptions = options
 0202                });
 203            }
 204
 0205            if (item is MusicArtist musicArtist)
 206            {
 0207                return LibraryManager.GetItemList(new InternalItemsQuery(user)
 0208                {
 0209                    Recursive = true,
 0210                    IncludeItemTypes = [BaseItemKind.Audio],
 0211                    ArtistIds = [musicArtist.Id],
 0212                    OrderBy = [(ItemSortBy.AlbumArtist, SortOrder.Ascending), (ItemSortBy.Album, SortOrder.Ascending), (
 0213                    DtoOptions = options
 0214                });
 215            }
 216
 0217            if (item is Folder folder)
 218            {
 0219                var query = new InternalItemsQuery(user)
 0220                {
 0221                    Recursive = true,
 0222                    IsFolder = false,
 0223                    MediaTypes = [MediaType.Audio, MediaType.Video],
 0224                    EnableTotalRecordCount = false,
 0225                    DtoOptions = options
 0226                };
 227
 0228                return folder.GetItemList(query);
 229            }
 230
 0231            return [item];
 232        }
 233
 234        public override bool IsVisible(User user, bool skipAllowedTagsCheck = false)
 235        {
 0236            if (!IsSharedItem)
 237            {
 0238                return base.IsVisible(user, skipAllowedTagsCheck);
 239            }
 240
 0241            if (OpenAccess)
 242            {
 0243                return true;
 244            }
 245
 0246            var userId = user.Id;
 0247            if (userId.Equals(OwnerUserId))
 248            {
 0249                return true;
 250            }
 251
 0252            var shares = Shares;
 0253            if (shares.Count == 0)
 254            {
 0255                return false;
 256            }
 257
 0258            return shares.Any(s => s.UserId.Equals(userId));
 259        }
 260
 261        public override bool CanDelete(User user)
 262        {
 0263            return user.HasPermission(PermissionKind.IsAdministrator) || user.Id.Equals(OwnerUserId);
 264        }
 265
 266        public override bool IsVisibleStandalone(User user)
 267        {
 0268            if (!IsSharedItem)
 269            {
 0270                return base.IsVisibleStandalone(user);
 271            }
 272
 0273            return IsVisible(user);
 274        }
 275    }
 276}

Methods/Properties

.cctor()
.ctor()
get_IsFile()
get_ContainingFolderPath()
get_FilterLinkedChildrenPerUser()
get_SupportsInheritedParentImages()
get_SupportsPlayedStatus()
get_AlwaysScanInternalMetadataPath()
get_SupportsCumulativeRunTimeTicks()
get_IsPreSorted()
get_MediaType()
get_IsSharedItem()
IsPlaylistFile(System.String)
SetMediaType(System.Nullable`1<Jellyfin.Data.Enums.MediaType>)
GetDefaultPrimaryImageAspectRatio()
IsAuthorizedToDelete(Jellyfin.Database.Implementations.Entities.User,System.Collections.Generic.List`1<MediaBrowser.Controller.Entities.Folder>)
IsSaveLocalMetadataEnabled()
LoadChildren()
ValidateChildrenInternal(System.IProgress`1<System.Double>,System.Boolean,System.Boolean,System.Boolean,MediaBrowser.Controller.Providers.MetadataRefreshOptions,MediaBrowser.Controller.Providers.IDirectoryService,System.Threading.CancellationToken)
GetChildren(Jellyfin.Database.Implementations.Entities.User,System.Boolean,MediaBrowser.Controller.Entities.InternalItemsQuery)
GetNonCachedChildren(MediaBrowser.Controller.Providers.IDirectoryService)
GetRecursiveChildren(Jellyfin.Database.Implementations.Entities.User,MediaBrowser.Controller.Entities.InternalItemsQuery,System.Int32&)
GetManageableItems()
GetPlayableItems(Jellyfin.Database.Implementations.Entities.User,MediaBrowser.Controller.Entities.InternalItemsQuery)
GetPlaylistItems(System.Collections.Generic.IEnumerable`1<MediaBrowser.Controller.Entities.BaseItem>,Jellyfin.Database.Implementations.Entities.User,MediaBrowser.Controller.Dto.DtoOptions)
GetPlaylistItems(MediaBrowser.Controller.Entities.BaseItem,Jellyfin.Database.Implementations.Entities.User,MediaBrowser.Controller.Dto.DtoOptions)
IsVisible(Jellyfin.Database.Implementations.Entities.User,System.Boolean)
CanDelete(Jellyfin.Database.Implementations.Entities.User)
IsVisibleStandalone(Jellyfin.Database.Implementations.Entities.User)