From 9bdb99fe92edaf06679ef855eae9f8bb69b970df Mon Sep 17 00:00:00 2001 From: Luke Foust Date: Sun, 22 Mar 2020 12:58:53 -0700 Subject: [PATCH 01/81] Add type to externalids to distinguish them in the UI --- .../Providers/IExternalId.cs | 19 +++++++++++++ .../Providers/ExternalIdInfo.cs | 6 ++++ .../Manager/ProviderManager.cs | 1 + .../Movies/MovieExternalIds.cs | 6 ++++ .../Music/MusicExternalIds.cs | 3 ++ .../Plugins/AudioDb/ExternalIds.cs | 16 +++++++++-- .../Plugins/MusicBrainz/ExternalIds.cs | 28 +++++++++++++++---- MediaBrowser.Providers/TV/TvExternalIds.cs | 12 ++++++++ .../Tmdb/BoxSets/TmdbBoxSetExternalId.cs | 3 ++ .../Tmdb/Movies/TmdbMovieExternalId.cs | 3 ++ .../Tmdb/People/TmdbPersonExternalId.cs | 3 ++ .../Tmdb/TV/TmdbSeriesExternalId.cs | 3 ++ 12 files changed, 96 insertions(+), 7 deletions(-) diff --git a/MediaBrowser.Controller/Providers/IExternalId.cs b/MediaBrowser.Controller/Providers/IExternalId.cs index d7e337bdab..157a2076eb 100644 --- a/MediaBrowser.Controller/Providers/IExternalId.cs +++ b/MediaBrowser.Controller/Providers/IExternalId.cs @@ -8,8 +8,27 @@ namespace MediaBrowser.Controller.Providers string Key { get; } + ExternalIdType Type { get; } + string UrlFormatString { get; } bool Supports(IHasProviderIds item); } + + public enum ExternalIdType + { + None, + Album, + AlbumArtist, + Artist, + BoxSet, + Episode, + Movie, + OtherArtist, + Person, + ReleaseGroup, + Season, + Series, + Track + } } diff --git a/MediaBrowser.Model/Providers/ExternalIdInfo.cs b/MediaBrowser.Model/Providers/ExternalIdInfo.cs index 2b481ad7ed..8d6d911434 100644 --- a/MediaBrowser.Model/Providers/ExternalIdInfo.cs +++ b/MediaBrowser.Model/Providers/ExternalIdInfo.cs @@ -16,6 +16,12 @@ namespace MediaBrowser.Model.Providers /// The key. public string Key { get; set; } + /// + /// Gets or sets the type. + /// + /// The type. + public string Type { get; set; } + /// /// Gets or sets the URL format string. /// diff --git a/MediaBrowser.Providers/Manager/ProviderManager.cs b/MediaBrowser.Providers/Manager/ProviderManager.cs index e7b349f67b..608a0cd194 100644 --- a/MediaBrowser.Providers/Manager/ProviderManager.cs +++ b/MediaBrowser.Providers/Manager/ProviderManager.cs @@ -910,6 +910,7 @@ namespace MediaBrowser.Providers.Manager { Name = i.Name, Key = i.Key, + Type = i.Type == ExternalIdType.None ? null : i.Type.ToString(), UrlFormatString = i.UrlFormatString }); diff --git a/MediaBrowser.Providers/Movies/MovieExternalIds.cs b/MediaBrowser.Providers/Movies/MovieExternalIds.cs index 55810b1ed8..1ede0e7a5f 100644 --- a/MediaBrowser.Providers/Movies/MovieExternalIds.cs +++ b/MediaBrowser.Providers/Movies/MovieExternalIds.cs @@ -15,6 +15,9 @@ namespace MediaBrowser.Providers.Movies /// public string Key => MetadataProviders.Imdb.ToString(); + /// + public ExternalIdType Type => ExternalIdType.None; + /// public string UrlFormatString => "https://www.imdb.com/title/{0}"; @@ -39,6 +42,9 @@ namespace MediaBrowser.Providers.Movies /// public string Key => MetadataProviders.Imdb.ToString(); + /// + public ExternalIdType Type => ExternalIdType.Person; + /// public string UrlFormatString => "https://www.imdb.com/name/{0}"; diff --git a/MediaBrowser.Providers/Music/MusicExternalIds.cs b/MediaBrowser.Providers/Music/MusicExternalIds.cs index 628b9a9a10..54e0347138 100644 --- a/MediaBrowser.Providers/Music/MusicExternalIds.cs +++ b/MediaBrowser.Providers/Music/MusicExternalIds.cs @@ -12,6 +12,9 @@ namespace MediaBrowser.Providers.Music /// public string Key => "IMVDb"; + /// + public ExternalIdType Type => ExternalIdType.None; + /// public string UrlFormatString => null; diff --git a/MediaBrowser.Providers/Plugins/AudioDb/ExternalIds.cs b/MediaBrowser.Providers/Plugins/AudioDb/ExternalIds.cs index 2d8cb431ca..785185d61f 100644 --- a/MediaBrowser.Providers/Plugins/AudioDb/ExternalIds.cs +++ b/MediaBrowser.Providers/Plugins/AudioDb/ExternalIds.cs @@ -12,6 +12,9 @@ namespace MediaBrowser.Providers.Plugins.AudioDb /// public string Key => MetadataProviders.AudioDbAlbum.ToString(); + /// + public ExternalIdType Type => ExternalIdType.None; + /// public string UrlFormatString => "https://www.theaudiodb.com/album/{0}"; @@ -22,11 +25,14 @@ namespace MediaBrowser.Providers.Plugins.AudioDb public class AudioDbOtherAlbumExternalId : IExternalId { /// - public string Name => "TheAudioDb Album"; + public string Name => "TheAudioDb"; /// public string Key => MetadataProviders.AudioDbAlbum.ToString(); + /// + public ExternalIdType Type => ExternalIdType.Album; + /// public string UrlFormatString => "https://www.theaudiodb.com/album/{0}"; @@ -42,6 +48,9 @@ namespace MediaBrowser.Providers.Plugins.AudioDb /// public string Key => MetadataProviders.AudioDbArtist.ToString(); + /// + public ExternalIdType Type => ExternalIdType.Artist; + /// public string UrlFormatString => "https://www.theaudiodb.com/artist/{0}"; @@ -52,11 +61,14 @@ namespace MediaBrowser.Providers.Plugins.AudioDb public class AudioDbOtherArtistExternalId : IExternalId { /// - public string Name => "TheAudioDb Artist"; + public string Name => "TheAudioDb"; /// public string Key => MetadataProviders.AudioDbArtist.ToString(); + /// + public ExternalIdType Type => ExternalIdType.OtherArtist; + /// public string UrlFormatString => "https://www.theaudiodb.com/artist/{0}"; diff --git a/MediaBrowser.Providers/Plugins/MusicBrainz/ExternalIds.cs b/MediaBrowser.Providers/Plugins/MusicBrainz/ExternalIds.cs index 03565a34c4..ed9fa6307f 100644 --- a/MediaBrowser.Providers/Plugins/MusicBrainz/ExternalIds.cs +++ b/MediaBrowser.Providers/Plugins/MusicBrainz/ExternalIds.cs @@ -8,11 +8,14 @@ namespace MediaBrowser.Providers.Music public class MusicBrainzReleaseGroupExternalId : IExternalId { /// - public string Name => "MusicBrainz Release Group"; + public string Name => "MusicBrainz"; /// public string Key => MetadataProviders.MusicBrainzReleaseGroup.ToString(); + /// + public ExternalIdType Type => ExternalIdType.ReleaseGroup; + /// public string UrlFormatString => Plugin.Instance.Configuration.Server + "/release-group/{0}"; @@ -23,11 +26,14 @@ namespace MediaBrowser.Providers.Music public class MusicBrainzAlbumArtistExternalId : IExternalId { /// - public string Name => "MusicBrainz Album Artist"; + public string Name => "MusicBrainz"; /// public string Key => MetadataProviders.MusicBrainzAlbumArtist.ToString(); + /// + public ExternalIdType Type => ExternalIdType.AlbumArtist; + /// public string UrlFormatString => Plugin.Instance.Configuration.Server + "/artist/{0}"; @@ -38,11 +44,14 @@ namespace MediaBrowser.Providers.Music public class MusicBrainzAlbumExternalId : IExternalId { /// - public string Name => "MusicBrainz Album"; + public string Name => "MusicBrainz"; /// public string Key => MetadataProviders.MusicBrainzAlbum.ToString(); + /// + public ExternalIdType Type => ExternalIdType.Album; + /// public string UrlFormatString => Plugin.Instance.Configuration.Server + "/release/{0}"; @@ -58,6 +67,9 @@ namespace MediaBrowser.Providers.Music /// public string Key => MetadataProviders.MusicBrainzArtist.ToString(); + /// + public ExternalIdType Type => ExternalIdType.Artist; + /// public string UrlFormatString => Plugin.Instance.Configuration.Server + "/artist/{0}"; @@ -68,12 +80,15 @@ namespace MediaBrowser.Providers.Music public class MusicBrainzOtherArtistExternalId : IExternalId { /// - public string Name => "MusicBrainz Artist"; + public string Name => "MusicBrainz"; /// public string Key => MetadataProviders.MusicBrainzArtist.ToString(); + /// + public ExternalIdType Type => ExternalIdType.OtherArtist; + /// public string UrlFormatString => Plugin.Instance.Configuration.Server + "/artist/{0}"; @@ -84,11 +99,14 @@ namespace MediaBrowser.Providers.Music public class MusicBrainzTrackId : IExternalId { /// - public string Name => "MusicBrainz Track"; + public string Name => "MusicBrainz"; /// public string Key => MetadataProviders.MusicBrainzTrack.ToString(); + /// + public ExternalIdType Type => ExternalIdType.Track; + /// public string UrlFormatString => Plugin.Instance.Configuration.Server + "/track/{0}"; diff --git a/MediaBrowser.Providers/TV/TvExternalIds.cs b/MediaBrowser.Providers/TV/TvExternalIds.cs index baf8542851..a3c24f7dd4 100644 --- a/MediaBrowser.Providers/TV/TvExternalIds.cs +++ b/MediaBrowser.Providers/TV/TvExternalIds.cs @@ -13,6 +13,9 @@ namespace MediaBrowser.Providers.TV /// public string Key => MetadataProviders.Zap2It.ToString(); + /// + public ExternalIdType Type => ExternalIdType.None; + /// public string UrlFormatString => "http://tvlistings.zap2it.com/overview.html?programSeriesId={0}"; @@ -28,6 +31,9 @@ namespace MediaBrowser.Providers.TV /// public string Key => MetadataProviders.Tvdb.ToString(); + /// + public ExternalIdType Type => ExternalIdType.None; + /// public string UrlFormatString => TvdbUtils.TvdbBaseUrl + "?tab=series&id={0}"; @@ -44,6 +50,9 @@ namespace MediaBrowser.Providers.TV /// public string Key => MetadataProviders.Tvdb.ToString(); + /// + public ExternalIdType Type => ExternalIdType.Season; + /// public string UrlFormatString => null; @@ -59,6 +68,9 @@ namespace MediaBrowser.Providers.TV /// public string Key => MetadataProviders.Tvdb.ToString(); + /// + public ExternalIdType Type => ExternalIdType.Episode; + /// public string UrlFormatString => TvdbUtils.TvdbBaseUrl + "?tab=episode&id={0}"; diff --git a/MediaBrowser.Providers/Tmdb/BoxSets/TmdbBoxSetExternalId.cs b/MediaBrowser.Providers/Tmdb/BoxSets/TmdbBoxSetExternalId.cs index 187295e1e4..a51355254d 100644 --- a/MediaBrowser.Providers/Tmdb/BoxSets/TmdbBoxSetExternalId.cs +++ b/MediaBrowser.Providers/Tmdb/BoxSets/TmdbBoxSetExternalId.cs @@ -13,6 +13,9 @@ namespace MediaBrowser.Providers.Tmdb.BoxSets /// public string Key => MetadataProviders.TmdbCollection.ToString(); + /// + public ExternalIdType Type => ExternalIdType.BoxSet; + /// public string UrlFormatString => TmdbUtils.BaseTmdbUrl + "collection/{0}"; diff --git a/MediaBrowser.Providers/Tmdb/Movies/TmdbMovieExternalId.cs b/MediaBrowser.Providers/Tmdb/Movies/TmdbMovieExternalId.cs index fc7a4583fd..af565b079b 100644 --- a/MediaBrowser.Providers/Tmdb/Movies/TmdbMovieExternalId.cs +++ b/MediaBrowser.Providers/Tmdb/Movies/TmdbMovieExternalId.cs @@ -14,6 +14,9 @@ namespace MediaBrowser.Providers.Tmdb.Movies /// public string Key => MetadataProviders.Tmdb.ToString(); + /// + public ExternalIdType Type => ExternalIdType.Movie; + /// public string UrlFormatString => TmdbUtils.BaseTmdbUrl + "movie/{0}"; diff --git a/MediaBrowser.Providers/Tmdb/People/TmdbPersonExternalId.cs b/MediaBrowser.Providers/Tmdb/People/TmdbPersonExternalId.cs index 2c61bc70aa..1ec43c2696 100644 --- a/MediaBrowser.Providers/Tmdb/People/TmdbPersonExternalId.cs +++ b/MediaBrowser.Providers/Tmdb/People/TmdbPersonExternalId.cs @@ -12,6 +12,9 @@ namespace MediaBrowser.Providers.Tmdb.People /// public string Key => MetadataProviders.Tmdb.ToString(); + /// + public ExternalIdType Type => ExternalIdType.Person; + /// public string UrlFormatString => TmdbUtils.BaseTmdbUrl + "person/{0}"; diff --git a/MediaBrowser.Providers/Tmdb/TV/TmdbSeriesExternalId.cs b/MediaBrowser.Providers/Tmdb/TV/TmdbSeriesExternalId.cs index 524a3b05e2..43ef06bf7a 100644 --- a/MediaBrowser.Providers/Tmdb/TV/TmdbSeriesExternalId.cs +++ b/MediaBrowser.Providers/Tmdb/TV/TmdbSeriesExternalId.cs @@ -12,6 +12,9 @@ namespace MediaBrowser.Providers.Tmdb.TV /// public string Key => MetadataProviders.Tmdb.ToString(); + /// + public ExternalIdType Type => ExternalIdType.Series; + /// public string UrlFormatString => TmdbUtils.BaseTmdbUrl + "tv/{0}"; From 0fb78cf54b51843c54e7ff59d191c490a5b196cd Mon Sep 17 00:00:00 2001 From: Luke Foust Date: Thu, 26 Mar 2020 14:26:12 -0700 Subject: [PATCH 02/81] Add documentation around Name, Id, and Type. Changed ExternalIdType to ExternalIdMediaType --- .../Providers/ExternalIdMediaType.cs | 45 +++++++++++++++++++ .../Providers/IExternalId.cs | 27 ++++------- .../Providers/ExternalIdInfo.cs | 17 ++++--- .../Manager/ProviderManager.cs | 2 +- .../Movies/MovieExternalIds.cs | 4 +- .../Music/MusicExternalIds.cs | 2 +- .../Plugins/AudioDb/ExternalIds.cs | 8 ++-- .../Plugins/MusicBrainz/ExternalIds.cs | 12 ++--- MediaBrowser.Providers/TV/TvExternalIds.cs | 8 ++-- .../Tmdb/BoxSets/TmdbBoxSetExternalId.cs | 2 +- .../Tmdb/Movies/TmdbMovieExternalId.cs | 2 +- .../Tmdb/People/TmdbPersonExternalId.cs | 2 +- .../Tmdb/TV/TmdbSeriesExternalId.cs | 2 +- 13 files changed, 84 insertions(+), 49 deletions(-) create mode 100644 MediaBrowser.Controller/Providers/ExternalIdMediaType.cs diff --git a/MediaBrowser.Controller/Providers/ExternalIdMediaType.cs b/MediaBrowser.Controller/Providers/ExternalIdMediaType.cs new file mode 100644 index 0000000000..470f1e24c0 --- /dev/null +++ b/MediaBrowser.Controller/Providers/ExternalIdMediaType.cs @@ -0,0 +1,45 @@ +namespace MediaBrowser.Controller.Providers +{ + /// The specific media type of an . + public enum ExternalIdMediaType + { + /// There is no specific media type + None, + + /// A music album + Album, + + /// The artist of a music album + AlbumArtist, + + /// The artist of a media item + Artist, + + /// A boxed set of media + BoxSet, + + /// A series episode + Episode, + + /// A movie + Movie, + + /// An alternative artist apart from the main artist + OtherArtist, + + /// A person + Person, + + /// A release group + ReleaseGroup, + + /// A single season of a series + Season, + + /// A series + Series, + + /// A music track + Track + } +} diff --git a/MediaBrowser.Controller/Providers/IExternalId.cs b/MediaBrowser.Controller/Providers/IExternalId.cs index 157a2076eb..c877ffe1fe 100644 --- a/MediaBrowser.Controller/Providers/IExternalId.cs +++ b/MediaBrowser.Controller/Providers/IExternalId.cs @@ -2,33 +2,24 @@ using MediaBrowser.Model.Entities; namespace MediaBrowser.Controller.Providers { + /// Represents and identifier for an external provider. public interface IExternalId { + /// Gets the name used to identify this provider string Name { get; } + /// Gets the unique key to distinguish this provider/type pair. This should be unique across providers. string Key { get; } - ExternalIdType Type { get; } + /// Gets the specific media type for this id. + ExternalIdMediaType Type { get; } + /// Gets the url format string for this id. string UrlFormatString { get; } + /// Determines whether this id supports a given item type. + /// The item. + /// True if this item is supported, otherwise false. bool Supports(IHasProviderIds item); } - - public enum ExternalIdType - { - None, - Album, - AlbumArtist, - Artist, - BoxSet, - Episode, - Movie, - OtherArtist, - Person, - ReleaseGroup, - Season, - Series, - Track - } } diff --git a/MediaBrowser.Model/Providers/ExternalIdInfo.cs b/MediaBrowser.Model/Providers/ExternalIdInfo.cs index 8d6d911434..befcc309bf 100644 --- a/MediaBrowser.Model/Providers/ExternalIdInfo.cs +++ b/MediaBrowser.Model/Providers/ExternalIdInfo.cs @@ -1,31 +1,30 @@ -#pragma warning disable CS1591 - namespace MediaBrowser.Model.Providers { + /// + /// Represents the external id information for serialization to the client. + /// public class ExternalIdInfo { /// - /// Gets or sets the name. + /// Gets or sets the name of the external id provider (IE: IMDB, MusicBrainz, etc). /// - /// The name. public string Name { get; set; } /// - /// Gets or sets the key. + /// Gets or sets the unique key for this id. This key should be unique across all providers. /// - /// The key. public string Key { get; set; } /// - /// Gets or sets the type. + /// Gets or sets the media type (Album, Artist, etc). + /// This can be null if there is no specific type. + /// This string is also used to localize the media type on the client. /// - /// The type. public string Type { get; set; } /// /// Gets or sets the URL format string. /// - /// The URL format string. public string UrlFormatString { get; set; } } } diff --git a/MediaBrowser.Providers/Manager/ProviderManager.cs b/MediaBrowser.Providers/Manager/ProviderManager.cs index 608a0cd194..fee988d50a 100644 --- a/MediaBrowser.Providers/Manager/ProviderManager.cs +++ b/MediaBrowser.Providers/Manager/ProviderManager.cs @@ -910,7 +910,7 @@ namespace MediaBrowser.Providers.Manager { Name = i.Name, Key = i.Key, - Type = i.Type == ExternalIdType.None ? null : i.Type.ToString(), + Type = i.Type == ExternalIdMediaType.None ? null : i.Type.ToString(), UrlFormatString = i.UrlFormatString }); diff --git a/MediaBrowser.Providers/Movies/MovieExternalIds.cs b/MediaBrowser.Providers/Movies/MovieExternalIds.cs index 1ede0e7a5f..a7b359a2d8 100644 --- a/MediaBrowser.Providers/Movies/MovieExternalIds.cs +++ b/MediaBrowser.Providers/Movies/MovieExternalIds.cs @@ -16,7 +16,7 @@ namespace MediaBrowser.Providers.Movies public string Key => MetadataProviders.Imdb.ToString(); /// - public ExternalIdType Type => ExternalIdType.None; + public ExternalIdMediaType Type => ExternalIdMediaType.None; /// public string UrlFormatString => "https://www.imdb.com/title/{0}"; @@ -43,7 +43,7 @@ namespace MediaBrowser.Providers.Movies public string Key => MetadataProviders.Imdb.ToString(); /// - public ExternalIdType Type => ExternalIdType.Person; + public ExternalIdMediaType Type => ExternalIdMediaType.Person; /// public string UrlFormatString => "https://www.imdb.com/name/{0}"; diff --git a/MediaBrowser.Providers/Music/MusicExternalIds.cs b/MediaBrowser.Providers/Music/MusicExternalIds.cs index 54e0347138..19879411e1 100644 --- a/MediaBrowser.Providers/Music/MusicExternalIds.cs +++ b/MediaBrowser.Providers/Music/MusicExternalIds.cs @@ -13,7 +13,7 @@ namespace MediaBrowser.Providers.Music public string Key => "IMVDb"; /// - public ExternalIdType Type => ExternalIdType.None; + public ExternalIdMediaType Type => ExternalIdMediaType.None; /// public string UrlFormatString => null; diff --git a/MediaBrowser.Providers/Plugins/AudioDb/ExternalIds.cs b/MediaBrowser.Providers/Plugins/AudioDb/ExternalIds.cs index 785185d61f..cd65acb769 100644 --- a/MediaBrowser.Providers/Plugins/AudioDb/ExternalIds.cs +++ b/MediaBrowser.Providers/Plugins/AudioDb/ExternalIds.cs @@ -13,7 +13,7 @@ namespace MediaBrowser.Providers.Plugins.AudioDb public string Key => MetadataProviders.AudioDbAlbum.ToString(); /// - public ExternalIdType Type => ExternalIdType.None; + public ExternalIdMediaType Type => ExternalIdMediaType.None; /// public string UrlFormatString => "https://www.theaudiodb.com/album/{0}"; @@ -31,7 +31,7 @@ namespace MediaBrowser.Providers.Plugins.AudioDb public string Key => MetadataProviders.AudioDbAlbum.ToString(); /// - public ExternalIdType Type => ExternalIdType.Album; + public ExternalIdMediaType Type => ExternalIdMediaType.Album; /// public string UrlFormatString => "https://www.theaudiodb.com/album/{0}"; @@ -49,7 +49,7 @@ namespace MediaBrowser.Providers.Plugins.AudioDb public string Key => MetadataProviders.AudioDbArtist.ToString(); /// - public ExternalIdType Type => ExternalIdType.Artist; + public ExternalIdMediaType Type => ExternalIdMediaType.Artist; /// public string UrlFormatString => "https://www.theaudiodb.com/artist/{0}"; @@ -67,7 +67,7 @@ namespace MediaBrowser.Providers.Plugins.AudioDb public string Key => MetadataProviders.AudioDbArtist.ToString(); /// - public ExternalIdType Type => ExternalIdType.OtherArtist; + public ExternalIdMediaType Type => ExternalIdMediaType.OtherArtist; /// public string UrlFormatString => "https://www.theaudiodb.com/artist/{0}"; diff --git a/MediaBrowser.Providers/Plugins/MusicBrainz/ExternalIds.cs b/MediaBrowser.Providers/Plugins/MusicBrainz/ExternalIds.cs index ed9fa6307f..7d74a8d351 100644 --- a/MediaBrowser.Providers/Plugins/MusicBrainz/ExternalIds.cs +++ b/MediaBrowser.Providers/Plugins/MusicBrainz/ExternalIds.cs @@ -14,7 +14,7 @@ namespace MediaBrowser.Providers.Music public string Key => MetadataProviders.MusicBrainzReleaseGroup.ToString(); /// - public ExternalIdType Type => ExternalIdType.ReleaseGroup; + public ExternalIdMediaType Type => ExternalIdMediaType.ReleaseGroup; /// public string UrlFormatString => Plugin.Instance.Configuration.Server + "/release-group/{0}"; @@ -32,7 +32,7 @@ namespace MediaBrowser.Providers.Music public string Key => MetadataProviders.MusicBrainzAlbumArtist.ToString(); /// - public ExternalIdType Type => ExternalIdType.AlbumArtist; + public ExternalIdMediaType Type => ExternalIdMediaType.AlbumArtist; /// public string UrlFormatString => Plugin.Instance.Configuration.Server + "/artist/{0}"; @@ -50,7 +50,7 @@ namespace MediaBrowser.Providers.Music public string Key => MetadataProviders.MusicBrainzAlbum.ToString(); /// - public ExternalIdType Type => ExternalIdType.Album; + public ExternalIdMediaType Type => ExternalIdMediaType.Album; /// public string UrlFormatString => Plugin.Instance.Configuration.Server + "/release/{0}"; @@ -68,7 +68,7 @@ namespace MediaBrowser.Providers.Music public string Key => MetadataProviders.MusicBrainzArtist.ToString(); /// - public ExternalIdType Type => ExternalIdType.Artist; + public ExternalIdMediaType Type => ExternalIdMediaType.Artist; /// public string UrlFormatString => Plugin.Instance.Configuration.Server + "/artist/{0}"; @@ -87,7 +87,7 @@ namespace MediaBrowser.Providers.Music public string Key => MetadataProviders.MusicBrainzArtist.ToString(); /// - public ExternalIdType Type => ExternalIdType.OtherArtist; + public ExternalIdMediaType Type => ExternalIdMediaType.OtherArtist; /// public string UrlFormatString => Plugin.Instance.Configuration.Server + "/artist/{0}"; @@ -105,7 +105,7 @@ namespace MediaBrowser.Providers.Music public string Key => MetadataProviders.MusicBrainzTrack.ToString(); /// - public ExternalIdType Type => ExternalIdType.Track; + public ExternalIdMediaType Type => ExternalIdMediaType.Track; /// public string UrlFormatString => Plugin.Instance.Configuration.Server + "/track/{0}"; diff --git a/MediaBrowser.Providers/TV/TvExternalIds.cs b/MediaBrowser.Providers/TV/TvExternalIds.cs index a3c24f7dd4..75d8b6bf58 100644 --- a/MediaBrowser.Providers/TV/TvExternalIds.cs +++ b/MediaBrowser.Providers/TV/TvExternalIds.cs @@ -14,7 +14,7 @@ namespace MediaBrowser.Providers.TV public string Key => MetadataProviders.Zap2It.ToString(); /// - public ExternalIdType Type => ExternalIdType.None; + public ExternalIdMediaType Type => ExternalIdMediaType.None; /// public string UrlFormatString => "http://tvlistings.zap2it.com/overview.html?programSeriesId={0}"; @@ -32,7 +32,7 @@ namespace MediaBrowser.Providers.TV public string Key => MetadataProviders.Tvdb.ToString(); /// - public ExternalIdType Type => ExternalIdType.None; + public ExternalIdMediaType Type => ExternalIdMediaType.None; /// public string UrlFormatString => TvdbUtils.TvdbBaseUrl + "?tab=series&id={0}"; @@ -51,7 +51,7 @@ namespace MediaBrowser.Providers.TV public string Key => MetadataProviders.Tvdb.ToString(); /// - public ExternalIdType Type => ExternalIdType.Season; + public ExternalIdMediaType Type => ExternalIdMediaType.Season; /// public string UrlFormatString => null; @@ -69,7 +69,7 @@ namespace MediaBrowser.Providers.TV public string Key => MetadataProviders.Tvdb.ToString(); /// - public ExternalIdType Type => ExternalIdType.Episode; + public ExternalIdMediaType Type => ExternalIdMediaType.Episode; /// public string UrlFormatString => TvdbUtils.TvdbBaseUrl + "?tab=episode&id={0}"; diff --git a/MediaBrowser.Providers/Tmdb/BoxSets/TmdbBoxSetExternalId.cs b/MediaBrowser.Providers/Tmdb/BoxSets/TmdbBoxSetExternalId.cs index a51355254d..a83cde93c6 100644 --- a/MediaBrowser.Providers/Tmdb/BoxSets/TmdbBoxSetExternalId.cs +++ b/MediaBrowser.Providers/Tmdb/BoxSets/TmdbBoxSetExternalId.cs @@ -14,7 +14,7 @@ namespace MediaBrowser.Providers.Tmdb.BoxSets public string Key => MetadataProviders.TmdbCollection.ToString(); /// - public ExternalIdType Type => ExternalIdType.BoxSet; + public ExternalIdMediaType Type => ExternalIdMediaType.BoxSet; /// public string UrlFormatString => TmdbUtils.BaseTmdbUrl + "collection/{0}"; diff --git a/MediaBrowser.Providers/Tmdb/Movies/TmdbMovieExternalId.cs b/MediaBrowser.Providers/Tmdb/Movies/TmdbMovieExternalId.cs index af565b079b..f9ea000676 100644 --- a/MediaBrowser.Providers/Tmdb/Movies/TmdbMovieExternalId.cs +++ b/MediaBrowser.Providers/Tmdb/Movies/TmdbMovieExternalId.cs @@ -15,7 +15,7 @@ namespace MediaBrowser.Providers.Tmdb.Movies public string Key => MetadataProviders.Tmdb.ToString(); /// - public ExternalIdType Type => ExternalIdType.Movie; + public ExternalIdMediaType Type => ExternalIdMediaType.Movie; /// public string UrlFormatString => TmdbUtils.BaseTmdbUrl + "movie/{0}"; diff --git a/MediaBrowser.Providers/Tmdb/People/TmdbPersonExternalId.cs b/MediaBrowser.Providers/Tmdb/People/TmdbPersonExternalId.cs index 1ec43c2696..854fd41560 100644 --- a/MediaBrowser.Providers/Tmdb/People/TmdbPersonExternalId.cs +++ b/MediaBrowser.Providers/Tmdb/People/TmdbPersonExternalId.cs @@ -13,7 +13,7 @@ namespace MediaBrowser.Providers.Tmdb.People public string Key => MetadataProviders.Tmdb.ToString(); /// - public ExternalIdType Type => ExternalIdType.Person; + public ExternalIdMediaType Type => ExternalIdMediaType.Person; /// public string UrlFormatString => TmdbUtils.BaseTmdbUrl + "person/{0}"; diff --git a/MediaBrowser.Providers/Tmdb/TV/TmdbSeriesExternalId.cs b/MediaBrowser.Providers/Tmdb/TV/TmdbSeriesExternalId.cs index 43ef06bf7a..770448c7f7 100644 --- a/MediaBrowser.Providers/Tmdb/TV/TmdbSeriesExternalId.cs +++ b/MediaBrowser.Providers/Tmdb/TV/TmdbSeriesExternalId.cs @@ -13,7 +13,7 @@ namespace MediaBrowser.Providers.Tmdb.TV public string Key => MetadataProviders.Tmdb.ToString(); /// - public ExternalIdType Type => ExternalIdType.Series; + public ExternalIdMediaType Type => ExternalIdMediaType.Series; /// public string UrlFormatString => TmdbUtils.BaseTmdbUrl + "tv/{0}"; From 526e47c3624aca76234006b031b74e595f295cc8 Mon Sep 17 00:00:00 2001 From: Mark Monteiro Date: Sun, 17 May 2020 14:22:36 -0400 Subject: [PATCH 03/81] Clean up documentation --- .../Providers/ExternalIdMediaType.cs | 60 ++++++++++++++----- .../Providers/IExternalId.cs | 21 +++++-- .../Providers/ExternalIdInfo.cs | 2 +- 3 files changed, 63 insertions(+), 20 deletions(-) diff --git a/MediaBrowser.Controller/Providers/ExternalIdMediaType.cs b/MediaBrowser.Controller/Providers/ExternalIdMediaType.cs index 470f1e24c0..dc87aefc83 100644 --- a/MediaBrowser.Controller/Providers/ExternalIdMediaType.cs +++ b/MediaBrowser.Controller/Providers/ExternalIdMediaType.cs @@ -1,45 +1,77 @@ namespace MediaBrowser.Controller.Providers { - /// The specific media type of an . + /// + /// The specific media type of an . + /// + /// + /// This is used as a translation key for clients. + /// public enum ExternalIdMediaType { - /// There is no specific media type + /// + /// There is no specific media type associated with the external id, or the external provider only has one + /// id type so there is no need to be specific. + /// None, - /// A music album + /// + /// A music album. + /// Album, - /// The artist of a music album + /// + /// The artist of a music album. + /// AlbumArtist, - /// The artist of a media item + /// + /// The artist of a media item. + /// Artist, - /// A boxed set of media + /// + /// A boxed set of media. + /// BoxSet, - /// A series episode + /// + /// A series episode. + /// Episode, - /// A movie + /// + /// A movie. + /// Movie, - /// An alternative artist apart from the main artist + /// + /// An alternative artist apart from the main artist. + /// OtherArtist, - /// A person + /// + /// A person. + /// Person, - /// A release group + /// + /// A release group. + /// ReleaseGroup, - /// A single season of a series + /// + /// A single season of a series. + /// Season, - /// A series + /// + /// A series. + /// Series, - /// A music track + /// + /// A music track. + /// Track } } diff --git a/MediaBrowser.Controller/Providers/IExternalId.cs b/MediaBrowser.Controller/Providers/IExternalId.cs index c877ffe1fe..f362c42eb1 100644 --- a/MediaBrowser.Controller/Providers/IExternalId.cs +++ b/MediaBrowser.Controller/Providers/IExternalId.cs @@ -5,19 +5,30 @@ namespace MediaBrowser.Controller.Providers /// Represents and identifier for an external provider. public interface IExternalId { - /// Gets the name used to identify this provider + /// + /// Gets the display name of the provider associated with this ID type. + /// string Name { get; } - /// Gets the unique key to distinguish this provider/type pair. This should be unique across providers. + /// + /// Gets the unique key to distinguish this provider/type pair. This should be unique across providers. + /// + // TODO: This property is not actually unique at the moment. It should be updated to be unique. string Key { get; } - /// Gets the specific media type for this id. + /// + /// Gets the specific media type for this id. + /// ExternalIdMediaType Type { get; } - /// Gets the url format string for this id. + /// + /// Gets the URL format string for this id. + /// string UrlFormatString { get; } - /// Determines whether this id supports a given item type. + /// + /// Determines whether this id supports a given item type. + /// /// The item. /// True if this item is supported, otherwise false. bool Supports(IHasProviderIds item); diff --git a/MediaBrowser.Model/Providers/ExternalIdInfo.cs b/MediaBrowser.Model/Providers/ExternalIdInfo.cs index befcc309bf..ca0c857c41 100644 --- a/MediaBrowser.Model/Providers/ExternalIdInfo.cs +++ b/MediaBrowser.Model/Providers/ExternalIdInfo.cs @@ -6,7 +6,7 @@ namespace MediaBrowser.Model.Providers public class ExternalIdInfo { /// - /// Gets or sets the name of the external id provider (IE: IMDB, MusicBrainz, etc). + /// Gets or sets the display name of the external id provider (IE: IMDB, MusicBrainz, etc). /// public string Name { get; set; } From e5c857ac3639c2aba34e59437e501bfdd6b1ba02 Mon Sep 17 00:00:00 2001 From: Mark Monteiro Date: Sun, 17 May 2020 15:29:53 -0400 Subject: [PATCH 04/81] Rename external id type 'None' to 'General' --- MediaBrowser.Controller/Providers/ExternalIdMediaType.cs | 2 +- MediaBrowser.Providers/Manager/ProviderManager.cs | 2 +- MediaBrowser.Providers/Movies/MovieExternalIds.cs | 2 +- MediaBrowser.Providers/Music/MusicExternalIds.cs | 2 +- MediaBrowser.Providers/Plugins/AudioDb/ExternalIds.cs | 2 +- MediaBrowser.Providers/TV/TvExternalIds.cs | 4 ++-- 6 files changed, 7 insertions(+), 7 deletions(-) diff --git a/MediaBrowser.Controller/Providers/ExternalIdMediaType.cs b/MediaBrowser.Controller/Providers/ExternalIdMediaType.cs index dc87aefc83..43c2b2f223 100644 --- a/MediaBrowser.Controller/Providers/ExternalIdMediaType.cs +++ b/MediaBrowser.Controller/Providers/ExternalIdMediaType.cs @@ -12,7 +12,7 @@ namespace MediaBrowser.Controller.Providers /// There is no specific media type associated with the external id, or the external provider only has one /// id type so there is no need to be specific. /// - None, + General, /// /// A music album. diff --git a/MediaBrowser.Providers/Manager/ProviderManager.cs b/MediaBrowser.Providers/Manager/ProviderManager.cs index b0380ae31b..49083c01b7 100644 --- a/MediaBrowser.Providers/Manager/ProviderManager.cs +++ b/MediaBrowser.Providers/Manager/ProviderManager.cs @@ -908,7 +908,7 @@ namespace MediaBrowser.Providers.Manager { Name = i.Name, Key = i.Key, - Type = i.Type == ExternalIdMediaType.None ? null : i.Type.ToString(), + Type = i.Type == ExternalIdMediaType.General ? null : i.Type.ToString(), UrlFormatString = i.UrlFormatString }); } diff --git a/MediaBrowser.Providers/Movies/MovieExternalIds.cs b/MediaBrowser.Providers/Movies/MovieExternalIds.cs index a7b359a2d8..1098b98820 100644 --- a/MediaBrowser.Providers/Movies/MovieExternalIds.cs +++ b/MediaBrowser.Providers/Movies/MovieExternalIds.cs @@ -16,7 +16,7 @@ namespace MediaBrowser.Providers.Movies public string Key => MetadataProviders.Imdb.ToString(); /// - public ExternalIdMediaType Type => ExternalIdMediaType.None; + public ExternalIdMediaType Type => ExternalIdMediaType.General; /// public string UrlFormatString => "https://www.imdb.com/title/{0}"; diff --git a/MediaBrowser.Providers/Music/MusicExternalIds.cs b/MediaBrowser.Providers/Music/MusicExternalIds.cs index 19879411e1..351cdb92c4 100644 --- a/MediaBrowser.Providers/Music/MusicExternalIds.cs +++ b/MediaBrowser.Providers/Music/MusicExternalIds.cs @@ -13,7 +13,7 @@ namespace MediaBrowser.Providers.Music public string Key => "IMVDb"; /// - public ExternalIdMediaType Type => ExternalIdMediaType.None; + public ExternalIdMediaType Type => ExternalIdMediaType.General; /// public string UrlFormatString => null; diff --git a/MediaBrowser.Providers/Plugins/AudioDb/ExternalIds.cs b/MediaBrowser.Providers/Plugins/AudioDb/ExternalIds.cs index cd65acb769..150149a6b3 100644 --- a/MediaBrowser.Providers/Plugins/AudioDb/ExternalIds.cs +++ b/MediaBrowser.Providers/Plugins/AudioDb/ExternalIds.cs @@ -13,7 +13,7 @@ namespace MediaBrowser.Providers.Plugins.AudioDb public string Key => MetadataProviders.AudioDbAlbum.ToString(); /// - public ExternalIdMediaType Type => ExternalIdMediaType.None; + public ExternalIdMediaType Type => ExternalIdMediaType.General; /// public string UrlFormatString => "https://www.theaudiodb.com/album/{0}"; diff --git a/MediaBrowser.Providers/TV/TvExternalIds.cs b/MediaBrowser.Providers/TV/TvExternalIds.cs index 75d8b6bf58..ccdf8bd29d 100644 --- a/MediaBrowser.Providers/TV/TvExternalIds.cs +++ b/MediaBrowser.Providers/TV/TvExternalIds.cs @@ -14,7 +14,7 @@ namespace MediaBrowser.Providers.TV public string Key => MetadataProviders.Zap2It.ToString(); /// - public ExternalIdMediaType Type => ExternalIdMediaType.None; + public ExternalIdMediaType Type => ExternalIdMediaType.General; /// public string UrlFormatString => "http://tvlistings.zap2it.com/overview.html?programSeriesId={0}"; @@ -32,7 +32,7 @@ namespace MediaBrowser.Providers.TV public string Key => MetadataProviders.Tvdb.ToString(); /// - public ExternalIdMediaType Type => ExternalIdMediaType.None; + public ExternalIdMediaType Type => ExternalIdMediaType.General; /// public string UrlFormatString => TvdbUtils.TvdbBaseUrl + "?tab=series&id={0}"; From 422d5b2b68bdce4da385a19382a7a52060cb10b2 Mon Sep 17 00:00:00 2001 From: Mark Monteiro Date: Sun, 17 May 2020 15:57:24 -0400 Subject: [PATCH 05/81] Move ExternalIdMediaType enum to MediaBrowser.Model --- MediaBrowser.Controller/Providers/IExternalId.cs | 1 + .../Providers/ExternalIdMediaType.cs | 2 +- MediaBrowser.Providers/Movies/MovieExternalIds.cs | 1 + MediaBrowser.Providers/Music/MusicExternalIds.cs | 1 + MediaBrowser.Providers/Plugins/AudioDb/ExternalIds.cs | 1 + MediaBrowser.Providers/Plugins/MusicBrainz/ExternalIds.cs | 1 + MediaBrowser.Providers/TV/TvExternalIds.cs | 1 + MediaBrowser.Providers/Tmdb/BoxSets/TmdbBoxSetExternalId.cs | 1 + MediaBrowser.Providers/Tmdb/Movies/TmdbMovieExternalId.cs | 1 + MediaBrowser.Providers/Tmdb/People/TmdbPersonExternalId.cs | 1 + MediaBrowser.Providers/Tmdb/TV/TmdbSeriesExternalId.cs | 1 + 11 files changed, 11 insertions(+), 1 deletion(-) rename {MediaBrowser.Controller => MediaBrowser.Model}/Providers/ExternalIdMediaType.cs (97%) diff --git a/MediaBrowser.Controller/Providers/IExternalId.cs b/MediaBrowser.Controller/Providers/IExternalId.cs index f362c42eb1..0fcf0c09de 100644 --- a/MediaBrowser.Controller/Providers/IExternalId.cs +++ b/MediaBrowser.Controller/Providers/IExternalId.cs @@ -1,4 +1,5 @@ using MediaBrowser.Model.Entities; +using MediaBrowser.Model.Providers; namespace MediaBrowser.Controller.Providers { diff --git a/MediaBrowser.Controller/Providers/ExternalIdMediaType.cs b/MediaBrowser.Model/Providers/ExternalIdMediaType.cs similarity index 97% rename from MediaBrowser.Controller/Providers/ExternalIdMediaType.cs rename to MediaBrowser.Model/Providers/ExternalIdMediaType.cs index 43c2b2f223..8c5356c926 100644 --- a/MediaBrowser.Controller/Providers/ExternalIdMediaType.cs +++ b/MediaBrowser.Model/Providers/ExternalIdMediaType.cs @@ -1,4 +1,4 @@ -namespace MediaBrowser.Controller.Providers +namespace MediaBrowser.Model.Providers { /// /// The specific media type of an . diff --git a/MediaBrowser.Providers/Movies/MovieExternalIds.cs b/MediaBrowser.Providers/Movies/MovieExternalIds.cs index 1098b98820..a82394a931 100644 --- a/MediaBrowser.Providers/Movies/MovieExternalIds.cs +++ b/MediaBrowser.Providers/Movies/MovieExternalIds.cs @@ -4,6 +4,7 @@ using MediaBrowser.Controller.Entities.TV; using MediaBrowser.Controller.LiveTv; using MediaBrowser.Controller.Providers; using MediaBrowser.Model.Entities; +using MediaBrowser.Model.Providers; namespace MediaBrowser.Providers.Movies { diff --git a/MediaBrowser.Providers/Music/MusicExternalIds.cs b/MediaBrowser.Providers/Music/MusicExternalIds.cs index 351cdb92c4..12323bcbd2 100644 --- a/MediaBrowser.Providers/Music/MusicExternalIds.cs +++ b/MediaBrowser.Providers/Music/MusicExternalIds.cs @@ -1,6 +1,7 @@ using MediaBrowser.Controller.Entities; using MediaBrowser.Controller.Providers; using MediaBrowser.Model.Entities; +using MediaBrowser.Model.Providers; namespace MediaBrowser.Providers.Music { diff --git a/MediaBrowser.Providers/Plugins/AudioDb/ExternalIds.cs b/MediaBrowser.Providers/Plugins/AudioDb/ExternalIds.cs index 150149a6b3..126a79a08e 100644 --- a/MediaBrowser.Providers/Plugins/AudioDb/ExternalIds.cs +++ b/MediaBrowser.Providers/Plugins/AudioDb/ExternalIds.cs @@ -1,6 +1,7 @@ using MediaBrowser.Controller.Entities.Audio; using MediaBrowser.Controller.Providers; using MediaBrowser.Model.Entities; +using MediaBrowser.Model.Providers; namespace MediaBrowser.Providers.Plugins.AudioDb { diff --git a/MediaBrowser.Providers/Plugins/MusicBrainz/ExternalIds.cs b/MediaBrowser.Providers/Plugins/MusicBrainz/ExternalIds.cs index 7d74a8d351..5756cb8381 100644 --- a/MediaBrowser.Providers/Plugins/MusicBrainz/ExternalIds.cs +++ b/MediaBrowser.Providers/Plugins/MusicBrainz/ExternalIds.cs @@ -1,6 +1,7 @@ using MediaBrowser.Controller.Entities.Audio; using MediaBrowser.Controller.Providers; using MediaBrowser.Model.Entities; +using MediaBrowser.Model.Providers; using MediaBrowser.Providers.Plugins.MusicBrainz; namespace MediaBrowser.Providers.Music diff --git a/MediaBrowser.Providers/TV/TvExternalIds.cs b/MediaBrowser.Providers/TV/TvExternalIds.cs index ccdf8bd29d..4c005666fa 100644 --- a/MediaBrowser.Providers/TV/TvExternalIds.cs +++ b/MediaBrowser.Providers/TV/TvExternalIds.cs @@ -1,6 +1,7 @@ using MediaBrowser.Controller.Entities.TV; using MediaBrowser.Controller.Providers; using MediaBrowser.Model.Entities; +using MediaBrowser.Model.Providers; using MediaBrowser.Providers.Plugins.TheTvdb; namespace MediaBrowser.Providers.TV diff --git a/MediaBrowser.Providers/Tmdb/BoxSets/TmdbBoxSetExternalId.cs b/MediaBrowser.Providers/Tmdb/BoxSets/TmdbBoxSetExternalId.cs index a83cde93c6..6e131029cd 100644 --- a/MediaBrowser.Providers/Tmdb/BoxSets/TmdbBoxSetExternalId.cs +++ b/MediaBrowser.Providers/Tmdb/BoxSets/TmdbBoxSetExternalId.cs @@ -2,6 +2,7 @@ using MediaBrowser.Controller.Entities; using MediaBrowser.Controller.Entities.Movies; using MediaBrowser.Controller.Providers; using MediaBrowser.Model.Entities; +using MediaBrowser.Model.Providers; namespace MediaBrowser.Providers.Tmdb.BoxSets { diff --git a/MediaBrowser.Providers/Tmdb/Movies/TmdbMovieExternalId.cs b/MediaBrowser.Providers/Tmdb/Movies/TmdbMovieExternalId.cs index f9ea000676..cffd335429 100644 --- a/MediaBrowser.Providers/Tmdb/Movies/TmdbMovieExternalId.cs +++ b/MediaBrowser.Providers/Tmdb/Movies/TmdbMovieExternalId.cs @@ -3,6 +3,7 @@ using MediaBrowser.Controller.Entities.Movies; using MediaBrowser.Controller.LiveTv; using MediaBrowser.Controller.Providers; using MediaBrowser.Model.Entities; +using MediaBrowser.Model.Providers; namespace MediaBrowser.Providers.Tmdb.Movies { diff --git a/MediaBrowser.Providers/Tmdb/People/TmdbPersonExternalId.cs b/MediaBrowser.Providers/Tmdb/People/TmdbPersonExternalId.cs index 854fd41560..460740254f 100644 --- a/MediaBrowser.Providers/Tmdb/People/TmdbPersonExternalId.cs +++ b/MediaBrowser.Providers/Tmdb/People/TmdbPersonExternalId.cs @@ -1,6 +1,7 @@ using MediaBrowser.Controller.Entities; using MediaBrowser.Controller.Providers; using MediaBrowser.Model.Entities; +using MediaBrowser.Model.Providers; namespace MediaBrowser.Providers.Tmdb.People { diff --git a/MediaBrowser.Providers/Tmdb/TV/TmdbSeriesExternalId.cs b/MediaBrowser.Providers/Tmdb/TV/TmdbSeriesExternalId.cs index 770448c7f7..8adcc4d465 100644 --- a/MediaBrowser.Providers/Tmdb/TV/TmdbSeriesExternalId.cs +++ b/MediaBrowser.Providers/Tmdb/TV/TmdbSeriesExternalId.cs @@ -1,6 +1,7 @@ using MediaBrowser.Controller.Entities.TV; using MediaBrowser.Controller.Providers; using MediaBrowser.Model.Entities; +using MediaBrowser.Model.Providers; namespace MediaBrowser.Providers.Tmdb.TV { From 67edf1b7f5f423ab5fa53644bacdba6974b430db Mon Sep 17 00:00:00 2001 From: Mark Monteiro Date: Sun, 17 May 2020 15:59:13 -0400 Subject: [PATCH 06/81] Do not convert 'Type' value to string unnecessarily, and do not replace 'General' type with null --- MediaBrowser.Controller/Providers/IExternalId.cs | 3 +++ MediaBrowser.Model/Providers/ExternalIdInfo.cs | 9 +++++---- MediaBrowser.Providers/Manager/ProviderManager.cs | 2 +- 3 files changed, 9 insertions(+), 5 deletions(-) diff --git a/MediaBrowser.Controller/Providers/IExternalId.cs b/MediaBrowser.Controller/Providers/IExternalId.cs index 0fcf0c09de..149c58847c 100644 --- a/MediaBrowser.Controller/Providers/IExternalId.cs +++ b/MediaBrowser.Controller/Providers/IExternalId.cs @@ -20,6 +20,9 @@ namespace MediaBrowser.Controller.Providers /// /// Gets the specific media type for this id. /// + /// + /// This can be used along with the to localize the external id on the client. + /// ExternalIdMediaType Type { get; } /// diff --git a/MediaBrowser.Model/Providers/ExternalIdInfo.cs b/MediaBrowser.Model/Providers/ExternalIdInfo.cs index ca0c857c41..493c6136ea 100644 --- a/MediaBrowser.Model/Providers/ExternalIdInfo.cs +++ b/MediaBrowser.Model/Providers/ExternalIdInfo.cs @@ -16,11 +16,12 @@ namespace MediaBrowser.Model.Providers public string Key { get; set; } /// - /// Gets or sets the media type (Album, Artist, etc). - /// This can be null if there is no specific type. - /// This string is also used to localize the media type on the client. + /// Gets or sets the specific media type for this id. /// - public string Type { get; set; } + /// + /// This can be used along with the to localize the external id on the client. + /// + public ExternalIdMediaType Type { get; set; } /// /// Gets or sets the URL format string. diff --git a/MediaBrowser.Providers/Manager/ProviderManager.cs b/MediaBrowser.Providers/Manager/ProviderManager.cs index 49083c01b7..4ab7581238 100644 --- a/MediaBrowser.Providers/Manager/ProviderManager.cs +++ b/MediaBrowser.Providers/Manager/ProviderManager.cs @@ -908,7 +908,7 @@ namespace MediaBrowser.Providers.Manager { Name = i.Name, Key = i.Key, - Type = i.Type == ExternalIdMediaType.General ? null : i.Type.ToString(), + Type = i.Type, UrlFormatString = i.UrlFormatString }); } From c82f7eeca14839cd21e1904f79007c0d24c85f8f Mon Sep 17 00:00:00 2001 From: Mark Monteiro Date: Sun, 17 May 2020 16:24:28 -0400 Subject: [PATCH 07/81] Clean up some doc comments --- MediaBrowser.Controller/Providers/IExternalId.cs | 9 ++++++--- MediaBrowser.Model/Providers/ExternalIdInfo.cs | 4 +++- MediaBrowser.Model/Providers/ExternalIdMediaType.cs | 8 ++++---- 3 files changed, 13 insertions(+), 8 deletions(-) diff --git a/MediaBrowser.Controller/Providers/IExternalId.cs b/MediaBrowser.Controller/Providers/IExternalId.cs index 149c58847c..ae87aab9ed 100644 --- a/MediaBrowser.Controller/Providers/IExternalId.cs +++ b/MediaBrowser.Controller/Providers/IExternalId.cs @@ -3,7 +3,9 @@ using MediaBrowser.Model.Providers; namespace MediaBrowser.Controller.Providers { - /// Represents and identifier for an external provider. + /// + /// Represents an identifier for an external provider. + /// public interface IExternalId { /// @@ -14,11 +16,12 @@ namespace MediaBrowser.Controller.Providers /// /// Gets the unique key to distinguish this provider/type pair. This should be unique across providers. /// - // TODO: This property is not actually unique at the moment. It should be updated to be unique. + // TODO: This property is not actually unique across the concrete types at the moment. It should be updated to be unique. string Key { get; } /// - /// Gets the specific media type for this id. + /// Gets the specific media type for this id. This is used to distinguish between the different + /// external id types for providers with multiple ids. /// /// /// This can be used along with the to localize the external id on the client. diff --git a/MediaBrowser.Model/Providers/ExternalIdInfo.cs b/MediaBrowser.Model/Providers/ExternalIdInfo.cs index 493c6136ea..92a6395468 100644 --- a/MediaBrowser.Model/Providers/ExternalIdInfo.cs +++ b/MediaBrowser.Model/Providers/ExternalIdInfo.cs @@ -13,10 +13,12 @@ namespace MediaBrowser.Model.Providers /// /// Gets or sets the unique key for this id. This key should be unique across all providers. /// + // TODO: This property is not actually unique across the concrete types at the moment. It should be updated to be unique. public string Key { get; set; } /// - /// Gets or sets the specific media type for this id. + /// Gets or sets the specific media type for this id. This is used to distinguish between the different + /// external id types for providers with multiple ids. /// /// /// This can be used along with the to localize the external id on the client. diff --git a/MediaBrowser.Model/Providers/ExternalIdMediaType.cs b/MediaBrowser.Model/Providers/ExternalIdMediaType.cs index 8c5356c926..881cd77fc9 100644 --- a/MediaBrowser.Model/Providers/ExternalIdMediaType.cs +++ b/MediaBrowser.Model/Providers/ExternalIdMediaType.cs @@ -1,16 +1,16 @@ namespace MediaBrowser.Model.Providers { /// - /// The specific media type of an . + /// The specific media type of an . /// /// - /// This is used as a translation key for clients. + /// Client applications may use this as a translation key. /// public enum ExternalIdMediaType { /// - /// There is no specific media type associated with the external id, or the external provider only has one - /// id type so there is no need to be specific. + /// There is no specific media type associated with the external id, or this is the default id for the external + /// provider so there is no need to specify a type. /// General, From d06fee75b65def754ce58e8322a59bf8c942b82f Mon Sep 17 00:00:00 2001 From: Mark Monteiro Date: Sun, 17 May 2020 17:35:43 -0400 Subject: [PATCH 08/81] Rename Name to ProviderName --- MediaBrowser.Controller/Providers/IExternalId.cs | 4 ++-- MediaBrowser.Model/Providers/ExternalIdInfo.cs | 1 + MediaBrowser.Providers/Manager/ProviderManager.cs | 6 +++--- MediaBrowser.Providers/Movies/MovieExternalIds.cs | 4 ++-- MediaBrowser.Providers/Music/MusicExternalIds.cs | 2 +- .../Plugins/AudioDb/ExternalIds.cs | 8 ++++---- .../Plugins/MusicBrainz/ExternalIds.cs | 12 ++++++------ MediaBrowser.Providers/TV/TvExternalIds.cs | 8 ++++---- .../Tmdb/BoxSets/TmdbBoxSetExternalId.cs | 2 +- .../Tmdb/Movies/TmdbMovieExternalId.cs | 2 +- .../Tmdb/People/TmdbPersonExternalId.cs | 2 +- .../Tmdb/TV/TmdbSeriesExternalId.cs | 2 +- 12 files changed, 27 insertions(+), 26 deletions(-) diff --git a/MediaBrowser.Controller/Providers/IExternalId.cs b/MediaBrowser.Controller/Providers/IExternalId.cs index ae87aab9ed..96d1e46223 100644 --- a/MediaBrowser.Controller/Providers/IExternalId.cs +++ b/MediaBrowser.Controller/Providers/IExternalId.cs @@ -11,7 +11,7 @@ namespace MediaBrowser.Controller.Providers /// /// Gets the display name of the provider associated with this ID type. /// - string Name { get; } + string ProviderName { get; } /// /// Gets the unique key to distinguish this provider/type pair. This should be unique across providers. @@ -24,7 +24,7 @@ namespace MediaBrowser.Controller.Providers /// external id types for providers with multiple ids. /// /// - /// This can be used along with the to localize the external id on the client. + /// This can be used along with the to localize the external id on the client. /// ExternalIdMediaType Type { get; } diff --git a/MediaBrowser.Model/Providers/ExternalIdInfo.cs b/MediaBrowser.Model/Providers/ExternalIdInfo.cs index 92a6395468..445c86d733 100644 --- a/MediaBrowser.Model/Providers/ExternalIdInfo.cs +++ b/MediaBrowser.Model/Providers/ExternalIdInfo.cs @@ -8,6 +8,7 @@ namespace MediaBrowser.Model.Providers /// /// Gets or sets the display name of the external id provider (IE: IMDB, MusicBrainz, etc). /// + // TODO: This should be renamed to ProviderName public string Name { get; set; } /// diff --git a/MediaBrowser.Providers/Manager/ProviderManager.cs b/MediaBrowser.Providers/Manager/ProviderManager.cs index 4ab7581238..95133a9a7f 100644 --- a/MediaBrowser.Providers/Manager/ProviderManager.cs +++ b/MediaBrowser.Providers/Manager/ProviderManager.cs @@ -96,7 +96,7 @@ namespace MediaBrowser.Providers.Manager _metadataServices = metadataServices.OrderBy(i => i.Order).ToArray(); _metadataProviders = metadataProviders.ToArray(); - _externalIds = externalIds.OrderBy(i => i.Name).ToArray(); + _externalIds = externalIds.OrderBy(i => i.ProviderName).ToArray(); _savers = metadataSavers.Where(i => { @@ -891,7 +891,7 @@ namespace MediaBrowser.Providers.Manager return new ExternalUrl { - Name = i.Name, + Name = i.ProviderName, Url = string.Format( CultureInfo.InvariantCulture, i.UrlFormatString, @@ -906,7 +906,7 @@ namespace MediaBrowser.Providers.Manager return GetExternalIds(item) .Select(i => new ExternalIdInfo { - Name = i.Name, + Name = i.ProviderName, Key = i.Key, Type = i.Type, UrlFormatString = i.UrlFormatString diff --git a/MediaBrowser.Providers/Movies/MovieExternalIds.cs b/MediaBrowser.Providers/Movies/MovieExternalIds.cs index a82394a931..2b0c0d1c27 100644 --- a/MediaBrowser.Providers/Movies/MovieExternalIds.cs +++ b/MediaBrowser.Providers/Movies/MovieExternalIds.cs @@ -11,7 +11,7 @@ namespace MediaBrowser.Providers.Movies public class ImdbExternalId : IExternalId { /// - public string Name => "IMDb"; + public string ProviderName => "IMDb"; /// public string Key => MetadataProviders.Imdb.ToString(); @@ -38,7 +38,7 @@ namespace MediaBrowser.Providers.Movies public class ImdbPersonExternalId : IExternalId { /// - public string Name => "IMDb"; + public string ProviderName => "IMDb"; /// public string Key => MetadataProviders.Imdb.ToString(); diff --git a/MediaBrowser.Providers/Music/MusicExternalIds.cs b/MediaBrowser.Providers/Music/MusicExternalIds.cs index 12323bcbd2..4490d0f052 100644 --- a/MediaBrowser.Providers/Music/MusicExternalIds.cs +++ b/MediaBrowser.Providers/Music/MusicExternalIds.cs @@ -8,7 +8,7 @@ namespace MediaBrowser.Providers.Music public class ImvdbId : IExternalId { /// - public string Name => "IMVDb"; + public string ProviderName => "IMVDb"; /// public string Key => "IMVDb"; diff --git a/MediaBrowser.Providers/Plugins/AudioDb/ExternalIds.cs b/MediaBrowser.Providers/Plugins/AudioDb/ExternalIds.cs index 126a79a08e..e299eb3ee2 100644 --- a/MediaBrowser.Providers/Plugins/AudioDb/ExternalIds.cs +++ b/MediaBrowser.Providers/Plugins/AudioDb/ExternalIds.cs @@ -8,7 +8,7 @@ namespace MediaBrowser.Providers.Plugins.AudioDb public class AudioDbAlbumExternalId : IExternalId { /// - public string Name => "TheAudioDb"; + public string ProviderName => "TheAudioDb"; /// public string Key => MetadataProviders.AudioDbAlbum.ToString(); @@ -26,7 +26,7 @@ namespace MediaBrowser.Providers.Plugins.AudioDb public class AudioDbOtherAlbumExternalId : IExternalId { /// - public string Name => "TheAudioDb"; + public string ProviderName => "TheAudioDb"; /// public string Key => MetadataProviders.AudioDbAlbum.ToString(); @@ -44,7 +44,7 @@ namespace MediaBrowser.Providers.Plugins.AudioDb public class AudioDbArtistExternalId : IExternalId { /// - public string Name => "TheAudioDb"; + public string ProviderName => "TheAudioDb"; /// public string Key => MetadataProviders.AudioDbArtist.ToString(); @@ -62,7 +62,7 @@ namespace MediaBrowser.Providers.Plugins.AudioDb public class AudioDbOtherArtistExternalId : IExternalId { /// - public string Name => "TheAudioDb"; + public string ProviderName => "TheAudioDb"; /// public string Key => MetadataProviders.AudioDbArtist.ToString(); diff --git a/MediaBrowser.Providers/Plugins/MusicBrainz/ExternalIds.cs b/MediaBrowser.Providers/Plugins/MusicBrainz/ExternalIds.cs index 5756cb8381..247e87fd52 100644 --- a/MediaBrowser.Providers/Plugins/MusicBrainz/ExternalIds.cs +++ b/MediaBrowser.Providers/Plugins/MusicBrainz/ExternalIds.cs @@ -9,7 +9,7 @@ namespace MediaBrowser.Providers.Music public class MusicBrainzReleaseGroupExternalId : IExternalId { /// - public string Name => "MusicBrainz"; + public string ProviderName => "MusicBrainz"; /// public string Key => MetadataProviders.MusicBrainzReleaseGroup.ToString(); @@ -27,7 +27,7 @@ namespace MediaBrowser.Providers.Music public class MusicBrainzAlbumArtistExternalId : IExternalId { /// - public string Name => "MusicBrainz"; + public string ProviderName => "MusicBrainz"; /// public string Key => MetadataProviders.MusicBrainzAlbumArtist.ToString(); @@ -45,7 +45,7 @@ namespace MediaBrowser.Providers.Music public class MusicBrainzAlbumExternalId : IExternalId { /// - public string Name => "MusicBrainz"; + public string ProviderName => "MusicBrainz"; /// public string Key => MetadataProviders.MusicBrainzAlbum.ToString(); @@ -63,7 +63,7 @@ namespace MediaBrowser.Providers.Music public class MusicBrainzArtistExternalId : IExternalId { /// - public string Name => "MusicBrainz"; + public string ProviderName => "MusicBrainz"; /// public string Key => MetadataProviders.MusicBrainzArtist.ToString(); @@ -81,7 +81,7 @@ namespace MediaBrowser.Providers.Music public class MusicBrainzOtherArtistExternalId : IExternalId { /// - public string Name => "MusicBrainz"; + public string ProviderName => "MusicBrainz"; /// @@ -100,7 +100,7 @@ namespace MediaBrowser.Providers.Music public class MusicBrainzTrackId : IExternalId { /// - public string Name => "MusicBrainz"; + public string ProviderName => "MusicBrainz"; /// public string Key => MetadataProviders.MusicBrainzTrack.ToString(); diff --git a/MediaBrowser.Providers/TV/TvExternalIds.cs b/MediaBrowser.Providers/TV/TvExternalIds.cs index 4c005666fa..12ad3d8a22 100644 --- a/MediaBrowser.Providers/TV/TvExternalIds.cs +++ b/MediaBrowser.Providers/TV/TvExternalIds.cs @@ -9,7 +9,7 @@ namespace MediaBrowser.Providers.TV public class Zap2ItExternalId : IExternalId { /// - public string Name => "Zap2It"; + public string ProviderName => "Zap2It"; /// public string Key => MetadataProviders.Zap2It.ToString(); @@ -27,7 +27,7 @@ namespace MediaBrowser.Providers.TV public class TvdbExternalId : IExternalId { /// - public string Name => "TheTVDB"; + public string ProviderName => "TheTVDB"; /// public string Key => MetadataProviders.Tvdb.ToString(); @@ -46,7 +46,7 @@ namespace MediaBrowser.Providers.TV public class TvdbSeasonExternalId : IExternalId { /// - public string Name => "TheTVDB"; + public string ProviderName => "TheTVDB"; /// public string Key => MetadataProviders.Tvdb.ToString(); @@ -64,7 +64,7 @@ namespace MediaBrowser.Providers.TV public class TvdbEpisodeExternalId : IExternalId { /// - public string Name => "TheTVDB"; + public string ProviderName => "TheTVDB"; /// public string Key => MetadataProviders.Tvdb.ToString(); diff --git a/MediaBrowser.Providers/Tmdb/BoxSets/TmdbBoxSetExternalId.cs b/MediaBrowser.Providers/Tmdb/BoxSets/TmdbBoxSetExternalId.cs index 6e131029cd..1d3c80536e 100644 --- a/MediaBrowser.Providers/Tmdb/BoxSets/TmdbBoxSetExternalId.cs +++ b/MediaBrowser.Providers/Tmdb/BoxSets/TmdbBoxSetExternalId.cs @@ -9,7 +9,7 @@ namespace MediaBrowser.Providers.Tmdb.BoxSets public class TmdbBoxSetExternalId : IExternalId { /// - public string Name => TmdbUtils.ProviderName; + public string ProviderName => TmdbUtils.ProviderName; /// public string Key => MetadataProviders.TmdbCollection.ToString(); diff --git a/MediaBrowser.Providers/Tmdb/Movies/TmdbMovieExternalId.cs b/MediaBrowser.Providers/Tmdb/Movies/TmdbMovieExternalId.cs index cffd335429..75e71dda49 100644 --- a/MediaBrowser.Providers/Tmdb/Movies/TmdbMovieExternalId.cs +++ b/MediaBrowser.Providers/Tmdb/Movies/TmdbMovieExternalId.cs @@ -10,7 +10,7 @@ namespace MediaBrowser.Providers.Tmdb.Movies public class TmdbMovieExternalId : IExternalId { /// - public string Name => TmdbUtils.ProviderName; + public string ProviderName => TmdbUtils.ProviderName; /// public string Key => MetadataProviders.Tmdb.ToString(); diff --git a/MediaBrowser.Providers/Tmdb/People/TmdbPersonExternalId.cs b/MediaBrowser.Providers/Tmdb/People/TmdbPersonExternalId.cs index 460740254f..a8685d6695 100644 --- a/MediaBrowser.Providers/Tmdb/People/TmdbPersonExternalId.cs +++ b/MediaBrowser.Providers/Tmdb/People/TmdbPersonExternalId.cs @@ -8,7 +8,7 @@ namespace MediaBrowser.Providers.Tmdb.People public class TmdbPersonExternalId : IExternalId { /// - public string Name => TmdbUtils.ProviderName; + public string ProviderName => TmdbUtils.ProviderName; /// public string Key => MetadataProviders.Tmdb.ToString(); diff --git a/MediaBrowser.Providers/Tmdb/TV/TmdbSeriesExternalId.cs b/MediaBrowser.Providers/Tmdb/TV/TmdbSeriesExternalId.cs index 8adcc4d465..fd6dd9b413 100644 --- a/MediaBrowser.Providers/Tmdb/TV/TmdbSeriesExternalId.cs +++ b/MediaBrowser.Providers/Tmdb/TV/TmdbSeriesExternalId.cs @@ -8,7 +8,7 @@ namespace MediaBrowser.Providers.Tmdb.TV public class TmdbSeriesExternalId : IExternalId { /// - public string Name => TmdbUtils.ProviderName; + public string ProviderName => TmdbUtils.ProviderName; /// public string Key => MetadataProviders.Tmdb.ToString(); From 07897ec7af468f5e71fd901a8dad05911e19daf5 Mon Sep 17 00:00:00 2001 From: Mark Monteiro Date: Sat, 23 May 2020 15:49:02 -0400 Subject: [PATCH 09/81] Specify enum values for ExternalIdMediaType explicitly --- .../Providers/ExternalIdMediaType.cs | 26 +++++++++---------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/MediaBrowser.Model/Providers/ExternalIdMediaType.cs b/MediaBrowser.Model/Providers/ExternalIdMediaType.cs index 881cd77fc9..56f55d15cf 100644 --- a/MediaBrowser.Model/Providers/ExternalIdMediaType.cs +++ b/MediaBrowser.Model/Providers/ExternalIdMediaType.cs @@ -12,66 +12,66 @@ namespace MediaBrowser.Model.Providers /// There is no specific media type associated with the external id, or this is the default id for the external /// provider so there is no need to specify a type. /// - General, + General = 0, /// /// A music album. /// - Album, + Album = 1, /// /// The artist of a music album. /// - AlbumArtist, + AlbumArtist = 2, /// /// The artist of a media item. /// - Artist, + Artist = 3, /// /// A boxed set of media. /// - BoxSet, + BoxSet = 4, /// /// A series episode. /// - Episode, + Episode = 5, /// /// A movie. /// - Movie, + Movie = 6, /// /// An alternative artist apart from the main artist. /// - OtherArtist, + OtherArtist = 7, /// /// A person. /// - Person, + Person = 8, /// /// A release group. /// - ReleaseGroup, + ReleaseGroup = 9, /// /// A single season of a series. /// - Season, + Season = 10, /// /// A series. /// - Series, + Series = 11, /// /// A music track. /// - Track + Track = 12 } } From 4f6e5591ece8d9344385d13f923384abfc07b709 Mon Sep 17 00:00:00 2001 From: Mark Monteiro Date: Sat, 23 May 2020 16:08:51 -0400 Subject: [PATCH 10/81] Remove 'General' as an ExternalIdMediaType, and instead use 'null' to represent a general external id type --- MediaBrowser.Controller/Providers/IExternalId.cs | 4 +++- MediaBrowser.Model/Providers/ExternalIdInfo.cs | 4 +++- MediaBrowser.Model/Providers/ExternalIdMediaType.cs | 6 ------ MediaBrowser.Providers/Movies/MovieExternalIds.cs | 4 ++-- MediaBrowser.Providers/Music/MusicExternalIds.cs | 2 +- .../Plugins/AudioDb/ExternalIds.cs | 8 ++++---- .../Plugins/MusicBrainz/ExternalIds.cs | 12 ++++++------ MediaBrowser.Providers/TV/TvExternalIds.cs | 8 ++++---- .../Tmdb/BoxSets/TmdbBoxSetExternalId.cs | 2 +- .../Tmdb/Movies/TmdbMovieExternalId.cs | 2 +- .../Tmdb/People/TmdbPersonExternalId.cs | 2 +- .../Tmdb/TV/TmdbSeriesExternalId.cs | 2 +- 12 files changed, 27 insertions(+), 29 deletions(-) diff --git a/MediaBrowser.Controller/Providers/IExternalId.cs b/MediaBrowser.Controller/Providers/IExternalId.cs index 96d1e46223..5e38446bc9 100644 --- a/MediaBrowser.Controller/Providers/IExternalId.cs +++ b/MediaBrowser.Controller/Providers/IExternalId.cs @@ -22,11 +22,13 @@ namespace MediaBrowser.Controller.Providers /// /// Gets the specific media type for this id. This is used to distinguish between the different /// external id types for providers with multiple ids. + /// A null value indicates there is no specific media type associated with the external id, or this is the + /// default id for the external provider so there is no need to specify a type. /// /// /// This can be used along with the to localize the external id on the client. /// - ExternalIdMediaType Type { get; } + ExternalIdMediaType? Type { get; } /// /// Gets the URL format string for this id. diff --git a/MediaBrowser.Model/Providers/ExternalIdInfo.cs b/MediaBrowser.Model/Providers/ExternalIdInfo.cs index 445c86d733..7687e676f9 100644 --- a/MediaBrowser.Model/Providers/ExternalIdInfo.cs +++ b/MediaBrowser.Model/Providers/ExternalIdInfo.cs @@ -20,11 +20,13 @@ namespace MediaBrowser.Model.Providers /// /// Gets or sets the specific media type for this id. This is used to distinguish between the different /// external id types for providers with multiple ids. + /// A null value indicates there is no specific media type associated with the external id, or this is the + /// default id for the external provider so there is no need to specify a type. /// /// /// This can be used along with the to localize the external id on the client. /// - public ExternalIdMediaType Type { get; set; } + public ExternalIdMediaType? Type { get; set; } /// /// Gets or sets the URL format string. diff --git a/MediaBrowser.Model/Providers/ExternalIdMediaType.cs b/MediaBrowser.Model/Providers/ExternalIdMediaType.cs index 56f55d15cf..5303c8f58b 100644 --- a/MediaBrowser.Model/Providers/ExternalIdMediaType.cs +++ b/MediaBrowser.Model/Providers/ExternalIdMediaType.cs @@ -8,12 +8,6 @@ namespace MediaBrowser.Model.Providers /// public enum ExternalIdMediaType { - /// - /// There is no specific media type associated with the external id, or this is the default id for the external - /// provider so there is no need to specify a type. - /// - General = 0, - /// /// A music album. /// diff --git a/MediaBrowser.Providers/Movies/MovieExternalIds.cs b/MediaBrowser.Providers/Movies/MovieExternalIds.cs index 2b0c0d1c27..b43ae63ab6 100644 --- a/MediaBrowser.Providers/Movies/MovieExternalIds.cs +++ b/MediaBrowser.Providers/Movies/MovieExternalIds.cs @@ -17,7 +17,7 @@ namespace MediaBrowser.Providers.Movies public string Key => MetadataProviders.Imdb.ToString(); /// - public ExternalIdMediaType Type => ExternalIdMediaType.General; + public ExternalIdMediaType? Type => null; /// public string UrlFormatString => "https://www.imdb.com/title/{0}"; @@ -44,7 +44,7 @@ namespace MediaBrowser.Providers.Movies public string Key => MetadataProviders.Imdb.ToString(); /// - public ExternalIdMediaType Type => ExternalIdMediaType.Person; + public ExternalIdMediaType? Type => ExternalIdMediaType.Person; /// public string UrlFormatString => "https://www.imdb.com/name/{0}"; diff --git a/MediaBrowser.Providers/Music/MusicExternalIds.cs b/MediaBrowser.Providers/Music/MusicExternalIds.cs index 4490d0f052..42694fdee8 100644 --- a/MediaBrowser.Providers/Music/MusicExternalIds.cs +++ b/MediaBrowser.Providers/Music/MusicExternalIds.cs @@ -14,7 +14,7 @@ namespace MediaBrowser.Providers.Music public string Key => "IMVDb"; /// - public ExternalIdMediaType Type => ExternalIdMediaType.General; + public ExternalIdMediaType? Type => null; /// public string UrlFormatString => null; diff --git a/MediaBrowser.Providers/Plugins/AudioDb/ExternalIds.cs b/MediaBrowser.Providers/Plugins/AudioDb/ExternalIds.cs index e299eb3ee2..1dd5b21a9c 100644 --- a/MediaBrowser.Providers/Plugins/AudioDb/ExternalIds.cs +++ b/MediaBrowser.Providers/Plugins/AudioDb/ExternalIds.cs @@ -14,7 +14,7 @@ namespace MediaBrowser.Providers.Plugins.AudioDb public string Key => MetadataProviders.AudioDbAlbum.ToString(); /// - public ExternalIdMediaType Type => ExternalIdMediaType.General; + public ExternalIdMediaType? Type => null; /// public string UrlFormatString => "https://www.theaudiodb.com/album/{0}"; @@ -32,7 +32,7 @@ namespace MediaBrowser.Providers.Plugins.AudioDb public string Key => MetadataProviders.AudioDbAlbum.ToString(); /// - public ExternalIdMediaType Type => ExternalIdMediaType.Album; + public ExternalIdMediaType? Type => ExternalIdMediaType.Album; /// public string UrlFormatString => "https://www.theaudiodb.com/album/{0}"; @@ -50,7 +50,7 @@ namespace MediaBrowser.Providers.Plugins.AudioDb public string Key => MetadataProviders.AudioDbArtist.ToString(); /// - public ExternalIdMediaType Type => ExternalIdMediaType.Artist; + public ExternalIdMediaType? Type => ExternalIdMediaType.Artist; /// public string UrlFormatString => "https://www.theaudiodb.com/artist/{0}"; @@ -68,7 +68,7 @@ namespace MediaBrowser.Providers.Plugins.AudioDb public string Key => MetadataProviders.AudioDbArtist.ToString(); /// - public ExternalIdMediaType Type => ExternalIdMediaType.OtherArtist; + public ExternalIdMediaType? Type => ExternalIdMediaType.OtherArtist; /// public string UrlFormatString => "https://www.theaudiodb.com/artist/{0}"; diff --git a/MediaBrowser.Providers/Plugins/MusicBrainz/ExternalIds.cs b/MediaBrowser.Providers/Plugins/MusicBrainz/ExternalIds.cs index 247e87fd52..969bdd01d2 100644 --- a/MediaBrowser.Providers/Plugins/MusicBrainz/ExternalIds.cs +++ b/MediaBrowser.Providers/Plugins/MusicBrainz/ExternalIds.cs @@ -15,7 +15,7 @@ namespace MediaBrowser.Providers.Music public string Key => MetadataProviders.MusicBrainzReleaseGroup.ToString(); /// - public ExternalIdMediaType Type => ExternalIdMediaType.ReleaseGroup; + public ExternalIdMediaType? Type => ExternalIdMediaType.ReleaseGroup; /// public string UrlFormatString => Plugin.Instance.Configuration.Server + "/release-group/{0}"; @@ -33,7 +33,7 @@ namespace MediaBrowser.Providers.Music public string Key => MetadataProviders.MusicBrainzAlbumArtist.ToString(); /// - public ExternalIdMediaType Type => ExternalIdMediaType.AlbumArtist; + public ExternalIdMediaType? Type => ExternalIdMediaType.AlbumArtist; /// public string UrlFormatString => Plugin.Instance.Configuration.Server + "/artist/{0}"; @@ -51,7 +51,7 @@ namespace MediaBrowser.Providers.Music public string Key => MetadataProviders.MusicBrainzAlbum.ToString(); /// - public ExternalIdMediaType Type => ExternalIdMediaType.Album; + public ExternalIdMediaType? Type => ExternalIdMediaType.Album; /// public string UrlFormatString => Plugin.Instance.Configuration.Server + "/release/{0}"; @@ -69,7 +69,7 @@ namespace MediaBrowser.Providers.Music public string Key => MetadataProviders.MusicBrainzArtist.ToString(); /// - public ExternalIdMediaType Type => ExternalIdMediaType.Artist; + public ExternalIdMediaType? Type => ExternalIdMediaType.Artist; /// public string UrlFormatString => Plugin.Instance.Configuration.Server + "/artist/{0}"; @@ -88,7 +88,7 @@ namespace MediaBrowser.Providers.Music public string Key => MetadataProviders.MusicBrainzArtist.ToString(); /// - public ExternalIdMediaType Type => ExternalIdMediaType.OtherArtist; + public ExternalIdMediaType? Type => ExternalIdMediaType.OtherArtist; /// public string UrlFormatString => Plugin.Instance.Configuration.Server + "/artist/{0}"; @@ -106,7 +106,7 @@ namespace MediaBrowser.Providers.Music public string Key => MetadataProviders.MusicBrainzTrack.ToString(); /// - public ExternalIdMediaType Type => ExternalIdMediaType.Track; + public ExternalIdMediaType? Type => ExternalIdMediaType.Track; /// public string UrlFormatString => Plugin.Instance.Configuration.Server + "/track/{0}"; diff --git a/MediaBrowser.Providers/TV/TvExternalIds.cs b/MediaBrowser.Providers/TV/TvExternalIds.cs index 12ad3d8a22..2bf6020dd5 100644 --- a/MediaBrowser.Providers/TV/TvExternalIds.cs +++ b/MediaBrowser.Providers/TV/TvExternalIds.cs @@ -15,7 +15,7 @@ namespace MediaBrowser.Providers.TV public string Key => MetadataProviders.Zap2It.ToString(); /// - public ExternalIdMediaType Type => ExternalIdMediaType.General; + public ExternalIdMediaType? Type => null; /// public string UrlFormatString => "http://tvlistings.zap2it.com/overview.html?programSeriesId={0}"; @@ -33,7 +33,7 @@ namespace MediaBrowser.Providers.TV public string Key => MetadataProviders.Tvdb.ToString(); /// - public ExternalIdMediaType Type => ExternalIdMediaType.General; + public ExternalIdMediaType? Type => null; /// public string UrlFormatString => TvdbUtils.TvdbBaseUrl + "?tab=series&id={0}"; @@ -52,7 +52,7 @@ namespace MediaBrowser.Providers.TV public string Key => MetadataProviders.Tvdb.ToString(); /// - public ExternalIdMediaType Type => ExternalIdMediaType.Season; + public ExternalIdMediaType? Type => ExternalIdMediaType.Season; /// public string UrlFormatString => null; @@ -70,7 +70,7 @@ namespace MediaBrowser.Providers.TV public string Key => MetadataProviders.Tvdb.ToString(); /// - public ExternalIdMediaType Type => ExternalIdMediaType.Episode; + public ExternalIdMediaType? Type => ExternalIdMediaType.Episode; /// public string UrlFormatString => TvdbUtils.TvdbBaseUrl + "?tab=episode&id={0}"; diff --git a/MediaBrowser.Providers/Tmdb/BoxSets/TmdbBoxSetExternalId.cs b/MediaBrowser.Providers/Tmdb/BoxSets/TmdbBoxSetExternalId.cs index 1d3c80536e..bfef1e0382 100644 --- a/MediaBrowser.Providers/Tmdb/BoxSets/TmdbBoxSetExternalId.cs +++ b/MediaBrowser.Providers/Tmdb/BoxSets/TmdbBoxSetExternalId.cs @@ -15,7 +15,7 @@ namespace MediaBrowser.Providers.Tmdb.BoxSets public string Key => MetadataProviders.TmdbCollection.ToString(); /// - public ExternalIdMediaType Type => ExternalIdMediaType.BoxSet; + public ExternalIdMediaType? Type => ExternalIdMediaType.BoxSet; /// public string UrlFormatString => TmdbUtils.BaseTmdbUrl + "collection/{0}"; diff --git a/MediaBrowser.Providers/Tmdb/Movies/TmdbMovieExternalId.cs b/MediaBrowser.Providers/Tmdb/Movies/TmdbMovieExternalId.cs index 75e71dda49..5b0cd75092 100644 --- a/MediaBrowser.Providers/Tmdb/Movies/TmdbMovieExternalId.cs +++ b/MediaBrowser.Providers/Tmdb/Movies/TmdbMovieExternalId.cs @@ -16,7 +16,7 @@ namespace MediaBrowser.Providers.Tmdb.Movies public string Key => MetadataProviders.Tmdb.ToString(); /// - public ExternalIdMediaType Type => ExternalIdMediaType.Movie; + public ExternalIdMediaType? Type => ExternalIdMediaType.Movie; /// public string UrlFormatString => TmdbUtils.BaseTmdbUrl + "movie/{0}"; diff --git a/MediaBrowser.Providers/Tmdb/People/TmdbPersonExternalId.cs b/MediaBrowser.Providers/Tmdb/People/TmdbPersonExternalId.cs index a8685d6695..fa12a4581a 100644 --- a/MediaBrowser.Providers/Tmdb/People/TmdbPersonExternalId.cs +++ b/MediaBrowser.Providers/Tmdb/People/TmdbPersonExternalId.cs @@ -14,7 +14,7 @@ namespace MediaBrowser.Providers.Tmdb.People public string Key => MetadataProviders.Tmdb.ToString(); /// - public ExternalIdMediaType Type => ExternalIdMediaType.Person; + public ExternalIdMediaType? Type => ExternalIdMediaType.Person; /// public string UrlFormatString => TmdbUtils.BaseTmdbUrl + "person/{0}"; diff --git a/MediaBrowser.Providers/Tmdb/TV/TmdbSeriesExternalId.cs b/MediaBrowser.Providers/Tmdb/TV/TmdbSeriesExternalId.cs index fd6dd9b413..8513dadd21 100644 --- a/MediaBrowser.Providers/Tmdb/TV/TmdbSeriesExternalId.cs +++ b/MediaBrowser.Providers/Tmdb/TV/TmdbSeriesExternalId.cs @@ -14,7 +14,7 @@ namespace MediaBrowser.Providers.Tmdb.TV public string Key => MetadataProviders.Tmdb.ToString(); /// - public ExternalIdMediaType Type => ExternalIdMediaType.Series; + public ExternalIdMediaType? Type => ExternalIdMediaType.Series; /// public string UrlFormatString => TmdbUtils.BaseTmdbUrl + "tv/{0}"; From 68e1ecaaf9626c9596c833571bb591a326449dc8 Mon Sep 17 00:00:00 2001 From: crobibero Date: Sun, 7 Jun 2020 14:47:08 -0600 Subject: [PATCH 11/81] Remove EasyPassword from Authentication providers --- .../Users/DefaultAuthenticationProvider.cs | 24 ------------------- .../Users/InvalidAuthProvider.cs | 12 ---------- .../Authentication/IAuthenticationProvider.cs | 2 -- 3 files changed, 38 deletions(-) diff --git a/Jellyfin.Server.Implementations/Users/DefaultAuthenticationProvider.cs b/Jellyfin.Server.Implementations/Users/DefaultAuthenticationProvider.cs index b0c02030e3..9c5056a6b7 100644 --- a/Jellyfin.Server.Implementations/Users/DefaultAuthenticationProvider.cs +++ b/Jellyfin.Server.Implementations/Users/DefaultAuthenticationProvider.cs @@ -111,29 +111,5 @@ namespace Jellyfin.Server.Implementations.Users return Task.CompletedTask; } - - /// - public void ChangeEasyPassword(User user, string newPassword, string newPasswordHash) - { - if (newPassword != null) - { - newPasswordHash = _cryptographyProvider.CreatePasswordHash(newPassword).ToString(); - } - - if (string.IsNullOrWhiteSpace(newPasswordHash)) - { - throw new ArgumentNullException(nameof(newPasswordHash)); - } - - user.EasyPassword = newPasswordHash; - } - - /// - public string GetEasyPasswordHash(User user) - { - return string.IsNullOrEmpty(user.EasyPassword) - ? null - : Hex.Encode(PasswordHash.Parse(user.EasyPassword).Hash); - } } } diff --git a/Jellyfin.Server.Implementations/Users/InvalidAuthProvider.cs b/Jellyfin.Server.Implementations/Users/InvalidAuthProvider.cs index b6e65b5595..8ad2fecdb0 100644 --- a/Jellyfin.Server.Implementations/Users/InvalidAuthProvider.cs +++ b/Jellyfin.Server.Implementations/Users/InvalidAuthProvider.cs @@ -32,17 +32,5 @@ namespace Jellyfin.Server.Implementations.Users { return Task.CompletedTask; } - - /// - public void ChangeEasyPassword(User user, string newPassword, string newPasswordHash) - { - // Nothing here - } - - /// - public string GetEasyPasswordHash(User user) - { - return string.Empty; - } } } diff --git a/MediaBrowser.Controller/Authentication/IAuthenticationProvider.cs b/MediaBrowser.Controller/Authentication/IAuthenticationProvider.cs index c0324a3841..da812f5512 100644 --- a/MediaBrowser.Controller/Authentication/IAuthenticationProvider.cs +++ b/MediaBrowser.Controller/Authentication/IAuthenticationProvider.cs @@ -11,8 +11,6 @@ namespace MediaBrowser.Controller.Authentication Task Authenticate(string username, string password); bool HasPassword(User user); Task ChangePassword(User user, string newPassword); - void ChangeEasyPassword(User user, string newPassword, string newPasswordHash); - string GetEasyPasswordHash(User user); } public interface IRequiresResolvedUser From 3d87c4c1b6bca920f444b4a16a99553d0ff6879e Mon Sep 17 00:00:00 2001 From: crobibero Date: Sun, 7 Jun 2020 14:55:37 -0600 Subject: [PATCH 12/81] Fix EasyPassword setting --- Jellyfin.Server.Implementations/Users/UserManager.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Jellyfin.Server.Implementations/Users/UserManager.cs b/Jellyfin.Server.Implementations/Users/UserManager.cs index 01151e65e4..35ec78f5c5 100644 --- a/Jellyfin.Server.Implementations/Users/UserManager.cs +++ b/Jellyfin.Server.Implementations/Users/UserManager.cs @@ -262,7 +262,7 @@ namespace Jellyfin.Server.Implementations.Users /// public void ChangeEasyPassword(User user, string newPassword, string newPasswordSha1) { - GetAuthenticationProvider(user).ChangeEasyPassword(user, newPassword, newPasswordSha1); + user.EasyPassword = _cryptoProvider.CreatePasswordHash(newPassword).ToString(); UpdateUser(user); OnUserPasswordChanged?.Invoke(this, new GenericEventArgs(user)); From 7a9113adff7ac8aaaa015f0b90ddb28c13de3858 Mon Sep 17 00:00:00 2001 From: crobibero Date: Fri, 19 Jun 2020 09:09:31 -0600 Subject: [PATCH 13/81] Remove (unused) SessionId route parameter --- MediaBrowser.Api/SyncPlay/SyncPlayService.cs | 43 +++++--------------- 1 file changed, 10 insertions(+), 33 deletions(-) diff --git a/MediaBrowser.Api/SyncPlay/SyncPlayService.cs b/MediaBrowser.Api/SyncPlay/SyncPlayService.cs index 1e14ea552c..88cddfff7f 100644 --- a/MediaBrowser.Api/SyncPlay/SyncPlayService.cs +++ b/MediaBrowser.Api/SyncPlay/SyncPlayService.cs @@ -11,21 +11,16 @@ using Microsoft.Extensions.Logging; namespace MediaBrowser.Api.SyncPlay { - [Route("/SyncPlay/{SessionId}/NewGroup", "POST", Summary = "Create a new SyncPlay group")] + [Route("/SyncPlay/NewGroup", "POST", Summary = "Create a new SyncPlay group")] [Authenticated] public class SyncPlayNewGroup : IReturnVoid { - [ApiMember(Name = "SessionId", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "POST")] - public string SessionId { get; set; } } - [Route("/SyncPlay/{SessionId}/JoinGroup", "POST", Summary = "Join an existing SyncPlay group")] + [Route("/SyncPlay/JoinGroup", "POST", Summary = "Join an existing SyncPlay group")] [Authenticated] public class SyncPlayJoinGroup : IReturnVoid { - [ApiMember(Name = "SessionId", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "POST")] - public string SessionId { get; set; } - /// /// Gets or sets the Group id. /// @@ -41,63 +36,48 @@ namespace MediaBrowser.Api.SyncPlay public string PlayingItemId { get; set; } } - [Route("/SyncPlay/{SessionId}/LeaveGroup", "POST", Summary = "Leave joined SyncPlay group")] + [Route("/SyncPlay/LeaveGroup", "POST", Summary = "Leave joined SyncPlay group")] [Authenticated] public class SyncPlayLeaveGroup : IReturnVoid { - [ApiMember(Name = "SessionId", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "POST")] - public string SessionId { get; set; } } - [Route("/SyncPlay/{SessionId}/ListGroups", "POST", Summary = "List SyncPlay groups")] + [Route("/SyncPlay/ListGroups", "GET", Summary = "List SyncPlay groups")] [Authenticated] public class SyncPlayListGroups : IReturnVoid { - [ApiMember(Name = "SessionId", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "POST")] - public string SessionId { get; set; } - /// /// Gets or sets the filter item id. /// /// The filter item id. - [ApiMember(Name = "FilterItemId", Description = "Filter by item id", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "POST")] + [ApiMember(Name = "FilterItemId", Description = "Filter by item id", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET")] public string FilterItemId { get; set; } } - [Route("/SyncPlay/{SessionId}/PlayRequest", "POST", Summary = "Request play in SyncPlay group")] + [Route("/SyncPlay/PlayRequest", "POST", Summary = "Request play in SyncPlay group")] [Authenticated] public class SyncPlayPlayRequest : IReturnVoid { - [ApiMember(Name = "SessionId", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "POST")] - public string SessionId { get; set; } } - [Route("/SyncPlay/{SessionId}/PauseRequest", "POST", Summary = "Request pause in SyncPlay group")] + [Route("/SyncPlay/PauseRequest", "POST", Summary = "Request pause in SyncPlay group")] [Authenticated] public class SyncPlayPauseRequest : IReturnVoid { - [ApiMember(Name = "SessionId", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "POST")] - public string SessionId { get; set; } } - [Route("/SyncPlay/{SessionId}/SeekRequest", "POST", Summary = "Request seek in SyncPlay group")] + [Route("/SyncPlay/SeekRequest", "POST", Summary = "Request seek in SyncPlay group")] [Authenticated] public class SyncPlaySeekRequest : IReturnVoid { - [ApiMember(Name = "SessionId", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "POST")] - public string SessionId { get; set; } - [ApiMember(Name = "PositionTicks", IsRequired = true, DataType = "long", ParameterType = "query", Verb = "POST")] public long PositionTicks { get; set; } } - [Route("/SyncPlay/{SessionId}/BufferingRequest", "POST", Summary = "Request group wait in SyncPlay group while buffering")] + [Route("/SyncPlay/BufferingRequest", "POST", Summary = "Request group wait in SyncPlay group while buffering")] [Authenticated] public class SyncPlayBufferingRequest : IReturnVoid { - [ApiMember(Name = "SessionId", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "POST")] - public string SessionId { get; set; } - /// /// Gets or sets the date used to pin PositionTicks in time. /// @@ -116,13 +96,10 @@ namespace MediaBrowser.Api.SyncPlay public bool BufferingDone { get; set; } } - [Route("/SyncPlay/{SessionId}/UpdatePing", "POST", Summary = "Update session ping")] + [Route("/SyncPlay/UpdatePing", "POST", Summary = "Update session ping")] [Authenticated] public class SyncPlayUpdatePing : IReturnVoid { - [ApiMember(Name = "SessionId", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "POST")] - public string SessionId { get; set; } - [ApiMember(Name = "Ping", IsRequired = true, DataType = "double", ParameterType = "query", Verb = "POST")] public double Ping { get; set; } } From 3169b0af8917ac0bfd189fdb2f261be774b8b869 Mon Sep 17 00:00:00 2001 From: crobibero Date: Mon, 22 Jun 2020 20:24:59 -0600 Subject: [PATCH 14/81] fix merge --- .../Users/DefaultAuthenticationProvider.cs | 28 ------------------- 1 file changed, 28 deletions(-) diff --git a/Jellyfin.Server.Implementations/Users/DefaultAuthenticationProvider.cs b/Jellyfin.Server.Implementations/Users/DefaultAuthenticationProvider.cs index 9e1183c765..f79e433a67 100644 --- a/Jellyfin.Server.Implementations/Users/DefaultAuthenticationProvider.cs +++ b/Jellyfin.Server.Implementations/Users/DefaultAuthenticationProvider.cs @@ -5,7 +5,6 @@ using System.Linq; using System.Text; using System.Threading.Tasks; using Jellyfin.Data.Entities; -using MediaBrowser.Common; using MediaBrowser.Common.Cryptography; using MediaBrowser.Controller.Authentication; using MediaBrowser.Model.Cryptography; @@ -117,32 +116,5 @@ namespace Jellyfin.Server.Implementations.Users return Task.CompletedTask; } -<<<<<<< HEAD -======= - - /// - public void ChangeEasyPassword(User user, string newPassword, string newPasswordHash) - { - if (newPassword != null) - { - newPasswordHash = _cryptographyProvider.CreatePasswordHash(newPassword).ToString(); - } - - if (string.IsNullOrWhiteSpace(newPasswordHash)) - { - throw new ArgumentNullException(nameof(newPasswordHash)); - } - - user.EasyPassword = newPasswordHash; - } - - /// - public string? GetEasyPasswordHash(User user) - { - return string.IsNullOrEmpty(user.EasyPassword) - ? null - : Hex.Encode(PasswordHash.Parse(user.EasyPassword).Hash); - } ->>>>>>> upstream/master } } From 5b0c1829084b8f54cd5356880d82b75723badf81 Mon Sep 17 00:00:00 2001 From: BaronGreenback Date: Wed, 24 Jun 2020 14:31:17 +0100 Subject: [PATCH 15/81] Added logging and broadcast = true Not intended for merge into the fork. --- Emby.Server.Implementations/Net/SocketFactory.cs | 15 ++++++++++++++- MediaBrowser.Model/Net/ISocketFactory.cs | 5 ++++- RSSDP/SsdpCommunicationsServer.cs | 14 +++++++++----- 3 files changed, 27 insertions(+), 7 deletions(-) diff --git a/Emby.Server.Implementations/Net/SocketFactory.cs b/Emby.Server.Implementations/Net/SocketFactory.cs index 1777216584..bed79a9adc 100644 --- a/Emby.Server.Implementations/Net/SocketFactory.cs +++ b/Emby.Server.Implementations/Net/SocketFactory.cs @@ -4,6 +4,7 @@ using System; using System.Net; using System.Net.Sockets; using MediaBrowser.Model.Net; +using Microsoft.Extensions.Logging; namespace Emby.Server.Implementations.Net { @@ -67,7 +68,7 @@ namespace Emby.Server.Implementations.Net /// The multicast time to live value for the acceptSocket. /// The number of the local port to bind to. /// - public ISocket CreateUdpMulticastSocket(string ipAddress, int multicastTimeToLive, int localPort) + public ISocket CreateUdpMulticastSocket(string ipAddress, int multicastTimeToLive, int localPort, ILogger _logger) { if (ipAddress == null) { @@ -89,6 +90,8 @@ namespace Emby.Server.Implementations.Net throw new ArgumentException("localPort cannot be less than zero.", nameof(localPort)); } + _logger.LogError("Created"); + var retVal = new Socket(AddressFamily.InterNetwork, System.Net.Sockets.SocketType.Dgram, System.Net.Sockets.ProtocolType.Udp); try @@ -100,6 +103,8 @@ namespace Emby.Server.Implementations.Net { } + _logger.LogError("Exclusive false"); + try { // seeing occasional exceptions thrown on qnap @@ -110,8 +115,14 @@ namespace Emby.Server.Implementations.Net { } + _logger.LogError("Reused"); + try { + retVal.EnableBroadcast = true; // CHANGE + + _logger.LogError("Broadcast"); + // retVal.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.Broadcast, true); retVal.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.MulticastTimeToLive, multicastTimeToLive); @@ -120,6 +131,8 @@ namespace Emby.Server.Implementations.Net retVal.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.AddMembership, new MulticastOption(IPAddress.Parse(ipAddress), localIp)); retVal.MulticastLoopback = true; + _logger.LogError("Sorted"); + return new UdpSocket(retVal, localPort, localIp); } catch diff --git a/MediaBrowser.Model/Net/ISocketFactory.cs b/MediaBrowser.Model/Net/ISocketFactory.cs index 363abefc19..3a19590a9b 100644 --- a/MediaBrowser.Model/Net/ISocketFactory.cs +++ b/MediaBrowser.Model/Net/ISocketFactory.cs @@ -1,6 +1,7 @@ #pragma warning disable CS1591 using System.Net; +using Microsoft.Extensions.Logging; namespace MediaBrowser.Model.Net { @@ -22,7 +23,9 @@ namespace MediaBrowser.Model.Net /// The multicast IP address to bind to. /// The multicast time to live value. Actually a maximum number of network hops for UDP packets. /// The local port to bind to. + /// /// A implementation. - ISocket CreateUdpMulticastSocket(string ipAddress, int multicastTimeToLive, int localPort); + ISocket CreateUdpMulticastSocket(string ipAddress, int multicastTimeToLive, int localPort, ILogger logger); + } } diff --git a/RSSDP/SsdpCommunicationsServer.cs b/RSSDP/SsdpCommunicationsServer.cs index 8fde700e0c..34b67a945f 100644 --- a/RSSDP/SsdpCommunicationsServer.cs +++ b/RSSDP/SsdpCommunicationsServer.cs @@ -338,9 +338,12 @@ namespace Rssdp.Infrastructure private ISocket ListenForBroadcastsAsync() { - var socket = _SocketFactory.CreateUdpMulticastSocket(SsdpConstants.MulticastLocalAdminAddress, _MulticastTtl, SsdpConstants.MulticastPort); + var socket = _SocketFactory.CreateUdpMulticastSocket(SsdpConstants.MulticastLocalAdminAddress, _MulticastTtl, SsdpConstants.MulticastPort, _logger); - _ = ListenToSocketInternal(socket); + // TODO: remove this try and logging - testing purposes only. + _logger.LogError("Socket Created."); + + _ = ListenToSocketInternal(socket, _logger); return socket; } @@ -374,16 +377,16 @@ namespace Rssdp.Infrastructure foreach (var socket in sockets) { - _ = ListenToSocketInternal(socket); + _ = ListenToSocketInternal(socket, _logger); } return sockets; } - private async Task ListenToSocketInternal(ISocket socket) + private async Task ListenToSocketInternal(ISocket socket, ILogger logger) { var cancelled = false; - var receiveBuffer = new byte[8192]; + var receiveBuffer = new byte[8192]; while (!cancelled && !IsDisposed) { @@ -393,6 +396,7 @@ namespace Rssdp.Infrastructure if (result.ReceivedBytes > 0) { + _logger.LogError("processing..."); // Strange cannot convert compiler error here if I don't explicitly // assign or cast to Action first. Assignment is easier to read, // so went with that. From 44a8ea6bee3cf3fefc3d290dbaaa8c8e1554868f Mon Sep 17 00:00:00 2001 From: crobibero Date: Wed, 24 Jun 2020 09:45:11 -0600 Subject: [PATCH 16/81] implement ChangeEasyPassword from legacy provider --- Jellyfin.Server.Implementations/Users/UserManager.cs | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/Jellyfin.Server.Implementations/Users/UserManager.cs b/Jellyfin.Server.Implementations/Users/UserManager.cs index 97ea03596d..55218c5de9 100644 --- a/Jellyfin.Server.Implementations/Users/UserManager.cs +++ b/Jellyfin.Server.Implementations/Users/UserManager.cs @@ -263,7 +263,17 @@ namespace Jellyfin.Server.Implementations.Users /// public void ChangeEasyPassword(User user, string newPassword, string? newPasswordSha1) { - user.EasyPassword = _cryptoProvider.CreatePasswordHash(newPassword).ToString(); + if (newPassword != null) + { + newPasswordSha1 = _cryptoProvider.CreatePasswordHash(newPassword).ToString(); + } + + if (string.IsNullOrWhiteSpace(newPasswordSha1)) + { + throw new ArgumentNullException(nameof(newPasswordSha1)); + } + + user.EasyPassword = newPasswordSha1; UpdateUser(user); OnUserPasswordChanged?.Invoke(this, new GenericEventArgs(user)); From c07d8abfd57fbdc67ad2a0189e1c6149b8244a65 Mon Sep 17 00:00:00 2001 From: BaronGreenback Date: Wed, 24 Jun 2020 17:11:02 +0100 Subject: [PATCH 17/81] Removed debugging info --- .../Net/SocketFactory.cs | 18 ++++-------------- MediaBrowser.Model/Net/ISocketFactory.cs | 3 +-- RSSDP/SsdpCommunicationsServer.cs | 13 ++++--------- 3 files changed, 9 insertions(+), 25 deletions(-) diff --git a/Emby.Server.Implementations/Net/SocketFactory.cs b/Emby.Server.Implementations/Net/SocketFactory.cs index bed79a9adc..e79a63ff25 100644 --- a/Emby.Server.Implementations/Net/SocketFactory.cs +++ b/Emby.Server.Implementations/Net/SocketFactory.cs @@ -20,6 +20,7 @@ namespace Emby.Server.Implementations.Net var retVal = new Socket(AddressFamily.InterNetwork, System.Net.Sockets.SocketType.Dgram, System.Net.Sockets.ProtocolType.Udp); try { + retVal.EnableBroadcast = true; retVal.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true); retVal.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.Broadcast, 1); @@ -47,6 +48,7 @@ namespace Emby.Server.Implementations.Net var retVal = new Socket(AddressFamily.InterNetwork, System.Net.Sockets.SocketType.Dgram, System.Net.Sockets.ProtocolType.Udp); try { + retVal.EnableBroadcast = true; retVal.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true); retVal.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.MulticastTimeToLive, 4); @@ -68,7 +70,7 @@ namespace Emby.Server.Implementations.Net /// The multicast time to live value for the acceptSocket. /// The number of the local port to bind to. /// - public ISocket CreateUdpMulticastSocket(string ipAddress, int multicastTimeToLive, int localPort, ILogger _logger) + public ISocket CreateUdpMulticastSocket(string ipAddress, int multicastTimeToLive, int localPort) { if (ipAddress == null) { @@ -90,8 +92,6 @@ namespace Emby.Server.Implementations.Net throw new ArgumentException("localPort cannot be less than zero.", nameof(localPort)); } - _logger.LogError("Created"); - var retVal = new Socket(AddressFamily.InterNetwork, System.Net.Sockets.SocketType.Dgram, System.Net.Sockets.ProtocolType.Udp); try @@ -103,8 +103,6 @@ namespace Emby.Server.Implementations.Net { } - _logger.LogError("Exclusive false"); - try { // seeing occasional exceptions thrown on qnap @@ -115,14 +113,9 @@ namespace Emby.Server.Implementations.Net { } - _logger.LogError("Reused"); - try { - retVal.EnableBroadcast = true; // CHANGE - - _logger.LogError("Broadcast"); - + retVal.EnableBroadcast = true; // retVal.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.Broadcast, true); retVal.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.MulticastTimeToLive, multicastTimeToLive); @@ -130,9 +123,6 @@ namespace Emby.Server.Implementations.Net retVal.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.AddMembership, new MulticastOption(IPAddress.Parse(ipAddress), localIp)); retVal.MulticastLoopback = true; - - _logger.LogError("Sorted"); - return new UdpSocket(retVal, localPort, localIp); } catch diff --git a/MediaBrowser.Model/Net/ISocketFactory.cs b/MediaBrowser.Model/Net/ISocketFactory.cs index 3a19590a9b..c4e1540645 100644 --- a/MediaBrowser.Model/Net/ISocketFactory.cs +++ b/MediaBrowser.Model/Net/ISocketFactory.cs @@ -23,9 +23,8 @@ namespace MediaBrowser.Model.Net /// The multicast IP address to bind to. /// The multicast time to live value. Actually a maximum number of network hops for UDP packets. /// The local port to bind to. - /// /// A implementation. - ISocket CreateUdpMulticastSocket(string ipAddress, int multicastTimeToLive, int localPort, ILogger logger); + ISocket CreateUdpMulticastSocket(string ipAddress, int multicastTimeToLive, int localPort); } } diff --git a/RSSDP/SsdpCommunicationsServer.cs b/RSSDP/SsdpCommunicationsServer.cs index 34b67a945f..0ff56ebacf 100644 --- a/RSSDP/SsdpCommunicationsServer.cs +++ b/RSSDP/SsdpCommunicationsServer.cs @@ -338,12 +338,8 @@ namespace Rssdp.Infrastructure private ISocket ListenForBroadcastsAsync() { - var socket = _SocketFactory.CreateUdpMulticastSocket(SsdpConstants.MulticastLocalAdminAddress, _MulticastTtl, SsdpConstants.MulticastPort, _logger); - - // TODO: remove this try and logging - testing purposes only. - _logger.LogError("Socket Created."); - - _ = ListenToSocketInternal(socket, _logger); + var socket = _SocketFactory.CreateUdpMulticastSocket(SsdpConstants.MulticastLocalAdminAddress, _MulticastTtl, SsdpConstants.MulticastPort); + _ = ListenToSocketInternal(socket); return socket; } @@ -377,13 +373,13 @@ namespace Rssdp.Infrastructure foreach (var socket in sockets) { - _ = ListenToSocketInternal(socket, _logger); + _ = ListenToSocketInternal(socket); } return sockets; } - private async Task ListenToSocketInternal(ISocket socket, ILogger logger) + private async Task ListenToSocketInternal(ISocket socket) { var cancelled = false; var receiveBuffer = new byte[8192]; @@ -396,7 +392,6 @@ namespace Rssdp.Infrastructure if (result.ReceivedBytes > 0) { - _logger.LogError("processing..."); // Strange cannot convert compiler error here if I don't explicitly // assign or cast to Action first. Assignment is easier to read, // so went with that. From f01baad05e5abc8875fa36f9075f8684857115e7 Mon Sep 17 00:00:00 2001 From: BaronGreenback Date: Wed, 24 Jun 2020 17:23:16 +0100 Subject: [PATCH 18/81] Sending multicasts out of Sockets without setting the broadcast to true - causes the error "Bad value for ai_flags" on some systems (#3404) The underlying cause looks to be https://github.com/dotnet/runtime/issues/28630. Basically, it's an access denied bug. It looks like multicasts need the same access rights as broadcasts on some systems. --- Emby.Server.Implementations/Net/SocketFactory.cs | 2 +- MediaBrowser.Model/Net/ISocketFactory.cs | 2 -- RSSDP/SsdpCommunicationsServer.cs | 5 +++-- 3 files changed, 4 insertions(+), 5 deletions(-) diff --git a/Emby.Server.Implementations/Net/SocketFactory.cs b/Emby.Server.Implementations/Net/SocketFactory.cs index e79a63ff25..0781a0e333 100644 --- a/Emby.Server.Implementations/Net/SocketFactory.cs +++ b/Emby.Server.Implementations/Net/SocketFactory.cs @@ -4,7 +4,6 @@ using System; using System.Net; using System.Net.Sockets; using MediaBrowser.Model.Net; -using Microsoft.Extensions.Logging; namespace Emby.Server.Implementations.Net { @@ -123,6 +122,7 @@ namespace Emby.Server.Implementations.Net retVal.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.AddMembership, new MulticastOption(IPAddress.Parse(ipAddress), localIp)); retVal.MulticastLoopback = true; + return new UdpSocket(retVal, localPort, localIp); } catch diff --git a/MediaBrowser.Model/Net/ISocketFactory.cs b/MediaBrowser.Model/Net/ISocketFactory.cs index c4e1540645..363abefc19 100644 --- a/MediaBrowser.Model/Net/ISocketFactory.cs +++ b/MediaBrowser.Model/Net/ISocketFactory.cs @@ -1,7 +1,6 @@ #pragma warning disable CS1591 using System.Net; -using Microsoft.Extensions.Logging; namespace MediaBrowser.Model.Net { @@ -25,6 +24,5 @@ namespace MediaBrowser.Model.Net /// The local port to bind to. /// A implementation. ISocket CreateUdpMulticastSocket(string ipAddress, int multicastTimeToLive, int localPort); - } } diff --git a/RSSDP/SsdpCommunicationsServer.cs b/RSSDP/SsdpCommunicationsServer.cs index 0ff56ebacf..3c52a0c2f4 100644 --- a/RSSDP/SsdpCommunicationsServer.cs +++ b/RSSDP/SsdpCommunicationsServer.cs @@ -338,7 +338,8 @@ namespace Rssdp.Infrastructure private ISocket ListenForBroadcastsAsync() { - var socket = _SocketFactory.CreateUdpMulticastSocket(SsdpConstants.MulticastLocalAdminAddress, _MulticastTtl, SsdpConstants.MulticastPort); + var socket = _SocketFactory.CreateUdpMulticastSocket(SsdpConstants.MulticastLocalAdminAddress, _MulticastTtl, SsdpConstants.MulticastPort); + _ = ListenToSocketInternal(socket); return socket; @@ -382,7 +383,7 @@ namespace Rssdp.Infrastructure private async Task ListenToSocketInternal(ISocket socket) { var cancelled = false; - var receiveBuffer = new byte[8192]; + var receiveBuffer = new byte[8192]; while (!cancelled && !IsDisposed) { From ef8bec23c4f1ce9b97a155913ed57bc387184e22 Mon Sep 17 00:00:00 2001 From: crobibero Date: Wed, 24 Jun 2020 15:09:15 -0600 Subject: [PATCH 19/81] revert missing session fields --- .../Session/SessionManager.cs | 3 ++- MediaBrowser.Controller/Session/SessionInfo.cs | 15 +++++++++++++++ 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/Emby.Server.Implementations/Session/SessionManager.cs b/Emby.Server.Implementations/Session/SessionManager.cs index 75fdedd107..d069d1ada8 100644 --- a/Emby.Server.Implementations/Session/SessionManager.cs +++ b/Emby.Server.Implementations/Session/SessionManager.cs @@ -502,7 +502,8 @@ namespace Emby.Server.Implementations.Session Client = appName, DeviceId = deviceId, ApplicationVersion = appVersion, - Id = key.GetMD5().ToString("N", CultureInfo.InvariantCulture) + Id = key.GetMD5().ToString("N", CultureInfo.InvariantCulture), + ServerId = _appHost.SystemId }; var username = user?.Username; diff --git a/MediaBrowser.Controller/Session/SessionInfo.cs b/MediaBrowser.Controller/Session/SessionInfo.cs index 36bc11be4f..4b088998cd 100644 --- a/MediaBrowser.Controller/Session/SessionInfo.cs +++ b/MediaBrowser.Controller/Session/SessionInfo.cs @@ -108,6 +108,12 @@ namespace MediaBrowser.Controller.Session /// The name of the device. public string DeviceName { get; set; } + /// + /// Gets or sets the type of the device. + /// + /// The type of the device. + public string DeviceType { get; set; } + /// /// Gets or sets the now playing item. /// @@ -215,8 +221,17 @@ namespace MediaBrowser.Controller.Session public string PlaylistItemId { get; set; } + public string ServerId { get; set; } + public string UserPrimaryImageTag { get; set; } + /// + /// Gets or sets the supported commands. + /// + /// The supported commands. + public string[] SupportedCommands + => Capabilities == null ? Array.Empty() : Capabilities.SupportedCommands; + public Tuple EnsureController(Func factory) { var controllers = SessionControllers.ToList(); From 9a01cd8590ffcae8ce561e6f733bf59fe54932fa Mon Sep 17 00:00:00 2001 From: Patrick Barron Date: Wed, 24 Jun 2020 20:19:47 -0400 Subject: [PATCH 20/81] Fix user deletion. --- .../Users/UserManager.cs | 19 ++++++++++++++----- MediaBrowser.Api/UserService.cs | 11 ++--------- .../Library/IUserManager.cs | 4 ++-- 3 files changed, 18 insertions(+), 16 deletions(-) diff --git a/Jellyfin.Server.Implementations/Users/UserManager.cs b/Jellyfin.Server.Implementations/Users/UserManager.cs index 9041147588..d86b25f81e 100644 --- a/Jellyfin.Server.Implementations/Users/UserManager.cs +++ b/Jellyfin.Server.Implementations/Users/UserManager.cs @@ -192,15 +192,15 @@ namespace Jellyfin.Server.Implementations.Users } /// - public void DeleteUser(User user) + public void DeleteUser(Guid userId) { + var dbContext = _dbProvider.CreateContext(); + var user = dbContext.Users.Find(userId); if (user == null) { - throw new ArgumentNullException(nameof(user)); + throw new ArgumentNullException(nameof(userId)); } - var dbContext = _dbProvider.CreateContext(); - if (dbContext.Users.Find(user.Id) == null) { throw new ArgumentException(string.Format( @@ -226,9 +226,18 @@ namespace Jellyfin.Server.Implementations.Users CultureInfo.InvariantCulture, "The user '{0}' cannot be deleted because there must be at least one admin user in the system.", user.Username), - nameof(user)); + nameof(userId)); + } + + // Clear all entities related to the user from the database. + if (user.ProfileImage != null) + { + dbContext.Remove(user.ProfileImage); } + dbContext.RemoveRange(user.Permissions); + dbContext.RemoveRange(user.Preferences); + dbContext.RemoveRange(user.AccessSchedules); dbContext.Users.Remove(user); dbContext.SaveChanges(); OnUserDeleted?.Invoke(this, new GenericEventArgs(user)); diff --git a/MediaBrowser.Api/UserService.cs b/MediaBrowser.Api/UserService.cs index 131def5542..6e9d788dc1 100644 --- a/MediaBrowser.Api/UserService.cs +++ b/MediaBrowser.Api/UserService.cs @@ -365,15 +365,8 @@ namespace MediaBrowser.Api public Task DeleteAsync(DeleteUser request) { - var user = _userManager.GetUserById(request.Id); - - if (user == null) - { - throw new ResourceNotFoundException("User not found"); - } - - _sessionMananger.RevokeUserTokens(user.Id, null); - _userManager.DeleteUser(user); + _userManager.DeleteUser(request.Id); + _sessionMananger.RevokeUserTokens(request.Id, null); return Task.CompletedTask; } diff --git a/MediaBrowser.Controller/Library/IUserManager.cs b/MediaBrowser.Controller/Library/IUserManager.cs index fe3e4f9e68..4ff3cee0f0 100644 --- a/MediaBrowser.Controller/Library/IUserManager.cs +++ b/MediaBrowser.Controller/Library/IUserManager.cs @@ -111,8 +111,8 @@ namespace MediaBrowser.Controller.Library /// /// Deletes the specified user. /// - /// The user to be deleted. - void DeleteUser(User user); + /// The if of the user to be deleted. + void DeleteUser(Guid userId); /// /// Resets the password. From 2967dd6afd158fc278697fa593852de45e99b84a Mon Sep 17 00:00:00 2001 From: Patrick Barron Date: Wed, 24 Jun 2020 20:36:58 -0400 Subject: [PATCH 21/81] Change to ResourceNotFoundException --- Jellyfin.Server.Implementations/Users/UserManager.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Jellyfin.Server.Implementations/Users/UserManager.cs b/Jellyfin.Server.Implementations/Users/UserManager.cs index d86b25f81e..ae5c311bf2 100644 --- a/Jellyfin.Server.Implementations/Users/UserManager.cs +++ b/Jellyfin.Server.Implementations/Users/UserManager.cs @@ -12,6 +12,7 @@ using Jellyfin.Data.Entities; using Jellyfin.Data.Enums; using MediaBrowser.Common; using MediaBrowser.Common.Cryptography; +using MediaBrowser.Common.Extensions; using MediaBrowser.Common.Net; using MediaBrowser.Controller.Authentication; using MediaBrowser.Controller.Drawing; @@ -198,7 +199,7 @@ namespace Jellyfin.Server.Implementations.Users var user = dbContext.Users.Find(userId); if (user == null) { - throw new ArgumentNullException(nameof(userId)); + throw new ResourceNotFoundException(nameof(userId)); } if (dbContext.Users.Find(user.Id) == null) From 5ee419ebe4ada7de98f877daa49dfc1755b375ef Mon Sep 17 00:00:00 2001 From: Patrick Barron Date: Wed, 24 Jun 2020 21:07:39 -0400 Subject: [PATCH 22/81] Fix typo --- MediaBrowser.Controller/Library/IUserManager.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MediaBrowser.Controller/Library/IUserManager.cs b/MediaBrowser.Controller/Library/IUserManager.cs index 4ff3cee0f0..e73fe71205 100644 --- a/MediaBrowser.Controller/Library/IUserManager.cs +++ b/MediaBrowser.Controller/Library/IUserManager.cs @@ -111,7 +111,7 @@ namespace MediaBrowser.Controller.Library /// /// Deletes the specified user. /// - /// The if of the user to be deleted. + /// The id of the user to be deleted. void DeleteUser(Guid userId); /// From 9dee1eef83d80801cf2781b8b0c2393ec0a3b82d Mon Sep 17 00:00:00 2001 From: Claus Vium Date: Thu, 25 Jun 2020 11:31:43 +0200 Subject: [PATCH 23/81] Never ignore application folders --- .../Library/CoreResolutionIgnoreRule.cs | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/Emby.Server.Implementations/Library/CoreResolutionIgnoreRule.cs b/Emby.Server.Implementations/Library/CoreResolutionIgnoreRule.cs index e140009ea9..77b2c0a694 100644 --- a/Emby.Server.Implementations/Library/CoreResolutionIgnoreRule.cs +++ b/Emby.Server.Implementations/Library/CoreResolutionIgnoreRule.cs @@ -1,5 +1,6 @@ using System; using System.IO; +using MediaBrowser.Controller; using MediaBrowser.Controller.Entities; using MediaBrowser.Controller.Library; using MediaBrowser.Controller.Resolvers; @@ -13,19 +14,28 @@ namespace Emby.Server.Implementations.Library public class CoreResolutionIgnoreRule : IResolverIgnoreRule { private readonly ILibraryManager _libraryManager; + private readonly IServerApplicationPaths _serverApplicationPaths; /// /// Initializes a new instance of the class. /// /// The library manager. - public CoreResolutionIgnoreRule(ILibraryManager libraryManager) + /// The server application paths. + public CoreResolutionIgnoreRule(ILibraryManager libraryManager, IServerApplicationPaths serverApplicationPaths) { _libraryManager = libraryManager; + _serverApplicationPaths = serverApplicationPaths; } /// public bool ShouldIgnore(FileSystemMetadata fileInfo, BaseItem parent) { + // Don't ignore application folders + if (fileInfo.FullName.Contains(_serverApplicationPaths.RootFolderPath, StringComparison.InvariantCulture)) + { + return false; + } + // Don't ignore top level folders if (fileInfo.IsDirectory && parent is AggregateFolder) { From 0f07b19ca5d6433a8574363cfe3c20fbfd285514 Mon Sep 17 00:00:00 2001 From: Claus Vium Date: Thu, 25 Jun 2020 11:33:10 +0200 Subject: [PATCH 24/81] Remove AllowIgnorePath --- .../Library/LibraryManager.cs | 13 ++++++------- MediaBrowser.Controller/Library/ILibraryManager.cs | 4 +--- 2 files changed, 7 insertions(+), 10 deletions(-) diff --git a/Emby.Server.Implementations/Library/LibraryManager.cs b/Emby.Server.Implementations/Library/LibraryManager.cs index edb58e9102..9b8091aa7a 100644 --- a/Emby.Server.Implementations/Library/LibraryManager.cs +++ b/Emby.Server.Implementations/Library/LibraryManager.cs @@ -514,8 +514,8 @@ namespace Emby.Server.Implementations.Library return key.GetMD5(); } - public BaseItem ResolvePath(FileSystemMetadata fileInfo, Folder parent = null, bool allowIgnorePath = true) - => ResolvePath(fileInfo, new DirectoryService(_fileSystem), null, parent, allowIgnorePath: allowIgnorePath); + public BaseItem ResolvePath(FileSystemMetadata fileInfo, Folder parent = null) + => ResolvePath(fileInfo, new DirectoryService(_fileSystem), null, parent); private BaseItem ResolvePath( FileSystemMetadata fileInfo, @@ -523,8 +523,7 @@ namespace Emby.Server.Implementations.Library IItemResolver[] resolvers, Folder parent = null, string collectionType = null, - LibraryOptions libraryOptions = null, - bool allowIgnorePath = true) + LibraryOptions libraryOptions = null) { if (fileInfo == null) { @@ -548,7 +547,7 @@ namespace Emby.Server.Implementations.Library }; // Return null if ignore rules deem that we should do so - if (allowIgnorePath && IgnoreFile(args.FileInfo, args.Parent)) + if (IgnoreFile(args.FileInfo, args.Parent)) { return null; } @@ -713,7 +712,7 @@ namespace Emby.Server.Implementations.Library Directory.CreateDirectory(rootFolderPath); var rootFolder = GetItemById(GetNewItemId(rootFolderPath, typeof(AggregateFolder))) as AggregateFolder ?? - ((Folder) ResolvePath(_fileSystem.GetDirectoryInfo(rootFolderPath), allowIgnorePath: false)) + ((Folder) ResolvePath(_fileSystem.GetDirectoryInfo(rootFolderPath))) .DeepCopy(); // In case program data folder was moved @@ -795,7 +794,7 @@ namespace Emby.Server.Implementations.Library if (tmpItem == null) { _logger.LogDebug("Creating new userRootFolder with DeepCopy"); - tmpItem = ((Folder)ResolvePath(_fileSystem.GetDirectoryInfo(userRootPath), allowIgnorePath: false)).DeepCopy(); + tmpItem = ((Folder)ResolvePath(_fileSystem.GetDirectoryInfo(userRootPath))).DeepCopy(); } // In case program data folder was moved diff --git a/MediaBrowser.Controller/Library/ILibraryManager.cs b/MediaBrowser.Controller/Library/ILibraryManager.cs index 47c080ebdc..9d6646857e 100644 --- a/MediaBrowser.Controller/Library/ILibraryManager.cs +++ b/MediaBrowser.Controller/Library/ILibraryManager.cs @@ -30,12 +30,10 @@ namespace MediaBrowser.Controller.Library /// /// The file information. /// The parent. - /// Allow the path to be ignored. /// BaseItem. BaseItem ResolvePath( FileSystemMetadata fileInfo, - Folder parent = null, - bool allowIgnorePath = true); + Folder parent = null); /// /// Resolves a set of files into a list of BaseItem. From 0714bde9ce7cad9eadd025fa3ffd179b2edee664 Mon Sep 17 00:00:00 2001 From: dkanada Date: Fri, 26 Jun 2020 01:25:14 +0900 Subject: [PATCH 25/81] fix azure badge --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 99a66e306a..4584713776 100644 --- a/README.md +++ b/README.md @@ -16,7 +16,7 @@ Translation Status - + Azure Builds From cc18aa38fa59c38f3cac6a38f481ed006a206d53 Mon Sep 17 00:00:00 2001 From: dkanada Date: Fri, 26 Jun 2020 01:29:28 +0900 Subject: [PATCH 26/81] update badge to match azure link --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 4584713776..83090100d4 100644 --- a/README.md +++ b/README.md @@ -17,7 +17,7 @@ Translation Status -Azure Builds +Azure Builds Docker Pull Count From 9eba11379a3695eda732a481634fbac620ac0624 Mon Sep 17 00:00:00 2001 From: crobibero Date: Thu, 25 Jun 2020 12:10:33 -0600 Subject: [PATCH 27/81] catch skia errors when getting image dimensions --- .../Library/LibraryManager.cs | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/Emby.Server.Implementations/Library/LibraryManager.cs b/Emby.Server.Implementations/Library/LibraryManager.cs index 6a20a015ad..b2c9638b2b 100644 --- a/Emby.Server.Implementations/Library/LibraryManager.cs +++ b/Emby.Server.Implementations/Library/LibraryManager.cs @@ -1894,9 +1894,19 @@ namespace Emby.Server.Implementations.Library } } - ImageDimensions size = _imageProcessor.GetImageDimensions(item, image); - image.Width = size.Width; - image.Height = size.Height; + try + { + ImageDimensions size = _imageProcessor.GetImageDimensions(item, image); + image.Width = size.Width; + image.Height = size.Height; + } + catch (Exception ex) + { + _logger.LogError(ex, "Cannnot get image dimensions for {0}", image.Path); + image.Width = 0; + image.Height = 0; + continue; + } try { From 27f6e1ddc8924c108787a2f5f7622ed910e5cb72 Mon Sep 17 00:00:00 2001 From: BaronGreenback Date: Fri, 26 Jun 2020 15:22:39 +0100 Subject: [PATCH 28/81] Update SsdpCommunicationsServer.cs --- RSSDP/SsdpCommunicationsServer.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/RSSDP/SsdpCommunicationsServer.cs b/RSSDP/SsdpCommunicationsServer.cs index 3c52a0c2f4..8fde700e0c 100644 --- a/RSSDP/SsdpCommunicationsServer.cs +++ b/RSSDP/SsdpCommunicationsServer.cs @@ -339,7 +339,7 @@ namespace Rssdp.Infrastructure private ISocket ListenForBroadcastsAsync() { var socket = _SocketFactory.CreateUdpMulticastSocket(SsdpConstants.MulticastLocalAdminAddress, _MulticastTtl, SsdpConstants.MulticastPort); - + _ = ListenToSocketInternal(socket); return socket; From 2272363197660939ec5474ea76fca2f9445993be Mon Sep 17 00:00:00 2001 From: BaronGreenback Date: Fri, 26 Jun 2020 15:24:46 +0100 Subject: [PATCH 29/81] Update SsdpCommunicationsServer.cs --- RSSDP/SsdpCommunicationsServer.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/RSSDP/SsdpCommunicationsServer.cs b/RSSDP/SsdpCommunicationsServer.cs index 8fde700e0c..a4be32e7d2 100644 --- a/RSSDP/SsdpCommunicationsServer.cs +++ b/RSSDP/SsdpCommunicationsServer.cs @@ -339,7 +339,6 @@ namespace Rssdp.Infrastructure private ISocket ListenForBroadcastsAsync() { var socket = _SocketFactory.CreateUdpMulticastSocket(SsdpConstants.MulticastLocalAdminAddress, _MulticastTtl, SsdpConstants.MulticastPort); - _ = ListenToSocketInternal(socket); return socket; From 5f1b1dc3cc01abcd52155144cb3d9a791ee655fa Mon Sep 17 00:00:00 2001 From: Cody Robibero Date: Fri, 26 Jun 2020 08:41:21 -0600 Subject: [PATCH 30/81] fix nullability --- MediaBrowser.Model/Providers/ExternalIdInfo.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/MediaBrowser.Model/Providers/ExternalIdInfo.cs b/MediaBrowser.Model/Providers/ExternalIdInfo.cs index 7687e676f9..01784554f9 100644 --- a/MediaBrowser.Model/Providers/ExternalIdInfo.cs +++ b/MediaBrowser.Model/Providers/ExternalIdInfo.cs @@ -9,13 +9,13 @@ namespace MediaBrowser.Model.Providers /// Gets or sets the display name of the external id provider (IE: IMDB, MusicBrainz, etc). /// // TODO: This should be renamed to ProviderName - public string Name { get; set; } + public string? Name { get; set; } /// /// Gets or sets the unique key for this id. This key should be unique across all providers. /// // TODO: This property is not actually unique across the concrete types at the moment. It should be updated to be unique. - public string Key { get; set; } + public string? Key { get; set; } /// /// Gets or sets the specific media type for this id. This is used to distinguish between the different @@ -31,6 +31,6 @@ namespace MediaBrowser.Model.Providers /// /// Gets or sets the URL format string. /// - public string UrlFormatString { get; set; } + public string? UrlFormatString { get; set; } } } From 83ae4d074dc9f665c992eefd1cf4ed78eb5a8dd1 Mon Sep 17 00:00:00 2001 From: dkanada Date: Sat, 27 Jun 2020 00:22:27 +0900 Subject: [PATCH 31/81] use constructor to set optimal config values --- .../Collections/CollectionManager.cs | 56 ------------------ .../ServerConfigurationManager.cs | 57 ------------------- Jellyfin.Api/Controllers/StartupController.cs | 1 - .../IServerConfigurationManager.cs | 2 - .../Configuration/ServerConfiguration.cs | 6 +- 5 files changed, 4 insertions(+), 118 deletions(-) diff --git a/Emby.Server.Implementations/Collections/CollectionManager.cs b/Emby.Server.Implementations/Collections/CollectionManager.cs index 8fb9520d6d..ac2edc1e2e 100644 --- a/Emby.Server.Implementations/Collections/CollectionManager.cs +++ b/Emby.Server.Implementations/Collections/CollectionManager.cs @@ -363,60 +363,4 @@ namespace Emby.Server.Implementations.Collections return results.Values; } } - - /// - /// The collection manager entry point. - /// - public sealed class CollectionManagerEntryPoint : IServerEntryPoint - { - private readonly CollectionManager _collectionManager; - private readonly IServerConfigurationManager _config; - private readonly ILogger _logger; - - /// - /// Initializes a new instance of the class. - /// - /// The collection manager. - /// The server configuration manager. - /// The logger. - public CollectionManagerEntryPoint( - ICollectionManager collectionManager, - IServerConfigurationManager config, - ILogger logger) - { - _collectionManager = (CollectionManager)collectionManager; - _config = config; - _logger = logger; - } - - /// - public async Task RunAsync() - { - if (!_config.Configuration.CollectionsUpgraded && _config.Configuration.IsStartupWizardCompleted) - { - var path = _collectionManager.GetCollectionsFolderPath(); - - if (Directory.Exists(path)) - { - try - { - await _collectionManager.EnsureLibraryFolder(path, true).ConfigureAwait(false); - } - catch (Exception ex) - { - _logger.LogError(ex, "Error creating camera uploads library"); - } - - _config.Configuration.CollectionsUpgraded = true; - _config.SaveConfiguration(); - } - } - } - - /// - public void Dispose() - { - // Nothing to dispose - } - } } diff --git a/Emby.Server.Implementations/Configuration/ServerConfigurationManager.cs b/Emby.Server.Implementations/Configuration/ServerConfigurationManager.cs index 94ee1ced71..a15295fca4 100644 --- a/Emby.Server.Implementations/Configuration/ServerConfigurationManager.cs +++ b/Emby.Server.Implementations/Configuration/ServerConfigurationManager.cs @@ -109,7 +109,6 @@ namespace Emby.Server.Implementations.Configuration if (!string.IsNullOrWhiteSpace(newPath) && !string.Equals(Configuration.CertificatePath, newPath, StringComparison.Ordinal)) { - // Validate if (!File.Exists(newPath)) { throw new FileNotFoundException( @@ -133,7 +132,6 @@ namespace Emby.Server.Implementations.Configuration if (!string.IsNullOrWhiteSpace(newPath) && !string.Equals(Configuration.MetadataPath, newPath, StringComparison.Ordinal)) { - // Validate if (!Directory.Exists(newPath)) { throw new DirectoryNotFoundException( @@ -146,60 +144,5 @@ namespace Emby.Server.Implementations.Configuration EnsureWriteAccess(newPath); } } - - /// - /// Sets all configuration values to their optimal values. - /// - /// If the configuration changed. - public bool SetOptimalValues() - { - var config = Configuration; - - var changed = false; - - if (!config.EnableCaseSensitiveItemIds) - { - config.EnableCaseSensitiveItemIds = true; - changed = true; - } - - if (!config.SkipDeserializationForBasicTypes) - { - config.SkipDeserializationForBasicTypes = true; - changed = true; - } - - if (!config.EnableSimpleArtistDetection) - { - config.EnableSimpleArtistDetection = true; - changed = true; - } - - if (!config.EnableNormalizedItemByNameIds) - { - config.EnableNormalizedItemByNameIds = true; - changed = true; - } - - if (!config.DisableLiveTvChannelUserDataName) - { - config.DisableLiveTvChannelUserDataName = true; - changed = true; - } - - if (!config.EnableNewOmdbSupport) - { - config.EnableNewOmdbSupport = true; - changed = true; - } - - if (!config.CollectionsUpgraded) - { - config.CollectionsUpgraded = true; - changed = true; - } - - return changed; - } } } diff --git a/Jellyfin.Api/Controllers/StartupController.cs b/Jellyfin.Api/Controllers/StartupController.cs index 6ec0a4e26f..04f134b8bf 100644 --- a/Jellyfin.Api/Controllers/StartupController.cs +++ b/Jellyfin.Api/Controllers/StartupController.cs @@ -36,7 +36,6 @@ namespace Jellyfin.Api.Controllers public void CompleteWizard() { _config.Configuration.IsStartupWizardCompleted = true; - _config.SetOptimalValues(); _config.SaveConfiguration(); } diff --git a/MediaBrowser.Controller/Configuration/IServerConfigurationManager.cs b/MediaBrowser.Controller/Configuration/IServerConfigurationManager.cs index a5c5e3bccf..43ad04dbac 100644 --- a/MediaBrowser.Controller/Configuration/IServerConfigurationManager.cs +++ b/MediaBrowser.Controller/Configuration/IServerConfigurationManager.cs @@ -19,7 +19,5 @@ namespace MediaBrowser.Controller.Configuration /// /// The configuration. ServerConfiguration Configuration { get; } - - bool SetOptimalValues(); } } diff --git a/MediaBrowser.Model/Configuration/ServerConfiguration.cs b/MediaBrowser.Model/Configuration/ServerConfiguration.cs index b87c8fbab2..bb4ca34fd0 100644 --- a/MediaBrowser.Model/Configuration/ServerConfiguration.cs +++ b/MediaBrowser.Model/Configuration/ServerConfiguration.cs @@ -82,8 +82,6 @@ namespace MediaBrowser.Model.Configuration public bool EnableRemoteAccess { get; set; } - public bool CollectionsUpgraded { get; set; } - /// /// Gets or sets a value indicating whether [enable case sensitive item ids]. /// @@ -269,6 +267,7 @@ namespace MediaBrowser.Model.Configuration PathSubstitutions = Array.Empty(); IgnoreVirtualInterfaces = false; EnableSimpleArtistDetection = false; + SkipDeserializationForBasicTypes = true; DisplaySpecialsWithinSeasons = true; EnableExternalContentInSuggestions = true; @@ -282,6 +281,9 @@ namespace MediaBrowser.Model.Configuration EnableHttps = false; EnableDashboardResponseCaching = true; EnableCaseSensitiveItemIds = true; + EnableNormalizedItemByNameIds = true; + DisableLiveTvChannelUserDataName = true; + EnableNewOmdbSupport = true; AutoRunWebApp = true; EnableRemoteAccess = true; From 9772749d8fa2c86089ff1e3e0b8443633193106a Mon Sep 17 00:00:00 2001 From: crobibero Date: Fri, 26 Jun 2020 11:04:35 -0600 Subject: [PATCH 32/81] Add more ignorepatterns and tests --- .../Library/IgnorePatterns.cs | 28 +++++++++++++++++-- .../Library/IgnorePatternsTests.cs | 7 +++++ 2 files changed, 32 insertions(+), 3 deletions(-) diff --git a/Emby.Server.Implementations/Library/IgnorePatterns.cs b/Emby.Server.Implementations/Library/IgnorePatterns.cs index 8c40989489..cd5c5f19db 100644 --- a/Emby.Server.Implementations/Library/IgnorePatterns.cs +++ b/Emby.Server.Implementations/Library/IgnorePatterns.cs @@ -11,7 +11,7 @@ namespace Emby.Server.Implementations.Library /// /// Files matching these glob patterns will be ignored. /// - public static readonly string[] Patterns = new string[] + private static readonly string[] _patterns = { "**/small.jpg", "**/albumart.jpg", @@ -19,32 +19,51 @@ namespace Emby.Server.Implementations.Library // Directories "**/metadata/**", + "**/metadata", "**/ps3_update/**", + "**/ps3_update", "**/ps3_vprm/**", + "**/ps3_vprm", "**/extrafanart/**", + "**/extrafanart", "**/extrathumbs/**", + "**/extrathumbs", "**/.actors/**", + "**/.actors", "**/.wd_tv/**", + "**/.wd_tv", "**/lost+found/**", + "**/lost+found", // WMC temp recording directories that will constantly be written to "**/TempRec/**", + "**/TempRec", "**/TempSBE/**", + "**/TempSBE", // Synology "**/eaDir/**", + "**/eaDir", "**/@eaDir/**", + "**/@eaDir", "**/#recycle/**", + "**/#recycle", // Qnap "**/@Recycle/**", + "**/@Recycle", "**/.@__thumb/**", + "**/.@__thumb", "**/$RECYCLE.BIN/**", + "**/$RECYCLE.BIN", "**/System Volume Information/**", + "**/System Volume Information", "**/.grab/**", + "**/.grab", // Unix hidden files and directories "**/.*/**", + "**/.*", // thumbs.db "**/thumbs.db", @@ -56,16 +75,19 @@ namespace Emby.Server.Implementations.Library private static readonly GlobOptions _globOptions = new GlobOptions { - Evaluation = { + Evaluation = + { CaseInsensitive = true } }; - private static readonly Glob[] _globs = Patterns.Select(p => Glob.Parse(p, _globOptions)).ToArray(); + private static readonly Glob[] _globs = _patterns.Select(p => Glob.Parse(p, _globOptions)).ToArray(); /// /// Returns true if the supplied path should be ignored. /// + /// The path to test. + /// Whether to ignore the path. public static bool ShouldIgnore(string path) { return _globs.Any(g => g.IsMatch(path)); diff --git a/tests/Jellyfin.Server.Implementations.Tests/Library/IgnorePatternsTests.cs b/tests/Jellyfin.Server.Implementations.Tests/Library/IgnorePatternsTests.cs index 26dee38c6d..c145ddc9d7 100644 --- a/tests/Jellyfin.Server.Implementations.Tests/Library/IgnorePatternsTests.cs +++ b/tests/Jellyfin.Server.Implementations.Tests/Library/IgnorePatternsTests.cs @@ -7,12 +7,19 @@ namespace Jellyfin.Server.Implementations.Tests.Library { [Theory] [InlineData("/media/small.jpg", true)] + [InlineData("/media/albumart.jpg", true)] + [InlineData("/media/movie.sample.mp4", true)] [InlineData("/media/movies/#Recycle/test.txt", true)] [InlineData("/media/movies/#recycle/", true)] + [InlineData("/media/movies/#recycle", true)] [InlineData("thumbs.db", true)] [InlineData(@"C:\media\movies\movie.avi", false)] [InlineData("/media/.hiddendir/file.mp4", true)] [InlineData("/media/dir/.hiddenfile.mp4", true)] + [InlineData("/volume1/video/Series/@eaDir", true)] + [InlineData("/volume1/video/Series/@eaDir/file.txt", true)] + [InlineData("/directory/@Recycle", true)] + [InlineData("/directory/@Recycle/file.mp3", true)] public void PathIgnored(string path, bool expected) { Assert.Equal(expected, IgnorePatterns.ShouldIgnore(path)); From ef49e2b21ccfbf8ffcaf524d4f5fa6949fd31b94 Mon Sep 17 00:00:00 2001 From: crobibero Date: Fri, 26 Jun 2020 13:20:49 -0600 Subject: [PATCH 33/81] Fix nullable string usage. --- MediaBrowser.LocalMetadata/Parsers/BaseItemXmlParser.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MediaBrowser.LocalMetadata/Parsers/BaseItemXmlParser.cs b/MediaBrowser.LocalMetadata/Parsers/BaseItemXmlParser.cs index e11ceb826d..4ac2498400 100644 --- a/MediaBrowser.LocalMetadata/Parsers/BaseItemXmlParser.cs +++ b/MediaBrowser.LocalMetadata/Parsers/BaseItemXmlParser.cs @@ -81,7 +81,7 @@ namespace MediaBrowser.LocalMetadata.Parsers var id = info.Key + "Id"; if (!_validProviderIds.ContainsKey(id)) { - _validProviderIds.Add(id, info.Key); + _validProviderIds.Add(id, info.Key!); } } From cb193b6afd339ab62a76644e02e9459962756c00 Mon Sep 17 00:00:00 2001 From: Bond-009 Date: Sat, 27 Jun 2020 11:32:57 +0200 Subject: [PATCH 34/81] Add support for ReadOnlySpan in IgnorePatterns --- .../Library/IgnorePatterns.cs | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/Emby.Server.Implementations/Library/IgnorePatterns.cs b/Emby.Server.Implementations/Library/IgnorePatterns.cs index cd5c5f19db..6e6ef1359a 100644 --- a/Emby.Server.Implementations/Library/IgnorePatterns.cs +++ b/Emby.Server.Implementations/Library/IgnorePatterns.cs @@ -1,3 +1,6 @@ +#nullable enable + +using System; using System.Linq; using DotNet.Globbing; @@ -88,9 +91,18 @@ namespace Emby.Server.Implementations.Library /// /// The path to test. /// Whether to ignore the path. - public static bool ShouldIgnore(string path) + public static bool ShouldIgnore(ReadOnlySpan path) { - return _globs.Any(g => g.IsMatch(path)); + int len = _globs.Length; + for (int i = 0; i < len; i++) + { + if (_globs[i].IsMatch(path)) + { + return true; + } + } + + return false; } } } From 2f4860741c807a866280e08239ff5727abd8455c Mon Sep 17 00:00:00 2001 From: BaronGreenback Date: Sat, 27 Jun 2020 15:41:57 +0100 Subject: [PATCH 35/81] _config.Configuration.PluginRespositories not instantiated causing InstallationManager.cs to crash with a null pointer. --- MediaBrowser.Model/Configuration/ServerConfiguration.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/MediaBrowser.Model/Configuration/ServerConfiguration.cs b/MediaBrowser.Model/Configuration/ServerConfiguration.cs index b87c8fbab2..83769a2958 100644 --- a/MediaBrowser.Model/Configuration/ServerConfiguration.cs +++ b/MediaBrowser.Model/Configuration/ServerConfiguration.cs @@ -270,6 +270,8 @@ namespace MediaBrowser.Model.Configuration IgnoreVirtualInterfaces = false; EnableSimpleArtistDetection = false; + PluginRepositories = new List(); + DisplaySpecialsWithinSeasons = true; EnableExternalContentInSuggestions = true; From 332527cf8c84b1b2d30a67d80de3d9bd7aa8d1dc Mon Sep 17 00:00:00 2001 From: Gonzalo Seguel Date: Sun, 28 Jun 2020 03:59:24 +0000 Subject: [PATCH 36/81] Translated using Weblate (Spanish (Mexico)) Translation: Jellyfin/Jellyfin Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-core/es_MX/ --- Emby.Server.Implementations/Localization/Core/es-MX.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Emby.Server.Implementations/Localization/Core/es-MX.json b/Emby.Server.Implementations/Localization/Core/es-MX.json index 20b37ec9f2..4ba324aa1b 100644 --- a/Emby.Server.Implementations/Localization/Core/es-MX.json +++ b/Emby.Server.Implementations/Localization/Core/es-MX.json @@ -31,7 +31,7 @@ "ItemAddedWithName": "{0} fue agregado a la biblioteca", "ItemRemovedWithName": "{0} fue removido de la biblioteca", "LabelIpAddressValue": "Dirección IP: {0}", - "LabelRunningTimeValue": "Duración: {0}", + "LabelRunningTimeValue": "Tiempo de reproducción: {0}", "Latest": "Recientes", "MessageApplicationUpdated": "El servidor Jellyfin ha sido actualizado", "MessageApplicationUpdatedTo": "El servidor Jellyfin ha sido actualizado a {0}", From 4e2115cd834cbf0a15c68acc6136561279e5944d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 29 Jun 2020 12:24:58 +0000 Subject: [PATCH 37/81] Bump AutoFixture from 4.11.0 to 4.12.0 Bumps [AutoFixture](https://github.com/AutoFixture/AutoFixture) from 4.11.0 to 4.12.0. - [Release notes](https://github.com/AutoFixture/AutoFixture/releases) - [Commits](https://github.com/AutoFixture/AutoFixture/compare/v4.11.0...v4.12.0) Signed-off-by: dependabot[bot] --- tests/Jellyfin.Api.Tests/Jellyfin.Api.Tests.csproj | 2 +- .../Jellyfin.Server.Implementations.Tests.csproj | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/Jellyfin.Api.Tests/Jellyfin.Api.Tests.csproj b/tests/Jellyfin.Api.Tests/Jellyfin.Api.Tests.csproj index 074bf23710..8b12828f00 100644 --- a/tests/Jellyfin.Api.Tests/Jellyfin.Api.Tests.csproj +++ b/tests/Jellyfin.Api.Tests/Jellyfin.Api.Tests.csproj @@ -13,7 +13,7 @@ - + diff --git a/tests/Jellyfin.Server.Implementations.Tests/Jellyfin.Server.Implementations.Tests.csproj b/tests/Jellyfin.Server.Implementations.Tests/Jellyfin.Server.Implementations.Tests.csproj index 91fd0e2e2e..efcc7087d7 100644 --- a/tests/Jellyfin.Server.Implementations.Tests/Jellyfin.Server.Implementations.Tests.csproj +++ b/tests/Jellyfin.Server.Implementations.Tests/Jellyfin.Server.Implementations.Tests.csproj @@ -14,7 +14,7 @@ - + From 84e74dbc500aa97d7f11298d0d0d95137d29a5a4 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 29 Jun 2020 12:25:06 +0000 Subject: [PATCH 38/81] Bump Swashbuckle.AspNetCore from 5.5.0 to 5.5.1 Bumps [Swashbuckle.AspNetCore](https://github.com/domaindrivendev/Swashbuckle.AspNetCore) from 5.5.0 to 5.5.1. - [Release notes](https://github.com/domaindrivendev/Swashbuckle.AspNetCore/releases) - [Commits](https://github.com/domaindrivendev/Swashbuckle.AspNetCore/compare/v5.5.0...v5.5.1) Signed-off-by: dependabot[bot] --- Jellyfin.Api/Jellyfin.Api.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Jellyfin.Api/Jellyfin.Api.csproj b/Jellyfin.Api/Jellyfin.Api.csproj index 55c5ef1b19..93c4612b66 100644 --- a/Jellyfin.Api/Jellyfin.Api.csproj +++ b/Jellyfin.Api/Jellyfin.Api.csproj @@ -16,7 +16,7 @@ - + From 80b43fb805a33a4fd2ea6a413917cf096e81bb14 Mon Sep 17 00:00:00 2001 From: crobibero Date: Mon, 29 Jun 2020 07:27:15 -0600 Subject: [PATCH 39/81] bump autofixture --- tests/Jellyfin.Api.Tests/Jellyfin.Api.Tests.csproj | 4 ++-- .../Jellyfin.Server.Implementations.Tests.csproj | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/Jellyfin.Api.Tests/Jellyfin.Api.Tests.csproj b/tests/Jellyfin.Api.Tests/Jellyfin.Api.Tests.csproj index 8b12828f00..93646d4a33 100644 --- a/tests/Jellyfin.Api.Tests/Jellyfin.Api.Tests.csproj +++ b/tests/Jellyfin.Api.Tests/Jellyfin.Api.Tests.csproj @@ -14,8 +14,8 @@ - - + + diff --git a/tests/Jellyfin.Server.Implementations.Tests/Jellyfin.Server.Implementations.Tests.csproj b/tests/Jellyfin.Server.Implementations.Tests/Jellyfin.Server.Implementations.Tests.csproj index efcc7087d7..f9a9f4d40e 100644 --- a/tests/Jellyfin.Server.Implementations.Tests/Jellyfin.Server.Implementations.Tests.csproj +++ b/tests/Jellyfin.Server.Implementations.Tests/Jellyfin.Server.Implementations.Tests.csproj @@ -15,7 +15,7 @@ - + From 438977350892179d5dc2259316b0fe27ceb1e5da Mon Sep 17 00:00:00 2001 From: Neil Burrows Date: Mon, 29 Jun 2020 17:08:20 +0100 Subject: [PATCH 40/81] Respect FFMpeg path passed via Environment Variable --- Emby.Server.Implementations/ApplicationHost.cs | 3 +-- Jellyfin.Server/StartupOptions.cs | 5 +++++ .../Extensions/ConfigurationExtensions.cs | 5 +++++ MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs | 7 ++++--- 4 files changed, 15 insertions(+), 5 deletions(-) diff --git a/Emby.Server.Implementations/ApplicationHost.cs b/Emby.Server.Implementations/ApplicationHost.cs index 14267b5613..8d213ac57d 100644 --- a/Emby.Server.Implementations/ApplicationHost.cs +++ b/Emby.Server.Implementations/ApplicationHost.cs @@ -568,8 +568,7 @@ namespace Emby.Server.Implementations // TODO: Refactor to eliminate the circular dependency here so that Lazy isn't required // TODO: Add StartupOptions.FFmpegPath to IConfiguration and remove this custom activation serviceCollection.AddTransient(provider => new Lazy(provider.GetRequiredService)); - serviceCollection.AddSingleton(provider => - ActivatorUtilities.CreateInstance(provider, _startupOptions.FFmpegPath ?? string.Empty)); + serviceCollection.AddSingleton(); // TODO: Refactor to eliminate the circular dependencies here so that Lazy isn't required serviceCollection.AddTransient(provider => new Lazy(provider.GetRequiredService)); diff --git a/Jellyfin.Server/StartupOptions.cs b/Jellyfin.Server/StartupOptions.cs index a26114e778..41a1430d26 100644 --- a/Jellyfin.Server/StartupOptions.cs +++ b/Jellyfin.Server/StartupOptions.cs @@ -101,6 +101,11 @@ namespace Jellyfin.Server config.Add(UdpServer.AddressOverrideConfigKey, PublishedServerUrl.ToString()); } + if (FFmpegPath != null) + { + config.Add(ConfigurationExtensions.FfmpegPathKey, FFmpegPath); + } + return config; } } diff --git a/MediaBrowser.Controller/Extensions/ConfigurationExtensions.cs b/MediaBrowser.Controller/Extensions/ConfigurationExtensions.cs index c0043c0efa..c2932cc4c4 100644 --- a/MediaBrowser.Controller/Extensions/ConfigurationExtensions.cs +++ b/MediaBrowser.Controller/Extensions/ConfigurationExtensions.cs @@ -23,6 +23,11 @@ namespace MediaBrowser.Controller.Extensions /// public const string FfmpegAnalyzeDurationKey = "FFmpeg:analyzeduration"; + /// + /// The key for the FFmpeg path option. + /// + public const string FfmpegPathKey = "ffmpeg"; + /// /// The key for a setting that indicates whether playlists should allow duplicate entries. /// diff --git a/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs b/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs index 9397a347f3..af99f2521d 100644 --- a/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs +++ b/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs @@ -21,6 +21,7 @@ using MediaBrowser.Model.MediaInfo; using MediaBrowser.Model.System; using Microsoft.Extensions.Logging; using System.Diagnostics; +using Microsoft.Extensions.Configuration; namespace MediaBrowser.MediaEncoding.Encoder { @@ -46,7 +47,7 @@ namespace MediaBrowser.MediaEncoding.Encoder private readonly object _runningProcessesLock = new object(); private readonly List _runningProcesses = new List(); - private string _ffmpegPath; + private string _ffmpegPath = string.Empty; private string _ffprobePath; public MediaEncoder( @@ -55,14 +56,14 @@ namespace MediaBrowser.MediaEncoding.Encoder IFileSystem fileSystem, ILocalizationManager localization, Lazy encodingHelperFactory, - string startupOptionsFFmpegPath) + IConfiguration config) { _logger = logger; _configurationManager = configurationManager; _fileSystem = fileSystem; _localization = localization; _encodingHelperFactory = encodingHelperFactory; - _startupOptionFFmpegPath = startupOptionsFFmpegPath; + _startupOptionFFmpegPath = config.GetValue(Controller.Extensions.ConfigurationExtensions.FfmpegPathKey) ?? ""; } private EncodingHelper EncodingHelper => _encodingHelperFactory.Value; From 4748df26b6b690f58867dbc2c39f23c44553f7a5 Mon Sep 17 00:00:00 2001 From: Neil Burrows Date: Mon, 29 Jun 2020 17:25:12 +0100 Subject: [PATCH 41/81] Remove un-needed comment --- Emby.Server.Implementations/ApplicationHost.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/Emby.Server.Implementations/ApplicationHost.cs b/Emby.Server.Implementations/ApplicationHost.cs index 8d213ac57d..18b6834ef5 100644 --- a/Emby.Server.Implementations/ApplicationHost.cs +++ b/Emby.Server.Implementations/ApplicationHost.cs @@ -566,7 +566,6 @@ namespace Emby.Server.Implementations serviceCollection.AddTransient(provider => new Lazy(provider.GetRequiredService)); // TODO: Refactor to eliminate the circular dependency here so that Lazy isn't required - // TODO: Add StartupOptions.FFmpegPath to IConfiguration and remove this custom activation serviceCollection.AddTransient(provider => new Lazy(provider.GetRequiredService)); serviceCollection.AddSingleton(); From 6b532b3da56a3f7fa0ef920a1f14ba8db70bcb35 Mon Sep 17 00:00:00 2001 From: Neil Burrows Date: Mon, 29 Jun 2020 20:52:20 +0100 Subject: [PATCH 42/81] User string.Empty instead of "" Co-authored-by: Patrick Barron <18354464+barronpm@users.noreply.github.com> --- MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs b/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs index af99f2521d..62fdbc618a 100644 --- a/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs +++ b/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs @@ -63,7 +63,7 @@ namespace MediaBrowser.MediaEncoding.Encoder _fileSystem = fileSystem; _localization = localization; _encodingHelperFactory = encodingHelperFactory; - _startupOptionFFmpegPath = config.GetValue(Controller.Extensions.ConfigurationExtensions.FfmpegPathKey) ?? ""; + _startupOptionFFmpegPath = config.GetValue(Controller.Extensions.ConfigurationExtensions.FfmpegPathKey) ?? string.Empty; } private EncodingHelper EncodingHelper => _encodingHelperFactory.Value; From 248a2d61ddfa40683f6b76986383272d7baec238 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 30 Jun 2020 02:20:44 +0000 Subject: [PATCH 43/81] Bump Moq from 4.14.3 to 4.14.4 Bumps [Moq](https://github.com/moq/moq4) from 4.14.3 to 4.14.4. - [Release notes](https://github.com/moq/moq4/releases) - [Changelog](https://github.com/moq/moq4/blob/master/CHANGELOG.md) - [Commits](https://github.com/moq/moq4/compare/v4.14.3...v4.14.4) Signed-off-by: dependabot[bot] --- tests/Jellyfin.Api.Tests/Jellyfin.Api.Tests.csproj | 2 +- .../Jellyfin.Server.Implementations.Tests.csproj | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/Jellyfin.Api.Tests/Jellyfin.Api.Tests.csproj b/tests/Jellyfin.Api.Tests/Jellyfin.Api.Tests.csproj index 93646d4a33..100f954245 100644 --- a/tests/Jellyfin.Api.Tests/Jellyfin.Api.Tests.csproj +++ b/tests/Jellyfin.Api.Tests/Jellyfin.Api.Tests.csproj @@ -21,7 +21,7 @@ - + diff --git a/tests/Jellyfin.Server.Implementations.Tests/Jellyfin.Server.Implementations.Tests.csproj b/tests/Jellyfin.Server.Implementations.Tests/Jellyfin.Server.Implementations.Tests.csproj index f9a9f4d40e..dd53c99023 100644 --- a/tests/Jellyfin.Server.Implementations.Tests/Jellyfin.Server.Implementations.Tests.csproj +++ b/tests/Jellyfin.Server.Implementations.Tests/Jellyfin.Server.Implementations.Tests.csproj @@ -16,7 +16,7 @@ - + From 1140bcc669f040027cac2c083f0d84f3187e1ffe Mon Sep 17 00:00:00 2001 From: Zyzto Date: Wed, 1 Jul 2020 00:24:14 +0000 Subject: [PATCH 44/81] Translated using Weblate (Arabic) Translation: Jellyfin/Jellyfin Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-core/ar/ --- Emby.Server.Implementations/Localization/Core/ar.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Emby.Server.Implementations/Localization/Core/ar.json b/Emby.Server.Implementations/Localization/Core/ar.json index d68928fce4..4eac8e75de 100644 --- a/Emby.Server.Implementations/Localization/Core/ar.json +++ b/Emby.Server.Implementations/Localization/Core/ar.json @@ -1,5 +1,5 @@ { - "Albums": "ألبومات", + "Albums": "البومات", "AppDeviceValues": "تطبيق: {0}, جهاز: {1}", "Application": "تطبيق", "Artists": "الفنانين", @@ -14,7 +14,7 @@ "FailedLoginAttemptWithUserName": "عملية تسجيل الدخول فشلت من {0}", "Favorites": "المفضلة", "Folders": "المجلدات", - "Genres": "الأنواع", + "Genres": "التضنيفات", "HeaderAlbumArtists": "فناني الألبومات", "HeaderCameraUploads": "تحميلات الكاميرا", "HeaderContinueWatching": "استئناف", @@ -50,7 +50,7 @@ "NotificationOptionAudioPlayback": "بدأ تشغيل المقطع الصوتي", "NotificationOptionAudioPlaybackStopped": "تم إيقاف تشغيل المقطع الصوتي", "NotificationOptionCameraImageUploaded": "تم رفع صورة الكاميرا", - "NotificationOptionInstallationFailed": "فشل في التثبيت", + "NotificationOptionInstallationFailed": "فشل التثبيت", "NotificationOptionNewLibraryContent": "تم إضافة محتوى جديد", "NotificationOptionPluginError": "فشل في البرنامج المضاف", "NotificationOptionPluginInstalled": "تم تثبيت الملحق", From af334f96d64fe8fdc91ea2a8cc5f880ed54e3fa5 Mon Sep 17 00:00:00 2001 From: Anthony Lavado Date: Fri, 3 Jul 2020 14:11:38 -0400 Subject: [PATCH 45/81] Use newer Jellyfin.XmlTv for Guide Fixes --- Emby.Server.Implementations/Emby.Server.Implementations.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Emby.Server.Implementations/Emby.Server.Implementations.csproj b/Emby.Server.Implementations/Emby.Server.Implementations.csproj index e75b662934..f7ad59c10f 100644 --- a/Emby.Server.Implementations/Emby.Server.Implementations.csproj +++ b/Emby.Server.Implementations/Emby.Server.Implementations.csproj @@ -25,7 +25,7 @@ - + From f5c53528618f2cd644f0d787c1e367f9886ff79a Mon Sep 17 00:00:00 2001 From: nyanmisaka Date: Sat, 4 Jul 2020 19:14:49 +0800 Subject: [PATCH 46/81] add FFmpeg 4.3 detection and tests --- .../Encoder/EncoderValidator.cs | 1 + .../EncoderValidatorTests.cs | 2 ++ .../EncoderValidatorTestsData.cs | 12 ++++++++++++ 3 files changed, 15 insertions(+) diff --git a/MediaBrowser.MediaEncoding/Encoder/EncoderValidator.cs b/MediaBrowser.MediaEncoding/Encoder/EncoderValidator.cs index 4250edfb7f..0fd0239b4a 100644 --- a/MediaBrowser.MediaEncoding/Encoder/EncoderValidator.cs +++ b/MediaBrowser.MediaEncoding/Encoder/EncoderValidator.cs @@ -90,6 +90,7 @@ namespace MediaBrowser.MediaEncoding.Encoder // $ ffmpeg -version | perl -ne ' print "$1=$2.$3," if /^(lib\w+)\s+(\d+)\.\s*(\d+)/' private static readonly IReadOnlyDictionary _ffmpegVersionMap = new Dictionary { + { "libavutil=56.51,libavcodec=58.91,libavformat=58.45,libavdevice=58.10,libavfilter=7.85,libswscale=5.7,libswresample=3.7,libpostproc=55.7,", new Version(4, 3) }, { "libavutil=56.31,libavcodec=58.54,libavformat=58.29,libavdevice=58.8,libavfilter=7.57,libswscale=5.5,libswresample=3.5,libpostproc=55.5,", new Version(4, 2) }, { "libavutil=56.22,libavcodec=58.35,libavformat=58.20,libavdevice=58.5,libavfilter=7.40,libswscale=5.3,libswresample=3.3,libpostproc=55.3,", new Version(4, 1) }, { "libavutil=56.14,libavcodec=58.18,libavformat=58.12,libavdevice=58.3,libavfilter=7.16,libswscale=5.1,libswresample=3.1,libpostproc=55.1,", new Version(4, 0) }, diff --git a/tests/Jellyfin.MediaEncoding.Tests/EncoderValidatorTests.cs b/tests/Jellyfin.MediaEncoding.Tests/EncoderValidatorTests.cs index af29fec870..9eb601edf7 100644 --- a/tests/Jellyfin.MediaEncoding.Tests/EncoderValidatorTests.cs +++ b/tests/Jellyfin.MediaEncoding.Tests/EncoderValidatorTests.cs @@ -17,6 +17,7 @@ namespace Jellyfin.MediaEncoding.Tests } [Theory] + [InlineData(EncoderValidatorTestsData.FFmpegV43Output, true)] [InlineData(EncoderValidatorTestsData.FFmpegV421Output, true)] [InlineData(EncoderValidatorTestsData.FFmpegV42Output, true)] [InlineData(EncoderValidatorTestsData.FFmpegV414Output, true)] @@ -32,6 +33,7 @@ namespace Jellyfin.MediaEncoding.Tests { public IEnumerator GetEnumerator() { + yield return new object?[] { EncoderValidatorTestsData.FFmpegV43Output, new Version(4, 3) }; yield return new object?[] { EncoderValidatorTestsData.FFmpegV421Output, new Version(4, 2, 1) }; yield return new object?[] { EncoderValidatorTestsData.FFmpegV42Output, new Version(4, 2) }; yield return new object?[] { EncoderValidatorTestsData.FFmpegV414Output, new Version(4, 1, 4) }; diff --git a/tests/Jellyfin.MediaEncoding.Tests/EncoderValidatorTestsData.cs b/tests/Jellyfin.MediaEncoding.Tests/EncoderValidatorTestsData.cs index c46c9578b9..f5ff3d723a 100644 --- a/tests/Jellyfin.MediaEncoding.Tests/EncoderValidatorTestsData.cs +++ b/tests/Jellyfin.MediaEncoding.Tests/EncoderValidatorTestsData.cs @@ -2,6 +2,18 @@ namespace Jellyfin.MediaEncoding.Tests { internal static class EncoderValidatorTestsData { + public const string FFmpegV43Output = @"ffmpeg version 4.3 Copyright (c) 2000-2020 the FFmpeg developers +built with gcc 7 (Ubuntu 7.5.0-3ubuntu1~18.04) +configuration: --prefix=/usr/lib/jellyfin-ffmpeg --target-os=linux --disable-doc --disable-ffplay --disable-shared --disable-libxcb --disable-vdpau --disable-sdl2 --disable-xlib --enable-gpl --enable-version3 --enable-static --enable-libfontconfig --enable-fontconfig --enable-gmp --enable-gnutls --enable-libass --enable-libbluray --enable-libdrm --enable-libfreetype --enable-libfribidi --enable-libmp3lame --enable-libopus --enable-libtheora --enable-libvorbis --enable-libwebp --enable-libx264 --enable-libx265 --enable-libzvbi --arch=amd64 --enable-amf --enable-nvenc --enable-nvdec --enable-vaapi --enable-opencl +libavutil 56. 51.100 / 56. 51.100 +libavcodec 58. 91.100 / 58. 91.100 +libavformat 58. 45.100 / 58. 45.100 +libavdevice 58. 10.100 / 58. 10.100 +libavfilter 7. 85.100 / 7. 85.100 +libswscale 5. 7.100 / 5. 7.100 +libswresample 3. 7.100 / 3. 7.100 +libpostproc 55. 7.100 / 55. 7.100"; + public const string FFmpegV421Output = @"ffmpeg version 4.2.1 Copyright (c) 2000-2019 the FFmpeg developers built with gcc 9.1.1 (GCC) 20190807 configuration: --enable-gpl --enable-version3 --enable-sdl2 --enable-fontconfig --enable-gnutls --enable-iconv --enable-libass --enable-libdav1d --enable-libbluray --enable-libfreetype --enable-libmp3lame --enable-libopencore-amrnb --enable-libopencore-amrwb --enable-libopenjpeg --enable-libopus --enable-libshine --enable-libsnappy --enable-libsoxr --enable-libtheora --enable-libtwolame --enable-libvpx --enable-libwavpack --enable-libwebp --enable-libx264 --enable-libx265 --enable-libxml2 --enable-libzimg --enable-lzma --enable-zlib --enable-gmp --enable-libvidstab --enable-libvorbis --enable-libvo-amrwbenc --enable-libmysofa --enable-libspeex --enable-libxvid --enable-libaom --enable-libmfx --enable-amf --enable-ffnvcodec --enable-cuvid --enable-d3d11va --enable-nvenc --enable-nvdec --enable-dxva2 --enable-avisynth --enable-libopenmpt From ce85cea9fa9b2444ead5b5c4857c9e9b56c4eb55 Mon Sep 17 00:00:00 2001 From: nyanmisaka Date: Sat, 4 Jul 2020 19:21:16 +0800 Subject: [PATCH 47/81] solve the green line issue on QSV --- .../MediaEncoding/EncodingHelper.cs | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs b/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs index d3fb6a46d4..cbfdf26959 100644 --- a/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs +++ b/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs @@ -483,7 +483,7 @@ namespace MediaBrowser.Controller.MediaEncoding { if (isQsvDecoder) { - arg.Append("-hwaccel qsv "); + arg.Append("-hwaccel qsv -init_hw_device qsv=hw "); } // While using SW decoder else @@ -1757,7 +1757,7 @@ namespace MediaBrowser.Controller.MediaEncoding // output dimensions. Output dimensions are guaranteed to be even. var outputWidth = width.Value; var outputHeight = height.Value; - var vaapi_or_qsv = string.Equals(videoEncoder, "h264_qsv", StringComparison.OrdinalIgnoreCase) ? "qsv" : "vaapi"; + var qsv_or_vaapi = string.Equals(videoEncoder, "h264_qsv", StringComparison.OrdinalIgnoreCase); if (!videoWidth.HasValue || outputWidth != videoWidth.Value @@ -1765,17 +1765,19 @@ namespace MediaBrowser.Controller.MediaEncoding || outputHeight != videoHeight.Value) { // Force nv12 pixel format to enable 10-bit to 8-bit colour conversion. + // use vpp_qsv filter to avoid green bar when the fixed output size is requested. filters.Add( string.Format( CultureInfo.InvariantCulture, - "scale_{0}=w={1}:h={2}:format=nv12", - vaapi_or_qsv, + "{0}=w={1}:h={2}:format=nv12", + qsv_or_vaapi ? "vpp_qsv" : "scale_vaapi", outputWidth, outputHeight)); } else { - filters.Add(string.Format(CultureInfo.InvariantCulture, "scale_{0}=format=nv12", vaapi_or_qsv)); + // set w=0:h=0 for vpp_qsv to keep the original dimensions, otherwise it will fail. + filters.Add(string.Format(CultureInfo.InvariantCulture, "{0}format=nv12", qsv_or_vaapi ? "vpp_qsv=w=0:h=0:" : "scale_vaapi=")); } } else if ((videoDecoder ?? string.Empty).IndexOf("cuvid", StringComparison.OrdinalIgnoreCase) != -1 From d0098f1b95bded47740ffa124db19df20ec27063 Mon Sep 17 00:00:00 2001 From: nyanmisaka Date: Sat, 4 Jul 2020 19:54:40 +0800 Subject: [PATCH 48/81] update ffmpeg 4.3 from zeranoe builds --- deployment/build.windows.amd64 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/deployment/build.windows.amd64 b/deployment/build.windows.amd64 index 3fabc2cac6..aae061e9d6 100755 --- a/deployment/build.windows.amd64 +++ b/deployment/build.windows.amd64 @@ -8,7 +8,7 @@ set -o xtrace # Version variables NSSM_VERSION="nssm-2.24-101-g897c7ad" NSSM_URL="http://files.evilt.win/nssm/${NSSM_VERSION}.zip" -FFMPEG_VERSION="ffmpeg-4.2.1-win64-static" +FFMPEG_VERSION="ffmpeg-4.3-win64-static" FFMPEG_URL="https://ffmpeg.zeranoe.com/builds/win64/static/${FFMPEG_VERSION}.zip" # Move to source directory From 6d1b00da648e01a15c0c0384c79d37c824358769 Mon Sep 17 00:00:00 2001 From: Patrick Barron Date: Sat, 4 Jul 2020 11:54:25 -0400 Subject: [PATCH 49/81] Use Array.Empty --- Emby.Dlna/Profiles/DefaultProfile.cs | 2 +- Emby.Dlna/Profiles/DenonAvrProfile.cs | 2 +- Emby.Dlna/Profiles/DirectTvProfile.cs | 2 +- Emby.Dlna/Profiles/Foobar2000Profile.cs | 2 +- Emby.Dlna/Profiles/MarantzProfile.cs | 2 +- Emby.Dlna/Profiles/MediaMonkeyProfile.cs | 3 ++- Emby.Dlna/Profiles/SonyBlurayPlayer2013.cs | 3 ++- Emby.Dlna/Profiles/SonyBlurayPlayer2014.cs | 3 ++- Emby.Dlna/Profiles/SonyBlurayPlayer2015.cs | 3 ++- Emby.Dlna/Profiles/SonyBlurayPlayer2016.cs | 3 ++- MediaBrowser.Api/FilterService.cs | 2 +- MediaBrowser.Controller/Entities/BaseItem.cs | 2 +- MediaBrowser.Controller/Entities/Movies/BoxSet.cs | 2 +- MediaBrowser.Controller/Library/TVUtils.cs | 2 +- MediaBrowser.MediaEncoding/BdInfo/BdInfoExaminer.cs | 2 +- .../Probing/ProbeResultNormalizer.cs | 4 ++-- .../Dlna/MediaFormatProfileResolver.cs | 2 +- MediaBrowser.Model/Dlna/StreamInfo.cs | 12 ++++++------ MediaBrowser.Model/Querying/UpcomingEpisodesQuery.cs | 3 ++- MediaBrowser.Providers/Manager/MetadataService.cs | 4 ++-- 20 files changed, 33 insertions(+), 27 deletions(-) diff --git a/Emby.Dlna/Profiles/DefaultProfile.cs b/Emby.Dlna/Profiles/DefaultProfile.cs index 2347ebd0d3..90a23a4a22 100644 --- a/Emby.Dlna/Profiles/DefaultProfile.cs +++ b/Emby.Dlna/Profiles/DefaultProfile.cs @@ -164,7 +164,7 @@ namespace Emby.Dlna.Profiles public void AddXmlRootAttribute(string name, string value) { - var atts = XmlRootAttributes ?? new XmlAttribute[] { }; + var atts = XmlRootAttributes ?? System.Array.Empty(); var list = atts.ToList(); list.Add(new XmlAttribute diff --git a/Emby.Dlna/Profiles/DenonAvrProfile.cs b/Emby.Dlna/Profiles/DenonAvrProfile.cs index 73a87c499e..a5ba0f36cc 100644 --- a/Emby.Dlna/Profiles/DenonAvrProfile.cs +++ b/Emby.Dlna/Profiles/DenonAvrProfile.cs @@ -28,7 +28,7 @@ namespace Emby.Dlna.Profiles }, }; - ResponseProfiles = new ResponseProfile[] { }; + ResponseProfiles = System.Array.Empty(); } } } diff --git a/Emby.Dlna/Profiles/DirectTvProfile.cs b/Emby.Dlna/Profiles/DirectTvProfile.cs index 5ca388167b..f6f98b07d8 100644 --- a/Emby.Dlna/Profiles/DirectTvProfile.cs +++ b/Emby.Dlna/Profiles/DirectTvProfile.cs @@ -123,7 +123,7 @@ namespace Emby.Dlna.Profiles } }; - ResponseProfiles = new ResponseProfile[] { }; + ResponseProfiles = System.Array.Empty(); } } } diff --git a/Emby.Dlna/Profiles/Foobar2000Profile.cs b/Emby.Dlna/Profiles/Foobar2000Profile.cs index ea3de686a6..68e959770a 100644 --- a/Emby.Dlna/Profiles/Foobar2000Profile.cs +++ b/Emby.Dlna/Profiles/Foobar2000Profile.cs @@ -72,7 +72,7 @@ namespace Emby.Dlna.Profiles } }; - ResponseProfiles = new ResponseProfile[] { }; + ResponseProfiles = System.Array.Empty(); } } } diff --git a/Emby.Dlna/Profiles/MarantzProfile.cs b/Emby.Dlna/Profiles/MarantzProfile.cs index 6cfcc3b824..24078ab29c 100644 --- a/Emby.Dlna/Profiles/MarantzProfile.cs +++ b/Emby.Dlna/Profiles/MarantzProfile.cs @@ -37,7 +37,7 @@ namespace Emby.Dlna.Profiles }, }; - ResponseProfiles = new ResponseProfile[] { }; + ResponseProfiles = System.Array.Empty(); } } } diff --git a/Emby.Dlna/Profiles/MediaMonkeyProfile.cs b/Emby.Dlna/Profiles/MediaMonkeyProfile.cs index 7161af7386..28d639b6db 100644 --- a/Emby.Dlna/Profiles/MediaMonkeyProfile.cs +++ b/Emby.Dlna/Profiles/MediaMonkeyProfile.cs @@ -1,5 +1,6 @@ #pragma warning disable CS1591 +using System; using MediaBrowser.Model.Dlna; namespace Emby.Dlna.Profiles @@ -37,7 +38,7 @@ namespace Emby.Dlna.Profiles } }; - ResponseProfiles = new ResponseProfile[] { }; + ResponseProfiles = Array.Empty(); } } } diff --git a/Emby.Dlna/Profiles/SonyBlurayPlayer2013.cs b/Emby.Dlna/Profiles/SonyBlurayPlayer2013.cs index 42b066d52b..238fe9f6bc 100644 --- a/Emby.Dlna/Profiles/SonyBlurayPlayer2013.cs +++ b/Emby.Dlna/Profiles/SonyBlurayPlayer2013.cs @@ -1,5 +1,6 @@ #pragma warning disable CS1591 +using System; using MediaBrowser.Model.Dlna; namespace Emby.Dlna.Profiles @@ -223,7 +224,7 @@ namespace Emby.Dlna.Profiles } }; - ResponseProfiles = new ResponseProfile[] { }; + ResponseProfiles = Array.Empty(); } } } diff --git a/Emby.Dlna/Profiles/SonyBlurayPlayer2014.cs b/Emby.Dlna/Profiles/SonyBlurayPlayer2014.cs index fbdf2c18e8..812a481513 100644 --- a/Emby.Dlna/Profiles/SonyBlurayPlayer2014.cs +++ b/Emby.Dlna/Profiles/SonyBlurayPlayer2014.cs @@ -1,5 +1,6 @@ #pragma warning disable CS1591 +using System; using MediaBrowser.Model.Dlna; namespace Emby.Dlna.Profiles @@ -223,7 +224,7 @@ namespace Emby.Dlna.Profiles } }; - ResponseProfiles = new ResponseProfile[] { }; + ResponseProfiles = Array.Empty(); } } } diff --git a/Emby.Dlna/Profiles/SonyBlurayPlayer2015.cs b/Emby.Dlna/Profiles/SonyBlurayPlayer2015.cs index ce32179a1b..6bfff322ef 100644 --- a/Emby.Dlna/Profiles/SonyBlurayPlayer2015.cs +++ b/Emby.Dlna/Profiles/SonyBlurayPlayer2015.cs @@ -1,5 +1,6 @@ #pragma warning disable CS1591 +using System; using MediaBrowser.Model.Dlna; namespace Emby.Dlna.Profiles @@ -211,7 +212,7 @@ namespace Emby.Dlna.Profiles } }; - ResponseProfiles = new ResponseProfile[] { }; + ResponseProfiles = Array.Empty(); } } } diff --git a/Emby.Dlna/Profiles/SonyBlurayPlayer2016.cs b/Emby.Dlna/Profiles/SonyBlurayPlayer2016.cs index aa1721d398..ec2529574c 100644 --- a/Emby.Dlna/Profiles/SonyBlurayPlayer2016.cs +++ b/Emby.Dlna/Profiles/SonyBlurayPlayer2016.cs @@ -1,5 +1,6 @@ #pragma warning disable CS1591 +using System; using MediaBrowser.Model.Dlna; namespace Emby.Dlna.Profiles @@ -211,7 +212,7 @@ namespace Emby.Dlna.Profiles } }; - ResponseProfiles = new ResponseProfile[] { }; + ResponseProfiles = Array.Empty(); } } } diff --git a/MediaBrowser.Api/FilterService.cs b/MediaBrowser.Api/FilterService.cs index 1b736c77da..dcfdcbfed3 100644 --- a/MediaBrowser.Api/FilterService.cs +++ b/MediaBrowser.Api/FilterService.cs @@ -125,7 +125,7 @@ namespace MediaBrowser.Api IncludeItemTypes = request.GetIncludeItemTypes(), DtoOptions = new Controller.Dto.DtoOptions { - Fields = new ItemFields[] { }, + Fields = Array.Empty(), EnableImages = false, EnableUserData = false }, diff --git a/MediaBrowser.Controller/Entities/BaseItem.cs b/MediaBrowser.Controller/Entities/BaseItem.cs index 25933bc909..90f62e153b 100644 --- a/MediaBrowser.Controller/Entities/BaseItem.cs +++ b/MediaBrowser.Controller/Entities/BaseItem.cs @@ -613,7 +613,7 @@ namespace MediaBrowser.Controller.Entities { if (!IsFileProtocol) { - return new string[] { }; + return Array.Empty(); } return new[] { Path }; diff --git a/MediaBrowser.Controller/Entities/Movies/BoxSet.cs b/MediaBrowser.Controller/Entities/Movies/BoxSet.cs index 70c48b6f1a..c131c5430a 100644 --- a/MediaBrowser.Controller/Entities/Movies/BoxSet.cs +++ b/MediaBrowser.Controller/Entities/Movies/BoxSet.cs @@ -198,7 +198,7 @@ namespace MediaBrowser.Controller.Entities.Movies public Guid[] GetLibraryFolderIds() { - var expandedFolders = new List() { }; + var expandedFolders = new List(); return FlattenItems(this, expandedFolders) .SelectMany(i => LibraryManager.GetCollectionFolders(i)) diff --git a/MediaBrowser.Controller/Library/TVUtils.cs b/MediaBrowser.Controller/Library/TVUtils.cs index fc9b3f1c6e..a3aa6019ec 100644 --- a/MediaBrowser.Controller/Library/TVUtils.cs +++ b/MediaBrowser.Controller/Library/TVUtils.cs @@ -38,7 +38,7 @@ namespace MediaBrowser.Controller.Library }; } - return new DayOfWeek[] { }; + return Array.Empty(); } return null; diff --git a/MediaBrowser.MediaEncoding/BdInfo/BdInfoExaminer.cs b/MediaBrowser.MediaEncoding/BdInfo/BdInfoExaminer.cs index e6359f4fbe..ccfae2fa54 100644 --- a/MediaBrowser.MediaEncoding/BdInfo/BdInfoExaminer.cs +++ b/MediaBrowser.MediaEncoding/BdInfo/BdInfoExaminer.cs @@ -41,7 +41,7 @@ namespace MediaBrowser.MediaEncoding.BdInfo var outputStream = new BlurayDiscInfo { - MediaStreams = new MediaStream[] { } + MediaStreams = Array.Empty() }; if (playlist == null) diff --git a/MediaBrowser.MediaEncoding/Probing/ProbeResultNormalizer.cs b/MediaBrowser.MediaEncoding/Probing/ProbeResultNormalizer.cs index 3f21c2bd40..c85d963ed1 100644 --- a/MediaBrowser.MediaEncoding/Probing/ProbeResultNormalizer.cs +++ b/MediaBrowser.MediaEncoding/Probing/ProbeResultNormalizer.cs @@ -1008,7 +1008,7 @@ namespace MediaBrowser.MediaEncoding.Probing var artist = FFProbeHelpers.GetDictionaryValue(tags, "artist"); if (string.IsNullOrWhiteSpace(artist)) { - audio.Artists = new string[] { }; + audio.Artists = Array.Empty(); } else { @@ -1031,7 +1031,7 @@ namespace MediaBrowser.MediaEncoding.Probing if (string.IsNullOrWhiteSpace(albumArtist)) { - audio.AlbumArtists = new string[] { }; + audio.AlbumArtists = Array.Empty(); } else { diff --git a/MediaBrowser.Model/Dlna/MediaFormatProfileResolver.cs b/MediaBrowser.Model/Dlna/MediaFormatProfileResolver.cs index 398c5db8c8..bdc5f8bb78 100644 --- a/MediaBrowser.Model/Dlna/MediaFormatProfileResolver.cs +++ b/MediaBrowser.Model/Dlna/MediaFormatProfileResolver.cs @@ -206,7 +206,7 @@ namespace MediaBrowser.Model.Dlna } } - return new MediaFormatProfile[] { }; + return Array.Empty(); } private MediaFormatProfile ValueOf(string value) diff --git a/MediaBrowser.Model/Dlna/StreamInfo.cs b/MediaBrowser.Model/Dlna/StreamInfo.cs index b89e9ce90a..8d7554e881 100644 --- a/MediaBrowser.Model/Dlna/StreamInfo.cs +++ b/MediaBrowser.Model/Dlna/StreamInfo.cs @@ -813,18 +813,18 @@ namespace MediaBrowser.Model.Dlna { var stream = TargetAudioStream; - string inputCodec = stream == null ? null : stream.Codec; + string inputCodec = stream?.Codec; if (IsDirectStream) { - return string.IsNullOrEmpty(inputCodec) ? new string[] { } : new[] { inputCodec }; + return string.IsNullOrEmpty(inputCodec) ? Array.Empty() : new[] { inputCodec }; } foreach (string codec in AudioCodecs) { if (string.Equals(codec, inputCodec, StringComparison.OrdinalIgnoreCase)) { - return string.IsNullOrEmpty(codec) ? new string[] { } : new[] { codec }; + return string.IsNullOrEmpty(codec) ? Array.Empty() : new[] { codec }; } } @@ -838,18 +838,18 @@ namespace MediaBrowser.Model.Dlna { var stream = TargetVideoStream; - string inputCodec = stream == null ? null : stream.Codec; + string inputCodec = stream?.Codec; if (IsDirectStream) { - return string.IsNullOrEmpty(inputCodec) ? new string[] { } : new[] { inputCodec }; + return string.IsNullOrEmpty(inputCodec) ? Array.Empty() : new[] { inputCodec }; } foreach (string codec in VideoCodecs) { if (string.Equals(codec, inputCodec, StringComparison.OrdinalIgnoreCase)) { - return string.IsNullOrEmpty(codec) ? new string[] { } : new[] { codec }; + return string.IsNullOrEmpty(codec) ? Array.Empty() : new[] { codec }; } } diff --git a/MediaBrowser.Model/Querying/UpcomingEpisodesQuery.cs b/MediaBrowser.Model/Querying/UpcomingEpisodesQuery.cs index 12d537492a..2ef6f7c60b 100644 --- a/MediaBrowser.Model/Querying/UpcomingEpisodesQuery.cs +++ b/MediaBrowser.Model/Querying/UpcomingEpisodesQuery.cs @@ -1,6 +1,7 @@ #nullable disable #pragma warning disable CS1591 +using System; using MediaBrowser.Model.Entities; namespace MediaBrowser.Model.Querying @@ -54,7 +55,7 @@ namespace MediaBrowser.Model.Querying public UpcomingEpisodesQuery() { - EnableImageTypes = new ImageType[] { }; + EnableImageTypes = Array.Empty(); } } } diff --git a/MediaBrowser.Providers/Manager/MetadataService.cs b/MediaBrowser.Providers/Manager/MetadataService.cs index ecfa3d46dd..3b0c7b56ca 100644 --- a/MediaBrowser.Providers/Manager/MetadataService.cs +++ b/MediaBrowser.Providers/Manager/MetadataService.cs @@ -723,7 +723,7 @@ namespace MediaBrowser.Providers.Manager userDataList.AddRange(localItem.UserDataList); } - MergeData(localItem, temp, new MetadataField[] { }, !options.ReplaceAllMetadata, true); + MergeData(localItem, temp, Array.Empty(), !options.ReplaceAllMetadata, true); refreshResult.UpdateType = refreshResult.UpdateType | ItemUpdateType.MetadataImport; // Only one local provider allowed per item @@ -849,7 +849,7 @@ namespace MediaBrowser.Providers.Manager { result.Provider = provider.Name; - MergeData(result, temp, new MetadataField[] { }, false, false); + MergeData(result, temp, Array.Empty(), false, false); MergeNewData(temp.Item, id); refreshResult.UpdateType = refreshResult.UpdateType | ItemUpdateType.MetadataDownload; From ae6eaa7f02bcd7faf30613f1472e16d03f5637d5 Mon Sep 17 00:00:00 2001 From: Bond_009 Date: Sat, 4 Jul 2020 22:06:27 +0200 Subject: [PATCH 50/81] Minor fixes --- .../ApplicationHost.cs | 26 ++++++++----------- Jellyfin.Server/Program.cs | 4 +-- MediaBrowser.Model/Dlna/StreamInfo.cs | 2 +- .../Plugins/Tmdb/Movies/TmdbMovieProvider.cs | 12 ++++----- 4 files changed, 20 insertions(+), 24 deletions(-) diff --git a/Emby.Server.Implementations/ApplicationHost.cs b/Emby.Server.Implementations/ApplicationHost.cs index 18b6834ef5..531775302b 100644 --- a/Emby.Server.Implementations/ApplicationHost.cs +++ b/Emby.Server.Implementations/ApplicationHost.cs @@ -43,9 +43,9 @@ using Emby.Server.Implementations.Security; using Emby.Server.Implementations.Serialization; using Emby.Server.Implementations.Services; using Emby.Server.Implementations.Session; +using Emby.Server.Implementations.SyncPlay; using Emby.Server.Implementations.TV; using Emby.Server.Implementations.Updates; -using Emby.Server.Implementations.SyncPlay; using MediaBrowser.Api; using MediaBrowser.Common; using MediaBrowser.Common.Configuration; @@ -78,8 +78,8 @@ using MediaBrowser.Controller.Security; using MediaBrowser.Controller.Session; using MediaBrowser.Controller.Sorting; using MediaBrowser.Controller.Subtitles; -using MediaBrowser.Controller.TV; using MediaBrowser.Controller.SyncPlay; +using MediaBrowser.Controller.TV; using MediaBrowser.LocalMetadata.Savers; using MediaBrowser.MediaEncoding.BdInfo; using MediaBrowser.Model.Configuration; @@ -484,12 +484,10 @@ namespace Emby.Server.Implementations foreach (var plugin in Plugins) { - pluginBuilder.AppendLine( - string.Format( - CultureInfo.InvariantCulture, - "{0} {1}", - plugin.Name, - plugin.Version)); + pluginBuilder.Append(plugin.Name) + .Append(' ') + .Append(plugin.Version) + .AppendLine(); } Logger.LogInformation("Plugins: {Plugins}", pluginBuilder.ToString()); @@ -1153,7 +1151,7 @@ namespace Emby.Server.Implementations return null; } - return GetLocalApiUrl(addresses.First()); + return GetLocalApiUrl(addresses[0]); } catch (Exception ex) { @@ -1226,7 +1224,7 @@ namespace Emby.Server.Implementations var addresses = ServerConfigurationManager .Configuration .LocalNetworkAddresses - .Select(NormalizeConfiguredLocalAddress) + .Select(x => NormalizeConfiguredLocalAddress(x)) .Where(i => i != null) .ToList(); @@ -1247,8 +1245,7 @@ namespace Emby.Server.Implementations } } - var valid = await IsLocalIpAddressValidAsync(address, cancellationToken).ConfigureAwait(false); - if (valid) + if (await IsLocalIpAddressValidAsync(address, cancellationToken).ConfigureAwait(false)) { resultList.Add(address); @@ -1262,13 +1259,12 @@ namespace Emby.Server.Implementations return resultList; } - public IPAddress NormalizeConfiguredLocalAddress(string address) + public IPAddress NormalizeConfiguredLocalAddress(ReadOnlySpan address) { var index = address.Trim('/').IndexOf('/'); - if (index != -1) { - address = address.Substring(index + 1); + address = address.Slice(index + 1); } if (IPAddress.TryParse(address.Trim('/'), out IPAddress result)) diff --git a/Jellyfin.Server/Program.cs b/Jellyfin.Server/Program.cs index 4d898ff5e3..ef3ebe90cb 100644 --- a/Jellyfin.Server/Program.cs +++ b/Jellyfin.Server/Program.cs @@ -274,10 +274,10 @@ namespace Jellyfin.Server var addresses = appHost.ServerConfigurationManager .Configuration .LocalNetworkAddresses - .Select(appHost.NormalizeConfiguredLocalAddress) + .Select(x => appHost.NormalizeConfiguredLocalAddress(x)) .Where(i => i != null) .ToHashSet(); - if (addresses.Any() && !addresses.Contains(IPAddress.Any)) + if (addresses.Count > 0 && !addresses.Contains(IPAddress.Any)) { if (!addresses.Contains(IPAddress.Loopback)) { diff --git a/MediaBrowser.Model/Dlna/StreamInfo.cs b/MediaBrowser.Model/Dlna/StreamInfo.cs index b89e9ce90a..fded0d6ed1 100644 --- a/MediaBrowser.Model/Dlna/StreamInfo.cs +++ b/MediaBrowser.Model/Dlna/StreamInfo.cs @@ -144,7 +144,7 @@ namespace MediaBrowser.Model.Dlna public Dictionary StreamOptions { get; private set; } - public string MediaSourceId => MediaSource == null ? null : MediaSource.Id; + public string MediaSourceId => MediaSource?.Id; public bool IsDirectStream => PlayMethod == PlayMethod.DirectStream || diff --git a/MediaBrowser.Providers/Plugins/Tmdb/Movies/TmdbMovieProvider.cs b/MediaBrowser.Providers/Plugins/Tmdb/Movies/TmdbMovieProvider.cs index 5e2b83294a..df471896f9 100644 --- a/MediaBrowser.Providers/Plugins/Tmdb/Movies/TmdbMovieProvider.cs +++ b/MediaBrowser.Providers/Plugins/Tmdb/Movies/TmdbMovieProvider.cs @@ -148,7 +148,7 @@ namespace MediaBrowser.Providers.Plugins.Tmdb.Movies using (HttpResponseInfo response = await GetMovieDbResponse(new HttpRequestOptions { - Url = string.Format(TmdbConfigUrl, TmdbUtils.ApiKey), + Url = string.Format(CultureInfo.InvariantCulture, TmdbConfigUrl, TmdbUtils.ApiKey), CancellationToken = cancellationToken, AcceptHeader = TmdbUtils.AcceptHeader }).ConfigureAwait(false)) @@ -245,7 +245,7 @@ namespace MediaBrowser.Providers.Plugins.Tmdb.Movies preferredLanguage = "alllang"; } - var filename = string.Format("all-{0}.json", preferredLanguage); + var filename = string.Format(CultureInfo.InvariantCulture, "all-{0}.json", preferredLanguage); return Path.Combine(path, filename); } @@ -276,7 +276,7 @@ namespace MediaBrowser.Providers.Plugins.Tmdb.Movies languages.Add("en"); } - return string.Join(",", languages.ToArray()); + return string.Join(",", languages); } public static string NormalizeLanguage(string language) @@ -321,11 +321,11 @@ namespace MediaBrowser.Providers.Plugins.Tmdb.Movies /// Task{CompleteMovieData}. internal async Task FetchMainResult(string id, bool isTmdbId, string language, CancellationToken cancellationToken) { - var url = string.Format(GetMovieInfo3, id, TmdbUtils.ApiKey); + var url = string.Format(CultureInfo.InvariantCulture, GetMovieInfo3, id, TmdbUtils.ApiKey); if (!string.IsNullOrEmpty(language)) { - url += string.Format("&language={0}", NormalizeLanguage(language)); + url += string.Format(CultureInfo.InvariantCulture, "&language={0}", NormalizeLanguage(language)); // Get images in english and with no language url += "&include_image_language=" + GetImageLanguagesParam(language); @@ -377,7 +377,7 @@ namespace MediaBrowser.Providers.Plugins.Tmdb.Movies { _logger.LogInformation("MovieDbProvider couldn't find meta for language " + language + ". Trying English..."); - url = string.Format(GetMovieInfo3, id, TmdbUtils.ApiKey) + "&language=en"; + url = string.Format(CultureInfo.InvariantCulture,GetMovieInfo3, id, TmdbUtils.ApiKey) + "&language=en"; if (!string.IsNullOrEmpty(language)) { From 1448df168461760390143b5f9a197a8a82555d71 Mon Sep 17 00:00:00 2001 From: Bond-009 Date: Sat, 4 Jul 2020 22:36:02 +0200 Subject: [PATCH 51/81] Update MediaBrowser.Providers/Plugins/Tmdb/Movies/TmdbMovieProvider.cs Co-authored-by: Patrick Barron <18354464+barronpm@users.noreply.github.com> --- MediaBrowser.Providers/Plugins/Tmdb/Movies/TmdbMovieProvider.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MediaBrowser.Providers/Plugins/Tmdb/Movies/TmdbMovieProvider.cs b/MediaBrowser.Providers/Plugins/Tmdb/Movies/TmdbMovieProvider.cs index df471896f9..74870c9992 100644 --- a/MediaBrowser.Providers/Plugins/Tmdb/Movies/TmdbMovieProvider.cs +++ b/MediaBrowser.Providers/Plugins/Tmdb/Movies/TmdbMovieProvider.cs @@ -377,7 +377,7 @@ namespace MediaBrowser.Providers.Plugins.Tmdb.Movies { _logger.LogInformation("MovieDbProvider couldn't find meta for language " + language + ". Trying English..."); - url = string.Format(CultureInfo.InvariantCulture,GetMovieInfo3, id, TmdbUtils.ApiKey) + "&language=en"; + url = string.Format(CultureInfo.InvariantCulture, GetMovieInfo3, id, TmdbUtils.ApiKey) + "&language=en"; if (!string.IsNullOrEmpty(language)) { From 942c733d4f13046cedd19fa849eec88b13d2d2c7 Mon Sep 17 00:00:00 2001 From: Patrick Barron Date: Sun, 5 Jul 2020 15:36:29 -0400 Subject: [PATCH 52/81] Fix TypeLoadException during plugin load --- Emby.Server.Implementations/ApplicationHost.cs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/Emby.Server.Implementations/ApplicationHost.cs b/Emby.Server.Implementations/ApplicationHost.cs index 18b6834ef5..fe1961b702 100644 --- a/Emby.Server.Implementations/ApplicationHost.cs +++ b/Emby.Server.Implementations/ApplicationHost.cs @@ -871,6 +871,11 @@ namespace Emby.Server.Implementations Logger.LogError(ex, "Error getting exported types from {Assembly}", ass.FullName); continue; } + catch (TypeLoadException ex) + { + Logger.LogError(ex, "Error loading types from {Assembly}.", ass.FullName); + continue; + } foreach (Type type in exportedTypes) { From 88d06aa156109eac6bbdb8fd14a18b9e9364c7f9 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 6 Jul 2020 12:02:46 +0000 Subject: [PATCH 53/81] Bump Moq from 4.14.4 to 4.14.5 Bumps [Moq](https://github.com/moq/moq4) from 4.14.4 to 4.14.5. - [Release notes](https://github.com/moq/moq4/releases) - [Changelog](https://github.com/moq/moq4/blob/master/CHANGELOG.md) - [Commits](https://github.com/moq/moq4/compare/v4.14.4...v4.14.5) Signed-off-by: dependabot[bot] --- tests/Jellyfin.Api.Tests/Jellyfin.Api.Tests.csproj | 2 +- .../Jellyfin.Server.Implementations.Tests.csproj | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/Jellyfin.Api.Tests/Jellyfin.Api.Tests.csproj b/tests/Jellyfin.Api.Tests/Jellyfin.Api.Tests.csproj index 100f954245..bdc3fe15c2 100644 --- a/tests/Jellyfin.Api.Tests/Jellyfin.Api.Tests.csproj +++ b/tests/Jellyfin.Api.Tests/Jellyfin.Api.Tests.csproj @@ -21,7 +21,7 @@ - + diff --git a/tests/Jellyfin.Server.Implementations.Tests/Jellyfin.Server.Implementations.Tests.csproj b/tests/Jellyfin.Server.Implementations.Tests/Jellyfin.Server.Implementations.Tests.csproj index dd53c99023..6610478ab0 100644 --- a/tests/Jellyfin.Server.Implementations.Tests/Jellyfin.Server.Implementations.Tests.csproj +++ b/tests/Jellyfin.Server.Implementations.Tests/Jellyfin.Server.Implementations.Tests.csproj @@ -16,7 +16,7 @@ - + From aab79ef3464f749ea12d361b94fc2d46a9613f1c Mon Sep 17 00:00:00 2001 From: "Joshua M. Boniface" Date: Mon, 6 Jul 2020 22:12:39 -0400 Subject: [PATCH 54/81] Add conditionals to root YAML definition Prevents running builds (that get skipped) in PR CI, and prevents running tests (which are irrelevant) in Merge CI. --- .ci/azure-pipelines.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.ci/azure-pipelines.yml b/.ci/azure-pipelines.yml index c9013b3b8a..0a17e97a1b 100644 --- a/.ci/azure-pipelines.yml +++ b/.ci/azure-pipelines.yml @@ -16,11 +16,13 @@ trigger: jobs: - template: azure-pipelines-main.yml + condition: ! or(startsWith(variables['Build.SourceBranch'], 'refs/tags'), startsWith(variables['Build.SourceBranch'], 'refs/heads/master')) parameters: LinuxImage: 'ubuntu-latest' RestoreBuildProjects: $(RestoreBuildProjects) - template: azure-pipelines-test.yml + condition: ! or(startsWith(variables['Build.SourceBranch'], 'refs/tags'), startsWith(variables['Build.SourceBranch'], 'refs/heads/master')) parameters: ImageNames: Linux: 'ubuntu-latest' @@ -28,6 +30,7 @@ jobs: macOS: 'macos-latest' - template: azure-pipelines-abi.yml + condition: ! or(startsWith(variables['Build.SourceBranch'], 'refs/tags'), startsWith(variables['Build.SourceBranch'], 'refs/heads/master')) parameters: Packages: Naming: @@ -45,3 +48,4 @@ jobs: LinuxImage: 'ubuntu-latest' - template: azure-pipelines-package.yml + condition: or(startsWith(variables['Build.SourceBranch'], 'refs/tags'), startsWith(variables['Build.SourceBranch'], 'refs/heads/master')) From 9d9c9a59450cbe71eeec3955399ddcaae2cf6ce8 Mon Sep 17 00:00:00 2001 From: "Joshua M. Boniface" Date: Mon, 6 Jul 2020 22:14:25 -0400 Subject: [PATCH 55/81] Remove unneeded conditions that are now in parent --- .ci/azure-pipelines-package.yml | 3 --- 1 file changed, 3 deletions(-) diff --git a/.ci/azure-pipelines-package.yml b/.ci/azure-pipelines-package.yml index b342531903..1d5c70bdb1 100644 --- a/.ci/azure-pipelines-package.yml +++ b/.ci/azure-pipelines-package.yml @@ -35,7 +35,6 @@ jobs: steps: - script: 'docker build -f deployment/Dockerfile.$(BuildConfiguration) -t jellyfin-server-$(BuildConfiguration) deployment' displayName: 'Build Dockerfile' - condition: or(startsWith(variables['Build.SourceBranch'], 'refs/tags'), startsWith(variables['Build.SourceBranch'], 'refs/heads/master')) - script: 'docker image ls -a && docker run -v $(pwd)/deployment/dist:/dist -v $(pwd):/jellyfin -e IS_UNSTABLE="yes" -e BUILD_ID=$(Build.BuildNumber) jellyfin-server-$(BuildConfiguration)' displayName: 'Run Dockerfile (unstable)' @@ -47,14 +46,12 @@ jobs: - task: PublishPipelineArtifact@1 displayName: 'Publish Release' - condition: or(startsWith(variables['Build.SourceBranch'], 'refs/tags'), startsWith(variables['Build.SourceBranch'], 'refs/heads/master')) inputs: targetPath: '$(Build.SourcesDirectory)/deployment/dist' artifactName: 'jellyfin-server-$(BuildConfiguration)' - task: CopyFilesOverSSH@0 displayName: 'Upload artifacts to repository server' - condition: or(startsWith(variables['Build.SourceBranch'], 'refs/tags'), startsWith(variables['Build.SourceBranch'], 'refs/heads/master')) inputs: sshEndpoint: repository sourceFolder: '$(Build.SourcesDirectory)/deployment/dist' From 8bef24f331eea5ca4ba907ce1a3cd0f9a31f5ed5 Mon Sep 17 00:00:00 2001 From: "Joshua M. Boniface" Date: Mon, 6 Jul 2020 22:31:49 -0400 Subject: [PATCH 56/81] Use weird other formating that AZP wants --- .ci/azure-pipelines.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.ci/azure-pipelines.yml b/.ci/azure-pipelines.yml index 0a17e97a1b..0c86c0171c 100644 --- a/.ci/azure-pipelines.yml +++ b/.ci/azure-pipelines.yml @@ -15,22 +15,22 @@ trigger: batch: true jobs: +- ${{ if not(or(startsWith(variables['Build.SourceBranch'], 'refs/tags'), startsWith(variables['Build.SourceBranch'], 'refs/heads/master'))) }}: - template: azure-pipelines-main.yml - condition: ! or(startsWith(variables['Build.SourceBranch'], 'refs/tags'), startsWith(variables['Build.SourceBranch'], 'refs/heads/master')) parameters: LinuxImage: 'ubuntu-latest' RestoreBuildProjects: $(RestoreBuildProjects) +- ${{ if not(or(startsWith(variables['Build.SourceBranch'], 'refs/tags'), startsWith(variables['Build.SourceBranch'], 'refs/heads/master'))) }}: - template: azure-pipelines-test.yml - condition: ! or(startsWith(variables['Build.SourceBranch'], 'refs/tags'), startsWith(variables['Build.SourceBranch'], 'refs/heads/master')) parameters: ImageNames: Linux: 'ubuntu-latest' Windows: 'windows-latest' macOS: 'macos-latest' +- ${{ if not(or(startsWith(variables['Build.SourceBranch'], 'refs/tags'), startsWith(variables['Build.SourceBranch'], 'refs/heads/master'))) }}: - template: azure-pipelines-abi.yml - condition: ! or(startsWith(variables['Build.SourceBranch'], 'refs/tags'), startsWith(variables['Build.SourceBranch'], 'refs/heads/master')) parameters: Packages: Naming: @@ -47,5 +47,5 @@ jobs: AssemblyFileName: MediaBrowser.Common.dll LinuxImage: 'ubuntu-latest' +- ${{ if or(startsWith(variables['Build.SourceBranch'], 'refs/tags'), startsWith(variables['Build.SourceBranch'], 'refs/heads/master')) }}: - template: azure-pipelines-package.yml - condition: or(startsWith(variables['Build.SourceBranch'], 'refs/tags'), startsWith(variables['Build.SourceBranch'], 'refs/heads/master')) From 6d0a3a110be361c8f9d2d79b8fe1c762f9b33380 Mon Sep 17 00:00:00 2001 From: "Joshua M. Boniface" Date: Mon, 6 Jul 2020 23:03:42 -0400 Subject: [PATCH 57/81] Explicitly exit from inline script --- .ci/azure-pipelines-package.yml | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/.ci/azure-pipelines-package.yml b/.ci/azure-pipelines-package.yml index 1d5c70bdb1..0907463986 100644 --- a/.ci/azure-pipelines-package.yml +++ b/.ci/azure-pipelines-package.yml @@ -117,7 +117,10 @@ jobs: inputs: sshEndpoint: repository runOptions: 'inline' - inline: 'sudo /srv/repository/collect-server.azure.sh /srv/repository/incoming/azure $(Build.BuildNumber) unstable' + inline: | + sudo /srv/repository/collect-server.azure.sh /srv/repository/incoming/azure $(Build.BuildNumber) unstable + rm $0 + exit - task: SSH@0 displayName: 'Update Stable Repository' @@ -125,4 +128,7 @@ jobs: inputs: sshEndpoint: repository runOptions: 'inline' - inline: 'sudo /srv/repository/collect-server.azure.sh /srv/repository/incoming/azure $(Build.BuildNumber)' + inline: | + sudo /srv/repository/collect-server.azure.sh /srv/repository/incoming/azure $(Build.BuildNumber) + rm $0 + exit From 33c465a5d3c4095455b5c35008acb184343e0515 Mon Sep 17 00:00:00 2001 From: crobibero Date: Tue, 7 Jul 2020 07:25:46 -0600 Subject: [PATCH 58/81] Clean syncplay endpoint names --- MediaBrowser.Api/SyncPlay/SyncPlayService.cs | 54 ++++++++++---------- 1 file changed, 27 insertions(+), 27 deletions(-) diff --git a/MediaBrowser.Api/SyncPlay/SyncPlayService.cs b/MediaBrowser.Api/SyncPlay/SyncPlayService.cs index 88cddfff7f..3782ea5f0b 100644 --- a/MediaBrowser.Api/SyncPlay/SyncPlayService.cs +++ b/MediaBrowser.Api/SyncPlay/SyncPlayService.cs @@ -11,15 +11,15 @@ using Microsoft.Extensions.Logging; namespace MediaBrowser.Api.SyncPlay { - [Route("/SyncPlay/NewGroup", "POST", Summary = "Create a new SyncPlay group")] + [Route("/SyncPlay/New", "POST", Summary = "Create a new SyncPlay group")] [Authenticated] - public class SyncPlayNewGroup : IReturnVoid + public class SyncPlayNew : IReturnVoid { } - [Route("/SyncPlay/JoinGroup", "POST", Summary = "Join an existing SyncPlay group")] + [Route("/SyncPlay/Join", "POST", Summary = "Join an existing SyncPlay group")] [Authenticated] - public class SyncPlayJoinGroup : IReturnVoid + public class SyncPlayJoin : IReturnVoid { /// /// Gets or sets the Group id. @@ -36,15 +36,15 @@ namespace MediaBrowser.Api.SyncPlay public string PlayingItemId { get; set; } } - [Route("/SyncPlay/LeaveGroup", "POST", Summary = "Leave joined SyncPlay group")] + [Route("/SyncPlay/Leave", "POST", Summary = "Leave joined SyncPlay group")] [Authenticated] - public class SyncPlayLeaveGroup : IReturnVoid + public class SyncPlayLeave : IReturnVoid { } - [Route("/SyncPlay/ListGroups", "GET", Summary = "List SyncPlay groups")] + [Route("/SyncPlay/List", "GET", Summary = "List SyncPlay groups")] [Authenticated] - public class SyncPlayListGroups : IReturnVoid + public class SyncPlayList : IReturnVoid { /// /// Gets or sets the filter item id. @@ -54,29 +54,29 @@ namespace MediaBrowser.Api.SyncPlay public string FilterItemId { get; set; } } - [Route("/SyncPlay/PlayRequest", "POST", Summary = "Request play in SyncPlay group")] + [Route("/SyncPlay/Play", "POST", Summary = "Request play in SyncPlay group")] [Authenticated] - public class SyncPlayPlayRequest : IReturnVoid + public class SyncPlayPlay : IReturnVoid { } - [Route("/SyncPlay/PauseRequest", "POST", Summary = "Request pause in SyncPlay group")] + [Route("/SyncPlay/Pause", "POST", Summary = "Request pause in SyncPlay group")] [Authenticated] - public class SyncPlayPauseRequest : IReturnVoid + public class SyncPlayPause : IReturnVoid { } - [Route("/SyncPlay/SeekRequest", "POST", Summary = "Request seek in SyncPlay group")] + [Route("/SyncPlay/Seek", "POST", Summary = "Request seek in SyncPlay group")] [Authenticated] - public class SyncPlaySeekRequest : IReturnVoid + public class SyncPlaySeek : IReturnVoid { [ApiMember(Name = "PositionTicks", IsRequired = true, DataType = "long", ParameterType = "query", Verb = "POST")] public long PositionTicks { get; set; } } - [Route("/SyncPlay/BufferingRequest", "POST", Summary = "Request group wait in SyncPlay group while buffering")] + [Route("/SyncPlay/Buffering", "POST", Summary = "Request group wait in SyncPlay group while buffering")] [Authenticated] - public class SyncPlayBufferingRequest : IReturnVoid + public class SyncPlayBuffering : IReturnVoid { /// /// Gets or sets the date used to pin PositionTicks in time. @@ -96,9 +96,9 @@ namespace MediaBrowser.Api.SyncPlay public bool BufferingDone { get; set; } } - [Route("/SyncPlay/UpdatePing", "POST", Summary = "Update session ping")] + [Route("/SyncPlay/Ping", "POST", Summary = "Update session ping")] [Authenticated] - public class SyncPlayUpdatePing : IReturnVoid + public class SyncPlayPing : IReturnVoid { [ApiMember(Name = "Ping", IsRequired = true, DataType = "double", ParameterType = "query", Verb = "POST")] public double Ping { get; set; } @@ -135,7 +135,7 @@ namespace MediaBrowser.Api.SyncPlay /// Handles the specified request. /// /// The request. - public void Post(SyncPlayNewGroup request) + public void Post(SyncPlayNew request) { var currentSession = GetSession(_sessionContext); _syncPlayManager.NewGroup(currentSession, CancellationToken.None); @@ -145,7 +145,7 @@ namespace MediaBrowser.Api.SyncPlay /// Handles the specified request. /// /// The request. - public void Post(SyncPlayJoinGroup request) + public void Post(SyncPlayJoin request) { var currentSession = GetSession(_sessionContext); @@ -178,7 +178,7 @@ namespace MediaBrowser.Api.SyncPlay /// Handles the specified request. /// /// The request. - public void Post(SyncPlayLeaveGroup request) + public void Post(SyncPlayLeave request) { var currentSession = GetSession(_sessionContext); _syncPlayManager.LeaveGroup(currentSession, CancellationToken.None); @@ -189,7 +189,7 @@ namespace MediaBrowser.Api.SyncPlay /// /// The request. /// The requested list of groups. - public List Post(SyncPlayListGroups request) + public List Post(SyncPlayList request) { var currentSession = GetSession(_sessionContext); var filterItemId = Guid.Empty; @@ -206,7 +206,7 @@ namespace MediaBrowser.Api.SyncPlay /// Handles the specified request. /// /// The request. - public void Post(SyncPlayPlayRequest request) + public void Post(SyncPlayPlay request) { var currentSession = GetSession(_sessionContext); var syncPlayRequest = new PlaybackRequest() @@ -220,7 +220,7 @@ namespace MediaBrowser.Api.SyncPlay /// Handles the specified request. /// /// The request. - public void Post(SyncPlayPauseRequest request) + public void Post(SyncPlayPause request) { var currentSession = GetSession(_sessionContext); var syncPlayRequest = new PlaybackRequest() @@ -234,7 +234,7 @@ namespace MediaBrowser.Api.SyncPlay /// Handles the specified request. /// /// The request. - public void Post(SyncPlaySeekRequest request) + public void Post(SyncPlaySeek request) { var currentSession = GetSession(_sessionContext); var syncPlayRequest = new PlaybackRequest() @@ -249,7 +249,7 @@ namespace MediaBrowser.Api.SyncPlay /// Handles the specified request. /// /// The request. - public void Post(SyncPlayBufferingRequest request) + public void Post(SyncPlayBuffering request) { var currentSession = GetSession(_sessionContext); var syncPlayRequest = new PlaybackRequest() @@ -265,7 +265,7 @@ namespace MediaBrowser.Api.SyncPlay /// Handles the specified request. /// /// The request. - public void Post(SyncPlayUpdatePing request) + public void Post(SyncPlayPing request) { var currentSession = GetSession(_sessionContext); var syncPlayRequest = new PlaybackRequest() From 3cca8db9059e7c0316d829f85d05dcb03ae70a95 Mon Sep 17 00:00:00 2001 From: Patrick Barron Date: Tue, 7 Jul 2020 18:20:17 -0400 Subject: [PATCH 59/81] Fix log spam from EF Core --- Emby.Server.Implementations/Session/SessionManager.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Emby.Server.Implementations/Session/SessionManager.cs b/Emby.Server.Implementations/Session/SessionManager.cs index d069d1ada8..ca9f95c707 100644 --- a/Emby.Server.Implementations/Session/SessionManager.cs +++ b/Emby.Server.Implementations/Session/SessionManager.cs @@ -296,7 +296,7 @@ namespace Emby.Server.Implementations.Session } catch (DbUpdateConcurrencyException e) { - _logger.LogWarning(e, "Error updating user's last activity date."); + _logger.LogDebug(e, "Error updating user's last activity date."); } } } From 172203b5ccfe8e0647af78deb347dc42e6132c93 Mon Sep 17 00:00:00 2001 From: rhythm493 Date: Wed, 8 Jul 2020 16:23:26 +0000 Subject: [PATCH 60/81] Translated using Weblate (Marathi) Translation: Jellyfin/Jellyfin Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-core/mr/ --- Emby.Server.Implementations/Localization/Core/mr.json | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Emby.Server.Implementations/Localization/Core/mr.json b/Emby.Server.Implementations/Localization/Core/mr.json index 50b6360d8f..b6db2b0f29 100644 --- a/Emby.Server.Implementations/Localization/Core/mr.json +++ b/Emby.Server.Implementations/Localization/Core/mr.json @@ -57,5 +57,7 @@ "HeaderCameraUploads": "कॅमेरा अपलोड", "CameraImageUploadedFrom": "एक नवीन कॅमेरा चित्र {0} येथून अपलोड केले आहे", "Application": "अ‍ॅप्लिकेशन", - "AppDeviceValues": "अ‍ॅप: {0}, यंत्र: {1}" + "AppDeviceValues": "अ‍ॅप: {0}, यंत्र: {1}", + "Collections": "संग्रह", + "ChapterNameValue": "धडा {0}" } From c0bd10879aeaeda9d1a62766c5cfd046cc3ff908 Mon Sep 17 00:00:00 2001 From: Patrick Barron Date: Thu, 9 Jul 2020 21:55:07 -0400 Subject: [PATCH 61/81] Ignore casing when authenticating users --- Jellyfin.Server.Implementations/Users/UserManager.cs | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/Jellyfin.Server.Implementations/Users/UserManager.cs b/Jellyfin.Server.Implementations/Users/UserManager.cs index ace9c4af05..47d514b1a4 100644 --- a/Jellyfin.Server.Implementations/Users/UserManager.cs +++ b/Jellyfin.Server.Implementations/Users/UserManager.cs @@ -110,9 +110,8 @@ namespace Jellyfin.Server.Implementations.Users throw new ArgumentException("Invalid username", nameof(name)); } - // This can't use an overload with StringComparer because that would cause the query to - // have to be evaluated client-side. - return _dbProvider.CreateContext().Users.FirstOrDefault(u => string.Equals(u.Username, name)); + return _dbProvider.CreateContext().Users.ToList() + .FirstOrDefault(u => string.Equals(u.Username, name, StringComparison.OrdinalIgnoreCase)); } /// From 2c231e84e655a4e892f540827d064d4a7e24519b Mon Sep 17 00:00:00 2001 From: crobibero Date: Sat, 11 Jul 2020 10:26:01 -0600 Subject: [PATCH 62/81] Fix syncplay function name --- MediaBrowser.Api/SyncPlay/SyncPlayService.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MediaBrowser.Api/SyncPlay/SyncPlayService.cs b/MediaBrowser.Api/SyncPlay/SyncPlayService.cs index 3782ea5f0b..18983ea5ba 100644 --- a/MediaBrowser.Api/SyncPlay/SyncPlayService.cs +++ b/MediaBrowser.Api/SyncPlay/SyncPlayService.cs @@ -189,7 +189,7 @@ namespace MediaBrowser.Api.SyncPlay /// /// The request. /// The requested list of groups. - public List Post(SyncPlayList request) + public List Get(SyncPlayList request) { var currentSession = GetSession(_sessionContext); var filterItemId = Guid.Empty; From 8959621da7d9e0696e530448fc028c0089c2609a Mon Sep 17 00:00:00 2001 From: Patrick Barron Date: Sun, 12 Jul 2020 14:45:52 -0400 Subject: [PATCH 63/81] Fix EF Core memory leak --- .../Users/UserManager.cs | 54 ++++++++++++++----- 1 file changed, 40 insertions(+), 14 deletions(-) diff --git a/Jellyfin.Server.Implementations/Users/UserManager.cs b/Jellyfin.Server.Implementations/Users/UserManager.cs index 47d514b1a4..c8d7fa769a 100644 --- a/Jellyfin.Server.Implementations/Users/UserManager.cs +++ b/Jellyfin.Server.Implementations/Users/UserManager.cs @@ -23,6 +23,7 @@ using MediaBrowser.Model.Cryptography; using MediaBrowser.Model.Dto; using MediaBrowser.Model.Events; using MediaBrowser.Model.Users; +using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.Logging; namespace Jellyfin.Server.Implementations.Users @@ -86,7 +87,18 @@ namespace Jellyfin.Server.Implementations.Users public event EventHandler>? OnUserLockedOut; /// - public IEnumerable Users => _dbProvider.CreateContext().Users; + public IEnumerable Users + { + get + { + using var dbContext = _dbProvider.CreateContext(); + return dbContext.Users.Include(user => user.Permissions) + .Include(user => user.Preferences) + .Include(user => user.AccessSchedules) + .Include(user => user.ProfileImage) + .ToList(); + } + } /// public IEnumerable UsersIds => _dbProvider.CreateContext().Users.Select(u => u.Id); @@ -99,7 +111,12 @@ namespace Jellyfin.Server.Implementations.Users throw new ArgumentException("Guid can't be empty", nameof(id)); } - return _dbProvider.CreateContext().Users.Find(id); + using var dbContext = _dbProvider.CreateContext(); + return dbContext.Users.Include(user => user.Permissions) + .Include(user => user.Preferences) + .Include(user => user.AccessSchedules) + .Include(user => user.ProfileImage) + .FirstOrDefault(user => user.Id == id); } /// @@ -110,7 +127,13 @@ namespace Jellyfin.Server.Implementations.Users throw new ArgumentException("Invalid username", nameof(name)); } - return _dbProvider.CreateContext().Users.ToList() + using var dbContext = _dbProvider.CreateContext(); + + return dbContext.Users.Include(user => user.Permissions) + .Include(user => user.Preferences) + .Include(user => user.AccessSchedules) + .Include(user => user.ProfileImage) + .ToList() .FirstOrDefault(u => string.Equals(u.Username, name, StringComparison.OrdinalIgnoreCase)); } @@ -127,7 +150,7 @@ namespace Jellyfin.Server.Implementations.Users throw new ArgumentException("Invalid username", nameof(newName)); } - if (user.Username.Equals(newName, StringComparison.Ordinal)) + if (user.Username.Equals(newName, StringComparison.OrdinalIgnoreCase)) { throw new ArgumentException("The new and old names must be different."); } @@ -149,7 +172,7 @@ namespace Jellyfin.Server.Implementations.Users /// public void UpdateUser(User user) { - var dbContext = _dbProvider.CreateContext(); + using var dbContext = _dbProvider.CreateContext(); dbContext.Users.Update(user); dbContext.SaveChanges(); } @@ -157,7 +180,7 @@ namespace Jellyfin.Server.Implementations.Users /// public async Task UpdateUserAsync(User user) { - var dbContext = _dbProvider.CreateContext(); + await using var dbContext = _dbProvider.CreateContext(); dbContext.Users.Update(user); await dbContext.SaveChangesAsync().ConfigureAwait(false); @@ -171,7 +194,7 @@ namespace Jellyfin.Server.Implementations.Users throw new ArgumentException("Usernames can contain unicode symbols, numbers (0-9), dashes (-), underscores (_), apostrophes ('), and periods (.)"); } - var dbContext = _dbProvider.CreateContext(); + using var dbContext = _dbProvider.CreateContext(); // TODO: Remove after user item data is migrated. var max = dbContext.Users.Any() ? dbContext.Users.Select(u => u.InternalId).Max() : 0; @@ -194,8 +217,12 @@ namespace Jellyfin.Server.Implementations.Users /// public void DeleteUser(Guid userId) { - var dbContext = _dbProvider.CreateContext(); - var user = dbContext.Users.Find(userId); + using var dbContext = _dbProvider.CreateContext(); + var user = dbContext.Users.Include(u => u.Permissions) + .Include(u => u.Preferences) + .Include(u => u.AccessSchedules) + .Include(u => u.ProfileImage) + .FirstOrDefault(u => u.Id == userId); if (user == null) { throw new ResourceNotFoundException(nameof(userId)); @@ -380,7 +407,7 @@ namespace Jellyfin.Server.Implementations.Users throw new ArgumentNullException(nameof(username)); } - var user = Users.ToList().FirstOrDefault(i => string.Equals(username, i.Username, StringComparison.OrdinalIgnoreCase)); + var user = Users.FirstOrDefault(i => string.Equals(username, i.Username, StringComparison.OrdinalIgnoreCase)); bool success; IAuthenticationProvider? authenticationProvider; @@ -408,8 +435,7 @@ namespace Jellyfin.Server.Implementations.Users // Search the database for the user again // the authentication provider might have created it - user = Users - .ToList().FirstOrDefault(i => string.Equals(username, i.Username, StringComparison.OrdinalIgnoreCase)); + user = Users.FirstOrDefault(i => string.Equals(username, i.Username, StringComparison.OrdinalIgnoreCase)); if (authenticationProvider is IHasNewUserPolicy hasNewUserPolicy) { @@ -546,7 +572,7 @@ namespace Jellyfin.Server.Implementations.Users public void Initialize() { // TODO: Refactor the startup wizard so that it doesn't require a user to already exist. - var dbContext = _dbProvider.CreateContext(); + using var dbContext = _dbProvider.CreateContext(); if (dbContext.Users.Any()) { @@ -698,7 +724,7 @@ namespace Jellyfin.Server.Implementations.Users /// public void ClearProfileImage(User user) { - var dbContext = _dbProvider.CreateContext(); + using var dbContext = _dbProvider.CreateContext(); dbContext.Remove(user.ProfileImage); dbContext.SaveChanges(); } From 0ee55bc1f98283de0926e0e1608e48c71b833934 Mon Sep 17 00:00:00 2001 From: Patrick Barron Date: Sun, 12 Jul 2020 15:08:55 -0400 Subject: [PATCH 64/81] Use AsEnumerable instead of ToList --- Jellyfin.Server.Implementations/Users/UserManager.cs | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/Jellyfin.Server.Implementations/Users/UserManager.cs b/Jellyfin.Server.Implementations/Users/UserManager.cs index 47d514b1a4..5a2d7774a4 100644 --- a/Jellyfin.Server.Implementations/Users/UserManager.cs +++ b/Jellyfin.Server.Implementations/Users/UserManager.cs @@ -110,7 +110,7 @@ namespace Jellyfin.Server.Implementations.Users throw new ArgumentException("Invalid username", nameof(name)); } - return _dbProvider.CreateContext().Users.ToList() + return _dbProvider.CreateContext().Users.AsEnumerable() .FirstOrDefault(u => string.Equals(u.Username, name, StringComparison.OrdinalIgnoreCase)); } @@ -380,7 +380,7 @@ namespace Jellyfin.Server.Implementations.Users throw new ArgumentNullException(nameof(username)); } - var user = Users.ToList().FirstOrDefault(i => string.Equals(username, i.Username, StringComparison.OrdinalIgnoreCase)); + var user = Users.AsEnumerable().FirstOrDefault(i => string.Equals(username, i.Username, StringComparison.OrdinalIgnoreCase)); bool success; IAuthenticationProvider? authenticationProvider; @@ -408,8 +408,7 @@ namespace Jellyfin.Server.Implementations.Users // Search the database for the user again // the authentication provider might have created it - user = Users - .ToList().FirstOrDefault(i => string.Equals(username, i.Username, StringComparison.OrdinalIgnoreCase)); + user = Users.AsEnumerable().FirstOrDefault(i => string.Equals(username, i.Username, StringComparison.OrdinalIgnoreCase)); if (authenticationProvider is IHasNewUserPolicy hasNewUserPolicy) { From 5e706ba7cee116ecd7a99fccfebec5fc275a8993 Mon Sep 17 00:00:00 2001 From: dkanada Date: Mon, 13 Jul 2020 06:55:03 +0900 Subject: [PATCH 65/81] keep playstate during syncplay group creation --- .../SyncPlay/SyncPlayController.cs | 32 +++++++++---------- .../SyncPlay/SyncPlayManager.cs | 10 +++--- MediaBrowser.Api/SyncPlay/SyncPlayService.cs | 25 +++------------ MediaBrowser.Controller/SyncPlay/GroupInfo.cs | 22 ++++++------- .../SyncPlay/GroupMember.cs | 2 +- .../SyncPlay/ISyncPlayController.cs | 2 +- .../SyncPlay/JoinGroupRequest.cs | 6 ---- .../SyncPlay/PlaybackRequestType.cs | 6 ++-- 8 files changed, 41 insertions(+), 64 deletions(-) diff --git a/Emby.Server.Implementations/SyncPlay/SyncPlayController.cs b/Emby.Server.Implementations/SyncPlay/SyncPlayController.cs index b1f8fd330c..e596d99005 100644 --- a/Emby.Server.Implementations/SyncPlay/SyncPlayController.cs +++ b/Emby.Server.Implementations/SyncPlay/SyncPlayController.cs @@ -194,26 +194,24 @@ namespace Emby.Server.Implementations.SyncPlay } /// - public void InitGroup(SessionInfo session, CancellationToken cancellationToken) + public void CreateGroup(SessionInfo session, CancellationToken cancellationToken) { _group.AddSession(session); _syncPlayManager.AddSessionToGroup(session, this); _group.PlayingItem = session.FullNowPlayingItem; - _group.IsPaused = true; + _group.IsPaused = session.PlayState.IsPaused; _group.PositionTicks = session.PlayState.PositionTicks ?? 0; _group.LastActivity = DateTime.UtcNow; var updateSession = NewSyncPlayGroupUpdate(GroupUpdateType.GroupJoined, DateToUTCString(DateTime.UtcNow)); SendGroupUpdate(session, BroadcastType.CurrentSession, updateSession, cancellationToken); - var pauseCommand = NewSyncPlayCommand(SendCommandType.Pause); - SendCommand(session, BroadcastType.CurrentSession, pauseCommand, cancellationToken); } /// public void SessionJoin(SessionInfo session, JoinGroupRequest request, CancellationToken cancellationToken) { - if (session.NowPlayingItem?.Id == _group.PlayingItem.Id && request.PlayingItemId == _group.PlayingItem.Id) + if (session.NowPlayingItem?.Id == _group.PlayingItem.Id) { _group.AddSession(session); _syncPlayManager.AddSessionToGroup(session, this); @@ -224,7 +222,7 @@ namespace Emby.Server.Implementations.SyncPlay var updateOthers = NewSyncPlayGroupUpdate(GroupUpdateType.UserJoined, session.UserName); SendGroupUpdate(session, BroadcastType.AllExceptCurrentSession, updateOthers, cancellationToken); - // Client join and play, syncing will happen client side + // syncing will happen client side if (!_group.IsPaused) { var playCommand = NewSyncPlayCommand(SendCommandType.Play); @@ -262,10 +260,9 @@ namespace Emby.Server.Implementations.SyncPlay /// public void HandleRequest(SessionInfo session, PlaybackRequest request, CancellationToken cancellationToken) { - // The server's job is to mantain a consistent state to which clients refer to, - // as also to notify clients of state changes. - // The actual syncing of media playback happens client side. - // Clients are aware of the server's time and use it to sync. + // The server's job is to maintain a consistent state for clients to reference + // and notify clients of state changes. The actual syncing of media playback + // happens client side. Clients are aware of the server's time and use it to sync. switch (request.Type) { case PlaybackRequestType.Play: @@ -277,13 +274,13 @@ namespace Emby.Server.Implementations.SyncPlay case PlaybackRequestType.Seek: HandleSeekRequest(session, request, cancellationToken); break; - case PlaybackRequestType.Buffering: + case PlaybackRequestType.Buffer: HandleBufferingRequest(session, request, cancellationToken); break; - case PlaybackRequestType.BufferingDone: + case PlaybackRequestType.Ready: HandleBufferingDoneRequest(session, request, cancellationToken); break; - case PlaybackRequestType.UpdatePing: + case PlaybackRequestType.Ping: HandlePingUpdateRequest(session, request); break; } @@ -301,7 +298,7 @@ namespace Emby.Server.Implementations.SyncPlay { // Pick a suitable time that accounts for latency var delay = _group.GetHighestPing() * 2; - delay = delay < _group.DefaulPing ? _group.DefaulPing : delay; + delay = delay < _group.DefaultPing ? _group.DefaultPing : delay; // Unpause group and set starting point in future // Clients will start playback at LastActivity (datetime) from PositionTicks (playback position) @@ -337,8 +334,9 @@ namespace Emby.Server.Implementations.SyncPlay var currentTime = DateTime.UtcNow; var elapsedTime = currentTime - _group.LastActivity; _group.LastActivity = currentTime; + // Seek only if playback actually started - // (a pause request may be issued during the delay added to account for latency) + // Pause request may be issued during the delay added to account for latency _group.PositionTicks += elapsedTime.Ticks > 0 ? elapsedTime.Ticks : 0; var command = NewSyncPlayCommand(SendCommandType.Pause); @@ -451,7 +449,7 @@ namespace Emby.Server.Implementations.SyncPlay { // Client, that was buffering, resumed playback but did not update others in time delay = _group.GetHighestPing() * 2; - delay = delay < _group.DefaulPing ? _group.DefaulPing : delay; + delay = delay < _group.DefaultPing ? _group.DefaultPing : delay; _group.LastActivity = currentTime.AddMilliseconds( delay); @@ -495,7 +493,7 @@ namespace Emby.Server.Implementations.SyncPlay private void HandlePingUpdateRequest(SessionInfo session, PlaybackRequest request) { // Collected pings are used to account for network latency when unpausing playback - _group.UpdatePing(session, request.Ping ?? _group.DefaulPing); + _group.UpdatePing(session, request.Ping ?? _group.DefaultPing); } /// diff --git a/Emby.Server.Implementations/SyncPlay/SyncPlayManager.cs b/Emby.Server.Implementations/SyncPlay/SyncPlayManager.cs index 45a43fd789..966ed5024e 100644 --- a/Emby.Server.Implementations/SyncPlay/SyncPlayManager.cs +++ b/Emby.Server.Implementations/SyncPlay/SyncPlayManager.cs @@ -170,10 +170,11 @@ namespace Emby.Server.Implementations.SyncPlay { _logger.LogWarning("NewGroup: {0} does not have permission to create groups.", session.Id); - var error = new GroupUpdate() + var error = new GroupUpdate { Type = GroupUpdateType.CreateGroupDenied }; + _sessionManager.SendSyncPlayGroupUpdate(session.Id, error, CancellationToken.None); return; } @@ -188,7 +189,7 @@ namespace Emby.Server.Implementations.SyncPlay var group = new SyncPlayController(_sessionManager, this); _groups[group.GetGroupId()] = group; - group.InitGroup(session, cancellationToken); + group.CreateGroup(session, cancellationToken); } } @@ -205,6 +206,7 @@ namespace Emby.Server.Implementations.SyncPlay { Type = GroupUpdateType.JoinGroupDenied }; + _sessionManager.SendSyncPlayGroupUpdate(session.Id, error, CancellationToken.None); return; } @@ -300,9 +302,9 @@ namespace Emby.Server.Implementations.SyncPlay group => group.GetPlayingItemId().Equals(filterItemId) && HasAccessToItem(user, group.GetPlayingItemId())).Select( group => group.GetInfo()).ToList(); } - // Otherwise show all available groups else { + // Otherwise show all available groups return _groups.Values.Where( group => HasAccessToItem(user, group.GetPlayingItemId())).Select( group => group.GetInfo()).ToList(); @@ -322,6 +324,7 @@ namespace Emby.Server.Implementations.SyncPlay { Type = GroupUpdateType.JoinGroupDenied }; + _sessionManager.SendSyncPlayGroupUpdate(session.Id, error, CancellationToken.None); return; } @@ -366,7 +369,6 @@ namespace Emby.Server.Implementations.SyncPlay } _sessionToGroupMap.Remove(session.Id, out var tempGroup); - if (!tempGroup.GetGroupId().Equals(group.GetGroupId())) { throw new InvalidOperationException("Session was in wrong group!"); diff --git a/MediaBrowser.Api/SyncPlay/SyncPlayService.cs b/MediaBrowser.Api/SyncPlay/SyncPlayService.cs index 18983ea5ba..daa1b521f4 100644 --- a/MediaBrowser.Api/SyncPlay/SyncPlayService.cs +++ b/MediaBrowser.Api/SyncPlay/SyncPlayService.cs @@ -27,13 +27,6 @@ namespace MediaBrowser.Api.SyncPlay /// The Group id to join. [ApiMember(Name = "GroupId", Description = "Group Id", IsRequired = true, DataType = "string", ParameterType = "query", Verb = "POST")] public string GroupId { get; set; } - - /// - /// Gets or sets the playing item id. - /// - /// The client's currently playing item id. - [ApiMember(Name = "PlayingItemId", Description = "Client's playing item id", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "POST")] - public string PlayingItemId { get; set; } } [Route("/SyncPlay/Leave", "POST", Summary = "Leave joined SyncPlay group")] @@ -89,7 +82,7 @@ namespace MediaBrowser.Api.SyncPlay public long PositionTicks { get; set; } /// - /// Gets or sets whether this is a buffering or a buffering-done request. + /// Gets or sets whether this is a buffering or a ready request. /// /// true if buffering is complete; false otherwise. [ApiMember(Name = "BufferingDone", IsRequired = true, DataType = "bool", ParameterType = "query", Verb = "POST")] @@ -150,25 +143,15 @@ namespace MediaBrowser.Api.SyncPlay var currentSession = GetSession(_sessionContext); Guid groupId; - Guid playingItemId = Guid.Empty; - if (!Guid.TryParse(request.GroupId, out groupId)) { Logger.LogError("JoinGroup: {0} is not a valid format for GroupId. Ignoring request.", request.GroupId); return; } - // Both null and empty strings mean that client isn't playing anything - if (!string.IsNullOrEmpty(request.PlayingItemId) && !Guid.TryParse(request.PlayingItemId, out playingItemId)) - { - Logger.LogError("JoinGroup: {0} is not a valid format for PlayingItemId. Ignoring request.", request.PlayingItemId); - return; - } - var joinRequest = new JoinGroupRequest() { - GroupId = groupId, - PlayingItemId = playingItemId + GroupId = groupId }; _syncPlayManager.JoinGroup(currentSession, groupId, joinRequest, CancellationToken.None); @@ -254,7 +237,7 @@ namespace MediaBrowser.Api.SyncPlay var currentSession = GetSession(_sessionContext); var syncPlayRequest = new PlaybackRequest() { - Type = request.BufferingDone ? PlaybackRequestType.BufferingDone : PlaybackRequestType.Buffering, + Type = request.BufferingDone ? PlaybackRequestType.Ready : PlaybackRequestType.Buffer, When = DateTime.Parse(request.When), PositionTicks = request.PositionTicks }; @@ -270,7 +253,7 @@ namespace MediaBrowser.Api.SyncPlay var currentSession = GetSession(_sessionContext); var syncPlayRequest = new PlaybackRequest() { - Type = PlaybackRequestType.UpdatePing, + Type = PlaybackRequestType.Ping, Ping = Convert.ToInt64(request.Ping) }; _syncPlayManager.HandleRequest(currentSession, syncPlayRequest, CancellationToken.None); diff --git a/MediaBrowser.Controller/SyncPlay/GroupInfo.cs b/MediaBrowser.Controller/SyncPlay/GroupInfo.cs index d0fac1efa3..e742df5179 100644 --- a/MediaBrowser.Controller/SyncPlay/GroupInfo.cs +++ b/MediaBrowser.Controller/SyncPlay/GroupInfo.cs @@ -16,7 +16,7 @@ namespace MediaBrowser.Controller.SyncPlay /// /// Gets the default ping value used for sessions. /// - public long DefaulPing { get; } = 500; + public long DefaultPing { get; } = 500; /// /// Gets or sets the group identifier. @@ -70,16 +70,16 @@ namespace MediaBrowser.Controller.SyncPlay /// The session. public void AddSession(SessionInfo session) { - if (ContainsSession(session.Id.ToString())) + if (ContainsSession(session.Id)) { return; } var member = new GroupMember(); member.Session = session; - member.Ping = DefaulPing; + member.Ping = DefaultPing; member.IsBuffering = false; - Participants[session.Id.ToString()] = member; + Participants[session.Id] = member; } /// @@ -88,12 +88,12 @@ namespace MediaBrowser.Controller.SyncPlay /// The session. public void RemoveSession(SessionInfo session) { - if (!ContainsSession(session.Id.ToString())) + if (!ContainsSession(session.Id)) { return; } - Participants.Remove(session.Id.ToString(), out _); + Participants.Remove(session.Id, out _); } /// @@ -103,12 +103,12 @@ namespace MediaBrowser.Controller.SyncPlay /// The ping. public void UpdatePing(SessionInfo session, long ping) { - if (!ContainsSession(session.Id.ToString())) + if (!ContainsSession(session.Id)) { return; } - Participants[session.Id.ToString()].Ping = ping; + Participants[session.Id].Ping = ping; } /// @@ -117,7 +117,7 @@ namespace MediaBrowser.Controller.SyncPlay /// The highest ping in the group. public long GetHighestPing() { - long max = Int64.MinValue; + long max = long.MinValue; foreach (var session in Participants.Values) { max = Math.Max(max, session.Ping); @@ -133,12 +133,12 @@ namespace MediaBrowser.Controller.SyncPlay /// The state. public void SetBuffering(SessionInfo session, bool isBuffering) { - if (!ContainsSession(session.Id.ToString())) + if (!ContainsSession(session.Id)) { return; } - Participants[session.Id.ToString()].IsBuffering = isBuffering; + Participants[session.Id].IsBuffering = isBuffering; } /// diff --git a/MediaBrowser.Controller/SyncPlay/GroupMember.cs b/MediaBrowser.Controller/SyncPlay/GroupMember.cs index a3975c334c..cde6f8e8ce 100644 --- a/MediaBrowser.Controller/SyncPlay/GroupMember.cs +++ b/MediaBrowser.Controller/SyncPlay/GroupMember.cs @@ -8,7 +8,7 @@ namespace MediaBrowser.Controller.SyncPlay public class GroupMember { /// - /// Gets or sets whether this member is buffering. + /// Gets or sets a value indicating whether this member is buffering. /// /// true if member is buffering; false otherwise. public bool IsBuffering { get; set; } diff --git a/MediaBrowser.Controller/SyncPlay/ISyncPlayController.cs b/MediaBrowser.Controller/SyncPlay/ISyncPlayController.cs index de1fcd2591..45c5438061 100644 --- a/MediaBrowser.Controller/SyncPlay/ISyncPlayController.cs +++ b/MediaBrowser.Controller/SyncPlay/ISyncPlayController.cs @@ -33,7 +33,7 @@ namespace MediaBrowser.Controller.SyncPlay /// /// The session. /// The cancellation token. - void InitGroup(SessionInfo session, CancellationToken cancellationToken); + void CreateGroup(SessionInfo session, CancellationToken cancellationToken); /// /// Adds the session to the group. diff --git a/MediaBrowser.Model/SyncPlay/JoinGroupRequest.cs b/MediaBrowser.Model/SyncPlay/JoinGroupRequest.cs index d67b6bd555..0c77a61322 100644 --- a/MediaBrowser.Model/SyncPlay/JoinGroupRequest.cs +++ b/MediaBrowser.Model/SyncPlay/JoinGroupRequest.cs @@ -12,11 +12,5 @@ namespace MediaBrowser.Model.SyncPlay /// /// The Group id to join. public Guid GroupId { get; set; } - - /// - /// Gets or sets the playing item id. - /// - /// The client's currently playing item id. - public Guid PlayingItemId { get; set; } } } diff --git a/MediaBrowser.Model/SyncPlay/PlaybackRequestType.cs b/MediaBrowser.Model/SyncPlay/PlaybackRequestType.cs index 671f4e01ff..e89efeed8a 100644 --- a/MediaBrowser.Model/SyncPlay/PlaybackRequestType.cs +++ b/MediaBrowser.Model/SyncPlay/PlaybackRequestType.cs @@ -23,16 +23,16 @@ namespace MediaBrowser.Model.SyncPlay /// /// A user is signaling that playback is buffering. /// - Buffering = 3, + Buffer = 3, /// /// A user is signaling that playback resumed. /// - BufferingDone = 4, + Ready = 4, /// /// A user is reporting its ping. /// - UpdatePing = 5 + Ping = 5 } } From 52290380aa5e3cafc5208a9e4b5ebf1b93f52d38 Mon Sep 17 00:00:00 2001 From: kanenses Date: Mon, 13 Jul 2020 00:30:14 +0000 Subject: [PATCH 66/81] Translated using Weblate (Portuguese) Translation: Jellyfin/Jellyfin Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-core/pt/ --- Emby.Server.Implementations/Localization/Core/pt.json | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/Emby.Server.Implementations/Localization/Core/pt.json b/Emby.Server.Implementations/Localization/Core/pt.json index 5365fff232..b534d0bbeb 100644 --- a/Emby.Server.Implementations/Localization/Core/pt.json +++ b/Emby.Server.Implementations/Localization/Core/pt.json @@ -104,5 +104,14 @@ "TaskRefreshChapterImagesDescription": "Cria miniaturas para vídeos que têm capítulos.", "TaskCleanCacheDescription": "Apaga ficheiros em cache que já não são usados pelo sistema.", "TasksChannelsCategory": "Canais de Internet", - "TaskRefreshChapterImages": "Extrair Imagens do Capítulo" + "TaskRefreshChapterImages": "Extrair Imagens do Capítulo", + "TaskDownloadMissingSubtitlesDescription": "Pesquisa na Internet as legendas em falta com base na configuração de metadados.", + "TaskDownloadMissingSubtitles": "Download das legendas em falta", + "TaskRefreshChannelsDescription": "Atualiza as informações do canal da Internet.", + "TaskCleanTranscodeDescription": "Apagar os ficheiros com mais de um dia, de Transcode.", + "TaskCleanTranscode": "Limpar o diretório de Transcode", + "TaskUpdatePluginsDescription": "Download e instala as atualizações para plug-ins configurados para atualização automática.", + "TaskRefreshPeopleDescription": "Atualiza os metadados para atores e diretores na tua biblioteca de media.", + "TaskRefreshPeople": "Atualizar pessoas", + "TaskRefreshLibraryDescription": "Pesquisa a tua biblioteca de media por novos ficheiros e atualiza os metadados." } From aefe011d7df75f2ee02eac3271b8b07de9b2c1a3 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 13 Jul 2020 12:04:07 +0000 Subject: [PATCH 67/81] Bump AutoFixture from 4.12.0 to 4.13.0 Bumps [AutoFixture](https://github.com/AutoFixture/AutoFixture) from 4.12.0 to 4.13.0. - [Release notes](https://github.com/AutoFixture/AutoFixture/releases) - [Commits](https://github.com/AutoFixture/AutoFixture/compare/v4.12.0...v4.13.0) Signed-off-by: dependabot[bot] --- tests/Jellyfin.Api.Tests/Jellyfin.Api.Tests.csproj | 2 +- .../Jellyfin.Server.Implementations.Tests.csproj | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/Jellyfin.Api.Tests/Jellyfin.Api.Tests.csproj b/tests/Jellyfin.Api.Tests/Jellyfin.Api.Tests.csproj index bdc3fe15c2..2190208886 100644 --- a/tests/Jellyfin.Api.Tests/Jellyfin.Api.Tests.csproj +++ b/tests/Jellyfin.Api.Tests/Jellyfin.Api.Tests.csproj @@ -13,7 +13,7 @@ - + diff --git a/tests/Jellyfin.Server.Implementations.Tests/Jellyfin.Server.Implementations.Tests.csproj b/tests/Jellyfin.Server.Implementations.Tests/Jellyfin.Server.Implementations.Tests.csproj index 6610478ab0..03187f4b9c 100644 --- a/tests/Jellyfin.Server.Implementations.Tests/Jellyfin.Server.Implementations.Tests.csproj +++ b/tests/Jellyfin.Server.Implementations.Tests/Jellyfin.Server.Implementations.Tests.csproj @@ -14,7 +14,7 @@ - + From 359b0044b848cf49e8c52bb30fb1a3e8cf8f16b7 Mon Sep 17 00:00:00 2001 From: Neil Burrows Date: Mon, 13 Jul 2020 15:12:51 +0100 Subject: [PATCH 68/81] Prevent failure to bind to Auto Discover port being a fatal error --- .../EntryPoints/UdpServerEntryPoint.cs | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/Emby.Server.Implementations/EntryPoints/UdpServerEntryPoint.cs b/Emby.Server.Implementations/EntryPoints/UdpServerEntryPoint.cs index b207397bda..a9e84c2384 100644 --- a/Emby.Server.Implementations/EntryPoints/UdpServerEntryPoint.cs +++ b/Emby.Server.Implementations/EntryPoints/UdpServerEntryPoint.cs @@ -48,8 +48,16 @@ namespace Emby.Server.Implementations.EntryPoints /// public Task RunAsync() { - _udpServer = new UdpServer(_logger, _appHost, _config); - _udpServer.Start(PortNumber, _cancellationTokenSource.Token); + try + { + _udpServer = new UdpServer(_logger, _appHost, _config); + _udpServer.Start(PortNumber, _cancellationTokenSource.Token); + } + catch (System.Net.Sockets.SocketException ex) + { + _logger.LogWarning($"Unable to start AutoDiscovery listener on UDP port {PortNumber} - {ex.Message}"); + } + return Task.CompletedTask; } From 25e382748899dd1a0e001530fbffa80b8f4451a8 Mon Sep 17 00:00:00 2001 From: Neil Burrows Date: Mon, 13 Jul 2020 15:39:14 +0100 Subject: [PATCH 69/81] Update Emby.Server.Implementations/EntryPoints/UdpServerEntryPoint.cs Update log format message and log exception Co-authored-by: Cody Robibero --- Emby.Server.Implementations/EntryPoints/UdpServerEntryPoint.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Emby.Server.Implementations/EntryPoints/UdpServerEntryPoint.cs b/Emby.Server.Implementations/EntryPoints/UdpServerEntryPoint.cs index a9e84c2384..946b9a87b8 100644 --- a/Emby.Server.Implementations/EntryPoints/UdpServerEntryPoint.cs +++ b/Emby.Server.Implementations/EntryPoints/UdpServerEntryPoint.cs @@ -55,7 +55,7 @@ namespace Emby.Server.Implementations.EntryPoints } catch (System.Net.Sockets.SocketException ex) { - _logger.LogWarning($"Unable to start AutoDiscovery listener on UDP port {PortNumber} - {ex.Message}"); + _logger.LogWarning(ex, "Unable to start AutoDiscovery listener on UDP port {PortNumber}", PortNumber); } return Task.CompletedTask; From da8eb1f15b034b946e6533baffca8ffa17bcb3a7 Mon Sep 17 00:00:00 2001 From: Neil Burrows Date: Mon, 13 Jul 2020 16:33:39 +0100 Subject: [PATCH 70/81] using System.Net.Sockets --- Emby.Server.Implementations/EntryPoints/UdpServerEntryPoint.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Emby.Server.Implementations/EntryPoints/UdpServerEntryPoint.cs b/Emby.Server.Implementations/EntryPoints/UdpServerEntryPoint.cs index 946b9a87b8..9486874d58 100644 --- a/Emby.Server.Implementations/EntryPoints/UdpServerEntryPoint.cs +++ b/Emby.Server.Implementations/EntryPoints/UdpServerEntryPoint.cs @@ -1,3 +1,4 @@ +using System.Net.Sockets; using System.Threading; using System.Threading.Tasks; using Emby.Server.Implementations.Udp; @@ -53,7 +54,7 @@ namespace Emby.Server.Implementations.EntryPoints _udpServer = new UdpServer(_logger, _appHost, _config); _udpServer.Start(PortNumber, _cancellationTokenSource.Token); } - catch (System.Net.Sockets.SocketException ex) + catch (SocketException ex) { _logger.LogWarning(ex, "Unable to start AutoDiscovery listener on UDP port {PortNumber}", PortNumber); } From befd0c7a00d0129d85db95d9ddf8e9d96df79d0a Mon Sep 17 00:00:00 2001 From: Patrick Barron Date: Mon, 13 Jul 2020 12:49:20 -0400 Subject: [PATCH 71/81] Remove EF Core Proxies --- Jellyfin.Data/Jellyfin.Data.csproj | 1 - Jellyfin.Server/CoreAppHost.cs | 3 +-- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/Jellyfin.Data/Jellyfin.Data.csproj b/Jellyfin.Data/Jellyfin.Data.csproj index 282ea511cf..58d1ba2f36 100644 --- a/Jellyfin.Data/Jellyfin.Data.csproj +++ b/Jellyfin.Data/Jellyfin.Data.csproj @@ -21,7 +21,6 @@ - diff --git a/Jellyfin.Server/CoreAppHost.cs b/Jellyfin.Server/CoreAppHost.cs index fe07411a68..207eaa98d1 100644 --- a/Jellyfin.Server/CoreAppHost.cs +++ b/Jellyfin.Server/CoreAppHost.cs @@ -66,8 +66,7 @@ namespace Jellyfin.Server // TODO: Set up scoping and use AddDbContextPool serviceCollection.AddDbContext( options => options - .UseSqlite($"Filename={Path.Combine(ApplicationPaths.DataPath, "jellyfin.db")}") - .UseLazyLoadingProxies(), + .UseSqlite($"Filename={Path.Combine(ApplicationPaths.DataPath, "jellyfin.db")}"), ServiceLifetime.Transient); serviceCollection.AddSingleton(); From b468ae2aea3b42a3073a81c2566dd19a313dc3fa Mon Sep 17 00:00:00 2001 From: Patrick Barron Date: Mon, 13 Jul 2020 14:09:20 -0400 Subject: [PATCH 72/81] Use AsEnumerable for UserManager.Users --- Jellyfin.Server.Implementations/Users/UserManager.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Jellyfin.Server.Implementations/Users/UserManager.cs b/Jellyfin.Server.Implementations/Users/UserManager.cs index 4ed0b7501a..6283a1bca5 100644 --- a/Jellyfin.Server.Implementations/Users/UserManager.cs +++ b/Jellyfin.Server.Implementations/Users/UserManager.cs @@ -96,7 +96,7 @@ namespace Jellyfin.Server.Implementations.Users .Include(user => user.Preferences) .Include(user => user.AccessSchedules) .Include(user => user.ProfileImage) - .ToList(); + .AsEnumerable(); } } From b4212cc2102f1abfeb40fde6ff05e7a94599633c Mon Sep 17 00:00:00 2001 From: "Joshua M. Boniface" Date: Mon, 13 Jul 2020 14:36:07 -0400 Subject: [PATCH 73/81] Explicitly add what Azure used to do implicitly ... before they changed it on us out of nowhere. --- .ci/azure-pipelines-package.yml | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/.ci/azure-pipelines-package.yml b/.ci/azure-pipelines-package.yml index 0907463986..5539b16ab4 100644 --- a/.ci/azure-pipelines-package.yml +++ b/.ci/azure-pipelines-package.yml @@ -50,6 +50,13 @@ jobs: targetPath: '$(Build.SourcesDirectory)/deployment/dist' artifactName: 'jellyfin-server-$(BuildConfiguration)' + - task: SSH@0 + displayName: 'Create target directory on repository server' + inputs: + sshEndpoint: repository + runOptions: 'inline' + inline: 'mkdir -p /srv/repository/incoming/azure/$(Build.BuildNumber)/$(BuildConfiguration)' + - task: CopyFilesOverSSH@0 displayName: 'Upload artifacts to repository server' inputs: From bf09bbeacd78c53d881174d82e35412fb33bd492 Mon Sep 17 00:00:00 2001 From: dkanada Date: Tue, 14 Jul 2020 08:25:02 +0900 Subject: [PATCH 74/81] update comment Co-authored-by: Patrick Barron <18354464+barronpm@users.noreply.github.com> --- Emby.Server.Implementations/SyncPlay/SyncPlayController.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Emby.Server.Implementations/SyncPlay/SyncPlayController.cs b/Emby.Server.Implementations/SyncPlay/SyncPlayController.cs index e596d99005..39d17833ff 100644 --- a/Emby.Server.Implementations/SyncPlay/SyncPlayController.cs +++ b/Emby.Server.Implementations/SyncPlay/SyncPlayController.cs @@ -222,7 +222,7 @@ namespace Emby.Server.Implementations.SyncPlay var updateOthers = NewSyncPlayGroupUpdate(GroupUpdateType.UserJoined, session.UserName); SendGroupUpdate(session, BroadcastType.AllExceptCurrentSession, updateOthers, cancellationToken); - // syncing will happen client side + // Syncing will happen client-side if (!_group.IsPaused) { var playCommand = NewSyncPlayCommand(SendCommandType.Play); From 340b585234430efa9bc9ba1689aab09852b33358 Mon Sep 17 00:00:00 2001 From: Claus Vium Date: Tue, 14 Jul 2020 12:38:56 +0200 Subject: [PATCH 75/81] Use ToList instead of AsEnumerable due to delayed execution --- Jellyfin.Server.Implementations/Users/UserManager.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Jellyfin.Server.Implementations/Users/UserManager.cs b/Jellyfin.Server.Implementations/Users/UserManager.cs index 6283a1bca5..4ed0b7501a 100644 --- a/Jellyfin.Server.Implementations/Users/UserManager.cs +++ b/Jellyfin.Server.Implementations/Users/UserManager.cs @@ -96,7 +96,7 @@ namespace Jellyfin.Server.Implementations.Users .Include(user => user.Preferences) .Include(user => user.AccessSchedules) .Include(user => user.ProfileImage) - .AsEnumerable(); + .ToList(); } } From eddce72c5228f423d8f2e738ced5cc4c3cccae66 Mon Sep 17 00:00:00 2001 From: Raif Coonjah Date: Tue, 14 Jul 2020 11:21:09 +0000 Subject: [PATCH 76/81] Translated using Weblate (Afrikaans) Translation: Jellyfin/Jellyfin Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-core/af/ --- Emby.Server.Implementations/Localization/Core/af.json | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/Emby.Server.Implementations/Localization/Core/af.json b/Emby.Server.Implementations/Localization/Core/af.json index 20447347b3..e587c37d53 100644 --- a/Emby.Server.Implementations/Localization/Core/af.json +++ b/Emby.Server.Implementations/Localization/Core/af.json @@ -19,8 +19,8 @@ "Sync": "Sinkroniseer", "HeaderFavoriteSongs": "Gunsteling Liedjies", "Songs": "Liedjies", - "DeviceOnlineWithName": "{0} is verbind", - "DeviceOfflineWithName": "{0} het afgesluit", + "DeviceOnlineWithName": "{0} gekoppel is", + "DeviceOfflineWithName": "{0} is ontkoppel", "Collections": "Versamelings", "Inherit": "Ontvang", "HeaderLiveTV": "Live TV", @@ -91,5 +91,9 @@ "ChapterNameValue": "Hoofstuk", "CameraImageUploadedFrom": "'n Nuwe kamera photo opgelaai van {0}", "AuthenticationSucceededWithUserName": "{0} suksesvol geverifieer", - "Albums": "Albums" + "Albums": "Albums", + "TasksChannelsCategory": "Internet kanale", + "TasksApplicationCategory": "aansoek", + "TasksLibraryCategory": "biblioteek", + "TasksMaintenanceCategory": "onderhoud" } From e143387cbd339020e33d30b7e001172519d66923 Mon Sep 17 00:00:00 2001 From: crobibero Date: Tue, 14 Jul 2020 06:47:46 -0600 Subject: [PATCH 77/81] Fix update user --- .../Users/UserManager.cs | 22 ++++++++++++++----- 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/Jellyfin.Server.Implementations/Users/UserManager.cs b/Jellyfin.Server.Implementations/Users/UserManager.cs index 4ed0b7501a..9aff808db0 100644 --- a/Jellyfin.Server.Implementations/Users/UserManager.cs +++ b/Jellyfin.Server.Implementations/Users/UserManager.cs @@ -92,7 +92,8 @@ namespace Jellyfin.Server.Implementations.Users get { using var dbContext = _dbProvider.CreateContext(); - return dbContext.Users.Include(user => user.Permissions) + return dbContext.Users + .Include(user => user.Permissions) .Include(user => user.Preferences) .Include(user => user.AccessSchedules) .Include(user => user.ProfileImage) @@ -112,7 +113,8 @@ namespace Jellyfin.Server.Implementations.Users } using var dbContext = _dbProvider.CreateContext(); - return dbContext.Users.Include(user => user.Permissions) + return dbContext.Users + .Include(user => user.Permissions) .Include(user => user.Preferences) .Include(user => user.AccessSchedules) .Include(user => user.ProfileImage) @@ -128,8 +130,8 @@ namespace Jellyfin.Server.Implementations.Users } using var dbContext = _dbProvider.CreateContext(); - - return dbContext.Users.Include(user => user.Permissions) + return dbContext.Users + .Include(user => user.Permissions) .Include(user => user.Preferences) .Include(user => user.AccessSchedules) .Include(user => user.ProfileImage) @@ -218,7 +220,8 @@ namespace Jellyfin.Server.Implementations.Users public void DeleteUser(Guid userId) { using var dbContext = _dbProvider.CreateContext(); - var user = dbContext.Users.Include(u => u.Permissions) + var user = dbContext.Users + .Include(u => u.Permissions) .Include(u => u.Preferences) .Include(u => u.AccessSchedules) .Include(u => u.ProfileImage) @@ -635,7 +638,14 @@ namespace Jellyfin.Server.Implementations.Users public void UpdateConfiguration(Guid userId, UserConfiguration config) { var dbContext = _dbProvider.CreateContext(); - var user = dbContext.Users.Find(userId) ?? throw new ArgumentException("No user exists with given Id!"); + var user = dbContext.Users + .Include(u => u.Permissions) + .Include(u => u.Preferences) + .Include(u => u.AccessSchedules) + .Include(u => u.ProfileImage) + .FirstOrDefault(u => u.Id == userId) + ?? throw new ArgumentException("No user exists with given Id!"); + user.SubtitleMode = config.SubtitleMode; user.HidePlayedInLatest = config.HidePlayedInLatest; user.EnableLocalPassword = config.EnableLocalPassword; From 87f5a6bdb3e3856f2dfaddcc3b0902a45ff48ca2 Mon Sep 17 00:00:00 2001 From: Max Git Date: Wed, 15 Jul 2020 05:56:05 +0200 Subject: [PATCH 78/81] Move videostream null check to start of GetHardwareAcceleratedVideoDecoder --- .../MediaEncoding/EncodingHelper.cs | 24 ++++++++++++------- 1 file changed, 15 insertions(+), 9 deletions(-) diff --git a/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs b/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs index cbfdf26959..fa06de0a36 100644 --- a/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs +++ b/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs @@ -2523,21 +2523,21 @@ namespace MediaBrowser.Controller.MediaEncoding } /// - /// Gets the name of the output video codec. + /// Gets the ffmpeg option string for the hardware accelerated video decoder. /// + /// The encoding job info. + /// The encoding options. + /// The option string or null if none available. protected string GetHardwareAcceleratedVideoDecoder(EncodingJobInfo state, EncodingOptions encodingOptions) { - var videoType = state.MediaSource.VideoType ?? VideoType.VideoFile; var videoStream = state.VideoStream; - var isColorDepth10 = !string.IsNullOrEmpty(videoStream.Profile) && (videoStream.Profile.Contains("Main 10", StringComparison.OrdinalIgnoreCase) - || videoStream.Profile.Contains("High 10", StringComparison.OrdinalIgnoreCase)); - - if (EncodingHelper.IsCopyCodec(state.OutputVideoCodec)) + if (videoStream == null) { return null; } + var videoType = state.MediaSource.VideoType ?? VideoType.VideoFile; // Only use alternative encoders for video files. // When using concat with folder rips, if the mfx session fails to initialize, ffmpeg will be stuck retrying and will not exit gracefully // Since transcoding of folder rips is expiremental anyway, it's not worth adding additional variables such as this. @@ -2546,10 +2546,16 @@ namespace MediaBrowser.Controller.MediaEncoding return null; } - if (videoStream != null - && !string.IsNullOrEmpty(videoStream.Codec) - && !string.IsNullOrEmpty(encodingOptions.HardwareAccelerationType)) + if (IsCopyCodec(state.OutputVideoCodec)) { + return null; + } + + if (!string.IsNullOrEmpty(videoStream.Codec) && !string.IsNullOrEmpty(encodingOptions.HardwareAccelerationType)) + { + var isColorDepth10 = !string.IsNullOrEmpty(videoStream.Profile) + && (videoStream.Profile.Contains("Main 10", StringComparison.OrdinalIgnoreCase) || videoStream.Profile.Contains("High 10", StringComparison.OrdinalIgnoreCase)); + // Only hevc and vp9 formats have 10-bit hardware decoder support now. if (isColorDepth10 && !(string.Equals(videoStream.Codec, "hevc", StringComparison.OrdinalIgnoreCase) || string.Equals(videoStream.Codec, "h265", StringComparison.OrdinalIgnoreCase) From b356ff6c8908e5479c0d2eb6e17b2910d8ed01e4 Mon Sep 17 00:00:00 2001 From: Max Git Date: Wed, 15 Jul 2020 06:58:36 +0200 Subject: [PATCH 79/81] Simplify name of IsCopyDoc --- MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs b/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs index fa06de0a36..534e0c372e 100644 --- a/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs +++ b/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs @@ -1351,7 +1351,7 @@ namespace MediaBrowser.Controller.MediaEncoding transcoderChannelLimit = 6; } - var isTranscodingAudio = !EncodingHelper.IsCopyCodec(codec); + var isTranscodingAudio = !IsCopyCodec(codec); int? resultChannels = state.GetRequestedAudioChannels(codec); if (isTranscodingAudio) @@ -2264,7 +2264,7 @@ namespace MediaBrowser.Controller.MediaEncoding flags.Add("+ignidx"); } - if (state.GenPtsInput || EncodingHelper.IsCopyCodec(state.OutputVideoCodec)) + if (state.GenPtsInput || IsCopyCodec(state.OutputVideoCodec)) { flags.Add("+genpts"); } @@ -3008,7 +3008,7 @@ namespace MediaBrowser.Controller.MediaEncoding args += " -mpegts_m2ts_mode 1"; } - if (EncodingHelper.IsCopyCodec(videoCodec)) + if (IsCopyCodec(videoCodec)) { if (state.VideoStream != null && string.Equals(state.OutputContainer, "ts", StringComparison.OrdinalIgnoreCase) @@ -3110,7 +3110,7 @@ namespace MediaBrowser.Controller.MediaEncoding var args = "-codec:a:0 " + codec; - if (EncodingHelper.IsCopyCodec(codec)) + if (IsCopyCodec(codec)) { return args; } From 8c0168ef72501bf43cff2a27866785d3efcb79e1 Mon Sep 17 00:00:00 2001 From: Claus Vium Date: Wed, 15 Jul 2020 16:45:14 +0200 Subject: [PATCH 80/81] Fetch image keytypes before querying images --- .../Plugins/TheTvdb/TvdbClientManager.cs | 45 +++++++++++++++++++ .../TheTvdb/TvdbSeasonImageProvider.cs | 2 +- .../TheTvdb/TvdbSeriesImageProvider.cs | 5 ++- .../Plugins/TheTvdb/TvdbSeriesProvider.cs | 15 +++++-- .../Plugins/TheTvdb/TvdbUtils.cs | 3 +- 5 files changed, 63 insertions(+), 7 deletions(-) diff --git a/MediaBrowser.Providers/Plugins/TheTvdb/TvdbClientManager.cs b/MediaBrowser.Providers/Plugins/TheTvdb/TvdbClientManager.cs index 2c6682f821..b9b477ecb4 100644 --- a/MediaBrowser.Providers/Plugins/TheTvdb/TvdbClientManager.cs +++ b/MediaBrowser.Providers/Plugins/TheTvdb/TvdbClientManager.cs @@ -229,6 +229,51 @@ namespace MediaBrowser.Providers.Plugins.TheTvdb return GetEpisodesPageAsync(tvdbId, 1, episodeQuery, language, cancellationToken); } + public async Task> GetImageKeyTypesForSeriesAsync(int tvdbId, string language, CancellationToken cancellationToken) + { + var cacheKey = GenerateKey(nameof(TvDbClient.Series.GetImagesSummaryAsync), tvdbId); + var imagesSummary = await TryGetValue(cacheKey, language, () => TvDbClient.Series.GetImagesSummaryAsync(tvdbId, cancellationToken)).ConfigureAwait(false); + var keyTypes = new List(); + + if (imagesSummary.Data.Fanart > 0) + { + keyTypes.Add(KeyType.Fanart); + } + + if (imagesSummary.Data.Series > 0) + { + keyTypes.Add(KeyType.Series); + } + + if (imagesSummary.Data.Poster > 0) + { + keyTypes.Add(KeyType.Poster); + } + + return keyTypes; + } + + public async Task> GetImageKeyTypesForSeasonAsync(int tvdbId, string language, CancellationToken cancellationToken) + { + var cacheKey = GenerateKey(nameof(TvDbClient.Series.GetImagesSummaryAsync), tvdbId); + var imagesSummary = await TryGetValue(cacheKey, language, () => TvDbClient.Series.GetImagesSummaryAsync(tvdbId, cancellationToken)).ConfigureAwait(false); + var keyTypes = new List(); + + if (imagesSummary.Data.Season > 0) + { + keyTypes.Add(KeyType.Season); + } + + if (imagesSummary.Data.Fanart > 0) + { + keyTypes.Add(KeyType.Fanart); + } + + // TODO seasonwide is not supported in TvDbSharper + + return keyTypes; + } + private async Task TryGetValue(string key, string language, Func> resultFactory) { if (_cache.TryGetValue(key, out T cachedValue)) diff --git a/MediaBrowser.Providers/Plugins/TheTvdb/TvdbSeasonImageProvider.cs b/MediaBrowser.Providers/Plugins/TheTvdb/TvdbSeasonImageProvider.cs index 5af99a573e..2cf822ac04 100644 --- a/MediaBrowser.Providers/Plugins/TheTvdb/TvdbSeasonImageProvider.cs +++ b/MediaBrowser.Providers/Plugins/TheTvdb/TvdbSeasonImageProvider.cs @@ -65,7 +65,7 @@ namespace MediaBrowser.Providers.Plugins.TheTvdb var language = item.GetPreferredMetadataLanguage(); var remoteImages = new List(); - var keyTypes = new[] { KeyType.Season, KeyType.Seasonwide, KeyType.Fanart }; + var keyTypes = await _tvdbClientManager.GetImageKeyTypesForSeasonAsync(tvdbId, language, cancellationToken).ConfigureAwait(false); foreach (var keyType in keyTypes) { var imageQuery = new ImagesQuery diff --git a/MediaBrowser.Providers/Plugins/TheTvdb/TvdbSeriesImageProvider.cs b/MediaBrowser.Providers/Plugins/TheTvdb/TvdbSeriesImageProvider.cs index 7dd0128250..174c923870 100644 --- a/MediaBrowser.Providers/Plugins/TheTvdb/TvdbSeriesImageProvider.cs +++ b/MediaBrowser.Providers/Plugins/TheTvdb/TvdbSeriesImageProvider.cs @@ -59,9 +59,10 @@ namespace MediaBrowser.Providers.Plugins.TheTvdb var language = item.GetPreferredMetadataLanguage(); var remoteImages = new List(); - var keyTypes = new[] { KeyType.Poster, KeyType.Series, KeyType.Fanart }; var tvdbId = Convert.ToInt32(item.GetProviderId(MetadataProvider.Tvdb)); - foreach (KeyType keyType in keyTypes) + var allowedKeyTypes = await _tvdbClientManager.GetImageKeyTypesForSeriesAsync(tvdbId, language, cancellationToken) + .ConfigureAwait(false); + foreach (KeyType keyType in allowedKeyTypes) { var imageQuery = new ImagesQuery { diff --git a/MediaBrowser.Providers/Plugins/TheTvdb/TvdbSeriesProvider.cs b/MediaBrowser.Providers/Plugins/TheTvdb/TvdbSeriesProvider.cs index b3641dc9f4..196e801c03 100644 --- a/MediaBrowser.Providers/Plugins/TheTvdb/TvdbSeriesProvider.cs +++ b/MediaBrowser.Providers/Plugins/TheTvdb/TvdbSeriesProvider.cs @@ -247,10 +247,15 @@ namespace MediaBrowser.Providers.Plugins.TheTvdb { Name = tvdbTitles.FirstOrDefault(), ProductionYear = firstAired.Year, - SearchProviderName = Name, - ImageUrl = TvdbUtils.BannerUrl + seriesSearchResult.Banner + SearchProviderName = Name }; + if (!string.IsNullOrEmpty(seriesSearchResult.Banner)) + { + // Results from their Search endpoints already include the /banners/ part in the url, because reasons... + remoteSearchResult.ImageUrl = TvdbUtils.TvdbImageBaseUrl + seriesSearchResult.Banner; + } + try { var seriesSesult = @@ -365,10 +370,14 @@ namespace MediaBrowser.Providers.Plugins.TheTvdb Type = PersonType.Actor, Name = (actor.Name ?? string.Empty).Trim(), Role = actor.Role, - ImageUrl = TvdbUtils.BannerUrl + actor.Image, SortOrder = actor.SortOrder }; + if (!string.IsNullOrEmpty(actor.Image)) + { + personInfo.ImageUrl = TvdbUtils.TvdbImageBaseUrl + actor.Image; + } + if (!string.IsNullOrWhiteSpace(personInfo.Name)) { result.AddPerson(personInfo); diff --git a/MediaBrowser.Providers/Plugins/TheTvdb/TvdbUtils.cs b/MediaBrowser.Providers/Plugins/TheTvdb/TvdbUtils.cs index 3f71041b2b..37a8d04a6f 100644 --- a/MediaBrowser.Providers/Plugins/TheTvdb/TvdbUtils.cs +++ b/MediaBrowser.Providers/Plugins/TheTvdb/TvdbUtils.cs @@ -9,7 +9,8 @@ namespace MediaBrowser.Providers.Plugins.TheTvdb { public const string TvdbApiKey = "OG4V3YJ3FAP7FP2K"; public const string TvdbBaseUrl = "https://www.thetvdb.com/"; - public const string BannerUrl = TvdbBaseUrl + "banners/"; + public const string TvdbImageBaseUrl = "https://www.thetvdb.com"; + public const string BannerUrl = TvdbImageBaseUrl + "/banners/"; public static ImageType GetImageTypeFromKeyType(string keyType) { From 6d37a5fe528ed07ab3529e9dfc07c03d1c572558 Mon Sep 17 00:00:00 2001 From: Claus Vium Date: Wed, 15 Jul 2020 17:14:39 +0200 Subject: [PATCH 81/81] Change to IAsyncEnumerable --- .../Plugins/TheTvdb/TvdbClientManager.cs | 20 +++++++------------ .../TheTvdb/TvdbSeasonImageProvider.cs | 4 ++-- .../TheTvdb/TvdbSeriesImageProvider.cs | 4 ++-- 3 files changed, 11 insertions(+), 17 deletions(-) diff --git a/MediaBrowser.Providers/Plugins/TheTvdb/TvdbClientManager.cs b/MediaBrowser.Providers/Plugins/TheTvdb/TvdbClientManager.cs index b9b477ecb4..8c1b22a885 100644 --- a/MediaBrowser.Providers/Plugins/TheTvdb/TvdbClientManager.cs +++ b/MediaBrowser.Providers/Plugins/TheTvdb/TvdbClientManager.cs @@ -229,49 +229,43 @@ namespace MediaBrowser.Providers.Plugins.TheTvdb return GetEpisodesPageAsync(tvdbId, 1, episodeQuery, language, cancellationToken); } - public async Task> GetImageKeyTypesForSeriesAsync(int tvdbId, string language, CancellationToken cancellationToken) + public async IAsyncEnumerable GetImageKeyTypesForSeriesAsync(int tvdbId, string language, CancellationToken cancellationToken) { var cacheKey = GenerateKey(nameof(TvDbClient.Series.GetImagesSummaryAsync), tvdbId); var imagesSummary = await TryGetValue(cacheKey, language, () => TvDbClient.Series.GetImagesSummaryAsync(tvdbId, cancellationToken)).ConfigureAwait(false); - var keyTypes = new List(); if (imagesSummary.Data.Fanart > 0) { - keyTypes.Add(KeyType.Fanart); + yield return KeyType.Fanart; } if (imagesSummary.Data.Series > 0) { - keyTypes.Add(KeyType.Series); + yield return KeyType.Series; } if (imagesSummary.Data.Poster > 0) { - keyTypes.Add(KeyType.Poster); + yield return KeyType.Poster; } - - return keyTypes; } - public async Task> GetImageKeyTypesForSeasonAsync(int tvdbId, string language, CancellationToken cancellationToken) + public async IAsyncEnumerable GetImageKeyTypesForSeasonAsync(int tvdbId, string language, CancellationToken cancellationToken) { var cacheKey = GenerateKey(nameof(TvDbClient.Series.GetImagesSummaryAsync), tvdbId); var imagesSummary = await TryGetValue(cacheKey, language, () => TvDbClient.Series.GetImagesSummaryAsync(tvdbId, cancellationToken)).ConfigureAwait(false); - var keyTypes = new List(); if (imagesSummary.Data.Season > 0) { - keyTypes.Add(KeyType.Season); + yield return KeyType.Season; } if (imagesSummary.Data.Fanart > 0) { - keyTypes.Add(KeyType.Fanart); + yield return KeyType.Fanart; } // TODO seasonwide is not supported in TvDbSharper - - return keyTypes; } private async Task TryGetValue(string key, string language, Func> resultFactory) diff --git a/MediaBrowser.Providers/Plugins/TheTvdb/TvdbSeasonImageProvider.cs b/MediaBrowser.Providers/Plugins/TheTvdb/TvdbSeasonImageProvider.cs index 2cf822ac04..e9ba204754 100644 --- a/MediaBrowser.Providers/Plugins/TheTvdb/TvdbSeasonImageProvider.cs +++ b/MediaBrowser.Providers/Plugins/TheTvdb/TvdbSeasonImageProvider.cs @@ -65,8 +65,8 @@ namespace MediaBrowser.Providers.Plugins.TheTvdb var language = item.GetPreferredMetadataLanguage(); var remoteImages = new List(); - var keyTypes = await _tvdbClientManager.GetImageKeyTypesForSeasonAsync(tvdbId, language, cancellationToken).ConfigureAwait(false); - foreach (var keyType in keyTypes) + var keyTypes = _tvdbClientManager.GetImageKeyTypesForSeasonAsync(tvdbId, language, cancellationToken).ConfigureAwait(false); + await foreach (var keyType in keyTypes) { var imageQuery = new ImagesQuery { diff --git a/MediaBrowser.Providers/Plugins/TheTvdb/TvdbSeriesImageProvider.cs b/MediaBrowser.Providers/Plugins/TheTvdb/TvdbSeriesImageProvider.cs index 174c923870..c33aefbc19 100644 --- a/MediaBrowser.Providers/Plugins/TheTvdb/TvdbSeriesImageProvider.cs +++ b/MediaBrowser.Providers/Plugins/TheTvdb/TvdbSeriesImageProvider.cs @@ -60,9 +60,9 @@ namespace MediaBrowser.Providers.Plugins.TheTvdb var language = item.GetPreferredMetadataLanguage(); var remoteImages = new List(); var tvdbId = Convert.ToInt32(item.GetProviderId(MetadataProvider.Tvdb)); - var allowedKeyTypes = await _tvdbClientManager.GetImageKeyTypesForSeriesAsync(tvdbId, language, cancellationToken) + var allowedKeyTypes = _tvdbClientManager.GetImageKeyTypesForSeriesAsync(tvdbId, language, cancellationToken) .ConfigureAwait(false); - foreach (KeyType keyType in allowedKeyTypes) + await foreach (KeyType keyType in allowedKeyTypes) { var imageQuery = new ImagesQuery {