diff options
23 files changed, 238 insertions, 155 deletions
diff --git a/.ci/azure-pipelines-package.yml b/.ci/azure-pipelines-package.yml index 89f7137fd..19d65ea0c 100644 --- a/.ci/azure-pipelines-package.yml +++ b/.ci/azure-pipelines-package.yml @@ -43,10 +43,6 @@ jobs: displayName: Set release version (stable) condition: startsWith(variables['Build.SourceBranch'], 'refs/tags/v') - - script: './bump-version $(JellyfinVersion)' - displayName: Bump internal version (stable) - condition: startsWith(variables['Build.SourceBranch'], 'refs/tags/v') - - script: 'docker build -f deployment/Dockerfile.$(BuildConfiguration) -t jellyfin-server-$(BuildConfiguration) deployment' displayName: 'Build Dockerfile' @@ -92,10 +88,6 @@ jobs: displayName: Set release version (stable) condition: startsWith(variables['Build.SourceBranch'], 'refs/tags/v') - - script: './bump-version $(JellyfinVersion)' - displayName: Bump internal version (stable) - condition: startsWith(variables['Build.SourceBranch'], 'refs/tags/v') - - task: DownloadPipelineArtifact@2 displayName: 'Download OpenAPI Spec' inputs: @@ -143,10 +135,6 @@ jobs: displayName: Set release version (stable) condition: startsWith(variables['Build.SourceBranch'], 'refs/tags/v') - - script: './bump-version $(JellyfinVersion)' - displayName: Bump internal version (stable) - condition: startsWith(variables['Build.SourceBranch'], 'refs/tags/v') - - task: Docker@2 displayName: 'Push Unstable Image' condition: startsWith(variables['Build.SourceBranch'], 'refs/heads/master') diff --git a/Emby.Dlna/Didl/DidlBuilder.cs b/Emby.Dlna/Didl/DidlBuilder.cs index b00e1c98a..6803b3b87 100644 --- a/Emby.Dlna/Didl/DidlBuilder.cs +++ b/Emby.Dlna/Didl/DidlBuilder.cs @@ -989,7 +989,7 @@ namespace Emby.Dlna.Didl writer.WriteAttributeString("dlna", "profileID", NsDlna, _profile.AlbumArtPn); } - writer.WriteString(albumArtUrlInfo.url); + writer.WriteString(albumArtUrlInfo.Url); writer.WriteFullEndElement(); // TODO: Remove these default values @@ -998,7 +998,7 @@ namespace Emby.Dlna.Didl _profile.MaxIconWidth ?? 48, _profile.MaxIconHeight ?? 48, "jpg"); - writer.WriteElementString("upnp", "icon", NsUpnp, iconUrlInfo.url); + writer.WriteElementString("upnp", "icon", NsUpnp, iconUrlInfo.Url); if (!_profile.EnableAlbumArtInDidl) { @@ -1045,8 +1045,8 @@ namespace Emby.Dlna.Didl // Images must have a reported size or many clients (Bubble upnp), will only use the first thumbnail // rather than using a larger one when available - var width = albumartUrlInfo.width ?? maxWidth; - var height = albumartUrlInfo.height ?? maxHeight; + var width = albumartUrlInfo.Width ?? maxWidth; + var height = albumartUrlInfo.Height ?? maxHeight; var contentFeatures = ContentFeatureBuilder.BuildImageHeader(_profile, format, width, height, imageInfo.IsDirectStream, org_Pn); @@ -1062,7 +1062,7 @@ namespace Emby.Dlna.Didl "resolution", string.Format(CultureInfo.InvariantCulture, "{0}x{1}", width, height)); - writer.WriteString(albumartUrlInfo.url); + writer.WriteString(albumartUrlInfo.Url); writer.WriteFullEndElement(); } @@ -1200,7 +1200,7 @@ namespace Emby.Dlna.Didl return id; } - private (string url, int? width, int? height) GetImageUrl(ImageDownloadInfo info, int maxWidth, int maxHeight, string format) + private (string Url, int? Width, int? Height) GetImageUrl(ImageDownloadInfo info, int maxWidth, int maxHeight, string format) { var url = string.Format( CultureInfo.InvariantCulture, diff --git a/Emby.Server.Implementations/Data/SqliteItemRepository.cs b/Emby.Server.Implementations/Data/SqliteItemRepository.cs index 41f29b835..5ab9e02fe 100644 --- a/Emby.Server.Implementations/Data/SqliteItemRepository.cs +++ b/Emby.Server.Implementations/Data/SqliteItemRepository.cs @@ -3015,86 +3015,101 @@ namespace Emby.Server.Implementations.Data return " ORDER BY " + string.Join(',', orderBy.Select(i => { - var columnMap = MapOrderByField(i.OrderBy, query); - var sortOrder = columnMap.SortOrder == SortOrder.Ascending ? "ASC" : "DESC"; - return columnMap.SortBy + " " + sortOrder; + var sortBy = MapOrderByField(i.OrderBy, query); + var sortOrder = i.SortOrder == SortOrder.Ascending ? "ASC" : "DESC"; + return sortBy + " " + sortOrder; })); } - private (string SortBy, SortOrder SortOrder) MapOrderByField(string name, InternalItemsQuery query) + private string MapOrderByField(string name, InternalItemsQuery query) { if (string.Equals(name, ItemSortBy.AirTime, StringComparison.OrdinalIgnoreCase)) { // TODO - return ("SortName", SortOrder.Ascending); + return "SortName"; } - else if (string.Equals(name, ItemSortBy.Runtime, StringComparison.OrdinalIgnoreCase)) + + if (string.Equals(name, ItemSortBy.Runtime, StringComparison.OrdinalIgnoreCase)) { - return ("RuntimeTicks", SortOrder.Ascending); + return "RuntimeTicks"; } - else if (string.Equals(name, ItemSortBy.Random, StringComparison.OrdinalIgnoreCase)) + + if (string.Equals(name, ItemSortBy.Random, StringComparison.OrdinalIgnoreCase)) { - return ("RANDOM()", SortOrder.Ascending); + return "RANDOM()"; } - else if (string.Equals(name, ItemSortBy.DatePlayed, StringComparison.OrdinalIgnoreCase)) + + if (string.Equals(name, ItemSortBy.DatePlayed, StringComparison.OrdinalIgnoreCase)) { if (query.GroupBySeriesPresentationUniqueKey) { - return ("MAX(LastPlayedDate)", SortOrder.Ascending); + return "MAX(LastPlayedDate)"; } - return ("LastPlayedDate", SortOrder.Ascending); + return "LastPlayedDate"; } - else if (string.Equals(name, ItemSortBy.PlayCount, StringComparison.OrdinalIgnoreCase)) + + if (string.Equals(name, ItemSortBy.PlayCount, StringComparison.OrdinalIgnoreCase)) { - return ("PlayCount", SortOrder.Ascending); + return "PlayCount"; } - else if (string.Equals(name, ItemSortBy.IsFavoriteOrLiked, StringComparison.OrdinalIgnoreCase)) + + if (string.Equals(name, ItemSortBy.IsFavoriteOrLiked, StringComparison.OrdinalIgnoreCase)) { - return ("(Select Case When IsFavorite is null Then 0 Else IsFavorite End )", SortOrder.Descending); + return "(Select Case When IsFavorite is null Then 0 Else IsFavorite End )"; } - else if (string.Equals(name, ItemSortBy.IsFolder, StringComparison.OrdinalIgnoreCase)) + + if (string.Equals(name, ItemSortBy.IsFolder, StringComparison.OrdinalIgnoreCase)) { - return ("IsFolder", SortOrder.Descending); + return "IsFolder"; } - else if (string.Equals(name, ItemSortBy.IsPlayed, StringComparison.OrdinalIgnoreCase)) + + if (string.Equals(name, ItemSortBy.IsPlayed, StringComparison.OrdinalIgnoreCase)) { - return ("played", SortOrder.Descending); + return "played"; } - else if (string.Equals(name, ItemSortBy.IsUnplayed, StringComparison.OrdinalIgnoreCase)) + + if (string.Equals(name, ItemSortBy.IsUnplayed, StringComparison.OrdinalIgnoreCase)) { - return ("played", SortOrder.Descending); + return "played"; } - else if (string.Equals(name, ItemSortBy.DateLastContentAdded, StringComparison.OrdinalIgnoreCase)) + + if (string.Equals(name, ItemSortBy.DateLastContentAdded, StringComparison.OrdinalIgnoreCase)) { - return ("DateLastMediaAdded", SortOrder.Ascending); + return "DateLastMediaAdded"; } - else if (string.Equals(name, ItemSortBy.Artist, StringComparison.OrdinalIgnoreCase)) + + if (string.Equals(name, ItemSortBy.Artist, StringComparison.OrdinalIgnoreCase)) { - return ("(select CleanValue from itemvalues where ItemId=Guid and Type=0 LIMIT 1)", SortOrder.Ascending); + return "(select CleanValue from itemvalues where ItemId=Guid and Type=0 LIMIT 1)"; } - else if (string.Equals(name, ItemSortBy.AlbumArtist, StringComparison.OrdinalIgnoreCase)) + + if (string.Equals(name, ItemSortBy.AlbumArtist, StringComparison.OrdinalIgnoreCase)) { - return ("(select CleanValue from itemvalues where ItemId=Guid and Type=1 LIMIT 1)", SortOrder.Ascending); + return "(select CleanValue from itemvalues where ItemId=Guid and Type=1 LIMIT 1)"; } - else if (string.Equals(name, ItemSortBy.OfficialRating, StringComparison.OrdinalIgnoreCase)) + + if (string.Equals(name, ItemSortBy.OfficialRating, StringComparison.OrdinalIgnoreCase)) { - return ("InheritedParentalRatingValue", SortOrder.Ascending); + return "InheritedParentalRatingValue"; } - else if (string.Equals(name, ItemSortBy.Studio, StringComparison.OrdinalIgnoreCase)) + + if (string.Equals(name, ItemSortBy.Studio, StringComparison.OrdinalIgnoreCase)) { - return ("(select CleanValue from itemvalues where ItemId=Guid and Type=3 LIMIT 1)", SortOrder.Ascending); + return "(select CleanValue from itemvalues where ItemId=Guid and Type=3 LIMIT 1)"; } - else if (string.Equals(name, ItemSortBy.SeriesDatePlayed, StringComparison.OrdinalIgnoreCase)) + + if (string.Equals(name, ItemSortBy.SeriesDatePlayed, StringComparison.OrdinalIgnoreCase)) { - return ("(Select MAX(LastPlayedDate) from TypedBaseItems B" + GetJoinUserDataText(query) + " where Played=1 and B.SeriesPresentationUniqueKey=A.PresentationUniqueKey)", SortOrder.Ascending); + return "(Select MAX(LastPlayedDate) from TypedBaseItems B" + GetJoinUserDataText(query) + " where Played=1 and B.SeriesPresentationUniqueKey=A.PresentationUniqueKey)"; } - else if (string.Equals(name, ItemSortBy.SeriesSortName, StringComparison.OrdinalIgnoreCase)) + + if (string.Equals(name, ItemSortBy.SeriesSortName, StringComparison.OrdinalIgnoreCase)) { - return ("SeriesName", SortOrder.Ascending); + return "SeriesName"; } - return (name, SortOrder.Ascending); + return name; } public List<Guid> GetItemIdsList(InternalItemsQuery query) diff --git a/Emby.Server.Implementations/Library/LibraryManager.cs b/Emby.Server.Implementations/Library/LibraryManager.cs index db2836a70..464a621cf 100644 --- a/Emby.Server.Implementations/Library/LibraryManager.cs +++ b/Emby.Server.Implementations/Library/LibraryManager.cs @@ -1444,7 +1444,7 @@ namespace Emby.Server.Implementations.Library for (int i = 0; i < len; i++) { parents[i] = GetItemById(ancestorIds[i]); - if (!(parents[i] is ICollectionFolder || parents[i] is UserView)) + if (parents[i] is not (ICollectionFolder or UserView)) { return; } diff --git a/Emby.Server.Implementations/Localization/Core/he.json b/Emby.Server.Implementations/Localization/Core/he.json index 5e299ea0e..e32ab4ca8 100644 --- a/Emby.Server.Implementations/Localization/Core/he.json +++ b/Emby.Server.Implementations/Localization/Core/he.json @@ -119,5 +119,6 @@ "Undefined": "לא מוגדר", "Forced": "כפוי", "Default": "ברירת מחדל", - "TaskOptimizeDatabase": "מיטוב מסד נתונים" + "TaskOptimizeDatabase": "מיטוב מסד נתונים", + "TaskOptimizeDatabaseDescription": "דוחס את מסד הנתונים ומוריד את שטח האחסון שבשימוש. הרצה של פעולה זו לאחר סריקת הספרייה או שינויים אחרים שמשפיעים על מסד הנתונים יכולה לשפר ביצועים." } diff --git a/Emby.Server.Implementations/Localization/Core/my.json b/Emby.Server.Implementations/Localization/Core/my.json index 0967ef424..418376c4e 100644 --- a/Emby.Server.Implementations/Localization/Core/my.json +++ b/Emby.Server.Implementations/Localization/Core/my.json @@ -1 +1,123 @@ -{} +{ + "Default": "ပုံသေ", + "Collections": "စုစည်းမှုများ", + "Channels": "ချန်နယ်များ", + "Books": "စာအုပ်များ", + "Artists": "အနုပညာရှင်များ", + "Albums": "အခွေများ", + "TaskOptimizeDatabaseDescription": "ဒေတာဘေ့စ်ကို ကျစ်လစ်စေပြီး နေရာလွတ်များကို ဖြတ်တောက်ပေးသည်။ စာကြည့်တိုက်ကို စကင်န်ဖတ်ပြီးနောက် ဤလုပ်ငန်းကို လုပ်ဆောင်ခြင်း သို့မဟုတ် ဒေတာဘေ့စ်မွမ်းမံမှုများ စွမ်းဆောင်ရည်ကို မြှင့်တင်ပေးနိုင်သည်ဟု ရည်ညွှန်းသော အခြားပြောင်းလဲမှုများကို လုပ်ဆောင်ခြင်း။.", + "TaskOptimizeDatabase": "ဒေတာဘေ့စ်ကို အကောင်းဆုံးဖြစ်အောင်လုပ်ပါ။", + "TaskDownloadMissingSubtitlesDescription": "မက်တာဒေတာ ဖွဲ့စည်းမှုပုံစံအပေါ် အခြေခံ၍ ပျောက်ဆုံးနေသော စာတန်းထိုးများအတွက် အင်တာနက်ကို ရှာဖွေသည်။", + "TaskDownloadMissingSubtitles": "ပျောက်ဆုံးနေသော စာတန်းထိုးများကို ဒေါင်းလုဒ်လုပ်ပါ။", + "TaskRefreshChannelsDescription": "အင်တာနက်ချန်နယ်အချက်အလက်ကို ပြန်လည်စတင်သည်။", + "TaskRefreshChannels": "ချန်နယ်များကို ပြန်လည်စတင်ပါ။", + "TaskCleanTranscodeDescription": "သက်တမ်း တစ်ရက်ထက်ပိုသော အသွင်ပြောင်းကုဒ်ဖိုင်များကို ဖျက်ပါ။", + "TaskCleanTranscode": "Transcode လမ်းညွှန်ကို သန့်ရှင်းပါ။", + "TaskUpdatePluginsDescription": "အလိုအလျောက် အပ်ဒိတ်လုပ်ရန် စီစဉ်ထားသော ပလပ်အင်များအတွက် အပ်ဒိတ်များကို ဒေါင်းလုဒ်လုပ်ပြီး ထည့်သွင်းပါ။", + "TaskUpdatePlugins": "ပလပ်အင်များကို အပ်ဒိတ်လုပ်ပါ။", + "TaskRefreshPeopleDescription": "သင့်မီဒီယာစာကြည့်တိုက်ရှိ သရုပ်ဆောင်များနှင့် ဒါရိုက်တာများအတွက် မက်တာဒေတာကို အပ်ဒိတ်လုပ်ပါ။", + "TaskRefreshPeople": "လူများကို ပြန်လည်ဆန်းသစ်ပါ။", + "TaskCleanLogsDescription": "{0} ရက်ထက်ပိုသော မှတ်တမ်းဖိုင်များကို ဖျက်သည်။", + "TaskCleanLogs": "မှတ်တမ်းလမ်းညွှန်ကို သန့်ရှင်းပါ။", + "TaskRefreshLibraryDescription": "ဖိုင်အသစ်များအတွက် သင့်မီဒီယာဒစ်ဂျစ်တိုက်ကို စကင်န်ဖတ်ပြီး မက်တာဒေတာကို ပြန်လည်စတင်ပါ။", + "TaskRefreshLibrary": "မီဒီယာစာကြည့်တိုက်ကို စကင်န်ဖတ်ပါ။", + "TaskRefreshChapterImagesDescription": "အခန်းများပါရှိသော ဗီဒီယိုများအတွက် ပုံသေးများကို ဖန်တီးပါ။", + "TaskRefreshChapterImages": "အခန်းပုံများကို ထုတ်ယူပါ။", + "TaskCleanCacheDescription": "စနစ်မှ မလိုအပ်တော့သော ကက်ရှ်ဖိုင်များကို ဖျက်ပါ။.", + "TaskCleanCache": "Cache Directory ကို ရှင်းပါ။", + "TaskCleanActivityLogDescription": "စီစဉ်သတ်မှတ်ထားသော အသက်ထက် ပိုကြီးသော လုပ်ဆောင်ချက်မှတ်တမ်းများကို ဖျက်ပါ။", + "TaskCleanActivityLog": "လုပ်ဆောင်ချက်မှတ်တမ်းကို ရှင်းလင်းပါ။", + "TasksChannelsCategory": "အင်တာနက်ချန်နယ်များ", + "TasksApplicationCategory": "အပလီကေးရှင်း", + "TasksLibraryCategory": "စာကြည့်တိုက်", + "TasksMaintenanceCategory": "ထိန်းသိမ်းခြင်း", + "VersionNumber": "ဗားရှင်း {0}", + "ValueSpecialEpisodeName": "အထူး- {0}", + "ValueHasBeenAddedToLibrary": "{0} ကို သင့်မီဒီယာဒစ်ဂျစ်တိုက်သို့ ပေါင်းထည့်လိုက်ပါပြီ။", + "UserStoppedPlayingItemWithValues": "{0} သည် {1} ကို {2} တွင် ဖွင့်ပြီးပါပြီ", + "UserStartedPlayingItemWithValues": "{0} သည် {1} ကို {2} တွင် ပြသနေသည်", + "UserPolicyUpdatedWithName": "{0} အတွက် အသုံးပြုသူမူဝါဒကို အပ်ဒိတ်လုပ်ပြီးပါပြီ", + "UserPasswordChangedWithName": "အသုံးပြုသူ {0} အတွက် စကားဝှက်ကို ပြောင်းထားသည်", + "UserOnlineFromDevice": "{0} သည် {1} မှ အွန်လိုင်းဖြစ်သည်", + "UserOfflineFromDevice": "{0} သည် {1} မှ ချိတ်ဆက်မှုပြတ်တောက်သွားသည်", + "UserLockedOutWithName": "အသုံးပြုသူ {0} အား လော့ခ်ချထားသည်။", + "UserDownloadingItemWithValues": "{0} သည် {1} ကို ဒေါင်းလုဒ်လုပ်နေသည်", + "UserDeletedWithName": "အသုံးပြုသူ {0} ကို ဖျက်လိုက်ပါပြီ။", + "UserCreatedWithName": "အသုံးပြုသူ {0} ကို ဖန်တီးပြီးပါပြီ။", + "User": "အသုံးပြုသူ", + "Undefined": "သတ်မှတ်မထားသော", + "TvShows": "တီဗီရှိုးများ", + "System": "စနစ်", + "Sync": "ထပ်တူကျသည်။", + "SubtitleDownloadFailureFromForItem": "စာတန်းထိုးများကို {1} အတွက် {0} မှ ဒေါင်းလုဒ်လုပ်၍ မရပါ", + "StartupEmbyServerIsLoading": "Jellyfin ဆာဗာကို ဖွင့်နေပါသည်။ ခဏနေ ထပ်စမ်းကြည့်ပါ။", + "Songs": "သီချင်းများ", + "Shows": "ရှိုးပွဲ", + "ServerNameNeedsToBeRestarted": "{0} ကို ပြန်လည်စတင်ရန် လိုအပ်သည်။", + "ScheduledTaskStartedWithName": "{0} စတင်ခဲ့သည်။", + "ScheduledTaskFailedWithName": "{0} မအောင်မြင်ပါ။", + "ProviderValue": "ဝန်ဆောင်မှုပေးသူ- {0}", + "PluginUpdatedWithName": "{0} ကို အပ်ဒိတ်လုပ်ထားသည်။", + "PluginUninstalledWithName": "{0} ကို ဖြုတ်လိုက်ပါပြီ။", + "PluginInstalledWithName": "{0} ကို ထည့်သွင်းခဲ့သည်။", + "Plugin": "ပလပ်အင်", + "Playlists": "အစီအစဉ်များ", + "Photos": "ဓာတ်ပုံများ", + "NotificationOptionVideoPlaybackStopped": "ဗီဒီယိုပြန်ဖွင့်ခြင်းကို ရပ်သွားသည်။", + "NotificationOptionVideoPlayback": "ဗီဒီယိုဖွင့်ခြင်း စတင်ပါပြီ။", + "NotificationOptionUserLockedOut": "အသုံးပြုသူ ထွက်သွားသည်။", + "NotificationOptionTaskFailed": "စီစဉ်ထားသော အလုပ်ပျက်ကွက်", + "NotificationOptionServerRestartRequired": "ဆာဗာ ပြန်လည်စတင်ရန် လိုအပ်သည်။", + "NotificationOptionPluginUpdateInstalled": "ပလပ်အင် အပ်ဒိတ် ထည့်သွင်းပြီးပါပြီ။", + "NotificationOptionPluginUninstalled": "ပလပ်အင်ကို ဖြုတ်လိုက်ပါပြီ။", + "NotificationOptionPluginInstalled": "ပလပ်အင် ထည့်သွင်းထားသည်။", + "NotificationOptionPluginError": "ပလပ်အင် ချို့ယွင်းခြင်း။", + "NotificationOptionNewLibraryContent": "အကြောင်းအရာအသစ် ထပ်ထည့်ထားပါတယ်။", + "NotificationOptionInstallationFailed": "တပ်ဆင်မှု မအောင်မြင်ပါ။", + "NotificationOptionCameraImageUploaded": "ကင်မရာပုံ အပ်လုဒ်လုပ်ထားသည်။", + "NotificationOptionAudioPlaybackStopped": "အသံပြန်ဖွင့်ခြင်းကို ရပ်သွားသည်။", + "NotificationOptionAudioPlayback": "အသံပြန်ဖွင့်ခြင်း စတင်ပါပြီ။", + "NotificationOptionApplicationUpdateInstalled": "အပလီကေးရှင်း အပ်ဒိတ်ကို ထည့်သွင်းထားသည်။", + "NotificationOptionApplicationUpdateAvailable": "အပလီကေးရှင်း အပ်ဒိတ် ရနိုင်ပါပြီ။", + "NewVersionIsAvailable": "Jellyfin Server ၏ ဗားရှင်းအသစ်ကို ဒေါင်းလုဒ်လုပ်နိုင်ပါသည်။", + "NameSeasonUnknown": "အမည််မသိ ဇာတ်လမ်းတွဲ", + "NameSeasonNumber": "ဇာတ်လမ်းတွဲ {0}", + "NameInstallFailed": "{0} ထည့်သွင်းမှု မအောင်မြင်ပါ။", + "MusicVideos": "ဂီတဗီဒီယိုများ", + "Music": "တေးဂီတ", + "Movies": "ရုပ်ရှင်များ", + "MixedContent": "ရောနှောပါဝင်မှု", + "MessageServerConfigurationUpdated": "ဆာဗာဖွဲ့စည်းပုံကို အပ်ဒိတ်လုပ်ပြီးပါပြီ။", + "MessageNamedServerConfigurationUpdatedWithValue": "ဆာဗာဖွဲ့စည်းပုံကဏ္ဍ {0} ကို အပ်ဒိတ်လုပ်ပြီးပါပြီ။", + "MessageApplicationUpdatedTo": "Jellyfin ဆာဗာကို {0} သို့ အပ်ဒိတ်လုပ်ထားသည်", + "MessageApplicationUpdated": "Jellyfin ဆာဗာကို အပ်ဒိတ်လုပ်ပြီးပါပြီ။", + "Latest": "နောက်ဆုံး", + "LabelRunningTimeValue": "လည်ပတ်ချိန်- {0}", + "LabelIpAddressValue": "IP လိပ်စာ- {0}", + "ItemRemovedWithName": "{0} ကို ဒစ်ဂျစ်တိုက်မှ ဖယ်ရှားခဲ့သည်။", + "ItemAddedWithName": "{0} ကို စာကြည့်တိုက်သို့ ထည့်ထားသည်။", + "Inherit": "ဆက်လက် လုပ်ဆောင်သည်။", + "HomeVideos": "ပင်မဗီဒီယိုများ", + "HeaderRecordingGroups": "အသံဖမ်းအဖွဲ့များ", + "HeaderNextUp": "နောက်ထပ်", + "HeaderLiveTV": "Live TV", + "HeaderFavoriteSongs": "အကြိုက်ဆုံးသီချင်းများ", + "HeaderFavoriteShows": "အကြိုက်ဆုံးရှိုးများ", + "HeaderFavoriteEpisodes": "အကြိုက်ဆုံးအပိုင်းများ", + "HeaderFavoriteArtists": "အကြိုက်ဆုံးအနုပညာရှင်များ", + "HeaderFavoriteAlbums": "အကြိုက်ဆုံး အယ်လ်ဘမ်များ", + "HeaderContinueWatching": "ဆက်လက်ကြည့်ရှုပါ။", + "HeaderAlbumArtists": "အယ်လ်ဘမ်အနုပညာရှင်များ", + "Genres": "အမျိုးအစားများ", + "Forced": "အတင်းအကြပ်", + "Folders": "ဖိုဒါများ", + "Favorites": "အကြိုက်ဆုံးများ", + "FailedLoginAttemptWithUserName": "{0} မှ အကောင့်ဝင်ရန် မအောင်မြင်ပါ", + "DeviceOnlineWithName": "{0} ကို ချိတ်ဆက်ထားသည်။", + "DeviceOfflineWithName": "{0} နှင့် အဆက်ပြတ်သွားပါပြီ။", + "ChapterNameValue": "အခန်း {0}", + "CameraImageUploadedFrom": "ကင်မရာပုံအသစ်ကို {0} မှ အပ်လုဒ်လုပ်ထားသည်", + "AuthenticationSucceededWithUserName": "{0} စစ်မှန်ကြောင်း အောင်မြင်စွာ အတည်ပြုပြီးပါပြီ။", + "Application": "အပလီကေးရှင်း", + "AppDeviceValues": "အက်ပ်- {0}၊ စက်- {1}" +} diff --git a/Emby.Server.Implementations/Localization/Core/vi.json b/Emby.Server.Implementations/Localization/Core/vi.json index b7ece8d5f..d80f1760d 100644 --- a/Emby.Server.Implementations/Localization/Core/vi.json +++ b/Emby.Server.Implementations/Localization/Core/vi.json @@ -13,7 +13,7 @@ "Songs": "Bài Hát", "Sync": "Đồng Bộ", "ValueSpecialEpisodeName": "Đặc Biệt - {0}", - "Albums": "Tuyển Tập", + "Albums": "", "Artists": "Ca Sĩ", "TaskDownloadMissingSubtitlesDescription": "Tìm kiếm phụ đề bị thiếu trên Internet dựa trên cấu hình dữ liệu mô tả.", "TaskDownloadMissingSubtitles": "Tải Xuống Phụ Đề Bị Thiếu", diff --git a/Jellyfin.Api/Controllers/ItemsController.cs b/Jellyfin.Api/Controllers/ItemsController.cs index 1b938f4d5..f8192955e 100644 --- a/Jellyfin.Api/Controllers/ItemsController.cs +++ b/Jellyfin.Api/Controllers/ItemsController.cs @@ -228,9 +228,7 @@ namespace Jellyfin.Api.Controllers [FromQuery] bool enableTotalRecordCount = true, [FromQuery] bool? enableImages = true) { - var user = !userId.Equals(Guid.Empty) - ? _userManager.GetUserById(userId) - : null; + var user = userId == Guid.Empty ? null : _userManager.GetUserById(userId); var dtoOptions = new DtoOptions { Fields = fields } .AddClientFields(Request) .AddAdditionalDtoOptions(enableImages, enableUserData, imageTypeLimit, enableImageTypes); diff --git a/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs b/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs index d6f69a150..9c96d2472 100644 --- a/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs +++ b/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs @@ -1278,7 +1278,7 @@ namespace MediaBrowser.Controller.MediaEncoding param += " -pix_fmt nv21"; } - var isVc1 = string.Equals(state.VideoStream.Codec, "vc1", StringComparison.OrdinalIgnoreCase); + var isVc1 = string.Equals(state.VideoStream?.Codec, "vc1", StringComparison.OrdinalIgnoreCase); var isLibX265 = string.Equals(videoEncoder, "libx265", StringComparison.OrdinalIgnoreCase); if (string.Equals(videoEncoder, "libx264", StringComparison.OrdinalIgnoreCase) || isLibX265) diff --git a/MediaBrowser.Model/Dlna/StreamBuilder.cs b/MediaBrowser.Model/Dlna/StreamBuilder.cs index 84a6f6abe..d2ca21150 100644 --- a/MediaBrowser.Model/Dlna/StreamBuilder.cs +++ b/MediaBrowser.Model/Dlna/StreamBuilder.cs @@ -1236,7 +1236,7 @@ namespace MediaBrowser.Model.Dlna return (false, TranscodeReason.ContainerBitrateExceedsLimit); } - if (audioStream.IsExternal) + if (audioStream?.IsExternal == true) { return (false, TranscodeReason.AudioIsExternal); } diff --git a/MediaBrowser.Providers/TV/SeasonMetadataService.cs b/MediaBrowser.Providers/TV/SeasonMetadataService.cs index b173fc7a3..1f06cbdb2 100644 --- a/MediaBrowser.Providers/TV/SeasonMetadataService.cs +++ b/MediaBrowser.Providers/TV/SeasonMetadataService.cs @@ -35,7 +35,7 @@ namespace MediaBrowser.Providers.TV { var updatedType = base.BeforeSaveInternal(item, isFullRefresh, updateType); - if (item.IndexNumber.HasValue && item.IndexNumber.Value == 0) + if (item.IndexNumber == 0 && !item.IsLocked && !item.LockedFields.Contains(MetadataField.Name)) { var seasonZeroDisplayName = LibraryManager.GetLibraryOptions(item).SeasonZeroDisplayName; @@ -85,7 +85,7 @@ These instructions will help you get set up with a local development environment Before the project can be built, you must first install the [.NET 6.0 SDK](https://dotnet.microsoft.com/download/dotnet) on your system. -Instructions to run this project from the command line are included here, but you will also need to install an IDE if you want to debug the server while it is running. Any IDE that supports .NET Core development will work, but two options are recent versions of [Visual Studio](https://visualstudio.microsoft.com/downloads/) (at least 2017) and [Visual Studio Code](https://code.visualstudio.com/Download). +Instructions to run this project from the command line are included here, but you will also need to install an IDE if you want to debug the server while it is running. Any IDE that supports .NET 6 development will work, but two options are recent versions of [Visual Studio](https://visualstudio.microsoft.com/downloads/) (at least 2022) and [Visual Studio Code](https://code.visualstudio.com/Download). [ffmpeg](https://github.com/jellyfin/jellyfin-ffmpeg) will also need to be installed. @@ -138,10 +138,10 @@ A second option is to build the project and then run the resulting executable fi 1. Build the project - ```bash - dotnet build # Build the project - cd bin/Debug/net5.0 # Change into the build output directory - ``` +```bash +dotnet build # Build the project +cd Jellyfin.Server/bin/Debug/net6.0 # Change into the build output directory +``` 2. Execute the build output. On Linux, Mac, etc. use `./jellyfin` and on Windows use `jellyfin.exe`. diff --git a/jellyfin.ruleset b/jellyfin.ruleset index e9293588c..52bedabee 100644 --- a/jellyfin.ruleset +++ b/jellyfin.ruleset @@ -11,6 +11,8 @@ <Rule Id="SA1142" Action="Error" /> <!-- error on SA1210: Using directives should be ordered alphabetically by the namespaces --> <Rule Id="SA1210" Action="Error" /> + <!-- error on SA1316: Tuple element names should use correct casing --> + <Rule Id="SA1316" Action="Error" /> <!-- error on SA1518: File is required to end with a single newline character --> <Rule Id="SA1518" Action="Error" /> <!-- error on SA1629: Documentation text should end with a period --> diff --git a/tests/Jellyfin.Naming.Tests/TV/AbsoluteEpisodeNumberTests.cs b/tests/Jellyfin.Naming.Tests/TV/AbsoluteEpisodeNumberTests.cs index 356ba216d..e81c5152e 100644 --- a/tests/Jellyfin.Naming.Tests/TV/AbsoluteEpisodeNumberTests.cs +++ b/tests/Jellyfin.Naming.Tests/TV/AbsoluteEpisodeNumberTests.cs @@ -6,6 +6,8 @@ namespace Jellyfin.Naming.Tests.TV { public class AbsoluteEpisodeNumberTests { + private readonly EpisodeResolver _resolver = new EpisodeResolver(new NamingOptions()); + [Theory] [InlineData("The Simpsons/12.avi", 12)] [InlineData("The Simpsons/The Simpsons 12.avi", 12)] @@ -16,10 +18,7 @@ namespace Jellyfin.Naming.Tests.TV [InlineData("The Simpsons/The Simpsons 101.avi", 101)] public void GetEpisodeNumberFromFileTest(string path, int episodeNumber) { - var options = new NamingOptions(); - - var result = new EpisodeResolver(options) - .Resolve(path, false, null, null, true); + var result = _resolver.Resolve(path, false, null, null, true); Assert.Equal(episodeNumber, result?.EpisodeNumber); } diff --git a/tests/Jellyfin.Naming.Tests/TV/DailyEpisodeTests.cs b/tests/Jellyfin.Naming.Tests/TV/DailyEpisodeTests.cs index 2937914b9..72052a23c 100644 --- a/tests/Jellyfin.Naming.Tests/TV/DailyEpisodeTests.cs +++ b/tests/Jellyfin.Naming.Tests/TV/DailyEpisodeTests.cs @@ -6,6 +6,8 @@ namespace Jellyfin.Naming.Tests.TV { public class DailyEpisodeTests { + private readonly EpisodeResolver _resolver = new EpisodeResolver(new NamingOptions()); + [Theory] [InlineData(@"/server/anything_1996.11.14.mp4", "anything", 1996, 11, 14)] [InlineData(@"/server/anything_1996-11-14.mp4", "anything", 1996, 11, 14)] @@ -16,10 +18,7 @@ namespace Jellyfin.Naming.Tests.TV // TODO: [InlineData(@"/server/Last Man Standing_KTLADT_2018_05_25_01_28_00.wtv", "Last Man Standing", 2018, 05, 25)] public void Test(string path, string seriesName, int? year, int? month, int? day) { - var options = new NamingOptions(); - - var result = new EpisodeResolver(options) - .Resolve(path, false); + var result = _resolver.Resolve(path, false); Assert.Null(result?.SeasonNumber); Assert.Null(result?.EpisodeNumber); diff --git a/tests/Jellyfin.Naming.Tests/TV/EpisodeNumberWithoutSeasonTests.cs b/tests/Jellyfin.Naming.Tests/TV/EpisodeNumberWithoutSeasonTests.cs index 8bd1a43d6..1da5a30a8 100644 --- a/tests/Jellyfin.Naming.Tests/TV/EpisodeNumberWithoutSeasonTests.cs +++ b/tests/Jellyfin.Naming.Tests/TV/EpisodeNumberWithoutSeasonTests.cs @@ -6,6 +6,8 @@ namespace Jellyfin.Naming.Tests.TV { public class EpisodeNumberWithoutSeasonTests { + private readonly EpisodeResolver _resolver = new EpisodeResolver(new NamingOptions()); + [Theory] [InlineData(8, @"The Simpsons/The Simpsons.S25E08.Steal this episode.mp4")] [InlineData(2, @"The Simpsons/The Simpsons - 02 - Ep Name.avi")] @@ -24,10 +26,7 @@ namespace Jellyfin.Naming.Tests.TV // TODO: [InlineData(13, @"Case Closed (1996-2007)/Case Closed - 13.mkv")] public void GetEpisodeNumberFromFileTest(int episodeNumber, string path) { - var options = new NamingOptions(); - - var result = new EpisodeResolver(options) - .Resolve(path, false); + var result = _resolver.Resolve(path, false); Assert.Equal(episodeNumber, result?.EpisodeNumber); } diff --git a/tests/Jellyfin.Naming.Tests/TV/EpisodePathParserTest.cs b/tests/Jellyfin.Naming.Tests/TV/EpisodePathParserTest.cs index 12fc19bc4..af219b118 100644 --- a/tests/Jellyfin.Naming.Tests/TV/EpisodePathParserTest.cs +++ b/tests/Jellyfin.Naming.Tests/TV/EpisodePathParserTest.cs @@ -6,6 +6,8 @@ namespace Jellyfin.Naming.Tests.TV { public class EpisodePathParserTest { + private readonly NamingOptions _namingOptions = new NamingOptions(); + [Theory] [InlineData("/media/Foo/Foo-S01E01", true, "Foo", 1, 1)] [InlineData("/media/Foo - S04E011", true, "Foo", 4, 11)] @@ -36,8 +38,7 @@ namespace Jellyfin.Naming.Tests.TV // TODO: [InlineData("/The.Legend.of.Condor.Heroes.2017.V2.web-dl.1080p.h264.aac-hdctv/The.Legend.of.Condor.Heroes.2017.E07.V2.web-dl.1080p.h264.aac-hdctv.mkv", "The Legend of Condor Heroes 2017", 1, 7)] public void ParseEpisodesCorrectly(string path, bool isDirectory, string name, int season, int episode) { - NamingOptions o = new NamingOptions(); - EpisodePathParser p = new EpisodePathParser(o); + EpisodePathParser p = new EpisodePathParser(_namingOptions); var res = p.Parse(path, isDirectory); Assert.True(res.Success); @@ -50,8 +51,7 @@ namespace Jellyfin.Naming.Tests.TV [InlineData("/test/01-03.avi", true, true)] public void EpisodePathParserTest_DifferentExpressionsParameters(string path, bool? isNamed, bool? isOptimistic) { - NamingOptions o = new NamingOptions(); - EpisodePathParser p = new EpisodePathParser(o); + EpisodePathParser p = new EpisodePathParser(_namingOptions); var res = p.Parse(path, false, isNamed, isOptimistic); Assert.True(res.Success); @@ -60,8 +60,7 @@ namespace Jellyfin.Naming.Tests.TV [Fact] public void EpisodePathParserTest_FalsePositivePixelRate() { - NamingOptions o = new NamingOptions(); - EpisodePathParser p = new EpisodePathParser(o); + EpisodePathParser p = new EpisodePathParser(_namingOptions); var res = p.Parse("Series Special (1920x1080).mkv", false); Assert.False(res.Success); @@ -70,14 +69,14 @@ namespace Jellyfin.Naming.Tests.TV [Fact] public void EpisodeResolverTest_WrongExtension() { - var res = new EpisodeResolver(new NamingOptions()).Resolve("test.mp3", false); + var res = new EpisodeResolver(_namingOptions).Resolve("test.mp3", false); Assert.Null(res); } [Fact] public void EpisodeResolverTest_WrongExtensionStub() { - var res = new EpisodeResolver(new NamingOptions()).Resolve("dvd.disc", false); + var res = new EpisodeResolver(_namingOptions).Resolve("dvd.disc", false); Assert.NotNull(res); Assert.True(res!.IsStub); } diff --git a/tests/Jellyfin.Naming.Tests/TV/EpisodeWithoutSeasonTests.cs b/tests/Jellyfin.Naming.Tests/TV/EpisodeWithoutSeasonTests.cs deleted file mode 100644 index d0418a49e..000000000 --- a/tests/Jellyfin.Naming.Tests/TV/EpisodeWithoutSeasonTests.cs +++ /dev/null @@ -1,27 +0,0 @@ -using Emby.Naming.Common; -using Emby.Naming.TV; -using Xunit; - -namespace Jellyfin.Naming.Tests.TV -{ - public class EpisodeWithoutSeasonTests - { - // TODO: [Theory] - // TODO: [InlineData(@"/server/anything_ep02.mp4", "anything", null, 2)] - // TODO: [InlineData(@"/server/anything_ep_02.mp4", "anything", null, 2)] - // TODO: [InlineData(@"/server/anything_part.II.mp4", "anything", null, null)] - // TODO: [InlineData(@"/server/anything_pt.II.mp4", "anything", null, null)] - // TODO: [InlineData(@"/server/anything_pt_II.mp4", "anything", null, null)] - public void Test(string path, string seriesName, int? seasonNumber, int? episodeNumber) - { - var options = new NamingOptions(); - - var result = new EpisodeResolver(options) - .Resolve(path, false); - - Assert.Equal(seasonNumber, result?.SeasonNumber); - Assert.Equal(episodeNumber, result?.EpisodeNumber); - Assert.Equal(seriesName, result?.SeriesName, ignoreCase: true); - } - } -} diff --git a/tests/Jellyfin.Naming.Tests/TV/MultiEpisodeTests.cs b/tests/Jellyfin.Naming.Tests/TV/MultiEpisodeTests.cs index 58ea0bec5..ffaa64c3f 100644 --- a/tests/Jellyfin.Naming.Tests/TV/MultiEpisodeTests.cs +++ b/tests/Jellyfin.Naming.Tests/TV/MultiEpisodeTests.cs @@ -6,6 +6,8 @@ namespace Jellyfin.Naming.Tests.TV { public class MultiEpisodeTests { + private readonly EpisodePathParser _episodePathParser = new EpisodePathParser(new NamingOptions()); + [Theory] [InlineData(@"Season 1/4x01 – 20 Hours in America (1).mkv", null)] [InlineData(@"Season 1/01x02 blah.avi", null)] @@ -69,10 +71,7 @@ namespace Jellyfin.Naming.Tests.TV [InlineData(@"Season 1/MOONLIGHTING_s01e01-e04", 4)] public void TestGetEndingEpisodeNumberFromFile(string filename, int? endingEpisodeNumber) { - var options = new NamingOptions(); - - var result = new EpisodePathParser(options) - .Parse(filename, false); + var result = _episodePathParser.Parse(filename, false); Assert.Equal(result.EndingEpisodeNumber, endingEpisodeNumber); } diff --git a/tests/Jellyfin.Naming.Tests/TV/SeasonNumberTests.cs b/tests/Jellyfin.Naming.Tests/TV/SeasonNumberTests.cs index 4837e3a3b..58ec1b5d2 100644 --- a/tests/Jellyfin.Naming.Tests/TV/SeasonNumberTests.cs +++ b/tests/Jellyfin.Naming.Tests/TV/SeasonNumberTests.cs @@ -6,7 +6,7 @@ namespace Jellyfin.Naming.Tests.TV { public class SeasonNumberTests { - private readonly NamingOptions _namingOptions = new NamingOptions(); + private readonly EpisodeResolver _resolver = new EpisodeResolver(new NamingOptions()); [Theory] [InlineData("The Daily Show/The Daily Show 25x22 - [WEBDL-720p][AAC 2.0][x264] Noah Baumbach-TBS.mkv", 25)] @@ -56,8 +56,7 @@ namespace Jellyfin.Naming.Tests.TV // TODO: [InlineData(@"Seinfeld/Seinfeld 0807 The Checks.avi", 8)] public void GetSeasonNumberFromEpisodeFileTest(string path, int? expected) { - var result = new EpisodeResolver(_namingOptions) - .Resolve(path, false); + var result = _resolver.Resolve(path, false); Assert.Equal(expected, result?.SeasonNumber); } diff --git a/tests/Jellyfin.Naming.Tests/TV/SeriesPathParserTest.cs b/tests/Jellyfin.Naming.Tests/TV/SeriesPathParserTest.cs index ceb5f8b73..e6b0409db 100644 --- a/tests/Jellyfin.Naming.Tests/TV/SeriesPathParserTest.cs +++ b/tests/Jellyfin.Naming.Tests/TV/SeriesPathParserTest.cs @@ -6,6 +6,8 @@ namespace Jellyfin.Naming.Tests.TV { public class SeriesPathParserTest { + private readonly NamingOptions _namingOptions = new NamingOptions(); + [Theory] [InlineData("The.Show.S01", "The.Show")] [InlineData("/The.Show.S01", "The.Show")] @@ -18,8 +20,7 @@ namespace Jellyfin.Naming.Tests.TV [InlineData("/something/The Show/S01", "The Show")] public void SeriesPathParserParseTest(string path, string name) { - NamingOptions o = new NamingOptions(); - var res = SeriesPathParser.Parse(o, path); + var res = SeriesPathParser.Parse(_namingOptions, path); Assert.Equal(name, res.SeriesName); Assert.True(res.Success); diff --git a/tests/Jellyfin.Naming.Tests/TV/SeriesResolverTests.cs b/tests/Jellyfin.Naming.Tests/TV/SeriesResolverTests.cs index 97f4b4058..84758c9c3 100644 --- a/tests/Jellyfin.Naming.Tests/TV/SeriesResolverTests.cs +++ b/tests/Jellyfin.Naming.Tests/TV/SeriesResolverTests.cs @@ -6,6 +6,8 @@ namespace Jellyfin.Naming.Tests.TV { public class SeriesResolverTests { + private readonly NamingOptions _namingOptions = new NamingOptions(); + [Theory] [InlineData("The.Show.S01", "The Show")] [InlineData("The.Show.S01.COMPLETE", "The Show")] @@ -19,8 +21,7 @@ namespace Jellyfin.Naming.Tests.TV [InlineData("/some/path/The Show s02e10 the episode 720p hdtv", "The Show")] public void SeriesResolverResolveTest(string path, string name) { - NamingOptions o = new NamingOptions(); - var res = SeriesResolver.Resolve(o, path); + var res = SeriesResolver.Resolve(_namingOptions, path); Assert.Equal(name, res.Name); } diff --git a/tests/Jellyfin.Naming.Tests/TV/SimpleEpisodeTests.cs b/tests/Jellyfin.Naming.Tests/TV/SimpleEpisodeTests.cs index 6d49ac832..fa46ecc3a 100644 --- a/tests/Jellyfin.Naming.Tests/TV/SimpleEpisodeTests.cs +++ b/tests/Jellyfin.Naming.Tests/TV/SimpleEpisodeTests.cs @@ -7,6 +7,8 @@ namespace Jellyfin.Naming.Tests.TV { public class SimpleEpisodeTests { + private readonly EpisodeResolver _resolver = new EpisodeResolver(new NamingOptions()); + [Theory] [InlineData("/server/anything_s01e02.mp4", "anything", 1, 2)] [InlineData("/server/anything_s1e2.mp4", "anything", 1, 2)] @@ -23,39 +25,25 @@ namespace Jellyfin.Naming.Tests.TV [InlineData(@"Love.Death.and.Robots.S01.1080p.NF.WEB-DL.DDP5.1.x264-NTG/Love.Death.and.Robots.S01E01.Sonnies.Edge.1080p.NF.WEB-DL.DDP5.1.x264-NTG.mkv", "Love.Death.and.Robots", 1, 1)] [InlineData("[YuiSubs] Tensura Nikki - Tensei Shitara Slime Datta Ken/[YuiSubs] Tensura Nikki - Tensei Shitara Slime Datta Ken - 12 (NVENC H.265 1080p).mkv", "Tensura Nikki - Tensei Shitara Slime Datta Ken", null, 12)] [InlineData("[Baz-Bar]Foo - 01 - 12[1080p][Multiple Subtitle]/[Baz-Bar] Foo - 05 [1080p][Multiple Subtitle].mkv", "Foo", null, 5)] + [InlineData("Series/4-12 - The Woman.mp4", "", 4, 12, 12)] // TODO: [InlineData("E:\\Anime\\Yahari Ore no Seishun Love Comedy wa Machigatteiru\\Yahari Ore no Seishun Love Comedy wa Machigatteiru. Zoku\\Oregairu Zoku 11 - Hayama Hayato Always Renconds to Everyone's Expectations..mkv", "Yahari Ore no Seishun Love Comedy wa Machigatteiru", null, 11)] // TODO: [InlineData(@"/Library/Series/The Grand Tour (2016)/Season 1/S01E01 The Holy Trinity.mkv", "The Grand Tour", 1, 1)] - public void TestSimple(string path, string seriesName, int? seasonNumber, int? episodeNumber) + public void TestSimple(string path, string seriesName, int? seasonNumber, int? episodeNumber, int? episodeEndNumber = null) { - Test(path, seriesName, seasonNumber, episodeNumber, null); - } - - [Theory] - [InlineData("Series/4-12 - The Woman.mp4", "", 4, 12, 12)] - public void TestWithPossibleEpisodeEnd(string path, string seriesName, int? seasonNumber, int? episodeNumber, int? episodeEndNumber) - { - Test(path, seriesName, seasonNumber, episodeNumber, episodeEndNumber); - } - - private void Test(string path, string seriesName, int? seasonNumber, int? episodeNumber, int? episodeEndNumber) - { - var options = new NamingOptions(); - - var result = new EpisodeResolver(options) - .Resolve(path, false); + var result = _resolver.Resolve(path, false); Assert.NotNull(result); - Assert.Equal(seasonNumber, result?.SeasonNumber); - Assert.Equal(episodeNumber, result?.EpisodeNumber); - Assert.Equal(seriesName, result?.SeriesName, true); - Assert.Equal(path, result?.Path); + Assert.Equal(seasonNumber, result!.SeasonNumber); + Assert.Equal(episodeNumber, result!.EpisodeNumber); + Assert.Equal(seriesName, result!.SeriesName, true); + Assert.Equal(path, result!.Path); Assert.Equal(Path.GetExtension(path).Substring(1), result?.Container); - Assert.Null(result?.Format3D); - Assert.False(result?.Is3D); - Assert.False(result?.IsStub); - Assert.Null(result?.StubType); - Assert.Equal(episodeEndNumber, result?.EndingEpisodeNumber); - Assert.False(result?.IsByDate); + Assert.Null(result!.Format3D); + Assert.False(result!.Is3D); + Assert.False(result!.IsStub); + Assert.Null(result!.StubType); + Assert.Equal(episodeEndNumber, result!.EndingEpisodeNumber); + Assert.False(result!.IsByDate); } } } |
