mirror of
				https://github.com/jellyfin/jellyfin.git
				synced 2025-11-03 19:17:24 -05:00 
			
		
		
		
	Merge remote-tracking branch 'upstream/master' into NetworkPR2
This commit is contained in:
		
						commit
						b04aed2f58
					
				@ -198,3 +198,4 @@
 | 
				
			|||||||
 - [tikuf](https://github.com/tikuf/)
 | 
					 - [tikuf](https://github.com/tikuf/)
 | 
				
			||||||
 - [Tim Hobbs](https://github.com/timhobbs)
 | 
					 - [Tim Hobbs](https://github.com/timhobbs)
 | 
				
			||||||
 - [SvenVandenbrande](https://github.com/SvenVandenbrande)
 | 
					 - [SvenVandenbrande](https://github.com/SvenVandenbrande)
 | 
				
			||||||
 | 
					 - [olsh](https://github.com/olsh)
 | 
				
			||||||
 | 
				
			|||||||
@ -455,7 +455,7 @@ namespace Emby.Drawing
 | 
				
			|||||||
                throw new ArgumentException("Path can't be empty.", nameof(path));
 | 
					                throw new ArgumentException("Path can't be empty.", nameof(path));
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            if (path.IsEmpty)
 | 
					            if (filename.IsEmpty)
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
                throw new ArgumentException("Filename can't be empty.", nameof(filename));
 | 
					                throw new ArgumentException("Filename can't be empty.", nameof(filename));
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
				
			|||||||
@ -50,27 +50,14 @@ namespace Emby.Naming.AudioBook
 | 
				
			|||||||
                        {
 | 
					                        {
 | 
				
			||||||
                            if (int.TryParse(value.Value, NumberStyles.Integer, CultureInfo.InvariantCulture, out var intValue))
 | 
					                            if (int.TryParse(value.Value, NumberStyles.Integer, CultureInfo.InvariantCulture, out var intValue))
 | 
				
			||||||
                            {
 | 
					                            {
 | 
				
			||||||
                                result.ChapterNumber = intValue;
 | 
					                                result.PartNumber = intValue;
 | 
				
			||||||
                            }
 | 
					                            }
 | 
				
			||||||
                        }
 | 
					                        }
 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            /*var matches = _iRegexProvider.GetRegex("\\d+", RegexOptions.IgnoreCase).Matches(fileName);
 | 
					            result.Success = result.ChapterNumber.HasValue || result.PartNumber.HasValue;
 | 
				
			||||||
            if (matches.Count > 0)
 | 
					 | 
				
			||||||
            {
 | 
					 | 
				
			||||||
                if (!result.ChapterNumber.HasValue)
 | 
					 | 
				
			||||||
                {
 | 
					 | 
				
			||||||
                    result.ChapterNumber = int.Parse(matches[0].Groups[0].Value);
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                if (matches.Count > 1)
 | 
					 | 
				
			||||||
                {
 | 
					 | 
				
			||||||
                    result.PartNumber = int.Parse(matches[matches.Count - 1].Groups[0].Value);
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
            }*/
 | 
					 | 
				
			||||||
            result.Success = result.PartNumber.HasValue || result.ChapterNumber.HasValue;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
            return result;
 | 
					            return result;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
				
			|||||||
@ -55,8 +55,8 @@ namespace Emby.Naming.AudioBook
 | 
				
			|||||||
            {
 | 
					            {
 | 
				
			||||||
                Path = path,
 | 
					                Path = path,
 | 
				
			||||||
                Container = container,
 | 
					                Container = container,
 | 
				
			||||||
                PartNumber = parsingResult.PartNumber,
 | 
					 | 
				
			||||||
                ChapterNumber = parsingResult.ChapterNumber,
 | 
					                ChapterNumber = parsingResult.ChapterNumber,
 | 
				
			||||||
 | 
					                PartNumber = parsingResult.PartNumber,
 | 
				
			||||||
                IsDirectory = isDirectory
 | 
					                IsDirectory = isDirectory
 | 
				
			||||||
            };
 | 
					            };
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										117
									
								
								Emby.Server.Implementations/Localization/Core/sq.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										117
									
								
								Emby.Server.Implementations/Localization/Core/sq.json
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,117 @@
 | 
				
			|||||||
 | 
					{
 | 
				
			||||||
 | 
					    "MessageApplicationUpdatedTo": "Serveri Jellyfin u përditesua në versionin {0}",
 | 
				
			||||||
 | 
					    "Inherit": "Trashgimi",
 | 
				
			||||||
 | 
					    "TaskDownloadMissingSubtitlesDescription": "Kërkon në internet për titra që mungojnë bazuar tek konfigurimi i metadata-ve.",
 | 
				
			||||||
 | 
					    "TaskDownloadMissingSubtitles": "Shkarko titra që mungojnë",
 | 
				
			||||||
 | 
					    "TaskRefreshChannelsDescription": "Rifreskon informacionin e kanaleve të internetit.",
 | 
				
			||||||
 | 
					    "TaskRefreshChannels": "Rifresko Kanalet",
 | 
				
			||||||
 | 
					    "TaskCleanTranscodeDescription": "Fshin skedarët e transkodimit që janë më të vjetër se një ditë.",
 | 
				
			||||||
 | 
					    "TaskCleanTranscode": "Fshi dosjen e transkodimit",
 | 
				
			||||||
 | 
					    "TaskUpdatePluginsDescription": "Shkarkon dhe instalon përditësimi për plugin që janë konfiguruar të përditësohen automatikisht.",
 | 
				
			||||||
 | 
					    "TaskUpdatePlugins": "Përditëso Plugin",
 | 
				
			||||||
 | 
					    "TaskRefreshPeopleDescription": "Përditëson metadata të aktorëve dhe regjizorëve në librarinë tuaj.",
 | 
				
			||||||
 | 
					    "TaskRefreshPeople": "Rifresko aktorët",
 | 
				
			||||||
 | 
					    "TaskCleanLogsDescription": "Fshin skëdarët log që janë më të vjetër se {0} ditë.",
 | 
				
			||||||
 | 
					    "TaskCleanLogs": "Fshi dosjen Log",
 | 
				
			||||||
 | 
					    "TaskRefreshLibraryDescription": "Skanon librarinë media për skedarë të rinj dhe rifreskon metadata.",
 | 
				
			||||||
 | 
					    "TaskRefreshLibrary": "Skano librarinë media",
 | 
				
			||||||
 | 
					    "TaskRefreshChapterImagesDescription": "Krijon imazh për videot që kanë kapituj.",
 | 
				
			||||||
 | 
					    "TaskRefreshChapterImages": "Ekstrakto Imazhet e Kapitullit",
 | 
				
			||||||
 | 
					    "TaskCleanCacheDescription": "Fshi skedarët e cache-s që nuk i duhen më sistemit.",
 | 
				
			||||||
 | 
					    "TaskCleanCache": "Pastro memorjen cache",
 | 
				
			||||||
 | 
					    "TasksChannelsCategory": "Kanalet nga interneti",
 | 
				
			||||||
 | 
					    "TasksApplicationCategory": "Aplikacioni",
 | 
				
			||||||
 | 
					    "TasksLibraryCategory": "Libraria",
 | 
				
			||||||
 | 
					    "TasksMaintenanceCategory": "Mirëmbajtje",
 | 
				
			||||||
 | 
					    "VersionNumber": "Versioni {0}",
 | 
				
			||||||
 | 
					    "ValueSpecialEpisodeName": "Speciale - {0}",
 | 
				
			||||||
 | 
					    "ValueHasBeenAddedToLibrary": "{0} u shtua tek libraria juaj",
 | 
				
			||||||
 | 
					    "UserStoppedPlayingItemWithValues": "{0} mbaroi së shikuari {1} tek {2}",
 | 
				
			||||||
 | 
					    "UserStartedPlayingItemWithValues": "{0} po shikon {1} tek {2}",
 | 
				
			||||||
 | 
					    "UserPolicyUpdatedWithName": "Politika e përdoruesit u përditësua për {0}",
 | 
				
			||||||
 | 
					    "UserPasswordChangedWithName": "Fjalëkalimi u ndryshua për përdoruesin {0}",
 | 
				
			||||||
 | 
					    "UserOnlineFromDevice": "{0} është në linjë nga {1}",
 | 
				
			||||||
 | 
					    "UserOfflineFromDevice": "{0} u shkëput nga {1}",
 | 
				
			||||||
 | 
					    "UserLockedOutWithName": "Përdoruesi {0} u përjashtua",
 | 
				
			||||||
 | 
					    "UserDownloadingItemWithValues": "{0} po shkarkon {1}",
 | 
				
			||||||
 | 
					    "UserDeletedWithName": "Përdoruesi {0} u fshi",
 | 
				
			||||||
 | 
					    "UserCreatedWithName": "Përdoruesi {0} u krijua",
 | 
				
			||||||
 | 
					    "User": "Përdoruesi",
 | 
				
			||||||
 | 
					    "TvShows": "Seriale TV",
 | 
				
			||||||
 | 
					    "System": "Sistemi",
 | 
				
			||||||
 | 
					    "Sync": "Sinkronizo",
 | 
				
			||||||
 | 
					    "SubtitleDownloadFailureFromForItem": "Titrat deshtuan të shkarkohen nga {0} për {1}",
 | 
				
			||||||
 | 
					    "StartupEmbyServerIsLoading": "Serveri Jellyfin po ngarkohet. Ju lutemi provoni përseri pas pak.",
 | 
				
			||||||
 | 
					    "Songs": "Këngë",
 | 
				
			||||||
 | 
					    "Shows": "Seriale",
 | 
				
			||||||
 | 
					    "ServerNameNeedsToBeRestarted": "{0} duhet të ristartoj",
 | 
				
			||||||
 | 
					    "ScheduledTaskStartedWithName": "{0} filloi",
 | 
				
			||||||
 | 
					    "ScheduledTaskFailedWithName": "{0} dështoi",
 | 
				
			||||||
 | 
					    "ProviderValue": "Ofruesi: {0}",
 | 
				
			||||||
 | 
					    "PluginUpdatedWithName": "{0} u përditësua",
 | 
				
			||||||
 | 
					    "PluginUninstalledWithName": "{0} u çinstalua",
 | 
				
			||||||
 | 
					    "PluginInstalledWithName": "{0} u instalua",
 | 
				
			||||||
 | 
					    "Plugin": "Plugin",
 | 
				
			||||||
 | 
					    "Playlists": "Listat për luajtje",
 | 
				
			||||||
 | 
					    "Photos": "Fotografitë",
 | 
				
			||||||
 | 
					    "NotificationOptionVideoPlaybackStopped": "Luajtja e videos ndaloi",
 | 
				
			||||||
 | 
					    "NotificationOptionVideoPlayback": "Luajtja e videos filloi",
 | 
				
			||||||
 | 
					    "NotificationOptionUserLockedOut": "Përdoruesi u përjashtua",
 | 
				
			||||||
 | 
					    "NotificationOptionTaskFailed": "Ushtrimi i planifikuar dështoi",
 | 
				
			||||||
 | 
					    "NotificationOptionServerRestartRequired": "Kërkohet ristartim i serverit",
 | 
				
			||||||
 | 
					    "NotificationOptionPluginUpdateInstalled": "Përditësimi i plugin u instalua",
 | 
				
			||||||
 | 
					    "NotificationOptionPluginUninstalled": "Plugin u çinstalua",
 | 
				
			||||||
 | 
					    "NotificationOptionPluginInstalled": "Plugin u instalua",
 | 
				
			||||||
 | 
					    "NotificationOptionPluginError": "Plugin dështoi",
 | 
				
			||||||
 | 
					    "NotificationOptionNewLibraryContent": "Një përmbajtje e re u shtua",
 | 
				
			||||||
 | 
					    "NotificationOptionInstallationFailed": "Instalimi dështoi",
 | 
				
			||||||
 | 
					    "NotificationOptionCameraImageUploaded": "Fotoja nga kamera u ngarkua",
 | 
				
			||||||
 | 
					    "NotificationOptionAudioPlaybackStopped": "Luajtja e audios ndaloi",
 | 
				
			||||||
 | 
					    "NotificationOptionAudioPlayback": "Luajtja e audios filloi",
 | 
				
			||||||
 | 
					    "NotificationOptionApplicationUpdateInstalled": "Përditësimi i aplikacionit u instalua",
 | 
				
			||||||
 | 
					    "NotificationOptionApplicationUpdateAvailable": "Një perditësim i aplikacionit është gati",
 | 
				
			||||||
 | 
					    "NewVersionIsAvailable": "Një version i ri i Jellyfin është gati për tu shkarkuar.",
 | 
				
			||||||
 | 
					    "NameSeasonUnknown": "Sezon i panjohur",
 | 
				
			||||||
 | 
					    "NameSeasonNumber": "Sezoni {0}",
 | 
				
			||||||
 | 
					    "NameInstallFailed": "Instalimi i {0} dështoi",
 | 
				
			||||||
 | 
					    "MusicVideos": "Video muzikore",
 | 
				
			||||||
 | 
					    "Music": "Muzikë",
 | 
				
			||||||
 | 
					    "Movies": "Filma",
 | 
				
			||||||
 | 
					    "MixedContent": "Përmbajtje e përzier",
 | 
				
			||||||
 | 
					    "MessageServerConfigurationUpdated": "Konfigurimet e serverit u përditësuan",
 | 
				
			||||||
 | 
					    "MessageNamedServerConfigurationUpdatedWithValue": "Seksioni i konfigurimit të serverit {0} u përditësua",
 | 
				
			||||||
 | 
					    "MessageApplicationUpdated": "Serveri Jellyfin u përditësua",
 | 
				
			||||||
 | 
					    "Latest": "Të fundit",
 | 
				
			||||||
 | 
					    "LabelRunningTimeValue": "Kohëzgjatja: {0}",
 | 
				
			||||||
 | 
					    "LabelIpAddressValue": "Adresa IP: {0}",
 | 
				
			||||||
 | 
					    "ItemRemovedWithName": "{0} u fshi nga libraria",
 | 
				
			||||||
 | 
					    "ItemAddedWithName": "{0} u shtua tek libraria",
 | 
				
			||||||
 | 
					    "HomeVideos": "Video personale",
 | 
				
			||||||
 | 
					    "HeaderRecordingGroups": "Grupet e regjistrimit",
 | 
				
			||||||
 | 
					    "HeaderNextUp": "Në vazhdim",
 | 
				
			||||||
 | 
					    "HeaderLiveTV": "TV Live",
 | 
				
			||||||
 | 
					    "HeaderFavoriteSongs": "Kënget e preferuara",
 | 
				
			||||||
 | 
					    "HeaderFavoriteShows": "Serialet e preferuar",
 | 
				
			||||||
 | 
					    "HeaderFavoriteEpisodes": "Episodet e preferuar",
 | 
				
			||||||
 | 
					    "HeaderFavoriteArtists": "Artistët e preferuar",
 | 
				
			||||||
 | 
					    "HeaderFavoriteAlbums": "Albumet e preferuar",
 | 
				
			||||||
 | 
					    "HeaderContinueWatching": "Vazhdo të shikosh",
 | 
				
			||||||
 | 
					    "HeaderCameraUploads": "Ngarkimet nga Kamera",
 | 
				
			||||||
 | 
					    "HeaderAlbumArtists": "Artistët e albumeve",
 | 
				
			||||||
 | 
					    "Genres": "Zhanre",
 | 
				
			||||||
 | 
					    "Folders": "Dosje",
 | 
				
			||||||
 | 
					    "Favorites": "Të preferuara",
 | 
				
			||||||
 | 
					    "FailedLoginAttemptWithUserName": "Përpjekja për hyrje dështoi nga {0}",
 | 
				
			||||||
 | 
					    "DeviceOnlineWithName": "{0} u lidh",
 | 
				
			||||||
 | 
					    "DeviceOfflineWithName": "{0} u shkëput",
 | 
				
			||||||
 | 
					    "Collections": "Koleksione",
 | 
				
			||||||
 | 
					    "ChapterNameValue": "Kapituj",
 | 
				
			||||||
 | 
					    "Channels": "Kanale",
 | 
				
			||||||
 | 
					    "CameraImageUploadedFrom": "Një foto e re nga kamera u ngarkua nga {0}",
 | 
				
			||||||
 | 
					    "Books": "Libra",
 | 
				
			||||||
 | 
					    "AuthenticationSucceededWithUserName": "{0} u identifikua me sukses",
 | 
				
			||||||
 | 
					    "Artists": "Artistë",
 | 
				
			||||||
 | 
					    "Application": "Aplikacioni",
 | 
				
			||||||
 | 
					    "AppDeviceValues": "Aplikacioni: {0}, Pajisja: {1}",
 | 
				
			||||||
 | 
					    "Albums": "Albumet"
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										117
									
								
								Emby.Server.Implementations/Localization/Core/vi.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										117
									
								
								Emby.Server.Implementations/Localization/Core/vi.json
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,117 @@
 | 
				
			|||||||
 | 
					{
 | 
				
			||||||
 | 
					    "Collections": "Bộ Sưu Tập",
 | 
				
			||||||
 | 
					    "Favorites": "Sở Thích",
 | 
				
			||||||
 | 
					    "Folders": "Thư Mục",
 | 
				
			||||||
 | 
					    "Genres": "Thể Loại",
 | 
				
			||||||
 | 
					    "HeaderAlbumArtists": "Bộ Sưu Tập Nghệ sĩ",
 | 
				
			||||||
 | 
					    "HeaderContinueWatching": "Tiếp Tục Xem",
 | 
				
			||||||
 | 
					    "HeaderLiveTV": "TV Trực Tiếp",
 | 
				
			||||||
 | 
					    "Movies": "Phim",
 | 
				
			||||||
 | 
					    "Photos": "Ảnh",
 | 
				
			||||||
 | 
					    "Playlists": "Danh Sách Chơi",
 | 
				
			||||||
 | 
					    "Shows": "Các Chương Trình",
 | 
				
			||||||
 | 
					    "Songs": "Các Bài Hát",
 | 
				
			||||||
 | 
					    "Sync": "Đồng Bộ",
 | 
				
			||||||
 | 
					    "ValueSpecialEpisodeName": "Đặc Biệt - {0}",
 | 
				
			||||||
 | 
					    "Albums": "Bộ Sưu Tập",
 | 
				
			||||||
 | 
					    "Artists": "Nghệ Sĩ",
 | 
				
			||||||
 | 
					    "TaskDownloadMissingSubtitlesDescription": "Tìm kiếm phụ đề bị thiếu trên Internet dựa trên cấu hình thông tin chi tiết.",
 | 
				
			||||||
 | 
					    "TaskDownloadMissingSubtitles": "Tải xuống phụ đề bị thiếu",
 | 
				
			||||||
 | 
					    "TaskRefreshChannelsDescription": "Làm mới thông tin kênh internet.",
 | 
				
			||||||
 | 
					    "TaskRefreshChannels": "Làm Mới Kênh",
 | 
				
			||||||
 | 
					    "TaskCleanTranscodeDescription": "Xóa các tệp chuyển mã cũ hơn một ngày.",
 | 
				
			||||||
 | 
					    "TaskCleanTranscode": "Làm Sạch Thư Mục Chuyển Mã",
 | 
				
			||||||
 | 
					    "TaskUpdatePluginsDescription": "Tải xuống và cài đặt các bản cập nhật cho các plugin được định cấu hình để cập nhật tự động.",
 | 
				
			||||||
 | 
					    "TaskUpdatePlugins": "Cập Nhật Plugins",
 | 
				
			||||||
 | 
					    "TaskRefreshPeopleDescription": "Cập nhật thông tin chi tiết cho diễn viên và đạo diễn trong thư viện phương tiện của bạn.",
 | 
				
			||||||
 | 
					    "TaskRefreshPeople": "Làm mới Người dùng",
 | 
				
			||||||
 | 
					    "TaskCleanLogsDescription": "Xóa tập tin nhật ký cũ hơn {0} ngày.",
 | 
				
			||||||
 | 
					    "TaskCleanLogs": "Làm sạch nhật ký",
 | 
				
			||||||
 | 
					    "TaskRefreshLibraryDescription": "Quét thư viện phương tiện của bạn để tìm các tệp mới và làm mới thông tin chi tiết.",
 | 
				
			||||||
 | 
					    "TaskRefreshLibrary": "Quét Thư viện Phương tiện",
 | 
				
			||||||
 | 
					    "TaskRefreshChapterImagesDescription": "Tạo hình thu nhỏ cho các video có chương.",
 | 
				
			||||||
 | 
					    "TaskRefreshChapterImages": "Trích xuất hình ảnh chương",
 | 
				
			||||||
 | 
					    "TaskCleanCacheDescription": "Xóa các tệp cache không còn cần thiết của hệ thống.",
 | 
				
			||||||
 | 
					    "TaskCleanCache": "Làm Sạch Thư Mục Cache",
 | 
				
			||||||
 | 
					    "TasksChannelsCategory": "Kênh Internet",
 | 
				
			||||||
 | 
					    "TasksApplicationCategory": "Ứng Dụng",
 | 
				
			||||||
 | 
					    "TasksLibraryCategory": "Thư Viện",
 | 
				
			||||||
 | 
					    "TasksMaintenanceCategory": "Bảo Trì",
 | 
				
			||||||
 | 
					    "VersionNumber": "Phiên Bản {0}",
 | 
				
			||||||
 | 
					    "ValueHasBeenAddedToLibrary": "{0} đã được thêm vào thư viện của bạn",
 | 
				
			||||||
 | 
					    "UserStoppedPlayingItemWithValues": "{0} đã phát xong {1} trên {2}",
 | 
				
			||||||
 | 
					    "UserStartedPlayingItemWithValues": "{0} đang phát {1} trên {2}",
 | 
				
			||||||
 | 
					    "UserPolicyUpdatedWithName": "Chính sách người dùng đã được cập nhật cho {0}",
 | 
				
			||||||
 | 
					    "UserPasswordChangedWithName": "Mật khẩu đã được thay đổi cho người dùng {0}",
 | 
				
			||||||
 | 
					    "UserOnlineFromDevice": "{0} trực tuyến từ {1}",
 | 
				
			||||||
 | 
					    "UserOfflineFromDevice": "{0} đã ngắt kết nối từ {1}",
 | 
				
			||||||
 | 
					    "UserLockedOutWithName": "User {0} đã bị khóa",
 | 
				
			||||||
 | 
					    "UserDownloadingItemWithValues": "{0} đang tải xuống {1}",
 | 
				
			||||||
 | 
					    "UserDeletedWithName": "Người Dùng {0} đã được xóa",
 | 
				
			||||||
 | 
					    "UserCreatedWithName": "Người Dùng {0} đã được tạo",
 | 
				
			||||||
 | 
					    "User": "Người Dùng",
 | 
				
			||||||
 | 
					    "TvShows": "Chương Trình TV",
 | 
				
			||||||
 | 
					    "System": "Hệ Thống",
 | 
				
			||||||
 | 
					    "SubtitleDownloadFailureFromForItem": "Không thể tải xuống phụ đề từ {0} cho {1}",
 | 
				
			||||||
 | 
					    "StartupEmbyServerIsLoading": "Jellyfin Server đang tải. Vui lòng thử lại trong thời gian ngắn.",
 | 
				
			||||||
 | 
					    "ServerNameNeedsToBeRestarted": "{0} cần được khởi động lại",
 | 
				
			||||||
 | 
					    "ScheduledTaskStartedWithName": "{0} đã bắt đầu",
 | 
				
			||||||
 | 
					    "ScheduledTaskFailedWithName": "{0} đã thất bại",
 | 
				
			||||||
 | 
					    "ProviderValue": "Provider: {0}",
 | 
				
			||||||
 | 
					    "PluginUpdatedWithName": "{0} đã cập nhật",
 | 
				
			||||||
 | 
					    "PluginUninstalledWithName": "{0} đã được gỡ bỏ",
 | 
				
			||||||
 | 
					    "PluginInstalledWithName": "{0} đã được cài đặt",
 | 
				
			||||||
 | 
					    "Plugin": "Plugin",
 | 
				
			||||||
 | 
					    "NotificationOptionVideoPlaybackStopped": "Phát lại video đã dừng",
 | 
				
			||||||
 | 
					    "NotificationOptionVideoPlayback": "Đã bắt đầu phát lại video",
 | 
				
			||||||
 | 
					    "NotificationOptionUserLockedOut": "Người dùng bị khóa",
 | 
				
			||||||
 | 
					    "NotificationOptionTaskFailed": "Lỗi tác vụ đã lên lịch",
 | 
				
			||||||
 | 
					    "NotificationOptionServerRestartRequired": "Yêu cầu khởi động lại Server",
 | 
				
			||||||
 | 
					    "NotificationOptionPluginUpdateInstalled": "Cập nhật Plugin đã được cài đặt",
 | 
				
			||||||
 | 
					    "NotificationOptionPluginUninstalled": "Đã gỡ bỏ Plugin",
 | 
				
			||||||
 | 
					    "NotificationOptionPluginInstalled": "Đã cài đặt Plugin",
 | 
				
			||||||
 | 
					    "NotificationOptionPluginError": "Thất bại Plugin",
 | 
				
			||||||
 | 
					    "NotificationOptionNewLibraryContent": "Nội dung mới được thêm vào",
 | 
				
			||||||
 | 
					    "NotificationOptionInstallationFailed": "Cài đặt thất bại",
 | 
				
			||||||
 | 
					    "NotificationOptionCameraImageUploaded": "Đã tải lên hình ảnh máy ảnh",
 | 
				
			||||||
 | 
					    "NotificationOptionAudioPlaybackStopped": "Phát lại âm thanh đã dừng",
 | 
				
			||||||
 | 
					    "NotificationOptionAudioPlayback": "Phát lại âm thanh đã bắt đầu",
 | 
				
			||||||
 | 
					    "NotificationOptionApplicationUpdateInstalled": "Bản cập nhật ứng dụng đã được cài đặt",
 | 
				
			||||||
 | 
					    "NotificationOptionApplicationUpdateAvailable": "Bản cập nhật ứng dụng hiện sẵn có",
 | 
				
			||||||
 | 
					    "NewVersionIsAvailable": "Một phiên bản mới của Jellyfin Server sẵn có để tải.",
 | 
				
			||||||
 | 
					    "NameSeasonUnknown": "Không Rõ Mùa",
 | 
				
			||||||
 | 
					    "NameSeasonNumber": "Mùa {0}",
 | 
				
			||||||
 | 
					    "NameInstallFailed": "{0} cài đặt thất bại",
 | 
				
			||||||
 | 
					    "MusicVideos": "Video Nhạc",
 | 
				
			||||||
 | 
					    "Music": "Nhạc",
 | 
				
			||||||
 | 
					    "MixedContent": "Nội dung hỗn hợp",
 | 
				
			||||||
 | 
					    "MessageServerConfigurationUpdated": "Cấu hình máy chủ đã được cập nhật",
 | 
				
			||||||
 | 
					    "MessageNamedServerConfigurationUpdatedWithValue": "Phần cấu hình máy chủ {0} đã được cập nhật",
 | 
				
			||||||
 | 
					    "MessageApplicationUpdatedTo": "Jellyfin Server đã được cập nhật lên {0}",
 | 
				
			||||||
 | 
					    "MessageApplicationUpdated": "Jellyfin Server đã được cập nhật",
 | 
				
			||||||
 | 
					    "Latest": "Gần Nhất",
 | 
				
			||||||
 | 
					    "LabelRunningTimeValue": "Thời Gian Chạy: {0}",
 | 
				
			||||||
 | 
					    "LabelIpAddressValue": "Địa Chỉ IP: {0}",
 | 
				
			||||||
 | 
					    "ItemRemovedWithName": "{0} đã xóa khỏi thư viện",
 | 
				
			||||||
 | 
					    "ItemAddedWithName": "{0} được thêm vào thư viện",
 | 
				
			||||||
 | 
					    "Inherit": "Thừa hưởng",
 | 
				
			||||||
 | 
					    "HomeVideos": "Video nhà",
 | 
				
			||||||
 | 
					    "HeaderRecordingGroups": "Nhóm Ghi Video",
 | 
				
			||||||
 | 
					    "HeaderNextUp": "Tiếp Theo",
 | 
				
			||||||
 | 
					    "HeaderFavoriteSongs": "Bài Hát Yêu Thích",
 | 
				
			||||||
 | 
					    "HeaderFavoriteShows": "Chương Trình Yêu Thích",
 | 
				
			||||||
 | 
					    "HeaderFavoriteEpisodes": "Tập Phim Yêu Thích",
 | 
				
			||||||
 | 
					    "HeaderFavoriteArtists": "Nghệ Sĩ Yêu Thích",
 | 
				
			||||||
 | 
					    "HeaderFavoriteAlbums": "Album Ưa Thích",
 | 
				
			||||||
 | 
					    "HeaderCameraUploads": "Máy Ảnh Tải Lên",
 | 
				
			||||||
 | 
					    "FailedLoginAttemptWithUserName": "Nỗ lực đăng nhập thất bại từ {0}",
 | 
				
			||||||
 | 
					    "DeviceOnlineWithName": "{0} đã kết nối",
 | 
				
			||||||
 | 
					    "DeviceOfflineWithName": "{0} đã ngắt kết nối",
 | 
				
			||||||
 | 
					    "ChapterNameValue": "Chương {0}",
 | 
				
			||||||
 | 
					    "Channels": "Kênh",
 | 
				
			||||||
 | 
					    "CameraImageUploadedFrom": "Một hình ảnh máy ảnh mới đã được tải lên từ {0}",
 | 
				
			||||||
 | 
					    "Books": "Sách",
 | 
				
			||||||
 | 
					    "AuthenticationSucceededWithUserName": "{0} xác thực thành công",
 | 
				
			||||||
 | 
					    "Application": "Ứng Dụng",
 | 
				
			||||||
 | 
					    "AppDeviceValues": "Ứng Dụng: {0}, Thiết Bị: {1}"
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@ -141,6 +141,7 @@ namespace MediaBrowser.Providers.Plugins.TheTvdb
 | 
				
			|||||||
                    Name = episode.EpisodeName,
 | 
					                    Name = episode.EpisodeName,
 | 
				
			||||||
                    Overview = episode.Overview,
 | 
					                    Overview = episode.Overview,
 | 
				
			||||||
                    CommunityRating = (float?)episode.SiteRating,
 | 
					                    CommunityRating = (float?)episode.SiteRating,
 | 
				
			||||||
 | 
					                    OfficialRating = episode.ContentRating,
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
            };
 | 
					            };
 | 
				
			||||||
            result.ResetPeople();
 | 
					            result.ResetPeople();
 | 
				
			||||||
 | 
				
			|||||||
@ -0,0 +1,90 @@
 | 
				
			|||||||
 | 
					using System.Linq;
 | 
				
			||||||
 | 
					using Emby.Naming.AudioBook;
 | 
				
			||||||
 | 
					using Emby.Naming.Common;
 | 
				
			||||||
 | 
					using MediaBrowser.Model.IO;
 | 
				
			||||||
 | 
					using Xunit;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace Jellyfin.Naming.Tests.AudioBook
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    public class AudioBookListResolverTests
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        private readonly NamingOptions _namingOptions = new NamingOptions();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        [Fact]
 | 
				
			||||||
 | 
					        public void TestStackAndExtras()
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            // No stacking here because there is no part/disc/etc
 | 
				
			||||||
 | 
					            var files = new[]
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                "Harry Potter and the Deathly Hallows/Part 1.mp3",
 | 
				
			||||||
 | 
					                "Harry Potter and the Deathly Hallows/Part 2.mp3",
 | 
				
			||||||
 | 
					                "Harry Potter and the Deathly Hallows/book.nfo",
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                "Batman/Chapter 1.mp3",
 | 
				
			||||||
 | 
					                "Batman/Chapter 2.mp3",
 | 
				
			||||||
 | 
					                "Batman/Chapter 3.mp3",
 | 
				
			||||||
 | 
					            };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            var resolver = GetResolver();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            var result = resolver.Resolve(files.Select(i => new FileSystemMetadata
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                IsDirectory = false,
 | 
				
			||||||
 | 
					                FullName = i
 | 
				
			||||||
 | 
					            })).ToList();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            Assert.Equal(2, result[0].Files.Count);
 | 
				
			||||||
 | 
					            // Assert.Empty(result[0].Extras); FIXME: AudioBookListResolver should resolve extra files properly
 | 
				
			||||||
 | 
					            Assert.Equal("Harry Potter and the Deathly Hallows", result[0].Name);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            Assert.Equal(3, result[1].Files.Count);
 | 
				
			||||||
 | 
					            Assert.Empty(result[1].Extras);
 | 
				
			||||||
 | 
					            Assert.Equal("Batman", result[1].Name);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        [Fact]
 | 
				
			||||||
 | 
					        public void TestWithMetadata()
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            var files = new[]
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                "Harry Potter and the Deathly Hallows/Chapter 1.ogg",
 | 
				
			||||||
 | 
					                "Harry Potter and the Deathly Hallows/Harry Potter and the Deathly Hallows.nfo"
 | 
				
			||||||
 | 
					            };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            var resolver = GetResolver();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            var result = resolver.Resolve(files.Select(i => new FileSystemMetadata
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                IsDirectory = false,
 | 
				
			||||||
 | 
					                FullName = i
 | 
				
			||||||
 | 
					            }));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            Assert.Single(result);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        [Fact]
 | 
				
			||||||
 | 
					        public void TestWithExtra()
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            var files = new[]
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                "Harry Potter and the Deathly Hallows/Chapter 1.mp3",
 | 
				
			||||||
 | 
					                "Harry Potter and the Deathly Hallows/Harry Potter and the Deathly Hallows trailer.mp3"
 | 
				
			||||||
 | 
					            };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            var resolver = GetResolver();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            var result = resolver.Resolve(files.Select(i => new FileSystemMetadata
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                IsDirectory = false,
 | 
				
			||||||
 | 
					                FullName = i
 | 
				
			||||||
 | 
					            })).ToList();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            Assert.Single(result);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        private AudioBookListResolver GetResolver()
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            return new AudioBookListResolver(_namingOptions);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@ -0,0 +1,57 @@
 | 
				
			|||||||
 | 
					using System.Collections.Generic;
 | 
				
			||||||
 | 
					using Emby.Naming.AudioBook;
 | 
				
			||||||
 | 
					using Emby.Naming.Common;
 | 
				
			||||||
 | 
					using Xunit;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace Jellyfin.Naming.Tests.AudioBook
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    public class AudioBookResolverTests
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        private readonly NamingOptions _namingOptions = new NamingOptions();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public static IEnumerable<object[]> GetResolveFileTestData()
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            yield return new object[]
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                new AudioBookFileInfo()
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    Path = @"/server/AudioBooks/Larry Potter/Larry Potter.mp3",
 | 
				
			||||||
 | 
					                    Container = "mp3",
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            };
 | 
				
			||||||
 | 
					            yield return new object[]
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                new AudioBookFileInfo()
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    Path = @"/server/AudioBooks/Berry Potter/Chapter 1 .ogg",
 | 
				
			||||||
 | 
					                    Container = "ogg",
 | 
				
			||||||
 | 
					                    ChapterNumber = 1
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            };
 | 
				
			||||||
 | 
					            yield return new object[]
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                new AudioBookFileInfo()
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    Path = @"/server/AudioBooks/Nerry Potter/Part 3 - Chapter 2.mp3",
 | 
				
			||||||
 | 
					                    Container = "mp3",
 | 
				
			||||||
 | 
					                    ChapterNumber = 2,
 | 
				
			||||||
 | 
					                    PartNumber = 3
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            };
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        [Theory]
 | 
				
			||||||
 | 
					        [MemberData(nameof(GetResolveFileTestData))]
 | 
				
			||||||
 | 
					        public void ResolveFile_ValidFileName_Success(AudioBookFileInfo expectedResult)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            var result = new AudioBookResolver(_namingOptions).Resolve(expectedResult.Path);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            Assert.NotNull(result);
 | 
				
			||||||
 | 
					            Assert.Equal(result.Path, expectedResult.Path);
 | 
				
			||||||
 | 
					            Assert.Equal(result.Container, expectedResult.Container);
 | 
				
			||||||
 | 
					            Assert.Equal(result.ChapterNumber, expectedResult.ChapterNumber);
 | 
				
			||||||
 | 
					            Assert.Equal(result.PartNumber, expectedResult.PartNumber);
 | 
				
			||||||
 | 
					            Assert.Equal(result.IsDirectory, expectedResult.IsDirectory);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user