aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--MediaBrowser.Api/Devices/DeviceService.cs18
-rw-r--r--MediaBrowser.Api/IHasDtoOptions.cs49
-rw-r--r--MediaBrowser.Api/Images/ImageService.cs36
-rw-r--r--MediaBrowser.Api/ItemLookupService.cs13
-rw-r--r--MediaBrowser.Api/Library/LibraryService.cs6
-rw-r--r--MediaBrowser.Api/MediaBrowser.Api.csproj1
-rw-r--r--MediaBrowser.Api/Movies/MoviesService.cs15
-rw-r--r--MediaBrowser.Api/Movies/TrailersService.cs2
-rw-r--r--MediaBrowser.Api/Music/InstantMixService.cs17
-rw-r--r--MediaBrowser.Api/PackageReviewService.cs8
-rw-r--r--MediaBrowser.Api/PackageService.cs7
-rw-r--r--MediaBrowser.Api/Playback/BaseStreamingService.cs5
-rw-r--r--MediaBrowser.Api/PlaylistService.cs2
-rw-r--r--MediaBrowser.Api/Session/SessionsService.cs12
-rw-r--r--MediaBrowser.Api/StartupWizardService.cs1
-rw-r--r--MediaBrowser.Api/TvShowsService.cs30
-rw-r--r--MediaBrowser.Api/UserLibrary/ArtistsService.cs2
-rw-r--r--MediaBrowser.Api/UserLibrary/BaseItemsByNameService.cs12
-rw-r--r--MediaBrowser.Api/UserLibrary/BaseItemsRequest.cs16
-rw-r--r--MediaBrowser.Api/UserLibrary/ItemsService.cs11
-rw-r--r--MediaBrowser.Api/UserLibrary/UserLibraryService.cs17
-rw-r--r--MediaBrowser.Common.Implementations/HttpClientManager/HttpClientManager.cs16
-rw-r--r--MediaBrowser.Common.Implementations/Logging/LogHelper.cs5
-rw-r--r--MediaBrowser.Common.Implementations/Networking/BaseNetworkManager.cs18
-rw-r--r--MediaBrowser.Common.Implementations/Security/PluginSecurityManager.cs6
-rw-r--r--MediaBrowser.Common.Implementations/Updates/InstallationManager.cs5
-rw-r--r--MediaBrowser.Common/Constants/Constants.cs8
-rw-r--r--MediaBrowser.Common/Extensions/BaseExtensions.cs55
-rw-r--r--MediaBrowser.Common/IO/FileSystemRepository.cs122
-rw-r--r--MediaBrowser.Common/MediaBrowser.Common.csproj2
-rw-r--r--MediaBrowser.Controller/Collections/CollectionCreationOptions.cs2
-rw-r--r--MediaBrowser.Controller/Devices/IDeviceManager.cs4
-rw-r--r--MediaBrowser.Controller/Dlna/DlnaIconResponse.cs22
-rw-r--r--MediaBrowser.Controller/Dlna/IDlnaManager.cs5
-rw-r--r--MediaBrowser.Controller/Drawing/IImageProcessor.cs2
-rw-r--r--MediaBrowser.Controller/Drawing/ImageFormat.cs11
-rw-r--r--MediaBrowser.Controller/Drawing/ImageProcessingOptions.cs2
-rw-r--r--MediaBrowser.Controller/Drawing/ImageStream.cs28
-rw-r--r--MediaBrowser.Controller/Dto/IDtoService.cs18
-rw-r--r--MediaBrowser.Controller/Entities/BaseItem.cs228
-rw-r--r--MediaBrowser.Controller/Entities/Folder.cs69
-rw-r--r--MediaBrowser.Controller/Entities/Game.cs13
-rw-r--r--MediaBrowser.Controller/Entities/IHasImages.cs6
-rw-r--r--MediaBrowser.Controller/Entities/IHasTrailers.cs9
-rw-r--r--MediaBrowser.Controller/Entities/Movies/BoxSet.cs33
-rw-r--r--MediaBrowser.Controller/Entities/Movies/Movie.cs31
-rw-r--r--MediaBrowser.Controller/Entities/MusicVideo.cs36
-rw-r--r--MediaBrowser.Controller/Entities/Share.cs15
-rw-r--r--MediaBrowser.Controller/Entities/TV/Series.cs15
-rw-r--r--MediaBrowser.Controller/Entities/Trailer.cs6
-rw-r--r--MediaBrowser.Controller/Entities/User.cs3
-rw-r--r--MediaBrowser.Controller/Entities/UserView.cs3
-rw-r--r--MediaBrowser.Controller/Entities/UserViewBuilder.cs2
-rw-r--r--MediaBrowser.Controller/Entities/Video.cs274
-rw-r--r--MediaBrowser.Controller/Library/ILibraryManager.cs81
-rw-r--r--MediaBrowser.Controller/Library/IMusicManager.cs8
-rw-r--r--MediaBrowser.Controller/Library/IUserManager.cs14
-rw-r--r--MediaBrowser.Controller/LiveTv/ILiveTvService.cs7
-rw-r--r--MediaBrowser.Controller/LiveTv/StreamResponseInfo.cs20
-rw-r--r--MediaBrowser.Controller/MediaBrowser.Controller.csproj7
-rw-r--r--MediaBrowser.Controller/Persistence/IUserRepository.cs6
-rw-r--r--MediaBrowser.Controller/Playlists/Playlist.cs19
-rw-r--r--MediaBrowser.Controller/Providers/BaseItemXmlParser.cs84
-rw-r--r--MediaBrowser.Controller/Providers/IImageEnhancer.cs6
-rw-r--r--MediaBrowser.Controller/Providers/IImageSaver.cs4
-rw-r--r--MediaBrowser.Controller/Providers/ILocalImageProvider.cs4
-rw-r--r--MediaBrowser.Controller/Resolvers/IItemResolver.cs23
-rw-r--r--MediaBrowser.Controller/Sync/ISyncManager.cs14
-rw-r--r--MediaBrowser.Controller/Sync/ISyncRepository.cs14
-rw-r--r--MediaBrowser.Dlna/ContentDirectory/ContentDirectory.cs8
-rw-r--r--MediaBrowser.Dlna/ContentDirectory/ControlHandler.cs220
-rw-r--r--MediaBrowser.Dlna/Didl/DidlBuilder.cs41
-rw-r--r--MediaBrowser.Dlna/DlnaManager.cs10
-rw-r--r--MediaBrowser.Dlna/Images/people48.jpgbin0 -> 1101 bytes
-rw-r--r--MediaBrowser.Dlna/Images/people48.pngbin0 -> 688 bytes
-rw-r--r--MediaBrowser.Dlna/Images/people480.jpgbin0 -> 8691 bytes
-rw-r--r--MediaBrowser.Dlna/Images/people480.pngbin0 -> 6351 bytes
-rw-r--r--MediaBrowser.Dlna/MediaBrowser.Dlna.csproj13
-rw-r--r--MediaBrowser.Dlna/Profiles/SamsungSmartTvProfile.cs2
-rw-r--r--MediaBrowser.Dlna/Profiles/XboxOneProfile.cs7
-rw-r--r--MediaBrowser.Dlna/Profiles/Xml/Android.xml84
-rw-r--r--MediaBrowser.Dlna/Profiles/Xml/Samsung Smart TV.xml2
-rw-r--r--MediaBrowser.Dlna/Profiles/Xml/Windows 8 RT.xml78
-rw-r--r--MediaBrowser.Dlna/Profiles/Xml/Windows Phone.xml86
-rw-r--r--MediaBrowser.Dlna/Profiles/Xml/Xbox One.xml4
-rw-r--r--MediaBrowser.LocalMetadata/Images/LocalImageProvider.cs138
-rw-r--r--MediaBrowser.LocalMetadata/MediaBrowser.LocalMetadata.csproj1
-rw-r--r--MediaBrowser.LocalMetadata/Parsers/PlaylistXmlParser.cs12
-rw-r--r--MediaBrowser.LocalMetadata/Providers/GameXmlProvider.cs22
-rw-r--r--MediaBrowser.LocalMetadata/Providers/TrailerXmlProvider.cs37
-rw-r--r--MediaBrowser.LocalMetadata/Savers/PlaylistXmlSaver.cs5
-rw-r--r--MediaBrowser.LocalMetadata/Savers/XmlSaverHelpers.cs23
-rw-r--r--MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs3
-rw-r--r--MediaBrowser.Model.Portable/MediaBrowser.Model.Portable.csproj27
-rw-r--r--MediaBrowser.Model.net35/MediaBrowser.Model.net35.csproj27
-rw-r--r--MediaBrowser.Model/ApiClient/ConnectionMode.cs3
-rw-r--r--MediaBrowser.Model/ApiClient/IApiClient.cs17
-rw-r--r--MediaBrowser.Model/ApiClient/ServerCredentials.cs10
-rw-r--r--MediaBrowser.Model/ApiClient/ServerDiscoveryInfo.cs5
-rw-r--r--MediaBrowser.Model/ApiClient/ServerInfo.cs21
-rw-r--r--MediaBrowser.Model/Configuration/ServerConfiguration.cs6
-rw-r--r--MediaBrowser.Model/Devices/DeviceQuery.cs17
-rw-r--r--MediaBrowser.Model/Dlna/Profiles/AndroidProfile.cs167
-rw-r--r--MediaBrowser.Model/Dlna/StreamBuilder.cs1
-rw-r--r--MediaBrowser.Model/Dlna/TranscodingProfile.cs3
-rw-r--r--MediaBrowser.Model/Drawing/ImageFormat.cs (renamed from MediaBrowser.Model/Drawing/ImageOutputFormat.cs)2
-rw-r--r--MediaBrowser.Model/Drawing/ImageSize.cs6
-rw-r--r--MediaBrowser.Model/Dto/BaseItemDto.cs26
-rw-r--r--MediaBrowser.Model/Dto/DtoOptions.cs32
-rw-r--r--MediaBrowser.Model/Dto/ImageOptions.cs2
-rw-r--r--MediaBrowser.Model/MediaBrowser.Model.csproj9
-rw-r--r--MediaBrowser.Model/Querying/ItemFields.cs35
-rw-r--r--MediaBrowser.Model/Querying/ItemQuery.cs25
-rw-r--r--MediaBrowser.Model/Querying/ItemsByNameQuery.cs18
-rw-r--r--MediaBrowser.Model/Querying/LatestItemsQuery.cs22
-rw-r--r--MediaBrowser.Model/Querying/NextUpQuery.cs23
-rw-r--r--MediaBrowser.Model/Querying/UpcomingEpisodesQuery.cs24
-rw-r--r--MediaBrowser.Model/Session/ClientCapabilities.cs3
-rw-r--r--MediaBrowser.Model/Sync/SyncJob.cs22
-rw-r--r--MediaBrowser.Model/Sync/SyncJobItem.cs13
-rw-r--r--MediaBrowser.Model/Sync/SyncJobItemQuery.cs27
-rw-r--r--MediaBrowser.Model/Sync/SyncJobItemStatus.cs12
-rw-r--r--MediaBrowser.Model/Sync/SyncJobQuery.cs5
-rw-r--r--MediaBrowser.Model/Sync/SyncJobRequest.cs18
-rw-r--r--MediaBrowser.Model/Sync/SyncJobStatus.cs8
-rw-r--r--MediaBrowser.Model/Sync/SyncLimitType.cs7
-rw-r--r--MediaBrowser.Model/Users/UserPolicy.cs11
-rw-r--r--MediaBrowser.Providers/BoxSets/BoxSetMetadataService.cs9
-rw-r--r--MediaBrowser.Providers/Manager/ProviderManager.cs1
-rw-r--r--MediaBrowser.Providers/MediaBrowser.Providers.csproj1
-rw-r--r--MediaBrowser.Providers/MediaInfo/FFProbeProvider.cs6
-rw-r--r--MediaBrowser.Providers/MediaInfo/FFProbeVideoInfo.cs7
-rw-r--r--MediaBrowser.Providers/MediaInfo/VideoImageProvider.cs2
-rw-r--r--MediaBrowser.Providers/Movies/FanartMovieImageProvider.cs7
-rw-r--r--MediaBrowser.Providers/Movies/MovieDbImageProvider.cs7
-rw-r--r--MediaBrowser.Providers/Movies/MovieDbTrailerProvider.cs7
-rw-r--r--MediaBrowser.Providers/Movies/MovieExternalIds.cs6
-rw-r--r--MediaBrowser.Providers/Movies/MovieUpdatesPrescanTask.cs2
-rw-r--r--MediaBrowser.Providers/Movies/TrailerMetadataService.cs34
-rw-r--r--MediaBrowser.Providers/Omdb/OmdbImageProvider.cs2
-rw-r--r--MediaBrowser.Providers/Omdb/OmdbItemProvider.cs14
-rw-r--r--MediaBrowser.Providers/Playlists/PlaylistMetadataService.cs14
-rw-r--r--MediaBrowser.Server.Implementations/Channels/ChannelManager.cs24
-rw-r--r--MediaBrowser.Server.Implementations/Collections/CollectionManager.cs9
-rw-r--r--MediaBrowser.Server.Implementations/Connect/ConnectManager.cs41
-rw-r--r--MediaBrowser.Server.Implementations/Devices/DeviceManager.cs28
-rw-r--r--MediaBrowser.Server.Implementations/Drawing/ImageExtensions.cs (renamed from MediaBrowser.Controller/Drawing/ImageExtensions.cs)10
-rw-r--r--MediaBrowser.Server.Implementations/Drawing/ImageHeader.cs50
-rw-r--r--MediaBrowser.Server.Implementations/Drawing/ImageProcessor.cs99
-rw-r--r--MediaBrowser.Server.Implementations/Dto/DtoService.cs207
-rw-r--r--MediaBrowser.Server.Implementations/EntryPoints/Notifications/RemoteNotifications.cs2
-rw-r--r--MediaBrowser.Server.Implementations/EntryPoints/UsageReporter.cs5
-rw-r--r--MediaBrowser.Server.Implementations/FileOrganization/TvFolderOrganizer.cs3
-rw-r--r--MediaBrowser.Server.Implementations/Intros/DefaultIntroProvider.cs11
-rw-r--r--MediaBrowser.Server.Implementations/Library/CoreResolutionIgnoreRule.cs32
-rw-r--r--MediaBrowser.Server.Implementations/Library/EntityResolutionHelper.cs104
-rw-r--r--MediaBrowser.Server.Implementations/Library/LibraryManager.cs267
-rw-r--r--MediaBrowser.Server.Implementations/Library/LocalTrailerPostScanTask.cs94
-rw-r--r--MediaBrowser.Server.Implementations/Library/MusicManager.cs13
-rw-r--r--MediaBrowser.Server.Implementations/Library/PathExtensions.cs37
-rw-r--r--MediaBrowser.Server.Implementations/Library/ResolverHelper.cs156
-rw-r--r--MediaBrowser.Server.Implementations/Library/Resolvers/Audio/AudioResolver.cs11
-rw-r--r--MediaBrowser.Server.Implementations/Library/Resolvers/Audio/MusicAlbumResolver.cs6
-rw-r--r--MediaBrowser.Server.Implementations/Library/Resolvers/BaseVideoResolver.cs261
-rw-r--r--MediaBrowser.Server.Implementations/Library/Resolvers/LocalTrailerResolver.cs61
-rw-r--r--MediaBrowser.Server.Implementations/Library/Resolvers/Movies/BoxSetResolver.cs12
-rw-r--r--MediaBrowser.Server.Implementations/Library/Resolvers/Movies/MovieResolver.cs391
-rw-r--r--MediaBrowser.Server.Implementations/Library/Resolvers/PhotoResolver.cs4
-rw-r--r--MediaBrowser.Server.Implementations/Library/Resolvers/PlaylistResolver.cs6
-rw-r--r--MediaBrowser.Server.Implementations/Library/Resolvers/TV/EpisodeResolver.cs33
-rw-r--r--MediaBrowser.Server.Implementations/Library/Resolvers/TV/SeriesResolver.cs45
-rw-r--r--MediaBrowser.Server.Implementations/Library/Resolvers/VideoResolver.cs18
-rw-r--r--MediaBrowser.Server.Implementations/Library/UserManager.cs15
-rw-r--r--MediaBrowser.Server.Implementations/Library/Validators/ArtistsPostScanTask.cs2
-rw-r--r--MediaBrowser.Server.Implementations/Library/Validators/GameGenresPostScanTask.cs2
-rw-r--r--MediaBrowser.Server.Implementations/Library/Validators/GenresPostScanTask.cs2
-rw-r--r--MediaBrowser.Server.Implementations/Library/Validators/MusicGenresPostScanTask.cs2
-rw-r--r--MediaBrowser.Server.Implementations/Library/Validators/StudiosPostScanTask.cs2
-rw-r--r--MediaBrowser.Server.Implementations/LiveTv/LiveTvDtoService.cs16
-rw-r--r--MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs14
-rw-r--r--MediaBrowser.Server.Implementations/LiveTv/RefreshChannelsScheduledTask.cs7
-rw-r--r--MediaBrowser.Server.Implementations/Localization/JavaScript/ar.json20
-rw-r--r--MediaBrowser.Server.Implementations/Localization/JavaScript/ca.json20
-rw-r--r--MediaBrowser.Server.Implementations/Localization/JavaScript/cs.json20
-rw-r--r--MediaBrowser.Server.Implementations/Localization/JavaScript/da.json20
-rw-r--r--MediaBrowser.Server.Implementations/Localization/JavaScript/de.json22
-rw-r--r--MediaBrowser.Server.Implementations/Localization/JavaScript/el.json20
-rw-r--r--MediaBrowser.Server.Implementations/Localization/JavaScript/en_GB.json20
-rw-r--r--MediaBrowser.Server.Implementations/Localization/JavaScript/en_US.json20
-rw-r--r--MediaBrowser.Server.Implementations/Localization/JavaScript/es.json20
-rw-r--r--MediaBrowser.Server.Implementations/Localization/JavaScript/es_MX.json24
-rw-r--r--MediaBrowser.Server.Implementations/Localization/JavaScript/fi.json20
-rw-r--r--MediaBrowser.Server.Implementations/Localization/JavaScript/fr.json22
-rw-r--r--MediaBrowser.Server.Implementations/Localization/JavaScript/he.json20
-rw-r--r--MediaBrowser.Server.Implementations/Localization/JavaScript/hr.json20
-rw-r--r--MediaBrowser.Server.Implementations/Localization/JavaScript/it.json34
-rw-r--r--MediaBrowser.Server.Implementations/Localization/JavaScript/javascript.json20
-rw-r--r--MediaBrowser.Server.Implementations/Localization/JavaScript/kk.json40
-rw-r--r--MediaBrowser.Server.Implementations/Localization/JavaScript/ms.json20
-rw-r--r--MediaBrowser.Server.Implementations/Localization/JavaScript/nb.json20
-rw-r--r--MediaBrowser.Server.Implementations/Localization/JavaScript/nl.json22
-rw-r--r--MediaBrowser.Server.Implementations/Localization/JavaScript/pl.json20
-rw-r--r--MediaBrowser.Server.Implementations/Localization/JavaScript/pt_BR.json20
-rw-r--r--MediaBrowser.Server.Implementations/Localization/JavaScript/pt_PT.json20
-rw-r--r--MediaBrowser.Server.Implementations/Localization/JavaScript/ru.json36
-rw-r--r--MediaBrowser.Server.Implementations/Localization/JavaScript/sv.json20
-rw-r--r--MediaBrowser.Server.Implementations/Localization/JavaScript/tr.json20
-rw-r--r--MediaBrowser.Server.Implementations/Localization/JavaScript/vi.json20
-rw-r--r--MediaBrowser.Server.Implementations/Localization/JavaScript/zh_CN.json20
-rw-r--r--MediaBrowser.Server.Implementations/Localization/JavaScript/zh_TW.json20
-rw-r--r--MediaBrowser.Server.Implementations/Localization/Server/ar.json8
-rw-r--r--MediaBrowser.Server.Implementations/Localization/Server/ca.json8
-rw-r--r--MediaBrowser.Server.Implementations/Localization/Server/cs.json8
-rw-r--r--MediaBrowser.Server.Implementations/Localization/Server/da.json8
-rw-r--r--MediaBrowser.Server.Implementations/Localization/Server/de.json20
-rw-r--r--MediaBrowser.Server.Implementations/Localization/Server/el.json8
-rw-r--r--MediaBrowser.Server.Implementations/Localization/Server/en_GB.json8
-rw-r--r--MediaBrowser.Server.Implementations/Localization/Server/en_US.json8
-rw-r--r--MediaBrowser.Server.Implementations/Localization/Server/es.json8
-rw-r--r--MediaBrowser.Server.Implementations/Localization/Server/es_MX.json14
-rw-r--r--MediaBrowser.Server.Implementations/Localization/Server/fi.json8
-rw-r--r--MediaBrowser.Server.Implementations/Localization/Server/fr.json16
-rw-r--r--MediaBrowser.Server.Implementations/Localization/Server/he.json8
-rw-r--r--MediaBrowser.Server.Implementations/Localization/Server/hr.json8
-rw-r--r--MediaBrowser.Server.Implementations/Localization/Server/it.json38
-rw-r--r--MediaBrowser.Server.Implementations/Localization/Server/kk.json68
-rw-r--r--MediaBrowser.Server.Implementations/Localization/Server/ko.json8
-rw-r--r--MediaBrowser.Server.Implementations/Localization/Server/ms.json8
-rw-r--r--MediaBrowser.Server.Implementations/Localization/Server/nb.json8
-rw-r--r--MediaBrowser.Server.Implementations/Localization/Server/nl.json14
-rw-r--r--MediaBrowser.Server.Implementations/Localization/Server/pl.json8
-rw-r--r--MediaBrowser.Server.Implementations/Localization/Server/pt_BR.json8
-rw-r--r--MediaBrowser.Server.Implementations/Localization/Server/pt_PT.json8
-rw-r--r--MediaBrowser.Server.Implementations/Localization/Server/ru.json72
-rw-r--r--MediaBrowser.Server.Implementations/Localization/Server/server.json8
-rw-r--r--MediaBrowser.Server.Implementations/Localization/Server/sv.json8
-rw-r--r--MediaBrowser.Server.Implementations/Localization/Server/tr.json8
-rw-r--r--MediaBrowser.Server.Implementations/Localization/Server/vi.json8
-rw-r--r--MediaBrowser.Server.Implementations/Localization/Server/zh_CN.json8
-rw-r--r--MediaBrowser.Server.Implementations/Localization/Server/zh_TW.json8
-rw-r--r--MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj9
-rw-r--r--MediaBrowser.Server.Implementations/Playlists/ManualPlaylistsFolder.cs2
-rw-r--r--MediaBrowser.Server.Implementations/Playlists/PlaylistManager.cs9
-rw-r--r--MediaBrowser.Server.Implementations/ScheduledTasks/RefreshMediaLibraryTask.cs7
-rw-r--r--MediaBrowser.Server.Implementations/Sync/MockSyncProvider.cs6
-rw-r--r--MediaBrowser.Server.Implementations/Sync/SyncJobProcessor.cs395
-rw-r--r--MediaBrowser.Server.Implementations/Sync/SyncManager.cs147
-rw-r--r--MediaBrowser.Server.Implementations/Sync/SyncRepository.cs220
-rw-r--r--MediaBrowser.Server.Implementations/Sync/SyncScheduledTask.cs62
-rw-r--r--MediaBrowser.Server.Implementations/packages.config2
-rw-r--r--MediaBrowser.Server.Mac/readme.txt13
-rw-r--r--MediaBrowser.Server.Startup.Common/ApplicationHost.cs18
-rw-r--r--MediaBrowser.Server.Startup.Common/MediaBrowser.Server.Startup.Common.csproj1
-rw-r--r--MediaBrowser.Server.Startup.Common/Migrations/DeleteDlnaProfiles.cs42
-rw-r--r--MediaBrowser.ServerApplication/App.config2
-rw-r--r--MediaBrowser.Tests/Dlna/StreamBuilderTests.cs78
-rw-r--r--MediaBrowser.Tests/MediaBrowser.Tests.csproj1
-rw-r--r--MediaBrowser.WebDashboard/Api/PackageCreator.cs3
-rw-r--r--MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj10
-rw-r--r--MediaBrowser.XbmcMetadata/Images/XbmcImageSaver.cs6
-rw-r--r--MediaBrowser.XbmcMetadata/Providers/BaseVideoNfoProvider.cs2
-rw-r--r--MediaBrowser.XbmcMetadata/Providers/MovieNfoProvider.cs9
-rw-r--r--MediaBrowser.XbmcMetadata/Savers/MovieNfoSaver.cs2
-rw-r--r--MediaBrowser.sln309
-rw-r--r--Nuget/MediaBrowser.Common.Internal.nuspec4
-rw-r--r--Nuget/MediaBrowser.Common.nuspec2
-rw-r--r--Nuget/MediaBrowser.Model.Signed.nuspec2
-rw-r--r--Nuget/MediaBrowser.Server.Core.nuspec4
-rw-r--r--SharedVersion.cs6
269 files changed, 4728 insertions, 3047 deletions
diff --git a/MediaBrowser.Api/Devices/DeviceService.cs b/MediaBrowser.Api/Devices/DeviceService.cs
index 0d86d6a5c0..ab0a4a4b2a 100644
--- a/MediaBrowser.Api/Devices/DeviceService.cs
+++ b/MediaBrowser.Api/Devices/DeviceService.cs
@@ -1,22 +1,19 @@
using MediaBrowser.Controller.Devices;
using MediaBrowser.Controller.Net;
using MediaBrowser.Model.Devices;
+using MediaBrowser.Model.Querying;
using MediaBrowser.Model.Session;
using ServiceStack;
using ServiceStack.Web;
-using System.Collections.Generic;
using System.IO;
-using System.Linq;
using System.Threading.Tasks;
namespace MediaBrowser.Api.Devices
{
[Route("/Devices", "GET", Summary = "Gets all devices")]
[Authenticated(Roles = "Admin")]
- public class GetDevices : IReturn<List<DeviceInfo>>
+ public class GetDevices : DeviceQuery, IReturn<QueryResult<DeviceInfo>>
{
- [ApiMember(Name = "SupportsContentUploading", Description = "SupportsContentUploading", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET")]
- public bool? SupportsContentUploading { get; set; }
}
[Route("/Devices", "DELETE", Summary = "Deletes a device")]
@@ -109,16 +106,7 @@ namespace MediaBrowser.Api.Devices
public object Get(GetDevices request)
{
- var devices = _deviceManager.GetDevices();
-
- if (request.SupportsContentUploading.HasValue)
- {
- var val = request.SupportsContentUploading.Value;
-
- devices = devices.Where(i => _deviceManager.GetCapabilities(i.Id).SupportsContentUploading == val);
- }
-
- return ToOptimizedResult(devices.ToList());
+ return ToOptimizedResult(_deviceManager.GetDevices(request));
}
public object Get(GetCameraUploads request)
diff --git a/MediaBrowser.Api/IHasDtoOptions.cs b/MediaBrowser.Api/IHasDtoOptions.cs
new file mode 100644
index 0000000000..f7fb57f014
--- /dev/null
+++ b/MediaBrowser.Api/IHasDtoOptions.cs
@@ -0,0 +1,49 @@
+using MediaBrowser.Model.Dto;
+using MediaBrowser.Model.Entities;
+using System;
+using System.Linq;
+
+namespace MediaBrowser.Api
+{
+ public interface IHasDtoOptions : IHasItemFields
+ {
+ bool? EnableImages { get; set; }
+
+ int? ImageTypeLimit { get; set; }
+
+ string EnableImageTypes { get; set; }
+ }
+
+ public static class HasDtoOptionsExtensions
+ {
+ public static DtoOptions GetDtoOptions(this IHasDtoOptions request)
+ {
+ var options = new DtoOptions();
+
+ options.Fields = request.GetItemFields().ToList();
+ options.EnableImages = request.EnableImages ?? true;
+
+ if (request.ImageTypeLimit.HasValue)
+ {
+ options.ImageTypeLimit = request.ImageTypeLimit.Value;
+ }
+
+ if (string.IsNullOrWhiteSpace(request.EnableImageTypes))
+ {
+ if (options.EnableImages)
+ {
+ // Get everything
+ options.ImageTypes = Enum.GetNames(typeof(ImageType))
+ .Select(i => (ImageType)Enum.Parse(typeof(ImageType), i, true))
+ .ToList();
+ }
+ }
+ else
+ {
+ options.ImageTypes = (request.EnableImageTypes ?? string.Empty).Split(',').Where(i => !string.IsNullOrWhiteSpace(i)).Select(v => (ImageType)Enum.Parse(typeof(ImageType), v, true)).ToList();
+ }
+
+ return options;
+ }
+ }
+}
diff --git a/MediaBrowser.Api/Images/ImageService.cs b/MediaBrowser.Api/Images/ImageService.cs
index 9d7362f63a..0e4ccf0b17 100644
--- a/MediaBrowser.Api/Images/ImageService.cs
+++ b/MediaBrowser.Api/Images/ImageService.cs
@@ -567,7 +567,7 @@ namespace MediaBrowser.Api.Images
private async Task<object> GetImageResult(IHasImages item,
ImageRequest request,
ItemImageInfo image,
- ImageOutputFormat format,
+ ImageFormat format,
List<IImageEnhancer> enhancers,
string contentType,
TimeSpan? cacheDuration,
@@ -612,11 +612,11 @@ namespace MediaBrowser.Api.Images
});
}
- private ImageOutputFormat GetOutputFormat(ImageRequest request, ItemImageInfo image, List<IImageEnhancer> enhancers)
+ private ImageFormat GetOutputFormat(ImageRequest request, ItemImageInfo image, List<IImageEnhancer> enhancers)
{
if (!string.IsNullOrWhiteSpace(request.Format))
{
- ImageOutputFormat format;
+ ImageFormat format;
if (Enum.TryParse(request.Format, true, out format))
{
return format;
@@ -627,28 +627,28 @@ namespace MediaBrowser.Api.Images
var clientFormats = GetClientSupportedFormats();
- if (serverFormats.Contains(ImageOutputFormat.Webp) &&
- clientFormats.Contains(ImageOutputFormat.Webp))
+ if (serverFormats.Contains(ImageFormat.Webp) &&
+ clientFormats.Contains(ImageFormat.Webp))
{
- return ImageOutputFormat.Webp;
+ return ImageFormat.Webp;
}
if (enhancers.Count > 0)
{
- return ImageOutputFormat.Png;
+ return ImageFormat.Png;
}
if (string.Equals(Path.GetExtension(image.Path), ".jpg", StringComparison.OrdinalIgnoreCase) ||
string.Equals(Path.GetExtension(image.Path), ".jpeg", StringComparison.OrdinalIgnoreCase))
{
- return ImageOutputFormat.Jpg;
+ return ImageFormat.Jpg;
}
// We can't predict if there will be transparency or not, so play it safe
- return ImageOutputFormat.Png;
+ return ImageFormat.Png;
}
- private ImageOutputFormat[] GetClientSupportedFormats()
+ private ImageFormat[] GetClientSupportedFormats()
{
if ((Request.AcceptTypes ?? new string[] { }).Contains("image/webp", StringComparer.OrdinalIgnoreCase))
{
@@ -657,32 +657,32 @@ namespace MediaBrowser.Api.Images
// Not displaying properly on iOS
if (userAgent.IndexOf("cfnetwork", StringComparison.OrdinalIgnoreCase) == -1)
{
- return new[] { ImageOutputFormat.Webp, ImageOutputFormat.Jpg, ImageOutputFormat.Png };
+ return new[] { ImageFormat.Webp, ImageFormat.Jpg, ImageFormat.Png };
}
}
- return new[] { ImageOutputFormat.Jpg, ImageOutputFormat.Png };
+ return new[] { ImageFormat.Jpg, ImageFormat.Png };
}
- private string GetMimeType(ImageOutputFormat format, string path)
+ private string GetMimeType(ImageFormat format, string path)
{
- if (format == ImageOutputFormat.Bmp)
+ if (format == ImageFormat.Bmp)
{
return Common.Net.MimeTypes.GetMimeType("i.bmp");
}
- if (format == ImageOutputFormat.Gif)
+ if (format == ImageFormat.Gif)
{
return Common.Net.MimeTypes.GetMimeType("i.gif");
}
- if (format == ImageOutputFormat.Jpg)
+ if (format == ImageFormat.Jpg)
{
return Common.Net.MimeTypes.GetMimeType("i.jpg");
}
- if (format == ImageOutputFormat.Png)
+ if (format == ImageFormat.Png)
{
return Common.Net.MimeTypes.GetMimeType("i.png");
}
- if (format == ImageOutputFormat.Webp)
+ if (format == ImageFormat.Webp)
{
return Common.Net.MimeTypes.GetMimeType("i.webp");
}
diff --git a/MediaBrowser.Api/ItemLookupService.cs b/MediaBrowser.Api/ItemLookupService.cs
index b19d6c6549..507d569708 100644
--- a/MediaBrowser.Api/ItemLookupService.cs
+++ b/MediaBrowser.Api/ItemLookupService.cs
@@ -37,12 +37,6 @@ namespace MediaBrowser.Api
{
}
- [Route("/Items/RemoteSearch/Trailer", "POST")]
- [Authenticated]
- public class GetTrailerRemoteSearchResults : RemoteSearchQuery<TrailerInfo>, IReturn<List<RemoteSearchResult>>
- {
- }
-
[Route("/Items/RemoteSearch/AdultVideo", "POST")]
[Authenticated]
public class GetAdultVideoRemoteSearchResults : RemoteSearchQuery<ItemLookupInfo>, IReturn<List<RemoteSearchResult>>
@@ -162,13 +156,6 @@ namespace MediaBrowser.Api
return ToOptimizedResult(result);
}
- public object Post(GetTrailerRemoteSearchResults request)
- {
- var result = _providerManager.GetRemoteSearchResults<Trailer, TrailerInfo>(request, CancellationToken.None).Result;
-
- return ToOptimizedResult(result);
- }
-
public object Post(GetMusicAlbumRemoteSearchResults request)
{
var result = _providerManager.GetRemoteSearchResults<MusicAlbum, AlbumInfo>(request, CancellationToken.None).Result;
diff --git a/MediaBrowser.Api/Library/LibraryService.cs b/MediaBrowser.Api/Library/LibraryService.cs
index 06d8e0478e..5cb007f8fe 100644
--- a/MediaBrowser.Api/Library/LibraryService.cs
+++ b/MediaBrowser.Api/Library/LibraryService.cs
@@ -276,7 +276,7 @@ namespace MediaBrowser.Api.Library
var fields = Enum.GetNames(typeof(ItemFields))
.Select(i => (ItemFields)Enum.Parse(typeof(ItemFields), i, true))
.ToList();
-
+
var result = new ItemsResult
{
TotalRecordCount = items.Count,
@@ -353,7 +353,7 @@ namespace MediaBrowser.Api.Library
.ToList();
BaseItem parent = item.Parent;
-
+
while (parent != null)
{
if (user != null)
@@ -607,7 +607,7 @@ namespace MediaBrowser.Api.Library
}
}
}
-
+
var dtos = themeSongIds.Select(_libraryManager.GetItemById)
.OrderBy(i => i.SortName)
.Select(i => _dtoService.GetBaseItemDto(i, fields, user, item));
diff --git a/MediaBrowser.Api/MediaBrowser.Api.csproj b/MediaBrowser.Api/MediaBrowser.Api.csproj
index dae3790990..286b807b66 100644
--- a/MediaBrowser.Api/MediaBrowser.Api.csproj
+++ b/MediaBrowser.Api/MediaBrowser.Api.csproj
@@ -77,6 +77,7 @@
<Compile Include="Dlna\DlnaServerService.cs" />
<Compile Include="Dlna\DlnaService.cs" />
<Compile Include="FilterService.cs" />
+ <Compile Include="IHasDtoOptions.cs" />
<Compile Include="Library\ChapterService.cs" />
<Compile Include="Playback\Hls\MpegDashService.cs" />
<Compile Include="Playback\MediaInfoService.cs" />
diff --git a/MediaBrowser.Api/Movies/MoviesService.cs b/MediaBrowser.Api/Movies/MoviesService.cs
index ef86a46e8a..fc03ab466e 100644
--- a/MediaBrowser.Api/Movies/MoviesService.cs
+++ b/MediaBrowser.Api/Movies/MoviesService.cs
@@ -200,6 +200,19 @@ namespace MediaBrowser.Api.Movies
.ToList();
}
+ if (item is Video)
+ {
+ var imdbId = item.GetProviderId(MetadataProviders.Imdb);
+
+ // Use imdb id to try to filter duplicates of the same item
+ if (!string.IsNullOrWhiteSpace(imdbId))
+ {
+ list = list
+ .Where(i => !string.Equals(imdbId, i.GetProviderId(MetadataProviders.Imdb), StringComparison.OrdinalIgnoreCase))
+ .ToList();
+ }
+ }
+
var items = SimilarItemsHelper.GetSimilaritems(item, list, getSimilarityScore).ToList();
IEnumerable<BaseItem> returnItems = items;
@@ -208,7 +221,7 @@ namespace MediaBrowser.Api.Movies
{
returnItems = returnItems.Take(request.Limit.Value);
}
-
+
var result = new ItemsResult
{
Items = returnItems.Select(i => _dtoService.GetBaseItemDto(i, fields, user)).ToArray(),
diff --git a/MediaBrowser.Api/Movies/TrailersService.cs b/MediaBrowser.Api/Movies/TrailersService.cs
index a6024d4610..8e1704af73 100644
--- a/MediaBrowser.Api/Movies/TrailersService.cs
+++ b/MediaBrowser.Api/Movies/TrailersService.cs
@@ -92,7 +92,7 @@ namespace MediaBrowser.Api.Movies
Logger,
// Strip out secondary versions
- request, item => (item is Movie || item is Trailer) && !((Video)item).PrimaryVersionId.HasValue,
+ request, item => (item is Movie) && !((Video)item).PrimaryVersionId.HasValue,
SimilarItemsHelper.GetSimiliarityScore);
diff --git a/MediaBrowser.Api/Music/InstantMixService.cs b/MediaBrowser.Api/Music/InstantMixService.cs
index f342422426..43fd0894b9 100644
--- a/MediaBrowser.Api/Music/InstantMixService.cs
+++ b/MediaBrowser.Api/Music/InstantMixService.cs
@@ -3,6 +3,7 @@ using MediaBrowser.Controller.Entities;
using MediaBrowser.Controller.Entities.Audio;
using MediaBrowser.Controller.Library;
using MediaBrowser.Controller.Net;
+using MediaBrowser.Controller.Playlists;
using MediaBrowser.Model.Querying;
using ServiceStack;
using System.Collections.Generic;
@@ -20,6 +21,11 @@ namespace MediaBrowser.Api.Music
{
}
+ [Route("/Playlists/{Id}/InstantMix", "GET", Summary = "Creates an instant playlist based on a given playlist")]
+ public class GetInstantMixFromPlaylist : BaseGetSimilarItemsFromItem
+ {
+ }
+
[Route("/Artists/{Name}/InstantMix", "GET", Summary = "Creates an instant playlist based on a given artist")]
public class GetInstantMixFromArtist : BaseGetSimilarItems
{
@@ -109,6 +115,17 @@ namespace MediaBrowser.Api.Music
return GetResult(items, user, request);
}
+ public object Get(GetInstantMixFromPlaylist request)
+ {
+ var playlist = (Playlist)_libraryManager.GetItemById(request.Id);
+
+ var user = _userManager.GetUserById(request.UserId.Value);
+
+ var items = _musicManager.GetInstantMixFromPlaylist(playlist, user);
+
+ return GetResult(items, user, request);
+ }
+
public object Get(GetInstantMixFromMusicGenre request)
{
var user = _userManager.GetUserById(request.UserId.Value);
diff --git a/MediaBrowser.Api/PackageReviewService.cs b/MediaBrowser.Api/PackageReviewService.cs
index 112a2c5cea..ce366ccd4c 100644
--- a/MediaBrowser.Api/PackageReviewService.cs
+++ b/MediaBrowser.Api/PackageReviewService.cs
@@ -1,5 +1,4 @@
-using MediaBrowser.Common.Constants;
-using MediaBrowser.Common.Net;
+using MediaBrowser.Common.Net;
using MediaBrowser.Controller.Net;
using MediaBrowser.Model.Entities;
using MediaBrowser.Model.Serialization;
@@ -103,6 +102,7 @@ namespace MediaBrowser.Api
private readonly IHttpClient _httpClient;
private readonly INetworkManager _netManager;
private readonly IJsonSerializer _serializer;
+ private const string MbAdminUrl = "https://www.mb3admin.com/admin/";
public PackageReviewService(IHttpClient client, INetworkManager net, IJsonSerializer serializer)
{
@@ -132,7 +132,7 @@ namespace MediaBrowser.Api
parms += "&title=true";
}
- var result = _httpClient.Get(Constants.MbAdminUrl + "/service/packageReview/retrieve" + parms, CancellationToken.None).Result;
+ var result = _httpClient.Get(MbAdminUrl + "/service/packageReview/retrieve" + parms, CancellationToken.None).Result;
var reviews = _serializer.DeserializeFromStream<List<PackageReviewInfo>>(result);
@@ -153,7 +153,7 @@ namespace MediaBrowser.Api
{ "review", reviewText },
};
- Task.WaitAll(_httpClient.Post(Constants.MbAdminUrl + "/service/packageReview/update", review, CancellationToken.None));
+ Task.WaitAll(_httpClient.Post(MbAdminUrl + "/service/packageReview/update", review, CancellationToken.None));
}
}
}
diff --git a/MediaBrowser.Api/PackageService.cs b/MediaBrowser.Api/PackageService.cs
index cf87b42e8e..136969b170 100644
--- a/MediaBrowser.Api/PackageService.cs
+++ b/MediaBrowser.Api/PackageService.cs
@@ -173,9 +173,10 @@ namespace MediaBrowser.Api
public object Get(GetPackage request)
{
var packages = _installationManager.GetAvailablePackages(CancellationToken.None, applicationVersion: _appHost.ApplicationVersion).Result;
+ var list = packages.ToList();
- var result = packages.FirstOrDefault(p => string.Equals(p.guid, request.AssemblyGuid ?? "none", StringComparison.OrdinalIgnoreCase))
- ?? packages.FirstOrDefault(p => p.name.Equals(request.Name, StringComparison.OrdinalIgnoreCase));
+ var result = list.FirstOrDefault(p => string.Equals(p.guid, request.AssemblyGuid ?? "none", StringComparison.OrdinalIgnoreCase))
+ ?? list.FirstOrDefault(p => p.name.Equals(request.Name, StringComparison.OrdinalIgnoreCase));
return ToOptimizedResult(result);
}
@@ -243,4 +244,4 @@ namespace MediaBrowser.Api
}
}
-} \ No newline at end of file
+}
diff --git a/MediaBrowser.Api/Playback/BaseStreamingService.cs b/MediaBrowser.Api/Playback/BaseStreamingService.cs
index 21c4a3dffe..12ccfb6b1d 100644
--- a/MediaBrowser.Api/Playback/BaseStreamingService.cs
+++ b/MediaBrowser.Api/Playback/BaseStreamingService.cs
@@ -2011,11 +2011,6 @@ namespace MediaBrowser.Api.Playback
state.EstimateContentLength = transcodingProfile.EstimateContentLength;
state.EnableMpegtsM2TsMode = transcodingProfile.EnableMpegtsM2TsMode;
state.TranscodeSeekInfo = transcodingProfile.TranscodeSeekInfo;
-
- if (state.VideoRequest != null && string.IsNullOrWhiteSpace(state.VideoRequest.Profile))
- {
- state.VideoRequest.Profile = transcodingProfile.VideoProfile;
- }
}
}
diff --git a/MediaBrowser.Api/PlaylistService.cs b/MediaBrowser.Api/PlaylistService.cs
index 5325e9c448..7f7717f71b 100644
--- a/MediaBrowser.Api/PlaylistService.cs
+++ b/MediaBrowser.Api/PlaylistService.cs
@@ -151,7 +151,7 @@ namespace MediaBrowser.Api
{
items = items.Take(request.Limit.Value).ToArray();
}
-
+
var dtos = items
.Select(i => _dtoService.GetBaseItemDto(i.Item2, request.GetItemFields().ToList(), user))
.ToArray();
diff --git a/MediaBrowser.Api/Session/SessionsService.cs b/MediaBrowser.Api/Session/SessionsService.cs
index 7721107942..df50255abb 100644
--- a/MediaBrowser.Api/Session/SessionsService.cs
+++ b/MediaBrowser.Api/Session/SessionsService.cs
@@ -238,6 +238,12 @@ namespace MediaBrowser.Api.Session
[ApiMember(Name = "SupportsContentUploading", Description = "Determines whether camera upload is supported.", IsRequired = false, DataType = "bool", ParameterType = "query", Verb = "POST")]
public bool SupportsContentUploading { get; set; }
+
+ [ApiMember(Name = "SupportsSync", Description = "Determines whether sync is supported.", IsRequired = false, DataType = "bool", ParameterType = "query", Verb = "POST")]
+ public bool SupportsSync { get; set; }
+
+ [ApiMember(Name = "SupportsUniqueIdentifier", Description = "Determines whether the device supports a unique identifier.", IsRequired = false, DataType = "bool", ParameterType = "query", Verb = "POST")]
+ public bool SupportsUniqueIdentifier { get; set; }
}
[Route("/Sessions/Logout", "POST", Summary = "Reports that a session has ended")]
@@ -516,7 +522,11 @@ namespace MediaBrowser.Api.Session
MessageCallbackUrl = request.MessageCallbackUrl,
- SupportsContentUploading = request.SupportsContentUploading
+ SupportsContentUploading = request.SupportsContentUploading,
+
+ SupportsSync = request.SupportsSync,
+
+ SupportsUniqueIdentifier = request.SupportsUniqueIdentifier
});
}
}
diff --git a/MediaBrowser.Api/StartupWizardService.cs b/MediaBrowser.Api/StartupWizardService.cs
index fd50191264..4443b2a2bc 100644
--- a/MediaBrowser.Api/StartupWizardService.cs
+++ b/MediaBrowser.Api/StartupWizardService.cs
@@ -61,6 +61,7 @@ namespace MediaBrowser.Api
public void Post(ReportStartupWizardComplete request)
{
_config.Configuration.IsStartupWizardCompleted = true;
+ _config.Configuration.EnableLocalizedGuids = true;
_config.SaveConfiguration();
}
diff --git a/MediaBrowser.Api/TvShowsService.cs b/MediaBrowser.Api/TvShowsService.cs
index 2f9bbca476..d1464cd262 100644
--- a/MediaBrowser.Api/TvShowsService.cs
+++ b/MediaBrowser.Api/TvShowsService.cs
@@ -19,7 +19,7 @@ namespace MediaBrowser.Api
/// Class GetNextUpEpisodes
/// </summary>
[Route("/Shows/NextUp", "GET", Summary = "Gets a list of next up episodes")]
- public class GetNextUpEpisodes : IReturn<ItemsResult>, IHasItemFields
+ public class GetNextUpEpisodes : IReturn<ItemsResult>, IHasDtoOptions
{
/// <summary>
/// Gets or sets the user id.
@@ -58,10 +58,19 @@ namespace MediaBrowser.Api
/// <value>The parent id.</value>
[ApiMember(Name = "ParentId", Description = "Specify this to localize the search to a specific item or folder. Omit to use the root", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET")]
public string ParentId { get; set; }
+
+ [ApiMember(Name = "EnableImages", Description = "Optional, include image information in output", IsRequired = false, DataType = "boolean", ParameterType = "query", Verb = "GET")]
+ public bool? EnableImages { get; set; }
+
+ [ApiMember(Name = "ImageTypeLimit", Description = "Optional, the max number of images to return, per image type", IsRequired = false, DataType = "int", ParameterType = "query", Verb = "GET")]
+ public int? ImageTypeLimit { get; set; }
+
+ [ApiMember(Name = "EnableImageTypes", Description = "Optional. The image types to include in the output.", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET")]
+ public string EnableImageTypes { get; set; }
}
[Route("/Shows/Upcoming", "GET", Summary = "Gets a list of upcoming episodes")]
- public class GetUpcomingEpisodes : IReturn<ItemsResult>, IHasItemFields
+ public class GetUpcomingEpisodes : IReturn<ItemsResult>, IHasDtoOptions
{
/// <summary>
/// Gets or sets the user id.
@@ -97,6 +106,15 @@ namespace MediaBrowser.Api
/// <value>The parent id.</value>
[ApiMember(Name = "ParentId", Description = "Specify this to localize the search to a specific item or folder. Omit to use the root", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET")]
public string ParentId { get; set; }
+
+ [ApiMember(Name = "EnableImages", Description = "Optional, include image information in output", IsRequired = false, DataType = "boolean", ParameterType = "query", Verb = "GET")]
+ public bool? EnableImages { get; set; }
+
+ [ApiMember(Name = "ImageTypeLimit", Description = "Optional, the max number of images to return, per image type", IsRequired = false, DataType = "int", ParameterType = "query", Verb = "GET")]
+ public int? ImageTypeLimit { get; set; }
+
+ [ApiMember(Name = "EnableImageTypes", Description = "Optional. The image types to include in the output.", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET")]
+ public string EnableImageTypes { get; set; }
}
[Route("/Shows/{Id}/Similar", "GET", Summary = "Finds tv shows similar to a given one.")]
@@ -252,9 +270,9 @@ namespace MediaBrowser.Api
var pagedItems = ApplyPaging(previousEpisodes, request.StartIndex, request.Limit);
- var fields = request.GetItemFields().ToList();
+ var options = request.GetDtoOptions();
- var returnItems = pagedItems.Select(i => _dtoService.GetBaseItemDto(i, fields, user)).ToArray();
+ var returnItems = pagedItems.Select(i => _dtoService.GetBaseItemDto(i, options, user)).ToArray();
var result = new ItemsResult
{
@@ -283,9 +301,9 @@ namespace MediaBrowser.Api
var user = _userManager.GetUserById(request.UserId);
- var fields = request.GetItemFields().ToList();
+ var options = request.GetDtoOptions();
- var returnItems = result.Items.Select(i => _dtoService.GetBaseItemDto(i, fields, user)).ToArray();
+ var returnItems = result.Items.Select(i => _dtoService.GetBaseItemDto(i, options, user)).ToArray();
return ToOptimizedSerializedResultUsingCache(new ItemsResult
{
diff --git a/MediaBrowser.Api/UserLibrary/ArtistsService.cs b/MediaBrowser.Api/UserLibrary/ArtistsService.cs
index 07015ecae2..2299b2b1aa 100644
--- a/MediaBrowser.Api/UserLibrary/ArtistsService.cs
+++ b/MediaBrowser.Api/UserLibrary/ArtistsService.cs
@@ -89,7 +89,7 @@ namespace MediaBrowser.Api.UserLibrary
if (request.UserId.HasValue)
{
var user = UserManager.GetUserById(request.UserId.Value);
-
+
return DtoService.GetBaseItemDto(item, fields.ToList(), user);
}
diff --git a/MediaBrowser.Api/UserLibrary/BaseItemsByNameService.cs b/MediaBrowser.Api/UserLibrary/BaseItemsByNameService.cs
index 3ae53daf88..9d211a4199 100644
--- a/MediaBrowser.Api/UserLibrary/BaseItemsByNameService.cs
+++ b/MediaBrowser.Api/UserLibrary/BaseItemsByNameService.cs
@@ -127,11 +127,11 @@ namespace MediaBrowser.Api.UserLibrary
}
- var fields = request.GetItemFields().ToList();
-
var tuples = ibnItems.Select(i => new Tuple<TItemType, List<BaseItem>>(i, i.GetTaggedItems(libraryItems).ToList()));
- var dtos = tuples.Select(i => GetDto(i.Item1, user, fields, i.Item2));
+ var dtoOptions = request.GetDtoOptions();
+
+ var dtos = tuples.Select(i => GetDto(i.Item1, user, dtoOptions, i.Item2));
result.Items = dtos.Where(i => i != null).ToArray();
@@ -332,12 +332,12 @@ namespace MediaBrowser.Api.UserLibrary
/// </summary>
/// <param name="item">The item.</param>
/// <param name="user">The user.</param>
- /// <param name="fields">The fields.</param>
+ /// <param name="options">The options.</param>
/// <param name="libraryItems">The library items.</param>
/// <returns>Task{DtoBaseItem}.</returns>
- private BaseItemDto GetDto(TItemType item, User user, List<ItemFields> fields, List<BaseItem> libraryItems)
+ private BaseItemDto GetDto(TItemType item, User user, DtoOptions options, List<BaseItem> libraryItems)
{
- var dto = DtoService.GetItemByNameDto(item, fields, libraryItems, user);
+ var dto = DtoService.GetItemByNameDto(item, options, libraryItems, user);
return dto;
}
diff --git a/MediaBrowser.Api/UserLibrary/BaseItemsRequest.cs b/MediaBrowser.Api/UserLibrary/BaseItemsRequest.cs
index 6b0c64b797..fffc11d68f 100644
--- a/MediaBrowser.Api/UserLibrary/BaseItemsRequest.cs
+++ b/MediaBrowser.Api/UserLibrary/BaseItemsRequest.cs
@@ -7,8 +7,13 @@ using System.Linq;
namespace MediaBrowser.Api.UserLibrary
{
- public abstract class BaseItemsRequest : IHasItemFields
+ public abstract class BaseItemsRequest : IHasDtoOptions
{
+ protected BaseItemsRequest()
+ {
+ EnableImages = true;
+ }
+
/// <summary>
/// Skips over a given number of items within the results. Use for paging.
/// </summary>
@@ -116,6 +121,15 @@ namespace MediaBrowser.Api.UserLibrary
[ApiMember(Name = "Years", Description = "Optional. If specified, results will be filtered based on production year. This allows multiple, comma delimeted.", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET", AllowMultiple = true)]
public string Years { get; set; }
+ [ApiMember(Name = "EnableImages", Description = "Optional, include image information in output", IsRequired = false, DataType = "boolean", ParameterType = "query", Verb = "GET")]
+ public bool? EnableImages { get; set; }
+
+ [ApiMember(Name = "ImageTypeLimit", Description = "Optional, the max number of images to return, per image type", IsRequired = false, DataType = "int", ParameterType = "query", Verb = "GET")]
+ public int? ImageTypeLimit { get; set; }
+
+ [ApiMember(Name = "EnableImageTypes", Description = "Optional. The image types to include in the output.", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET")]
+ public string EnableImageTypes { get; set; }
+
public string[] GetGenres()
{
return (Genres ?? string.Empty).Split(new[] { '|' }, StringSplitOptions.RemoveEmptyEntries);
diff --git a/MediaBrowser.Api/UserLibrary/ItemsService.cs b/MediaBrowser.Api/UserLibrary/ItemsService.cs
index b87ee895af..cf9b0b4387 100644
--- a/MediaBrowser.Api/UserLibrary/ItemsService.cs
+++ b/MediaBrowser.Api/UserLibrary/ItemsService.cs
@@ -321,15 +321,14 @@ namespace MediaBrowser.Api.UserLibrary
var result = await GetItemsToSerialize(request, user, parentItem).ConfigureAwait(false);
var isFiltered = result.Item2;
+ var dtoOptions = request.GetDtoOptions();
if (isFiltered)
{
- var currentFields = request.GetItemFields().ToList();
-
return new ItemsResult
{
TotalRecordCount = result.Item1.TotalRecordCount,
- Items = result.Item1.Items.Select(i => _dtoService.GetBaseItemDto(i, currentFields, user)).ToArray()
+ Items = result.Item1.Items.Select(i => _dtoService.GetBaseItemDto(i, dtoOptions, user)).ToArray()
};
}
@@ -363,9 +362,7 @@ namespace MediaBrowser.Api.UserLibrary
var pagedItems = ApplyPaging(request, itemsArray);
- var fields = request.GetItemFields().ToList();
-
- var returnItems = pagedItems.Select(i => _dtoService.GetBaseItemDto(i, fields, user)).ToArray();
+ var returnItems = pagedItems.Select(i => _dtoService.GetBaseItemDto(i, dtoOptions, user)).ToArray();
return new ItemsResult
{
@@ -880,7 +877,7 @@ namespace MediaBrowser.Api.UserLibrary
var hasTrailers = i as IHasTrailers;
if (hasTrailers != null)
{
- trailerCount = hasTrailers.LocalTrailerIds.Count;
+ trailerCount = hasTrailers.GetTrailerIds().Count;
}
var ok = val ? trailerCount > 0 : trailerCount == 0;
diff --git a/MediaBrowser.Api/UserLibrary/UserLibraryService.cs b/MediaBrowser.Api/UserLibrary/UserLibraryService.cs
index fd0e79a217..040cad436e 100644
--- a/MediaBrowser.Api/UserLibrary/UserLibraryService.cs
+++ b/MediaBrowser.Api/UserLibrary/UserLibraryService.cs
@@ -221,7 +221,7 @@ namespace MediaBrowser.Api.UserLibrary
}
[Route("/Users/{UserId}/Items/Latest", "GET", Summary = "Gets latest media")]
- public class GetLatestMedia : IReturn<List<BaseItemDto>>, IHasItemFields
+ public class GetLatestMedia : IReturn<List<BaseItemDto>>, IHasDtoOptions
{
/// <summary>
/// Gets or sets the user id.
@@ -251,6 +251,15 @@ namespace MediaBrowser.Api.UserLibrary
[ApiMember(Name = "GroupItems", Description = "Whether or not to group items into a parent container.", IsRequired = false, DataType = "bool", ParameterType = "query", Verb = "GET")]
public bool GroupItems { get; set; }
+ [ApiMember(Name = "EnableImages", Description = "Optional, include image information in output", IsRequired = false, DataType = "boolean", ParameterType = "query", Verb = "GET")]
+ public bool? EnableImages { get; set; }
+
+ [ApiMember(Name = "ImageTypeLimit", Description = "Optional, the max number of images to return, per image type", IsRequired = false, DataType = "int", ParameterType = "query", Verb = "GET")]
+ public int? ImageTypeLimit { get; set; }
+
+ [ApiMember(Name = "EnableImageTypes", Description = "Optional. The image types to include in the output.", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET")]
+ public string EnableImageTypes { get; set; }
+
public GetLatestMedia()
{
Limit = 20;
@@ -362,7 +371,7 @@ namespace MediaBrowser.Api.UserLibrary
}
}
- var fields = request.GetItemFields().ToList();
+ var options = request.GetDtoOptions();
var dtos = list.Select(i =>
{
@@ -375,7 +384,7 @@ namespace MediaBrowser.Api.UserLibrary
childCount = i.Item2.Count;
}
- var dto = _dtoService.GetBaseItemDto(item, fields, user);
+ var dto = _dtoService.GetBaseItemDto(item, options, user);
dto.ChildCount = childCount;
@@ -506,7 +515,7 @@ namespace MediaBrowser.Api.UserLibrary
var hasTrailers = item as IHasTrailers;
if (hasTrailers != null)
{
- trailerIds = hasTrailers.LocalTrailerIds;
+ trailerIds = hasTrailers.GetTrailerIds();
}
var dtos = trailerIds
diff --git a/MediaBrowser.Common.Implementations/HttpClientManager/HttpClientManager.cs b/MediaBrowser.Common.Implementations/HttpClientManager/HttpClientManager.cs
index 900009a238..89d00b87dc 100644
--- a/MediaBrowser.Common.Implementations/HttpClientManager/HttpClientManager.cs
+++ b/MediaBrowser.Common.Implementations/HttpClientManager/HttpClientManager.cs
@@ -1,4 +1,5 @@
-using MediaBrowser.Common.Configuration;
+using System.Net.Sockets;
+using MediaBrowser.Common.Configuration;
using MediaBrowser.Common.Extensions;
using MediaBrowser.Common.IO;
using MediaBrowser.Common.Net;
@@ -134,9 +135,22 @@ namespace MediaBrowser.Common.Implementations.HttpClientManager
request.Referer = options.Referer;
}
+ //request.ServicePoint.BindIPEndPointDelegate = BindIPEndPointCallback;
+
return request;
}
+ private static IPEndPoint BindIPEndPointCallback(ServicePoint servicePoint, IPEndPoint remoteEndPoint, int retryCount)
+ {
+ // Prefer local ipv4
+ if (remoteEndPoint.AddressFamily == AddressFamily.InterNetworkV6)
+ {
+ return new IPEndPoint(IPAddress.IPv6Any, 0);
+ }
+
+ return new IPEndPoint(IPAddress.Any, 0);
+ }
+
private void AddRequestHeaders(HttpWebRequest request, HttpRequestOptions options)
{
foreach (var header in options.RequestHeaders.ToList())
diff --git a/MediaBrowser.Common.Implementations/Logging/LogHelper.cs b/MediaBrowser.Common.Implementations/Logging/LogHelper.cs
index 91e937ca7c..8080c2111c 100644
--- a/MediaBrowser.Common.Implementations/Logging/LogHelper.cs
+++ b/MediaBrowser.Common.Implementations/Logging/LogHelper.cs
@@ -15,6 +15,11 @@ namespace MediaBrowser.Common.Implementations.Logging
/// <returns>StringBuilder.</returns>
public static StringBuilder GetLogMessage(Exception exception)
{
+ if (exception == null)
+ {
+ throw new ArgumentNullException("exception");
+ }
+
var messageText = new StringBuilder();
messageText.AppendLine(exception.Message);
diff --git a/MediaBrowser.Common.Implementations/Networking/BaseNetworkManager.cs b/MediaBrowser.Common.Implementations/Networking/BaseNetworkManager.cs
index 2a1c5dfe68..bf6ebf7ef7 100644
--- a/MediaBrowser.Common.Implementations/Networking/BaseNetworkManager.cs
+++ b/MediaBrowser.Common.Implementations/Networking/BaseNetworkManager.cs
@@ -24,14 +24,28 @@ namespace MediaBrowser.Common.Implementations.Networking
/// <returns>IPAddress.</returns>
public IEnumerable<string> GetLocalIpAddresses()
{
- var list = GetIPsDefault().Where(i => !IPAddress.IsLoopback(i)).Select(i => i.ToString()).ToList();
+ var list = GetIPsDefault()
+ .Where(i => !IPAddress.IsLoopback(i))
+ .Select(i => i.ToString())
+ .Where(FilterIpAddress)
+ .ToList();
if (list.Count > 0)
{
return list;
}
- return GetLocalIpAddressesFallback();
+ return GetLocalIpAddressesFallback().Where(FilterIpAddress);
+ }
+
+ private bool FilterIpAddress(string address)
+ {
+ if (address.StartsWith("169.", StringComparison.OrdinalIgnoreCase))
+ {
+ return false;
+ }
+
+ return true;
}
private bool IsInPrivateAddressSpace(string endpoint)
diff --git a/MediaBrowser.Common.Implementations/Security/PluginSecurityManager.cs b/MediaBrowser.Common.Implementations/Security/PluginSecurityManager.cs
index 2c387a4ddf..dfdf61016e 100644
--- a/MediaBrowser.Common.Implementations/Security/PluginSecurityManager.cs
+++ b/MediaBrowser.Common.Implementations/Security/PluginSecurityManager.cs
@@ -17,7 +17,9 @@ namespace MediaBrowser.Common.Implementations.Security
/// </summary>
public class PluginSecurityManager : ISecurityManager
{
- private const string MBValidateUrl = Constants.Constants.MbAdminUrl + "service/registration/validate";
+ private const string MbAdminUrl = "https://www.mb3admin.com/admin/";
+
+ private const string MBValidateUrl = MbAdminUrl + "service/registration/validate";
/// <summary>
/// The _is MB supporter
@@ -160,7 +162,7 @@ namespace MediaBrowser.Common.Implementations.Security
return new SupporterInfo();
}
- var url = Constants.Constants.MbAdminUrl + "/service/supporter/retrieve?key=" + key;
+ var url = MbAdminUrl + "/service/supporter/retrieve?key=" + key;
using (var stream = await _httpClient.Get(url, CancellationToken.None).ConfigureAwait(false))
{
diff --git a/MediaBrowser.Common.Implementations/Updates/InstallationManager.cs b/MediaBrowser.Common.Implementations/Updates/InstallationManager.cs
index b022dc6719..0a8ce012f2 100644
--- a/MediaBrowser.Common.Implementations/Updates/InstallationManager.cs
+++ b/MediaBrowser.Common.Implementations/Updates/InstallationManager.cs
@@ -161,7 +161,7 @@ namespace MediaBrowser.Common.Implementations.Updates
{ "systemid", _applicationHost.SystemId }
};
- using (var json = await _httpClient.Post(Constants.Constants.MbAdminUrl + "service/package/retrieveall", data, cancellationToken).ConfigureAwait(false))
+ using (var json = await _httpClient.Post(MbAdminUrl + "service/package/retrieveall", data, cancellationToken).ConfigureAwait(false))
{
cancellationToken.ThrowIfCancellationRequested();
@@ -172,6 +172,7 @@ namespace MediaBrowser.Common.Implementations.Updates
}
private Tuple<List<PackageInfo>, DateTime> _lastPackageListResult;
+ private const string MbAdminUrl = "https://www.mb3admin.com/admin/";
/// <summary>
/// Gets all available packages.
@@ -203,7 +204,7 @@ namespace MediaBrowser.Common.Implementations.Updates
}
}
- using (var json = await _httpClient.Get(Constants.Constants.MbAdminUrl + "service/MB3Packages.json", cancellationToken).ConfigureAwait(false))
+ using (var json = await _httpClient.Get(MbAdminUrl + "service/MB3Packages.json", cancellationToken).ConfigureAwait(false))
{
cancellationToken.ThrowIfCancellationRequested();
diff --git a/MediaBrowser.Common/Constants/Constants.cs b/MediaBrowser.Common/Constants/Constants.cs
deleted file mode 100644
index d569fd8eae..0000000000
--- a/MediaBrowser.Common/Constants/Constants.cs
+++ /dev/null
@@ -1,8 +0,0 @@
-
-namespace MediaBrowser.Common.Constants
-{
- public static class Constants
- {
- public const string MbAdminUrl = "http://www.mb3admin.com/admin/";
- }
-}
diff --git a/MediaBrowser.Common/Extensions/BaseExtensions.cs b/MediaBrowser.Common/Extensions/BaseExtensions.cs
index be2fbffc64..8e96373f44 100644
--- a/MediaBrowser.Common/Extensions/BaseExtensions.cs
+++ b/MediaBrowser.Common/Extensions/BaseExtensions.cs
@@ -1,5 +1,4 @@
using System;
-using System.Globalization;
using System.Security.Cryptography;
using System.Text;
using System.Text.RegularExpressions;
@@ -56,28 +55,6 @@ namespace MediaBrowser.Common.Extensions
}
/// <summary>
- /// Removes the accent.
- /// </summary>
- /// <param name="text">The text.</param>
- /// <returns>System.String.</returns>
- public static string RemoveAccent(this string text)
- {
- var normalizedString = text.Normalize(NormalizationForm.FormD);
- var stringBuilder = new StringBuilder();
-
- foreach (var c in normalizedString)
- {
- var unicodeCategory = CharUnicodeInfo.GetUnicodeCategory(c);
- if (unicodeCategory != UnicodeCategory.NonSpacingMark)
- {
- stringBuilder.Append(c);
- }
- }
-
- return stringBuilder.ToString().Normalize(NormalizationForm.FormC);
- }
-
- /// <summary>
/// Gets the M d5.
/// </summary>
/// <param name="str">The STR.</param>
@@ -96,6 +73,8 @@ namespace MediaBrowser.Common.Extensions
/// <param name="str">The STR.</param>
/// <param name="type">The type.</param>
/// <returns>Guid.</returns>
+ /// <exception cref="System.ArgumentNullException">type</exception>
+ [Obsolete("Use LibraryManager.GetNewItemId")]
public static Guid GetMBId(this string str, Type type)
{
if (type == null)
@@ -107,35 +86,5 @@ namespace MediaBrowser.Common.Extensions
return key.GetMD5();
}
-
- /// <summary>
- /// Gets the attribute value.
- /// </summary>
- /// <param name="str">The STR.</param>
- /// <param name="attrib">The attrib.</param>
- /// <returns>System.String.</returns>
- /// <exception cref="System.ArgumentNullException">attrib</exception>
- public static string GetAttributeValue(this string str, string attrib)
- {
- if (string.IsNullOrEmpty(str))
- {
- throw new ArgumentNullException("str");
- }
-
- if (string.IsNullOrEmpty(attrib))
- {
- throw new ArgumentNullException("attrib");
- }
-
- string srch = "[" + attrib + "=";
- int start = str.IndexOf(srch, StringComparison.OrdinalIgnoreCase);
- if (start > -1)
- {
- start += srch.Length;
- int end = str.IndexOf(']', start);
- return str.Substring(start, end - start);
- }
- return null;
- }
}
}
diff --git a/MediaBrowser.Common/IO/FileSystemRepository.cs b/MediaBrowser.Common/IO/FileSystemRepository.cs
deleted file mode 100644
index 07328d72d9..0000000000
--- a/MediaBrowser.Common/IO/FileSystemRepository.cs
+++ /dev/null
@@ -1,122 +0,0 @@
-using MediaBrowser.Common.Extensions;
-using System;
-using System.IO;
-
-namespace MediaBrowser.Common.IO
-{
- /// <summary>
- /// This is a wrapper for storing large numbers of files within a directory on a file system.
- /// Simply pass a filename into GetResourcePath and it will return a full path location of where the file should be stored.
- /// </summary>
- public class FileSystemRepository
- {
- /// <summary>
- /// Gets or sets the path.
- /// </summary>
- /// <value>The path.</value>
- protected string Path { get; set; }
-
- /// <summary>
- /// Initializes a new instance of the <see cref="FileSystemRepository" /> class.
- /// </summary>
- /// <param name="path">The path.</param>
- /// <exception cref="System.ArgumentNullException"></exception>
- public FileSystemRepository(string path)
- {
- if (string.IsNullOrEmpty(path))
- {
- throw new ArgumentNullException();
- }
-
- Path = path;
- }
-
- /// <summary>
- /// Gets the full path of where a resource should be stored within the repository
- /// </summary>
- /// <param name="uniqueName">Name of the unique.</param>
- /// <param name="fileExtension">The file extension.</param>
- /// <returns>System.String.</returns>
- /// <exception cref="System.ArgumentNullException">
- /// </exception>
- public string GetResourcePath(string uniqueName, string fileExtension)
- {
- if (string.IsNullOrEmpty(uniqueName))
- {
- throw new ArgumentNullException("uniqueName");
- }
-
- if (string.IsNullOrEmpty(fileExtension))
- {
- throw new ArgumentNullException("fileExtension");
- }
-
- var filename = uniqueName.GetMD5() + fileExtension;
-
- return GetResourcePath(filename);
- }
-
- /// <summary>
- /// Gets the resource path.
- /// </summary>
- /// <param name="filename">The filename.</param>
- /// <returns>System.String.</returns>
- /// <exception cref="System.ArgumentNullException"></exception>
- public string GetResourcePath(string filename)
- {
- if (string.IsNullOrEmpty(filename))
- {
- throw new ArgumentNullException("filename");
- }
-
- var prefix = filename.Substring(0, 1);
-
- var path = System.IO.Path.Combine(Path, prefix);
-
- return System.IO.Path.Combine(path, filename);
- }
-
- /// <summary>
- /// Determines if a resource is present in the repository
- /// </summary>
- /// <param name="uniqueName">Name of the unique.</param>
- /// <param name="fileExtension">The file extension.</param>
- /// <returns><c>true</c> if the specified unique name contains resource; otherwise, <c>false</c>.</returns>
- public bool ContainsResource(string uniqueName, string fileExtension)
- {
- return ContainsFilePath(GetResourcePath(uniqueName, fileExtension));
- }
-
- /// <summary>
- /// Determines if a file with a given name is present in the repository
- /// </summary>
- /// <param name="filename">The filename.</param>
- /// <returns><c>true</c> if the specified filename contains filename; otherwise, <c>false</c>.</returns>
- /// <exception cref="System.ArgumentNullException"></exception>
- public bool ContainsFilename(string filename)
- {
- if (string.IsNullOrEmpty(filename))
- {
- throw new ArgumentNullException();
- }
-
- return ContainsFilePath(GetResourcePath(filename));
- }
-
- /// <summary>
- /// Determines if a file is present in the repository
- /// </summary>
- /// <param name="path">The path.</param>
- /// <returns><c>true</c> if [contains file path] [the specified path]; otherwise, <c>false</c>.</returns>
- /// <exception cref="System.ArgumentNullException"></exception>
- public bool ContainsFilePath(string path)
- {
- if (string.IsNullOrEmpty(path))
- {
- throw new ArgumentNullException();
- }
-
- return File.Exists(path);
- }
- }
-}
diff --git a/MediaBrowser.Common/MediaBrowser.Common.csproj b/MediaBrowser.Common/MediaBrowser.Common.csproj
index 6e96feed3a..9fdfccaaf6 100644
--- a/MediaBrowser.Common/MediaBrowser.Common.csproj
+++ b/MediaBrowser.Common/MediaBrowser.Common.csproj
@@ -57,12 +57,10 @@
<Compile Include="Configuration\ConfigurationUpdateEventArgs.cs" />
<Compile Include="Configuration\IConfigurationManager.cs" />
<Compile Include="Configuration\IConfigurationFactory.cs" />
- <Compile Include="Constants\Constants.cs" />
<Compile Include="Events\EventHelper.cs" />
<Compile Include="Extensions\BaseExtensions.cs" />
<Compile Include="Extensions\ResourceNotFoundException.cs" />
<Compile Include="IDependencyContainer.cs" />
- <Compile Include="IO\FileSystemRepository.cs" />
<Compile Include="IO\IFileSystem.cs" />
<Compile Include="IO\ProgressStream.cs" />
<Compile Include="IO\StreamDefaults.cs" />
diff --git a/MediaBrowser.Controller/Collections/CollectionCreationOptions.cs b/MediaBrowser.Controller/Collections/CollectionCreationOptions.cs
index 74ae420950..4a2d390662 100644
--- a/MediaBrowser.Controller/Collections/CollectionCreationOptions.cs
+++ b/MediaBrowser.Controller/Collections/CollectionCreationOptions.cs
@@ -15,11 +15,13 @@ namespace MediaBrowser.Controller.Collections
public Dictionary<string, string> ProviderIds { get; set; }
public List<Guid> ItemIdList { get; set; }
+ public List<Guid> UserIds { get; set; }
public CollectionCreationOptions()
{
ProviderIds = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
ItemIdList = new List<Guid>();
+ UserIds = new List<Guid>();
}
}
}
diff --git a/MediaBrowser.Controller/Devices/IDeviceManager.cs b/MediaBrowser.Controller/Devices/IDeviceManager.cs
index af184e6e93..efd24336af 100644
--- a/MediaBrowser.Controller/Devices/IDeviceManager.cs
+++ b/MediaBrowser.Controller/Devices/IDeviceManager.cs
@@ -1,5 +1,6 @@
using MediaBrowser.Model.Devices;
using MediaBrowser.Model.Events;
+using MediaBrowser.Model.Querying;
using MediaBrowser.Model.Session;
using System;
using System.Collections.Generic;
@@ -58,8 +59,9 @@ namespace MediaBrowser.Controller.Devices
/// <summary>
/// Gets the devices.
/// </summary>
+ /// <param name="query">The query.</param>
/// <returns>IEnumerable&lt;DeviceInfo&gt;.</returns>
- IEnumerable<DeviceInfo> GetDevices();
+ QueryResult<DeviceInfo> GetDevices(DeviceQuery query);
/// <summary>
/// Deletes the device.
diff --git a/MediaBrowser.Controller/Dlna/DlnaIconResponse.cs b/MediaBrowser.Controller/Dlna/DlnaIconResponse.cs
deleted file mode 100644
index 04d8e88b97..0000000000
--- a/MediaBrowser.Controller/Dlna/DlnaIconResponse.cs
+++ /dev/null
@@ -1,22 +0,0 @@
-using MediaBrowser.Controller.Drawing;
-using System;
-using System.IO;
-
-namespace MediaBrowser.Controller.Dlna
-{
- public class DlnaIconResponse : IDisposable
- {
- public Stream Stream { get; set; }
-
- public ImageFormat Format { get; set; }
-
- public void Dispose()
- {
- if (Stream != null)
- {
- Stream.Dispose();
- Stream = null;
- }
- }
- }
-}
diff --git a/MediaBrowser.Controller/Dlna/IDlnaManager.cs b/MediaBrowser.Controller/Dlna/IDlnaManager.cs
index b7a06b368b..34464f6a2d 100644
--- a/MediaBrowser.Controller/Dlna/IDlnaManager.cs
+++ b/MediaBrowser.Controller/Dlna/IDlnaManager.cs
@@ -1,4 +1,5 @@
-using MediaBrowser.Model.Dlna;
+using MediaBrowser.Controller.Drawing;
+using MediaBrowser.Model.Dlna;
using System.Collections.Generic;
namespace MediaBrowser.Controller.Dlna
@@ -69,6 +70,6 @@ namespace MediaBrowser.Controller.Dlna
/// </summary>
/// <param name="filename">The filename.</param>
/// <returns>DlnaIconResponse.</returns>
- DlnaIconResponse GetIcon(string filename);
+ ImageStream GetIcon(string filename);
}
}
diff --git a/MediaBrowser.Controller/Drawing/IImageProcessor.cs b/MediaBrowser.Controller/Drawing/IImageProcessor.cs
index 3bd3335276..8ac7d56d29 100644
--- a/MediaBrowser.Controller/Drawing/IImageProcessor.cs
+++ b/MediaBrowser.Controller/Drawing/IImageProcessor.cs
@@ -94,6 +94,6 @@ namespace MediaBrowser.Controller.Drawing
/// Gets the supported image output formats.
/// </summary>
/// <returns>ImageOutputFormat[].</returns>
- ImageOutputFormat[] GetSupportedImageOutputFormats();
+ ImageFormat[] GetSupportedImageOutputFormats();
}
}
diff --git a/MediaBrowser.Controller/Drawing/ImageFormat.cs b/MediaBrowser.Controller/Drawing/ImageFormat.cs
deleted file mode 100644
index f785625567..0000000000
--- a/MediaBrowser.Controller/Drawing/ImageFormat.cs
+++ /dev/null
@@ -1,11 +0,0 @@
-
-namespace MediaBrowser.Controller.Drawing
-{
- public enum ImageFormat
- {
- Jpg,
- Png,
- Gif,
- Bmp
- }
-}
diff --git a/MediaBrowser.Controller/Drawing/ImageProcessingOptions.cs b/MediaBrowser.Controller/Drawing/ImageProcessingOptions.cs
index b99186f37f..d8f5d52c3b 100644
--- a/MediaBrowser.Controller/Drawing/ImageProcessingOptions.cs
+++ b/MediaBrowser.Controller/Drawing/ImageProcessingOptions.cs
@@ -29,7 +29,7 @@ namespace MediaBrowser.Controller.Drawing
public List<IImageEnhancer> Enhancers { get; set; }
- public ImageOutputFormat OutputFormat { get; set; }
+ public ImageFormat OutputFormat { get; set; }
public bool AddPlayedIndicator { get; set; }
diff --git a/MediaBrowser.Controller/Drawing/ImageStream.cs b/MediaBrowser.Controller/Drawing/ImageStream.cs
new file mode 100644
index 0000000000..353abaca33
--- /dev/null
+++ b/MediaBrowser.Controller/Drawing/ImageStream.cs
@@ -0,0 +1,28 @@
+using MediaBrowser.Model.Drawing;
+using System;
+using System.IO;
+
+namespace MediaBrowser.Controller.Drawing
+{
+ public class ImageStream : IDisposable
+ {
+ /// <summary>
+ /// Gets or sets the stream.
+ /// </summary>
+ /// <value>The stream.</value>
+ public Stream Stream { get; set; }
+ /// <summary>
+ /// Gets or sets the format.
+ /// </summary>
+ /// <value>The format.</value>
+ public ImageFormat Format { get; set; }
+
+ public void Dispose()
+ {
+ if (Stream != null)
+ {
+ Stream.Dispose();
+ }
+ }
+ }
+}
diff --git a/MediaBrowser.Controller/Dto/IDtoService.cs b/MediaBrowser.Controller/Dto/IDtoService.cs
index 61b2caec0d..7c7ec56d50 100644
--- a/MediaBrowser.Controller/Dto/IDtoService.cs
+++ b/MediaBrowser.Controller/Dto/IDtoService.cs
@@ -22,7 +22,8 @@ namespace MediaBrowser.Controller.Dto
/// </summary>
/// <param name="dto">The dto.</param>
/// <param name="item">The item.</param>
- void AttachPrimaryImageAspectRatio(IItemDto dto, IHasImages item);
+ /// <param name="fields">The fields.</param>
+ void AttachPrimaryImageAspectRatio(IItemDto dto, IHasImages item, List<ItemFields> fields);
/// <summary>
/// Gets the base item dto.
@@ -35,6 +36,16 @@ namespace MediaBrowser.Controller.Dto
BaseItemDto GetBaseItemDto(BaseItem item, List<ItemFields> fields, User user = null, BaseItem owner = null);
/// <summary>
+ /// Gets the base item dto.
+ /// </summary>
+ /// <param name="item">The item.</param>
+ /// <param name="options">The options.</param>
+ /// <param name="user">The user.</param>
+ /// <param name="owner">The owner.</param>
+ /// <returns>BaseItemDto.</returns>
+ BaseItemDto GetBaseItemDto(BaseItem item, DtoOptions options, User user = null, BaseItem owner = null);
+
+ /// <summary>
/// Gets the chapter information dto.
/// </summary>
/// <param name="item">The item.</param>
@@ -51,12 +62,13 @@ namespace MediaBrowser.Controller.Dto
/// <summary>
/// Gets the item by name dto.
/// </summary>
+ /// <typeparam name="T"></typeparam>
/// <param name="item">The item.</param>
- /// <param name="fields">The fields.</param>
+ /// <param name="options">The options.</param>
/// <param name="taggedItems">The tagged items.</param>
/// <param name="user">The user.</param>
/// <returns>BaseItemDto.</returns>
- BaseItemDto GetItemByNameDto<T>(T item, List<ItemFields> fields, List<BaseItem> taggedItems, User user = null)
+ BaseItemDto GetItemByNameDto<T>(T item, DtoOptions options, List<BaseItem> taggedItems, User user = null)
where T : BaseItem, IItemByName;
}
}
diff --git a/MediaBrowser.Controller/Entities/BaseItem.cs b/MediaBrowser.Controller/Entities/BaseItem.cs
index 990ea49f67..e01b8857f6 100644
--- a/MediaBrowser.Controller/Entities/BaseItem.cs
+++ b/MediaBrowser.Controller/Entities/BaseItem.cs
@@ -53,16 +53,6 @@ namespace MediaBrowser.Controller.Entities
public static string ThemeSongFilename = "theme";
public static string ThemeVideosFolderName = "backdrops";
- public static List<KeyValuePair<string, ExtraType>> ExtraSuffixes = new List<KeyValuePair<string, ExtraType>>
- {
- new KeyValuePair<string,ExtraType>("-trailer", ExtraType.Trailer),
- new KeyValuePair<string,ExtraType>("-deleted", ExtraType.DeletedScene),
- new KeyValuePair<string,ExtraType>("-behindthescenes", ExtraType.BehindTheScenes),
- new KeyValuePair<string,ExtraType>("-interview", ExtraType.Interview),
- new KeyValuePair<string,ExtraType>("-scene", ExtraType.Scene),
- new KeyValuePair<string,ExtraType>("-sample", ExtraType.Sample)
- };
-
public List<ItemImageInfo> ImageInfos { get; set; }
[IgnoreDataMember]
@@ -222,6 +212,20 @@ namespace MediaBrowser.Controller.Entities
}
}
+ [IgnoreDataMember]
+ public virtual string FileNameWithoutExtension
+ {
+ get
+ {
+ if (LocationType == LocationType.FileSystem)
+ {
+ return System.IO.Path.GetFileNameWithoutExtension(Path);
+ }
+
+ return null;
+ }
+ }
+
/// <summary>
/// This is just a helper for convenience
/// </summary>
@@ -361,6 +365,15 @@ namespace MediaBrowser.Controller.Entities
}
}
+ public bool ContainsPerson(string name)
+ {
+ if (string.IsNullOrWhiteSpace(name))
+ {
+ throw new ArgumentNullException("name");
+ }
+ return People.Any(i => string.Equals(i.Name, name, StringComparison.OrdinalIgnoreCase));
+ }
+
public string GetInternalMetadataPath()
{
return GetInternalMetadataPath(ConfigurationManager.ApplicationPaths.InternalMetadataPath);
@@ -594,118 +607,6 @@ namespace MediaBrowser.Controller.Entities
}
/// <summary>
- /// Loads local trailers from the file system
- /// </summary>
- /// <returns>List{Video}.</returns>
- private IEnumerable<Trailer> LoadLocalTrailers(List<FileSystemInfo> fileSystemChildren, IDirectoryService directoryService)
- {
- var files = fileSystemChildren.OfType<DirectoryInfo>()
- .Where(i => string.Equals(i.Name, TrailerFolderName, StringComparison.OrdinalIgnoreCase))
- .SelectMany(i => i.EnumerateFiles("*", SearchOption.TopDirectoryOnly))
- .ToList();
-
- var extraTypes = new List<ExtraType> { ExtraType.Trailer };
- var suffixes = ExtraSuffixes.Where(i => extraTypes.Contains(i.Value))
- .Select(i => i.Key)
- .ToList();
-
- files.AddRange(fileSystemChildren.OfType<FileInfo>()
- .Where(i =>
- {
- var nameEithoutExtension = FileSystem.GetFileNameWithoutExtension(i);
-
- if (!suffixes.Any(s => nameEithoutExtension.EndsWith(s, StringComparison.OrdinalIgnoreCase)))
- {
- return false;
- }
-
- return !string.Equals(Path, i.FullName, StringComparison.OrdinalIgnoreCase);
- }));
-
- return LibraryManager.ResolvePaths<Trailer>(files, directoryService, null).Select(video =>
- {
- // Try to retrieve it from the db. If we don't find it, use the resolved version
- var dbItem = LibraryManager.GetItemById(video.Id) as Trailer;
-
- if (dbItem != null)
- {
- video = dbItem;
- }
-
- if (video != null)
- {
- video.ExtraType = ExtraType.Trailer;
- }
-
- return video;
-
- // Sort them so that the list can be easily compared for changes
- }).OrderBy(i => i.Path).ToList();
- }
-
- protected IEnumerable<Video> LoadSpecialFeatures(List<FileSystemInfo> fileSystemChildren, IDirectoryService directoryService)
- {
- var files = fileSystemChildren.OfType<DirectoryInfo>()
- .Where(i => string.Equals(i.Name, "extras", StringComparison.OrdinalIgnoreCase) || string.Equals(i.Name, "specials", StringComparison.OrdinalIgnoreCase))
- .SelectMany(i => i.EnumerateFiles("*", SearchOption.TopDirectoryOnly))
- .ToList();
-
- var extraTypes = new List<ExtraType> { ExtraType.BehindTheScenes, ExtraType.DeletedScene, ExtraType.Interview, ExtraType.Sample, ExtraType.Scene, ExtraType.Clip };
- var suffixes = ExtraSuffixes.Where(i => extraTypes.Contains(i.Value))
- .Select(i => i.Key)
- .ToList();
-
- files.AddRange(fileSystemChildren.OfType<FileInfo>()
- .Where(i =>
- {
- var nameEithoutExtension = FileSystem.GetFileNameWithoutExtension(i);
-
- if (!suffixes.Any(s => nameEithoutExtension.EndsWith(s, StringComparison.OrdinalIgnoreCase)))
- {
- return false;
- }
-
- return !string.Equals(Path, i.FullName, StringComparison.OrdinalIgnoreCase);
- }));
-
- return LibraryManager.ResolvePaths<Video>(files, directoryService, null).Select(video =>
- {
- // Try to retrieve it from the db. If we don't find it, use the resolved version
- var dbItem = LibraryManager.GetItemById(video.Id) as Video;
-
- if (dbItem != null)
- {
- video = dbItem;
- }
-
- if (video != null)
- {
- SetExtraTypeFromFilename(video);
- }
-
- return video;
-
- // Sort them so that the list can be easily compared for changes
- }).OrderBy(i => i.Path).ToList();
- }
-
- private void SetExtraTypeFromFilename(Video item)
- {
- var name = System.IO.Path.GetFileNameWithoutExtension(item.Path) ?? string.Empty;
-
- foreach (var suffix in ExtraSuffixes)
- {
- if (name.EndsWith(suffix.Key, StringComparison.OrdinalIgnoreCase))
- {
- item.ExtraType = suffix.Value;
- return;
- }
- }
-
- item.ExtraType = ExtraType.Clip;
- }
-
- /// <summary>
/// Loads the theme songs.
/// </summary>
/// <returns>List{Audio.Audio}.</returns>
@@ -721,7 +622,9 @@ namespace MediaBrowser.Controller.Entities
.Where(i => string.Equals(FileSystem.GetFileNameWithoutExtension(i), ThemeSongFilename, StringComparison.OrdinalIgnoreCase))
);
- return LibraryManager.ResolvePaths<Audio.Audio>(files, directoryService, null).Select(audio =>
+ return LibraryManager.ResolvePaths(files, directoryService, null)
+ .OfType<Audio.Audio>()
+ .Select(audio =>
{
// Try to retrieve it from the db. If we don't find it, use the resolved version
var dbItem = LibraryManager.GetItemById(audio.Id) as Audio.Audio;
@@ -731,10 +634,7 @@ namespace MediaBrowser.Controller.Entities
audio = dbItem;
}
- if (audio != null)
- {
- audio.ExtraType = ExtraType.ThemeSong;
- }
+ audio.ExtraType = ExtraType.ThemeSong;
return audio;
@@ -752,7 +652,9 @@ namespace MediaBrowser.Controller.Entities
.Where(i => string.Equals(i.Name, ThemeVideosFolderName, StringComparison.OrdinalIgnoreCase))
.SelectMany(i => i.EnumerateFiles("*", SearchOption.TopDirectoryOnly));
- return LibraryManager.ResolvePaths<Video>(files, directoryService, null).Select(item =>
+ return LibraryManager.ResolvePaths(files, directoryService, null)
+ .OfType<Video>()
+ .Select(item =>
{
// Try to retrieve it from the db. If we don't find it, use the resolved version
var dbItem = LibraryManager.GetItemById(item.Id) as Video;
@@ -762,10 +664,7 @@ namespace MediaBrowser.Controller.Entities
item = dbItem;
}
- if (item != null)
- {
- item.ExtraType = ExtraType.ThemeVideo;
- }
+ item.ExtraType = ExtraType.ThemeVideo;
return item;
@@ -870,7 +769,8 @@ namespace MediaBrowser.Controller.Entities
private async Task<bool> RefreshLocalTrailers(IHasTrailers item, MetadataRefreshOptions options, List<FileSystemInfo> fileSystemChildren, CancellationToken cancellationToken)
{
- var newItems = LoadLocalTrailers(fileSystemChildren, options.DirectoryService).ToList();
+ var newItems = LibraryManager.FindTrailers(this, fileSystemChildren, options.DirectoryService).ToList();
+
var newItemIds = newItems.Select(i => i.Id).ToList();
var itemsChanged = !item.LocalTrailerIds.SequenceEqual(newItemIds);
@@ -995,6 +895,28 @@ namespace MediaBrowser.Controller.Entities
return Id.ToString();
}
+ internal virtual bool IsValidFromResolver(BaseItem newItem)
+ {
+ var current = this;
+
+ var currentAsPlaceHolder = current as ISupportsPlaceHolders;
+
+ if (currentAsPlaceHolder != null)
+ {
+ var newHasPlaceHolder = newItem as ISupportsPlaceHolders;
+
+ if (newHasPlaceHolder != null)
+ {
+ if (currentAsPlaceHolder.IsPlaceHolder != newHasPlaceHolder.IsPlaceHolder)
+ {
+ return false;
+ }
+ }
+ }
+
+ return current.IsInMixedFolder == newItem.IsInMixedFolder;
+ }
+
/// <summary>
/// Gets the preferred metadata language.
/// </summary>
@@ -1390,7 +1312,7 @@ namespace MediaBrowser.Controller.Entities
/// <param name="resetPosition">if set to <c>true</c> [reset position].</param>
/// <returns>Task.</returns>
/// <exception cref="System.ArgumentNullException"></exception>
- public virtual async Task MarkPlayed(User user,
+ public virtual async Task MarkPlayed(User user,
DateTime? datePlayed,
bool resetPosition)
{
@@ -1778,7 +1700,8 @@ namespace MediaBrowser.Controller.Entities
Name = Name,
ProviderIds = ProviderIds,
IndexNumber = IndexNumber,
- ParentIndexNumber = ParentIndexNumber
+ ParentIndexNumber = ParentIndexNumber,
+ Year = ProductionYear
};
}
@@ -1820,9 +1743,42 @@ namespace MediaBrowser.Controller.Entities
if (pct > 0)
{
pct = userData.PlaybackPositionTicks / pct;
- dto.PlayedPercentage = 100 * pct;
+
+ if (pct > 0)
+ {
+ dto.PlayedPercentage = 100 * pct;
+ }
}
}
}
+
+ protected Task RefreshMetadataForOwnedVideo(MetadataRefreshOptions options, string path, CancellationToken cancellationToken)
+ {
+ var newOptions = new MetadataRefreshOptions(options.DirectoryService)
+ {
+ ImageRefreshMode = options.ImageRefreshMode,
+ MetadataRefreshMode = options.MetadataRefreshMode,
+ ReplaceAllMetadata = options.ReplaceAllMetadata
+ };
+
+ var id = LibraryManager.GetNewItemId(path, typeof(Video));
+
+ // Try to retrieve it from the db. If we don't find it, use the resolved version
+ var video = LibraryManager.GetItemById(id) as Video;
+
+ if (video == null)
+ {
+ video = LibraryManager.ResolvePath(new FileInfo(path)) as Video;
+
+ newOptions.ForceSave = true;
+ }
+
+ if (video == null)
+ {
+ return Task.FromResult(true);
+ }
+
+ return video.RefreshMetadata(newOptions, cancellationToken);
+ }
}
}
diff --git a/MediaBrowser.Controller/Entities/Folder.cs b/MediaBrowser.Controller/Entities/Folder.cs
index 34f52aac5d..87ad9c3804 100644
--- a/MediaBrowser.Controller/Entities/Folder.cs
+++ b/MediaBrowser.Controller/Entities/Folder.cs
@@ -1,5 +1,4 @@
-using MediaBrowser.Common.Extensions;
-using MediaBrowser.Common.Progress;
+using MediaBrowser.Common.Progress;
using MediaBrowser.Controller.Entities.TV;
using MediaBrowser.Controller.Library;
using MediaBrowser.Controller.Localization;
@@ -59,6 +58,20 @@ namespace MediaBrowser.Controller.Entities
}
}
+ [IgnoreDataMember]
+ public override string FileNameWithoutExtension
+ {
+ get
+ {
+ if (LocationType == LocationType.FileSystem)
+ {
+ return System.IO.Path.GetFileName(Path);
+ }
+
+ return null;
+ }
+ }
+
/// <summary>
/// Gets or sets a value indicating whether this instance is physical root.
/// </summary>
@@ -103,7 +116,7 @@ namespace MediaBrowser.Controller.Entities
if (item.Id == Guid.Empty)
{
- item.Id = item.Path.GetMBId(item.GetType());
+ item.Id = LibraryManager.GetNewItemId(item.Path, item.GetType());
}
if (ActualChildren.Any(i => i.Id == item.Id))
@@ -364,47 +377,7 @@ namespace MediaBrowser.Controller.Entities
private bool IsValidFromResolver(BaseItem current, BaseItem newItem)
{
- var currentAsVideo = current as Video;
-
- if (currentAsVideo != null)
- {
- var newAsVideo = newItem as Video;
-
- if (newAsVideo != null)
- {
- if (currentAsVideo.IsPlaceHolder != newAsVideo.IsPlaceHolder)
- {
- return false;
- }
- if (currentAsVideo.IsMultiPart != newAsVideo.IsMultiPart)
- {
- return false;
- }
- if (currentAsVideo.HasLocalAlternateVersions != newAsVideo.HasLocalAlternateVersions)
- {
- return false;
- }
- }
- }
- else
- {
- var currentAsPlaceHolder = current as ISupportsPlaceHolders;
-
- if (currentAsPlaceHolder != null)
- {
- var newHasPlaceHolder = newItem as ISupportsPlaceHolders;
-
- if (newHasPlaceHolder != null)
- {
- if (currentAsPlaceHolder.IsPlaceHolder != newHasPlaceHolder.IsPlaceHolder)
- {
- return false;
- }
- }
- }
- }
-
- return current.IsInMixedFolder == newItem.IsInMixedFolder;
+ return current.IsValidFromResolver(newItem);
}
/// <summary>
@@ -737,7 +710,7 @@ namespace MediaBrowser.Controller.Entities
{
var collectionType = LibraryManager.FindCollectionType(this);
- return LibraryManager.ResolvePaths<BaseItem>(GetFileSystemChildren(directoryService), directoryService, this, collectionType);
+ return LibraryManager.ResolvePaths(GetFileSystemChildren(directoryService), directoryService, this, collectionType);
}
/// <summary>
@@ -782,6 +755,12 @@ namespace MediaBrowser.Controller.Entities
private BaseItem RetrieveChild(BaseItem child)
{
+ if (child.Id == Guid.Empty)
+ {
+ Logger.Error("Item found with empty Id: " + (child.Path ?? child.Name));
+ return null;
+ }
+
var item = LibraryManager.GetMemoryItemById(child.Id);
if (item != null)
diff --git a/MediaBrowser.Controller/Entities/Game.cs b/MediaBrowser.Controller/Entities/Game.cs
index 062bdfa88a..e4d0323590 100644
--- a/MediaBrowser.Controller/Entities/Game.cs
+++ b/MediaBrowser.Controller/Entities/Game.cs
@@ -28,12 +28,14 @@ namespace MediaBrowser.Controller.Entities
SoundtrackIds = new List<Guid>();
RemoteTrailers = new List<MediaUrl>();
LocalTrailerIds = new List<Guid>();
+ RemoteTrailerIds = new List<Guid>();
ThemeSongIds = new List<Guid>();
ThemeVideoIds = new List<Guid>();
Tags = new List<string>();
}
public List<Guid> LocalTrailerIds { get; set; }
+ public List<Guid> RemoteTrailerIds { get; set; }
/// <summary>
/// Gets or sets the tags.
@@ -119,5 +121,16 @@ namespace MediaBrowser.Controller.Entities
return id;
}
+
+ /// <summary>
+ /// Gets the trailer ids.
+ /// </summary>
+ /// <returns>List&lt;Guid&gt;.</returns>
+ public List<Guid> GetTrailerIds()
+ {
+ var list = LocalTrailerIds.ToList();
+ list.AddRange(RemoteTrailerIds);
+ return list;
+ }
}
}
diff --git a/MediaBrowser.Controller/Entities/IHasImages.cs b/MediaBrowser.Controller/Entities/IHasImages.cs
index 5c523d2e30..5aafc8eb31 100644
--- a/MediaBrowser.Controller/Entities/IHasImages.cs
+++ b/MediaBrowser.Controller/Entities/IHasImages.cs
@@ -22,6 +22,12 @@ namespace MediaBrowser.Controller.Entities
string Path { get; set; }
/// <summary>
+ /// Gets the file name without extension.
+ /// </summary>
+ /// <value>The file name without extension.</value>
+ string FileNameWithoutExtension { get; }
+
+ /// <summary>
/// Gets the identifier.
/// </summary>
/// <value>The identifier.</value>
diff --git a/MediaBrowser.Controller/Entities/IHasTrailers.cs b/MediaBrowser.Controller/Entities/IHasTrailers.cs
index 47779064b4..bc1c7d8758 100644
--- a/MediaBrowser.Controller/Entities/IHasTrailers.cs
+++ b/MediaBrowser.Controller/Entities/IHasTrailers.cs
@@ -4,7 +4,7 @@ using System.Collections.Generic;
namespace MediaBrowser.Controller.Entities
{
- public interface IHasTrailers
+ public interface IHasTrailers : IHasProviderIds
{
/// <summary>
/// Gets or sets the remote trailers.
@@ -17,5 +17,12 @@ namespace MediaBrowser.Controller.Entities
/// </summary>
/// <value>The local trailer ids.</value>
List<Guid> LocalTrailerIds { get; set; }
+ List<Guid> RemoteTrailerIds { get; set; }
+
+ /// <summary>
+ /// Gets the trailer ids.
+ /// </summary>
+ /// <returns>List&lt;Guid&gt;.</returns>
+ List<Guid> GetTrailerIds();
}
}
diff --git a/MediaBrowser.Controller/Entities/Movies/BoxSet.cs b/MediaBrowser.Controller/Entities/Movies/BoxSet.cs
index 705cf90575..9dc600675f 100644
--- a/MediaBrowser.Controller/Entities/Movies/BoxSet.cs
+++ b/MediaBrowser.Controller/Entities/Movies/BoxSet.cs
@@ -15,15 +15,19 @@ namespace MediaBrowser.Controller.Entities.Movies
/// <summary>
/// Class BoxSet
/// </summary>
- public class BoxSet : Folder, IHasTrailers, IHasKeywords, IHasPreferredMetadataLanguage, IHasDisplayOrder, IHasLookupInfo<BoxSetInfo>, IMetadataContainer
+ public class BoxSet : Folder, IHasTrailers, IHasKeywords, IHasPreferredMetadataLanguage, IHasDisplayOrder, IHasLookupInfo<BoxSetInfo>, IMetadataContainer, IHasShares
{
+ public List<Share> Shares { get; set; }
+
public BoxSet()
{
RemoteTrailers = new List<MediaUrl>();
LocalTrailerIds = new List<Guid>();
+ RemoteTrailerIds = new List<Guid>();
DisplayOrder = ItemSortBy.PremiereDate;
Keywords = new List<string>();
+ Shares = new List<Share>();
}
protected override bool FilterLinkedChildrenPerUser
@@ -35,6 +39,7 @@ namespace MediaBrowser.Controller.Entities.Movies
}
public List<Guid> LocalTrailerIds { get; set; }
+ public List<Guid> RemoteTrailerIds { get; set; }
/// <summary>
/// Gets or sets the remote trailers.
@@ -76,6 +81,17 @@ namespace MediaBrowser.Controller.Entities.Movies
}
}
+ /// <summary>
+ /// Gets the trailer ids.
+ /// </summary>
+ /// <returns>List&lt;Guid&gt;.</returns>
+ public List<Guid> GetTrailerIds()
+ {
+ var list = LocalTrailerIds.ToList();
+ list.AddRange(RemoteTrailerIds);
+ return list;
+ }
+
public override IEnumerable<BaseItem> GetChildren(User user, bool includeLinkedChildren)
{
var children = base.GetChildren(user, includeLinkedChildren);
@@ -147,5 +163,20 @@ namespace MediaBrowser.Controller.Entities.Movies
progress.Report(100);
}
+
+ public override bool IsVisible(User user)
+ {
+ if (base.IsVisible(user))
+ {
+ var userId = user.Id.ToString("N");
+
+ return Shares.Any(i => string.Equals(userId, i.UserId, StringComparison.OrdinalIgnoreCase)) ||
+
+ // Need to support this for boxsets created prior to the creation of Shares
+ Shares.Count == 0;
+ }
+
+ return false;
+ }
}
}
diff --git a/MediaBrowser.Controller/Entities/Movies/Movie.cs b/MediaBrowser.Controller/Entities/Movies/Movie.cs
index 686abdaf56..e749d89e4f 100644
--- a/MediaBrowser.Controller/Entities/Movies/Movie.cs
+++ b/MediaBrowser.Controller/Entities/Movies/Movie.cs
@@ -36,6 +36,7 @@ namespace MediaBrowser.Controller.Entities.Movies
SoundtrackIds = new List<Guid>();
RemoteTrailers = new List<MediaUrl>();
LocalTrailerIds = new List<Guid>();
+ RemoteTrailerIds = new List<Guid>();
ThemeSongIds = new List<Guid>();
ThemeVideoIds = new List<Guid>();
BoxSetIdList = new List<Guid>();
@@ -49,6 +50,7 @@ namespace MediaBrowser.Controller.Entities.Movies
public float? Metascore { get; set; }
public List<Guid> LocalTrailerIds { get; set; }
+ public List<Guid> RemoteTrailerIds { get; set; }
public List<string> Keywords { get; set; }
public List<MediaUrl> RemoteTrailers { get; set; }
@@ -90,6 +92,17 @@ namespace MediaBrowser.Controller.Entities.Movies
public string TmdbCollectionName { get; set; }
/// <summary>
+ /// Gets the trailer ids.
+ /// </summary>
+ /// <returns>List&lt;Guid&gt;.</returns>
+ public List<Guid> GetTrailerIds()
+ {
+ var list = LocalTrailerIds.ToList();
+ list.AddRange(RemoteTrailerIds);
+ return list;
+ }
+
+ /// <summary>
/// Gets the user data key.
/// </summary>
/// <returns>System.String.</returns>
@@ -119,7 +132,7 @@ namespace MediaBrowser.Controller.Entities.Movies
private async Task<bool> RefreshSpecialFeatures(MetadataRefreshOptions options, List<FileSystemInfo> fileSystemChildren, CancellationToken cancellationToken)
{
- var newItems = LoadSpecialFeatures(fileSystemChildren, options.DirectoryService).ToList();
+ var newItems = LibraryManager.FindExtras(this, fileSystemChildren, options.DirectoryService).ToList();
var newItemIds = newItems.Select(i => i.Id).ToList();
var itemsChanged = !SpecialFeatureIds.SequenceEqual(newItemIds);
@@ -158,6 +171,22 @@ namespace MediaBrowser.Controller.Entities.Movies
ProductionYear = yearInName;
hasChanges = true;
}
+ else
+ {
+ // Try to get the year from the folder name
+ if (!IsInMixedFolder)
+ {
+ info = LibraryManager.ParseName(System.IO.Path.GetFileName(ContainingFolderPath));
+
+ yearInName = info.Year;
+
+ if (yearInName.HasValue)
+ {
+ ProductionYear = yearInName;
+ hasChanges = true;
+ }
+ }
+ }
}
return hasChanges;
diff --git a/MediaBrowser.Controller/Entities/MusicVideo.cs b/MediaBrowser.Controller/Entities/MusicVideo.cs
index 015e4b4aee..d7cd62aa68 100644
--- a/MediaBrowser.Controller/Entities/MusicVideo.cs
+++ b/MediaBrowser.Controller/Entities/MusicVideo.cs
@@ -89,5 +89,41 @@ namespace MediaBrowser.Controller.Entities
{
return GetItemLookupInfo<MusicVideoInfo>();
}
+
+ public override bool BeforeMetadataRefresh()
+ {
+ var hasChanges = base.BeforeMetadataRefresh();
+
+ if (!ProductionYear.HasValue)
+ {
+ var info = LibraryManager.ParseName(Name);
+
+ var yearInName = info.Year;
+
+ if (yearInName.HasValue)
+ {
+ ProductionYear = yearInName;
+ hasChanges = true;
+ }
+ else
+ {
+ // Try to get the year from the folder name
+ if (!IsInMixedFolder)
+ {
+ info = LibraryManager.ParseName(System.IO.Path.GetFileName(ContainingFolderPath));
+
+ yearInName = info.Year;
+
+ if (yearInName.HasValue)
+ {
+ ProductionYear = yearInName;
+ hasChanges = true;
+ }
+ }
+ }
+ }
+
+ return hasChanges;
+ }
}
}
diff --git a/MediaBrowser.Controller/Entities/Share.cs b/MediaBrowser.Controller/Entities/Share.cs
new file mode 100644
index 0000000000..e194f62388
--- /dev/null
+++ b/MediaBrowser.Controller/Entities/Share.cs
@@ -0,0 +1,15 @@
+using System.Collections.Generic;
+
+namespace MediaBrowser.Controller.Entities
+{
+ public interface IHasShares
+ {
+ List<Share> Shares { get; set; }
+ }
+
+ public class Share
+ {
+ public string UserId { get; set; }
+ public bool CanEdit { get; set; }
+ }
+}
diff --git a/MediaBrowser.Controller/Entities/TV/Series.cs b/MediaBrowser.Controller/Entities/TV/Series.cs
index 3d1051b183..4c0d1fdfb6 100644
--- a/MediaBrowser.Controller/Entities/TV/Series.cs
+++ b/MediaBrowser.Controller/Entities/TV/Series.cs
@@ -36,6 +36,7 @@ namespace MediaBrowser.Controller.Entities.TV
SoundtrackIds = new List<Guid>();
RemoteTrailers = new List<MediaUrl>();
LocalTrailerIds = new List<Guid>();
+ RemoteTrailerIds = new List<Guid>();
DisplaySpecialsWithSeasons = true;
}
@@ -57,7 +58,8 @@ namespace MediaBrowser.Controller.Entities.TV
public bool DisplaySpecialsWithSeasons { get; set; }
public List<Guid> LocalTrailerIds { get; set; }
-
+ public List<Guid> RemoteTrailerIds { get; set; }
+
public List<MediaUrl> RemoteTrailers { get; set; }
/// <summary>
@@ -109,6 +111,17 @@ namespace MediaBrowser.Controller.Entities.TV
return this.GetProviderId(MetadataProviders.Tvdb) ?? this.GetProviderId(MetadataProviders.Tvcom) ?? base.GetUserDataKey();
}
+ /// <summary>
+ /// Gets the trailer ids.
+ /// </summary>
+ /// <returns>List&lt;Guid&gt;.</returns>
+ public List<Guid> GetTrailerIds()
+ {
+ var list = LocalTrailerIds.ToList();
+ list.AddRange(RemoteTrailerIds);
+ return list;
+ }
+
// Studio, Genre and Rating will all be the same so makes no sense to index by these
protected override IEnumerable<string> GetIndexByOptions()
{
diff --git a/MediaBrowser.Controller/Entities/Trailer.cs b/MediaBrowser.Controller/Entities/Trailer.cs
index bbbf2358f0..bb165d7909 100644
--- a/MediaBrowser.Controller/Entities/Trailer.cs
+++ b/MediaBrowser.Controller/Entities/Trailer.cs
@@ -12,7 +12,8 @@ namespace MediaBrowser.Controller.Entities
/// <summary>
/// Class Trailer
/// </summary>
- public class Trailer : Video, IHasCriticRating, IHasSoundtracks, IHasProductionLocations, IHasBudget, IHasTrailers, IHasKeywords, IHasTaglines, IHasMetascore, IHasLookupInfo<TrailerInfo>
+ [Obsolete]
+ public class Trailer : Video, IHasCriticRating, IHasSoundtracks, IHasProductionLocations, IHasBudget, IHasKeywords, IHasTaglines, IHasMetascore, IHasLookupInfo<TrailerInfo>
{
public List<Guid> SoundtrackIds { get; set; }
@@ -23,15 +24,12 @@ namespace MediaBrowser.Controller.Entities
RemoteTrailers = new List<MediaUrl>();
Taglines = new List<string>();
SoundtrackIds = new List<Guid>();
- LocalTrailerIds = new List<Guid>();
Keywords = new List<string>();
ProductionLocations = new List<string>();
}
public float? Metascore { get; set; }
- public List<Guid> LocalTrailerIds { get; set; }
-
public List<MediaUrl> RemoteTrailers { get; set; }
public List<string> Keywords { get; set; }
diff --git a/MediaBrowser.Controller/Entities/User.cs b/MediaBrowser.Controller/Entities/User.cs
index 0bbd2eeca7..3fa0a04356 100644
--- a/MediaBrowser.Controller/Entities/User.cs
+++ b/MediaBrowser.Controller/Entities/User.cs
@@ -4,6 +4,7 @@ using MediaBrowser.Controller.Providers;
using MediaBrowser.Model.Configuration;
using MediaBrowser.Model.Connect;
using MediaBrowser.Model.Serialization;
+using MediaBrowser.Model.Users;
using System;
using System.IO;
using System.Linq;
@@ -287,7 +288,7 @@ namespace MediaBrowser.Controller.Entities
var localTime = date.ToLocalTime();
- return DayOfWeekHelper.GetDaysOfWeek(schedule.DayOfWeek).Contains(localTime.DayOfWeek) &&
+ return DayOfWeekHelper.GetDaysOfWeek(schedule.DayOfWeek).Contains(localTime.DayOfWeek) &&
IsWithinTime(schedule, localTime);
}
diff --git a/MediaBrowser.Controller/Entities/UserView.cs b/MediaBrowser.Controller/Entities/UserView.cs
index 7674dc1d38..926ffa19c1 100644
--- a/MediaBrowser.Controller/Entities/UserView.cs
+++ b/MediaBrowser.Controller/Entities/UserView.cs
@@ -63,8 +63,7 @@ namespace MediaBrowser.Controller.Entities
{
CollectionType.Books,
CollectionType.HomeVideos,
- CollectionType.Photos,
- CollectionType.Trailers
+ CollectionType.Photos
};
var collectionFolder = folder as ICollectionFolder;
diff --git a/MediaBrowser.Controller/Entities/UserViewBuilder.cs b/MediaBrowser.Controller/Entities/UserViewBuilder.cs
index aff4af468f..166d56c514 100644
--- a/MediaBrowser.Controller/Entities/UserViewBuilder.cs
+++ b/MediaBrowser.Controller/Entities/UserViewBuilder.cs
@@ -1428,7 +1428,7 @@ namespace MediaBrowser.Controller.Entities
var hasTrailers = item as IHasTrailers;
if (hasTrailers != null)
{
- trailerCount = hasTrailers.LocalTrailerIds.Count;
+ trailerCount = hasTrailers.GetTrailerIds().Count;
}
var ok = val ? trailerCount > 0 : trailerCount == 0;
diff --git a/MediaBrowser.Controller/Entities/Video.cs b/MediaBrowser.Controller/Entities/Video.cs
index 1c59b8bfb2..6b098cbd82 100644
--- a/MediaBrowser.Controller/Entities/Video.cs
+++ b/MediaBrowser.Controller/Entities/Video.cs
@@ -1,12 +1,10 @@
using MediaBrowser.Controller.Library;
using MediaBrowser.Controller.Persistence;
using MediaBrowser.Controller.Providers;
-using MediaBrowser.Controller.Resolvers;
using MediaBrowser.Model.Dto;
using MediaBrowser.Model.Entities;
using MediaBrowser.Model.MediaInfo;
using System;
-using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Linq;
@@ -19,24 +17,23 @@ namespace MediaBrowser.Controller.Entities
/// <summary>
/// Class Video
/// </summary>
- public class Video : BaseItem,
- IHasAspectRatio,
- IHasTags,
+ public class Video : BaseItem,
+ IHasAspectRatio,
+ IHasTags,
ISupportsPlaceHolders,
IHasMediaSources,
IHasShortOverview,
IHasPreferredMetadataLanguage,
IThemeMedia
{
- public bool IsMultiPart { get; set; }
- public bool HasLocalAlternateVersions { get; set; }
public Guid? PrimaryVersionId { get; set; }
- public List<Guid> AdditionalPartIds { get; set; }
- public List<Guid> LocalAlternateVersionIds { get; set; }
+ public List<string> AdditionalParts { get; set; }
+ public List<string> LocalAlternateVersions { get; set; }
+ public List<LinkedChild> LinkedAlternateVersions { get; set; }
public bool IsThemeMedia { get; set; }
-
+
public string FormatName { get; set; }
public long? Size { get; set; }
public string Container { get; set; }
@@ -56,12 +53,12 @@ namespace MediaBrowser.Controller.Entities
/// </summary>
/// <value>The timestamp.</value>
public TransportStreamTimestamp? Timestamp { get; set; }
-
+
public Video()
{
PlayableStreamFileNames = new List<string>();
- AdditionalPartIds = new List<Guid>();
- LocalAlternateVersionIds = new List<Guid>();
+ AdditionalParts = new List<string>();
+ LocalAlternateVersions = new List<string>();
Tags = new List<string>();
SubtitleFiles = new List<string>();
LinkedAlternateVersions = new List<LinkedChild>();
@@ -78,11 +75,31 @@ namespace MediaBrowser.Controller.Entities
{
get
{
- return LinkedAlternateVersions.Count + LocalAlternateVersionIds.Count + 1;
+ return LinkedAlternateVersions.Count + LocalAlternateVersions.Count + 1;
}
}
- public List<LinkedChild> LinkedAlternateVersions { get; set; }
+ [IgnoreDataMember]
+ public bool IsStacked
+ {
+ get { return AdditionalParts.Count > 0; }
+ }
+
+ [IgnoreDataMember]
+ public bool HasLocalAlternateVersions
+ {
+ get { return LocalAlternateVersions.Count > 0; }
+ }
+
+ public IEnumerable<Guid> GetAdditionalPartIds()
+ {
+ return AdditionalParts.Select(i => LibraryManager.GetNewItemId(i, typeof(Video)));
+ }
+
+ public IEnumerable<Guid> GetLocalAlternateVersionIds()
+ {
+ return LocalAlternateVersions.Select(i => LibraryManager.GetNewItemId(i, typeof(Video)));
+ }
/// <summary>
/// Gets the linked children.
@@ -90,7 +107,7 @@ namespace MediaBrowser.Controller.Entities
/// <returns>IEnumerable{BaseItem}.</returns>
public IEnumerable<Video> GetAlternateVersions()
{
- var filesWithinSameDirectory = LocalAlternateVersionIds
+ var filesWithinSameDirectory = GetLocalAlternateVersionIds()
.Select(i => LibraryManager.GetItemById(i))
.Where(i => i != null)
.OfType<Video>();
@@ -116,7 +133,7 @@ namespace MediaBrowser.Controller.Entities
/// <returns>IEnumerable{Video}.</returns>
public IEnumerable<Video> GetAdditionalParts()
{
- return AdditionalPartIds
+ return GetAdditionalPartIds()
.Select(i => LibraryManager.GetItemById(i))
.Where(i => i != null)
.OfType<Video>()
@@ -200,7 +217,7 @@ namespace MediaBrowser.Controller.Entities
{
get
{
- if (IsMultiPart)
+ if (IsStacked)
{
return System.IO.Path.GetDirectoryName(Path);
}
@@ -218,6 +235,46 @@ namespace MediaBrowser.Controller.Entities
}
}
+ [IgnoreDataMember]
+ public override string FileNameWithoutExtension
+ {
+ get
+ {
+ if (LocationType == LocationType.FileSystem)
+ {
+ if (VideoType == VideoType.BluRay || VideoType == VideoType.Dvd || VideoType == VideoType.HdDvd)
+ {
+ return System.IO.Path.GetFileName(Path);
+ }
+
+ return System.IO.Path.GetFileNameWithoutExtension(Path);
+ }
+
+ return null;
+ }
+ }
+
+ internal override bool IsValidFromResolver(BaseItem newItem)
+ {
+ var current = this;
+
+ var newAsVideo = newItem as Video;
+
+ if (newAsVideo != null)
+ {
+ if (!current.AdditionalParts.SequenceEqual(newAsVideo.AdditionalParts, StringComparer.OrdinalIgnoreCase))
+ {
+ return false;
+ }
+ if (!current.LocalAlternateVersions.SequenceEqual(newAsVideo.LocalAlternateVersions, StringComparer.OrdinalIgnoreCase))
+ {
+ return false;
+ }
+ }
+
+ return base.IsValidFromResolver(newItem);
+ }
+
public string MainFeaturePlaylistName { get; set; }
/// <summary>
@@ -263,37 +320,34 @@ namespace MediaBrowser.Controller.Entities
{
var hasChanges = await base.RefreshedOwnedItems(options, fileSystemChildren, cancellationToken).ConfigureAwait(false);
+ if (IsStacked)
+ {
+ var tasks = AdditionalParts
+ .Select(i => RefreshMetadataForOwnedVideo(options, i, cancellationToken));
+
+ await Task.WhenAll(tasks).ConfigureAwait(false);
+ }
+
// Must have a parent to have additional parts or alternate versions
// In other words, it must be part of the Parent/Child tree
// The additional parts won't have additional parts themselves
if (LocationType == LocationType.FileSystem && Parent != null)
{
- if (IsMultiPart)
- {
- var additionalPartsChanged = await RefreshAdditionalParts(options, fileSystemChildren, cancellationToken).ConfigureAwait(false);
-
- if (additionalPartsChanged)
- {
- hasChanges = true;
- }
- }
- else
+ if (!IsStacked)
{
RefreshLinkedAlternateVersions();
- var additionalPartsChanged = await RefreshAlternateVersionsWithinSameDirectory(options, fileSystemChildren, cancellationToken).ConfigureAwait(false);
+ var tasks = LocalAlternateVersions
+ .Select(i => RefreshMetadataForOwnedVideo(options, i, cancellationToken));
- if (additionalPartsChanged)
- {
- hasChanges = true;
- }
+ await Task.WhenAll(tasks).ConfigureAwait(false);
}
}
return hasChanges;
}
- private bool RefreshLinkedAlternateVersions()
+ private void RefreshLinkedAlternateVersions()
{
foreach (var child in LinkedAlternateVersions)
{
@@ -303,111 +357,13 @@ namespace MediaBrowser.Controller.Entities
child.ItemId = null;
}
}
-
- return false;
- }
-
- /// <summary>
- /// Refreshes the additional parts.
- /// </summary>
- /// <param name="options">The options.</param>
- /// <param name="fileSystemChildren">The file system children.</param>
- /// <param name="cancellationToken">The cancellation token.</param>
- /// <returns>Task{System.Boolean}.</returns>
- private async Task<bool> RefreshAdditionalParts(MetadataRefreshOptions options, IEnumerable<FileSystemInfo> fileSystemChildren, CancellationToken cancellationToken)
- {
- var newItems = LoadAdditionalParts(fileSystemChildren, options.DirectoryService).ToList();
-
- var newItemIds = newItems.Select(i => i.Id).ToList();
-
- var itemsChanged = !AdditionalPartIds.SequenceEqual(newItemIds);
-
- var tasks = newItems.Select(i => i.RefreshMetadata(options, cancellationToken));
-
- await Task.WhenAll(tasks).ConfigureAwait(false);
-
- AdditionalPartIds = newItemIds;
-
- return itemsChanged;
- }
-
- /// <summary>
- /// Loads the additional parts.
- /// </summary>
- /// <returns>IEnumerable{Video}.</returns>
- private IEnumerable<Video> LoadAdditionalParts(IEnumerable<FileSystemInfo> fileSystemChildren, IDirectoryService directoryService)
- {
- var files = LibraryManager.GetAdditionalParts(Path, VideoType, fileSystemChildren);
-
- return LibraryManager.ResolvePaths<Video>(files, directoryService, null).Select(video =>
- {
- // Try to retrieve it from the db. If we don't find it, use the resolved version
- var dbItem = LibraryManager.GetItemById(video.Id) as Video;
-
- if (dbItem != null)
- {
- video = dbItem;
- }
-
- return video;
-
- // Sort them so that the list can be easily compared for changes
- }).OrderBy(i => i.Path).ToList();
- }
-
- private async Task<bool> RefreshAlternateVersionsWithinSameDirectory(MetadataRefreshOptions options, IEnumerable<FileSystemInfo> fileSystemChildren, CancellationToken cancellationToken)
- {
- var newItems = HasLocalAlternateVersions ?
- LoadAlternateVersionsWithinSameDirectory(fileSystemChildren, options.DirectoryService).ToList() :
- new List<Video>();
-
- var newItemIds = newItems.Select(i => i.Id).ToList();
-
- var itemsChanged = !LocalAlternateVersionIds.SequenceEqual(newItemIds);
-
- var tasks = newItems.Select(i => RefreshAlternateVersion(options, i, cancellationToken));
-
- await Task.WhenAll(tasks).ConfigureAwait(false);
-
- LocalAlternateVersionIds = newItemIds;
-
- return itemsChanged;
- }
-
- private Task RefreshAlternateVersion(MetadataRefreshOptions options, Video video, CancellationToken cancellationToken)
- {
- var currentImagePath = video.GetImagePath(ImageType.Primary);
- var ownerImagePath = this.GetImagePath(ImageType.Primary);
-
- var newOptions = new MetadataRefreshOptions(options.DirectoryService)
- {
- ImageRefreshMode = options.ImageRefreshMode,
- MetadataRefreshMode = options.MetadataRefreshMode,
- ReplaceAllMetadata = options.ReplaceAllMetadata
- };
-
- if (!string.Equals(currentImagePath, ownerImagePath, StringComparison.OrdinalIgnoreCase))
- {
- newOptions.ForceSave = true;
-
- if (string.IsNullOrWhiteSpace(ownerImagePath))
- {
- video.ImageInfos.Clear();
- }
- else
- {
- video.SetImagePath(ImageType.Primary, ownerImagePath);
- }
- }
-
- return video.RefreshMetadata(newOptions, cancellationToken);
}
public override async Task UpdateToRepository(ItemUpdateType updateReason, CancellationToken cancellationToken)
{
await base.UpdateToRepository(updateReason, cancellationToken).ConfigureAwait(false);
- foreach (var item in LocalAlternateVersionIds.Select(i => LibraryManager.GetItemById(i)))
+ foreach (var item in GetLocalAlternateVersionIds().Select(i => LibraryManager.GetItemById(i)))
{
item.ImageInfos = ImageInfos;
item.Overview = Overview;
@@ -422,56 +378,6 @@ namespace MediaBrowser.Controller.Entities
}
}
- /// <summary>
- /// Loads the additional parts.
- /// </summary>
- /// <returns>IEnumerable{Video}.</returns>
- private IEnumerable<Video> LoadAlternateVersionsWithinSameDirectory(IEnumerable<FileSystemInfo> fileSystemChildren, IDirectoryService directoryService)
- {
- IEnumerable<FileSystemInfo> files;
-
- // Only support this for video files. For folder rips, they'll have to use the linking feature
- if (VideoType == VideoType.VideoFile || VideoType == VideoType.Iso)
- {
- var path = Path;
-
- var filenamePrefix = System.IO.Path.GetFileName(System.IO.Path.GetDirectoryName(path));
-
- files = fileSystemChildren.Where(i =>
- {
- if ((i.Attributes & FileAttributes.Directory) == FileAttributes.Directory)
- {
- return false;
- }
-
- return !string.Equals(i.FullName, path, StringComparison.OrdinalIgnoreCase) &&
- LibraryManager.IsVideoFile(i.FullName) &&
- i.Name.StartsWith(filenamePrefix + " - ", StringComparison.OrdinalIgnoreCase);
- });
- }
- else
- {
- files = new List<FileSystemInfo>();
- }
-
- return LibraryManager.ResolvePaths<Video>(files, directoryService, null).Select(video =>
- {
- // Try to retrieve it from the db. If we don't find it, use the resolved version
- var dbItem = LibraryManager.GetItemById(video.Id) as Video;
-
- if (dbItem != null)
- {
- video = dbItem;
- }
-
- video.PrimaryVersionId = Id;
-
- return video;
-
- // Sort them so that the list can be easily compared for changes
- }).OrderBy(i => i.Path).ToList();
- }
-
public override IEnumerable<string> GetDeletePaths()
{
if (!IsInMixedFolder)
@@ -539,7 +445,7 @@ namespace MediaBrowser.Controller.Entities
var mediaStreams = ItemRepository.GetMediaStreams(new MediaStreamQuery { ItemId = i.Id }).ToList();
var locationType = i.LocationType;
-
+
var info = new MediaSourceInfo
{
Id = i.Id.ToString("N"),
diff --git a/MediaBrowser.Controller/Library/ILibraryManager.cs b/MediaBrowser.Controller/Library/ILibraryManager.cs
index 3367f98e47..33dea4dca6 100644
--- a/MediaBrowser.Controller/Library/ILibraryManager.cs
+++ b/MediaBrowser.Controller/Library/ILibraryManager.cs
@@ -24,7 +24,9 @@ namespace MediaBrowser.Controller.Library
/// <param name="parent">The parent.</param>
/// <param name="collectionType">Type of the collection.</param>
/// <returns>BaseItem.</returns>
- BaseItem ResolvePath(FileSystemInfo fileInfo, Folder parent = null, string collectionType = null);
+ BaseItem ResolvePath(FileSystemInfo fileInfo,
+ Folder parent = null,
+ string collectionType = null);
/// <summary>
/// Resolves a set of files into a list of BaseItem
@@ -35,8 +37,10 @@ namespace MediaBrowser.Controller.Library
/// <param name="parent">The parent.</param>
/// <param name="collectionType">Type of the collection.</param>
/// <returns>List{``0}.</returns>
- List<T> ResolvePaths<T>(IEnumerable<FileSystemInfo> files, IDirectoryService directoryService, Folder parent, string collectionType = null)
- where T : BaseItem;
+ IEnumerable<BaseItem> ResolvePaths(IEnumerable<FileSystemInfo> files,
+ IDirectoryService directoryService,
+ Folder parent, string
+ collectionType = null);
/// <summary>
/// Gets the root folder.
@@ -230,46 +234,6 @@ namespace MediaBrowser.Controller.Library
BaseItem RetrieveItem(Guid id);
/// <summary>
- /// Validates the artists.
- /// </summary>
- /// <param name="cancellationToken">The cancellation token.</param>
- /// <param name="progress">The progress.</param>
- /// <returns>Task.</returns>
- Task ValidateArtists(CancellationToken cancellationToken, IProgress<double> progress);
-
- /// <summary>
- /// Validates the music genres.
- /// </summary>
- /// <param name="cancellationToken">The cancellation token.</param>
- /// <param name="progress">The progress.</param>
- /// <returns>Task.</returns>
- Task ValidateMusicGenres(CancellationToken cancellationToken, IProgress<double> progress);
-
- /// <summary>
- /// Validates the game genres.
- /// </summary>
- /// <param name="cancellationToken">The cancellation token.</param>
- /// <param name="progress">The progress.</param>
- /// <returns>Task.</returns>
- Task ValidateGameGenres(CancellationToken cancellationToken, IProgress<double> progress);
-
- /// <summary>
- /// Validates the genres.
- /// </summary>
- /// <param name="cancellationToken">The cancellation token.</param>
- /// <param name="progress">The progress.</param>
- /// <returns>Task.</returns>
- Task ValidateGenres(CancellationToken cancellationToken, IProgress<double> progress);
-
- /// <summary>
- /// Validates the studios.
- /// </summary>
- /// <param name="cancellationToken">The cancellation token.</param>
- /// <param name="progress">The progress.</param>
- /// <returns>Task.</returns>
- Task ValidateStudios(CancellationToken cancellationToken, IProgress<double> progress);
-
- /// <summary>
/// Occurs when [item added].
/// </summary>
event EventHandler<ItemChangeEventArgs> ItemAdded;
@@ -405,14 +369,31 @@ namespace MediaBrowser.Controller.Library
ItemLookupInfo ParseName(string name);
/// <summary>
- /// Gets the additional parts.
+ /// Gets the new item identifier.
/// </summary>
- /// <param name="file">The file.</param>
+ /// <param name="key">The key.</param>
/// <param name="type">The type.</param>
- /// <param name="files">The files.</param>
- /// <returns>IEnumerable&lt;System.String&gt;.</returns>
- IEnumerable<FileSystemInfo> GetAdditionalParts(string file,
- VideoType type,
- IEnumerable<FileSystemInfo> files);
+ /// <returns>Guid.</returns>
+ Guid GetNewItemId(string key, Type type);
+
+ /// <summary>
+ /// Finds the trailers.
+ /// </summary>
+ /// <param name="owner">The owner.</param>
+ /// <param name="fileSystemChildren">The file system children.</param>
+ /// <param name="directoryService">The directory service.</param>
+ /// <returns>IEnumerable&lt;Trailer&gt;.</returns>
+ IEnumerable<Video> FindTrailers(BaseItem owner, List<FileSystemInfo> fileSystemChildren,
+ IDirectoryService directoryService);
+
+ /// <summary>
+ /// Finds the extras.
+ /// </summary>
+ /// <param name="owner">The owner.</param>
+ /// <param name="fileSystemChildren">The file system children.</param>
+ /// <param name="directoryService">The directory service.</param>
+ /// <returns>IEnumerable&lt;Video&gt;.</returns>
+ IEnumerable<Video> FindExtras(BaseItem owner, List<FileSystemInfo> fileSystemChildren,
+ IDirectoryService directoryService);
}
} \ No newline at end of file
diff --git a/MediaBrowser.Controller/Library/IMusicManager.cs b/MediaBrowser.Controller/Library/IMusicManager.cs
index 192ce2e833..f66f18401d 100644
--- a/MediaBrowser.Controller/Library/IMusicManager.cs
+++ b/MediaBrowser.Controller/Library/IMusicManager.cs
@@ -1,5 +1,6 @@
using MediaBrowser.Controller.Entities;
using MediaBrowser.Controller.Entities.Audio;
+using MediaBrowser.Controller.Playlists;
using System.Collections.Generic;
namespace MediaBrowser.Controller.Library
@@ -28,6 +29,13 @@ namespace MediaBrowser.Controller.Library
/// <returns>IEnumerable{Audio}.</returns>
IEnumerable<Audio> GetInstantMixFromAlbum(MusicAlbum item, User user);
/// <summary>
+ /// Gets the instant mix from playlist.
+ /// </summary>
+ /// <param name="item">The item.</param>
+ /// <param name="user">The user.</param>
+ /// <returns>IEnumerable&lt;Audio&gt;.</returns>
+ IEnumerable<Audio> GetInstantMixFromPlaylist(Playlist item, User user);
+ /// <summary>
/// Gets the instant mix from genre.
/// </summary>
/// <param name="genres">The genres.</param>
diff --git a/MediaBrowser.Controller/Library/IUserManager.cs b/MediaBrowser.Controller/Library/IUserManager.cs
index bd44f786f9..debdafe4d5 100644
--- a/MediaBrowser.Controller/Library/IUserManager.cs
+++ b/MediaBrowser.Controller/Library/IUserManager.cs
@@ -164,5 +164,19 @@ namespace MediaBrowser.Controller.Library
/// <param name="pin">The pin.</param>
/// <returns><c>true</c> if XXXX, <c>false</c> otherwise.</returns>
Task<PinRedeemResult> RedeemPasswordResetPin(string pin);
+
+ /// <summary>
+ /// Gets the user policy.
+ /// </summary>
+ /// <param name="userId">The user identifier.</param>
+ /// <returns>UserPolicy.</returns>
+ UserPolicy GetUserPolicy(string userId);
+
+ /// <summary>
+ /// Updates the user policy.
+ /// </summary>
+ /// <param name="userId">The user identifier.</param>
+ /// <param name="userPolicy">The user policy.</param>
+ Task UpdateUserPolicy(string userId, UserPolicy userPolicy);
}
}
diff --git a/MediaBrowser.Controller/LiveTv/ILiveTvService.cs b/MediaBrowser.Controller/LiveTv/ILiveTvService.cs
index eda69b164e..993db00043 100644
--- a/MediaBrowser.Controller/LiveTv/ILiveTvService.cs
+++ b/MediaBrowser.Controller/LiveTv/ILiveTvService.cs
@@ -3,6 +3,7 @@ using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
using MediaBrowser.Controller.Channels;
+using MediaBrowser.Controller.Drawing;
namespace MediaBrowser.Controller.LiveTv
{
@@ -109,7 +110,7 @@ namespace MediaBrowser.Controller.LiveTv
/// <param name="channelId">The channel identifier.</param>
/// <param name="cancellationToken">The cancellation token.</param>
/// <returns>Task{Stream}.</returns>
- Task<StreamResponseInfo> GetChannelImageAsync(string channelId, CancellationToken cancellationToken);
+ Task<ImageStream> GetChannelImageAsync(string channelId, CancellationToken cancellationToken);
/// <summary>
/// Gets the recording image asynchronous. This only needs to be implemented if an image path or url cannot be supplied to RecordingInfo
@@ -117,7 +118,7 @@ namespace MediaBrowser.Controller.LiveTv
/// <param name="recordingId">The recording identifier.</param>
/// <param name="cancellationToken">The cancellation token.</param>
/// <returns>Task{ImageResponseInfo}.</returns>
- Task<StreamResponseInfo> GetRecordingImageAsync(string recordingId, CancellationToken cancellationToken);
+ Task<ImageStream> GetRecordingImageAsync(string recordingId, CancellationToken cancellationToken);
/// <summary>
/// Gets the program image asynchronous. This only needs to be implemented if an image path or url cannot be supplied to ProgramInfo
@@ -126,7 +127,7 @@ namespace MediaBrowser.Controller.LiveTv
/// <param name="channelId">The channel identifier.</param>
/// <param name="cancellationToken">The cancellation token.</param>
/// <returns>Task{ImageResponseInfo}.</returns>
- Task<StreamResponseInfo> GetProgramImageAsync(string programId, string channelId, CancellationToken cancellationToken);
+ Task<ImageStream> GetProgramImageAsync(string programId, string channelId, CancellationToken cancellationToken);
/// <summary>
/// Gets the recordings asynchronous.
diff --git a/MediaBrowser.Controller/LiveTv/StreamResponseInfo.cs b/MediaBrowser.Controller/LiveTv/StreamResponseInfo.cs
deleted file mode 100644
index b133874d09..0000000000
--- a/MediaBrowser.Controller/LiveTv/StreamResponseInfo.cs
+++ /dev/null
@@ -1,20 +0,0 @@
-using MediaBrowser.Controller.Drawing;
-using System.IO;
-
-namespace MediaBrowser.Controller.LiveTv
-{
- public class StreamResponseInfo
- {
- /// <summary>
- /// Gets or sets the stream.
- /// </summary>
- /// <value>The stream.</value>
- public Stream Stream { get; set; }
-
- /// <summary>
- /// Gets or sets the type of the MIME.
- /// </summary>
- /// <value>The type of the MIME.</value>
- public ImageFormat Format { get; set; }
- }
-}
diff --git a/MediaBrowser.Controller/MediaBrowser.Controller.csproj b/MediaBrowser.Controller/MediaBrowser.Controller.csproj
index 1c8a588f60..c198a58d49 100644
--- a/MediaBrowser.Controller/MediaBrowser.Controller.csproj
+++ b/MediaBrowser.Controller/MediaBrowser.Controller.csproj
@@ -55,7 +55,6 @@
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.Data" />
- <Reference Include="System.Drawing" />
<Reference Include="System.Net" />
<Reference Include="System.Runtime.Serialization" />
<Reference Include="Microsoft.CSharp" />
@@ -106,7 +105,6 @@
<Compile Include="Devices\IDeviceRepository.cs" />
<Compile Include="Dlna\ControlRequest.cs" />
<Compile Include="Dlna\ControlResponse.cs" />
- <Compile Include="Dlna\DlnaIconResponse.cs" />
<Compile Include="Dlna\EventSubscriptionResponse.cs" />
<Compile Include="Dlna\IConnectionManager.cs" />
<Compile Include="Dlna\IContentDirectory.cs" />
@@ -114,9 +112,9 @@
<Compile Include="Dlna\IEventManager.cs" />
<Compile Include="Dlna\IUpnpService.cs" />
<Compile Include="Drawing\IImageProcessor.cs" />
- <Compile Include="Drawing\ImageFormat.cs" />
<Compile Include="Drawing\ImageProcessingOptions.cs" />
<Compile Include="Drawing\ImageProcessorExtensions.cs" />
+ <Compile Include="Drawing\ImageStream.cs" />
<Compile Include="Dto\IDtoService.cs" />
<Compile Include="Entities\AdultVideo.cs" />
<Compile Include="Entities\Audio\IHasAlbumArtist.cs" />
@@ -164,6 +162,7 @@
<Compile Include="Entities\IHasAwards.cs" />
<Compile Include="Entities\Photo.cs" />
<Compile Include="Entities\PhotoAlbum.cs" />
+ <Compile Include="Entities\Share.cs" />
<Compile Include="Entities\UserView.cs" />
<Compile Include="Entities\UserViewBuilder.cs" />
<Compile Include="FileOrganization\IFileOrganizationService.cs" />
@@ -192,7 +191,6 @@
<Compile Include="LiveTv\LiveTvException.cs" />
<Compile Include="LiveTv\LiveTvServiceStatusInfo.cs" />
<Compile Include="LiveTv\LiveTvTunerInfo.cs" />
- <Compile Include="LiveTv\StreamResponseInfo.cs" />
<Compile Include="LiveTv\LiveTvProgram.cs" />
<Compile Include="LiveTv\LiveTvVideoRecording.cs" />
<Compile Include="LiveTv\ProgramInfo.cs" />
@@ -270,7 +268,6 @@
<Compile Include="Providers\MetadataStatus.cs" />
<Compile Include="Providers\ISeriesOrderManager.cs" />
<Compile Include="Session\ISessionManager.cs" />
- <Compile Include="Drawing\ImageExtensions.cs" />
<Compile Include="Entities\AggregateFolder.cs" />
<Compile Include="Entities\Audio\Audio.cs" />
<Compile Include="Entities\Audio\MusicAlbum.cs" />
diff --git a/MediaBrowser.Controller/Persistence/IUserRepository.cs b/MediaBrowser.Controller/Persistence/IUserRepository.cs
index 0241b8c034..80961a369a 100644
--- a/MediaBrowser.Controller/Persistence/IUserRepository.cs
+++ b/MediaBrowser.Controller/Persistence/IUserRepository.cs
@@ -11,12 +11,6 @@ namespace MediaBrowser.Controller.Persistence
public interface IUserRepository : IRepository
{
/// <summary>
- /// Opens the connection to the repository
- /// </summary>
- /// <returns>Task.</returns>
- Task Initialize();
-
- /// <summary>
/// Deletes the user.
/// </summary>
/// <param name="user">The user.</param>
diff --git a/MediaBrowser.Controller/Playlists/Playlist.cs b/MediaBrowser.Controller/Playlists/Playlist.cs
index 75e1bbde71..e48cddaaa6 100644
--- a/MediaBrowser.Controller/Playlists/Playlist.cs
+++ b/MediaBrowser.Controller/Playlists/Playlist.cs
@@ -11,10 +11,17 @@ using System.Runtime.Serialization;
namespace MediaBrowser.Controller.Playlists
{
- public class Playlist : Folder
+ public class Playlist : Folder, IHasShares
{
public string OwnerUserId { get; set; }
+ public List<Share> Shares { get; set; }
+
+ public Playlist()
+ {
+ Shares = new List<Share>();
+ }
+
[IgnoreDataMember]
protected override bool FilterLinkedChildrenPerUser
{
@@ -166,7 +173,15 @@ namespace MediaBrowser.Controller.Playlists
public override bool IsVisible(User user)
{
- return base.IsVisible(user) && string.Equals(user.Id.ToString("N"), OwnerUserId);
+ if (base.IsVisible(user))
+ {
+ var userId = user.Id.ToString("N");
+
+ return Shares.Any(i => string.Equals(userId, i.UserId, StringComparison.OrdinalIgnoreCase)) ||
+ string.Equals(OwnerUserId, userId, StringComparison.OrdinalIgnoreCase);
+ }
+
+ return false;
}
}
}
diff --git a/MediaBrowser.Controller/Providers/BaseItemXmlParser.cs b/MediaBrowser.Controller/Providers/BaseItemXmlParser.cs
index 0a1c0938ad..a37f7eb8a8 100644
--- a/MediaBrowser.Controller/Providers/BaseItemXmlParser.cs
+++ b/MediaBrowser.Controller/Providers/BaseItemXmlParser.cs
@@ -819,6 +819,19 @@ namespace MediaBrowser.Controller.Providers
break;
}
+ case "Shares":
+ {
+ using (var subtree = reader.ReadSubtree())
+ {
+ var hasShares = item as IHasShares;
+ if (hasShares != null)
+ {
+ FetchFromSharesNode(subtree, hasShares);
+ }
+ }
+ break;
+ }
+
case "Format3D":
{
var video = item as Video;
@@ -853,6 +866,71 @@ namespace MediaBrowser.Controller.Providers
}
}
+ private void FetchFromSharesNode(XmlReader reader, IHasShares item)
+ {
+ reader.MoveToContent();
+
+ while (reader.Read())
+ {
+ if (reader.NodeType == XmlNodeType.Element)
+ {
+ switch (reader.Name)
+ {
+ case "Share":
+ {
+ using (var subtree = reader.ReadSubtree())
+ {
+ var share = GetShareFromNode(subtree);
+ if (share != null)
+ {
+ item.Shares.Add(share);
+ }
+ }
+ break;
+ }
+
+ default:
+ reader.Skip();
+ break;
+ }
+ }
+ }
+ }
+
+ private Share GetShareFromNode(XmlReader reader)
+ {
+ var share = new Share();
+
+ reader.MoveToContent();
+
+ while (reader.Read())
+ {
+ if (reader.NodeType == XmlNodeType.Element)
+ {
+ switch (reader.Name)
+ {
+ case "UserId":
+ {
+ share.UserId = reader.ReadElementContentAsString();
+ break;
+ }
+
+ case "CanEdit":
+ {
+ share.CanEdit = string.Equals(reader.ReadElementContentAsString(), true.ToString(), StringComparison.OrdinalIgnoreCase);
+ break;
+ }
+
+ default:
+ reader.Skip();
+ break;
+ }
+ }
+ }
+
+ return share;
+ }
+
private void FetchFromCountriesNode(XmlReader reader, T item)
{
reader.MoveToContent();
@@ -1340,6 +1418,12 @@ namespace MediaBrowser.Controller.Providers
}
}
+ // This is valid
+ if (!string.IsNullOrWhiteSpace(linkedItem.Path))
+ {
+ return linkedItem;
+ }
+
return string.IsNullOrWhiteSpace(linkedItem.ItemName) || string.IsNullOrWhiteSpace(linkedItem.ItemType) ? null : linkedItem;
}
diff --git a/MediaBrowser.Controller/Providers/IImageEnhancer.cs b/MediaBrowser.Controller/Providers/IImageEnhancer.cs
index ae605ec0d5..56f8d02bef 100644
--- a/MediaBrowser.Controller/Providers/IImageEnhancer.cs
+++ b/MediaBrowser.Controller/Providers/IImageEnhancer.cs
@@ -1,7 +1,7 @@
-using MediaBrowser.Controller.Entities;
+using MediaBrowser.Controller.Drawing;
+using MediaBrowser.Controller.Entities;
using MediaBrowser.Model.Drawing;
using MediaBrowser.Model.Entities;
-using System.Drawing;
using System.Threading.Tasks;
namespace MediaBrowser.Controller.Providers
@@ -49,6 +49,6 @@ namespace MediaBrowser.Controller.Providers
/// <param name="imageIndex">Index of the image.</param>
/// <returns>Task{Image}.</returns>
/// <exception cref="System.ArgumentNullException"></exception>
- Task<Image> EnhanceImageAsync(IHasImages item, Image originalImage, ImageType imageType, int imageIndex);
+ Task<ImageStream> EnhanceImageAsync(IHasImages item, ImageStream originalImage, ImageType imageType, int imageIndex);
}
} \ No newline at end of file
diff --git a/MediaBrowser.Controller/Providers/IImageSaver.cs b/MediaBrowser.Controller/Providers/IImageSaver.cs
index 5516c08f6a..a983de63e7 100644
--- a/MediaBrowser.Controller/Providers/IImageSaver.cs
+++ b/MediaBrowser.Controller/Providers/IImageSaver.cs
@@ -1,5 +1,5 @@
-using MediaBrowser.Controller.Drawing;
-using MediaBrowser.Controller.Entities;
+using MediaBrowser.Controller.Entities;
+using MediaBrowser.Model.Drawing;
using MediaBrowser.Model.Entities;
using System.Collections.Generic;
diff --git a/MediaBrowser.Controller/Providers/ILocalImageProvider.cs b/MediaBrowser.Controller/Providers/ILocalImageProvider.cs
index 68afb84b86..d1345d7a6e 100644
--- a/MediaBrowser.Controller/Providers/ILocalImageProvider.cs
+++ b/MediaBrowser.Controller/Providers/ILocalImageProvider.cs
@@ -1,5 +1,5 @@
-using MediaBrowser.Controller.Drawing;
-using MediaBrowser.Controller.Entities;
+using MediaBrowser.Controller.Entities;
+using MediaBrowser.Model.Drawing;
using MediaBrowser.Model.Entities;
using System;
using System.Collections.Generic;
diff --git a/MediaBrowser.Controller/Resolvers/IItemResolver.cs b/MediaBrowser.Controller/Resolvers/IItemResolver.cs
index 780d5d013d..fec6be55c9 100644
--- a/MediaBrowser.Controller/Resolvers/IItemResolver.cs
+++ b/MediaBrowser.Controller/Resolvers/IItemResolver.cs
@@ -1,5 +1,8 @@
using MediaBrowser.Controller.Entities;
using MediaBrowser.Controller.Library;
+using MediaBrowser.Controller.Providers;
+using System.Collections.Generic;
+using System.IO;
namespace MediaBrowser.Controller.Resolvers
{
@@ -20,4 +23,24 @@ namespace MediaBrowser.Controller.Resolvers
/// <value>The priority.</value>
ResolverPriority Priority { get; }
}
+
+ public interface IMultiItemResolver
+ {
+ MultiItemResolverResult ResolveMultiple(Folder parent,
+ List<FileSystemInfo> files,
+ string collectionType,
+ IDirectoryService directoryService);
+ }
+
+ public class MultiItemResolverResult
+ {
+ public List<BaseItem> Items { get; set; }
+ public List<FileSystemInfo> ExtraFiles { get; set; }
+
+ public MultiItemResolverResult()
+ {
+ Items = new List<BaseItem>();
+ ExtraFiles = new List<FileSystemInfo>();
+ }
+ }
}
diff --git a/MediaBrowser.Controller/Sync/ISyncManager.cs b/MediaBrowser.Controller/Sync/ISyncManager.cs
index 1e744a0872..31c3c0c6d2 100644
--- a/MediaBrowser.Controller/Sync/ISyncManager.cs
+++ b/MediaBrowser.Controller/Sync/ISyncManager.cs
@@ -1,6 +1,5 @@
-using System.IO;
-using MediaBrowser.Controller.Entities;
-using MediaBrowser.Model.Devices;
+using MediaBrowser.Controller.Entities;
+using MediaBrowser.Model.Dlna;
using MediaBrowser.Model.Querying;
using MediaBrowser.Model.Sync;
using System.Collections.Generic;
@@ -29,7 +28,7 @@ namespace MediaBrowser.Controller.Sync
/// <param name="id">The identifier.</param>
/// <returns>SyncJob.</returns>
SyncJob GetJob(string id);
-
+
/// <summary>
/// Cancels the job.
/// </summary>
@@ -53,5 +52,12 @@ namespace MediaBrowser.Controller.Sync
/// <param name="item">The item.</param>
/// <returns><c>true</c> if XXXX, <c>false</c> otherwise.</returns>
bool SupportsSync(BaseItem item);
+
+ /// <summary>
+ /// Gets the device profile.
+ /// </summary>
+ /// <param name="targetId">The target identifier.</param>
+ /// <returns>DeviceProfile.</returns>
+ DeviceProfile GetDeviceProfile(string targetId);
}
}
diff --git a/MediaBrowser.Controller/Sync/ISyncRepository.cs b/MediaBrowser.Controller/Sync/ISyncRepository.cs
index 9cce69bdc2..f1bcd7f07e 100644
--- a/MediaBrowser.Controller/Sync/ISyncRepository.cs
+++ b/MediaBrowser.Controller/Sync/ISyncRepository.cs
@@ -28,6 +28,13 @@ namespace MediaBrowser.Controller.Sync
Task Update(SyncJob job);
/// <summary>
+ /// Deletes the job.
+ /// </summary>
+ /// <param name="id">The identifier.</param>
+ /// <returns>Task.</returns>
+ Task DeleteJob(string id);
+
+ /// <summary>
/// Gets the jobs.
/// </summary>
/// <param name="query">The query.</param>
@@ -54,5 +61,12 @@ namespace MediaBrowser.Controller.Sync
/// <param name="jobItem">The job item.</param>
/// <returns>Task.</returns>
Task Update(SyncJobItem jobItem);
+
+ /// <summary>
+ /// Gets the job items.
+ /// </summary>
+ /// <param name="query">The query.</param>
+ /// <returns>IEnumerable&lt;SyncJobItem&gt;.</returns>
+ QueryResult<SyncJobItem> GetJobItems(SyncJobItemQuery query);
}
}
diff --git a/MediaBrowser.Dlna/ContentDirectory/ContentDirectory.cs b/MediaBrowser.Dlna/ContentDirectory/ContentDirectory.cs
index 87f705e16a..d4be1b2f4e 100644
--- a/MediaBrowser.Dlna/ContentDirectory/ContentDirectory.cs
+++ b/MediaBrowser.Dlna/ContentDirectory/ContentDirectory.cs
@@ -1,4 +1,5 @@
using MediaBrowser.Common.Net;
+using MediaBrowser.Controller.Channels;
using MediaBrowser.Controller.Configuration;
using MediaBrowser.Controller.Dlna;
using MediaBrowser.Controller.Drawing;
@@ -23,6 +24,7 @@ namespace MediaBrowser.Dlna.ContentDirectory
private readonly IServerConfigurationManager _config;
private readonly IUserManager _userManager;
private readonly ILocalizationManager _localization;
+ private readonly IChannelManager _channelManager;
public ContentDirectory(IDlnaManager dlna,
IUserDataManager userDataManager,
@@ -31,7 +33,7 @@ namespace MediaBrowser.Dlna.ContentDirectory
IServerConfigurationManager config,
IUserManager userManager,
ILogger logger,
- IHttpClient httpClient, ILocalizationManager localization)
+ IHttpClient httpClient, ILocalizationManager localization, IChannelManager channelManager)
: base(logger, httpClient)
{
_dlna = dlna;
@@ -41,6 +43,7 @@ namespace MediaBrowser.Dlna.ContentDirectory
_config = config;
_userManager = userManager;
_localization = localization;
+ _channelManager = channelManager;
}
private int SystemUpdateId
@@ -77,7 +80,8 @@ namespace MediaBrowser.Dlna.ContentDirectory
user,
SystemUpdateId,
_config,
- _localization)
+ _localization,
+ _channelManager)
.ProcessControlRequest(request);
}
diff --git a/MediaBrowser.Dlna/ContentDirectory/ControlHandler.cs b/MediaBrowser.Dlna/ContentDirectory/ControlHandler.cs
index ba98400eae..1faf690c93 100644
--- a/MediaBrowser.Dlna/ContentDirectory/ControlHandler.cs
+++ b/MediaBrowser.Dlna/ContentDirectory/ControlHandler.cs
@@ -1,13 +1,16 @@
using MediaBrowser.Common.Extensions;
+using MediaBrowser.Controller.Channels;
using MediaBrowser.Controller.Configuration;
using MediaBrowser.Controller.Drawing;
using MediaBrowser.Controller.Entities;
using MediaBrowser.Controller.Entities.Movies;
+using MediaBrowser.Controller.Entities.TV;
using MediaBrowser.Controller.Library;
using MediaBrowser.Controller.Localization;
using MediaBrowser.Dlna.Didl;
using MediaBrowser.Dlna.Server;
using MediaBrowser.Dlna.Service;
+using MediaBrowser.Model.Channels;
using MediaBrowser.Model.Dlna;
using MediaBrowser.Model.Entities;
using MediaBrowser.Model.Logging;
@@ -26,6 +29,7 @@ namespace MediaBrowser.Dlna.ContentDirectory
public class ControlHandler : BaseControlHandler
{
private readonly ILibraryManager _libraryManager;
+ private readonly IChannelManager _channelManager;
private readonly IUserDataManager _userDataManager;
private readonly User _user;
@@ -41,13 +45,14 @@ namespace MediaBrowser.Dlna.ContentDirectory
private readonly DeviceProfile _profile;
- public ControlHandler(ILogger logger, ILibraryManager libraryManager, DeviceProfile profile, string serverAddress, IImageProcessor imageProcessor, IUserDataManager userDataManager, User user, int systemUpdateId, IServerConfigurationManager config, ILocalizationManager localization)
+ public ControlHandler(ILogger logger, ILibraryManager libraryManager, DeviceProfile profile, string serverAddress, IImageProcessor imageProcessor, IUserDataManager userDataManager, User user, int systemUpdateId, IServerConfigurationManager config, ILocalizationManager localization, IChannelManager channelManager)
: base(config, logger)
{
_libraryManager = libraryManager;
_userDataManager = userDataManager;
_user = user;
_systemUpdateId = systemUpdateId;
+ _channelManager = channelManager;
_profile = profile;
_didlBuilder = new DidlBuilder(profile, user, imageProcessor, serverAddress, userDataManager, localization);
@@ -208,14 +213,15 @@ namespace MediaBrowser.Dlna.ContentDirectory
var serverItem = GetItemFromObjectId(id, user);
var item = serverItem.Item;
- var totalCount = 0;
+ int totalCount;
if (string.Equals(flag, "BrowseMetadata"))
{
+ totalCount = 1;
+
if (item.IsFolder || serverItem.StubType.HasValue)
{
var childrenResult = (await GetUserItems(item, serverItem.StubType, user, sortCriteria, start, requested).ConfigureAwait(false));
- totalCount = 1;
result.DocumentElement.AppendChild(_didlBuilder.GetFolderElement(result, item, serverItem.StubType, null, childrenResult.TotalRecordCount, filter, id));
}
@@ -235,18 +241,19 @@ namespace MediaBrowser.Dlna.ContentDirectory
foreach (var i in childrenResult.Items)
{
- var displayStubType = GetDisplayStubType(i, serverItem.Item);
+ var childItem = i.Item;
+ var displayStubType = i.StubType;
- if (i.IsFolder || displayStubType.HasValue)
+ if (childItem.IsFolder || displayStubType.HasValue)
{
- var childCount = (await GetUserItems(i, displayStubType, user, sortCriteria, null, 0).ConfigureAwait(false))
+ var childCount = (await GetUserItems(childItem, displayStubType, user, sortCriteria, null, 0).ConfigureAwait(false))
.TotalRecordCount;
- result.DocumentElement.AppendChild(_didlBuilder.GetFolderElement(result, i, displayStubType, item, childCount, filter));
+ result.DocumentElement.AppendChild(_didlBuilder.GetFolderElement(result, childItem, displayStubType, item, childCount, filter));
}
else
{
- result.DocumentElement.AppendChild(_didlBuilder.GetItemElement(result, i, item, serverItem.StubType, deviceId, filter));
+ result.DocumentElement.AppendChild(_didlBuilder.GetItemElement(result, childItem, item, serverItem.StubType, deviceId, filter));
}
}
}
@@ -262,24 +269,6 @@ namespace MediaBrowser.Dlna.ContentDirectory
};
}
- private StubType? GetDisplayStubType(BaseItem item, BaseItem context)
- {
- if (context == null || context.IsFolder)
- {
- var movie = item as Movie;
- if (movie != null)
- {
- if (movie.LocalTrailerIds.Count > 0 ||
- movie.SpecialFeatureIds.Count > 0)
- {
- return StubType.Folder;
- }
- }
- }
-
- return null;
- }
-
private async Task<IEnumerable<KeyValuePair<string, string>>> HandleSearch(Headers sparams, User user, string deviceId)
{
var searchCriteria = new SearchCriteria(sparams.GetValueOrDefault("SearchCriteria", ""));
@@ -408,16 +397,49 @@ namespace MediaBrowser.Dlna.ContentDirectory
}).ConfigureAwait(false);
}
- private async Task<QueryResult<BaseItem>> GetUserItems(BaseItem item, StubType? stubType, User user, SortCriteria sort, int? startIndex, int? limit)
+ private async Task<QueryResult<ServerItem>> GetUserItems(BaseItem item, StubType? stubType, User user, SortCriteria sort, int? startIndex, int? limit)
{
if (stubType.HasValue)
{
- var movie = item as Movie;
+ if (stubType.Value == StubType.People)
+ {
+ var items = item.People.Select(i =>
+ {
+ try
+ {
+ return _libraryManager.GetPerson(i.Name);
+ }
+ catch
+ {
+ return null;
+ }
+
+ }).Where(i => i != null).ToArray();
+
+ var result = new QueryResult<ServerItem>
+ {
+ Items = items.Select(i => new ServerItem { Item = i, StubType = StubType.Folder }).ToArray(),
+ TotalRecordCount = items.Length
+ };
- if (movie != null)
+ return ApplyPaging(result, startIndex, limit);
+ }
+ if (stubType.Value == StubType.Folder)
{
- return await GetMovieItems(movie).ConfigureAwait(false);
+ var movie = item as Movie;
+ if (movie != null)
+ {
+ return ApplyPaging(await GetMovieItems(movie).ConfigureAwait(false), startIndex, limit);
+ }
+ }
+
+ var person = item as Person;
+ if (person != null)
+ {
+ return await GetItemsFromPerson(person, user, startIndex, limit).ConfigureAwait(false);
}
+
+ return ApplyPaging(new QueryResult<ServerItem>(), startIndex, limit);
}
var folder = (Folder)item;
@@ -428,7 +450,7 @@ namespace MediaBrowser.Dlna.ContentDirectory
sortOrders.Add(ItemSortBy.SortName);
}
- return await folder.GetItems(new InternalItemsQuery
+ var queryResult = await folder.GetItems(new InternalItemsQuery
{
Limit = limit,
StartIndex = startIndex,
@@ -438,22 +460,138 @@ namespace MediaBrowser.Dlna.ContentDirectory
Filter = FilterUnsupportedContent
}).ConfigureAwait(false);
+
+ var serverItems = queryResult
+ .Items
+ .Select(i => new ServerItem
+ {
+ Item = i,
+ StubType = GetDisplayStubType(i, item)
+ })
+ .ToArray();
+
+ return new QueryResult<ServerItem>
+ {
+ TotalRecordCount = queryResult.TotalRecordCount,
+ Items = serverItems
+ };
+ }
+
+ private async Task<QueryResult<ServerItem>> GetItemsFromPerson(Person person, User user, int? startIndex, int? limit)
+ {
+ var items = user.RootFolder.GetRecursiveChildren(user)
+ .Where(i => i is Movie || i is Series)
+ .Where(i => i.ContainsPerson(person.Name))
+ .ToList();
+
+ var trailerResult = await _channelManager.GetAllMediaInternal(new AllChannelMediaQuery
+ {
+ ContentTypes = new[] { ChannelMediaContentType.MovieExtra },
+ ExtraTypes = new[] { ExtraType.Trailer },
+ UserId = user.Id.ToString("N")
+
+ }, CancellationToken.None).ConfigureAwait(false);
+
+ var currentIds = items.Select(i => i.GetProviderId(MetadataProviders.Imdb))
+ .ToList();
+
+ var trailersToAdd = trailerResult.Items
+ .Where(i => i.ContainsPerson(person.Name))
+ .Where(i =>
+ {
+ // Try to filter out dupes using imdb id
+ var imdb = i.GetProviderId(MetadataProviders.Imdb);
+ if (!string.IsNullOrWhiteSpace(imdb) &&
+ currentIds.Contains(imdb, StringComparer.OrdinalIgnoreCase))
+ {
+ return false;
+ }
+ return true;
+ });
+
+ items.AddRange(trailersToAdd);
+
+ items = _libraryManager.Sort(items, user, new[] { ItemSortBy.SortName }, SortOrder.Ascending)
+ .Skip(startIndex ?? 0)
+ .Take(limit ?? int.MaxValue)
+ .ToList();
+
+ var serverItems = items.Select(i => new ServerItem
+ {
+ Item = i,
+ StubType = null
+ })
+ .ToArray();
+
+ return new QueryResult<ServerItem>
+ {
+ TotalRecordCount = serverItems.Length,
+ Items = serverItems
+ };
}
- private Task<QueryResult<BaseItem>> GetMovieItems(Movie item)
+ private QueryResult<ServerItem> ApplyPaging(QueryResult<ServerItem> result, int? startIndex, int? limit)
+ {
+ result.Items = result.Items.Skip(startIndex ?? 0).Take(limit ?? int.MaxValue).ToArray();
+
+ return result;
+ }
+
+ private StubType? GetDisplayStubType(BaseItem item, BaseItem context)
+ {
+ if (context == null || context.IsFolder)
+ {
+ var movie = item as Movie;
+ if (movie != null)
+ {
+ if (movie.GetTrailerIds().Count > 0 ||
+ movie.SpecialFeatureIds.Count > 0)
+ {
+ return StubType.Folder;
+ }
+ }
+
+ if (EnablePeopleDisplay(item))
+ {
+ return StubType.Folder;
+ }
+ }
+
+ return null;
+ }
+
+ private bool EnablePeopleDisplay(BaseItem item)
+ {
+ if (item.People.Count > 0)
+ {
+ return item is Movie;
+ }
+
+ return false;
+ }
+
+ private Task<QueryResult<ServerItem>> GetMovieItems(Movie item)
{
var list = new List<BaseItem>();
list.Add(item);
- list.AddRange(item.LocalTrailerIds.Select(i => _libraryManager.GetItemById(i)).Where(i => i != null));
+ list.AddRange(item.GetTrailerIds().Select(i => _libraryManager.GetItemById(i)).Where(i => i != null));
list.AddRange(item.SpecialFeatureIds.Select(i => _libraryManager.GetItemById(i)).Where(i => i != null));
- list.AddRange(item.ThemeVideoIds.Select(i => _libraryManager.GetItemById(i)).Where(i => i != null));
- return Task.FromResult(new QueryResult<BaseItem>
+ var serverItems = list.Select(i => new ServerItem { Item = i, StubType = null })
+ .ToList();
+
+ serverItems.Add(new ServerItem
{
- Items = list.ToArray(),
- TotalRecordCount = list.Count
+ Item = item,
+ StubType = StubType.People
+ });
+
+ return Task.FromResult(new QueryResult<ServerItem>
+ {
+ Items = serverItems.ToArray(),
+ TotalRecordCount = serverItems.Count
});
}
@@ -498,6 +636,11 @@ namespace MediaBrowser.Dlna.ContentDirectory
stubType = StubType.Folder;
id = id.Split(new[] { '_' }, 2)[1];
}
+ else if (id.StartsWith("people_", StringComparison.OrdinalIgnoreCase))
+ {
+ stubType = StubType.People;
+ id = id.Split(new[] { '_' }, 2)[1];
+ }
if (Guid.TryParse(id, out itemId))
{
@@ -524,6 +667,7 @@ namespace MediaBrowser.Dlna.ContentDirectory
public enum StubType
{
- Folder = 0
+ Folder = 0,
+ People = 1
}
}
diff --git a/MediaBrowser.Dlna/Didl/DidlBuilder.cs b/MediaBrowser.Dlna/Didl/DidlBuilder.cs
index 565431758f..bdb1c4cbff 100644
--- a/MediaBrowser.Dlna/Didl/DidlBuilder.cs
+++ b/MediaBrowser.Dlna/Didl/DidlBuilder.cs
@@ -111,7 +111,7 @@ namespace MediaBrowser.Dlna.Didl
}
}
- AddCover(item, element);
+ AddCover(item, null, element);
return element;
}
@@ -293,8 +293,17 @@ namespace MediaBrowser.Dlna.Didl
container.AppendChild(res);
}
- private string GetDisplayName(BaseItem item, BaseItem context)
+ private string GetDisplayName(BaseItem item, StubType? itemStubType, BaseItem context)
{
+ if (itemStubType.HasValue && itemStubType.Value == StubType.People)
+ {
+ if (item is Video)
+ {
+ return _localization.GetLocalizedString("HeaderCastCrew");
+ }
+ return _localization.GetLocalizedString("HeaderPeople");
+ }
+
var episode = item as Episode;
var season = context as Season;
@@ -460,7 +469,7 @@ namespace MediaBrowser.Dlna.Didl
AddCommonFields(folder, stubType, null, container, filter);
- AddCover(folder, container);
+ AddCover(folder, stubType, container);
return container;
}
@@ -491,7 +500,7 @@ namespace MediaBrowser.Dlna.Didl
// MediaMonkey for example won't display content without a title
//if (filter.Contains("dc:title"))
{
- AddValue(element, "dc", "title", GetDisplayName(item, context), NS_DC);
+ AddValue(element, "dc", "title", GetDisplayName(item, itemStubType, context), NS_DC);
}
element.AppendChild(CreateObjectClass(element.OwnerDocument, item, itemStubType));
@@ -741,8 +750,14 @@ namespace MediaBrowser.Dlna.Didl
}
}
- private void AddCover(BaseItem item, XmlElement element)
+ private void AddCover(BaseItem item, StubType? stubType, XmlElement element)
{
+ if (stubType.HasValue && stubType.Value == StubType.People)
+ {
+ AddEmbeddedImageAsCover("people", element);
+ return;
+ }
+
var imageInfo = GetImageInfo(item);
if (imageInfo == null)
@@ -801,6 +816,22 @@ namespace MediaBrowser.Dlna.Didl
}
}
+ private void AddEmbeddedImageAsCover(string name, XmlElement element)
+ {
+ var result = element.OwnerDocument;
+
+ var icon = result.CreateElement("upnp", "albumArtURI", NS_UPNP);
+ var profile = result.CreateAttribute("dlna", "profileID", NS_DLNA);
+ profile.InnerText = _profile.AlbumArtPn;
+ icon.SetAttributeNode(profile);
+ icon.InnerText = _serverAddress + "/Dlna/icons/people480.jpg";
+ element.AppendChild(icon);
+
+ icon = result.CreateElement("upnp", "icon", NS_UPNP);
+ icon.InnerText = _serverAddress + "/Dlna/icons/people48.jpg";
+ element.AppendChild(icon);
+ }
+
private void AddImageResElement(BaseItem item,
XmlElement element,
int maxWidth,
diff --git a/MediaBrowser.Dlna/DlnaManager.cs b/MediaBrowser.Dlna/DlnaManager.cs
index f4578eca7c..7517cea50d 100644
--- a/MediaBrowser.Dlna/DlnaManager.cs
+++ b/MediaBrowser.Dlna/DlnaManager.cs
@@ -8,6 +8,7 @@ using MediaBrowser.Dlna.Profiles;
using MediaBrowser.Dlna.Server;
using MediaBrowser.Model.Dlna;
using MediaBrowser.Model.Dlna.Profiles;
+using MediaBrowser.Model.Drawing;
using MediaBrowser.Model.Logging;
using MediaBrowser.Model.Serialization;
using System;
@@ -469,13 +470,13 @@ namespace MediaBrowser.Dlna
return new DescriptionXmlBuilder(profile, serverUuId, "").GetXml();
}
- public DlnaIconResponse GetIcon(string filename)
+ public ImageStream GetIcon(string filename)
{
var format = filename.EndsWith(".png", StringComparison.OrdinalIgnoreCase)
? ImageFormat.Png
: ImageFormat.Jpg;
- return new DlnaIconResponse
+ return new ImageStream
{
Format = format,
Stream = GetType().Assembly.GetManifestResourceStream("MediaBrowser.Dlna.Images." + filename.ToLower())
@@ -522,10 +523,9 @@ namespace MediaBrowser.Dlna
new LgTvProfile(),
new Foobar2000Profile(),
new MediaMonkeyProfile(),
- new Windows81Profile(),
+ //new Windows81Profile(),
//new WindowsMediaCenterProfile(),
- new WindowsPhoneProfile(),
- new AndroidProfile(),
+ //new WindowsPhoneProfile(),
new DirectTvProfile(),
new DishHopperJoeyProfile(),
new DefaultProfile(),
diff --git a/MediaBrowser.Dlna/Images/people48.jpg b/MediaBrowser.Dlna/Images/people48.jpg
new file mode 100644
index 0000000000..06f49a8a2d
--- /dev/null
+++ b/MediaBrowser.Dlna/Images/people48.jpg
Binary files differ
diff --git a/MediaBrowser.Dlna/Images/people48.png b/MediaBrowser.Dlna/Images/people48.png
new file mode 100644
index 0000000000..7f846373f8
--- /dev/null
+++ b/MediaBrowser.Dlna/Images/people48.png
Binary files differ
diff --git a/MediaBrowser.Dlna/Images/people480.jpg b/MediaBrowser.Dlna/Images/people480.jpg
new file mode 100644
index 0000000000..5b78216349
--- /dev/null
+++ b/MediaBrowser.Dlna/Images/people480.jpg
Binary files differ
diff --git a/MediaBrowser.Dlna/Images/people480.png b/MediaBrowser.Dlna/Images/people480.png
new file mode 100644
index 0000000000..6d9a668d4e
--- /dev/null
+++ b/MediaBrowser.Dlna/Images/people480.png
Binary files differ
diff --git a/MediaBrowser.Dlna/MediaBrowser.Dlna.csproj b/MediaBrowser.Dlna/MediaBrowser.Dlna.csproj
index cff668b47a..7871946cba 100644
--- a/MediaBrowser.Dlna/MediaBrowser.Dlna.csproj
+++ b/MediaBrowser.Dlna/MediaBrowser.Dlna.csproj
@@ -181,11 +181,6 @@
<EmbeddedResource Include="Profiles\Xml\MediaMonkey.xml" />
</ItemGroup>
<ItemGroup>
- <EmbeddedResource Include="Profiles\Xml\Android.xml" />
- <EmbeddedResource Include="Profiles\Xml\Windows 8 RT.xml" />
- <EmbeddedResource Include="Profiles\Xml\Windows Phone.xml" />
- </ItemGroup>
- <ItemGroup>
<EmbeddedResource Include="Images\logo240.jpg" />
<EmbeddedResource Include="Images\logo240.png" />
</ItemGroup>
@@ -198,6 +193,14 @@
<ItemGroup>
<EmbeddedResource Include="Profiles\Xml\Popcorn Hour.xml" />
</ItemGroup>
+ <ItemGroup>
+ <EmbeddedResource Include="Images\people48.jpg" />
+ <EmbeddedResource Include="Images\people48.png" />
+ </ItemGroup>
+ <ItemGroup>
+ <EmbeddedResource Include="Images\people480.jpg" />
+ <EmbeddedResource Include="Images\people480.png" />
+ </ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
diff --git a/MediaBrowser.Dlna/Profiles/SamsungSmartTvProfile.cs b/MediaBrowser.Dlna/Profiles/SamsungSmartTvProfile.cs
index 542ec2e3f0..1499d0e745 100644
--- a/MediaBrowser.Dlna/Profiles/SamsungSmartTvProfile.cs
+++ b/MediaBrowser.Dlna/Profiles/SamsungSmartTvProfile.cs
@@ -91,7 +91,7 @@ namespace MediaBrowser.Dlna.Profiles
},
new DirectPlayProfile
{
- Container = "3gpp",
+ Container = "3gp",
VideoCodec = "h264,mpeg4",
AudioCodec = "aac,he-aac",
Type = DlnaProfileType.Video
diff --git a/MediaBrowser.Dlna/Profiles/XboxOneProfile.cs b/MediaBrowser.Dlna/Profiles/XboxOneProfile.cs
index fea65438a8..4399462cf0 100644
--- a/MediaBrowser.Dlna/Profiles/XboxOneProfile.cs
+++ b/MediaBrowser.Dlna/Profiles/XboxOneProfile.cs
@@ -16,7 +16,12 @@ namespace MediaBrowser.Dlna.Profiles
Identification = new DeviceIdentification
{
ModelName = "Xbox One",
- FriendlyName = "Xbox-SystemOS"
+ FriendlyName = "Xbox-SystemOS",
+
+ Headers = new[]
+ {
+ new HttpHeaderInfo {Name = "User-Agent", Value = "NSPlayer", Match = HeaderMatchType.Substring}
+ }
};
TranscodingProfiles = new[]
diff --git a/MediaBrowser.Dlna/Profiles/Xml/Android.xml b/MediaBrowser.Dlna/Profiles/Xml/Android.xml
deleted file mode 100644
index 56a229869b..0000000000
--- a/MediaBrowser.Dlna/Profiles/Xml/Android.xml
+++ /dev/null
@@ -1,84 +0,0 @@
-<?xml version="1.0"?>
-<Profile xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
- <Name>Android</Name>
- <FriendlyName>Media Browser</FriendlyName>
- <Manufacturer>Media Browser</Manufacturer>
- <ManufacturerUrl>http://mediabrowser.tv/</ManufacturerUrl>
- <ModelName>Media Browser</ModelName>
- <ModelDescription>Media Browser</ModelDescription>
- <ModelNumber>Media Browser</ModelNumber>
- <ModelUrl>http://mediabrowser.tv/</ModelUrl>
- <IgnoreTranscodeByteRangeRequests>false</IgnoreTranscodeByteRangeRequests>
- <EnableAlbumArtInDidl>false</EnableAlbumArtInDidl>
- <EnableSingleAlbumArtLimit>false</EnableSingleAlbumArtLimit>
- <SupportedMediaTypes>Audio,Photo,Video</SupportedMediaTypes>
- <AlbumArtPn>JPEG_SM</AlbumArtPn>
- <MaxAlbumArtWidth>480</MaxAlbumArtWidth>
- <MaxAlbumArtHeight>480</MaxAlbumArtHeight>
- <MaxIconWidth>48</MaxIconWidth>
- <MaxIconHeight>48</MaxIconHeight>
- <MaxStreamingBitrate>8000000</MaxStreamingBitrate>
- <MaxStaticBitrate>8000000</MaxStaticBitrate>
- <MusicStreamingTranscodingBitrate>128000</MusicStreamingTranscodingBitrate>
- <MusicSyncBitrate>128000</MusicSyncBitrate>
- <XDlnaDoc>DMS-1.50</XDlnaDoc>
- <ProtocolInfo>http-get:*:video/vnd.dlna.mpeg-tts:DLNA.ORG_PN=AVC_TS_HD_50_AC3;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/vnd.dlna.mpeg-tts:DLNA.ORG_PN=AVC_TS_HD_50_AC3_T;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/mpeg:DLNA.ORG_PN=AVC_TS_HD_50_AC3_ISO;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:audio/mpeg:DLNA.ORG_PN=MP3;DLNA.ORG_OP=01;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:audio/L16;rate=44100;channels=1:DLNA.ORG_PN=LPCM;DLNA.ORG_OP=01;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:audio/L16;rate=44100;channels=2:DLNA.ORG_PN=LPCM;DLNA.ORG_OP=01;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:audio/L16;rate=48000;channels=1:DLNA.ORG_PN=LPCM;DLNA.ORG_OP=01;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:audio/L16;rate=48000;channels=2:DLNA.ORG_PN=LPCM;DLNA.ORG_OP=01;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:audio/x-ms-wma:DLNA.ORG_PN=WMA_BASE;DLNA.ORG_OP=01;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:audio/x-ms-wma:DLNA.ORG_PN=WMA_FULL;DLNA.ORG_OP=01;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:image/jpeg:DLNA.ORG_PN=JPEG_SM;DLNA.ORG_OP=00;DLNA.ORG_FLAGS=00D00000000000000000000000000000,http-get:*:image/jpeg:DLNA.ORG_PN=JPEG_MED;DLNA.ORG_OP=00;DLNA.ORG_FLAGS=00D00000000000000000000000000000,http-get:*:image/jpeg:DLNA.ORG_PN=JPEG_LRG;DLNA.ORG_OP=00;DLNA.ORG_FLAGS=00D00000000000000000000000000000,http-get:*:image/jpeg:DLNA.ORG_PN=JPEG_TN;DLNA.ORG_OP=00;DLNA.ORG_FLAGS=00D00000000000000000000000000000,http-get:*:video/mpeg:DLNA.ORG_PN=MPEG1;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/mpeg:DLNA.ORG_PN=MPEG_PS_PAL;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/mpeg:DLNA.ORG_PN=MPEG_PS_NTSC;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/vnd.dlna.mpeg-tts:DLNA.ORG_PN=MPEG_TS_SD_EU;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/vnd.dlna.mpeg-tts:DLNA.ORG_PN=MPEG_TS_SD_EU_T;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/mpeg:DLNA.ORG_PN=MPEG_TS_SD_EU_ISO;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/vnd.dlna.mpeg-tts:DLNA.ORG_PN=MPEG_TS_SD_NA;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/vnd.dlna.mpeg-tts:DLNA.ORG_PN=MPEG_TS_SD_NA_T;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/mpeg:DLNA.ORG_PN=MPEG_TS_SD_NA_ISO;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/vnd.dlna.mpeg-tts:DLNA.ORG_PN=MPEG_TS_SD_KO;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/vnd.dlna.mpeg-tts:DLNA.ORG_PN=MPEG_TS_SD_KO_T;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/mpeg:DLNA.ORG_PN=MPEG_TS_SD_KO_ISO;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/x-msvideo:DLNA.ORG_PN=AVI;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/x-matroska:DLNA.ORG_PN=MATROSKA;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/mp4:DLNA.ORG_PN=AVC_MP4_MP_SD_AAC_MULT5;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/mp4:DLNA.ORG_PN=AVC_MP4_MP_SD_MPEG1_L3;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/mp4:DLNA.ORG_PN=AVC_MP4_MP_SD_AC3;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/mp4:DLNA.ORG_PN=AVC_MP4_MP_HD_720p_AAC;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/mp4:DLNA.ORG_PN=AVC_MP4_MP_HD_1080i_AAC;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/mp4:DLNA.ORG_PN=AVC_MP4_HP_HD_AAC;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/mp4:DLNA.ORG_PN=AVC_MP4_LPCM;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/mp4:DLNA.ORG_PN=MPEG4_P2_MP4_ASP_AAC;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/mp4:DLNA.ORG_PN=MPEG4_P2_MP4_SP_L6_AAC;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/mp4:DLNA.ORG_PN=MPEG4_P2_MP4_NDSD;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/vnd.dlna.mpeg-tts:DLNA.ORG_PN=AVC_TS_MP_SD_AAC_MULT5;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/vnd.dlna.mpeg-tts:DLNA.ORG_PN=AVC_TS_MP_SD_AAC_MULT5_T;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/mpeg:DLNA.ORG_PN=AVC_TS_MP_SD_AAC_MULT5_ISO;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/vnd.dlna.mpeg-tts:DLNA.ORG_PN=AVC_TS_MP_SD_MPEG1_L3;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/vnd.dlna.mpeg-tts:DLNA.ORG_PN=AVC_TS_MP_SD_MPEG1_L3_T;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/mpeg:DLNA.ORG_PN=AVC_TS_MP_SD_MPEG1_L3_ISO;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/vnd.dlna.mpeg-tts:DLNA.ORG_PN=AVC_TS_MP_HD_AAC_MULT5;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/vnd.dlna.mpeg-tts:DLNA.ORG_PN=AVC_TS_MP_HD_AAC_MULT5_T;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/mpeg:DLNA.ORG_PN=AVC_TS_MP_HD_AAC_MULT5_ISO;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/vnd.dlna.mpeg-tts:DLNA.ORG_PN=AVC_TS_MP_HD_MPEG1_L3;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/vnd.dlna.mpeg-tts:DLNA.ORG_PN=AVC_TS_MP_HD_MPEG1_L3_T;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/mpeg:DLNA.ORG_PN=AVC_TS_MP_HD_MPEG1_L3_ISO;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/vnd.dlna.mpeg-tts:DLNA.ORG_PN=AVC_TS_HD_50_LPCM_T;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/x-ms-wmv:DLNA.ORG_PN=WMVMED_BASE;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/x-ms-wmv:DLNA.ORG_PN=WMVMED_FULL;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/x-ms-wmv:DLNA.ORG_PN=WMVHIGH_FULL;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/x-ms-wmv:DLNA.ORG_PN=WMVMED_PRO;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/x-ms-wmv:DLNA.ORG_PN=WMVHIGH_PRO;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/x-ms-asf:DLNA.ORG_PN=VC1_ASF_AP_L1_WMA;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/x-ms-asf:DLNA.ORG_PN=VC1_ASF_AP_L2_WMA;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/x-ms-asf:DLNA.ORG_PN=VC1_ASF_AP_L3_WMA;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000</ProtocolInfo>
- <TimelineOffsetSeconds>0</TimelineOffsetSeconds>
- <RequiresPlainVideoItems>false</RequiresPlainVideoItems>
- <RequiresPlainFolders>false</RequiresPlainFolders>
- <SupportsDirectRemoteContent>false</SupportsDirectRemoteContent>
- <SupportsCustomHttpHeaders>false</SupportsCustomHttpHeaders>
- <XmlRootAttributes />
- <DirectPlayProfiles>
- <DirectPlayProfile container="mp4" audioCodec="aac" videoCodec="h264,mpeg4" type="Video" />
- <DirectPlayProfile container="mp4,aac" audioCodec="aac" type="Audio" />
- <DirectPlayProfile container="mp3" audioCodec="mp3" type="Audio" />
- <DirectPlayProfile container="flac" audioCodec="flac" type="Audio" />
- <DirectPlayProfile container="ogg" audioCodec="vorbis" type="Audio" />
- <DirectPlayProfile container="jpeg,png,gif,bmp" type="Photo" />
- </DirectPlayProfiles>
- <TranscodingProfiles>
- <TranscodingProfile container="mp3" type="Audio" audioCodec="mp3" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" context="Streaming" />
- <TranscodingProfile container="ts" type="Video" videoCodec="h264" audioCodec="aac" protocol="hls" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" context="Streaming" />
- <TranscodingProfile container="mp4" type="Video" videoCodec="h264" audioCodec="aac" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" context="Static" />
- </TranscodingProfiles>
- <ContainerProfiles />
- <CodecProfiles>
- <CodecProfile type="Video" codec="h264">
- <Conditions>
- <ProfileCondition condition="EqualsAny" property="VideoProfile" value="baseline|constrained baseline" isRequired="false" />
- <ProfileCondition condition="LessThanEqual" property="Width" value="1920" isRequired="false" />
- <ProfileCondition condition="LessThanEqual" property="Height" value="1080" isRequired="false" />
- <ProfileCondition condition="LessThanEqual" property="VideoBitDepth" value="8" isRequired="false" />
- <ProfileCondition condition="NotEquals" property="IsAnamorphic" value="true" isRequired="false" />
- <ProfileCondition condition="Equals" property="IsCabac" value="true" isRequired="false" />
- </Conditions>
- </CodecProfile>
- <CodecProfile type="Video">
- <Conditions>
- <ProfileCondition condition="LessThanEqual" property="Width" value="1920" isRequired="false" />
- <ProfileCondition condition="LessThanEqual" property="Height" value="1080" isRequired="false" />
- <ProfileCondition condition="LessThanEqual" property="VideoBitDepth" value="8" isRequired="false" />
- <ProfileCondition condition="NotEquals" property="IsAnamorphic" value="true" isRequired="false" />
- </Conditions>
- </CodecProfile>
- <CodecProfile type="VideoAudio" codec="aac">
- <Conditions>
- <ProfileCondition condition="LessThanEqual" property="AudioChannels" value="2" isRequired="false" />
- </Conditions>
- </CodecProfile>
- <CodecProfile type="Audio" codec="aac">
- <Conditions>
- <ProfileCondition condition="LessThanEqual" property="AudioChannels" value="2" isRequired="false" />
- </Conditions>
- </CodecProfile>
- <CodecProfile type="Audio" codec="mp3">
- <Conditions>
- <ProfileCondition condition="LessThanEqual" property="AudioChannels" value="2" isRequired="false" />
- <ProfileCondition condition="LessThanEqual" property="AudioBitrate" value="320000" isRequired="false" />
- </Conditions>
- </CodecProfile>
- </CodecProfiles>
- <ResponseProfiles />
- <SubtitleProfiles />
-</Profile> \ No newline at end of file
diff --git a/MediaBrowser.Dlna/Profiles/Xml/Samsung Smart TV.xml b/MediaBrowser.Dlna/Profiles/Xml/Samsung Smart TV.xml
index c903cdb14f..27d8e00ec8 100644
--- a/MediaBrowser.Dlna/Profiles/Xml/Samsung Smart TV.xml
+++ b/MediaBrowser.Dlna/Profiles/Xml/Samsung Smart TV.xml
@@ -42,7 +42,7 @@
<DirectPlayProfile container="avi" audioCodec="mp3,ac3,dca" videoCodec="h264,mpeg4,mjpeg" type="Video" />
<DirectPlayProfile container="mkv" audioCodec="mp3,ac3,dca,aac" videoCodec="h264,mpeg4,mjpeg4" type="Video" />
<DirectPlayProfile container="mp4" audioCodec="mp3,aac" videoCodec="h264,mpeg4" type="Video" />
- <DirectPlayProfile container="3gpp" audioCodec="aac,he-aac" videoCodec="h264,mpeg4" type="Video" />
+ <DirectPlayProfile container="3gp" audioCodec="aac,he-aac" videoCodec="h264,mpeg4" type="Video" />
<DirectPlayProfile container="mpg,mpeg" audioCodec="ac3,mp2,mp3,aac" videoCodec="mpeg1video,mpeg2video,h264" type="Video" />
<DirectPlayProfile container="vro,vob" audioCodec="ac3,mp2,mp3" videoCodec="mpeg1video,mpeg2video" type="Video" />
<DirectPlayProfile container="ts" audioCodec="ac3,aac,mp3,eac3" videoCodec="mpeg2video,h264,vc1" type="Video" />
diff --git a/MediaBrowser.Dlna/Profiles/Xml/Windows 8 RT.xml b/MediaBrowser.Dlna/Profiles/Xml/Windows 8 RT.xml
deleted file mode 100644
index 9283cf91af..0000000000
--- a/MediaBrowser.Dlna/Profiles/Xml/Windows 8 RT.xml
+++ /dev/null
@@ -1,78 +0,0 @@
-<?xml version="1.0"?>
-<Profile xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
- <Name>Windows 8/RT</Name>
- <Identification>
- <Manufacturer>Microsoft SDK Customer</Manufacturer>
- <Headers />
- </Identification>
- <FriendlyName>Media Browser</FriendlyName>
- <Manufacturer>Media Browser</Manufacturer>
- <ManufacturerUrl>http://mediabrowser.tv/</ManufacturerUrl>
- <ModelName>Media Browser</ModelName>
- <ModelDescription>Media Browser</ModelDescription>
- <ModelNumber>Media Browser</ModelNumber>
- <ModelUrl>http://mediabrowser.tv/</ModelUrl>
- <IgnoreTranscodeByteRangeRequests>false</IgnoreTranscodeByteRangeRequests>
- <EnableAlbumArtInDidl>false</EnableAlbumArtInDidl>
- <EnableSingleAlbumArtLimit>false</EnableSingleAlbumArtLimit>
- <SupportedMediaTypes>Audio,Photo,Video</SupportedMediaTypes>
- <AlbumArtPn>JPEG_SM</AlbumArtPn>
- <MaxAlbumArtWidth>480</MaxAlbumArtWidth>
- <MaxAlbumArtHeight>480</MaxAlbumArtHeight>
- <MaxIconWidth>48</MaxIconWidth>
- <MaxIconHeight>48</MaxIconHeight>
- <MaxStreamingBitrate>8000000</MaxStreamingBitrate>
- <MaxStaticBitrate>8000000</MaxStaticBitrate>
- <MusicStreamingTranscodingBitrate>128000</MusicStreamingTranscodingBitrate>
- <MusicSyncBitrate>128000</MusicSyncBitrate>
- <XDlnaDoc>DMS-1.50</XDlnaDoc>
- <ProtocolInfo>http-get:*:video/vnd.dlna.mpeg-tts:DLNA.ORG_PN=AVC_TS_HD_50_AC3;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/vnd.dlna.mpeg-tts:DLNA.ORG_PN=AVC_TS_HD_50_AC3_T;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/mpeg:DLNA.ORG_PN=AVC_TS_HD_50_AC3_ISO;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:audio/mpeg:DLNA.ORG_PN=MP3;DLNA.ORG_OP=01;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:audio/L16;rate=44100;channels=1:DLNA.ORG_PN=LPCM;DLNA.ORG_OP=01;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:audio/L16;rate=44100;channels=2:DLNA.ORG_PN=LPCM;DLNA.ORG_OP=01;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:audio/L16;rate=48000;channels=1:DLNA.ORG_PN=LPCM;DLNA.ORG_OP=01;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:audio/L16;rate=48000;channels=2:DLNA.ORG_PN=LPCM;DLNA.ORG_OP=01;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:audio/x-ms-wma:DLNA.ORG_PN=WMA_BASE;DLNA.ORG_OP=01;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:audio/x-ms-wma:DLNA.ORG_PN=WMA_FULL;DLNA.ORG_OP=01;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:image/jpeg:DLNA.ORG_PN=JPEG_SM;DLNA.ORG_OP=00;DLNA.ORG_FLAGS=00D00000000000000000000000000000,http-get:*:image/jpeg:DLNA.ORG_PN=JPEG_MED;DLNA.ORG_OP=00;DLNA.ORG_FLAGS=00D00000000000000000000000000000,http-get:*:image/jpeg:DLNA.ORG_PN=JPEG_LRG;DLNA.ORG_OP=00;DLNA.ORG_FLAGS=00D00000000000000000000000000000,http-get:*:image/jpeg:DLNA.ORG_PN=JPEG_TN;DLNA.ORG_OP=00;DLNA.ORG_FLAGS=00D00000000000000000000000000000,http-get:*:video/mpeg:DLNA.ORG_PN=MPEG1;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/mpeg:DLNA.ORG_PN=MPEG_PS_PAL;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/mpeg:DLNA.ORG_PN=MPEG_PS_NTSC;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/vnd.dlna.mpeg-tts:DLNA.ORG_PN=MPEG_TS_SD_EU;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/vnd.dlna.mpeg-tts:DLNA.ORG_PN=MPEG_TS_SD_EU_T;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/mpeg:DLNA.ORG_PN=MPEG_TS_SD_EU_ISO;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/vnd.dlna.mpeg-tts:DLNA.ORG_PN=MPEG_TS_SD_NA;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/vnd.dlna.mpeg-tts:DLNA.ORG_PN=MPEG_TS_SD_NA_T;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/mpeg:DLNA.ORG_PN=MPEG_TS_SD_NA_ISO;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/vnd.dlna.mpeg-tts:DLNA.ORG_PN=MPEG_TS_SD_KO;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/vnd.dlna.mpeg-tts:DLNA.ORG_PN=MPEG_TS_SD_KO_T;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/mpeg:DLNA.ORG_PN=MPEG_TS_SD_KO_ISO;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/x-msvideo:DLNA.ORG_PN=AVI;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/x-matroska:DLNA.ORG_PN=MATROSKA;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/mp4:DLNA.ORG_PN=AVC_MP4_MP_SD_AAC_MULT5;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/mp4:DLNA.ORG_PN=AVC_MP4_MP_SD_MPEG1_L3;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/mp4:DLNA.ORG_PN=AVC_MP4_MP_SD_AC3;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/mp4:DLNA.ORG_PN=AVC_MP4_MP_HD_720p_AAC;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/mp4:DLNA.ORG_PN=AVC_MP4_MP_HD_1080i_AAC;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/mp4:DLNA.ORG_PN=AVC_MP4_HP_HD_AAC;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/mp4:DLNA.ORG_PN=AVC_MP4_LPCM;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/mp4:DLNA.ORG_PN=MPEG4_P2_MP4_ASP_AAC;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/mp4:DLNA.ORG_PN=MPEG4_P2_MP4_SP_L6_AAC;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/mp4:DLNA.ORG_PN=MPEG4_P2_MP4_NDSD;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/vnd.dlna.mpeg-tts:DLNA.ORG_PN=AVC_TS_MP_SD_AAC_MULT5;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/vnd.dlna.mpeg-tts:DLNA.ORG_PN=AVC_TS_MP_SD_AAC_MULT5_T;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/mpeg:DLNA.ORG_PN=AVC_TS_MP_SD_AAC_MULT5_ISO;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/vnd.dlna.mpeg-tts:DLNA.ORG_PN=AVC_TS_MP_SD_MPEG1_L3;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/vnd.dlna.mpeg-tts:DLNA.ORG_PN=AVC_TS_MP_SD_MPEG1_L3_T;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/mpeg:DLNA.ORG_PN=AVC_TS_MP_SD_MPEG1_L3_ISO;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/vnd.dlna.mpeg-tts:DLNA.ORG_PN=AVC_TS_MP_HD_AAC_MULT5;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/vnd.dlna.mpeg-tts:DLNA.ORG_PN=AVC_TS_MP_HD_AAC_MULT5_T;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/mpeg:DLNA.ORG_PN=AVC_TS_MP_HD_AAC_MULT5_ISO;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/vnd.dlna.mpeg-tts:DLNA.ORG_PN=AVC_TS_MP_HD_MPEG1_L3;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/vnd.dlna.mpeg-tts:DLNA.ORG_PN=AVC_TS_MP_HD_MPEG1_L3_T;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/mpeg:DLNA.ORG_PN=AVC_TS_MP_HD_MPEG1_L3_ISO;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/vnd.dlna.mpeg-tts:DLNA.ORG_PN=AVC_TS_HD_50_LPCM_T;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/x-ms-wmv:DLNA.ORG_PN=WMVMED_BASE;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/x-ms-wmv:DLNA.ORG_PN=WMVMED_FULL;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/x-ms-wmv:DLNA.ORG_PN=WMVHIGH_FULL;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/x-ms-wmv:DLNA.ORG_PN=WMVMED_PRO;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/x-ms-wmv:DLNA.ORG_PN=WMVHIGH_PRO;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/x-ms-asf:DLNA.ORG_PN=VC1_ASF_AP_L1_WMA;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/x-ms-asf:DLNA.ORG_PN=VC1_ASF_AP_L2_WMA;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/x-ms-asf:DLNA.ORG_PN=VC1_ASF_AP_L3_WMA;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000</ProtocolInfo>
- <TimelineOffsetSeconds>0</TimelineOffsetSeconds>
- <RequiresPlainVideoItems>false</RequiresPlainVideoItems>
- <RequiresPlainFolders>false</RequiresPlainFolders>
- <SupportsDirectRemoteContent>false</SupportsDirectRemoteContent>
- <SupportsCustomHttpHeaders>false</SupportsCustomHttpHeaders>
- <XmlRootAttributes />
- <DirectPlayProfiles>
- <DirectPlayProfile container="mp4,mov" audioCodec="aac,ac3,eac3,mp3,pcm" videoCodec="h264,mpeg4" type="Video" />
- <DirectPlayProfile container="ts" audioCodec="aac,ac3,eac3,mp3,mp2,pcm" videoCodec="h264" type="Video" />
- <DirectPlayProfile container="asf" audioCodec="wmav2,wmapro,wmavoice" videoCodec="wmv2,wmv3,vc1" type="Video" />
- <DirectPlayProfile container="avi" audioCodec="mp3,ac3,eac3,mp2,pcm" videoCodec="mpeg4,msmpeg4,mjpeg" type="Video" />
- <DirectPlayProfile container="mp4" audioCodec="aac" type="Audio" />
- <DirectPlayProfile container="mp3" audioCodec="mp3" type="Audio" />
- <DirectPlayProfile container="jpeg" type="Photo" />
- </DirectPlayProfiles>
- <TranscodingProfiles>
- <TranscodingProfile container="mp3" type="Audio" audioCodec="mp3" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" context="Streaming" />
- <TranscodingProfile container="ts" type="Video" videoCodec="h264" audioCodec="aac" protocol="hls" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" context="Streaming" />
- <TranscodingProfile container="ts" type="Video" videoCodec="h264" audioCodec="aac" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" context="Streaming" />
- <TranscodingProfile container="mp4" type="Video" videoCodec="h264" audioCodec="aac,ac3,eac3" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" context="Static" />
- </TranscodingProfiles>
- <ContainerProfiles />
- <CodecProfiles>
- <CodecProfile type="Video">
- <Conditions>
- <ProfileCondition condition="LessThanEqual" property="VideoBitDepth" value="8" isRequired="false" />
- </Conditions>
- </CodecProfile>
- <CodecProfile type="Video" codec="h264">
- <Conditions>
- <ProfileCondition condition="EqualsAny" property="VideoProfile" value="baseline|constrained baseline" isRequired="false" />
- </Conditions>
- </CodecProfile>
- <CodecProfile type="VideoAudio" codec="aac,eac3">
- <Conditions>
- <ProfileCondition condition="LessThanEqual" property="AudioChannels" value="8" isRequired="true" />
- </Conditions>
- </CodecProfile>
- <CodecProfile type="VideoAudio" codec="ac3">
- <Conditions>
- <ProfileCondition condition="LessThanEqual" property="AudioChannels" value="6" isRequired="true" />
- </Conditions>
- </CodecProfile>
- </CodecProfiles>
- <ResponseProfiles />
- <SubtitleProfiles>
- <SubtitleProfile format="vtt" method="External" />
- </SubtitleProfiles>
-</Profile> \ No newline at end of file
diff --git a/MediaBrowser.Dlna/Profiles/Xml/Windows Phone.xml b/MediaBrowser.Dlna/Profiles/Xml/Windows Phone.xml
deleted file mode 100644
index efa52208b2..0000000000
--- a/MediaBrowser.Dlna/Profiles/Xml/Windows Phone.xml
+++ /dev/null
@@ -1,86 +0,0 @@
-<?xml version="1.0"?>
-<Profile xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
- <Name>Windows Phone</Name>
- <FriendlyName>Media Browser</FriendlyName>
- <Manufacturer>Media Browser</Manufacturer>
- <ManufacturerUrl>http://mediabrowser.tv/</ManufacturerUrl>
- <ModelName>Media Browser</ModelName>
- <ModelDescription>Media Browser</ModelDescription>
- <ModelNumber>Media Browser</ModelNumber>
- <ModelUrl>http://mediabrowser.tv/</ModelUrl>
- <IgnoreTranscodeByteRangeRequests>false</IgnoreTranscodeByteRangeRequests>
- <EnableAlbumArtInDidl>false</EnableAlbumArtInDidl>
- <EnableSingleAlbumArtLimit>false</EnableSingleAlbumArtLimit>
- <SupportedMediaTypes>Audio,Photo,Video</SupportedMediaTypes>
- <AlbumArtPn>JPEG_SM</AlbumArtPn>
- <MaxAlbumArtWidth>480</MaxAlbumArtWidth>
- <MaxAlbumArtHeight>480</MaxAlbumArtHeight>
- <MaxIconWidth>48</MaxIconWidth>
- <MaxIconHeight>48</MaxIconHeight>
- <MaxStreamingBitrate>8000000</MaxStreamingBitrate>
- <MaxStaticBitrate>8000000</MaxStaticBitrate>
- <MusicStreamingTranscodingBitrate>128000</MusicStreamingTranscodingBitrate>
- <MusicSyncBitrate>128000</MusicSyncBitrate>
- <XDlnaDoc>DMS-1.50</XDlnaDoc>
- <ProtocolInfo>http-get:*:video/vnd.dlna.mpeg-tts:DLNA.ORG_PN=AVC_TS_HD_50_AC3;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/vnd.dlna.mpeg-tts:DLNA.ORG_PN=AVC_TS_HD_50_AC3_T;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/mpeg:DLNA.ORG_PN=AVC_TS_HD_50_AC3_ISO;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:audio/mpeg:DLNA.ORG_PN=MP3;DLNA.ORG_OP=01;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:audio/L16;rate=44100;channels=1:DLNA.ORG_PN=LPCM;DLNA.ORG_OP=01;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:audio/L16;rate=44100;channels=2:DLNA.ORG_PN=LPCM;DLNA.ORG_OP=01;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:audio/L16;rate=48000;channels=1:DLNA.ORG_PN=LPCM;DLNA.ORG_OP=01;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:audio/L16;rate=48000;channels=2:DLNA.ORG_PN=LPCM;DLNA.ORG_OP=01;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:audio/x-ms-wma:DLNA.ORG_PN=WMA_BASE;DLNA.ORG_OP=01;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:audio/x-ms-wma:DLNA.ORG_PN=WMA_FULL;DLNA.ORG_OP=01;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:image/jpeg:DLNA.ORG_PN=JPEG_SM;DLNA.ORG_OP=00;DLNA.ORG_FLAGS=00D00000000000000000000000000000,http-get:*:image/jpeg:DLNA.ORG_PN=JPEG_MED;DLNA.ORG_OP=00;DLNA.ORG_FLAGS=00D00000000000000000000000000000,http-get:*:image/jpeg:DLNA.ORG_PN=JPEG_LRG;DLNA.ORG_OP=00;DLNA.ORG_FLAGS=00D00000000000000000000000000000,http-get:*:image/jpeg:DLNA.ORG_PN=JPEG_TN;DLNA.ORG_OP=00;DLNA.ORG_FLAGS=00D00000000000000000000000000000,http-get:*:video/mpeg:DLNA.ORG_PN=MPEG1;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/mpeg:DLNA.ORG_PN=MPEG_PS_PAL;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/mpeg:DLNA.ORG_PN=MPEG_PS_NTSC;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/vnd.dlna.mpeg-tts:DLNA.ORG_PN=MPEG_TS_SD_EU;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/vnd.dlna.mpeg-tts:DLNA.ORG_PN=MPEG_TS_SD_EU_T;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/mpeg:DLNA.ORG_PN=MPEG_TS_SD_EU_ISO;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/vnd.dlna.mpeg-tts:DLNA.ORG_PN=MPEG_TS_SD_NA;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/vnd.dlna.mpeg-tts:DLNA.ORG_PN=MPEG_TS_SD_NA_T;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/mpeg:DLNA.ORG_PN=MPEG_TS_SD_NA_ISO;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/vnd.dlna.mpeg-tts:DLNA.ORG_PN=MPEG_TS_SD_KO;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/vnd.dlna.mpeg-tts:DLNA.ORG_PN=MPEG_TS_SD_KO_T;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/mpeg:DLNA.ORG_PN=MPEG_TS_SD_KO_ISO;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/x-msvideo:DLNA.ORG_PN=AVI;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/x-matroska:DLNA.ORG_PN=MATROSKA;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/mp4:DLNA.ORG_PN=AVC_MP4_MP_SD_AAC_MULT5;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/mp4:DLNA.ORG_PN=AVC_MP4_MP_SD_MPEG1_L3;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/mp4:DLNA.ORG_PN=AVC_MP4_MP_SD_AC3;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/mp4:DLNA.ORG_PN=AVC_MP4_MP_HD_720p_AAC;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/mp4:DLNA.ORG_PN=AVC_MP4_MP_HD_1080i_AAC;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/mp4:DLNA.ORG_PN=AVC_MP4_HP_HD_AAC;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/mp4:DLNA.ORG_PN=AVC_MP4_LPCM;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/mp4:DLNA.ORG_PN=MPEG4_P2_MP4_ASP_AAC;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/mp4:DLNA.ORG_PN=MPEG4_P2_MP4_SP_L6_AAC;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/mp4:DLNA.ORG_PN=MPEG4_P2_MP4_NDSD;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/vnd.dlna.mpeg-tts:DLNA.ORG_PN=AVC_TS_MP_SD_AAC_MULT5;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/vnd.dlna.mpeg-tts:DLNA.ORG_PN=AVC_TS_MP_SD_AAC_MULT5_T;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/mpeg:DLNA.ORG_PN=AVC_TS_MP_SD_AAC_MULT5_ISO;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/vnd.dlna.mpeg-tts:DLNA.ORG_PN=AVC_TS_MP_SD_MPEG1_L3;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/vnd.dlna.mpeg-tts:DLNA.ORG_PN=AVC_TS_MP_SD_MPEG1_L3_T;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/mpeg:DLNA.ORG_PN=AVC_TS_MP_SD_MPEG1_L3_ISO;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/vnd.dlna.mpeg-tts:DLNA.ORG_PN=AVC_TS_MP_HD_AAC_MULT5;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/vnd.dlna.mpeg-tts:DLNA.ORG_PN=AVC_TS_MP_HD_AAC_MULT5_T;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/mpeg:DLNA.ORG_PN=AVC_TS_MP_HD_AAC_MULT5_ISO;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/vnd.dlna.mpeg-tts:DLNA.ORG_PN=AVC_TS_MP_HD_MPEG1_L3;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/vnd.dlna.mpeg-tts:DLNA.ORG_PN=AVC_TS_MP_HD_MPEG1_L3_T;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/mpeg:DLNA.ORG_PN=AVC_TS_MP_HD_MPEG1_L3_ISO;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/vnd.dlna.mpeg-tts:DLNA.ORG_PN=AVC_TS_HD_50_LPCM_T;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/x-ms-wmv:DLNA.ORG_PN=WMVMED_BASE;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/x-ms-wmv:DLNA.ORG_PN=WMVMED_FULL;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/x-ms-wmv:DLNA.ORG_PN=WMVHIGH_FULL;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/x-ms-wmv:DLNA.ORG_PN=WMVMED_PRO;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/x-ms-wmv:DLNA.ORG_PN=WMVHIGH_PRO;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/x-ms-asf:DLNA.ORG_PN=VC1_ASF_AP_L1_WMA;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/x-ms-asf:DLNA.ORG_PN=VC1_ASF_AP_L2_WMA;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/x-ms-asf:DLNA.ORG_PN=VC1_ASF_AP_L3_WMA;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000</ProtocolInfo>
- <TimelineOffsetSeconds>0</TimelineOffsetSeconds>
- <RequiresPlainVideoItems>false</RequiresPlainVideoItems>
- <RequiresPlainFolders>false</RequiresPlainFolders>
- <SupportsDirectRemoteContent>false</SupportsDirectRemoteContent>
- <SupportsCustomHttpHeaders>false</SupportsCustomHttpHeaders>
- <XmlRootAttributes />
- <DirectPlayProfiles>
- <DirectPlayProfile container="mp4,mov" audioCodec="aac,mp3" videoCodec="h264" type="Video" />
- <DirectPlayProfile container="mp4,avi" audioCodec="aac,mp3" videoCodec="mpeg4,msmpeg4" type="Video" />
- <DirectPlayProfile container="asf" audioCodec="wmav2,wmapro,wmavoice" videoCodec="wmv2,wmv3,vc1" type="Video" />
- <DirectPlayProfile container="asf" audioCodec="wmav2,wmapro,wmavoice" type="Audio" />
- <DirectPlayProfile container="mp4,aac" audioCodec="aac" type="Audio" />
- <DirectPlayProfile container="mp3" audioCodec="mp3" type="Audio" />
- <DirectPlayProfile container="jpeg,png,gif,bmp" type="Photo" />
- </DirectPlayProfiles>
- <TranscodingProfiles>
- <TranscodingProfile container="mp3" type="Audio" audioCodec="mp3" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" context="Streaming" />
- <TranscodingProfile container="ts" type="Video" videoCodec="h264" audioCodec="aac" protocol="hls" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" context="Streaming" />
- <TranscodingProfile container="mp4" type="Video" videoCodec="h264" audioCodec="aac" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" context="Streaming" />
- <TranscodingProfile container="mp4" type="Video" videoCodec="h264" audioCodec="aac" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" context="Static" />
- </TranscodingProfiles>
- <ContainerProfiles />
- <CodecProfiles>
- <CodecProfile type="Video">
- <Conditions>
- <ProfileCondition condition="NotEquals" property="IsAnamorphic" value="true" isRequired="true" />
- </Conditions>
- </CodecProfile>
- <CodecProfile type="Video" codec="h264">
- <Conditions>
- <ProfileCondition condition="LessThanEqual" property="Width" value="800" isRequired="true" />
- <ProfileCondition condition="LessThanEqual" property="Height" value="480" isRequired="true" />
- <ProfileCondition condition="LessThanEqual" property="VideoBitrate" value="1000000" isRequired="false" />
- <ProfileCondition condition="LessThanEqual" property="VideoFramerate" value="24" isRequired="false" />
- <ProfileCondition condition="LessThanEqual" property="VideoLevel" value="3" isRequired="true" />
- <ProfileCondition condition="EqualsAny" property="VideoProfile" value="baseline|constrained baseline" isRequired="false" />
- </Conditions>
- </CodecProfile>
- <CodecProfile type="Video">
- <Conditions>
- <ProfileCondition condition="LessThanEqual" property="Width" value="800" isRequired="true" />
- <ProfileCondition condition="LessThanEqual" property="Height" value="480" isRequired="true" />
- <ProfileCondition condition="LessThanEqual" property="VideoBitrate" value="1000000" isRequired="false" />
- <ProfileCondition condition="LessThanEqual" property="VideoFramerate" value="24" isRequired="false" />
- </Conditions>
- </CodecProfile>
- <CodecProfile type="VideoAudio">
- <Conditions>
- <ProfileCondition condition="LessThanEqual" property="AudioBitrate" value="128000" isRequired="true" />
- <ProfileCondition condition="LessThanEqual" property="AudioChannels" value="2" isRequired="true" />
- </Conditions>
- </CodecProfile>
- <CodecProfile type="Audio">
- <Conditions>
- <ProfileCondition condition="LessThanEqual" property="AudioBitrate" value="128000" isRequired="true" />
- </Conditions>
- </CodecProfile>
- </CodecProfiles>
- <ResponseProfiles />
- <SubtitleProfiles />
-</Profile> \ No newline at end of file
diff --git a/MediaBrowser.Dlna/Profiles/Xml/Xbox One.xml b/MediaBrowser.Dlna/Profiles/Xml/Xbox One.xml
index 7c791f13e8..f666dfd27f 100644
--- a/MediaBrowser.Dlna/Profiles/Xml/Xbox One.xml
+++ b/MediaBrowser.Dlna/Profiles/Xml/Xbox One.xml
@@ -4,7 +4,9 @@
<Identification>
<FriendlyName>Xbox-SystemOS</FriendlyName>
<ModelName>Xbox One</ModelName>
- <Headers />
+ <Headers>
+ <HttpHeaderInfo name="User-Agent" value="NSPlayer" match="Substring" />
+ </Headers>
</Identification>
<FriendlyName>Media Browser</FriendlyName>
<Manufacturer>Media Browser</Manufacturer>
diff --git a/MediaBrowser.LocalMetadata/Images/LocalImageProvider.cs b/MediaBrowser.LocalMetadata/Images/LocalImageProvider.cs
index 248ed2661f..044d29a1b8 100644
--- a/MediaBrowser.LocalMetadata/Images/LocalImageProvider.cs
+++ b/MediaBrowser.LocalMetadata/Images/LocalImageProvider.cs
@@ -126,33 +126,29 @@ namespace MediaBrowser.LocalMetadata.Images
private void PopulateImages(IHasImages item, List<LocalImageInfo> images, List<FileSystemInfo> files, bool supportParentSeriesFiles, IDirectoryService directoryService)
{
- var imagePrefix = string.Empty;
+ var imagePrefix = item.FileNameWithoutExtension + "-";
+ var isInMixedFolder = item.IsInMixedFolder;
- var baseItem = item as BaseItem;
- if (baseItem != null && baseItem.IsInMixedFolder)
- {
- imagePrefix = _fileSystem.GetFileNameWithoutExtension(item.Path) + "-";
- }
-
- PopulatePrimaryImages(item, images, files, imagePrefix);
- PopulateBackdrops(item, images, files, imagePrefix, directoryService);
- PopulateScreenshots(images, files, imagePrefix);
+ PopulatePrimaryImages(item, images, files, imagePrefix, isInMixedFolder);
- AddImage(files, images, imagePrefix + "logo", ImageType.Logo);
- AddImage(files, images, imagePrefix + "clearart", ImageType.Art);
- AddImage(files, images, imagePrefix + "disc", ImageType.Disc);
- AddImage(files, images, imagePrefix + "cdart", ImageType.Disc);
- AddImage(files, images, imagePrefix + "box", ImageType.Box);
- AddImage(files, images, imagePrefix + "back", ImageType.BoxRear);
- AddImage(files, images, imagePrefix + "boxrear", ImageType.BoxRear);
- AddImage(files, images, imagePrefix + "menu", ImageType.Menu);
+ AddImage(files, images, "logo", imagePrefix, isInMixedFolder, ImageType.Logo);
+ AddImage(files, images, "clearart", imagePrefix, isInMixedFolder, ImageType.Art);
+ AddImage(files, images, "disc", imagePrefix, isInMixedFolder, ImageType.Disc);
+ AddImage(files, images, "cdart", imagePrefix, isInMixedFolder, ImageType.Disc);
+ AddImage(files, images, "box", imagePrefix, isInMixedFolder, ImageType.Box);
+ AddImage(files, images, "back", imagePrefix, isInMixedFolder, ImageType.BoxRear);
+ AddImage(files, images, "boxrear", imagePrefix, isInMixedFolder, ImageType.BoxRear);
+ AddImage(files, images, "menu", imagePrefix, isInMixedFolder, ImageType.Menu);
// Banner
- AddImage(files, images, imagePrefix + "banner", ImageType.Banner);
+ AddImage(files, images, "banner", imagePrefix, isInMixedFolder, ImageType.Banner);
// Thumb
- AddImage(files, images, imagePrefix + "thumb", ImageType.Thumb);
- AddImage(files, images, imagePrefix + "landscape", ImageType.Thumb);
+ AddImage(files, images, "thumb", imagePrefix, isInMixedFolder, ImageType.Thumb);
+ AddImage(files, images, "landscape", imagePrefix, isInMixedFolder, ImageType.Thumb);
+
+ PopulateBackdrops(item, images, files, imagePrefix, isInMixedFolder, directoryService);
+ PopulateScreenshots(images, files, imagePrefix, isInMixedFolder);
if (supportParentSeriesFiles)
{
@@ -165,54 +161,72 @@ namespace MediaBrowser.LocalMetadata.Images
}
}
- private void PopulatePrimaryImages(IHasImages item, List<LocalImageInfo> images, List<FileSystemInfo> files, string imagePrefix)
+ private void PopulatePrimaryImages(IHasImages item, List<LocalImageInfo> images, List<FileSystemInfo> files, string imagePrefix, bool isInMixedFolder)
{
- AddImage(files, images, imagePrefix + "folder", ImageType.Primary);
- AddImage(files, images, imagePrefix + "cover", ImageType.Primary);
- AddImage(files, images, imagePrefix + "poster", ImageType.Primary);
- AddImage(files, images, imagePrefix + "default", ImageType.Primary);
+ var names = new List<string>
+ {
+ "folder",
+ "cover",
+ "poster",
+ "default"
+ };
- // Support plex/xbmc convention
+ // Support plex/kodi convention
if (item is Series)
{
- AddImage(files, images, imagePrefix + "show", ImageType.Primary);
+ names.Add("show");
}
- // Support plex/xbmc convention
+ // Support plex/kodi convention
if (item is Video && !(item is Episode))
{
- AddImage(files, images, imagePrefix + "movie", ImageType.Primary);
+ names.Add("movie");
}
- if (!string.IsNullOrEmpty(item.Path))
+ foreach (var name in names)
{
- var name = _fileSystem.GetFileNameWithoutExtension(item.Path);
+ AddImage(files, images, imagePrefix + name, ImageType.Primary);
+ }
- if (!string.IsNullOrEmpty(name))
+ var fileNameWithoutExtension = item.FileNameWithoutExtension;
+
+ if (!string.IsNullOrEmpty(fileNameWithoutExtension))
+ {
+ AddImage(files, images, fileNameWithoutExtension, ImageType.Primary);
+ }
+
+ if (!isInMixedFolder)
+ {
+ foreach (var name in names)
{
AddImage(files, images, name, ImageType.Primary);
- AddImage(files, images, name + "-poster", ImageType.Primary);
}
}
}
- private void PopulateBackdrops(IHasImages item, List<LocalImageInfo> images, List<FileSystemInfo> files, string imagePrefix, IDirectoryService directoryService)
+ private void PopulateBackdrops(IHasImages item, List<LocalImageInfo> images, List<FileSystemInfo> files, string imagePrefix, bool isInMixedFolder, IDirectoryService directoryService)
{
- PopulateBackdrops(images, files, imagePrefix, "backdrop", "backdrop", ImageType.Backdrop);
+ PopulateBackdrops(images, files, imagePrefix, "backdrop", "backdrop", isInMixedFolder, ImageType.Backdrop);
if (!string.IsNullOrEmpty(item.Path))
{
- var name = _fileSystem.GetFileNameWithoutExtension(item.Path);
+ var name = item.FileNameWithoutExtension;
if (!string.IsNullOrEmpty(name))
{
AddImage(files, images, imagePrefix + name + "-fanart", ImageType.Backdrop);
+
+ // Support without the prefix if it's in it's own folder
+ if (!isInMixedFolder)
+ {
+ AddImage(files, images, name + "-fanart", ImageType.Backdrop);
+ }
}
}
- PopulateBackdrops(images, files, imagePrefix, "fanart", "fanart-", ImageType.Backdrop);
- PopulateBackdrops(images, files, imagePrefix, "background", "background-", ImageType.Backdrop);
- PopulateBackdrops(images, files, imagePrefix, "art", "art-", ImageType.Backdrop);
+ PopulateBackdrops(images, files, imagePrefix, "fanart", "fanart-", isInMixedFolder, ImageType.Backdrop);
+ PopulateBackdrops(images, files, imagePrefix, "background", "background-", isInMixedFolder, ImageType.Backdrop);
+ PopulateBackdrops(images, files, imagePrefix, "art", "art-", isInMixedFolder, ImageType.Backdrop);
var extraFanartFolder = files
.FirstOrDefault(i => string.Equals(i.Name, "extrafanart", StringComparison.OrdinalIgnoreCase));
@@ -245,12 +259,12 @@ namespace MediaBrowser.LocalMetadata.Images
}));
}
- private void PopulateScreenshots(List<LocalImageInfo> images, List<FileSystemInfo> files, string imagePrefix)
+ private void PopulateScreenshots(List<LocalImageInfo> images, List<FileSystemInfo> files, string imagePrefix, bool isInMixedFolder)
{
- PopulateBackdrops(images, files, imagePrefix, "screenshot", "screenshot", ImageType.Screenshot);
+ PopulateBackdrops(images, files, imagePrefix, "screenshot", "screenshot", isInMixedFolder, ImageType.Screenshot);
}
- private void PopulateBackdrops(List<LocalImageInfo> images, List<FileSystemInfo> files, string imagePrefix, string firstFileName, string subsequentFileNamePrefix, ImageType type)
+ private void PopulateBackdrops(List<LocalImageInfo> images, List<FileSystemInfo> files, string imagePrefix, string firstFileName, string subsequentFileNamePrefix, bool isInMixedFolder, ImageType type)
{
AddImage(files, images, imagePrefix + firstFileName, type);
@@ -270,6 +284,29 @@ namespace MediaBrowser.LocalMetadata.Images
}
}
}
+
+ // Support without the prefix
+ if (!isInMixedFolder)
+ {
+ AddImage(files, images, firstFileName, type);
+
+ unfound = 0;
+ for (var i = 1; i <= 20; i++)
+ {
+ // Screenshot Image
+ var found = AddImage(files, images, subsequentFileNamePrefix + i, type);
+
+ if (!found)
+ {
+ unfound++;
+
+ if (unfound >= 3)
+ {
+ break;
+ }
+ }
+ }
+ }
}
private readonly CultureInfo _usCulture = new CultureInfo("en-US");
@@ -310,6 +347,21 @@ namespace MediaBrowser.LocalMetadata.Images
}
}
+ private bool AddImage(List<FileSystemInfo> files, List<LocalImageInfo> images, string name, string imagePrefix, bool isInMixedFolder, ImageType type)
+ {
+ var added = AddImage(files, images, imagePrefix + name, type);
+
+ if (!isInMixedFolder)
+ {
+ if (AddImage(files, images, name, type))
+ {
+ added = true;
+ }
+ }
+
+ return added;
+ }
+
private bool AddImage(IEnumerable<FileSystemInfo> files, List<LocalImageInfo> images, string name, ImageType type)
{
var image = GetImage(files, name) as FileInfo;
diff --git a/MediaBrowser.LocalMetadata/MediaBrowser.LocalMetadata.csproj b/MediaBrowser.LocalMetadata/MediaBrowser.LocalMetadata.csproj
index 1daf0e4ac4..cb9c23494a 100644
--- a/MediaBrowser.LocalMetadata/MediaBrowser.LocalMetadata.csproj
+++ b/MediaBrowser.LocalMetadata/MediaBrowser.LocalMetadata.csproj
@@ -72,7 +72,6 @@
<Compile Include="Providers\PlaylistXmlProvider.cs" />
<Compile Include="Providers\SeasonXmlProvider.cs" />
<Compile Include="Providers\SeriesXmlProvider.cs" />
- <Compile Include="Providers\TrailerXmlProvider.cs" />
<Compile Include="Providers\VideoXmlProvider.cs" />
<Compile Include="Savers\BoxSetXmlSaver.cs" />
<Compile Include="Savers\ChannelXmlSaver.cs" />
diff --git a/MediaBrowser.LocalMetadata/Parsers/PlaylistXmlParser.cs b/MediaBrowser.LocalMetadata/Parsers/PlaylistXmlParser.cs
index c7f9742008..a12724ff72 100644
--- a/MediaBrowser.LocalMetadata/Parsers/PlaylistXmlParser.cs
+++ b/MediaBrowser.LocalMetadata/Parsers/PlaylistXmlParser.cs
@@ -2,7 +2,9 @@
using MediaBrowser.Controller.Playlists;
using MediaBrowser.Controller.Providers;
using MediaBrowser.Model.Logging;
+using System;
using System.Collections.Generic;
+using System.Linq;
using System.Xml;
namespace MediaBrowser.LocalMetadata.Parsers
@@ -20,7 +22,15 @@ namespace MediaBrowser.LocalMetadata.Parsers
{
case "OwnerUserId":
{
- item.OwnerUserId = reader.ReadElementContentAsString();
+ var userId = reader.ReadElementContentAsString();
+ if (!item.Shares.Any(i => string.Equals(userId, i.UserId, StringComparison.OrdinalIgnoreCase)))
+ {
+ item.Shares.Add(new Share
+ {
+ UserId = userId,
+ CanEdit = true
+ });
+ }
break;
}
diff --git a/MediaBrowser.LocalMetadata/Providers/GameXmlProvider.cs b/MediaBrowser.LocalMetadata/Providers/GameXmlProvider.cs
index 83ef6e4243..0a25ce9b67 100644
--- a/MediaBrowser.LocalMetadata/Providers/GameXmlProvider.cs
+++ b/MediaBrowser.LocalMetadata/Providers/GameXmlProvider.cs
@@ -1,10 +1,10 @@
-using System.IO;
-using System.Threading;
-using MediaBrowser.Common.IO;
+using MediaBrowser.Common.IO;
using MediaBrowser.Controller.Entities;
using MediaBrowser.Controller.Providers;
using MediaBrowser.LocalMetadata.Parsers;
using MediaBrowser.Model.Logging;
+using System.IO;
+using System.Threading;
namespace MediaBrowser.LocalMetadata.Providers
{
@@ -25,22 +25,10 @@ namespace MediaBrowser.LocalMetadata.Providers
protected override FileSystemInfo GetXmlFile(ItemInfo info, IDirectoryService directoryService)
{
- var fileInfo = FileSystem.GetFileSystemInfo(info.Path);
-
- var directoryInfo = fileInfo as DirectoryInfo;
-
- if (directoryInfo == null)
- {
- directoryInfo = new DirectoryInfo(Path.GetDirectoryName(info.Path));
- }
-
- var directoryPath = directoryInfo.FullName;
-
- var specificFile = Path.Combine(directoryPath, FileSystem.GetFileNameWithoutExtension(info.Path) + ".xml");
-
+ var specificFile = Path.ChangeExtension(info.Path, ".xml");
var file = new FileInfo(specificFile);
- return info.IsInMixedFolder || file.Exists ? file : new FileInfo(Path.Combine(directoryPath, "game.xml"));
+ return info.IsInMixedFolder || file.Exists ? file : new FileInfo(Path.Combine(Path.GetDirectoryName(info.Path), "game.xml"));
}
}
}
diff --git a/MediaBrowser.LocalMetadata/Providers/TrailerXmlProvider.cs b/MediaBrowser.LocalMetadata/Providers/TrailerXmlProvider.cs
deleted file mode 100644
index 7f96f7d961..0000000000
--- a/MediaBrowser.LocalMetadata/Providers/TrailerXmlProvider.cs
+++ /dev/null
@@ -1,37 +0,0 @@
-using MediaBrowser.Common.IO;
-using MediaBrowser.Controller.Entities;
-using MediaBrowser.Controller.Providers;
-using MediaBrowser.LocalMetadata.Parsers;
-using MediaBrowser.Model.Entities;
-using MediaBrowser.Model.Logging;
-using System.Collections.Generic;
-using System.IO;
-using System.Threading;
-
-namespace MediaBrowser.LocalMetadata.Providers
-{
- public class TrailerXmlProvider : BaseXmlProvider<Trailer>
- {
- private readonly ILogger _logger;
-
- public TrailerXmlProvider(IFileSystem fileSystem, ILogger logger)
- : base(fileSystem)
- {
- _logger = logger;
- }
-
- protected override void Fetch(LocalMetadataResult<Trailer> result, string path, CancellationToken cancellationToken)
- {
- var chapters = new List<ChapterInfo>();
-
- new MovieXmlParser(_logger).Fetch(result.Item, chapters, path, cancellationToken);
-
- result.Chapters = chapters;
- }
-
- protected override FileSystemInfo GetXmlFile(ItemInfo info, IDirectoryService directoryService)
- {
- return MovieXmlProvider.GetXmlFileInfo(info, FileSystem);
- }
- }
-}
diff --git a/MediaBrowser.LocalMetadata/Savers/PlaylistXmlSaver.cs b/MediaBrowser.LocalMetadata/Savers/PlaylistXmlSaver.cs
index 16c4373815..76ef4d4bfa 100644
--- a/MediaBrowser.LocalMetadata/Savers/PlaylistXmlSaver.cs
+++ b/MediaBrowser.LocalMetadata/Savers/PlaylistXmlSaver.cs
@@ -57,11 +57,6 @@ namespace MediaBrowser.LocalMetadata.Savers
builder.Append("<Item>");
- if (!string.IsNullOrEmpty(playlist.OwnerUserId))
- {
- builder.Append("<OwnerUserId>" + SecurityElement.Escape(playlist.OwnerUserId) + "</OwnerUserId>");
- }
-
if (!string.IsNullOrEmpty(playlist.PlaylistMediaType))
{
builder.Append("<PlaylistMediaType>" + SecurityElement.Escape(playlist.PlaylistMediaType) + "</PlaylistMediaType>");
diff --git a/MediaBrowser.LocalMetadata/Savers/XmlSaverHelpers.cs b/MediaBrowser.LocalMetadata/Savers/XmlSaverHelpers.cs
index 93876f4742..3e11c994bc 100644
--- a/MediaBrowser.LocalMetadata/Savers/XmlSaverHelpers.cs
+++ b/MediaBrowser.LocalMetadata/Savers/XmlSaverHelpers.cs
@@ -645,6 +645,29 @@ namespace MediaBrowser.LocalMetadata.Savers
{
AddLinkedChildren(playlist, builder, "PlaylistItems", "PlaylistItem");
}
+
+ var hasShares = item as IHasShares;
+ if (hasShares != null)
+ {
+
+ }
+ }
+
+ public static void AddShares(IHasShares item, StringBuilder builder)
+ {
+ builder.Append("<Shares>");
+
+ foreach (var share in item.Shares)
+ {
+ builder.Append("<Share>");
+
+ builder.Append("<UserId>" + SecurityElement.Escape(share.UserId) + "</UserId>");
+ builder.Append("<CanEdit>" + SecurityElement.Escape(share.CanEdit.ToString().ToLower()) + "</CanEdit>");
+
+ builder.Append("</Share>");
+ }
+
+ builder.Append("</Shares>");
}
public static void AddChapters(Video item, StringBuilder builder, IItemRepository repository)
diff --git a/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs b/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs
index 82d5e0344c..7fb27e25f5 100644
--- a/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs
+++ b/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs
@@ -299,6 +299,9 @@ namespace MediaBrowser.MediaEncoding.Encoder
}
}
+ // TODO: Output in webp for smaller sizes
+ // -f image2 -f webp
+
// Use ffmpeg to sample 100 (we can drop this if required using thumbnail=50 for 50 frames) frames and pick the best thumbnail. Have a fall back just in case.
var args = useIFrame ? string.Format("-i {0} -threads 0 -v quiet -vframes 1 -vf \"{2},thumbnail=30\" -f image2 \"{1}\"", inputPath, "-", vf) :
string.Format("-i {0} -threads 0 -v quiet -vframes 1 -vf \"{2}\" -f image2 \"{1}\"", inputPath, "-", vf);
diff --git a/MediaBrowser.Model.Portable/MediaBrowser.Model.Portable.csproj b/MediaBrowser.Model.Portable/MediaBrowser.Model.Portable.csproj
index 292bad943a..f2497c5a9b 100644
--- a/MediaBrowser.Model.Portable/MediaBrowser.Model.Portable.csproj
+++ b/MediaBrowser.Model.Portable/MediaBrowser.Model.Portable.csproj
@@ -275,6 +275,9 @@
<Compile Include="..\MediaBrowser.Model\Devices\DeviceOptions.cs">
<Link>Devices\DeviceOptions.cs</Link>
</Compile>
+ <Compile Include="..\MediaBrowser.Model\Devices\DeviceQuery.cs">
+ <Link>Devices\DeviceQuery.cs</Link>
+ </Compile>
<Compile Include="..\MediaBrowser.Model\Devices\DevicesOptions.cs">
<Link>Devices\DevicesOptions.cs</Link>
</Compile>
@@ -347,9 +350,6 @@
<Compile Include="..\MediaBrowser.Model\Dlna\ProfileConditionValue.cs">
<Link>Dlna\ProfileConditionValue.cs</Link>
</Compile>
- <Compile Include="..\MediaBrowser.Model\Dlna\Profiles\AndroidProfile.cs">
- <Link>Dlna\Profiles\AndroidProfile.cs</Link>
- </Compile>
<Compile Include="..\MediaBrowser.Model\Dlna\Profiles\DefaultProfile.cs">
<Link>Dlna\Profiles\DefaultProfile.cs</Link>
</Compile>
@@ -404,12 +404,12 @@
<Compile Include="..\MediaBrowser.Model\Drawing\DrawingUtils.cs">
<Link>Drawing\DrawingUtils.cs</Link>
</Compile>
+ <Compile Include="..\MediaBrowser.Model\Drawing\ImageFormat.cs">
+ <Link>Drawing\ImageFormat.cs</Link>
+ </Compile>
<Compile Include="..\MediaBrowser.Model\Drawing\ImageOrientation.cs">
<Link>Drawing\ImageOrientation.cs</Link>
</Compile>
- <Compile Include="..\MediaBrowser.Model\Drawing\ImageOutputFormat.cs">
- <Link>Drawing\ImageOutputFormat.cs</Link>
- </Compile>
<Compile Include="..\MediaBrowser.Model\Drawing\ImageSize.cs">
<Link>Drawing\ImageSize.cs</Link>
</Compile>
@@ -422,6 +422,9 @@
<Compile Include="..\MediaBrowser.Model\Dto\ChapterInfoDto.cs">
<Link>Dto\ChapterInfoDto.cs</Link>
</Compile>
+ <Compile Include="..\MediaBrowser.Model\Dto\DtoOptions.cs">
+ <Link>Dto\DtoOptions.cs</Link>
+ </Compile>
<Compile Include="..\MediaBrowser.Model\Dto\GameSystemSummary.cs">
<Link>Dto\GameSystemSummary.cs</Link>
</Compile>
@@ -1031,6 +1034,12 @@
<Compile Include="..\MediaBrowser.Model\Sync\SyncJobItem.cs">
<Link>Sync\SyncJobItem.cs</Link>
</Compile>
+ <Compile Include="..\MediaBrowser.Model\Sync\SyncJobItemQuery.cs">
+ <Link>SyncJobItemQuery.cs</Link>
+ </Compile>
+ <Compile Include="..\MediaBrowser.Model\Sync\SyncJobItemStatus.cs">
+ <Link>Sync\SyncJobItemStatus.cs</Link>
+ </Compile>
<Compile Include="..\MediaBrowser.Model\Sync\SyncJobQuery.cs">
<Link>Sync\SyncJobQuery.cs</Link>
</Compile>
@@ -1040,9 +1049,6 @@
<Compile Include="..\MediaBrowser.Model\Sync\SyncJobStatus.cs">
<Link>Sync\SyncJobStatus.cs</Link>
</Compile>
- <Compile Include="..\MediaBrowser.Model\Sync\SyncLimitType.cs">
- <Link>Sync\SyncLimitType.cs</Link>
- </Compile>
<Compile Include="..\MediaBrowser.Model\Sync\SyncQuality.cs">
<Link>Sync\SyncQuality.cs</Link>
</Compile>
@@ -1118,6 +1124,9 @@
<Compile Include="..\MediaBrowser.Model\Users\PinRedeemResult.cs">
<Link>Users\PinRedeemResult.cs</Link>
</Compile>
+ <Compile Include="..\MediaBrowser.Model\Users\UserPolicy.cs">
+ <Link>Users\UserPolicy.cs</Link>
+ </Compile>
<Compile Include="..\SharedVersion.cs">
<Link>Properties\SharedVersion.cs</Link>
</Compile>
diff --git a/MediaBrowser.Model.net35/MediaBrowser.Model.net35.csproj b/MediaBrowser.Model.net35/MediaBrowser.Model.net35.csproj
index 96a3a21a5d..b44accb7ac 100644
--- a/MediaBrowser.Model.net35/MediaBrowser.Model.net35.csproj
+++ b/MediaBrowser.Model.net35/MediaBrowser.Model.net35.csproj
@@ -240,6 +240,9 @@
<Compile Include="..\MediaBrowser.Model\Devices\DeviceOptions.cs">
<Link>Devices\DeviceOptions.cs</Link>
</Compile>
+ <Compile Include="..\MediaBrowser.Model\Devices\DeviceQuery.cs">
+ <Link>Devices\DeviceQuery.cs</Link>
+ </Compile>
<Compile Include="..\MediaBrowser.Model\Devices\DevicesOptions.cs">
<Link>Devices\DevicesOptions.cs</Link>
</Compile>
@@ -312,9 +315,6 @@
<Compile Include="..\MediaBrowser.Model\Dlna\ProfileConditionValue.cs">
<Link>Dlna\ProfileConditionValue.cs</Link>
</Compile>
- <Compile Include="..\MediaBrowser.Model\Dlna\Profiles\AndroidProfile.cs">
- <Link>Dlna\Profiles\AndroidProfile.cs</Link>
- </Compile>
<Compile Include="..\MediaBrowser.Model\Dlna\Profiles\DefaultProfile.cs">
<Link>Dlna\Profiles\DefaultProfile.cs</Link>
</Compile>
@@ -369,12 +369,12 @@
<Compile Include="..\MediaBrowser.Model\Drawing\DrawingUtils.cs">
<Link>Drawing\DrawingUtils.cs</Link>
</Compile>
+ <Compile Include="..\MediaBrowser.Model\Drawing\ImageFormat.cs">
+ <Link>Drawing\ImageFormat.cs</Link>
+ </Compile>
<Compile Include="..\MediaBrowser.Model\Drawing\ImageOrientation.cs">
<Link>Drawing\ImageOrientation.cs</Link>
</Compile>
- <Compile Include="..\MediaBrowser.Model\Drawing\ImageOutputFormat.cs">
- <Link>Drawing\ImageOutputFormat.cs</Link>
- </Compile>
<Compile Include="..\MediaBrowser.Model\Drawing\ImageSize.cs">
<Link>Drawing\ImageSize.cs</Link>
</Compile>
@@ -387,6 +387,9 @@
<Compile Include="..\MediaBrowser.Model\Dto\ChapterInfoDto.cs">
<Link>Dto\ChapterInfoDto.cs</Link>
</Compile>
+ <Compile Include="..\MediaBrowser.Model\Dto\DtoOptions.cs">
+ <Link>Dto\DtoOptions.cs</Link>
+ </Compile>
<Compile Include="..\MediaBrowser.Model\Dto\GameSystemSummary.cs">
<Link>Dto\GameSystemSummary.cs</Link>
</Compile>
@@ -990,6 +993,12 @@
<Compile Include="..\MediaBrowser.Model\Sync\SyncJobItem.cs">
<Link>Sync\SyncJobItem.cs</Link>
</Compile>
+ <Compile Include="..\MediaBrowser.Model\Sync\SyncJobItemQuery.cs">
+ <Link>Sync\SyncJobItemQuery.cs</Link>
+ </Compile>
+ <Compile Include="..\MediaBrowser.Model\Sync\SyncJobItemStatus.cs">
+ <Link>Sync\SyncJobItemStatus.cs</Link>
+ </Compile>
<Compile Include="..\MediaBrowser.Model\Sync\SyncJobQuery.cs">
<Link>Sync\SyncJobQuery.cs</Link>
</Compile>
@@ -999,9 +1008,6 @@
<Compile Include="..\MediaBrowser.Model\Sync\SyncJobStatus.cs">
<Link>Sync\SyncJobStatus.cs</Link>
</Compile>
- <Compile Include="..\MediaBrowser.Model\Sync\SyncLimitType.cs">
- <Link>Sync\SyncLimitType.cs</Link>
- </Compile>
<Compile Include="..\MediaBrowser.Model\Sync\SyncQuality.cs">
<Link>Sync\SyncQuality.cs</Link>
</Compile>
@@ -1077,6 +1083,9 @@
<Compile Include="..\MediaBrowser.Model\Users\PinRedeemResult.cs">
<Link>Users\PinRedeemResult.cs</Link>
</Compile>
+ <Compile Include="..\MediaBrowser.Model\Users\UserPolicy.cs">
+ <Link>Users\UserPolicy.cs</Link>
+ </Compile>
<Compile Include="..\SharedVersion.cs">
<Link>Properties\SharedVersion.cs</Link>
</Compile>
diff --git a/MediaBrowser.Model/ApiClient/ConnectionMode.cs b/MediaBrowser.Model/ApiClient/ConnectionMode.cs
index f14c88a093..5dc224d959 100644
--- a/MediaBrowser.Model/ApiClient/ConnectionMode.cs
+++ b/MediaBrowser.Model/ApiClient/ConnectionMode.cs
@@ -3,6 +3,7 @@ namespace MediaBrowser.Model.ApiClient
public enum ConnectionMode
{
Local = 1,
- Remote = 2
+ Remote = 2,
+ Manual = 3
}
} \ No newline at end of file
diff --git a/MediaBrowser.Model/ApiClient/IApiClient.cs b/MediaBrowser.Model/ApiClient/IApiClient.cs
index 15ec130cfe..13907e5c60 100644
--- a/MediaBrowser.Model/ApiClient/IApiClient.cs
+++ b/MediaBrowser.Model/ApiClient/IApiClient.cs
@@ -14,6 +14,7 @@ using MediaBrowser.Model.Querying;
using MediaBrowser.Model.Search;
using MediaBrowser.Model.Serialization;
using MediaBrowser.Model.Session;
+using MediaBrowser.Model.Sync;
using MediaBrowser.Model.System;
using MediaBrowser.Model.Tasks;
using MediaBrowser.Model.Users;
@@ -413,7 +414,7 @@ namespace MediaBrowser.Model.ApiClient
/// </summary>
/// <param name="query">The query.</param>
/// <returns>Task{ItemsResult}.</returns>
- Task<ItemsResult> GetUpcomingEpisodesAsync(NextUpQuery query);
+ Task<ItemsResult> GetUpcomingEpisodesAsync(UpcomingEpisodesQuery query);
/// <summary>
/// Gets a genre
@@ -1372,6 +1373,20 @@ namespace MediaBrowser.Model.ApiClient
Task<DevicesOptions> GetDevicesOptions();
/// <summary>
+ /// Updates the item.
+ /// </summary>
+ /// <param name="item">The item.</param>
+ /// <returns>Task.</returns>
+ Task UpdateItem(BaseItemDto item);
+
+ /// <summary>
+ /// Requests the synchronize.
+ /// </summary>
+ /// <param name="request">The request.</param>
+ /// <returns>Task&lt;SyncJob&gt;.</returns>
+ Task<SyncJob> RequestSync(SyncJobRequest request);
+
+ /// <summary>
/// Opens the web socket.
/// </summary>
/// <param name="webSocketFactory">The web socket factory.</param>
diff --git a/MediaBrowser.Model/ApiClient/ServerCredentials.cs b/MediaBrowser.Model/ApiClient/ServerCredentials.cs
index 2490ba606c..fbbc6c05de 100644
--- a/MediaBrowser.Model/ApiClient/ServerCredentials.cs
+++ b/MediaBrowser.Model/ApiClient/ServerCredentials.cs
@@ -50,10 +50,14 @@ namespace MediaBrowser.Model.ApiClient
{
existing.RemoteAddress = server.RemoteAddress;
}
- if (!existing.IsLocalAddressFixed && !string.IsNullOrEmpty(server.LocalAddress))
+ if (!string.IsNullOrEmpty(server.LocalAddress))
{
existing.LocalAddress = server.LocalAddress;
}
+ if (!string.IsNullOrEmpty(server.ManualAddress))
+ {
+ existing.LocalAddress = server.ManualAddress;
+ }
if (!string.IsNullOrEmpty(server.Name))
{
existing.Name = server.Name;
@@ -62,9 +66,9 @@ namespace MediaBrowser.Model.ApiClient
{
existing.WakeOnLanInfos = server.WakeOnLanInfos.ToList();
}
- if (server.IsLocalAddressFixed)
+ if (server.LastConnectionMode.HasValue)
{
- existing.IsLocalAddressFixed = true;
+ existing.LastConnectionMode = server.LastConnectionMode;
}
}
else
diff --git a/MediaBrowser.Model/ApiClient/ServerDiscoveryInfo.cs b/MediaBrowser.Model/ApiClient/ServerDiscoveryInfo.cs
index bb2b48e76f..e2f7806055 100644
--- a/MediaBrowser.Model/ApiClient/ServerDiscoveryInfo.cs
+++ b/MediaBrowser.Model/ApiClient/ServerDiscoveryInfo.cs
@@ -18,5 +18,10 @@ namespace MediaBrowser.Model.ApiClient
/// </summary>
/// <value>The name.</value>
public string Name { get; set; }
+ /// <summary>
+ /// Gets or sets the endpoint address.
+ /// </summary>
+ /// <value>The endpoint address.</value>
+ public string EndpointAddress { get; set; }
}
}
diff --git a/MediaBrowser.Model/ApiClient/ServerInfo.cs b/MediaBrowser.Model/ApiClient/ServerInfo.cs
index 95cdf006b5..46cc560af2 100644
--- a/MediaBrowser.Model/ApiClient/ServerInfo.cs
+++ b/MediaBrowser.Model/ApiClient/ServerInfo.cs
@@ -11,14 +11,14 @@ namespace MediaBrowser.Model.ApiClient
public String Id { get; set; }
public String LocalAddress { get; set; }
public String RemoteAddress { get; set; }
+ public String ManualAddress { get; set; }
public String UserId { get; set; }
public String AccessToken { get; set; }
public List<WakeOnLanInfo> WakeOnLanInfos { get; set; }
public DateTime DateLastAccessed { get; set; }
public String ExchangeToken { get; set; }
public UserLinkType? UserLinkType { get; set; }
-
- public bool IsLocalAddressFixed { get; set; }
+ public ConnectionMode? LastConnectionMode { get; set; }
public ServerInfo()
{
@@ -30,7 +30,7 @@ namespace MediaBrowser.Model.ApiClient
Name = systemInfo.ServerName;
Id = systemInfo.Id;
- if (!IsLocalAddressFixed && !string.IsNullOrEmpty(systemInfo.LocalAddress))
+ if (!string.IsNullOrEmpty(systemInfo.LocalAddress))
{
LocalAddress = systemInfo.LocalAddress;
}
@@ -55,5 +55,20 @@ namespace MediaBrowser.Model.ApiClient
}
}
}
+
+ public string GetAddress(ConnectionMode mode)
+ {
+ switch (mode)
+ {
+ case ConnectionMode.Local:
+ return LocalAddress;
+ case ConnectionMode.Manual:
+ return ManualAddress;
+ case ConnectionMode.Remote:
+ return RemoteAddress;
+ default:
+ throw new ArgumentException("Unexpected ConnectionMode");
+ }
+ }
}
}
diff --git a/MediaBrowser.Model/Configuration/ServerConfiguration.cs b/MediaBrowser.Model/Configuration/ServerConfiguration.cs
index c9df615e1c..b9eaf70010 100644
--- a/MediaBrowser.Model/Configuration/ServerConfiguration.cs
+++ b/MediaBrowser.Model/Configuration/ServerConfiguration.cs
@@ -56,6 +56,12 @@ namespace MediaBrowser.Model.Configuration
public bool SaveLocalMeta { get; set; }
/// <summary>
+ /// Gets or sets a value indicating whether [enable localized guids].
+ /// </summary>
+ /// <value><c>true</c> if [enable localized guids]; otherwise, <c>false</c>.</value>
+ public bool EnableLocalizedGuids { get; set; }
+
+ /// <summary>
/// Gets or sets the preferred metadata language.
/// </summary>
/// <value>The preferred metadata language.</value>
diff --git a/MediaBrowser.Model/Devices/DeviceQuery.cs b/MediaBrowser.Model/Devices/DeviceQuery.cs
new file mode 100644
index 0000000000..76f7117b64
--- /dev/null
+++ b/MediaBrowser.Model/Devices/DeviceQuery.cs
@@ -0,0 +1,17 @@
+
+namespace MediaBrowser.Model.Devices
+{
+ public class DeviceQuery
+ {
+ /// <summary>
+ /// Gets or sets a value indicating whether [supports content uploading].
+ /// </summary>
+ /// <value><c>null</c> if [supports content uploading] contains no value, <c>true</c> if [supports content uploading]; otherwise, <c>false</c>.</value>
+ public bool? SupportsContentUploading { get; set; }
+ /// <summary>
+ /// Gets or sets a value indicating whether [supports unique identifier].
+ /// </summary>
+ /// <value><c>null</c> if [supports unique identifier] contains no value, <c>true</c> if [supports unique identifier]; otherwise, <c>false</c>.</value>
+ public bool? SupportsUniqueIdentifier { get; set; }
+ }
+}
diff --git a/MediaBrowser.Model/Dlna/Profiles/AndroidProfile.cs b/MediaBrowser.Model/Dlna/Profiles/AndroidProfile.cs
deleted file mode 100644
index 7aa7f98db1..0000000000
--- a/MediaBrowser.Model/Dlna/Profiles/AndroidProfile.cs
+++ /dev/null
@@ -1,167 +0,0 @@
-using System.Collections.Generic;
-using System.Xml.Serialization;
-
-namespace MediaBrowser.Model.Dlna.Profiles
-{
- [XmlRoot("Profile")]
- public class AndroidProfile : DefaultProfile
- {
- public AndroidProfile()
- : this(true, true, new[] { "baseline", "constrained baseline" })
- {
-
- }
-
- public AndroidProfile(bool supportsHls,
- bool supportsMpegDash,
- string[] supportedH264Profiles)
- {
- Name = "Android";
-
- List<TranscodingProfile> transcodingProfiles = new List<TranscodingProfile>();
-
- transcodingProfiles.Add(new TranscodingProfile
- {
- Container = "mp3",
- AudioCodec = "mp3",
- Type = DlnaProfileType.Audio
- });
-
- if (supportsMpegDash)
- {
-
- }
- if (supportsHls)
- {
- transcodingProfiles.Add(new TranscodingProfile
- {
- Protocol = "hls",
- Container = "ts",
- VideoCodec = "h264",
- AudioCodec = "aac",
- Type = DlnaProfileType.Video,
- Context = EncodingContext.Streaming
- });
- }
- transcodingProfiles.Add(new TranscodingProfile
- {
- Container = "mp4",
- VideoCodec = "h264",
- AudioCodec = "aac",
- Type = DlnaProfileType.Video,
- Context = EncodingContext.Static
- });
-
- TranscodingProfiles = transcodingProfiles.ToArray();
-
- DirectPlayProfiles = new[]
- {
- new DirectPlayProfile
- {
- Container = "mp4",
- VideoCodec = "h264,mpeg4",
- AudioCodec = "aac",
- Type = DlnaProfileType.Video
- },
-
- new DirectPlayProfile
- {
- Container = "mp4,aac",
- AudioCodec = "aac",
- Type = DlnaProfileType.Audio
- },
-
- new DirectPlayProfile
- {
- Container = "mp3",
- AudioCodec = "mp3",
- Type = DlnaProfileType.Audio
- },
-
- new DirectPlayProfile
- {
- Container = "flac",
- AudioCodec = "flac",
- Type = DlnaProfileType.Audio
- },
-
- new DirectPlayProfile
- {
- Container = "ogg",
- AudioCodec = "vorbis",
- Type = DlnaProfileType.Audio
- },
-
- new DirectPlayProfile
- {
- Container = "jpeg,png,gif,bmp",
- Type = DlnaProfileType.Photo
- }
- };
-
- CodecProfiles = new[]
- {
- new CodecProfile
- {
- Type = CodecType.Video,
- Codec= "h264",
-
- Conditions = new []
- {
- new ProfileCondition(ProfileConditionType.EqualsAny, ProfileConditionValue.VideoProfile, string.Join("|", supportedH264Profiles)),
- new ProfileCondition(ProfileConditionType.LessThanEqual, ProfileConditionValue.Width, "1920"),
- new ProfileCondition(ProfileConditionType.LessThanEqual, ProfileConditionValue.Height, "1080"),
- new ProfileCondition(ProfileConditionType.LessThanEqual, ProfileConditionValue.VideoBitDepth, "8"),
- new ProfileCondition(ProfileConditionType.NotEquals, ProfileConditionValue.IsAnamorphic, "true"),
- new ProfileCondition(ProfileConditionType.Equals, ProfileConditionValue.IsCabac, "true")
- }
- },
-
- new CodecProfile
- {
- Type = CodecType.Video,
-
- Conditions = new []
- {
- new ProfileCondition(ProfileConditionType.LessThanEqual, ProfileConditionValue.Width, "1920"),
- new ProfileCondition(ProfileConditionType.LessThanEqual, ProfileConditionValue.Height, "1080"),
- new ProfileCondition(ProfileConditionType.LessThanEqual, ProfileConditionValue.VideoBitDepth, "8"),
- new ProfileCondition(ProfileConditionType.NotEquals, ProfileConditionValue.IsAnamorphic, "true")
- }
- },
-
- new CodecProfile
- {
- Type = CodecType.VideoAudio,
- Codec = "aac",
- Conditions = new []
- {
- new ProfileCondition(ProfileConditionType.LessThanEqual, ProfileConditionValue.AudioChannels, "2")
- }
- },
-
- new CodecProfile
- {
- Type = CodecType.Audio,
- Codec = "aac",
- Conditions = new []
- {
- new ProfileCondition(ProfileConditionType.LessThanEqual, ProfileConditionValue.AudioChannels, "2")
- }
- },
-
- new CodecProfile
- {
- Type = CodecType.Audio,
- Codec = "mp3",
- Conditions = new []
- {
- new ProfileCondition(ProfileConditionType.LessThanEqual, ProfileConditionValue.AudioChannels, "2"),
- new ProfileCondition(ProfileConditionType.LessThanEqual, ProfileConditionValue.AudioBitrate, "320000")
- }
- }
- };
-
- }
- }
-}
diff --git a/MediaBrowser.Model/Dlna/StreamBuilder.cs b/MediaBrowser.Model/Dlna/StreamBuilder.cs
index 4907abfd73..fb26f1ff8c 100644
--- a/MediaBrowser.Model/Dlna/StreamBuilder.cs
+++ b/MediaBrowser.Model/Dlna/StreamBuilder.cs
@@ -298,7 +298,6 @@ namespace MediaBrowser.Model.Dlna
playlistItem.VideoCodec = transcodingProfile.VideoCodec;
playlistItem.Protocol = transcodingProfile.Protocol;
playlistItem.AudioStreamIndex = audioStreamIndex;
- playlistItem.VideoProfile = transcodingProfile.VideoProfile;
List<ProfileCondition> videoTranscodingConditions = new List<ProfileCondition>();
foreach (CodecProfile i in options.Profile.CodecProfiles)
diff --git a/MediaBrowser.Model/Dlna/TranscodingProfile.cs b/MediaBrowser.Model/Dlna/TranscodingProfile.cs
index ad82d6facd..d9963eb750 100644
--- a/MediaBrowser.Model/Dlna/TranscodingProfile.cs
+++ b/MediaBrowser.Model/Dlna/TranscodingProfile.cs
@@ -29,9 +29,6 @@ namespace MediaBrowser.Model.Dlna
[XmlAttribute("transcodeSeekInfo")]
public TranscodeSeekInfo TranscodeSeekInfo { get; set; }
- [XmlAttribute("videoProfile")]
- public string VideoProfile { get; set; }
-
[XmlAttribute("context")]
public EncodingContext Context { get; set; }
diff --git a/MediaBrowser.Model/Drawing/ImageOutputFormat.cs b/MediaBrowser.Model/Drawing/ImageFormat.cs
index ec32f64f26..0172c9754f 100644
--- a/MediaBrowser.Model/Drawing/ImageOutputFormat.cs
+++ b/MediaBrowser.Model/Drawing/ImageFormat.cs
@@ -4,7 +4,7 @@ namespace MediaBrowser.Model.Drawing
/// <summary>
/// Enum ImageOutputFormat
/// </summary>
- public enum ImageOutputFormat
+ public enum ImageFormat
{
/// <summary>
/// The BMP
diff --git a/MediaBrowser.Model/Drawing/ImageSize.cs b/MediaBrowser.Model/Drawing/ImageSize.cs
index 076e2ddbfa..5ed6e72933 100644
--- a/MediaBrowser.Model/Drawing/ImageSize.cs
+++ b/MediaBrowser.Model/Drawing/ImageSize.cs
@@ -55,6 +55,12 @@ namespace MediaBrowser.Model.Drawing
ParseValue(value);
}
+ public ImageSize(int width, int height)
+ {
+ _width = width;
+ _height = height;
+ }
+
private void ParseValue(string value)
{
if (!string.IsNullOrEmpty(value))
diff --git a/MediaBrowser.Model/Dto/BaseItemDto.cs b/MediaBrowser.Model/Dto/BaseItemDto.cs
index a9f13374bc..45f6810665 100644
--- a/MediaBrowser.Model/Dto/BaseItemDto.cs
+++ b/MediaBrowser.Model/Dto/BaseItemDto.cs
@@ -64,7 +64,7 @@ namespace MediaBrowser.Model.Dto
public float? Metascore { get; set; }
- public bool IsUnidentified { get; set; }
+ public bool? IsUnidentified { get; set; }
public int? AnimeSeriesIndex { get; set; }
@@ -186,6 +186,12 @@ namespace MediaBrowser.Model.Dto
/// </summary>
/// <value>The genres.</value>
public List<string> Genres { get; set; }
+
+ /// <summary>
+ /// Gets or sets the series genres.
+ /// </summary>
+ /// <value>The series genres.</value>
+ public List<string> SeriesGenres { get; set; }
/// <summary>
/// Gets or sets the community rating.
@@ -218,6 +224,12 @@ namespace MediaBrowser.Model.Dto
public long? RunTimeTicks { get; set; }
/// <summary>
+ /// Gets or sets the recursive unplayed item count.
+ /// </summary>
+ /// <value>The recursive unplayed item count.</value>
+ public int? RecursiveUnplayedItemCount { get; set; }
+
+ /// <summary>
/// Gets or sets the play access.
/// </summary>
/// <value>The play access.</value>
@@ -236,13 +248,6 @@ namespace MediaBrowser.Model.Dto
public int? ProductionYear { get; set; }
/// <summary>
- /// Gets or sets the recursive unplayed item count.
- /// </summary>
- /// <value>The recursive unplayed item count.</value>
- [Obsolete]
- public int? RecursiveUnplayedItemCount { get; set; }
-
- /// <summary>
/// Gets or sets the season count.
/// </summary>
/// <value>The season count.</value>
@@ -709,11 +714,6 @@ namespace MediaBrowser.Model.Dto
/// <value>The game count.</value>
public int? GameCount { get; set; }
/// <summary>
- /// Gets or sets the trailer count.
- /// </summary>
- /// <value>The trailer count.</value>
- public int? TrailerCount { get; set; }
- /// <summary>
/// Gets or sets the song count.
/// </summary>
/// <value>The song count.</value>
diff --git a/MediaBrowser.Model/Dto/DtoOptions.cs b/MediaBrowser.Model/Dto/DtoOptions.cs
new file mode 100644
index 0000000000..069d71fceb
--- /dev/null
+++ b/MediaBrowser.Model/Dto/DtoOptions.cs
@@ -0,0 +1,32 @@
+using MediaBrowser.Model.Entities;
+using MediaBrowser.Model.Querying;
+using System.Collections.Generic;
+
+namespace MediaBrowser.Model.Dto
+{
+ public class DtoOptions
+ {
+ public List<ItemFields> Fields { get; set; }
+ public List<ImageType> ImageTypes { get; set; }
+ public int ImageTypeLimit { get; set; }
+ public bool EnableImages { get; set; }
+
+ public DtoOptions()
+ {
+ Fields = new List<ItemFields>();
+ ImageTypes = new List<ImageType>();
+ ImageTypeLimit = int.MaxValue;
+ EnableImages = true;
+ }
+
+ public int GetImageLimit(ImageType type)
+ {
+ if (EnableImages && ImageTypes.Contains(type))
+ {
+ return ImageTypeLimit;
+ }
+
+ return 0;
+ }
+ }
+}
diff --git a/MediaBrowser.Model/Dto/ImageOptions.cs b/MediaBrowser.Model/Dto/ImageOptions.cs
index 037be4a877..8e35c1323f 100644
--- a/MediaBrowser.Model/Dto/ImageOptions.cs
+++ b/MediaBrowser.Model/Dto/ImageOptions.cs
@@ -73,7 +73,7 @@ namespace MediaBrowser.Model.Dto
/// Gets or sets the format.
/// </summary>
/// <value>The format.</value>
- public ImageOutputFormat? Format { get; set; }
+ public ImageFormat? Format { get; set; }
/// <summary>
/// Gets or sets a value indicating whether [add played indicator].
diff --git a/MediaBrowser.Model/MediaBrowser.Model.csproj b/MediaBrowser.Model/MediaBrowser.Model.csproj
index b09f694c64..e370ad8e03 100644
--- a/MediaBrowser.Model/MediaBrowser.Model.csproj
+++ b/MediaBrowser.Model/MediaBrowser.Model.csproj
@@ -113,11 +113,11 @@
<Compile Include="Connect\PinStatusResult.cs" />
<Compile Include="Connect\UserLinkType.cs" />
<Compile Include="Devices\DeviceOptions.cs" />
+ <Compile Include="Devices\DeviceQuery.cs" />
<Compile Include="Devices\LocalFileInfo.cs" />
<Compile Include="Devices\DeviceInfo.cs" />
<Compile Include="Devices\DevicesOptions.cs" />
<Compile Include="Dlna\EncodingContext.cs" />
- <Compile Include="Dlna\Profiles\AndroidProfile.cs" />
<Compile Include="Dlna\Profiles\DefaultProfile.cs" />
<Compile Include="Dlna\ResolutionConfiguration.cs" />
<Compile Include="Dlna\ResolutionNormalizer.cs" />
@@ -125,6 +125,7 @@
<Compile Include="Dlna\SubtitleDeliveryMethod.cs" />
<Compile Include="Dlna\SubtitleStreamInfo.cs" />
<Compile Include="Drawing\ImageOrientation.cs" />
+ <Compile Include="Dto\DtoOptions.cs" />
<Compile Include="Dto\IHasServerId.cs" />
<Compile Include="MediaInfo\LiveMediaInfoResult.cs" />
<Compile Include="Dto\MediaSourceType.cs" />
@@ -191,7 +192,7 @@
<Compile Include="Dlna\TranscodingProfile.cs" />
<Compile Include="Dlna\VideoOptions.cs" />
<Compile Include="Dlna\XmlAttribute.cs" />
- <Compile Include="Drawing\ImageOutputFormat.cs" />
+ <Compile Include="Drawing\ImageFormat.cs" />
<Compile Include="Drawing\ImageSize.cs" />
<Compile Include="Dto\BaseItemPerson.cs" />
<Compile Include="Dto\ChapterInfoDto.cs" />
@@ -364,10 +365,11 @@
<Compile Include="Sync\SyncJob.cs" />
<Compile Include="Sync\SyncJobCreationResult.cs" />
<Compile Include="Sync\SyncJobItem.cs" />
+ <Compile Include="Sync\SyncJobItemQuery.cs" />
+ <Compile Include="Sync\SyncJobItemStatus.cs" />
<Compile Include="Sync\SyncJobQuery.cs" />
<Compile Include="Sync\SyncJobRequest.cs" />
<Compile Include="Sync\SyncJobStatus.cs" />
- <Compile Include="Sync\SyncLimitType.cs" />
<Compile Include="Sync\SyncQuality.cs" />
<Compile Include="Sync\SyncTarget.cs" />
<Compile Include="System\LogFile.cs" />
@@ -412,6 +414,7 @@
<Compile Include="Users\ForgotPasswordAction.cs" />
<Compile Include="Users\ForgotPasswordResult.cs" />
<Compile Include="Users\PinRedeemResult.cs" />
+ <Compile Include="Users\UserPolicy.cs" />
<None Include="Fody.targets" />
<None Include="FodyWeavers.xml" />
<None Include="MediaBrowser.Model.snk" />
diff --git a/MediaBrowser.Model/Querying/ItemFields.cs b/MediaBrowser.Model/Querying/ItemFields.cs
index 9ceca311c3..19e30cd8a7 100644
--- a/MediaBrowser.Model/Querying/ItemFields.cs
+++ b/MediaBrowser.Model/Querying/ItemFields.cs
@@ -7,6 +7,11 @@ namespace MediaBrowser.Model.Querying
public enum ItemFields
{
/// <summary>
+ /// The alternate episode numbers
+ /// </summary>
+ AlternateEpisodeNumbers,
+
+ /// <summary>
/// The awards summary
/// </summary>
AwardSummary,
@@ -82,11 +87,21 @@ namespace MediaBrowser.Model.Querying
Keywords,
/// <summary>
+ /// The media source count
+ /// </summary>
+ MediaSourceCount,
+
+ /// <summary>
/// The media versions
/// </summary>
MediaSources,
/// <summary>
+ /// The metascore
+ /// </summary>
+ Metascore,
+
+ /// <summary>
/// The metadata settings
/// </summary>
Settings,
@@ -127,6 +142,11 @@ namespace MediaBrowser.Model.Querying
PrimaryImageAspectRatio,
/// <summary>
+ /// The original primary image aspect ratio
+ /// </summary>
+ OriginalPrimaryImageAspectRatio,
+
+ /// <summary>
/// The revenue
/// </summary>
Revenue,
@@ -142,6 +162,16 @@ namespace MediaBrowser.Model.Querying
ScreenshotImageTags,
/// <summary>
+ /// The series genres
+ /// </summary>
+ SeriesGenres,
+
+ /// <summary>
+ /// The series studio
+ /// </summary>
+ SeriesStudio,
+
+ /// <summary>
/// The soundtrack ids
/// </summary>
SoundtrackIds,
@@ -172,6 +202,11 @@ namespace MediaBrowser.Model.Querying
Tags,
/// <summary>
+ /// The vote count
+ /// </summary>
+ VoteCount,
+
+ /// <summary>
/// The TMDB collection name
/// </summary>
TmdbCollectionName,
diff --git a/MediaBrowser.Model/Querying/ItemQuery.cs b/MediaBrowser.Model/Querying/ItemQuery.cs
index 3969eedaa8..0f929fa9bb 100644
--- a/MediaBrowser.Model/Querying/ItemQuery.cs
+++ b/MediaBrowser.Model/Querying/ItemQuery.cs
@@ -97,7 +97,7 @@ namespace MediaBrowser.Model.Querying
/// </summary>
/// <value>The genres.</value>
public string[] AllGenres { get; set; }
-
+
/// <summary>
/// Limit results to items containing specific studios
/// </summary>
@@ -211,7 +211,7 @@ namespace MediaBrowser.Model.Querying
/// </summary>
/// <value>The max players.</value>
public int? MaxPlayers { get; set; }
-
+
/// <summary>
/// Gets or sets the name starts with or greater.
/// </summary>
@@ -223,7 +223,7 @@ namespace MediaBrowser.Model.Querying
/// </summary>
/// <value>The name starts with or greater.</value>
public string NameStartsWith { get; set; }
-
+
/// <summary>
/// Gets or sets the name starts with.
/// </summary>
@@ -267,7 +267,7 @@ namespace MediaBrowser.Model.Querying
public bool? CollapseBoxSetItems { get; set; }
public bool? IsPlayed { get; set; }
-
+
/// <summary>
/// Gets or sets the exclude location types.
/// </summary>
@@ -282,7 +282,11 @@ namespace MediaBrowser.Model.Querying
public DateTime? MinPremiereDate { get; set; }
public DateTime? MaxPremiereDate { get; set; }
-
+
+ public bool? EnableImages { get; set; }
+ public int? ImageTypeLimit { get; set; }
+ public ImageType[] EnableImageTypes { get; set; }
+
/// <summary>
/// Initializes a new instance of the <see cref="ItemQuery" /> class.
/// </summary>
@@ -290,16 +294,16 @@ namespace MediaBrowser.Model.Querying
{
LocationTypes = new LocationType[] { };
ExcludeLocationTypes = new LocationType[] { };
-
+
SortBy = new string[] { };
- Filters = new ItemFilter[] {};
+ Filters = new ItemFilter[] { };
- Fields = new ItemFields[] {};
+ Fields = new ItemFields[] { };
- MediaTypes = new string[] {};
+ MediaTypes = new string[] { };
- VideoTypes = new VideoType[] {};
+ VideoTypes = new VideoType[] { };
Genres = new string[] { };
Studios = new string[] { };
@@ -313,6 +317,7 @@ namespace MediaBrowser.Model.Querying
ImageTypes = new ImageType[] { };
AirDays = new DayOfWeek[] { };
SeriesStatuses = new SeriesStatus[] { };
+ EnableImageTypes = new ImageType[] { };
}
}
}
diff --git a/MediaBrowser.Model/Querying/ItemsByNameQuery.cs b/MediaBrowser.Model/Querying/ItemsByNameQuery.cs
index bef2f7aed3..578f22f600 100644
--- a/MediaBrowser.Model/Querying/ItemsByNameQuery.cs
+++ b/MediaBrowser.Model/Querying/ItemsByNameQuery.cs
@@ -101,7 +101,22 @@ namespace MediaBrowser.Model.Querying
/// </summary>
/// <value><c>null</c> if [is played] contains no value, <c>true</c> if [is played]; otherwise, <c>false</c>.</value>
public bool? IsPlayed { get; set; }
-
+ /// <summary>
+ /// Gets or sets a value indicating whether [enable images].
+ /// </summary>
+ /// <value><c>null</c> if [enable images] contains no value, <c>true</c> if [enable images]; otherwise, <c>false</c>.</value>
+ public bool? EnableImages { get; set; }
+ /// <summary>
+ /// Gets or sets the image type limit.
+ /// </summary>
+ /// <value>The image type limit.</value>
+ public int? ImageTypeLimit { get; set; }
+ /// <summary>
+ /// Gets or sets the enable image types.
+ /// </summary>
+ /// <value>The enable image types.</value>
+ public ImageType[] EnableImageTypes { get; set; }
+
/// <summary>
/// Initializes a new instance of the <see cref="ItemsByNameQuery" /> class.
/// </summary>
@@ -115,6 +130,7 @@ namespace MediaBrowser.Model.Querying
SortBy = new string[] { };
ExcludeItemTypes = new string[] { };
IncludeItemTypes = new string[] { };
+ EnableImageTypes = new ImageType[] { };
}
}
}
diff --git a/MediaBrowser.Model/Querying/LatestItemsQuery.cs b/MediaBrowser.Model/Querying/LatestItemsQuery.cs
index ccf5ab087b..a8086e5cd9 100644
--- a/MediaBrowser.Model/Querying/LatestItemsQuery.cs
+++ b/MediaBrowser.Model/Querying/LatestItemsQuery.cs
@@ -1,4 +1,6 @@

+using MediaBrowser.Model.Entities;
+
namespace MediaBrowser.Model.Querying
{
public class LatestItemsQuery
@@ -50,5 +52,25 @@ namespace MediaBrowser.Model.Querying
/// </summary>
/// <value><c>true</c> if [group items]; otherwise, <c>false</c>.</value>
public bool GroupItems { get; set; }
+ /// <summary>
+ /// Gets or sets a value indicating whether [enable images].
+ /// </summary>
+ /// <value><c>null</c> if [enable images] contains no value, <c>true</c> if [enable images]; otherwise, <c>false</c>.</value>
+ public bool? EnableImages { get; set; }
+ /// <summary>
+ /// Gets or sets the image type limit.
+ /// </summary>
+ /// <value>The image type limit.</value>
+ public int? ImageTypeLimit { get; set; }
+ /// <summary>
+ /// Gets or sets the enable image types.
+ /// </summary>
+ /// <value>The enable image types.</value>
+ public ImageType[] EnableImageTypes { get; set; }
+
+ public LatestItemsQuery()
+ {
+ EnableImageTypes = new ImageType[] {};
+ }
}
}
diff --git a/MediaBrowser.Model/Querying/NextUpQuery.cs b/MediaBrowser.Model/Querying/NextUpQuery.cs
index 0e9c9882f3..b5f50bde03 100644
--- a/MediaBrowser.Model/Querying/NextUpQuery.cs
+++ b/MediaBrowser.Model/Querying/NextUpQuery.cs
@@ -1,4 +1,5 @@
-
+using MediaBrowser.Model.Entities;
+
namespace MediaBrowser.Model.Querying
{
public class NextUpQuery
@@ -38,5 +39,25 @@ namespace MediaBrowser.Model.Querying
/// </summary>
/// <value>The fields.</value>
public ItemFields[] Fields { get; set; }
+ /// <summary>
+ /// Gets or sets a value indicating whether [enable images].
+ /// </summary>
+ /// <value><c>null</c> if [enable images] contains no value, <c>true</c> if [enable images]; otherwise, <c>false</c>.</value>
+ public bool? EnableImages { get; set; }
+ /// <summary>
+ /// Gets or sets the image type limit.
+ /// </summary>
+ /// <value>The image type limit.</value>
+ public int? ImageTypeLimit { get; set; }
+ /// <summary>
+ /// Gets or sets the enable image types.
+ /// </summary>
+ /// <value>The enable image types.</value>
+ public ImageType[] EnableImageTypes { get; set; }
+
+ public NextUpQuery()
+ {
+ EnableImageTypes = new ImageType[] {};
+ }
}
}
diff --git a/MediaBrowser.Model/Querying/UpcomingEpisodesQuery.cs b/MediaBrowser.Model/Querying/UpcomingEpisodesQuery.cs
index e5a875e883..665b980eb8 100644
--- a/MediaBrowser.Model/Querying/UpcomingEpisodesQuery.cs
+++ b/MediaBrowser.Model/Querying/UpcomingEpisodesQuery.cs
@@ -1,4 +1,6 @@
-namespace MediaBrowser.Model.Querying
+using MediaBrowser.Model.Entities;
+
+namespace MediaBrowser.Model.Querying
{
public class UpcomingEpisodesQuery
{
@@ -31,5 +33,25 @@
/// </summary>
/// <value>The fields.</value>
public ItemFields[] Fields { get; set; }
+ /// <summary>
+ /// Gets or sets a value indicating whether [enable images].
+ /// </summary>
+ /// <value><c>null</c> if [enable images] contains no value, <c>true</c> if [enable images]; otherwise, <c>false</c>.</value>
+ public bool? EnableImages { get; set; }
+ /// <summary>
+ /// Gets or sets the image type limit.
+ /// </summary>
+ /// <value>The image type limit.</value>
+ public int? ImageTypeLimit { get; set; }
+ /// <summary>
+ /// Gets or sets the enable image types.
+ /// </summary>
+ /// <value>The enable image types.</value>
+ public ImageType[] EnableImageTypes { get; set; }
+
+ public UpcomingEpisodesQuery()
+ {
+ EnableImageTypes = new ImageType[] {};
+ }
}
} \ No newline at end of file
diff --git a/MediaBrowser.Model/Session/ClientCapabilities.cs b/MediaBrowser.Model/Session/ClientCapabilities.cs
index cbc1501d20..f2faa0545e 100644
--- a/MediaBrowser.Model/Session/ClientCapabilities.cs
+++ b/MediaBrowser.Model/Session/ClientCapabilities.cs
@@ -13,11 +13,14 @@ namespace MediaBrowser.Model.Session
public string MessageCallbackUrl { get; set; }
public bool SupportsContentUploading { get; set; }
+ public bool SupportsUniqueIdentifier { get; set; }
+ public bool SupportsSync { get; set; }
public ClientCapabilities()
{
PlayableMediaTypes = new List<string>();
SupportedCommands = new List<string>();
+ SupportsUniqueIdentifier = true;
}
}
} \ No newline at end of file
diff --git a/MediaBrowser.Model/Sync/SyncJob.cs b/MediaBrowser.Model/Sync/SyncJob.cs
index f69fccae50..db67f3cbb5 100644
--- a/MediaBrowser.Model/Sync/SyncJob.cs
+++ b/MediaBrowser.Model/Sync/SyncJob.cs
@@ -46,26 +46,26 @@ namespace MediaBrowser.Model.Sync
/// <value><c>true</c> if [unwatched only]; otherwise, <c>false</c>.</value>
public bool UnwatchedOnly { get; set; }
/// <summary>
- /// Gets or sets the limit.
+ /// Gets or sets a value indicating whether [remove when watched].
/// </summary>
- /// <value>The limit.</value>
- public long? Limit { get; set; }
+ /// <value><c>true</c> if [remove when watched]; otherwise, <c>false</c>.</value>
+ public bool RemoveWhenWatched { get; set; }
/// <summary>
- /// Gets or sets the type of the limit.
+ /// Gets or sets a value indicating whether [synchronize new content].
/// </summary>
- /// <value>The type of the limit.</value>
- public SyncLimitType? LimitType { get; set; }
+ /// <value><c>true</c> if [synchronize new content]; otherwise, <c>false</c>.</value>
+ public bool SyncNewContent { get; set; }
+ /// <summary>
+ /// Gets or sets the item limit.
+ /// </summary>
+ /// <value>The item limit.</value>
+ public int? ItemLimit { get; set; }
/// <summary>
/// Gets or sets the requested item ids.
/// </summary>
/// <value>The requested item ids.</value>
public List<string> RequestedItemIds { get; set; }
/// <summary>
- /// Gets or sets a value indicating whether this instance is dynamic.
- /// </summary>
- /// <value><c>true</c> if this instance is dynamic; otherwise, <c>false</c>.</value>
- public bool IsDynamic { get; set; }
- /// <summary>
/// Gets or sets the date created.
/// </summary>
/// <value>The date created.</value>
diff --git a/MediaBrowser.Model/Sync/SyncJobItem.cs b/MediaBrowser.Model/Sync/SyncJobItem.cs
index 141546eb5a..063f7feb25 100644
--- a/MediaBrowser.Model/Sync/SyncJobItem.cs
+++ b/MediaBrowser.Model/Sync/SyncJobItem.cs
@@ -1,4 +1,5 @@
-
+using System;
+
namespace MediaBrowser.Model.Sync
{
public class SyncJobItem
@@ -37,12 +38,18 @@ namespace MediaBrowser.Model.Sync
/// Gets or sets the status.
/// </summary>
/// <value>The status.</value>
- public SyncJobStatus Status { get; set; }
+ public SyncJobItemStatus Status { get; set; }
/// <summary>
/// Gets or sets the current progress.
/// </summary>
/// <value>The current progress.</value>
- public double? CurrentProgress { get; set; }
+ public double? Progress { get; set; }
+
+ /// <summary>
+ /// Gets or sets the date created.
+ /// </summary>
+ /// <value>The date created.</value>
+ public DateTime DateCreated { get; set; }
}
}
diff --git a/MediaBrowser.Model/Sync/SyncJobItemQuery.cs b/MediaBrowser.Model/Sync/SyncJobItemQuery.cs
new file mode 100644
index 0000000000..e9af642acd
--- /dev/null
+++ b/MediaBrowser.Model/Sync/SyncJobItemQuery.cs
@@ -0,0 +1,27 @@
+
+namespace MediaBrowser.Model.Sync
+{
+ public class SyncJobItemQuery
+ {
+ /// <summary>
+ /// Gets or sets the start index.
+ /// </summary>
+ /// <value>The start index.</value>
+ public int? StartIndex { get; set; }
+ /// <summary>
+ /// Gets or sets the limit.
+ /// </summary>
+ /// <value>The limit.</value>
+ public int? Limit { get; set; }
+ /// <summary>
+ /// Gets or sets the job identifier.
+ /// </summary>
+ /// <value>The job identifier.</value>
+ public string JobId { get; set; }
+ /// <summary>
+ /// Gets or sets a value indicating whether this instance is completed.
+ /// </summary>
+ /// <value><c>null</c> if [is completed] contains no value, <c>true</c> if [is completed]; otherwise, <c>false</c>.</value>
+ public bool? IsCompleted { get; set; }
+ }
+}
diff --git a/MediaBrowser.Model/Sync/SyncJobItemStatus.cs b/MediaBrowser.Model/Sync/SyncJobItemStatus.cs
new file mode 100644
index 0000000000..3d0579a3c0
--- /dev/null
+++ b/MediaBrowser.Model/Sync/SyncJobItemStatus.cs
@@ -0,0 +1,12 @@
+
+namespace MediaBrowser.Model.Sync
+{
+ public enum SyncJobItemStatus
+ {
+ Queued = 0,
+ Converting = 1,
+ Transferring = 2,
+ Completed = 3,
+ Failed = 4
+ }
+}
diff --git a/MediaBrowser.Model/Sync/SyncJobQuery.cs b/MediaBrowser.Model/Sync/SyncJobQuery.cs
index 74b35186e0..218b3823e9 100644
--- a/MediaBrowser.Model/Sync/SyncJobQuery.cs
+++ b/MediaBrowser.Model/Sync/SyncJobQuery.cs
@@ -13,5 +13,10 @@ namespace MediaBrowser.Model.Sync
/// </summary>
/// <value>The limit.</value>
public int? Limit { get; set; }
+ /// <summary>
+ /// Gets or sets a value indicating whether this instance is completed.
+ /// </summary>
+ /// <value><c>null</c> if [is completed] contains no value, <c>true</c> if [is completed]; otherwise, <c>false</c>.</value>
+ public bool? IsCompleted { get; set; }
}
}
diff --git a/MediaBrowser.Model/Sync/SyncJobRequest.cs b/MediaBrowser.Model/Sync/SyncJobRequest.cs
index 987f396e40..4e044d62a2 100644
--- a/MediaBrowser.Model/Sync/SyncJobRequest.cs
+++ b/MediaBrowser.Model/Sync/SyncJobRequest.cs
@@ -35,19 +35,25 @@ namespace MediaBrowser.Model.Sync
/// <value><c>true</c> if [unwatched only]; otherwise, <c>false</c>.</value>
public bool UnwatchedOnly { get; set; }
/// <summary>
- /// Gets or sets the limit.
+ /// Gets or sets a value indicating whether [remove when watched].
/// </summary>
- /// <value>The limit.</value>
- public long? Limit { get; set; }
+ /// <value><c>true</c> if [remove when watched]; otherwise, <c>false</c>.</value>
+ public bool RemoveWhenWatched { get; set; }
+ /// <summary>
+ /// Gets or sets a value indicating whether [synchronize new content].
+ /// </summary>
+ /// <value><c>true</c> if [synchronize new content]; otherwise, <c>false</c>.</value>
+ public bool SyncNewContent { get; set; }
/// <summary>
- /// Gets or sets the type of the limit.
+ /// Gets or sets the limit.
/// </summary>
- /// <value>The type of the limit.</value>
- public SyncLimitType? LimitType { get; set; }
+ /// <value>The limit.</value>
+ public int? ItemLimit { get; set; }
public SyncJobRequest()
{
ItemIds = new List<string>();
+ SyncNewContent = true;
}
}
}
diff --git a/MediaBrowser.Model/Sync/SyncJobStatus.cs b/MediaBrowser.Model/Sync/SyncJobStatus.cs
index ebe375ad80..961ccf5446 100644
--- a/MediaBrowser.Model/Sync/SyncJobStatus.cs
+++ b/MediaBrowser.Model/Sync/SyncJobStatus.cs
@@ -4,10 +4,8 @@ namespace MediaBrowser.Model.Sync
public enum SyncJobStatus
{
Queued = 0,
- Transcoding = 1,
- TranscodingFailed = 2,
- Transferring = 3,
- Completed = 4,
- Cancelled = 5
+ InProgress = 1,
+ Completed = 2,
+ CompletedWithError = 3
}
}
diff --git a/MediaBrowser.Model/Sync/SyncLimitType.cs b/MediaBrowser.Model/Sync/SyncLimitType.cs
deleted file mode 100644
index d20f9e33d1..0000000000
--- a/MediaBrowser.Model/Sync/SyncLimitType.cs
+++ /dev/null
@@ -1,7 +0,0 @@
-namespace MediaBrowser.Model.Sync
-{
- public enum SyncLimitType
- {
- ItemCount = 0
- }
-} \ No newline at end of file
diff --git a/MediaBrowser.Model/Users/UserPolicy.cs b/MediaBrowser.Model/Users/UserPolicy.cs
new file mode 100644
index 0000000000..02d1777472
--- /dev/null
+++ b/MediaBrowser.Model/Users/UserPolicy.cs
@@ -0,0 +1,11 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace MediaBrowser.Model.Users
+{
+ public class UserPolicy
+ {
+ }
+}
diff --git a/MediaBrowser.Providers/BoxSets/BoxSetMetadataService.cs b/MediaBrowser.Providers/BoxSets/BoxSetMetadataService.cs
index 76d5d7dd71..062519f9d5 100644
--- a/MediaBrowser.Providers/BoxSets/BoxSetMetadataService.cs
+++ b/MediaBrowser.Providers/BoxSets/BoxSetMetadataService.cs
@@ -38,12 +38,17 @@ namespace MediaBrowser.Providers.BoxSets
if (mergeMetadataSettings)
{
- var list = source.LinkedChildren.ToList();
+ var list = source.LinkedChildren.Where(i => i.Type != LinkedChildType.Manual).ToList();
- list.AddRange(target.LinkedChildren.Where(i => i.Type == LinkedChildType.Shortcut));
+ list.AddRange(target.LinkedChildren.Where(i => i.Type == LinkedChildType.Manual));
target.LinkedChildren = list;
}
+
+ if (replaceData || target.Shares.Count == 0)
+ {
+ target.Shares = source.Shares;
+ }
}
protected override ItemUpdateType BeforeSave(BoxSet item)
diff --git a/MediaBrowser.Providers/Manager/ProviderManager.cs b/MediaBrowser.Providers/Manager/ProviderManager.cs
index cdf1e788c8..d9982e7863 100644
--- a/MediaBrowser.Providers/Manager/ProviderManager.cs
+++ b/MediaBrowser.Providers/Manager/ProviderManager.cs
@@ -437,7 +437,6 @@ namespace MediaBrowser.Providers.Manager
GetPluginSummary<Game>(),
GetPluginSummary<GameSystem>(),
GetPluginSummary<Movie>(),
- GetPluginSummary<Trailer>(),
GetPluginSummary<BoxSet>(),
GetPluginSummary<Book>(),
GetPluginSummary<Series>(),
diff --git a/MediaBrowser.Providers/MediaBrowser.Providers.csproj b/MediaBrowser.Providers/MediaBrowser.Providers.csproj
index 0757541078..6ac1ab84e6 100644
--- a/MediaBrowser.Providers/MediaBrowser.Providers.csproj
+++ b/MediaBrowser.Providers/MediaBrowser.Providers.csproj
@@ -110,7 +110,6 @@
<Compile Include="MediaInfo\SubtitleScheduledTask.cs" />
<Compile Include="Movies\MovieDbTrailerProvider.cs" />
<Compile Include="Movies\MovieExternalIds.cs" />
- <Compile Include="Movies\TrailerMetadataService.cs" />
<Compile Include="Movies\GenericMovieDbInfo.cs" />
<Compile Include="Movies\MovieDbSearch.cs" />
<Compile Include="Movies\MovieMetadataService.cs" />
diff --git a/MediaBrowser.Providers/MediaInfo/FFProbeProvider.cs b/MediaBrowser.Providers/MediaInfo/FFProbeProvider.cs
index 16c255397f..acca43cf81 100644
--- a/MediaBrowser.Providers/MediaInfo/FFProbeProvider.cs
+++ b/MediaBrowser.Providers/MediaInfo/FFProbeProvider.cs
@@ -31,7 +31,6 @@ namespace MediaBrowser.Providers.MediaInfo
ICustomMetadataProvider<Movie>,
ICustomMetadataProvider<LiveTvVideoRecording>,
ICustomMetadataProvider<LiveTvAudioRecording>,
- ICustomMetadataProvider<Trailer>,
ICustomMetadataProvider<Video>,
ICustomMetadataProvider<Audio>,
IHasItemChangeMonitor,
@@ -77,11 +76,6 @@ namespace MediaBrowser.Providers.MediaInfo
return FetchVideoInfo(item, options, cancellationToken);
}
- public Task<ItemUpdateType> FetchAsync(Trailer item, MetadataRefreshOptions options, CancellationToken cancellationToken)
- {
- return FetchVideoInfo(item, options, cancellationToken);
- }
-
public Task<ItemUpdateType> FetchAsync(Video item, MetadataRefreshOptions options, CancellationToken cancellationToken)
{
return FetchVideoInfo(item, options, cancellationToken);
diff --git a/MediaBrowser.Providers/MediaInfo/FFProbeVideoInfo.cs b/MediaBrowser.Providers/MediaInfo/FFProbeVideoInfo.cs
index 8e6fff38cc..7c078866a8 100644
--- a/MediaBrowser.Providers/MediaInfo/FFProbeVideoInfo.cs
+++ b/MediaBrowser.Providers/MediaInfo/FFProbeVideoInfo.cs
@@ -757,13 +757,14 @@ namespace MediaBrowser.Providers.MediaInfo
/// <returns>System.Nullable{IsoType}.</returns>
private IsoType? DetermineIsoType(IIsoMount isoMount)
{
- var folders = Directory.EnumerateDirectories(isoMount.MountedPath).Select(Path.GetFileName).ToList();
+ var fileSystemEntries = Directory.EnumerateFileSystemEntries(isoMount.MountedPath).Select(Path.GetFileName).ToList();
- if (folders.Contains("video_ts", StringComparer.OrdinalIgnoreCase))
+ if (fileSystemEntries.Contains("video_ts", StringComparer.OrdinalIgnoreCase) ||
+ fileSystemEntries.Contains("VIDEO_TS.IFO", StringComparer.OrdinalIgnoreCase))
{
return IsoType.Dvd;
}
- if (folders.Contains("bdmv", StringComparer.OrdinalIgnoreCase))
+ if (fileSystemEntries.Contains("bdmv", StringComparer.OrdinalIgnoreCase))
{
return IsoType.BluRay;
}
diff --git a/MediaBrowser.Providers/MediaInfo/VideoImageProvider.cs b/MediaBrowser.Providers/MediaInfo/VideoImageProvider.cs
index 78a294e5f0..a91a01edca 100644
--- a/MediaBrowser.Providers/MediaInfo/VideoImageProvider.cs
+++ b/MediaBrowser.Providers/MediaInfo/VideoImageProvider.cs
@@ -1,8 +1,8 @@
using MediaBrowser.Controller.Configuration;
-using MediaBrowser.Controller.Drawing;
using MediaBrowser.Controller.Entities;
using MediaBrowser.Controller.MediaEncoding;
using MediaBrowser.Controller.Providers;
+using MediaBrowser.Model.Drawing;
using MediaBrowser.Model.Entities;
using MediaBrowser.Model.IO;
using MediaBrowser.Model.MediaInfo;
diff --git a/MediaBrowser.Providers/Movies/FanartMovieImageProvider.cs b/MediaBrowser.Providers/Movies/FanartMovieImageProvider.cs
index 8399c6f849..a7ccf3f6ec 100644
--- a/MediaBrowser.Providers/Movies/FanartMovieImageProvider.cs
+++ b/MediaBrowser.Providers/Movies/FanartMovieImageProvider.cs
@@ -57,13 +57,6 @@ namespace MediaBrowser.Providers.Movies
public bool Supports(IHasImages item)
{
- var trailer = item as Trailer;
-
- if (trailer != null)
- {
- return !trailer.IsLocalTrailer;
- }
-
return item is Movie || item is BoxSet || item is MusicVideo;
}
diff --git a/MediaBrowser.Providers/Movies/MovieDbImageProvider.cs b/MediaBrowser.Providers/Movies/MovieDbImageProvider.cs
index 129e418226..f5d5a6fb1d 100644
--- a/MediaBrowser.Providers/Movies/MovieDbImageProvider.cs
+++ b/MediaBrowser.Providers/Movies/MovieDbImageProvider.cs
@@ -40,13 +40,6 @@ namespace MediaBrowser.Providers.Movies
public bool Supports(IHasImages item)
{
- var trailer = item as Trailer;
-
- if (trailer != null)
- {
- return !trailer.IsLocalTrailer;
- }
-
var channelItem = item as ChannelVideoItem;
if (channelItem != null && channelItem.ContentType == ChannelMediaContentType.MovieExtra && channelItem.ExtraType == ExtraType.Trailer)
diff --git a/MediaBrowser.Providers/Movies/MovieDbTrailerProvider.cs b/MediaBrowser.Providers/Movies/MovieDbTrailerProvider.cs
index b3bb200c60..2bb452df77 100644
--- a/MediaBrowser.Providers/Movies/MovieDbTrailerProvider.cs
+++ b/MediaBrowser.Providers/Movies/MovieDbTrailerProvider.cs
@@ -12,7 +12,7 @@ using System.Threading.Tasks;
namespace MediaBrowser.Providers.Movies
{
- public class MovieDbTrailerProvider : IRemoteMetadataProvider<Trailer, TrailerInfo>, IHasOrder, IRemoteMetadataProvider<ChannelVideoItem, ChannelItemLookupInfo>
+ public class MovieDbTrailerProvider : IHasOrder, IRemoteMetadataProvider<ChannelVideoItem, ChannelItemLookupInfo>
{
private readonly IHttpClient _httpClient;
@@ -21,11 +21,6 @@ namespace MediaBrowser.Providers.Movies
_httpClient = httpClient;
}
- public Task<MetadataResult<Trailer>> GetMetadata(TrailerInfo info, CancellationToken cancellationToken)
- {
- return MovieDbProvider.Current.GetItemMetadata<Trailer>(info, cancellationToken);
- }
-
public Task<IEnumerable<RemoteSearchResult>> GetSearchResults(TrailerInfo searchInfo, CancellationToken cancellationToken)
{
return MovieDbProvider.Current.GetMovieSearchResults(searchInfo, cancellationToken);
diff --git a/MediaBrowser.Providers/Movies/MovieExternalIds.cs b/MediaBrowser.Providers/Movies/MovieExternalIds.cs
index f993069e2a..9c09d9d00c 100644
--- a/MediaBrowser.Providers/Movies/MovieExternalIds.cs
+++ b/MediaBrowser.Providers/Movies/MovieExternalIds.cs
@@ -34,7 +34,7 @@ namespace MediaBrowser.Providers.Movies
return true;
}
- return item is Movie || item is Trailer || item is MusicVideo;
+ return item is Movie || item is MusicVideo;
}
}
@@ -80,7 +80,7 @@ namespace MediaBrowser.Providers.Movies
public bool Supports(IHasProviderIds item)
{
- return item is Movie || item is Trailer || item is MusicVideo;
+ return item is Movie || item is MusicVideo;
}
}
@@ -156,7 +156,7 @@ namespace MediaBrowser.Providers.Movies
return true;
}
- return item is Movie || item is Trailer || item is MusicVideo || item is Series || item is Episode;
+ return item is Movie || item is MusicVideo || item is Series || item is Episode;
}
}
diff --git a/MediaBrowser.Providers/Movies/MovieUpdatesPrescanTask.cs b/MediaBrowser.Providers/Movies/MovieUpdatesPrescanTask.cs
index 2225b5fb80..d03573a965 100644
--- a/MediaBrowser.Providers/Movies/MovieUpdatesPrescanTask.cs
+++ b/MediaBrowser.Providers/Movies/MovieUpdatesPrescanTask.cs
@@ -178,7 +178,7 @@ namespace MediaBrowser.Providers.Movies
// Gather all movies into a lookup by tmdb id
var allMovies = _libraryManager.RootFolder.RecursiveChildren
- .Where(i => i is Movie || i is Trailer)
+ .Where(i => i is Movie)
.Where(i => !string.IsNullOrEmpty(i.GetProviderId(MetadataProviders.Tmdb)))
.ToLookup(i => i.GetProviderId(MetadataProviders.Tmdb));
diff --git a/MediaBrowser.Providers/Movies/TrailerMetadataService.cs b/MediaBrowser.Providers/Movies/TrailerMetadataService.cs
deleted file mode 100644
index 07abac67ce..0000000000
--- a/MediaBrowser.Providers/Movies/TrailerMetadataService.cs
+++ /dev/null
@@ -1,34 +0,0 @@
-using MediaBrowser.Common.IO;
-using MediaBrowser.Controller.Configuration;
-using MediaBrowser.Controller.Entities;
-using MediaBrowser.Controller.Library;
-using MediaBrowser.Controller.Providers;
-using MediaBrowser.Model.Entities;
-using MediaBrowser.Model.Logging;
-using MediaBrowser.Providers.Manager;
-using System.Collections.Generic;
-using System.Threading;
-using System.Threading.Tasks;
-
-namespace MediaBrowser.Providers.Movies
-{
- public class TrailerMetadataService : MetadataService<Trailer, TrailerInfo>
- {
- public TrailerMetadataService(IServerConfigurationManager serverConfigurationManager, ILogger logger, IProviderManager providerManager, IProviderRepository providerRepo, IFileSystem fileSystem, IUserDataManager userDataManager) : base(serverConfigurationManager, logger, providerManager, providerRepo, fileSystem, userDataManager)
- {
- }
-
- /// <summary>
- /// Merges the specified source.
- /// </summary>
- /// <param name="source">The source.</param>
- /// <param name="target">The target.</param>
- /// <param name="lockedFields">The locked fields.</param>
- /// <param name="replaceData">if set to <c>true</c> [replace data].</param>
- /// <param name="mergeMetadataSettings">if set to <c>true</c> [merge metadata settings].</param>
- protected override void MergeData(Trailer source, Trailer target, List<MetadataFields> lockedFields, bool replaceData, bool mergeMetadataSettings)
- {
- ProviderUtils.MergeBaseItemData(source, target, lockedFields, replaceData, mergeMetadataSettings);
- }
- }
-}
diff --git a/MediaBrowser.Providers/Omdb/OmdbImageProvider.cs b/MediaBrowser.Providers/Omdb/OmdbImageProvider.cs
index 887240ed4d..758d0a6bd9 100644
--- a/MediaBrowser.Providers/Omdb/OmdbImageProvider.cs
+++ b/MediaBrowser.Providers/Omdb/OmdbImageProvider.cs
@@ -108,7 +108,7 @@ namespace MediaBrowser.Providers.Omdb
}
}
- return item is Movie || item is Trailer;
+ return item is Movie;
}
public int Order
diff --git a/MediaBrowser.Providers/Omdb/OmdbItemProvider.cs b/MediaBrowser.Providers/Omdb/OmdbItemProvider.cs
index a3badd1dfc..1494eaee85 100644
--- a/MediaBrowser.Providers/Omdb/OmdbItemProvider.cs
+++ b/MediaBrowser.Providers/Omdb/OmdbItemProvider.cs
@@ -20,7 +20,7 @@ using System.Threading.Tasks;
namespace MediaBrowser.Providers.Omdb
{
public class OmdbItemProvider : IRemoteMetadataProvider<Series, SeriesInfo>,
- IRemoteMetadataProvider<Movie, MovieInfo>, IRemoteMetadataProvider<Trailer, TrailerInfo>, IRemoteMetadataProvider<ChannelVideoItem, ChannelItemLookupInfo>
+ IRemoteMetadataProvider<Movie, MovieInfo>, IRemoteMetadataProvider<ChannelVideoItem, ChannelItemLookupInfo>
{
private readonly IJsonSerializer _jsonSerializer;
private readonly IHttpClient _httpClient;
@@ -114,18 +114,6 @@ namespace MediaBrowser.Providers.Omdb
return GetMovieResult<Movie>(info, cancellationToken);
}
- public Task<MetadataResult<Trailer>> GetMetadata(TrailerInfo info, CancellationToken cancellationToken)
- {
- var result = new MetadataResult<Trailer>();
-
- if (info.IsLocalTrailer)
- {
- return Task.FromResult(result);
- }
-
- return GetMovieResult<Trailer>(info, cancellationToken);
- }
-
private async Task<MetadataResult<T>> GetMovieResult<T>(ItemLookupInfo info, CancellationToken cancellationToken)
where T : Video, new()
{
diff --git a/MediaBrowser.Providers/Playlists/PlaylistMetadataService.cs b/MediaBrowser.Providers/Playlists/PlaylistMetadataService.cs
index 4101827ccf..2e407f10ca 100644
--- a/MediaBrowser.Providers/Playlists/PlaylistMetadataService.cs
+++ b/MediaBrowser.Providers/Playlists/PlaylistMetadataService.cs
@@ -1,7 +1,5 @@
-using System.Linq;
-using MediaBrowser.Common.IO;
+using MediaBrowser.Common.IO;
using MediaBrowser.Controller.Configuration;
-using MediaBrowser.Controller.Entities;
using MediaBrowser.Controller.Library;
using MediaBrowser.Controller.Playlists;
using MediaBrowser.Controller.Providers;
@@ -35,18 +33,14 @@ namespace MediaBrowser.Providers.Playlists
target.PlaylistMediaType = source.PlaylistMediaType;
}
- if (replaceData || string.IsNullOrEmpty(target.OwnerUserId))
+ if (replaceData || target.Shares.Count == 0)
{
- target.OwnerUserId = source.OwnerUserId;
+ target.Shares = source.Shares;
}
if (mergeMetadataSettings)
{
- var list = source.LinkedChildren.ToList();
-
- list.AddRange(target.LinkedChildren);
-
- target.LinkedChildren = list;
+ target.LinkedChildren = source.LinkedChildren;
}
}
}
diff --git a/MediaBrowser.Server.Implementations/Channels/ChannelManager.cs b/MediaBrowser.Server.Implementations/Channels/ChannelManager.cs
index b777e8a9c5..382d0077a7 100644
--- a/MediaBrowser.Server.Implementations/Channels/ChannelManager.cs
+++ b/MediaBrowser.Server.Implementations/Channels/ChannelManager.cs
@@ -533,6 +533,12 @@ namespace MediaBrowser.Server.Implementations.Channels
? null
: _userManager.GetUserById(query.UserId);
+ // See below about parental control
+ if (user != null)
+ {
+ query.StartIndex = null;
+ }
+
var internalResult = await GetLatestChannelItemsInternal(query, cancellationToken).ConfigureAwait(false);
// Get everything
@@ -540,13 +546,27 @@ namespace MediaBrowser.Server.Implementations.Channels
.Select(i => (ItemFields)Enum.Parse(typeof(ItemFields), i, true))
.ToList();
- var returnItems = internalResult.Items.Select(i => _dtoService.GetBaseItemDto(i, fields, user))
+ var items = internalResult.Items;
+ var totalRecordCount = internalResult.TotalRecordCount;
+
+ // Supporting parental control is a hack because it has to be done after querying the remote data source
+ // This will get screwy if apps try to page, so limit to 10 results in an attempt to always keep them on the first page
+ if (user != null)
+ {
+ items = items.Where(i => i.IsVisible(user))
+ .Take(10)
+ .ToArray();
+
+ totalRecordCount = items.Length;
+ }
+
+ var returnItems = items.Select(i => _dtoService.GetBaseItemDto(i, fields, user))
.ToArray();
var result = new QueryResult<BaseItemDto>
{
Items = returnItems,
- TotalRecordCount = internalResult.TotalRecordCount
+ TotalRecordCount = totalRecordCount
};
return result;
diff --git a/MediaBrowser.Server.Implementations/Collections/CollectionManager.cs b/MediaBrowser.Server.Implementations/Collections/CollectionManager.cs
index e346d6d01b..9fee27db9b 100644
--- a/MediaBrowser.Server.Implementations/Collections/CollectionManager.cs
+++ b/MediaBrowser.Server.Implementations/Collections/CollectionManager.cs
@@ -72,7 +72,12 @@ namespace MediaBrowser.Server.Implementations.Collections
DisplayMediaType = "Collection",
Path = path,
IsLocked = options.IsLocked,
- ProviderIds = options.ProviderIds
+ ProviderIds = options.ProviderIds,
+ Shares = options.UserIds.Select(i => new Share
+ {
+ UserId = i.ToString("N")
+
+ }).ToList()
};
await parentFolder.AddChild(collection, CancellationToken.None).ConfigureAwait(false);
@@ -156,7 +161,7 @@ namespace MediaBrowser.Server.Implementations.Collections
}
itemList.Add(item);
-
+
if (currentLinkedChildren.Any(i => i.Id == itemId))
{
throw new ArgumentException("Item already exists in collection");
diff --git a/MediaBrowser.Server.Implementations/Connect/ConnectManager.cs b/MediaBrowser.Server.Implementations/Connect/ConnectManager.cs
index cff49df10f..cbd75cdeb7 100644
--- a/MediaBrowser.Server.Implementations/Connect/ConnectManager.cs
+++ b/MediaBrowser.Server.Implementations/Connect/ConnectManager.cs
@@ -88,6 +88,11 @@ namespace MediaBrowser.Server.Implementations.Connect
}
}
+ private string XApplicationValue
+ {
+ get { return "Media Browser Server/" + _appHost.ApplicationVersion; }
+ }
+
public ConnectManager(ILogger logger,
IApplicationPaths appPaths,
IJsonSerializer json,
@@ -204,9 +209,18 @@ namespace MediaBrowser.Server.Implementations.Connect
postData["localAddress"] = localAddress;
}
- using (var stream = await _httpClient.Post(url, postData, CancellationToken.None).ConfigureAwait(false))
+ var options = new HttpRequestOptions
+ {
+ Url = url,
+ CancellationToken = CancellationToken.None
+ };
+
+ options.SetPostData(postData);
+ SetApplicationHeader(options);
+
+ using (var response = await _httpClient.Post(options).ConfigureAwait(false))
{
- var data = _json.DeserializeFromStream<ServerRegistrationResponse>(stream);
+ var data = _json.DeserializeFromStream<ServerRegistrationResponse>(response.Content);
_data.ServerId = data.Id;
_data.AccessKey = data.AccessKey;
@@ -252,6 +266,7 @@ namespace MediaBrowser.Server.Implementations.Connect
options.SetPostData(postData);
SetServerAccessToken(options);
+ SetApplicationHeader(options);
// No need to examine the response
using (var stream = (await _httpClient.Post(options).ConfigureAwait(false)).Content)
@@ -398,6 +413,7 @@ namespace MediaBrowser.Server.Implementations.Connect
options.SetPostData(postData);
SetServerAccessToken(options);
+ SetApplicationHeader(options);
var result = new UserLinkResult();
@@ -517,6 +533,7 @@ namespace MediaBrowser.Server.Implementations.Connect
options.SetPostData(postData);
SetServerAccessToken(options);
+ SetApplicationHeader(options);
// No need to examine the response
using (var stream = (await _httpClient.Post(options).ConfigureAwait(false)).Content)
@@ -562,6 +579,7 @@ namespace MediaBrowser.Server.Implementations.Connect
};
options.SetPostData(postData);
+ SetApplicationHeader(options);
// No need to examine the response
using (var stream = (await _httpClient.Post(options).ConfigureAwait(false)).Content)
@@ -629,6 +647,7 @@ namespace MediaBrowser.Server.Implementations.Connect
};
SetServerAccessToken(options);
+ SetApplicationHeader(options);
using (var stream = await _httpClient.Get(options).ConfigureAwait(false))
{
@@ -645,6 +664,11 @@ namespace MediaBrowser.Server.Implementations.Connect
}
}
+ private void SetApplicationHeader(HttpRequestOptions options)
+ {
+ options.RequestHeaders.Add("X-Application", XApplicationValue);
+ }
+
private void SetServerAccessToken(HttpRequestOptions options)
{
if (string.IsNullOrWhiteSpace(ConnectAccessKey))
@@ -687,6 +711,7 @@ namespace MediaBrowser.Server.Implementations.Connect
};
SetServerAccessToken(options);
+ SetApplicationHeader(options);
try
{
@@ -974,6 +999,7 @@ namespace MediaBrowser.Server.Implementations.Connect
options.SetPostData(postData);
SetServerAccessToken(options);
+ SetApplicationHeader(options);
try
{
@@ -1006,20 +1032,22 @@ namespace MediaBrowser.Server.Implementations.Connect
{
throw new ArgumentNullException("passwordMd5");
}
-
- var request = new HttpRequestOptions
+
+ var options = new HttpRequestOptions
{
Url = GetConnectUrl("user/authenticate")
};
- request.SetPostData(new Dictionary<string, string>
+ options.SetPostData(new Dictionary<string, string>
{
{"userName",username},
{"password",passwordMd5}
});
+ SetApplicationHeader(options);
+
// No need to examine the response
- using (var stream = (await _httpClient.SendAsync(request, "POST").ConfigureAwait(false)).Content)
+ using (var response = (await _httpClient.SendAsync(options, "POST").ConfigureAwait(false)).Content)
{
}
}
@@ -1062,6 +1090,7 @@ namespace MediaBrowser.Server.Implementations.Connect
options.SetPostData(postData);
SetServerAccessToken(options);
+ SetApplicationHeader(options);
try
{
diff --git a/MediaBrowser.Server.Implementations/Devices/DeviceManager.cs b/MediaBrowser.Server.Implementations/Devices/DeviceManager.cs
index e2c729b2d9..8c67013ea3 100644
--- a/MediaBrowser.Server.Implementations/Devices/DeviceManager.cs
+++ b/MediaBrowser.Server.Implementations/Devices/DeviceManager.cs
@@ -6,6 +6,7 @@ using MediaBrowser.Controller.Library;
using MediaBrowser.Model.Devices;
using MediaBrowser.Model.Events;
using MediaBrowser.Model.Logging;
+using MediaBrowser.Model.Querying;
using MediaBrowser.Model.Session;
using System;
using System.Collections.Generic;
@@ -28,7 +29,7 @@ namespace MediaBrowser.Server.Implementations.Devices
/// Occurs when [device options updated].
/// </summary>
public event EventHandler<GenericEventArgs<DeviceInfo>> DeviceOptionsUpdated;
-
+
public DeviceManager(IDeviceRepository repo, IUserManager userManager, IFileSystem fileSystem, ILibraryMonitor libraryMonitor, IConfigurationManager config, ILogger logger)
{
_repo = repo;
@@ -79,9 +80,30 @@ namespace MediaBrowser.Server.Implementations.Devices
return _repo.GetDevice(id);
}
- public IEnumerable<DeviceInfo> GetDevices()
+ public QueryResult<DeviceInfo> GetDevices(DeviceQuery query)
{
- return _repo.GetDevices().OrderByDescending(i => i.DateLastModified);
+ IEnumerable<DeviceInfo> devices = _repo.GetDevices().OrderByDescending(i => i.DateLastModified);
+
+ if (query.SupportsContentUploading.HasValue)
+ {
+ var val = query.SupportsContentUploading.Value;
+
+ devices = devices.Where(i => GetCapabilities(i.Id).SupportsContentUploading == val);
+ }
+
+ if (query.SupportsUniqueIdentifier.HasValue)
+ {
+ var val = query.SupportsUniqueIdentifier.Value;
+
+ devices = devices.Where(i => GetCapabilities(i.Id).SupportsUniqueIdentifier == val);
+ }
+
+ var array = devices.ToArray();
+ return new QueryResult<DeviceInfo>
+ {
+ Items = array,
+ TotalRecordCount = array.Length
+ };
}
public Task DeleteDevice(string id)
diff --git a/MediaBrowser.Controller/Drawing/ImageExtensions.cs b/MediaBrowser.Server.Implementations/Drawing/ImageExtensions.cs
index 2511659c3f..28ea26a322 100644
--- a/MediaBrowser.Controller/Drawing/ImageExtensions.cs
+++ b/MediaBrowser.Server.Implementations/Drawing/ImageExtensions.cs
@@ -4,7 +4,7 @@ using System.Drawing.Drawing2D;
using System.Drawing.Imaging;
using System.IO;
-namespace MediaBrowser.Controller.Drawing
+namespace MediaBrowser.Server.Implementations.Drawing
{
/// <summary>
/// Class ImageExtensions
@@ -18,17 +18,17 @@ namespace MediaBrowser.Controller.Drawing
/// <param name="image">The image.</param>
/// <param name="toStream">To stream.</param>
/// <param name="quality">The quality.</param>
- public static void Save(this Image image, System.Drawing.Imaging.ImageFormat outputFormat, Stream toStream, int quality)
+ public static void Save(this Image image, ImageFormat outputFormat, Stream toStream, int quality)
{
// Use special save methods for jpeg and png that will result in a much higher quality image
// All other formats use the generic Image.Save
- if (System.Drawing.Imaging.ImageFormat.Jpeg.Equals(outputFormat))
+ if (ImageFormat.Jpeg.Equals(outputFormat))
{
SaveAsJpeg(image, toStream, quality);
}
- else if (System.Drawing.Imaging.ImageFormat.Png.Equals(outputFormat))
+ else if (ImageFormat.Png.Equals(outputFormat))
{
- image.Save(toStream, System.Drawing.Imaging.ImageFormat.Png);
+ image.Save(toStream, ImageFormat.Png);
}
else
{
diff --git a/MediaBrowser.Server.Implementations/Drawing/ImageHeader.cs b/MediaBrowser.Server.Implementations/Drawing/ImageHeader.cs
index 3d53d2b86f..e9c67bf48a 100644
--- a/MediaBrowser.Server.Implementations/Drawing/ImageHeader.cs
+++ b/MediaBrowser.Server.Implementations/Drawing/ImageHeader.cs
@@ -1,8 +1,8 @@
using MediaBrowser.Common.IO;
+using MediaBrowser.Model.Drawing;
using MediaBrowser.Model.Logging;
using System;
using System.Collections.Generic;
-using System.Drawing;
using System.IO;
using System.Linq;
@@ -24,7 +24,7 @@ namespace MediaBrowser.Server.Implementations.Drawing
/// <summary>
/// The image format decoders
/// </summary>
- private static readonly KeyValuePair<byte[], Func<BinaryReader, Size>>[] ImageFormatDecoders = new Dictionary<byte[], Func<BinaryReader, Size>>
+ private static readonly KeyValuePair<byte[], Func<BinaryReader, ImageSize>>[] ImageFormatDecoders = new Dictionary<byte[], Func<BinaryReader, ImageSize>>
{
{ new byte[] { 0x42, 0x4D }, DecodeBitmap },
{ new byte[] { 0x47, 0x49, 0x46, 0x38, 0x37, 0x61 }, DecodeGif },
@@ -44,7 +44,7 @@ namespace MediaBrowser.Server.Implementations.Drawing
/// <param name="fileSystem">The file system.</param>
/// <returns>The dimensions of the specified image.</returns>
/// <exception cref="ArgumentException">The image was of an unrecognised format.</exception>
- public static Size GetDimensions(string path, ILogger logger, IFileSystem fileSystem)
+ public static ImageSize GetDimensions(string path, ILogger logger, IFileSystem fileSystem)
{
try
{
@@ -71,9 +71,15 @@ namespace MediaBrowser.Server.Implementations.Drawing
memoryStream.Position = 0;
// Co it the old fashioned way
- using (var b = Image.FromStream(memoryStream, true, false))
+ using (var b = System.Drawing.Image.FromStream(memoryStream, true, false))
{
- return b.Size;
+ var size = b.Size;
+
+ return new ImageSize
+ {
+ Width = size.Width,
+ Height = size.Height
+ };
}
}
}
@@ -86,7 +92,7 @@ namespace MediaBrowser.Server.Implementations.Drawing
/// <returns>Size.</returns>
/// <exception cref="System.ArgumentException">binaryReader</exception>
/// <exception cref="ArgumentException">The image was of an unrecognized format.</exception>
- private static Size GetDimensions(BinaryReader binaryReader)
+ private static ImageSize GetDimensions(BinaryReader binaryReader)
{
var magicBytes = new byte[MaxMagicBytesLength];
@@ -161,12 +167,16 @@ namespace MediaBrowser.Server.Implementations.Drawing
/// </summary>
/// <param name="binaryReader">The binary reader.</param>
/// <returns>Size.</returns>
- private static Size DecodeBitmap(BinaryReader binaryReader)
+ private static ImageSize DecodeBitmap(BinaryReader binaryReader)
{
binaryReader.ReadBytes(16);
int width = binaryReader.ReadInt32();
int height = binaryReader.ReadInt32();
- return new Size(width, height);
+ return new ImageSize
+ {
+ Width = width,
+ Height = height
+ };
}
/// <summary>
@@ -174,11 +184,15 @@ namespace MediaBrowser.Server.Implementations.Drawing
/// </summary>
/// <param name="binaryReader">The binary reader.</param>
/// <returns>Size.</returns>
- private static Size DecodeGif(BinaryReader binaryReader)
+ private static ImageSize DecodeGif(BinaryReader binaryReader)
{
int width = binaryReader.ReadInt16();
int height = binaryReader.ReadInt16();
- return new Size(width, height);
+ return new ImageSize
+ {
+ Width = width,
+ Height = height
+ };
}
/// <summary>
@@ -186,12 +200,16 @@ namespace MediaBrowser.Server.Implementations.Drawing
/// </summary>
/// <param name="binaryReader">The binary reader.</param>
/// <returns>Size.</returns>
- private static Size DecodePng(BinaryReader binaryReader)
+ private static ImageSize DecodePng(BinaryReader binaryReader)
{
binaryReader.ReadBytes(8);
int width = ReadLittleEndianInt32(binaryReader);
int height = ReadLittleEndianInt32(binaryReader);
- return new Size(width, height);
+ return new ImageSize
+ {
+ Width = width,
+ Height = height
+ };
}
/// <summary>
@@ -200,7 +218,7 @@ namespace MediaBrowser.Server.Implementations.Drawing
/// <param name="binaryReader">The binary reader.</param>
/// <returns>Size.</returns>
/// <exception cref="System.ArgumentException"></exception>
- private static Size DecodeJfif(BinaryReader binaryReader)
+ private static ImageSize DecodeJfif(BinaryReader binaryReader)
{
while (binaryReader.ReadByte() == 0xff)
{
@@ -211,7 +229,11 @@ namespace MediaBrowser.Server.Implementations.Drawing
binaryReader.ReadByte();
int height = ReadLittleEndianInt16(binaryReader);
int width = ReadLittleEndianInt16(binaryReader);
- return new Size(width, height);
+ return new ImageSize
+ {
+ Width = width,
+ Height = height
+ };
}
if (chunkLength < 0)
diff --git a/MediaBrowser.Server.Implementations/Drawing/ImageProcessor.cs b/MediaBrowser.Server.Implementations/Drawing/ImageProcessor.cs
index feda361c82..b141fea1ed 100644
--- a/MediaBrowser.Server.Implementations/Drawing/ImageProcessor.cs
+++ b/MediaBrowser.Server.Implementations/Drawing/ImageProcessor.cs
@@ -129,13 +129,13 @@ namespace MediaBrowser.Server.Implementations.Drawing
}
}
- public ImageOutputFormat[] GetSupportedImageOutputFormats()
+ public Model.Drawing.ImageFormat[] GetSupportedImageOutputFormats()
{
if (_webpAvailable)
{
- return new[] { ImageOutputFormat.Webp, ImageOutputFormat.Gif, ImageOutputFormat.Jpg, ImageOutputFormat.Png };
+ return new[] { Model.Drawing.ImageFormat.Webp, Model.Drawing.ImageFormat.Gif, Model.Drawing.ImageFormat.Jpg, Model.Drawing.ImageFormat.Png };
}
- return new[] { ImageOutputFormat.Gif, ImageOutputFormat.Jpg, ImageOutputFormat.Png };
+ return new[] { Model.Drawing.ImageFormat.Gif, Model.Drawing.ImageFormat.Jpg, Model.Drawing.ImageFormat.Png };
}
public async Task<string> ProcessImage(ImageProcessingOptions options)
@@ -227,7 +227,7 @@ namespace MediaBrowser.Server.Implementations.Drawing
// Graphics.FromImage will throw an exception if the PixelFormat is Indexed, so we need to handle that here
// Also, Webp only supports Format32bppArgb and Format32bppRgb
- var pixelFormat = selectedOutputFormat == ImageOutputFormat.Webp
+ var pixelFormat = selectedOutputFormat == Model.Drawing.ImageFormat.Webp
? PixelFormat.Format32bppArgb
: PixelFormat.Format32bppPArgb;
@@ -263,7 +263,7 @@ namespace MediaBrowser.Server.Implementations.Drawing
// Save to the cache location
using (var cacheFileStream = _fileSystem.GetFileStream(cacheFilePath, FileMode.Create, FileAccess.Write, FileShare.Read, false))
{
- if (selectedOutputFormat == ImageOutputFormat.Webp)
+ if (selectedOutputFormat == Model.Drawing.ImageFormat.Webp)
{
SaveToWebP(thumbnail, cacheFileStream, quality);
}
@@ -381,17 +381,17 @@ namespace MediaBrowser.Server.Implementations.Drawing
/// <param name="image">The image.</param>
/// <param name="outputFormat">The output format.</param>
/// <returns>ImageFormat.</returns>
- private System.Drawing.Imaging.ImageFormat GetOutputFormat(Image image, ImageOutputFormat outputFormat)
+ private System.Drawing.Imaging.ImageFormat GetOutputFormat(Image image, Model.Drawing.ImageFormat outputFormat)
{
switch (outputFormat)
{
- case ImageOutputFormat.Bmp:
+ case Model.Drawing.ImageFormat.Bmp:
return System.Drawing.Imaging.ImageFormat.Bmp;
- case ImageOutputFormat.Gif:
+ case Model.Drawing.ImageFormat.Gif:
return System.Drawing.Imaging.ImageFormat.Gif;
- case ImageOutputFormat.Jpg:
+ case Model.Drawing.ImageFormat.Jpg:
return System.Drawing.Imaging.ImageFormat.Jpeg;
- case ImageOutputFormat.Png:
+ case Model.Drawing.ImageFormat.Png:
return System.Drawing.Imaging.ImageFormat.Png;
default:
return image.RawFormat;
@@ -471,7 +471,7 @@ namespace MediaBrowser.Server.Implementations.Drawing
/// <summary>
/// Gets the cache file path based on a set of parameters
/// </summary>
- private string GetCacheFilePath(string originalPath, ImageSize outputSize, int quality, DateTime dateModified, ImageOutputFormat format, bool addPlayedIndicator, double percentPlayed, int? unwatchedCount, string backgroundColor)
+ private string GetCacheFilePath(string originalPath, ImageSize outputSize, int quality, DateTime dateModified, Model.Drawing.ImageFormat format, bool addPlayedIndicator, double percentPlayed, int? unwatchedCount, string backgroundColor)
{
var filename = originalPath;
@@ -515,7 +515,7 @@ namespace MediaBrowser.Server.Implementations.Drawing
filename += "b=" + backgroundColor;
}
- return GetCachePath(ResizedImageCachePath, filename, Path.GetExtension(originalPath));
+ return GetCachePath(ResizedImageCachePath, filename, "." + format.ToString().ToLower());
}
/// <summary>
@@ -772,19 +772,39 @@ namespace MediaBrowser.Server.Implementations.Drawing
{
await fileStream.CopyToAsync(memoryStream).ConfigureAwait(false);
- using (var originalImage = Image.FromStream(memoryStream, true, false))
+ memoryStream.Position = 0;
+
+ var imageStream = new ImageStream
{
- //Pass the image through registered enhancers
- using (var newImage = await ExecuteImageEnhancers(supportedEnhancers, originalImage, item, imageType, imageIndex).ConfigureAwait(false))
- {
- var parentDirectory = Path.GetDirectoryName(enhancedImagePath);
+ Stream = memoryStream,
+ Format = GetFormat(originalImagePath)
+ };
+
+ //Pass the image through registered enhancers
+ using (var newImageStream = await ExecuteImageEnhancers(supportedEnhancers, imageStream, item, imageType, imageIndex).ConfigureAwait(false))
+ {
+ var parentDirectory = Path.GetDirectoryName(enhancedImagePath);
- Directory.CreateDirectory(parentDirectory);
+ Directory.CreateDirectory(parentDirectory);
+ // Save as png
+ if (newImageStream.Format == Model.Drawing.ImageFormat.Png)
+ {
//And then save it in the cache
using (var outputStream = _fileSystem.GetFileStream(enhancedImagePath, FileMode.Create, FileAccess.Write, FileShare.Read, false))
{
- newImage.Save(System.Drawing.Imaging.ImageFormat.Png, outputStream, 100);
+ await newImageStream.Stream.CopyToAsync(outputStream).ConfigureAwait(false);
+ }
+ }
+ else
+ {
+ using (var newImage = Image.FromStream(newImageStream.Stream, true, false))
+ {
+ //And then save it in the cache
+ using (var outputStream = _fileSystem.GetFileStream(enhancedImagePath, FileMode.Create, FileAccess.Write, FileShare.Read, false))
+ {
+ newImage.Save(System.Drawing.Imaging.ImageFormat.Png, outputStream, 100);
+ }
}
}
}
@@ -799,6 +819,30 @@ namespace MediaBrowser.Server.Implementations.Drawing
return enhancedImagePath;
}
+ private Model.Drawing.ImageFormat GetFormat(string path)
+ {
+ var extension = Path.GetExtension(path);
+
+ if (string.Equals(extension, ".png", StringComparison.OrdinalIgnoreCase))
+ {
+ return Model.Drawing.ImageFormat.Png;
+ }
+ if (string.Equals(extension, ".gif", StringComparison.OrdinalIgnoreCase))
+ {
+ return Model.Drawing.ImageFormat.Gif;
+ }
+ if (string.Equals(extension, ".webp", StringComparison.OrdinalIgnoreCase))
+ {
+ return Model.Drawing.ImageFormat.Webp;
+ }
+ if (string.Equals(extension, ".bmp", StringComparison.OrdinalIgnoreCase))
+ {
+ return Model.Drawing.ImageFormat.Bmp;
+ }
+
+ return Model.Drawing.ImageFormat.Jpg;
+ }
+
/// <summary>
/// Executes the image enhancers.
/// </summary>
@@ -808,7 +852,7 @@ namespace MediaBrowser.Server.Implementations.Drawing
/// <param name="imageType">Type of the image.</param>
/// <param name="imageIndex">Index of the image.</param>
/// <returns>Task{EnhancedImage}.</returns>
- private async Task<Image> ExecuteImageEnhancers(IEnumerable<IImageEnhancer> imageEnhancers, Image originalImage, IHasImages item, ImageType imageType, int imageIndex)
+ private async Task<ImageStream> ExecuteImageEnhancers(IEnumerable<IImageEnhancer> imageEnhancers, ImageStream originalImage, IHasImages item, ImageType imageType, int imageIndex)
{
var result = originalImage;
@@ -835,21 +879,6 @@ namespace MediaBrowser.Server.Implementations.Drawing
/// <summary>
/// The _semaphoreLocks
/// </summary>
- private readonly ConcurrentDictionary<string, object> _locks = new ConcurrentDictionary<string, object>();
-
- /// <summary>
- /// Gets the lock.
- /// </summary>
- /// <param name="filename">The filename.</param>
- /// <returns>System.Object.</returns>
- private object GetObjectLock(string filename)
- {
- return _locks.GetOrAdd(filename, key => new object());
- }
-
- /// <summary>
- /// The _semaphoreLocks
- /// </summary>
private readonly ConcurrentDictionary<string, SemaphoreSlim> _semaphoreLocks = new ConcurrentDictionary<string, SemaphoreSlim>();
/// <summary>
diff --git a/MediaBrowser.Server.Implementations/Dto/DtoService.cs b/MediaBrowser.Server.Implementations/Dto/DtoService.cs
index bfed3887f4..1020a43735 100644
--- a/MediaBrowser.Server.Implementations/Dto/DtoService.cs
+++ b/MediaBrowser.Server.Implementations/Dto/DtoService.cs
@@ -69,7 +69,22 @@ namespace MediaBrowser.Server.Implementations.Dto
/// <exception cref="System.ArgumentNullException">item</exception>
public BaseItemDto GetBaseItemDto(BaseItem item, List<ItemFields> fields, User user = null, BaseItem owner = null)
{
- var dto = GetBaseItemDtoInternal(item, fields, user, owner);
+ var options = new DtoOptions
+ {
+ Fields = fields
+ };
+
+ // Get everything
+ options.ImageTypes = Enum.GetNames(typeof(ImageType))
+ .Select(i => (ImageType)Enum.Parse(typeof(ImageType), i, true))
+ .ToList();
+
+ return GetBaseItemDto(item, options, user, owner);
+ }
+
+ public BaseItemDto GetBaseItemDto(BaseItem item, DtoOptions options, User user = null, BaseItem owner = null)
+ {
+ var dto = GetBaseItemDtoInternal(item, options, user, owner);
var byName = item as IItemByName;
@@ -87,8 +102,10 @@ namespace MediaBrowser.Server.Implementations.Dto
return dto;
}
- private BaseItemDto GetBaseItemDtoInternal(BaseItem item, List<ItemFields> fields, User user = null, BaseItem owner = null)
+ private BaseItemDto GetBaseItemDtoInternal(BaseItem item, DtoOptions options, User user = null, BaseItem owner = null)
{
+ var fields = options.Fields;
+
if (item == null)
{
throw new ArgumentNullException("item");
@@ -115,7 +132,7 @@ namespace MediaBrowser.Server.Implementations.Dto
{
try
{
- AttachPrimaryImageAspectRatio(dto, item);
+ AttachPrimaryImageAspectRatio(dto, item, fields);
}
catch (Exception ex)
{
@@ -155,7 +172,7 @@ namespace MediaBrowser.Server.Implementations.Dto
AttachStudios(dto, item);
}
- AttachBasicFields(dto, item, owner, fields);
+ AttachBasicFields(dto, item, owner, options);
if (fields.Contains(ItemFields.SyncInfo))
{
@@ -174,18 +191,19 @@ namespace MediaBrowser.Server.Implementations.Dto
}
}
- if (item is Playlist)
+ var playlist = item as Playlist;
+ if (playlist != null)
{
- AttachLinkedChildImages(dto, (Folder)item, user);
+ AttachLinkedChildImages(dto, playlist, user, options);
}
return dto;
}
- public BaseItemDto GetItemByNameDto<T>(T item, List<ItemFields> fields, List<BaseItem> taggedItems, User user = null)
+ public BaseItemDto GetItemByNameDto<T>(T item, DtoOptions options, List<BaseItem> taggedItems, User user = null)
where T : BaseItem, IItemByName
{
- var dto = GetBaseItemDtoInternal(item, fields, user);
+ var dto = GetBaseItemDtoInternal(item, options, user);
SetItemByNameInfo(item, dto, taggedItems, user);
@@ -215,7 +233,6 @@ namespace MediaBrowser.Server.Implementations.Dto
dto.MusicVideoCount = taggedItems.Count(i => i is MusicVideo);
dto.SeriesCount = taggedItems.Count(i => i is Series);
dto.SongCount = taggedItems.Count(i => i is Audio);
- dto.TrailerCount = taggedItems.Count(i => i is Trailer);
}
dto.ChildCount = taggedItems.Count;
@@ -369,36 +386,27 @@ namespace MediaBrowser.Server.Implementations.Dto
dto.GameSystem = item.GameSystemName;
}
- /// <summary>
- /// Gets the backdrop image tags.
- /// </summary>
- /// <param name="item">The item.</param>
- /// <returns>List{System.String}.</returns>
- private List<string> GetBackdropImageTags(BaseItem item)
+ private List<string> GetBackdropImageTags(BaseItem item, int limit)
{
- return GetCacheTags(item, ImageType.Backdrop).ToList();
+ return GetCacheTags(item, ImageType.Backdrop, limit).ToList();
}
- /// <summary>
- /// Gets the screenshot image tags.
- /// </summary>
- /// <param name="item">The item.</param>
- /// <returns>List{Guid}.</returns>
- private List<string> GetScreenshotImageTags(BaseItem item)
+ private List<string> GetScreenshotImageTags(BaseItem item, int limit)
{
var hasScreenshots = item as IHasScreenshots;
if (hasScreenshots == null)
{
return new List<string>();
}
- return GetCacheTags(item, ImageType.Screenshot).ToList();
+ return GetCacheTags(item, ImageType.Screenshot, limit).ToList();
}
- private IEnumerable<string> GetCacheTags(BaseItem item, ImageType type)
+ private IEnumerable<string> GetCacheTags(BaseItem item, ImageType type, int limit)
{
return item.GetImages(type)
.Select(p => GetImageCacheTag(item, p))
.Where(i => i != null)
+ .Take(limit)
.ToList();
}
@@ -649,9 +657,11 @@ namespace MediaBrowser.Server.Implementations.Dto
/// <param name="dto">The dto.</param>
/// <param name="item">The item.</param>
/// <param name="owner">The owner.</param>
- /// <param name="fields">The fields.</param>
- private void AttachBasicFields(BaseItemDto dto, BaseItem item, BaseItem owner, List<ItemFields> fields)
+ /// <param name="options">The options.</param>
+ private void AttachBasicFields(BaseItemDto dto, BaseItem item, BaseItem owner, DtoOptions options)
{
+ var fields = options.Fields;
+
if (fields.Contains(ItemFields.DateCreated))
{
dto.DateCreated = item.DateCreated;
@@ -662,7 +672,11 @@ namespace MediaBrowser.Server.Implementations.Dto
dto.DisplayMediaType = item.DisplayMediaType;
}
- dto.IsUnidentified = item.IsUnidentified;
+ // Leave null if false
+ if (item.IsUnidentified)
+ {
+ dto.IsUnidentified = item.IsUnidentified;
+ }
if (fields.Contains(ItemFields.Settings))
{
@@ -736,10 +750,13 @@ namespace MediaBrowser.Server.Implementations.Dto
dto.AspectRatio = hasAspectRatio.AspectRatio;
}
- var hasMetascore = item as IHasMetascore;
- if (hasMetascore != null)
+ if (fields.Contains(ItemFields.ProductionLocations))
{
- dto.Metascore = hasMetascore.Metascore;
+ var hasMetascore = item as IHasMetascore;
+ if (hasMetascore != null)
+ {
+ dto.Metascore = hasMetascore.Metascore;
+ }
}
if (fields.Contains(ItemFields.AwardSummary))
@@ -751,11 +768,19 @@ namespace MediaBrowser.Server.Implementations.Dto
}
}
- dto.BackdropImageTags = GetBackdropImageTags(item);
+ var backdropLimit = options.GetImageLimit(ImageType.Backdrop);
+ if (backdropLimit > 0)
+ {
+ dto.BackdropImageTags = GetBackdropImageTags(item, backdropLimit);
+ }
if (fields.Contains(ItemFields.ScreenshotImageTags))
{
- dto.ScreenshotImageTags = GetScreenshotImageTags(item);
+ var screenshotLimit = options.GetImageLimit(ImageType.Screenshot);
+ if (screenshotLimit > 0)
+ {
+ dto.ScreenshotImageTags = GetScreenshotImageTags(item, screenshotLimit);
+ }
}
if (fields.Contains(ItemFields.Genres))
@@ -769,11 +794,14 @@ namespace MediaBrowser.Server.Implementations.Dto
var currentItem = item;
foreach (var image in currentItem.ImageInfos.Where(i => !currentItem.AllowsMultipleImages(i.Type)))
{
- var tag = GetImageCacheTag(item, image);
-
- if (tag != null)
+ if (options.GetImageLimit(image.Type) > 0)
{
- dto.ImageTags[image.Type] = tag;
+ var tag = GetImageCacheTag(item, image);
+
+ if (tag != null)
+ {
+ dto.ImageTags[image.Type] = tag;
+ }
}
}
@@ -805,7 +833,7 @@ namespace MediaBrowser.Server.Implementations.Dto
var hasTrailers = item as IHasTrailers;
if (hasTrailers != null)
{
- dto.LocalTrailerCount = hasTrailers.LocalTrailerIds.Count;
+ dto.LocalTrailerCount = hasTrailers.GetTrailerIds().Count;
}
var hasDisplayOrder = item as IHasDisplayOrder;
@@ -851,14 +879,14 @@ namespace MediaBrowser.Server.Implementations.Dto
}
// If there are no backdrops, indicate what parent has them in case the Ui wants to allow inheritance
- if (dto.BackdropImageTags.Count == 0)
+ if (backdropLimit > 0 && dto.BackdropImageTags.Count == 0)
{
var parentWithBackdrop = GetParentBackdropItem(item, owner);
if (parentWithBackdrop != null)
{
dto.ParentBackdropItemId = GetDtoId(parentWithBackdrop);
- dto.ParentBackdropImageTags = GetBackdropImageTags(parentWithBackdrop);
+ dto.ParentBackdropImageTags = GetBackdropImageTags(parentWithBackdrop, backdropLimit);
}
}
@@ -874,7 +902,7 @@ namespace MediaBrowser.Server.Implementations.Dto
dto.ParentIndexNumber = item.ParentIndexNumber;
// If there is no logo, indicate what parent has one in case the Ui wants to allow inheritance
- if (!dto.HasLogo)
+ if (!dto.HasLogo && options.GetImageLimit(ImageType.Logo) > 0)
{
var parentWithLogo = GetParentImageItem(item, ImageType.Logo, owner);
@@ -887,7 +915,7 @@ namespace MediaBrowser.Server.Implementations.Dto
}
// If there is no art, indicate what parent has one in case the Ui wants to allow inheritance
- if (!dto.HasArtImage)
+ if (!dto.HasArtImage && options.GetImageLimit(ImageType.Art) > 0)
{
var parentWithImage = GetParentImageItem(item, ImageType.Art, owner);
@@ -900,7 +928,7 @@ namespace MediaBrowser.Server.Implementations.Dto
}
// If there is no thumb, indicate what parent has one in case the Ui wants to allow inheritance
- if (!dto.HasThumb)
+ if (!dto.HasThumb && options.GetImageLimit(ImageType.Thumb) > 0)
{
var parentWithImage = GetParentImageItem(item, ImageType.Thumb, owner);
@@ -953,7 +981,11 @@ namespace MediaBrowser.Server.Implementations.Dto
dto.Type = item.GetClientTypeName();
dto.CommunityRating = item.CommunityRating;
- dto.VoteCount = item.VoteCount;
+
+ if (fields.Contains(ItemFields.VoteCount))
+ {
+ dto.VoteCount = item.VoteCount;
+ }
if (item.IsFolder)
{
@@ -987,7 +1019,10 @@ namespace MediaBrowser.Server.Implementations.Dto
dto.AlbumPrimaryImageTag = GetImageCacheTag(albumParent, ImageType.Primary);
}
- dto.MediaSourceCount = 1;
+ //if (fields.Contains(ItemFields.MediaSourceCount))
+ //{
+ // Songs always have one
+ //}
}
var album = item as MusicAlbum;
@@ -1017,8 +1052,18 @@ namespace MediaBrowser.Server.Implementations.Dto
dto.IsoType = video.IsoType;
dto.IsHD = video.IsHD;
- dto.PartCount = video.AdditionalPartIds.Count + 1;
- dto.MediaSourceCount = video.MediaSourceCount;
+ if (video.AdditionalParts.Count != 0)
+ {
+ dto.PartCount = video.AdditionalParts.Count + 1;
+ }
+
+ if (fields.Contains(ItemFields.MediaSourceCount))
+ {
+ if (video.MediaSourceCount != 1)
+ {
+ dto.MediaSourceCount = video.MediaSourceCount;
+ }
+ }
if (fields.Contains(ItemFields.Chapters))
{
@@ -1080,12 +1125,16 @@ namespace MediaBrowser.Server.Implementations.Dto
{
dto.IndexNumberEnd = episode.IndexNumberEnd;
- dto.DvdSeasonNumber = episode.DvdSeasonNumber;
- dto.DvdEpisodeNumber = episode.DvdEpisodeNumber;
+ if (fields.Contains(ItemFields.AlternateEpisodeNumbers))
+ {
+ dto.DvdSeasonNumber = episode.DvdSeasonNumber;
+ dto.DvdEpisodeNumber = episode.DvdEpisodeNumber;
+ dto.AbsoluteEpisodeNumber = episode.AbsoluteEpisodeNumber;
+ }
+
dto.AirsAfterSeasonNumber = episode.AirsAfterSeasonNumber;
dto.AirsBeforeEpisodeNumber = episode.AirsBeforeEpisodeNumber;
dto.AirsBeforeSeasonNumber = episode.AirsBeforeSeasonNumber;
- dto.AbsoluteEpisodeNumber = episode.AbsoluteEpisodeNumber;
var episodeSeason = episode.Season;
if (episodeSeason != null)
@@ -1093,6 +1142,15 @@ namespace MediaBrowser.Server.Implementations.Dto
dto.SeasonId = episodeSeason.Id.ToString("N");
dto.SeasonName = episodeSeason.Name;
}
+
+ if (fields.Contains(ItemFields.SeriesGenres))
+ {
+ var episodeseries = episode.Series;
+ if (episodeseries != null)
+ {
+ dto.SeriesGenres = episodeseries.Genres.ToList();
+ }
+ }
}
// Add SeriesInfo
@@ -1123,9 +1181,21 @@ namespace MediaBrowser.Server.Implementations.Dto
dto.SeriesId = GetDtoId(series);
dto.SeriesName = series.Name;
dto.AirTime = series.AirTime;
- dto.SeriesStudio = series.Studios.FirstOrDefault();
- dto.SeriesThumbImageTag = GetImageCacheTag(series, ImageType.Thumb);
- dto.SeriesPrimaryImageTag = GetImageCacheTag(series, ImageType.Primary);
+
+ if (options.GetImageLimit(ImageType.Thumb) > 0)
+ {
+ dto.SeriesThumbImageTag = GetImageCacheTag(series, ImageType.Thumb);
+ }
+
+ if (options.GetImageLimit(ImageType.Primary) > 0)
+ {
+ dto.SeriesPrimaryImageTag = GetImageCacheTag(series, ImageType.Primary);
+ }
+
+ if (fields.Contains(ItemFields.SeriesStudio))
+ {
+ dto.SeriesStudio = series.Studios.FirstOrDefault();
+ }
}
}
@@ -1143,7 +1213,10 @@ namespace MediaBrowser.Server.Implementations.Dto
dto.AirTime = series.AirTime;
dto.SeriesStudio = series.Studios.FirstOrDefault();
- dto.SeriesPrimaryImageTag = GetImageCacheTag(series, ImageType.Primary);
+ if (options.GetImageLimit(ImageType.Primary) > 0)
+ {
+ dto.SeriesPrimaryImageTag = GetImageCacheTag(series, ImageType.Primary);
+ }
}
}
@@ -1200,28 +1273,28 @@ namespace MediaBrowser.Server.Implementations.Dto
}
}
- private void AttachLinkedChildImages(BaseItemDto dto, Folder folder, User user)
+ private void AttachLinkedChildImages(BaseItemDto dto, Folder folder, User user, DtoOptions options)
{
List<BaseItem> linkedChildren = null;
- if (dto.BackdropImageTags.Count == 0)
+ var backdropLimit = options.GetImageLimit(ImageType.Backdrop);
+
+ if (backdropLimit > 0 && dto.BackdropImageTags.Count == 0)
{
- if (linkedChildren == null)
- {
- linkedChildren = user == null
- ? folder.GetRecursiveChildren().ToList()
- : folder.GetRecursiveChildren(user, true).ToList();
- }
+ linkedChildren = user == null
+ ? folder.GetRecursiveChildren().ToList()
+ : folder.GetRecursiveChildren(user, true).ToList();
+
var parentWithBackdrop = linkedChildren.FirstOrDefault(i => i.GetImages(ImageType.Backdrop).Any());
if (parentWithBackdrop != null)
{
dto.ParentBackdropItemId = GetDtoId(parentWithBackdrop);
- dto.ParentBackdropImageTags = GetBackdropImageTags(parentWithBackdrop);
+ dto.ParentBackdropImageTags = GetBackdropImageTags(parentWithBackdrop, backdropLimit);
}
}
- if (!dto.ImageTags.ContainsKey(ImageType.Primary))
+ if (!dto.ImageTags.ContainsKey(ImageType.Primary) && options.GetImageLimit(ImageType.Primary) > 0)
{
if (linkedChildren == null)
{
@@ -1380,8 +1453,9 @@ namespace MediaBrowser.Server.Implementations.Dto
/// </summary>
/// <param name="dto">The dto.</param>
/// <param name="item">The item.</param>
+ /// <param name="fields">The fields.</param>
/// <returns>Task.</returns>
- public void AttachPrimaryImageAspectRatio(IItemDto dto, IHasImages item)
+ public void AttachPrimaryImageAspectRatio(IItemDto dto, IHasImages item, List<ItemFields> fields)
{
var imageInfo = item.GetImageInfo(ImageType.Primary, 0);
@@ -1412,7 +1486,10 @@ namespace MediaBrowser.Server.Implementations.Dto
return;
}
- dto.OriginalPrimaryImageAspectRatio = size.Width / size.Height;
+ if (fields.Contains(ItemFields.OriginalPrimaryImageAspectRatio))
+ {
+ dto.OriginalPrimaryImageAspectRatio = size.Width / size.Height;
+ }
var supportedEnhancers = _imageProcessor.GetSupportedEnhancers(item, ImageType.Primary).ToList();
diff --git a/MediaBrowser.Server.Implementations/EntryPoints/Notifications/RemoteNotifications.cs b/MediaBrowser.Server.Implementations/EntryPoints/Notifications/RemoteNotifications.cs
index d5b7f5b363..dba93cbd4c 100644
--- a/MediaBrowser.Server.Implementations/EntryPoints/Notifications/RemoteNotifications.cs
+++ b/MediaBrowser.Server.Implementations/EntryPoints/Notifications/RemoteNotifications.cs
@@ -18,7 +18,7 @@ namespace MediaBrowser.Server.Implementations.EntryPoints.Notifications
{
public class RemoteNotifications : IServerEntryPoint
{
- private const string Url = "http://www.mb3admin.com/admin/service/MB3ServerNotifications.json";
+ private const string Url = "https://www.mb3admin.com/admin/service/MB3ServerNotifications.json";
private Timer _timer;
private readonly IHttpClient _httpClient;
diff --git a/MediaBrowser.Server.Implementations/EntryPoints/UsageReporter.cs b/MediaBrowser.Server.Implementations/EntryPoints/UsageReporter.cs
index 85410faf2b..b7bb482e0d 100644
--- a/MediaBrowser.Server.Implementations/EntryPoints/UsageReporter.cs
+++ b/MediaBrowser.Server.Implementations/EntryPoints/UsageReporter.cs
@@ -12,6 +12,7 @@ namespace MediaBrowser.Server.Implementations.EntryPoints
private readonly IApplicationHost _applicationHost;
private readonly INetworkManager _networkManager;
private readonly IHttpClient _httpClient;
+ private const string MbAdminUrl = "https://www.mb3admin.com/admin/";
public UsageReporter(IApplicationHost applicationHost, INetworkManager networkManager, IHttpClient httpClient)
{
@@ -37,7 +38,7 @@ namespace MediaBrowser.Server.Implementations.EntryPoints
{ "isservice", _applicationHost.IsRunningAsService.ToString().ToLower()}
};
- return _httpClient.Post(Common.Constants.Constants.MbAdminUrl + "service/registration/ping", data, cancellationToken);
+ return _httpClient.Post(MbAdminUrl + "service/registration/ping", data, cancellationToken);
}
public Task ReportAppUsage(ClientInfo app, CancellationToken cancellationToken)
@@ -59,7 +60,7 @@ namespace MediaBrowser.Server.Implementations.EntryPoints
{ "platform", app.DeviceName },
};
- return _httpClient.Post(Common.Constants.Constants.MbAdminUrl + "service/registration/ping", data, cancellationToken);
+ return _httpClient.Post(MbAdminUrl + "service/registration/ping", data, cancellationToken);
}
}
diff --git a/MediaBrowser.Server.Implementations/FileOrganization/TvFolderOrganizer.cs b/MediaBrowser.Server.Implementations/FileOrganization/TvFolderOrganizer.cs
index c41aebb694..cf120f1476 100644
--- a/MediaBrowser.Server.Implementations/FileOrganization/TvFolderOrganizer.cs
+++ b/MediaBrowser.Server.Implementations/FileOrganization/TvFolderOrganizer.cs
@@ -3,8 +3,6 @@ using MediaBrowser.Controller.Configuration;
using MediaBrowser.Controller.FileOrganization;
using MediaBrowser.Controller.Library;
using MediaBrowser.Controller.Providers;
-using MediaBrowser.Controller.Resolvers;
-using MediaBrowser.Model.Configuration;
using MediaBrowser.Model.FileOrganization;
using MediaBrowser.Model.Logging;
using System;
@@ -13,7 +11,6 @@ using System.IO;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
-using MediaBrowser.Server.Implementations.Library;
namespace MediaBrowser.Server.Implementations.FileOrganization
{
diff --git a/MediaBrowser.Server.Implementations/Intros/DefaultIntroProvider.cs b/MediaBrowser.Server.Implementations/Intros/DefaultIntroProvider.cs
index 2d991abba4..fd1cc94842 100644
--- a/MediaBrowser.Server.Implementations/Intros/DefaultIntroProvider.cs
+++ b/MediaBrowser.Server.Implementations/Intros/DefaultIntroProvider.cs
@@ -59,7 +59,7 @@ namespace MediaBrowser.Server.Implementations.Intros
}
var ratingLevel = string.IsNullOrWhiteSpace(item.OfficialRating)
- ? (int?)null
+ ? null
: _localization.GetRatingLevel(item.OfficialRating);
var libaryItems = user.RootFolder.GetRecursiveChildren(user, false)
@@ -134,15 +134,6 @@ namespace MediaBrowser.Server.Implementations.Intros
WatchingItem = item,
Random = random
}));
-
- candidates.AddRange(libaryItems.Where(i => i is Trailer).Select(i => new ItemWithTrailer
- {
- Item = i,
- Type = ItemWithTrailerType.LibraryTrailer,
- User = user,
- WatchingItem = item,
- Random = random
- }));
}
var customIntros = !string.IsNullOrWhiteSpace(config.CustomIntroPath) ?
diff --git a/MediaBrowser.Server.Implementations/Library/CoreResolutionIgnoreRule.cs b/MediaBrowser.Server.Implementations/Library/CoreResolutionIgnoreRule.cs
index 0fc04c5046..7edd9541f2 100644
--- a/MediaBrowser.Server.Implementations/Library/CoreResolutionIgnoreRule.cs
+++ b/MediaBrowser.Server.Implementations/Library/CoreResolutionIgnoreRule.cs
@@ -3,6 +3,7 @@ using MediaBrowser.Controller.Entities;
using MediaBrowser.Controller.Library;
using MediaBrowser.Controller.Resolvers;
using System;
+using System.Collections.Generic;
using System.IO;
using System.Linq;
@@ -16,6 +17,21 @@ namespace MediaBrowser.Server.Implementations.Library
private readonly IFileSystem _fileSystem;
private readonly ILibraryManager _libraryManager;
+ /// <summary>
+ /// Any folder named in this list will be ignored - can be added to at runtime for extensibility
+ /// </summary>
+ public static readonly List<string> IgnoreFolders = new List<string>
+ {
+ "metadata",
+ "ps3_update",
+ "ps3_vprm",
+ "extrafanart",
+ "extrathumbs",
+ ".actors",
+ ".wd_tv"
+
+ };
+
public CoreResolutionIgnoreRule(IFileSystem fileSystem, ILibraryManager libraryManager)
{
_fileSystem = fileSystem;
@@ -64,7 +80,7 @@ namespace MediaBrowser.Server.Implementations.Library
if (args.IsDirectory)
{
// Ignore any folders in our list
- if (EntityResolutionHelper.IgnoreFolders.Contains(filename, StringComparer.OrdinalIgnoreCase))
+ if (IgnoreFolders.Contains(filename, StringComparer.OrdinalIgnoreCase))
{
return true;
}
@@ -88,20 +104,6 @@ namespace MediaBrowser.Server.Implementations.Library
}
else
{
- if (args.Parent != null)
- {
- // Don't resolve these into audio files
- if (string.Equals(_fileSystem.GetFileNameWithoutExtension(filename), BaseItem.ThemeSongFilename) && _libraryManager.IsAudioFile(filename))
- {
- return true;
- }
-
- if (BaseItem.ExtraSuffixes.Any(i => filename.IndexOf(i.Key, StringComparison.OrdinalIgnoreCase) != -1))
- {
- return true;
- }
- }
-
// Ignore samples
if (filename.IndexOf(".sample.", StringComparison.OrdinalIgnoreCase) != -1)
{
diff --git a/MediaBrowser.Server.Implementations/Library/EntityResolutionHelper.cs b/MediaBrowser.Server.Implementations/Library/EntityResolutionHelper.cs
deleted file mode 100644
index fdb0b35a1f..0000000000
--- a/MediaBrowser.Server.Implementations/Library/EntityResolutionHelper.cs
+++ /dev/null
@@ -1,104 +0,0 @@
-using MediaBrowser.Common.IO;
-using MediaBrowser.Controller.Entities;
-using MediaBrowser.Controller.Library;
-using System;
-using System.Collections.Generic;
-using System.IO;
-
-namespace MediaBrowser.Server.Implementations.Library
-{
- /// <summary>
- /// Class EntityResolutionHelper
- /// </summary>
- public static class EntityResolutionHelper
- {
- /// <summary>
- /// Any folder named in this list will be ignored - can be added to at runtime for extensibility
- /// </summary>
- public static readonly List<string> IgnoreFolders = new List<string>
- {
- "metadata",
- "ps3_update",
- "ps3_vprm",
- "extrafanart",
- "extrathumbs",
- ".actors",
- ".wd_tv"
-
- };
-
- /// <summary>
- /// Ensures DateCreated and DateModified have values
- /// </summary>
- /// <param name="fileSystem">The file system.</param>
- /// <param name="item">The item.</param>
- /// <param name="args">The args.</param>
- /// <param name="includeCreationTime">if set to <c>true</c> [include creation time].</param>
- public static void EnsureDates(IFileSystem fileSystem, BaseItem item, ItemResolveArgs args, bool includeCreationTime)
- {
- if (fileSystem == null)
- {
- throw new ArgumentNullException("fileSystem");
- }
- if (item == null)
- {
- throw new ArgumentNullException("item");
- }
- if (args == null)
- {
- throw new ArgumentNullException("args");
- }
-
- // See if a different path came out of the resolver than what went in
- if (!string.Equals(args.Path, item.Path, StringComparison.OrdinalIgnoreCase))
- {
- var childData = args.IsDirectory ? args.GetFileSystemEntryByPath(item.Path) : null;
-
- if (childData != null)
- {
- if (includeCreationTime)
- {
- SetDateCreated(item, fileSystem, childData);
- }
-
- item.DateModified = fileSystem.GetLastWriteTimeUtc(childData);
- }
- else
- {
- var fileData = fileSystem.GetFileSystemInfo(item.Path);
-
- if (fileData.Exists)
- {
- if (includeCreationTime)
- {
- SetDateCreated(item, fileSystem, fileData);
- }
- item.DateModified = fileSystem.GetLastWriteTimeUtc(fileData);
- }
- }
- }
- else
- {
- if (includeCreationTime)
- {
- SetDateCreated(item, fileSystem, args.FileInfo);
- }
- item.DateModified = fileSystem.GetLastWriteTimeUtc(args.FileInfo);
- }
- }
-
- private static void SetDateCreated(BaseItem item, IFileSystem fileSystem, FileSystemInfo info)
- {
- var config = BaseItem.ConfigurationManager.GetMetadataConfiguration();
-
- if (config.UseFileCreationTimeForDateAdded)
- {
- item.DateCreated = fileSystem.GetCreationTimeUtc(info);
- }
- else
- {
- item.DateCreated = DateTime.UtcNow;
- }
- }
- }
-}
diff --git a/MediaBrowser.Server.Implementations/Library/LibraryManager.cs b/MediaBrowser.Server.Implementations/Library/LibraryManager.cs
index 63ced85599..bfdfc03bac 100644
--- a/MediaBrowser.Server.Implementations/Library/LibraryManager.cs
+++ b/MediaBrowser.Server.Implementations/Library/LibraryManager.cs
@@ -466,29 +466,54 @@ namespace MediaBrowser.Server.Implementations.Library
/// </summary>
/// <param name="args">The args.</param>
/// <returns>BaseItem.</returns>
- public BaseItem ResolveItem(ItemResolveArgs args)
+ private BaseItem ResolveItem(ItemResolveArgs args)
{
- var item = EntityResolvers.Select(r =>
+ var item = EntityResolvers.Select(r => Resolve(args, r))
+ .FirstOrDefault(i => i != null);
+
+ if (item != null)
{
- try
- {
- return r.ResolvePath(args);
- }
- catch (Exception ex)
- {
- _logger.ErrorException("Error in {0} resolving {1}", ex, r.GetType().Name, args.Path);
+ ResolverHelper.SetInitialItemValues(item, args, _fileSystem, this);
+ }
- return null;
- }
+ return item;
+ }
- }).FirstOrDefault(i => i != null);
+ private BaseItem Resolve(ItemResolveArgs args, IItemResolver resolver)
+ {
+ try
+ {
+ return resolver.ResolvePath(args);
+ }
+ catch (Exception ex)
+ {
+ _logger.ErrorException("Error in {0} resolving {1}", ex, resolver.GetType().Name, args.Path);
+ return null;
+ }
+ }
- if (item != null)
+ public Guid GetNewItemId(string key, Type type)
+ {
+ if (string.IsNullOrWhiteSpace(key))
+ {
+ throw new ArgumentNullException("key");
+ }
+ if (type == null)
{
- ResolverHelper.SetInitialItemValues(item, args, _fileSystem);
+ throw new ArgumentNullException("type");
}
- return item;
+ if (ConfigurationManager.Configuration.EnableLocalizedGuids && key.StartsWith(ConfigurationManager.ApplicationPaths.ProgramDataPath))
+ {
+ // Try to normalize paths located underneath program-data in an attempt to make them more portable
+ key = key.Substring(ConfigurationManager.ApplicationPaths.ProgramDataPath.Length)
+ .TrimStart(new[] { '/', '\\' })
+ .Replace("/", "\\");
+ }
+
+ key = type.FullName + key.ToLower();
+
+ return key.GetMD5();
}
public IEnumerable<BaseItem> ReplaceVideosWithPrimaryVersions(IEnumerable<BaseItem> items)
@@ -541,7 +566,7 @@ namespace MediaBrowser.Server.Implementations.Library
return ResolvePath(fileInfo, new DirectoryService(_logger), parent, collectionType);
}
- public BaseItem ResolvePath(FileSystemInfo fileInfo, IDirectoryService directoryService, Folder parent = null, string collectionType = null)
+ private BaseItem ResolvePath(FileSystemInfo fileInfo, IDirectoryService directoryService, Folder parent = null, string collectionType = null)
{
if (fileInfo == null)
{
@@ -621,23 +646,50 @@ namespace MediaBrowser.Server.Implementations.Library
return !args.ContainsFileSystemEntryByName(".ignore");
}
- public List<T> ResolvePaths<T>(IEnumerable<FileSystemInfo> files, IDirectoryService directoryService, Folder parent, string collectionType = null)
- where T : BaseItem
+ public IEnumerable<BaseItem> ResolvePaths(IEnumerable<FileSystemInfo> files, IDirectoryService directoryService, Folder parent, string collectionType)
{
- return files.Select(f =>
+ var fileList = files.ToList();
+
+ if (parent != null)
+ {
+ var multiItemResolvers = EntityResolvers.OfType<IMultiItemResolver>();
+
+ foreach (var resolver in multiItemResolvers)
+ {
+ var result = resolver.ResolveMultiple(parent, fileList, collectionType, directoryService);
+
+ if (result != null && result.Items.Count > 0)
+ {
+ var items = new List<BaseItem>();
+ items.AddRange(result.Items);
+
+ foreach (var item in items)
+ {
+ ResolverHelper.SetInitialItemValues(item, parent, _fileSystem, this, directoryService);
+ }
+ items.AddRange(ResolveFileList(result.ExtraFiles, directoryService, parent, collectionType));
+ return items;
+ }
+ }
+ }
+
+ return ResolveFileList(fileList, directoryService, parent, collectionType);
+ }
+
+ private IEnumerable<BaseItem> ResolveFileList(IEnumerable<FileSystemInfo> fileList, IDirectoryService directoryService, Folder parent, string collectionType)
+ {
+ return fileList.Select(f =>
{
try
{
- return ResolvePath(f, directoryService, parent, collectionType) as T;
+ return ResolvePath(f, directoryService, parent, collectionType);
}
catch (Exception ex)
{
_logger.ErrorException("Error resolving path {0}", ex, f.FullName);
return null;
}
-
- }).Where(i => i != null)
- .ToList();
+ }).Where(i => i != null);
}
/// <summary>
@@ -651,7 +703,7 @@ namespace MediaBrowser.Server.Implementations.Library
Directory.CreateDirectory(rootFolderPath);
- var rootFolder = GetItemById(rootFolderPath.GetMBId(typeof(AggregateFolder))) as AggregateFolder ?? (AggregateFolder)ResolvePath(new DirectoryInfo(rootFolderPath));
+ var rootFolder = GetItemById(GetNewItemId(rootFolderPath, typeof(AggregateFolder))) as AggregateFolder ?? (AggregateFolder)ResolvePath(new DirectoryInfo(rootFolderPath));
// Add in the plug-in folders
foreach (var child in PluginFolderCreators)
@@ -662,7 +714,14 @@ namespace MediaBrowser.Server.Implementations.Library
{
if (folder.Id == Guid.Empty)
{
- folder.Id = (folder.Path ?? folder.GetType().Name).GetMBId(folder.GetType());
+ if (string.IsNullOrWhiteSpace(folder.Path))
+ {
+ folder.Id = GetNewItemId(folder.GetType().Name, folder.GetType());
+ }
+ else
+ {
+ folder.Id = GetNewItemId(folder.Path, folder.GetType());
+ }
}
folder = GetItemById(folder.Id) as BasePluginFolder ?? folder;
@@ -677,16 +736,27 @@ namespace MediaBrowser.Server.Implementations.Library
}
private UserRootFolder _userRootFolder;
+ private readonly object _syncLock = new object();
public Folder GetUserRootFolder()
{
if (_userRootFolder == null)
{
- var userRootPath = ConfigurationManager.ApplicationPaths.DefaultUserViewsPath;
+ lock (_syncLock)
+ {
+ if (_userRootFolder == null)
+ {
+ var userRootPath = ConfigurationManager.ApplicationPaths.DefaultUserViewsPath;
+
+ Directory.CreateDirectory(userRootPath);
- Directory.CreateDirectory(userRootPath);
+ _userRootFolder = GetItemById(GetNewItemId(userRootPath, typeof(UserRootFolder))) as UserRootFolder;
- _userRootFolder = GetItemById(userRootPath.GetMBId(typeof(UserRootFolder))) as UserRootFolder ??
- (UserRootFolder)ResolvePath(new DirectoryInfo(userRootPath));
+ if (_userRootFolder == null)
+ {
+ _userRootFolder = (UserRootFolder)ResolvePath(new DirectoryInfo(userRootPath));
+ }
+ }
+ }
}
return _userRootFolder;
@@ -801,7 +871,7 @@ namespace MediaBrowser.Server.Implementations.Library
Path.Combine(path, validFilename) :
Path.Combine(path, subFolderPrefix, validFilename);
- var id = fullPath.GetMBId(type);
+ var id = GetNewItemId(fullPath, type);
BaseItem obj;
@@ -1513,7 +1583,7 @@ namespace MediaBrowser.Server.Implementations.Library
path = Path.Combine(path, _fileSystem.GetValidFilename(type));
- var id = (path + "_namedview_" + name).GetMBId(typeof(UserView));
+ var id = GetNewItemId(path + "_namedview_" + name, typeof(UserView));
var item = GetItemById(id) as UserView;
@@ -1578,7 +1648,7 @@ namespace MediaBrowser.Server.Implementations.Library
throw new ArgumentNullException("viewType");
}
- var id = ("7_namedview_" + name + user.Id.ToString("N") + parentId).GetMBId(typeof(UserView));
+ var id = GetNewItemId("7_namedview_" + name + user.Id.ToString("N") + parentId, typeof(UserView));
var path = BaseItem.GetInternalMetadataPathForId(id);
@@ -1670,41 +1740,132 @@ namespace MediaBrowser.Server.Implementations.Library
};
}
- public IEnumerable<FileSystemInfo> GetAdditionalParts(string file,
- VideoType type,
- IEnumerable<FileSystemInfo> files)
+ public IEnumerable<Video> FindTrailers(BaseItem owner, List<FileSystemInfo> fileSystemChildren, IDirectoryService directoryService)
{
- var resolver = new StackResolver(new ExtendedNamingOptions(), new Naming.Logging.NullLogger());
+ var files = fileSystemChildren.OfType<DirectoryInfo>()
+ .Where(i => string.Equals(i.Name, BaseItem.TrailerFolderName, StringComparison.OrdinalIgnoreCase))
+ .SelectMany(i => i.EnumerateFiles("*", SearchOption.TopDirectoryOnly))
+ .ToList();
- StackResult result;
- List<FileSystemInfo> filteredFiles;
+ var videoListResolver = new VideoListResolver(new ExtendedNamingOptions(), new Naming.Logging.NullLogger());
- if (type == VideoType.BluRay || type == VideoType.Dvd)
+ var videos = videoListResolver.Resolve(fileSystemChildren.Select(i => new PortableFileInfo
{
- filteredFiles = files.Where(i => (i.Attributes & FileAttributes.Directory) == FileAttributes.Directory)
- .ToList();
+ FullName = i.FullName,
+ Type = GetFileType(i)
+
+ }).ToList());
+
+ var currentVideo = videos.FirstOrDefault(i => string.Equals(owner.Path, i.Files.First().Path, StringComparison.OrdinalIgnoreCase));
- result = resolver.ResolveDirectories(filteredFiles.Select(i => i.FullName));
+ if (currentVideo != null)
+ {
+ files.AddRange(currentVideo.Extras.Where(i => string.Equals(i.ExtraType, "trailer", StringComparison.OrdinalIgnoreCase)).Select(i => new FileInfo(i.Path)));
}
- else
+
+ return ResolvePaths(files, directoryService, null, null)
+ .OfType<Video>()
+ .Select(video =>
{
- filteredFiles = files.Where(i => (i.Attributes & FileAttributes.Directory) != FileAttributes.Directory)
- .ToList();
+ // Try to retrieve it from the db. If we don't find it, use the resolved version
+ var dbItem = GetItemById(video.Id) as Video;
+
+ if (dbItem != null)
+ {
+ video = dbItem;
+ }
+
+ video.ExtraType = ExtraType.Trailer;
- result = resolver.ResolveFiles(filteredFiles.Select(i => i.FullName));
+ return video;
+
+ // Sort them so that the list can be easily compared for changes
+ }).OrderBy(i => i.Path).ToList();
+ }
+
+ private FileInfoType GetFileType(FileSystemInfo info)
+ {
+ if ((info.Attributes & FileAttributes.Directory) == FileAttributes.Directory)
+ {
+ return FileInfoType.Directory;
}
- var stack = result.Stacks
- .FirstOrDefault(i => i.Files.Contains(file, StringComparer.OrdinalIgnoreCase));
+ return FileInfoType.File;
+ }
- if (stack != null)
+ public IEnumerable<Video> FindExtras(BaseItem owner, List<FileSystemInfo> fileSystemChildren, IDirectoryService directoryService)
+ {
+ var files = fileSystemChildren.OfType<DirectoryInfo>()
+ .Where(i => string.Equals(i.Name, "extras", StringComparison.OrdinalIgnoreCase) || string.Equals(i.Name, "specials", StringComparison.OrdinalIgnoreCase))
+ .SelectMany(i => i.EnumerateFiles("*", SearchOption.TopDirectoryOnly))
+ .ToList();
+
+ var videoListResolver = new VideoListResolver(new ExtendedNamingOptions(), new Naming.Logging.NullLogger());
+
+ var videos = videoListResolver.Resolve(fileSystemChildren.Select(i => new PortableFileInfo
{
- return stack.Files.Where(i => !string.Equals(i, file, StringComparison.OrdinalIgnoreCase))
- .Select(i => filteredFiles.FirstOrDefault(f => string.Equals(i, f.FullName, StringComparison.OrdinalIgnoreCase)))
- .Where(i => i != null);
+ FullName = i.FullName,
+ Type = GetFileType(i)
+
+ }).ToList());
+
+ var currentVideo = videos.FirstOrDefault(i => string.Equals(owner.Path, i.Files.First().Path, StringComparison.OrdinalIgnoreCase));
+
+ if (currentVideo != null)
+ {
+ files.AddRange(currentVideo.Extras.Where(i => !string.Equals(i.ExtraType, "trailer", StringComparison.OrdinalIgnoreCase)).Select(i => new FileInfo(i.Path)));
}
- return new List<FileSystemInfo>();
+ return ResolvePaths(files, directoryService, null, null)
+ .OfType<Video>()
+ .Select(video =>
+ {
+ // Try to retrieve it from the db. If we don't find it, use the resolved version
+ var dbItem = GetItemById(video.Id) as Video;
+
+ if (dbItem != null)
+ {
+ video = dbItem;
+ }
+
+ SetExtraTypeFromFilename(video);
+
+ return video;
+
+ // Sort them so that the list can be easily compared for changes
+ }).OrderBy(i => i.Path).ToList();
+ }
+
+ private void SetExtraTypeFromFilename(Video item)
+ {
+ var resolver = new ExtraResolver(new ExtendedNamingOptions(), new Naming.Logging.NullLogger(), new RegexProvider());
+
+ var result = resolver.GetExtraInfo(item.Path);
+
+ if (string.Equals(result.ExtraType, "deletedscene", StringComparison.OrdinalIgnoreCase))
+ {
+ item.ExtraType = ExtraType.DeletedScene;
+ }
+ else if (string.Equals(result.ExtraType, "behindthescenes", StringComparison.OrdinalIgnoreCase))
+ {
+ item.ExtraType = ExtraType.BehindTheScenes;
+ }
+ else if (string.Equals(result.ExtraType, "interview", StringComparison.OrdinalIgnoreCase))
+ {
+ item.ExtraType = ExtraType.Interview;
+ }
+ else if (string.Equals(result.ExtraType, "scene", StringComparison.OrdinalIgnoreCase))
+ {
+ item.ExtraType = ExtraType.Scene;
+ }
+ else if (string.Equals(result.ExtraType, "sample", StringComparison.OrdinalIgnoreCase))
+ {
+ item.ExtraType = ExtraType.Sample;
+ }
+ else
+ {
+ item.ExtraType = ExtraType.Clip;
+ }
}
}
}
diff --git a/MediaBrowser.Server.Implementations/Library/LocalTrailerPostScanTask.cs b/MediaBrowser.Server.Implementations/Library/LocalTrailerPostScanTask.cs
new file mode 100644
index 0000000000..9196bf7340
--- /dev/null
+++ b/MediaBrowser.Server.Implementations/Library/LocalTrailerPostScanTask.cs
@@ -0,0 +1,94 @@
+using System.Collections.Generic;
+using MediaBrowser.Controller.Channels;
+using MediaBrowser.Controller.Entities;
+using MediaBrowser.Controller.Library;
+using MediaBrowser.Model.Channels;
+using MediaBrowser.Model.Entities;
+using System;
+using System.Linq;
+using System.Threading;
+using System.Threading.Tasks;
+
+namespace MediaBrowser.Server.Implementations.Library
+{
+ public class LocalTrailerPostScanTask : ILibraryPostScanTask
+ {
+ private readonly ILibraryManager _libraryManager;
+ private readonly IChannelManager _channelManager;
+
+ public LocalTrailerPostScanTask(ILibraryManager libraryManager, IChannelManager channelManager)
+ {
+ _libraryManager = libraryManager;
+ _channelManager = channelManager;
+ }
+
+ public async Task Run(IProgress<double> progress, CancellationToken cancellationToken)
+ {
+ var items = _libraryManager.RootFolder
+ .RecursiveChildren
+ .OfType<IHasTrailers>()
+ .ToList();
+
+ var channelTrailerResult = await _channelManager.GetAllMediaInternal(new AllChannelMediaQuery
+ {
+ ExtraTypes = new[] { ExtraType.Trailer }
+
+ }, CancellationToken.None);
+ var channelTrailers = channelTrailerResult.Items;
+
+ var numComplete = 0;
+
+ foreach (var item in items)
+ {
+ cancellationToken.ThrowIfCancellationRequested();
+
+ await AssignTrailers(item, channelTrailers).ConfigureAwait(false);
+
+ numComplete++;
+ double percent = numComplete;
+ percent /= items.Count;
+ progress.Report(percent * 100);
+ }
+
+ progress.Report(100);
+ }
+
+ private async Task AssignTrailers(IHasTrailers item, BaseItem[] channelTrailers)
+ {
+ if (item is Game)
+ {
+ return;
+ }
+
+ var imdbId = item.GetProviderId(MetadataProviders.Imdb);
+ var tmdbId = item.GetProviderId(MetadataProviders.Tmdb);
+
+ var trailers = channelTrailers.Where(i =>
+ {
+ if (!string.IsNullOrWhiteSpace(imdbId) &&
+ string.Equals(imdbId, i.GetProviderId(MetadataProviders.Imdb), StringComparison.OrdinalIgnoreCase))
+ {
+ return true;
+ }
+ if (!string.IsNullOrWhiteSpace(tmdbId) &&
+ string.Equals(tmdbId, i.GetProviderId(MetadataProviders.Tmdb), StringComparison.OrdinalIgnoreCase))
+ {
+ return true;
+ }
+ return false;
+ });
+
+ var trailerIds = trailers.Select(i => i.Id)
+ .ToList();
+
+ if (!trailerIds.SequenceEqual(item.RemoteTrailerIds))
+ {
+ item.RemoteTrailerIds = trailerIds;
+
+ var baseItem = (BaseItem)item;
+ await baseItem.UpdateToRepository(ItemUpdateType.MetadataImport, CancellationToken.None)
+ .ConfigureAwait(false);
+ }
+ }
+ }
+}
diff --git a/MediaBrowser.Server.Implementations/Library/MusicManager.cs b/MediaBrowser.Server.Implementations/Library/MusicManager.cs
index 7ffbab860f..b8c29c19ba 100644
--- a/MediaBrowser.Server.Implementations/Library/MusicManager.cs
+++ b/MediaBrowser.Server.Implementations/Library/MusicManager.cs
@@ -1,6 +1,7 @@
using MediaBrowser.Controller.Entities;
using MediaBrowser.Controller.Entities.Audio;
using MediaBrowser.Controller.Library;
+using MediaBrowser.Controller.Playlists;
using System;
using System.Collections.Generic;
using System.Linq;
@@ -53,6 +54,18 @@ namespace MediaBrowser.Server.Implementations.Library
return GetInstantMixFromGenres(genres, user);
}
+ public IEnumerable<Audio> GetInstantMixFromPlaylist(Playlist item, User user)
+ {
+ var genres = item
+ .GetRecursiveChildren(user, true)
+ .OfType<Audio>()
+ .SelectMany(i => i.Genres)
+ .Concat(item.Genres)
+ .Distinct(StringComparer.OrdinalIgnoreCase);
+
+ return GetInstantMixFromGenres(genres, user);
+ }
+
public IEnumerable<Audio> GetInstantMixFromGenres(IEnumerable<string> genres, User user)
{
var inputItems = user.RootFolder.GetRecursiveChildren(user);
diff --git a/MediaBrowser.Server.Implementations/Library/PathExtensions.cs b/MediaBrowser.Server.Implementations/Library/PathExtensions.cs
new file mode 100644
index 0000000000..00bd651252
--- /dev/null
+++ b/MediaBrowser.Server.Implementations/Library/PathExtensions.cs
@@ -0,0 +1,37 @@
+using System;
+
+namespace MediaBrowser.Server.Implementations.Library
+{
+ public static class PathExtensions
+ {
+ /// <summary>
+ /// Gets the attribute value.
+ /// </summary>
+ /// <param name="str">The STR.</param>
+ /// <param name="attrib">The attrib.</param>
+ /// <returns>System.String.</returns>
+ /// <exception cref="System.ArgumentNullException">attrib</exception>
+ public static string GetAttributeValue(this string str, string attrib)
+ {
+ if (string.IsNullOrEmpty(str))
+ {
+ throw new ArgumentNullException("str");
+ }
+
+ if (string.IsNullOrEmpty(attrib))
+ {
+ throw new ArgumentNullException("attrib");
+ }
+
+ string srch = "[" + attrib + "=";
+ int start = str.IndexOf(srch, StringComparison.OrdinalIgnoreCase);
+ if (start > -1)
+ {
+ start += srch.Length;
+ int end = str.IndexOf(']', start);
+ return str.Substring(start, end - start);
+ }
+ return null;
+ }
+ }
+}
diff --git a/MediaBrowser.Server.Implementations/Library/ResolverHelper.cs b/MediaBrowser.Server.Implementations/Library/ResolverHelper.cs
index b9fbd6f8c4..03e28d7ba1 100644
--- a/MediaBrowser.Server.Implementations/Library/ResolverHelper.cs
+++ b/MediaBrowser.Server.Implementations/Library/ResolverHelper.cs
@@ -1,7 +1,7 @@
-using MediaBrowser.Common.Extensions;
-using MediaBrowser.Common.IO;
+using MediaBrowser.Common.IO;
using MediaBrowser.Controller.Entities;
using MediaBrowser.Controller.Library;
+using MediaBrowser.Controller.Providers;
using System;
using System.IO;
using System.Linq;
@@ -18,9 +18,52 @@ namespace MediaBrowser.Server.Implementations.Library
/// Sets the initial item values.
/// </summary>
/// <param name="item">The item.</param>
+ /// <param name="parent">The parent.</param>
+ /// <param name="fileSystem">The file system.</param>
+ /// <param name="libraryManager">The library manager.</param>
+ /// <param name="directoryService">The directory service.</param>
+ /// <exception cref="System.ArgumentException">Item must have a path</exception>
+ public static void SetInitialItemValues(BaseItem item, Folder parent, IFileSystem fileSystem, ILibraryManager libraryManager, IDirectoryService directoryService)
+ {
+ // This version of the below method has no ItemResolveArgs, so we have to require the path already being set
+ if (string.IsNullOrWhiteSpace(item.Path))
+ {
+ throw new ArgumentException("Item must have a Path");
+ }
+
+ // If the resolver didn't specify this
+ if (parent != null)
+ {
+ item.Parent = parent;
+ }
+
+ item.Id = libraryManager.GetNewItemId(item.Path, item.GetType());
+
+ // If the resolver didn't specify this
+ if (string.IsNullOrEmpty(item.DisplayMediaType))
+ {
+ item.DisplayMediaType = item.GetType().Name;
+ }
+
+ item.IsLocked = item.Path.IndexOf("[dontfetchmeta]", StringComparison.OrdinalIgnoreCase) != -1 ||
+ item.Parents.Any(i => i.IsLocked);
+
+ // Make sure DateCreated and DateModified have values
+ var fileInfo = directoryService.GetFile(item.Path);
+ item.DateModified = fileSystem.GetLastWriteTimeUtc(fileInfo);
+ SetDateCreated(item, fileSystem, fileInfo);
+
+ EnsureName(item, fileInfo);
+ }
+
+ /// <summary>
+ /// Sets the initial item values.
+ /// </summary>
+ /// <param name="item">The item.</param>
/// <param name="args">The args.</param>
/// <param name="fileSystem">The file system.</param>
- public static void SetInitialItemValues(BaseItem item, ItemResolveArgs args, IFileSystem fileSystem)
+ /// <param name="libraryManager">The library manager.</param>
+ public static void SetInitialItemValues(BaseItem item, ItemResolveArgs args, IFileSystem fileSystem, ILibraryManager libraryManager)
{
// If the resolver didn't specify this
if (string.IsNullOrEmpty(item.Path))
@@ -34,7 +77,7 @@ namespace MediaBrowser.Server.Implementations.Library
item.Parent = args.Parent;
}
- item.Id = item.Path.GetMBId(item.GetType());
+ item.Id = libraryManager.GetNewItemId(item.Path, item.GetType());
// If the resolver didn't specify this
if (string.IsNullOrEmpty(item.DisplayMediaType))
@@ -43,56 +86,123 @@ namespace MediaBrowser.Server.Implementations.Library
}
// Make sure the item has a name
- EnsureName(item, args);
+ EnsureName(item, args.FileInfo);
item.IsLocked = item.Path.IndexOf("[dontfetchmeta]", StringComparison.OrdinalIgnoreCase) != -1 ||
item.Parents.Any(i => i.IsLocked);
// Make sure DateCreated and DateModified have values
- EntityResolutionHelper.EnsureDates(fileSystem, item, args, true);
+ EnsureDates(fileSystem, item, args, true);
}
/// <summary>
/// Ensures the name.
/// </summary>
/// <param name="item">The item.</param>
- private static void EnsureName(BaseItem item, ItemResolveArgs args)
+ /// <param name="fileInfo">The file information.</param>
+ private static void EnsureName(BaseItem item, FileSystemInfo fileInfo)
{
// If the subclass didn't supply a name, add it here
if (string.IsNullOrEmpty(item.Name) && !string.IsNullOrEmpty(item.Path))
{
- //we use our resolve args name here to get the name of the containg folder, not actual video file
- item.Name = GetMbName(args.FileInfo.Name, (args.FileInfo.Attributes & FileAttributes.Directory) == FileAttributes.Directory);
+ item.Name = GetDisplayName(fileInfo.Name, (fileInfo.Attributes & FileAttributes.Directory) == FileAttributes.Directory);
}
}
/// <summary>
+ /// Gets the display name.
+ /// </summary>
+ /// <param name="path">The path.</param>
+ /// <param name="isDirectory">if set to <c>true</c> [is directory].</param>
+ /// <returns>System.String.</returns>
+ private static string GetDisplayName(string path, bool isDirectory)
+ {
+ return isDirectory ? Path.GetFileName(path) : Path.GetFileNameWithoutExtension(path);
+ }
+
+ /// <summary>
/// The MB name regex
/// </summary>
private static readonly Regex MbNameRegex = new Regex(@"(\[.*?\])", RegexOptions.Compiled);
+ internal static string StripBrackets(string inputString)
+ {
+ var output = MbNameRegex.Replace(inputString, string.Empty).Trim();
+ return Regex.Replace(output, @"\s+", " ");
+ }
+
/// <summary>
- /// Strip out attribute items and return just the name we will use for items
+ /// Ensures DateCreated and DateModified have values
/// </summary>
- /// <param name="path">Assumed to be a file or directory path</param>
- /// <param name="isDirectory">if set to <c>true</c> [is directory].</param>
- /// <returns>The cleaned name</returns>
- private static string GetMbName(string path, bool isDirectory)
+ /// <param name="fileSystem">The file system.</param>
+ /// <param name="item">The item.</param>
+ /// <param name="args">The args.</param>
+ /// <param name="includeCreationTime">if set to <c>true</c> [include creation time].</param>
+ private static void EnsureDates(IFileSystem fileSystem, BaseItem item, ItemResolveArgs args, bool includeCreationTime)
{
- //first just get the file or directory name
- var fn = isDirectory ? Path.GetFileName(path) : Path.GetFileNameWithoutExtension(path);
+ if (fileSystem == null)
+ {
+ throw new ArgumentNullException("fileSystem");
+ }
+ if (item == null)
+ {
+ throw new ArgumentNullException("item");
+ }
+ if (args == null)
+ {
+ throw new ArgumentNullException("args");
+ }
+
+ // See if a different path came out of the resolver than what went in
+ if (!string.Equals(args.Path, item.Path, StringComparison.OrdinalIgnoreCase))
+ {
+ var childData = args.IsDirectory ? args.GetFileSystemEntryByPath(item.Path) : null;
+
+ if (childData != null)
+ {
+ if (includeCreationTime)
+ {
+ SetDateCreated(item, fileSystem, childData);
+ }
- //now - strip out anything inside brackets
- fn = StripBrackets(fn);
+ item.DateModified = fileSystem.GetLastWriteTimeUtc(childData);
+ }
+ else
+ {
+ var fileData = fileSystem.GetFileSystemInfo(item.Path);
- return fn;
+ if (fileData.Exists)
+ {
+ if (includeCreationTime)
+ {
+ SetDateCreated(item, fileSystem, fileData);
+ }
+ item.DateModified = fileSystem.GetLastWriteTimeUtc(fileData);
+ }
+ }
+ }
+ else
+ {
+ if (includeCreationTime)
+ {
+ SetDateCreated(item, fileSystem, args.FileInfo);
+ }
+ item.DateModified = fileSystem.GetLastWriteTimeUtc(args.FileInfo);
+ }
}
- private static string StripBrackets(string inputString)
+ private static void SetDateCreated(BaseItem item, IFileSystem fileSystem, FileSystemInfo info)
{
- var output = MbNameRegex.Replace(inputString, string.Empty).Trim();
- return Regex.Replace(output, @"\s+", " ");
- }
+ var config = BaseItem.ConfigurationManager.GetMetadataConfiguration();
+ if (config.UseFileCreationTimeForDateAdded)
+ {
+ item.DateCreated = fileSystem.GetCreationTimeUtc(info);
+ }
+ else
+ {
+ item.DateCreated = DateTime.UtcNow;
+ }
+ }
}
}
diff --git a/MediaBrowser.Server.Implementations/Library/Resolvers/Audio/AudioResolver.cs b/MediaBrowser.Server.Implementations/Library/Resolvers/Audio/AudioResolver.cs
index 62eb1f47d4..b4cda39cd2 100644
--- a/MediaBrowser.Server.Implementations/Library/Resolvers/Audio/AudioResolver.cs
+++ b/MediaBrowser.Server.Implementations/Library/Resolvers/Audio/AudioResolver.cs
@@ -41,10 +41,19 @@ namespace MediaBrowser.Server.Implementations.Library.Resolvers.Audio
{
var collectionType = args.GetCollectionType();
+ var isMixed = string.IsNullOrWhiteSpace(collectionType);
+
+ // For conflicting extensions, give priority to videos
+ if (isMixed && _libraryManager.IsVideoFile(args.Path))
+ {
+ return null;
+ }
+
var isStandalone = args.Parent == null;
if (isStandalone ||
- string.Equals(collectionType, CollectionType.Music, StringComparison.OrdinalIgnoreCase))
+ string.Equals(collectionType, CollectionType.Music, StringComparison.OrdinalIgnoreCase) ||
+ isMixed)
{
return new Controller.Entities.Audio.Audio();
}
diff --git a/MediaBrowser.Server.Implementations/Library/Resolvers/Audio/MusicAlbumResolver.cs b/MediaBrowser.Server.Implementations/Library/Resolvers/Audio/MusicAlbumResolver.cs
index 5ba07cdaeb..7f844ca0ee 100644
--- a/MediaBrowser.Server.Implementations/Library/Resolvers/Audio/MusicAlbumResolver.cs
+++ b/MediaBrowser.Server.Implementations/Library/Resolvers/Audio/MusicAlbumResolver.cs
@@ -141,12 +141,6 @@ namespace MediaBrowser.Server.Implementations.Library.Resolvers.Audio
if (libraryManager.IsAudioFile(fullName))
{
- // Don't resolve these into audio files
- if (string.Equals(fileSystem.GetFileNameWithoutExtension(fullName), BaseItem.ThemeSongFilename))
- {
- continue;
- }
-
return true;
}
}
diff --git a/MediaBrowser.Server.Implementations/Library/Resolvers/BaseVideoResolver.cs b/MediaBrowser.Server.Implementations/Library/Resolvers/BaseVideoResolver.cs
index 1b49036411..8e2218b0ad 100644
--- a/MediaBrowser.Server.Implementations/Library/Resolvers/BaseVideoResolver.cs
+++ b/MediaBrowser.Server.Implementations/Library/Resolvers/BaseVideoResolver.cs
@@ -1,10 +1,12 @@
using MediaBrowser.Controller.Entities;
using MediaBrowser.Controller.Library;
+using MediaBrowser.Controller.Providers;
using MediaBrowser.Model.Entities;
-using MediaBrowser.Naming.Audio;
using MediaBrowser.Naming.Common;
using MediaBrowser.Naming.Video;
using System;
+using System.IO;
+using System.Linq;
namespace MediaBrowser.Server.Implementations.Library.Resolvers
{
@@ -29,7 +31,7 @@ namespace MediaBrowser.Server.Implementations.Library.Resolvers
/// <returns>`0.</returns>
protected override T Resolve(ItemResolveArgs args)
{
- return ResolveVideo<T>(args);
+ return ResolveVideo<T>(args, false);
}
/// <summary>
@@ -37,14 +39,93 @@ namespace MediaBrowser.Server.Implementations.Library.Resolvers
/// </summary>
/// <typeparam name="TVideoType">The type of the T video type.</typeparam>
/// <param name="args">The args.</param>
+ /// <param name="parseName">if set to <c>true</c> [parse name].</param>
/// <returns>``0.</returns>
- protected TVideoType ResolveVideo<TVideoType>(ItemResolveArgs args)
+ protected TVideoType ResolveVideo<TVideoType>(ItemResolveArgs args, bool parseName)
where TVideoType : Video, new()
{
// If the path is a file check for a matching extensions
- if (!args.IsDirectory)
+ var parser = new Naming.Video.VideoResolver(new ExtendedNamingOptions(), new Naming.Logging.NullLogger());
+
+ if (args.IsDirectory)
+ {
+ TVideoType video = null;
+ VideoFileInfo videoInfo = null;
+
+ // Loop through each child file/folder and see if we find a video
+ foreach (var child in args.FileSystemChildren)
+ {
+ var filename = child.Name;
+
+ if ((child.Attributes & FileAttributes.Directory) == FileAttributes.Directory)
+ {
+ if (IsDvdDirectory(filename))
+ {
+ videoInfo = parser.ResolveDirectory(args.Path);
+
+ if (videoInfo == null)
+ {
+ return null;
+ }
+
+ video = new TVideoType
+ {
+ Path = args.Path,
+ VideoType = VideoType.Dvd,
+ ProductionYear = videoInfo.Year
+ };
+ break;
+ }
+ if (IsBluRayDirectory(filename))
+ {
+ videoInfo = parser.ResolveDirectory(args.Path);
+
+ if (videoInfo == null)
+ {
+ return null;
+ }
+
+ video = new TVideoType
+ {
+ Path = args.Path,
+ VideoType = VideoType.BluRay,
+ ProductionYear = videoInfo.Year
+ };
+ break;
+ }
+ }
+ else if (IsDvdFile(filename))
+ {
+ videoInfo = parser.ResolveDirectory(args.Path);
+
+ if (videoInfo == null)
+ {
+ return null;
+ }
+
+ video = new TVideoType
+ {
+ Path = args.Path,
+ VideoType = VideoType.Dvd,
+ ProductionYear = videoInfo.Year
+ };
+ break;
+ }
+ }
+
+ if (video != null)
+ {
+ video.Name = parseName ?
+ videoInfo.Name :
+ Path.GetFileName(args.Path);
+
+ Set3DFormat(video, videoInfo);
+ }
+
+ return video;
+ }
+ else
{
- var parser = new Naming.Video.VideoResolver(new ExtendedNamingOptions(), new Naming.Logging.NullLogger());
var videoInfo = parser.ResolveFile(args.Path);
if (videoInfo == null)
@@ -52,74 +133,24 @@ namespace MediaBrowser.Server.Implementations.Library.Resolvers
return null;
}
- var isShortcut = string.Equals(videoInfo.Container, "strm", StringComparison.OrdinalIgnoreCase);
-
- if (LibraryManager.IsVideoFile(args.Path) || videoInfo.IsStub || isShortcut)
+ if (LibraryManager.IsVideoFile(args.Path) || videoInfo.IsStub)
{
- var type = string.Equals(videoInfo.Container, "iso", StringComparison.OrdinalIgnoreCase) || string.Equals(videoInfo.Container, "img", StringComparison.OrdinalIgnoreCase) ?
- VideoType.Iso :
- VideoType.VideoFile;
-
var path = args.Path;
var video = new TVideoType
{
- VideoType = type,
Path = path,
IsInMixedFolder = true,
- IsPlaceHolder = videoInfo.IsStub,
- IsShortcut = isShortcut,
- Name = videoInfo.Name,
ProductionYear = videoInfo.Year
};
- if (videoInfo.IsStub)
- {
- if (string.Equals(videoInfo.StubType, "dvd", StringComparison.OrdinalIgnoreCase))
- {
- video.VideoType = VideoType.Dvd;
- }
- else if (string.Equals(videoInfo.StubType, "hddvd", StringComparison.OrdinalIgnoreCase))
- {
- video.VideoType = VideoType.HdDvd;
- }
- else if (string.Equals(videoInfo.StubType, "bluray", StringComparison.OrdinalIgnoreCase))
- {
- video.VideoType = VideoType.BluRay;
- }
- }
+ SetVideoType(video, videoInfo);
+
+ video.Name = parseName ?
+ videoInfo.Name :
+ Path.GetFileNameWithoutExtension(args.Path);
- if (videoInfo.Is3D)
- {
- if (string.Equals(videoInfo.Format3D, "fsbs", StringComparison.OrdinalIgnoreCase))
- {
- video.Video3DFormat = Video3DFormat.FullSideBySide;
- }
- else if (string.Equals(videoInfo.Format3D, "ftab", StringComparison.OrdinalIgnoreCase))
- {
- video.Video3DFormat = Video3DFormat.FullTopAndBottom;
- }
- else if (string.Equals(videoInfo.Format3D, "hsbs", StringComparison.OrdinalIgnoreCase))
- {
- video.Video3DFormat = Video3DFormat.HalfSideBySide;
- }
- else if (string.Equals(videoInfo.Format3D, "htab", StringComparison.OrdinalIgnoreCase))
- {
- video.Video3DFormat = Video3DFormat.HalfTopAndBottom;
- }
- else if (string.Equals(videoInfo.Format3D, "sbs", StringComparison.OrdinalIgnoreCase))
- {
- video.Video3DFormat = Video3DFormat.HalfSideBySide;
- }
- else if (string.Equals(videoInfo.Format3D, "sbs3d", StringComparison.OrdinalIgnoreCase))
- {
- video.Video3DFormat = Video3DFormat.HalfSideBySide;
- }
- else if (string.Equals(videoInfo.Format3D, "tab", StringComparison.OrdinalIgnoreCase))
- {
- video.Video3DFormat = Video3DFormat.HalfTopAndBottom;
- }
- }
+ Set3DFormat(video, videoInfo);
return video;
}
@@ -127,5 +158,111 @@ namespace MediaBrowser.Server.Implementations.Library.Resolvers
return null;
}
+
+ protected void SetVideoType(Video video, VideoFileInfo videoInfo)
+ {
+ var extension = Path.GetExtension(video.Path);
+ video.VideoType = string.Equals(extension, ".iso", StringComparison.OrdinalIgnoreCase) ||
+ string.Equals(extension, ".img", StringComparison.OrdinalIgnoreCase) ?
+ VideoType.Iso :
+ VideoType.VideoFile;
+
+ video.IsShortcut = string.Equals(extension, ".strm", StringComparison.OrdinalIgnoreCase);
+ video.IsPlaceHolder = videoInfo.IsStub;
+
+ if (videoInfo.IsStub)
+ {
+ if (string.Equals(videoInfo.StubType, "dvd", StringComparison.OrdinalIgnoreCase))
+ {
+ video.VideoType = VideoType.Dvd;
+ }
+ else if (string.Equals(videoInfo.StubType, "hddvd", StringComparison.OrdinalIgnoreCase))
+ {
+ video.VideoType = VideoType.HdDvd;
+ }
+ else if (string.Equals(videoInfo.StubType, "bluray", StringComparison.OrdinalIgnoreCase))
+ {
+ video.VideoType = VideoType.BluRay;
+ }
+ }
+ }
+
+ protected void Set3DFormat(Video video, bool is3D, string format3D)
+ {
+ if (is3D)
+ {
+ if (string.Equals(format3D, "fsbs", StringComparison.OrdinalIgnoreCase))
+ {
+ video.Video3DFormat = Video3DFormat.FullSideBySide;
+ }
+ else if (string.Equals(format3D, "ftab", StringComparison.OrdinalIgnoreCase))
+ {
+ video.Video3DFormat = Video3DFormat.FullTopAndBottom;
+ }
+ else if (string.Equals(format3D, "hsbs", StringComparison.OrdinalIgnoreCase))
+ {
+ video.Video3DFormat = Video3DFormat.HalfSideBySide;
+ }
+ else if (string.Equals(format3D, "htab", StringComparison.OrdinalIgnoreCase))
+ {
+ video.Video3DFormat = Video3DFormat.HalfTopAndBottom;
+ }
+ else if (string.Equals(format3D, "sbs", StringComparison.OrdinalIgnoreCase))
+ {
+ video.Video3DFormat = Video3DFormat.HalfSideBySide;
+ }
+ else if (string.Equals(format3D, "sbs3d", StringComparison.OrdinalIgnoreCase))
+ {
+ video.Video3DFormat = Video3DFormat.HalfSideBySide;
+ }
+ else if (string.Equals(format3D, "tab", StringComparison.OrdinalIgnoreCase))
+ {
+ video.Video3DFormat = Video3DFormat.HalfTopAndBottom;
+ }
+ }
+ }
+
+ protected void Set3DFormat(Video video, VideoFileInfo videoInfo)
+ {
+ Set3DFormat(video, videoInfo.Is3D, videoInfo.Format3D);
+ }
+
+ protected void Set3DFormat(Video video)
+ {
+ var resolver = new Format3DParser(new ExtendedNamingOptions(), new Naming.Logging.NullLogger());
+ var result = resolver.Parse(video.Path);
+
+ Set3DFormat(video, result.Is3D, result.Format3D);
+ }
+
+ /// <summary>
+ /// Determines whether [is DVD directory] [the specified directory name].
+ /// </summary>
+ /// <param name="directoryName">Name of the directory.</param>
+ /// <returns><c>true</c> if [is DVD directory] [the specified directory name]; otherwise, <c>false</c>.</returns>
+ protected bool IsDvdDirectory(string directoryName)
+ {
+ return string.Equals(directoryName, "video_ts", StringComparison.OrdinalIgnoreCase);
+ }
+
+ /// <summary>
+ /// Determines whether [is DVD file] [the specified name].
+ /// </summary>
+ /// <param name="name">The name.</param>
+ /// <returns><c>true</c> if [is DVD file] [the specified name]; otherwise, <c>false</c>.</returns>
+ protected bool IsDvdFile(string name)
+ {
+ return string.Equals(name, "video_ts.ifo", StringComparison.OrdinalIgnoreCase);
+ }
+
+ /// <summary>
+ /// Determines whether [is blu ray directory] [the specified directory name].
+ /// </summary>
+ /// <param name="directoryName">Name of the directory.</param>
+ /// <returns><c>true</c> if [is blu ray directory] [the specified directory name]; otherwise, <c>false</c>.</returns>
+ protected bool IsBluRayDirectory(string directoryName)
+ {
+ return string.Equals(directoryName, "bdmv", StringComparison.OrdinalIgnoreCase);
+ }
}
}
diff --git a/MediaBrowser.Server.Implementations/Library/Resolvers/LocalTrailerResolver.cs b/MediaBrowser.Server.Implementations/Library/Resolvers/LocalTrailerResolver.cs
deleted file mode 100644
index dfeefb74fc..0000000000
--- a/MediaBrowser.Server.Implementations/Library/Resolvers/LocalTrailerResolver.cs
+++ /dev/null
@@ -1,61 +0,0 @@
-using MediaBrowser.Common.IO;
-using MediaBrowser.Controller.Entities;
-using MediaBrowser.Controller.Library;
-using MediaBrowser.Controller.Resolvers;
-using MediaBrowser.Model.Entities;
-using System;
-using System.IO;
-using System.Linq;
-
-namespace MediaBrowser.Server.Implementations.Library.Resolvers
-{
- /// <summary>
- /// Class LocalTrailerResolver
- /// </summary>
- public class LocalTrailerResolver : BaseVideoResolver<Trailer>
- {
- private readonly IFileSystem _fileSystem;
-
- public LocalTrailerResolver(ILibraryManager libraryManager, IFileSystem fileSystem) : base(libraryManager)
- {
- _fileSystem = fileSystem;
- }
-
- /// <summary>
- /// Resolves the specified args.
- /// </summary>
- /// <param name="args">The args.</param>
- /// <returns>Trailer.</returns>
- protected override Trailer Resolve(ItemResolveArgs args)
- {
- // Trailers are not Children, therefore this can never happen
- if (args.Parent != null)
- {
- return null;
- }
-
- // If the file is within a trailers folder, see if the VideoResolver returns something
- if (!args.IsDirectory)
- {
- if (string.Equals(Path.GetFileName(Path.GetDirectoryName(args.Path)), BaseItem.TrailerFolderName, StringComparison.OrdinalIgnoreCase))
- {
- return base.Resolve(args);
- }
-
- // Support xbmc local trailer convention, but only when looking for local trailers (hence the parent == null check)
- if (args.Parent == null)
- {
- var nameWithoutExtension = _fileSystem.GetFileNameWithoutExtension(args.Path);
- var suffix = BaseItem.ExtraSuffixes.First(i => i.Value == ExtraType.Trailer);
-
- if (nameWithoutExtension.EndsWith(suffix.Key, StringComparison.OrdinalIgnoreCase))
- {
- return base.Resolve(args);
- }
- }
- }
-
- return null;
- }
- }
-}
diff --git a/MediaBrowser.Server.Implementations/Library/Resolvers/Movies/BoxSetResolver.cs b/MediaBrowser.Server.Implementations/Library/Resolvers/Movies/BoxSetResolver.cs
index 1416bd04ea..cc261c3e7b 100644
--- a/MediaBrowser.Server.Implementations/Library/Resolvers/Movies/BoxSetResolver.cs
+++ b/MediaBrowser.Server.Implementations/Library/Resolvers/Movies/BoxSetResolver.cs
@@ -1,5 +1,4 @@
-using MediaBrowser.Common.Extensions;
-using MediaBrowser.Controller.Entities;
+using MediaBrowser.Controller.Entities;
using MediaBrowser.Controller.Entities.Movies;
using MediaBrowser.Controller.Library;
using MediaBrowser.Model.Entities;
@@ -38,9 +37,14 @@ namespace MediaBrowser.Server.Implementations.Library.Resolvers.Movies
return null;
}
- if (filename.IndexOf("[boxset]", StringComparison.OrdinalIgnoreCase) != -1 || args.ContainsFileSystemEntryByName("collection.xml"))
+ if (filename.IndexOf("[boxset]", StringComparison.OrdinalIgnoreCase) != -1 ||
+ args.ContainsFileSystemEntryByName("collection.xml"))
{
- return new BoxSet { Path = args.Path };
+ return new BoxSet
+ {
+ Path = args.Path,
+ Name = ResolverHelper.StripBrackets(Path.GetFileName(args.Path))
+ };
}
}
diff --git a/MediaBrowser.Server.Implementations/Library/Resolvers/Movies/MovieResolver.cs b/MediaBrowser.Server.Implementations/Library/Resolvers/Movies/MovieResolver.cs
index a2da9ff775..9f714cfc5c 100644
--- a/MediaBrowser.Server.Implementations/Library/Resolvers/Movies/MovieResolver.cs
+++ b/MediaBrowser.Server.Implementations/Library/Resolvers/Movies/MovieResolver.cs
@@ -1,33 +1,34 @@
-using MediaBrowser.Common.Extensions;
-using MediaBrowser.Common.IO;
+using MediaBrowser.Common.IO;
using MediaBrowser.Controller;
using MediaBrowser.Controller.Entities;
using MediaBrowser.Controller.Entities.Movies;
+using MediaBrowser.Controller.Entities.TV;
using MediaBrowser.Controller.Library;
using MediaBrowser.Controller.Providers;
using MediaBrowser.Controller.Resolvers;
using MediaBrowser.Model.Entities;
using MediaBrowser.Model.Logging;
+using MediaBrowser.Naming.Common;
+using MediaBrowser.Naming.IO;
+using MediaBrowser.Naming.Video;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
-using MediaBrowser.Naming.Audio;
-using MediaBrowser.Naming.Common;
-using MediaBrowser.Naming.Video;
namespace MediaBrowser.Server.Implementations.Library.Resolvers.Movies
{
/// <summary>
/// Class MovieResolver
/// </summary>
- public class MovieResolver : BaseVideoResolver<Video>
+ public class MovieResolver : BaseVideoResolver<Video>, IMultiItemResolver
{
private readonly IServerApplicationPaths _applicationPaths;
private readonly ILogger _logger;
private readonly IFileSystem _fileSystem;
- public MovieResolver(ILibraryManager libraryManager, IServerApplicationPaths applicationPaths, ILogger logger, IFileSystem fileSystem) : base(libraryManager)
+ public MovieResolver(ILibraryManager libraryManager, IServerApplicationPaths applicationPaths, ILogger logger, IFileSystem fileSystem)
+ : base(libraryManager)
{
_applicationPaths = applicationPaths;
_logger = logger;
@@ -45,93 +46,189 @@ namespace MediaBrowser.Server.Implementations.Library.Resolvers.Movies
// Give plugins a chance to catch iso's first
// Also since we have to loop through child files looking for videos,
// see if we can avoid some of that by letting other resolvers claim folders first
- return ResolverPriority.Second;
+ // Also run after series resolver
+ return ResolverPriority.Third;
}
}
- /// <summary>
- /// Resolves the specified args.
- /// </summary>
- /// <param name="args">The args.</param>
- /// <returns>Video.</returns>
- protected override Video Resolve(ItemResolveArgs args)
+ public MultiItemResolverResult ResolveMultiple(Folder parent,
+ List<FileSystemInfo> files,
+ string collectionType,
+ IDirectoryService directoryService)
{
- // Avoid expensive tests against VF's and all their children by not allowing this
- if (args.Parent != null)
+ if (IsInvalid(parent, collectionType, files))
+ {
+ return null;
+ }
+
+ if (string.Equals(collectionType, CollectionType.MusicVideos, StringComparison.OrdinalIgnoreCase))
+ {
+ return ResolveVideos<MusicVideo>(parent, files, directoryService, collectionType);
+ }
+
+ if (string.Equals(collectionType, CollectionType.HomeVideos, StringComparison.OrdinalIgnoreCase))
+ {
+ return ResolveVideos<Video>(parent, files, directoryService, collectionType);
+ }
+
+ if (string.IsNullOrEmpty(collectionType))
{
- if (args.Parent.IsRoot)
+ // Owned items should just use the plain video type
+ if (parent == null)
{
- return null;
+ return ResolveVideos<Video>(parent, files, directoryService, collectionType);
}
+
+ return ResolveVideos<Movie>(parent, files, directoryService, collectionType);
+ }
+
+ if (string.Equals(collectionType, CollectionType.Movies, StringComparison.OrdinalIgnoreCase) ||
+ string.Equals(collectionType, CollectionType.BoxSets, StringComparison.OrdinalIgnoreCase))
+ {
+ return ResolveVideos<Movie>(parent, files, directoryService, collectionType);
}
- var isDirectory = args.IsDirectory;
+ return null;
+ }
+
+ private MultiItemResolverResult ResolveVideos<T>(Folder parent, IEnumerable<FileSystemInfo> fileSystemEntries, IDirectoryService directoryService, string collectionType)
+ where T : Video, new()
+ {
+ var files = new List<FileSystemInfo>();
+ var videos = new List<BaseItem>();
+ var leftOver = new List<FileSystemInfo>();
- if (isDirectory)
+ // Loop through each child file/folder and see if we find a video
+ foreach (var child in fileSystemEntries)
{
- // Since the looping is expensive, this is an optimization to help us avoid it
- if (args.ContainsMetaFileByName("series.xml"))
+ if ((child.Attributes & FileAttributes.Directory) == FileAttributes.Directory)
+ {
+ leftOver.Add(child);
+ }
+ else
{
- return null;
+ files.Add(child);
}
}
+ var resolver = new VideoListResolver(new ExtendedNamingOptions(), new Naming.Logging.NullLogger());
+ var resolverResult = resolver.Resolve(files.Select(i => new PortableFileInfo
+ {
+ FullName = i.FullName,
+ Type = FileInfoType.File
+
+ }).ToList()).ToList();
+
+ var result = new MultiItemResolverResult
+ {
+ ExtraFiles = leftOver,
+ Items = videos
+ };
+
+ var isInMixedFolder = resolverResult.Count > 0;
+
+ foreach (var video in resolverResult)
+ {
+ var firstVideo = video.Files.First();
+
+ var videoItem = new T
+ {
+ Path = video.Files[0].Path,
+ IsInMixedFolder = isInMixedFolder,
+ ProductionYear = video.Year,
+ Name = video.Name,
+ AdditionalParts = video.Files.Skip(1).Select(i => i.Path).ToList()
+ };
+
+ SetVideoType(videoItem, firstVideo);
+ Set3DFormat(videoItem, firstVideo);
+
+ result.Items.Add(videoItem);
+ }
+
+ return result;
+ }
+
+ /// <summary>
+ /// Resolves the specified args.
+ /// </summary>
+ /// <param name="args">The args.</param>
+ /// <returns>Video.</returns>
+ protected override Video Resolve(ItemResolveArgs args)
+ {
var collectionType = args.GetCollectionType();
+ if (IsInvalid(args.Parent, collectionType, args.FileSystemChildren))
+ {
+ return null;
+ }
+
// Find movies with their own folders
- if (isDirectory)
+ if (args.IsDirectory)
{
- if (string.Equals(collectionType, CollectionType.Trailers, StringComparison.OrdinalIgnoreCase))
+ if (string.Equals(collectionType, CollectionType.MusicVideos, StringComparison.OrdinalIgnoreCase))
{
- return FindMovie<Trailer>(args.Path, args.Parent, args.FileSystemChildren.ToList(), args.DirectoryService, false, false, collectionType);
+ return FindMovie<MusicVideo>(args.Path, args.Parent, args.FileSystemChildren.ToList(), args.DirectoryService, collectionType, false);
}
- if (string.Equals(collectionType, CollectionType.MusicVideos, StringComparison.OrdinalIgnoreCase))
+ if (string.Equals(collectionType, CollectionType.HomeVideos, StringComparison.OrdinalIgnoreCase))
{
- return FindMovie<MusicVideo>(args.Path, args.Parent, args.FileSystemChildren.ToList(), args.DirectoryService, false, false, collectionType);
+ return FindMovie<Video>(args.Path, args.Parent, args.FileSystemChildren.ToList(), args.DirectoryService, collectionType, false);
}
- if (string.Equals(collectionType, CollectionType.HomeVideos, StringComparison.OrdinalIgnoreCase))
+ if (string.IsNullOrEmpty(collectionType))
{
- return FindMovie<Video>(args.Path, args.Parent, args.FileSystemChildren.ToList(), args.DirectoryService, true, false, collectionType);
+ // Owned items should just use the plain video type
+ if (args.Parent == null)
+ {
+ return FindMovie<Video>(args.Path, args.Parent, args.FileSystemChildren.ToList(), args.DirectoryService, collectionType);
+ }
+
+ // Since the looping is expensive, this is an optimization to help us avoid it
+ if (args.ContainsMetaFileByName("series.xml"))
+ {
+ return null;
+ }
+
+ return FindMovie<Movie>(args.Path, args.Parent, args.FileSystemChildren.ToList(), args.DirectoryService, collectionType);
}
- if (string.IsNullOrEmpty(collectionType) ||
- string.Equals(collectionType, CollectionType.Movies, StringComparison.OrdinalIgnoreCase) ||
- string.Equals(collectionType, CollectionType.BoxSets, StringComparison.OrdinalIgnoreCase))
+ if (string.Equals(collectionType, CollectionType.Movies, StringComparison.OrdinalIgnoreCase) ||
+ string.Equals(collectionType, CollectionType.BoxSets, StringComparison.OrdinalIgnoreCase))
{
- return FindMovie<Movie>(args.Path, args.Parent, args.FileSystemChildren.ToList(), args.DirectoryService, true, true, collectionType);
+ return FindMovie<Movie>(args.Path, args.Parent, args.FileSystemChildren.ToList(), args.DirectoryService, collectionType);
}
return null;
}
- var filename = Path.GetFileName(args.Path);
- // Don't misidentify extras or trailers
- if (BaseItem.ExtraSuffixes.Any(i => filename.IndexOf(i.Key, StringComparison.OrdinalIgnoreCase) != -1))
+ // Owned items will be caught by the plain video resolver
+ if (args.Parent == null)
{
return null;
}
- // Find movies that are mixed in the same folder
- if (string.Equals(collectionType, CollectionType.Trailers, StringComparison.OrdinalIgnoreCase))
- {
- return ResolveVideo<Trailer>(args);
- }
-
Video item = null;
if (string.Equals(collectionType, CollectionType.MusicVideos, StringComparison.OrdinalIgnoreCase))
{
- item = ResolveVideo<MusicVideo>(args);
+ item = ResolveVideo<MusicVideo>(args, false);
}
// To find a movie file, the collection type must be movies or boxsets
- // Otherwise we'll consider it a plain video and let the video resolver handle it
- if (string.Equals(collectionType, CollectionType.Movies, StringComparison.OrdinalIgnoreCase) ||
+ else if (string.Equals(collectionType, CollectionType.Movies, StringComparison.OrdinalIgnoreCase) ||
string.Equals(collectionType, CollectionType.BoxSets, StringComparison.OrdinalIgnoreCase))
{
- item = ResolveVideo<Movie>(args);
+ item = ResolveVideo<Movie>(args, true);
+ }
+
+ else if (string.Equals(collectionType, CollectionType.HomeVideos, StringComparison.OrdinalIgnoreCase))
+ {
+ item = ResolveVideo<Video>(args, false);
+ }
+ else if (string.IsNullOrEmpty(collectionType))
+ {
+ item = ResolveVideo<Movie>(args, false);
}
if (item != null)
@@ -179,16 +276,15 @@ namespace MediaBrowser.Server.Implementations.Library.Resolvers.Movies
/// <param name="parent">The parent.</param>
/// <param name="fileSystemEntries">The file system entries.</param>
/// <param name="directoryService">The directory service.</param>
- /// <param name="supportMultiFileItems">if set to <c>true</c> [support multi file items].</param>
+ /// <param name="collectionType">Type of the collection.</param>
+ /// <param name="supportMultiVersion">if set to <c>true</c> [support multi version].</param>
/// <returns>Movie.</returns>
- private T FindMovie<T>(string path, Folder parent, List<FileSystemInfo> fileSystemEntries, IDirectoryService directoryService, bool supportMultiFileItems, bool supportsMultipleSources, string collectionType)
+ private T FindMovie<T>(string path, Folder parent, List<FileSystemInfo> fileSystemEntries, IDirectoryService directoryService, string collectionType, bool supportMultiVersion = true)
where T : Video, new()
{
- var movies = new List<T>();
-
var multiDiscFolders = new List<FileSystemInfo>();
-
- // Loop through each child file/folder and see if we find a video
+
+ // Search for a folder rip
foreach (var child in fileSystemEntries)
{
var filename = child.Name;
@@ -197,78 +293,70 @@ namespace MediaBrowser.Server.Implementations.Library.Resolvers.Movies
{
if (IsDvdDirectory(filename))
{
- return new T
+ var movie = new T
{
Path = path,
VideoType = VideoType.Dvd
};
+ Set3DFormat(movie);
+ return movie;
}
if (IsBluRayDirectory(filename))
{
- return new T
+ var movie = new T
{
Path = path,
VideoType = VideoType.BluRay
};
+ Set3DFormat(movie);
+ return movie;
}
multiDiscFolders.Add(child);
-
- continue;
}
-
- // Don't misidentify extras or trailers as a movie
- if (BaseItem.ExtraSuffixes.Any(i => filename.IndexOf(i.Key, StringComparison.OrdinalIgnoreCase) != -1))
- {
- continue;
- }
-
- var childArgs = new ItemResolveArgs(_applicationPaths, LibraryManager, directoryService)
+ else if (IsDvdFile(filename))
{
- FileInfo = child,
- Path = child.FullName,
- Parent = parent,
- CollectionType = collectionType
- };
-
- var item = ResolveVideo<T>(childArgs);
-
- if (item != null)
- {
- item.IsInMixedFolder = false;
- movies.Add(item);
+ var movie = new T
+ {
+ Path = path,
+ VideoType = VideoType.Dvd
+ };
+ Set3DFormat(movie);
+ return movie;
}
}
+
+ var result = ResolveVideos<T>(parent, fileSystemEntries, directoryService, collectionType);
- if (movies.Count > 1)
+ // Test for multi-editions
+ if (result.Items.Count > 1 && supportMultiVersion)
{
- if (supportMultiFileItems)
- {
- var result = GetMultiFileMovie(movies);
+ var filenamePrefix = Path.GetFileName(path);
- if (result != null)
- {
- return result;
- }
- }
- if (supportsMultipleSources)
+ if (!string.IsNullOrWhiteSpace(filenamePrefix))
{
- var result = GetMovieWithMultipleSources(movies);
-
- if (result != null)
+ if (result.Items.All(i => _fileSystem.GetFileNameWithoutExtension(i.Path).StartsWith(filenamePrefix + " - ", StringComparison.OrdinalIgnoreCase)))
{
- return result;
+ var movie = (T)result.Items[0];
+ movie.Name = filenamePrefix;
+ movie.LocalAlternateVersions = result.Items.Skip(1).Select(i => i.Path).ToList();
+ movie.IsInMixedFolder = false;
+
+ _logger.Debug("Multi-version video found: " + movie.Path);
+
+ return movie;
}
}
- return null;
}
- if (movies.Count == 1)
+ if (result.Items.Count == 1)
{
- return movies[0];
+ var movie = (T)result.Items[0];
+ movie.IsInMixedFolder = false;
+ return movie;
}
- if (multiDiscFolders.Count > 0)
+ if (result.Items.Count == 0 && multiDiscFolders.Count > 0)
{
return GetMultiDiscMovie<T>(multiDiscFolders, directoryService);
}
@@ -290,7 +378,11 @@ namespace MediaBrowser.Server.Implementations.Library.Resolvers.Movies
var folderPaths = multiDiscFolders.Select(i => i.FullName).Where(i =>
{
- var subfolders = directoryService.GetDirectories(i)
+ var subFileEntries = directoryService.GetFileSystemEntries(i)
+ .ToList();
+
+ var subfolders = subFileEntries
+ .Where(e => (e.Attributes & FileAttributes.Directory) == FileAttributes.Directory)
.Select(d => d.Name)
.ToList();
@@ -305,6 +397,16 @@ namespace MediaBrowser.Server.Implementations.Library.Resolvers.Movies
return true;
}
+ var subFiles = subFileEntries
+ .Where(e => (e.Attributes & FileAttributes.Directory) != FileAttributes.Directory)
+ .Select(d => d.Name);
+
+ if (subFiles.Any(IsDvdFile))
+ {
+ videoTypes.Add(VideoType.Dvd);
+ return true;
+ }
+
return false;
}).OrderBy(i => i).ToList();
@@ -328,12 +430,12 @@ namespace MediaBrowser.Server.Implementations.Library.Resolvers.Movies
{
return null;
}
-
+
return new T
{
Path = folderPaths[0],
- IsMultiPart = true,
+ AdditionalParts = folderPaths.Skip(1).ToList(),
VideoType = videoTypes[0],
@@ -341,85 +443,42 @@ namespace MediaBrowser.Server.Implementations.Library.Resolvers.Movies
};
}
- /// <summary>
- /// Gets the multi file movie.
- /// </summary>
- /// <typeparam name="T"></typeparam>
- /// <param name="movies">The movies.</param>
- /// <returns>``0.</returns>
- private T GetMultiFileMovie<T>(IEnumerable<T> movies)
- where T : Video, new()
+ private bool IsInvalid(Folder parent, string collectionType, IEnumerable<FileSystemInfo> files)
{
- var sortedMovies = movies.OrderBy(i => i.Path).ToList();
-
- var firstMovie = sortedMovies[0];
-
- var paths = sortedMovies.Select(i => i.Path).ToList();
-
- var resolver = new StackResolver(new ExtendedNamingOptions(), new Naming.Logging.NullLogger());
-
- var result = resolver.ResolveFiles(paths);
-
- if (result.Stacks.Count != 1)
- {
- return null;
- }
-
- firstMovie.IsMultiPart = true;
- firstMovie.Name = result.Stacks[0].Name;
-
- // They must all be part of the sequence if we're going to consider it a multi-part movie
- return firstMovie;
- }
-
- private T GetMovieWithMultipleSources<T>(IEnumerable<T> movies)
- where T : Video, new()
- {
- var sortedMovies = movies.OrderBy(i => i.Path).ToList();
-
- // Cap this at five to help avoid incorrect matching
- if (sortedMovies.Count > 5)
+ if (parent != null)
{
- return null;
+ if (parent.IsRoot)
+ {
+ return true;
+ }
}
- var firstMovie = sortedMovies[0];
-
- var filenamePrefix = Path.GetFileName(Path.GetDirectoryName(firstMovie.Path));
-
- if (!string.IsNullOrWhiteSpace(filenamePrefix))
+ // Don't do any resolving within a series structure
+ if (string.IsNullOrEmpty(collectionType))
{
- if (sortedMovies.All(i => _fileSystem.GetFileNameWithoutExtension(i.Path).StartsWith(filenamePrefix + " - ", StringComparison.OrdinalIgnoreCase)))
+ if (parent is Season || parent is Series)
{
- firstMovie.HasLocalAlternateVersions = true;
-
- _logger.Debug("Multi-version video found: " + firstMovie.Path);
+ return true;
+ }
- return firstMovie;
+ // Since the looping is expensive, this is an optimization to help us avoid it
+ if (files.Select(i => i.Name).Contains("series.xml", StringComparer.OrdinalIgnoreCase))
+ {
+ return true;
}
}
- return null;
- }
-
- /// <summary>
- /// Determines whether [is DVD directory] [the specified directory name].
- /// </summary>
- /// <param name="directoryName">Name of the directory.</param>
- /// <returns><c>true</c> if [is DVD directory] [the specified directory name]; otherwise, <c>false</c>.</returns>
- private bool IsDvdDirectory(string directoryName)
- {
- return string.Equals(directoryName, "video_ts", StringComparison.OrdinalIgnoreCase);
- }
+ var validCollectionTypes = new[]
+ {
+ string.Empty,
+ CollectionType.Movies,
+ CollectionType.HomeVideos,
+ CollectionType.MusicVideos,
+ CollectionType.BoxSets,
+ CollectionType.Movies
+ };
- /// <summary>
- /// Determines whether [is blu ray directory] [the specified directory name].
- /// </summary>
- /// <param name="directoryName">Name of the directory.</param>
- /// <returns><c>true</c> if [is blu ray directory] [the specified directory name]; otherwise, <c>false</c>.</returns>
- private bool IsBluRayDirectory(string directoryName)
- {
- return string.Equals(directoryName, "bdmv", StringComparison.OrdinalIgnoreCase);
+ return !validCollectionTypes.Contains(collectionType ?? string.Empty, StringComparer.OrdinalIgnoreCase);
}
}
}
diff --git a/MediaBrowser.Server.Implementations/Library/Resolvers/PhotoResolver.cs b/MediaBrowser.Server.Implementations/Library/Resolvers/PhotoResolver.cs
index e3fe37be87..5580b442cb 100644
--- a/MediaBrowser.Server.Implementations/Library/Resolvers/PhotoResolver.cs
+++ b/MediaBrowser.Server.Implementations/Library/Resolvers/PhotoResolver.cs
@@ -17,7 +17,9 @@ namespace MediaBrowser.Server.Implementations.Library.Resolvers
protected override Photo Resolve(ItemResolveArgs args)
{
// Must be an image file within a photo collection
- if (!args.IsDirectory && IsImageFile(args.Path) && string.Equals(args.GetCollectionType(), CollectionType.Photos, StringComparison.OrdinalIgnoreCase))
+ if (!args.IsDirectory &&
+ string.Equals(args.GetCollectionType(), CollectionType.Photos, StringComparison.OrdinalIgnoreCase) &&
+ IsImageFile(args.Path))
{
return new Photo
{
diff --git a/MediaBrowser.Server.Implementations/Library/Resolvers/PlaylistResolver.cs b/MediaBrowser.Server.Implementations/Library/Resolvers/PlaylistResolver.cs
index 7eff53ce1f..a95739f227 100644
--- a/MediaBrowser.Server.Implementations/Library/Resolvers/PlaylistResolver.cs
+++ b/MediaBrowser.Server.Implementations/Library/Resolvers/PlaylistResolver.cs
@@ -28,7 +28,11 @@ namespace MediaBrowser.Server.Implementations.Library.Resolvers
if (filename.IndexOf("[playlist]", StringComparison.OrdinalIgnoreCase) != -1)
{
- return new Playlist { Path = args.Path };
+ return new Playlist
+ {
+ Path = args.Path,
+ Name = ResolverHelper.StripBrackets(Path.GetFileName(args.Path))
+ };
}
}
diff --git a/MediaBrowser.Server.Implementations/Library/Resolvers/TV/EpisodeResolver.cs b/MediaBrowser.Server.Implementations/Library/Resolvers/TV/EpisodeResolver.cs
index 839b14a9e1..057425ca90 100644
--- a/MediaBrowser.Server.Implementations/Library/Resolvers/TV/EpisodeResolver.cs
+++ b/MediaBrowser.Server.Implementations/Library/Resolvers/TV/EpisodeResolver.cs
@@ -1,7 +1,5 @@
using MediaBrowser.Controller.Entities.TV;
using MediaBrowser.Controller.Library;
-using MediaBrowser.Controller.Resolvers;
-using MediaBrowser.Model.Entities;
using System.Linq;
namespace MediaBrowser.Server.Implementations.Library.Resolvers.TV
@@ -41,39 +39,10 @@ namespace MediaBrowser.Server.Implementations.Library.Resolvers.TV
// If the parent is a Season or Series, then this is an Episode if the VideoResolver returns something
if (season != null || parent is Series || parent.Parents.OfType<Series>().Any())
{
- Episode episode = null;
-
- if (args.IsDirectory)
- {
- if (args.ContainsFileSystemEntryByName("video_ts"))
- {
- episode = new Episode
- {
- Path = args.Path,
- VideoType = VideoType.Dvd
- };
- }
- if (args.ContainsFileSystemEntryByName("bdmv"))
- {
- episode = new Episode
- {
- Path = args.Path,
- VideoType = VideoType.BluRay
- };
- }
- }
-
- if (episode == null)
- {
- episode = base.Resolve(args);
- }
+ var episode = ResolveVideo<Episode>(args, false);
if (episode != null)
{
- // The base video resolver is going to fill these in, so null them out
- episode.ProductionYear = null;
- episode.Name = null;
-
if (season != null)
{
episode.ParentIndexNumber = season.IndexNumber;
diff --git a/MediaBrowser.Server.Implementations/Library/Resolvers/TV/SeriesResolver.cs b/MediaBrowser.Server.Implementations/Library/Resolvers/TV/SeriesResolver.cs
index 30eaf3198d..ce74915248 100644
--- a/MediaBrowser.Server.Implementations/Library/Resolvers/TV/SeriesResolver.cs
+++ b/MediaBrowser.Server.Implementations/Library/Resolvers/TV/SeriesResolver.cs
@@ -1,5 +1,4 @@
-using MediaBrowser.Common.Extensions;
-using MediaBrowser.Common.IO;
+using MediaBrowser.Common.IO;
using MediaBrowser.Controller.Entities;
using MediaBrowser.Controller.Entities.Audio;
using MediaBrowser.Controller.Entities.TV;
@@ -81,7 +80,11 @@ namespace MediaBrowser.Server.Implementations.Library.Resolvers.TV
if (IsSeriesFolder(args.Path, isTvShowsFolder, args.FileSystemChildren, args.DirectoryService, _fileSystem, _logger, _libraryManager))
{
- return new Series();
+ return new Series
+ {
+ Path = args.Path,
+ Name = Path.GetFileName(args.Path)
+ };
}
}
@@ -96,12 +99,11 @@ namespace MediaBrowser.Server.Implementations.Library.Resolvers.TV
/// <param name="fileSystemChildren">The file system children.</param>
/// <param name="directoryService">The directory service.</param>
/// <param name="fileSystem">The file system.</param>
+ /// <param name="logger">The logger.</param>
+ /// <param name="libraryManager">The library manager.</param>
/// <returns><c>true</c> if [is series folder] [the specified path]; otherwise, <c>false</c>.</returns>
public static bool IsSeriesFolder(string path, bool considerSeasonlessEntries, IEnumerable<FileSystemInfo> fileSystemChildren, IDirectoryService directoryService, IFileSystem fileSystem, ILogger logger, ILibraryManager libraryManager)
{
- // A folder with more than 3 non-season folders in will not becounted as a series
- var nonSeriesFolders = 0;
-
foreach (var child in fileSystemChildren)
{
var attributes = child.Attributes;
@@ -126,19 +128,6 @@ namespace MediaBrowser.Server.Implementations.Library.Resolvers.TV
//logger.Debug("{0} is a series because of season folder {1}.", path, child.FullName);
return true;
}
-
- if (IsBadFolder(child.Name))
- {
- logger.Debug("Invalid folder under series: {0}", child.FullName);
-
- nonSeriesFolders++;
- }
-
- if (nonSeriesFolders >= 3)
- {
- logger.Debug("{0} not a series due to 3 or more invalid folders.", path);
- return false;
- }
}
else
{
@@ -176,24 +165,6 @@ namespace MediaBrowser.Server.Implementations.Library.Resolvers.TV
return string.Equals(extension, ".disc", StringComparison.OrdinalIgnoreCase);
}
- private static bool IsBadFolder(string name)
- {
- if (string.Equals(name, BaseItem.ThemeSongsFolderName, StringComparison.OrdinalIgnoreCase))
- {
- return false;
- }
- if (string.Equals(name, BaseItem.ThemeVideosFolderName, StringComparison.OrdinalIgnoreCase))
- {
- return false;
- }
- if (string.Equals(name, BaseItem.TrailerFolderName, StringComparison.OrdinalIgnoreCase))
- {
- return false;
- }
-
- return !EntityResolutionHelper.IgnoreFolders.Contains(name, StringComparer.OrdinalIgnoreCase);
- }
-
/// <summary>
/// Determines whether [is season folder] [the specified path].
/// </summary>
diff --git a/MediaBrowser.Server.Implementations/Library/Resolvers/VideoResolver.cs b/MediaBrowser.Server.Implementations/Library/Resolvers/VideoResolver.cs
index cde75aea29..97682db66f 100644
--- a/MediaBrowser.Server.Implementations/Library/Resolvers/VideoResolver.cs
+++ b/MediaBrowser.Server.Implementations/Library/Resolvers/VideoResolver.cs
@@ -1,9 +1,6 @@
using MediaBrowser.Controller.Entities;
using MediaBrowser.Controller.Library;
using MediaBrowser.Controller.Resolvers;
-using MediaBrowser.Model.Entities;
-using System;
-using System.Linq;
namespace MediaBrowser.Server.Implementations.Library.Resolvers
{
@@ -21,17 +18,8 @@ namespace MediaBrowser.Server.Implementations.Library.Resolvers
{
if (args.Parent != null)
{
- var collectionType = args.GetCollectionType() ?? string.Empty;
- var accepted = new[]
- {
- string.Empty,
- CollectionType.HomeVideos
- };
-
- if (!accepted.Contains(collectionType, StringComparer.OrdinalIgnoreCase))
- {
- return null;
- }
+ // The movie resolver will handle this
+ return null;
}
return base.Resolve(args);
@@ -46,6 +34,4 @@ namespace MediaBrowser.Server.Implementations.Library.Resolvers
get { return ResolverPriority.Last; }
}
}
-
-
}
diff --git a/MediaBrowser.Server.Implementations/Library/UserManager.cs b/MediaBrowser.Server.Implementations/Library/UserManager.cs
index 54c584d47f..ed45e890bf 100644
--- a/MediaBrowser.Server.Implementations/Library/UserManager.cs
+++ b/MediaBrowser.Server.Implementations/Library/UserManager.cs
@@ -17,6 +17,7 @@ using MediaBrowser.Model.Dto;
using MediaBrowser.Model.Entities;
using MediaBrowser.Model.Events;
using MediaBrowser.Model.Logging;
+using MediaBrowser.Model.Querying;
using MediaBrowser.Model.Serialization;
using MediaBrowser.Model.Users;
using System;
@@ -327,7 +328,10 @@ namespace MediaBrowser.Server.Implementations.Library
try
{
- _dtoServiceFactory().AttachPrimaryImageAspectRatio(dto, user);
+ _dtoServiceFactory().AttachPrimaryImageAspectRatio(dto, user, new List<ItemFields>
+ {
+ ItemFields.PrimaryImageAspectRatio
+ });
}
catch (Exception ex)
{
@@ -765,5 +769,14 @@ namespace MediaBrowser.Server.Implementations.Library
public DateTime ExpirationDate { get; set; }
}
+ public UserPolicy GetUserPolicy(string userId)
+ {
+ throw new NotImplementedException();
+ }
+
+ public Task UpdateUserPolicy(string userId, UserPolicy userPolicy)
+ {
+ throw new NotImplementedException();
+ }
}
}
diff --git a/MediaBrowser.Server.Implementations/Library/Validators/ArtistsPostScanTask.cs b/MediaBrowser.Server.Implementations/Library/Validators/ArtistsPostScanTask.cs
index 575ffec143..60116ac617 100644
--- a/MediaBrowser.Server.Implementations/Library/Validators/ArtistsPostScanTask.cs
+++ b/MediaBrowser.Server.Implementations/Library/Validators/ArtistsPostScanTask.cs
@@ -32,7 +32,7 @@ namespace MediaBrowser.Server.Implementations.Library.Validators
/// <returns>Task.</returns>
public Task Run(IProgress<double> progress, CancellationToken cancellationToken)
{
- return _libraryManager.ValidateArtists(cancellationToken, progress);
+ return ((LibraryManager)_libraryManager).ValidateArtists(cancellationToken, progress);
}
}
}
diff --git a/MediaBrowser.Server.Implementations/Library/Validators/GameGenresPostScanTask.cs b/MediaBrowser.Server.Implementations/Library/Validators/GameGenresPostScanTask.cs
index 097e94216e..ae6c863a71 100644
--- a/MediaBrowser.Server.Implementations/Library/Validators/GameGenresPostScanTask.cs
+++ b/MediaBrowser.Server.Implementations/Library/Validators/GameGenresPostScanTask.cs
@@ -32,7 +32,7 @@ namespace MediaBrowser.Server.Implementations.Library.Validators
/// <returns>Task.</returns>
public Task Run(IProgress<double> progress, CancellationToken cancellationToken)
{
- return _libraryManager.ValidateGameGenres(cancellationToken, progress);
+ return ((LibraryManager)_libraryManager).ValidateGameGenres(cancellationToken, progress);
}
}
}
diff --git a/MediaBrowser.Server.Implementations/Library/Validators/GenresPostScanTask.cs b/MediaBrowser.Server.Implementations/Library/Validators/GenresPostScanTask.cs
index d7add8574d..f1d0ef3706 100644
--- a/MediaBrowser.Server.Implementations/Library/Validators/GenresPostScanTask.cs
+++ b/MediaBrowser.Server.Implementations/Library/Validators/GenresPostScanTask.cs
@@ -29,7 +29,7 @@ namespace MediaBrowser.Server.Implementations.Library.Validators
/// <returns>Task.</returns>
public Task Run(IProgress<double> progress, CancellationToken cancellationToken)
{
- return _libraryManager.ValidateGenres(cancellationToken, progress);
+ return ((LibraryManager)_libraryManager).ValidateGenres(cancellationToken, progress);
}
}
}
diff --git a/MediaBrowser.Server.Implementations/Library/Validators/MusicGenresPostScanTask.cs b/MediaBrowser.Server.Implementations/Library/Validators/MusicGenresPostScanTask.cs
index da378228ad..280dd90f46 100644
--- a/MediaBrowser.Server.Implementations/Library/Validators/MusicGenresPostScanTask.cs
+++ b/MediaBrowser.Server.Implementations/Library/Validators/MusicGenresPostScanTask.cs
@@ -32,7 +32,7 @@ namespace MediaBrowser.Server.Implementations.Library.Validators
/// <returns>Task.</returns>
public Task Run(IProgress<double> progress, CancellationToken cancellationToken)
{
- return _libraryManager.ValidateMusicGenres(cancellationToken, progress);
+ return ((LibraryManager)_libraryManager).ValidateMusicGenres(cancellationToken, progress);
}
}
}
diff --git a/MediaBrowser.Server.Implementations/Library/Validators/StudiosPostScanTask.cs b/MediaBrowser.Server.Implementations/Library/Validators/StudiosPostScanTask.cs
index a3a8b86781..0f998b0708 100644
--- a/MediaBrowser.Server.Implementations/Library/Validators/StudiosPostScanTask.cs
+++ b/MediaBrowser.Server.Implementations/Library/Validators/StudiosPostScanTask.cs
@@ -32,7 +32,7 @@ namespace MediaBrowser.Server.Implementations.Library.Validators
/// <returns>Task.</returns>
public Task Run(IProgress<double> progress, CancellationToken cancellationToken)
{
- return _libraryManager.ValidateStudios(cancellationToken, progress);
+ return ((LibraryManager)_libraryManager).ValidateStudios(cancellationToken, progress);
}
}
}
diff --git a/MediaBrowser.Server.Implementations/LiveTv/LiveTvDtoService.cs b/MediaBrowser.Server.Implementations/LiveTv/LiveTvDtoService.cs
index 371619c084..b3066b460f 100644
--- a/MediaBrowser.Server.Implementations/LiveTv/LiveTvDtoService.cs
+++ b/MediaBrowser.Server.Implementations/LiveTv/LiveTvDtoService.cs
@@ -13,6 +13,7 @@ using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
+using MediaBrowser.Model.Querying;
namespace MediaBrowser.Server.Implementations.LiveTv
{
@@ -247,7 +248,10 @@ namespace MediaBrowser.Server.Implementations.LiveTv
if (imageTag != null)
{
dto.ImageTags[ImageType.Primary] = imageTag;
- _dtoService.AttachPrimaryImageAspectRatio(dto, recording);
+ _dtoService.AttachPrimaryImageAspectRatio(dto, recording, new List<ItemFields>
+ {
+ ItemFields.PrimaryImageAspectRatio
+ });
}
if (user != null)
@@ -337,7 +341,10 @@ namespace MediaBrowser.Server.Implementations.LiveTv
{
dto.ImageTags[ImageType.Primary] = imageTag;
- _dtoService.AttachPrimaryImageAspectRatio(dto, info);
+ _dtoService.AttachPrimaryImageAspectRatio(dto, info, new List<ItemFields>
+ {
+ ItemFields.PrimaryImageAspectRatio
+ });
}
if (currentProgram != null)
@@ -401,7 +408,10 @@ namespace MediaBrowser.Server.Implementations.LiveTv
if (imageTag != null)
{
dto.ImageTags[ImageType.Primary] = imageTag;
- _dtoService.AttachPrimaryImageAspectRatio(dto, item);
+ _dtoService.AttachPrimaryImageAspectRatio(dto, item, new List<ItemFields>
+ {
+ ItemFields.PrimaryImageAspectRatio
+ });
}
if (user != null)
diff --git a/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs b/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs
index 154a2756e2..83fe992b62 100644
--- a/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs
+++ b/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs
@@ -220,19 +220,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv
}
return 2;
- })
- .ThenBy(i =>
- {
- double number = 0;
-
- if (!string.IsNullOrEmpty(i.Number))
- {
- double.TryParse(i.Number, out number);
- }
-
- return number;
-
- }).ThenBy(i => i.Name);
+ });
var allChannels = channels.ToList();
IEnumerable<LiveTvChannel> allEnumerable = allChannels;
diff --git a/MediaBrowser.Server.Implementations/LiveTv/RefreshChannelsScheduledTask.cs b/MediaBrowser.Server.Implementations/LiveTv/RefreshChannelsScheduledTask.cs
index 23fed905ad..05cbfede0c 100644
--- a/MediaBrowser.Server.Implementations/LiveTv/RefreshChannelsScheduledTask.cs
+++ b/MediaBrowser.Server.Implementations/LiveTv/RefreshChannelsScheduledTask.cs
@@ -7,7 +7,7 @@ using System.Threading.Tasks;
namespace MediaBrowser.Server.Implementations.LiveTv
{
- class RefreshChannelsScheduledTask : IScheduledTask, IConfigurableScheduledTask
+ class RefreshChannelsScheduledTask : IScheduledTask, IConfigurableScheduledTask, IHasKey
{
private readonly ILiveTvManager _liveTvManager;
@@ -59,5 +59,10 @@ namespace MediaBrowser.Server.Implementations.LiveTv
{
get { return true; }
}
+
+ public string Key
+ {
+ get { return "RefreshGuide"; }
+ }
}
}
diff --git a/MediaBrowser.Server.Implementations/Localization/JavaScript/ar.json b/MediaBrowser.Server.Implementations/Localization/JavaScript/ar.json
index ec08593ede..81f648728e 100644
--- a/MediaBrowser.Server.Implementations/Localization/JavaScript/ar.json
+++ b/MediaBrowser.Server.Implementations/Localization/JavaScript/ar.json
@@ -626,5 +626,23 @@
"MessagePasswordResetForUsers": "Passwords have been reset for the following users:",
"HeaderInviteGuest": "Invite Guest",
"ButtonLinkMyMediaBrowserAccount": "Link my account now",
- "MessageConnectAccountRequiredToInviteGuest": "In order to invite guests you need to first link your Media Browser account to this server."
+ "MessageConnectAccountRequiredToInviteGuest": "In order to invite guests you need to first link your Media Browser account to this server.",
+ "ButtonSync": "Sync",
+ "SyncMedia": "Sync Media",
+ "HeaderCancelSyncJob": "Cancel Sync",
+ "CancelSyncJobConfirmation": "Are you sure you wish to cancel this sync job?",
+ "TabSync": "Sync",
+ "MessagePleaseSelectDeviceToSyncTo": "Please select a device to sync to.",
+ "MessageSyncJobCreated": "Sync job created.",
+ "LabelSyncTo": "Sync to:",
+ "LabelSyncJobName": "Sync job name:",
+ "LabelQuality": "Quality:",
+ "OptionHigh": "High",
+ "OptionMedium": "Medium",
+ "OptionLow": "Low",
+ "HeaderSettings": "Settings",
+ "OptionAutomaticallySyncNewContent": "Automatically sync new content",
+ "OptionAutomaticallySyncNewContentHelp": "New content added to these folders will be automatically synced to the device.",
+ "OptionSyncUnwatchedVideosOnly": "Sync unwatched videos only",
+ "OptionSyncUnwatchedVideosOnlyHelp": "Only unwatched videos will be synced, and videos will be removed from the device as they are watched."
} \ No newline at end of file
diff --git a/MediaBrowser.Server.Implementations/Localization/JavaScript/ca.json b/MediaBrowser.Server.Implementations/Localization/JavaScript/ca.json
index 63d7b02c01..d0dfd608b2 100644
--- a/MediaBrowser.Server.Implementations/Localization/JavaScript/ca.json
+++ b/MediaBrowser.Server.Implementations/Localization/JavaScript/ca.json
@@ -626,5 +626,23 @@
"MessagePasswordResetForUsers": "Passwords have been reset for the following users:",
"HeaderInviteGuest": "Invite Guest",
"ButtonLinkMyMediaBrowserAccount": "Link my account now",
- "MessageConnectAccountRequiredToInviteGuest": "In order to invite guests you need to first link your Media Browser account to this server."
+ "MessageConnectAccountRequiredToInviteGuest": "In order to invite guests you need to first link your Media Browser account to this server.",
+ "ButtonSync": "Sync",
+ "SyncMedia": "Sync Media",
+ "HeaderCancelSyncJob": "Cancel Sync",
+ "CancelSyncJobConfirmation": "Are you sure you wish to cancel this sync job?",
+ "TabSync": "Sync",
+ "MessagePleaseSelectDeviceToSyncTo": "Please select a device to sync to.",
+ "MessageSyncJobCreated": "Sync job created.",
+ "LabelSyncTo": "Sync to:",
+ "LabelSyncJobName": "Sync job name:",
+ "LabelQuality": "Quality:",
+ "OptionHigh": "High",
+ "OptionMedium": "Medium",
+ "OptionLow": "Low",
+ "HeaderSettings": "Settings",
+ "OptionAutomaticallySyncNewContent": "Automatically sync new content",
+ "OptionAutomaticallySyncNewContentHelp": "New content added to these folders will be automatically synced to the device.",
+ "OptionSyncUnwatchedVideosOnly": "Sync unwatched videos only",
+ "OptionSyncUnwatchedVideosOnlyHelp": "Only unwatched videos will be synced, and videos will be removed from the device as they are watched."
} \ No newline at end of file
diff --git a/MediaBrowser.Server.Implementations/Localization/JavaScript/cs.json b/MediaBrowser.Server.Implementations/Localization/JavaScript/cs.json
index c90af9fb18..9f2da77974 100644
--- a/MediaBrowser.Server.Implementations/Localization/JavaScript/cs.json
+++ b/MediaBrowser.Server.Implementations/Localization/JavaScript/cs.json
@@ -626,5 +626,23 @@
"MessagePasswordResetForUsers": "Passwords have been reset for the following users:",
"HeaderInviteGuest": "Invite Guest",
"ButtonLinkMyMediaBrowserAccount": "Link my account now",
- "MessageConnectAccountRequiredToInviteGuest": "In order to invite guests you need to first link your Media Browser account to this server."
+ "MessageConnectAccountRequiredToInviteGuest": "In order to invite guests you need to first link your Media Browser account to this server.",
+ "ButtonSync": "Sync",
+ "SyncMedia": "Sync Media",
+ "HeaderCancelSyncJob": "Cancel Sync",
+ "CancelSyncJobConfirmation": "Are you sure you wish to cancel this sync job?",
+ "TabSync": "Sync",
+ "MessagePleaseSelectDeviceToSyncTo": "Please select a device to sync to.",
+ "MessageSyncJobCreated": "Sync job created.",
+ "LabelSyncTo": "Sync to:",
+ "LabelSyncJobName": "Sync job name:",
+ "LabelQuality": "Quality:",
+ "OptionHigh": "High",
+ "OptionMedium": "Medium",
+ "OptionLow": "Low",
+ "HeaderSettings": "Settings",
+ "OptionAutomaticallySyncNewContent": "Automatically sync new content",
+ "OptionAutomaticallySyncNewContentHelp": "New content added to these folders will be automatically synced to the device.",
+ "OptionSyncUnwatchedVideosOnly": "Sync unwatched videos only",
+ "OptionSyncUnwatchedVideosOnlyHelp": "Only unwatched videos will be synced, and videos will be removed from the device as they are watched."
} \ No newline at end of file
diff --git a/MediaBrowser.Server.Implementations/Localization/JavaScript/da.json b/MediaBrowser.Server.Implementations/Localization/JavaScript/da.json
index dca2f1daa4..4bd7d3103c 100644
--- a/MediaBrowser.Server.Implementations/Localization/JavaScript/da.json
+++ b/MediaBrowser.Server.Implementations/Localization/JavaScript/da.json
@@ -626,5 +626,23 @@
"MessagePasswordResetForUsers": "Passwords have been reset for the following users:",
"HeaderInviteGuest": "Invite Guest",
"ButtonLinkMyMediaBrowserAccount": "Link my account now",
- "MessageConnectAccountRequiredToInviteGuest": "In order to invite guests you need to first link your Media Browser account to this server."
+ "MessageConnectAccountRequiredToInviteGuest": "In order to invite guests you need to first link your Media Browser account to this server.",
+ "ButtonSync": "Sync",
+ "SyncMedia": "Sync Media",
+ "HeaderCancelSyncJob": "Cancel Sync",
+ "CancelSyncJobConfirmation": "Are you sure you wish to cancel this sync job?",
+ "TabSync": "Sync",
+ "MessagePleaseSelectDeviceToSyncTo": "Please select a device to sync to.",
+ "MessageSyncJobCreated": "Sync job created.",
+ "LabelSyncTo": "Sync to:",
+ "LabelSyncJobName": "Sync job name:",
+ "LabelQuality": "Quality:",
+ "OptionHigh": "High",
+ "OptionMedium": "Medium",
+ "OptionLow": "Low",
+ "HeaderSettings": "Settings",
+ "OptionAutomaticallySyncNewContent": "Automatically sync new content",
+ "OptionAutomaticallySyncNewContentHelp": "New content added to these folders will be automatically synced to the device.",
+ "OptionSyncUnwatchedVideosOnly": "Sync unwatched videos only",
+ "OptionSyncUnwatchedVideosOnlyHelp": "Only unwatched videos will be synced, and videos will be removed from the device as they are watched."
} \ No newline at end of file
diff --git a/MediaBrowser.Server.Implementations/Localization/JavaScript/de.json b/MediaBrowser.Server.Implementations/Localization/JavaScript/de.json
index f3170f463c..9065404b60 100644
--- a/MediaBrowser.Server.Implementations/Localization/JavaScript/de.json
+++ b/MediaBrowser.Server.Implementations/Localization/JavaScript/de.json
@@ -610,7 +610,7 @@
"MessageInvitationSentToUser": "Eine E-Mail mit der Einladung zum Sharing ist an {0} geschickt worden.",
"MessageInvitationSentToNewUser": "Eine E-Mail mit der Einladung zur Anmeldung am Media Browser ist an {0} geschickt worden.",
"HeaderConnectionFailure": "Verbindungsfehler",
- "MessageUnableToConnectToServer": "We're unable to connect to the selected server right now. Please try again later.",
+ "MessageUnableToConnectToServer": "Wir sind momentan nicht in der Lage, zum ausgew\u00e4hlten Server zu verbinden. Bitte versuche es sp\u00e4ter noch einmal.",
"ButtonSelectServer": "W\u00e4hle Server",
"MessagePluginConfigurationRequiresLocalAccess": "Melde dich bitte direkt an deinem lokalen Server an, um dieses Plugin konfigurieren zu k\u00f6nnen.",
"MessageLoggedOutParentalControl": "Der Zugriff ist derzeit eingeschr\u00e4nkt. Bitte versuche es sp\u00e4ter erneut.",
@@ -626,5 +626,23 @@
"MessagePasswordResetForUsers": "Passw\u00f6rter wurden f\u00fcr die folgenden Benutzer zur\u00fcckgesetzt:",
"HeaderInviteGuest": "Lade G\u00e4ste ein",
"ButtonLinkMyMediaBrowserAccount": "Verkn\u00fcpfe jetzt meinen Account",
- "MessageConnectAccountRequiredToInviteGuest": "Um G\u00e4ste einladen zu k\u00f6nnen, musst du zuerst deinen Media Browser Account auf diesem Server verkn\u00fcpfen."
+ "MessageConnectAccountRequiredToInviteGuest": "Um G\u00e4ste einladen zu k\u00f6nnen, musst du zuerst deinen Media Browser Account auf diesem Server verkn\u00fcpfen.",
+ "ButtonSync": "Synchronisieren",
+ "SyncMedia": "Sync Media",
+ "HeaderCancelSyncJob": "Cancel Sync",
+ "CancelSyncJobConfirmation": "Are you sure you wish to cancel this sync job?",
+ "TabSync": "Synchronisieren",
+ "MessagePleaseSelectDeviceToSyncTo": "Please select a device to sync to.",
+ "MessageSyncJobCreated": "Sync job created.",
+ "LabelSyncTo": "Sync to:",
+ "LabelSyncJobName": "Sync job name:",
+ "LabelQuality": "Quality:",
+ "OptionHigh": "High",
+ "OptionMedium": "Medium",
+ "OptionLow": "Low",
+ "HeaderSettings": "Settings",
+ "OptionAutomaticallySyncNewContent": "Automatically sync new content",
+ "OptionAutomaticallySyncNewContentHelp": "New content added to these folders will be automatically synced to the device.",
+ "OptionSyncUnwatchedVideosOnly": "Sync unwatched videos only",
+ "OptionSyncUnwatchedVideosOnlyHelp": "Only unwatched videos will be synced, and videos will be removed from the device as they are watched."
} \ No newline at end of file
diff --git a/MediaBrowser.Server.Implementations/Localization/JavaScript/el.json b/MediaBrowser.Server.Implementations/Localization/JavaScript/el.json
index e0f427287f..20c9de1ef5 100644
--- a/MediaBrowser.Server.Implementations/Localization/JavaScript/el.json
+++ b/MediaBrowser.Server.Implementations/Localization/JavaScript/el.json
@@ -626,5 +626,23 @@
"MessagePasswordResetForUsers": "Passwords have been reset for the following users:",
"HeaderInviteGuest": "Invite Guest",
"ButtonLinkMyMediaBrowserAccount": "Link my account now",
- "MessageConnectAccountRequiredToInviteGuest": "In order to invite guests you need to first link your Media Browser account to this server."
+ "MessageConnectAccountRequiredToInviteGuest": "In order to invite guests you need to first link your Media Browser account to this server.",
+ "ButtonSync": "Sync",
+ "SyncMedia": "Sync Media",
+ "HeaderCancelSyncJob": "Cancel Sync",
+ "CancelSyncJobConfirmation": "Are you sure you wish to cancel this sync job?",
+ "TabSync": "Sync",
+ "MessagePleaseSelectDeviceToSyncTo": "Please select a device to sync to.",
+ "MessageSyncJobCreated": "Sync job created.",
+ "LabelSyncTo": "Sync to:",
+ "LabelSyncJobName": "Sync job name:",
+ "LabelQuality": "Quality:",
+ "OptionHigh": "High",
+ "OptionMedium": "Medium",
+ "OptionLow": "Low",
+ "HeaderSettings": "Settings",
+ "OptionAutomaticallySyncNewContent": "Automatically sync new content",
+ "OptionAutomaticallySyncNewContentHelp": "New content added to these folders will be automatically synced to the device.",
+ "OptionSyncUnwatchedVideosOnly": "Sync unwatched videos only",
+ "OptionSyncUnwatchedVideosOnlyHelp": "Only unwatched videos will be synced, and videos will be removed from the device as they are watched."
} \ No newline at end of file
diff --git a/MediaBrowser.Server.Implementations/Localization/JavaScript/en_GB.json b/MediaBrowser.Server.Implementations/Localization/JavaScript/en_GB.json
index 1412882be2..fec45e70c4 100644
--- a/MediaBrowser.Server.Implementations/Localization/JavaScript/en_GB.json
+++ b/MediaBrowser.Server.Implementations/Localization/JavaScript/en_GB.json
@@ -626,5 +626,23 @@
"MessagePasswordResetForUsers": "Passwords have been reset for the following users:",
"HeaderInviteGuest": "Invite Guest",
"ButtonLinkMyMediaBrowserAccount": "Link my account now",
- "MessageConnectAccountRequiredToInviteGuest": "In order to invite guests you need to first link your Media Browser account to this server."
+ "MessageConnectAccountRequiredToInviteGuest": "In order to invite guests you need to first link your Media Browser account to this server.",
+ "ButtonSync": "Sync",
+ "SyncMedia": "Sync Media",
+ "HeaderCancelSyncJob": "Cancel Sync",
+ "CancelSyncJobConfirmation": "Are you sure you wish to cancel this sync job?",
+ "TabSync": "Sync",
+ "MessagePleaseSelectDeviceToSyncTo": "Please select a device to sync to.",
+ "MessageSyncJobCreated": "Sync job created.",
+ "LabelSyncTo": "Sync to:",
+ "LabelSyncJobName": "Sync job name:",
+ "LabelQuality": "Quality:",
+ "OptionHigh": "High",
+ "OptionMedium": "Medium",
+ "OptionLow": "Low",
+ "HeaderSettings": "Settings",
+ "OptionAutomaticallySyncNewContent": "Automatically sync new content",
+ "OptionAutomaticallySyncNewContentHelp": "New content added to these folders will be automatically synced to the device.",
+ "OptionSyncUnwatchedVideosOnly": "Sync unwatched videos only",
+ "OptionSyncUnwatchedVideosOnlyHelp": "Only unwatched videos will be synced, and videos will be removed from the device as they are watched."
} \ No newline at end of file
diff --git a/MediaBrowser.Server.Implementations/Localization/JavaScript/en_US.json b/MediaBrowser.Server.Implementations/Localization/JavaScript/en_US.json
index d0479eb2af..369299be0c 100644
--- a/MediaBrowser.Server.Implementations/Localization/JavaScript/en_US.json
+++ b/MediaBrowser.Server.Implementations/Localization/JavaScript/en_US.json
@@ -626,5 +626,23 @@
"MessagePasswordResetForUsers": "Passwords have been reset for the following users:",
"HeaderInviteGuest": "Invite Guest",
"ButtonLinkMyMediaBrowserAccount": "Link my account now",
- "MessageConnectAccountRequiredToInviteGuest": "In order to invite guests you need to first link your Media Browser account to this server."
+ "MessageConnectAccountRequiredToInviteGuest": "In order to invite guests you need to first link your Media Browser account to this server.",
+ "ButtonSync": "Sync",
+ "SyncMedia": "Sync Media",
+ "HeaderCancelSyncJob": "Cancel Sync",
+ "CancelSyncJobConfirmation": "Are you sure you wish to cancel this sync job?",
+ "TabSync": "Sync",
+ "MessagePleaseSelectDeviceToSyncTo": "Please select a device to sync to.",
+ "MessageSyncJobCreated": "Sync job created.",
+ "LabelSyncTo": "Sync to:",
+ "LabelSyncJobName": "Sync job name:",
+ "LabelQuality": "Quality:",
+ "OptionHigh": "High",
+ "OptionMedium": "Medium",
+ "OptionLow": "Low",
+ "HeaderSettings": "Settings",
+ "OptionAutomaticallySyncNewContent": "Automatically sync new content",
+ "OptionAutomaticallySyncNewContentHelp": "New content added to these folders will be automatically synced to the device.",
+ "OptionSyncUnwatchedVideosOnly": "Sync unwatched videos only",
+ "OptionSyncUnwatchedVideosOnlyHelp": "Only unwatched videos will be synced, and videos will be removed from the device as they are watched."
} \ No newline at end of file
diff --git a/MediaBrowser.Server.Implementations/Localization/JavaScript/es.json b/MediaBrowser.Server.Implementations/Localization/JavaScript/es.json
index fa768f480d..d2957340cd 100644
--- a/MediaBrowser.Server.Implementations/Localization/JavaScript/es.json
+++ b/MediaBrowser.Server.Implementations/Localization/JavaScript/es.json
@@ -626,5 +626,23 @@
"MessagePasswordResetForUsers": "Passwords have been reset for the following users:",
"HeaderInviteGuest": "Invite Guest",
"ButtonLinkMyMediaBrowserAccount": "Link my account now",
- "MessageConnectAccountRequiredToInviteGuest": "In order to invite guests you need to first link your Media Browser account to this server."
+ "MessageConnectAccountRequiredToInviteGuest": "In order to invite guests you need to first link your Media Browser account to this server.",
+ "ButtonSync": "Sync",
+ "SyncMedia": "Sync Media",
+ "HeaderCancelSyncJob": "Cancel Sync",
+ "CancelSyncJobConfirmation": "Are you sure you wish to cancel this sync job?",
+ "TabSync": "Sync",
+ "MessagePleaseSelectDeviceToSyncTo": "Please select a device to sync to.",
+ "MessageSyncJobCreated": "Sync job created.",
+ "LabelSyncTo": "Sync to:",
+ "LabelSyncJobName": "Sync job name:",
+ "LabelQuality": "Quality:",
+ "OptionHigh": "High",
+ "OptionMedium": "Medium",
+ "OptionLow": "Low",
+ "HeaderSettings": "Settings",
+ "OptionAutomaticallySyncNewContent": "Automatically sync new content",
+ "OptionAutomaticallySyncNewContentHelp": "New content added to these folders will be automatically synced to the device.",
+ "OptionSyncUnwatchedVideosOnly": "Sync unwatched videos only",
+ "OptionSyncUnwatchedVideosOnlyHelp": "Only unwatched videos will be synced, and videos will be removed from the device as they are watched."
} \ No newline at end of file
diff --git a/MediaBrowser.Server.Implementations/Localization/JavaScript/es_MX.json b/MediaBrowser.Server.Implementations/Localization/JavaScript/es_MX.json
index 7855fff744..f53bd74c42 100644
--- a/MediaBrowser.Server.Implementations/Localization/JavaScript/es_MX.json
+++ b/MediaBrowser.Server.Implementations/Localization/JavaScript/es_MX.json
@@ -485,7 +485,7 @@
"ValueOneMusicVideo": "1 video musical",
"ValueMusicVideoCount": "{0} videos musicales",
"HeaderOffline": "Fuera de L\u00ednea",
- "HeaderUnaired": "No transmitido",
+ "HeaderUnaired": "No Emitido",
"HeaderMissing": "Falta",
"ButtonWebsite": "Sitio web",
"TooltipFavorite": "Favorito",
@@ -610,7 +610,7 @@
"MessageInvitationSentToUser": "Se ha enviado un correo electr\u00f3nico a {0}, invit\u00e1ndolo a aceptar tu invitaci\u00f3n para compartir.",
"MessageInvitationSentToNewUser": "Se ha enviado un correo electr\u00f3nico a {0} invit\u00e1ndolo a registrarse con Media Browser.",
"HeaderConnectionFailure": "Falla de Conexi\u00f3n",
- "MessageUnableToConnectToServer": "We're unable to connect to the selected server right now. Please try again later.",
+ "MessageUnableToConnectToServer": "No es posible conectarse al servidor seleccionado en este momento. Por favor int\u00e9ntelo nuevamente m\u00e1s tarde.",
"ButtonSelectServer": "Seleccionar servidor",
"MessagePluginConfigurationRequiresLocalAccess": "Para configurar este complemento por favor inicie sesi\u00f3n en su servidor local directamente.",
"MessageLoggedOutParentalControl": "El acceso se encuentra restringido en este momento. Por favor int\u00e9ntelo de nuevo mas tarde.",
@@ -626,5 +626,23 @@
"MessagePasswordResetForUsers": "Las contrase\u00f1as se han restablecido para los siguientes usuarios:",
"HeaderInviteGuest": "Agregar un Invitado",
"ButtonLinkMyMediaBrowserAccount": "Enlazar mi cuenta ahora",
- "MessageConnectAccountRequiredToInviteGuest": "Para poder agregar invitados primero necesitas vincular tu cuenta de Media Browser a este servidor."
+ "MessageConnectAccountRequiredToInviteGuest": "Para poder agregar invitados primero necesitas vincular tu cuenta de Media Browser a este servidor.",
+ "ButtonSync": "Sinc",
+ "SyncMedia": "Sincronizar Medios",
+ "HeaderCancelSyncJob": "Cancelar Sincronizaci\u00f3n",
+ "CancelSyncJobConfirmation": "\u00bfEsta seguro de querer cancelar este trabajo de sincronizaci\u00f3n?",
+ "TabSync": "Sinc",
+ "MessagePleaseSelectDeviceToSyncTo": "Por favor seleccione un dispositivo con el que desea sincronizar.",
+ "MessageSyncJobCreated": "Trabajo de sincornizaci\u00f3n creado.",
+ "LabelSyncTo": "Sincronizar con:",
+ "LabelSyncJobName": "Nombre del trabajo de sincronizaci\u00f3n:",
+ "LabelQuality": "Calidad:",
+ "OptionHigh": "Alta",
+ "OptionMedium": "Media",
+ "OptionLow": "Baja",
+ "HeaderSettings": "Configuraci\u00f3n",
+ "OptionAutomaticallySyncNewContent": "Sincronizar autom\u00e1ticamente nuevos contenidos",
+ "OptionAutomaticallySyncNewContentHelp": "Los contenidos nuevos que sean agregados a estas carpetas ser\u00e1n sincronizados autom\u00e1ticamente con el dispositivo.",
+ "OptionSyncUnwatchedVideosOnly": "Sincronizar \u00fanicamente videos no vistos",
+ "OptionSyncUnwatchedVideosOnlyHelp": "Solamente los videos a\u00fan no vistos ser\u00e1n sincronizados, se eliminar\u00e1n los videos del dispositivo conforme \u00e9stos sean vistos."
} \ No newline at end of file
diff --git a/MediaBrowser.Server.Implementations/Localization/JavaScript/fi.json b/MediaBrowser.Server.Implementations/Localization/JavaScript/fi.json
index a5ffa3cd63..e9c6263e2c 100644
--- a/MediaBrowser.Server.Implementations/Localization/JavaScript/fi.json
+++ b/MediaBrowser.Server.Implementations/Localization/JavaScript/fi.json
@@ -626,5 +626,23 @@
"MessagePasswordResetForUsers": "Passwords have been reset for the following users:",
"HeaderInviteGuest": "Invite Guest",
"ButtonLinkMyMediaBrowserAccount": "Link my account now",
- "MessageConnectAccountRequiredToInviteGuest": "In order to invite guests you need to first link your Media Browser account to this server."
+ "MessageConnectAccountRequiredToInviteGuest": "In order to invite guests you need to first link your Media Browser account to this server.",
+ "ButtonSync": "Sync",
+ "SyncMedia": "Sync Media",
+ "HeaderCancelSyncJob": "Cancel Sync",
+ "CancelSyncJobConfirmation": "Are you sure you wish to cancel this sync job?",
+ "TabSync": "Sync",
+ "MessagePleaseSelectDeviceToSyncTo": "Please select a device to sync to.",
+ "MessageSyncJobCreated": "Sync job created.",
+ "LabelSyncTo": "Sync to:",
+ "LabelSyncJobName": "Sync job name:",
+ "LabelQuality": "Quality:",
+ "OptionHigh": "High",
+ "OptionMedium": "Medium",
+ "OptionLow": "Low",
+ "HeaderSettings": "Settings",
+ "OptionAutomaticallySyncNewContent": "Automatically sync new content",
+ "OptionAutomaticallySyncNewContentHelp": "New content added to these folders will be automatically synced to the device.",
+ "OptionSyncUnwatchedVideosOnly": "Sync unwatched videos only",
+ "OptionSyncUnwatchedVideosOnlyHelp": "Only unwatched videos will be synced, and videos will be removed from the device as they are watched."
} \ No newline at end of file
diff --git a/MediaBrowser.Server.Implementations/Localization/JavaScript/fr.json b/MediaBrowser.Server.Implementations/Localization/JavaScript/fr.json
index e2190a380f..2c0acb241b 100644
--- a/MediaBrowser.Server.Implementations/Localization/JavaScript/fr.json
+++ b/MediaBrowser.Server.Implementations/Localization/JavaScript/fr.json
@@ -610,7 +610,7 @@
"MessageInvitationSentToUser": "Un mail a \u00e9t\u00e9 envoy\u00e9 \u00e0 {0} pour les inviter \u00e0 accepter votre invitation de partage.",
"MessageInvitationSentToNewUser": "Un mail a \u00e9t\u00e9 envoy\u00e9 \u00e0 {0} pour les inviter \u00e0 s'inscrire sur Media Browser.",
"HeaderConnectionFailure": "Erreur de connexion",
- "MessageUnableToConnectToServer": "We're unable to connect to the selected server right now. Please try again later.",
+ "MessageUnableToConnectToServer": "Nous sommes dans l'impossibilit\u00e9 de nous connect\u00e9 au serveur pour le moment. Veuillez r\u00e9essayer plus tard.",
"ButtonSelectServer": "S\u00e9lectionner le serveur",
"MessagePluginConfigurationRequiresLocalAccess": "Pour configurer ce plugin, S.v.p. connecter vous \u00e0 votre serveur local directement.",
"MessageLoggedOutParentalControl": "L'acc\u00e8s est actuellement limit\u00e9. S.v.p. r\u00e9essayez plus tard",
@@ -626,5 +626,23 @@
"MessagePasswordResetForUsers": "Les mot de passes ont \u00e9t\u00e9 r\u00e9initialis\u00e9s pour les utilisateurs suivants:",
"HeaderInviteGuest": "Inviter une personne",
"ButtonLinkMyMediaBrowserAccount": "Lier \u00e0 mon compte maintenant",
- "MessageConnectAccountRequiredToInviteGuest": "Pour inviter des personnes vous devez d'abord lier votre compte Media Browser \u00e0 ce serveur."
+ "MessageConnectAccountRequiredToInviteGuest": "Pour inviter des personnes vous devez d'abord lier votre compte Media Browser \u00e0 ce serveur.",
+ "ButtonSync": "Sync",
+ "SyncMedia": "Sync Media",
+ "HeaderCancelSyncJob": "Cancel Sync",
+ "CancelSyncJobConfirmation": "Are you sure you wish to cancel this sync job?",
+ "TabSync": "Sync",
+ "MessagePleaseSelectDeviceToSyncTo": "Please select a device to sync to.",
+ "MessageSyncJobCreated": "Sync job created.",
+ "LabelSyncTo": "Sync to:",
+ "LabelSyncJobName": "Sync job name:",
+ "LabelQuality": "Quality:",
+ "OptionHigh": "High",
+ "OptionMedium": "Medium",
+ "OptionLow": "Low",
+ "HeaderSettings": "Param\u00e8tres",
+ "OptionAutomaticallySyncNewContent": "Synchroniser automatiquement le nouveau contenu",
+ "OptionAutomaticallySyncNewContentHelp": "Le nouveau contenu ajout\u00e9 \u00e0 ces r\u00e9pertoires sera automatiquement synchronis\u00e9 \u00e0 votre p\u00e9riph\u00e9rique.",
+ "OptionSyncUnwatchedVideosOnly": "Synchroniser seulement les vid\u00e9os non lus.",
+ "OptionSyncUnwatchedVideosOnlyHelp": "Seulement les vid\u00e9os non lus seront synchronis\u00e9es et seront supprim\u00e9es du p\u00e9riph\u00e9rique au fur et \u00e0 mesure qu'elles sont lus."
} \ No newline at end of file
diff --git a/MediaBrowser.Server.Implementations/Localization/JavaScript/he.json b/MediaBrowser.Server.Implementations/Localization/JavaScript/he.json
index 323eb950e3..7d268200ba 100644
--- a/MediaBrowser.Server.Implementations/Localization/JavaScript/he.json
+++ b/MediaBrowser.Server.Implementations/Localization/JavaScript/he.json
@@ -626,5 +626,23 @@
"MessagePasswordResetForUsers": "Passwords have been reset for the following users:",
"HeaderInviteGuest": "Invite Guest",
"ButtonLinkMyMediaBrowserAccount": "Link my account now",
- "MessageConnectAccountRequiredToInviteGuest": "In order to invite guests you need to first link your Media Browser account to this server."
+ "MessageConnectAccountRequiredToInviteGuest": "In order to invite guests you need to first link your Media Browser account to this server.",
+ "ButtonSync": "Sync",
+ "SyncMedia": "Sync Media",
+ "HeaderCancelSyncJob": "Cancel Sync",
+ "CancelSyncJobConfirmation": "Are you sure you wish to cancel this sync job?",
+ "TabSync": "Sync",
+ "MessagePleaseSelectDeviceToSyncTo": "Please select a device to sync to.",
+ "MessageSyncJobCreated": "Sync job created.",
+ "LabelSyncTo": "Sync to:",
+ "LabelSyncJobName": "Sync job name:",
+ "LabelQuality": "Quality:",
+ "OptionHigh": "High",
+ "OptionMedium": "Medium",
+ "OptionLow": "Low",
+ "HeaderSettings": "Settings",
+ "OptionAutomaticallySyncNewContent": "Automatically sync new content",
+ "OptionAutomaticallySyncNewContentHelp": "New content added to these folders will be automatically synced to the device.",
+ "OptionSyncUnwatchedVideosOnly": "Sync unwatched videos only",
+ "OptionSyncUnwatchedVideosOnlyHelp": "Only unwatched videos will be synced, and videos will be removed from the device as they are watched."
} \ No newline at end of file
diff --git a/MediaBrowser.Server.Implementations/Localization/JavaScript/hr.json b/MediaBrowser.Server.Implementations/Localization/JavaScript/hr.json
index c5fb87ea99..ef186d800a 100644
--- a/MediaBrowser.Server.Implementations/Localization/JavaScript/hr.json
+++ b/MediaBrowser.Server.Implementations/Localization/JavaScript/hr.json
@@ -626,5 +626,23 @@
"MessagePasswordResetForUsers": "Passwords have been reset for the following users:",
"HeaderInviteGuest": "Invite Guest",
"ButtonLinkMyMediaBrowserAccount": "Link my account now",
- "MessageConnectAccountRequiredToInviteGuest": "In order to invite guests you need to first link your Media Browser account to this server."
+ "MessageConnectAccountRequiredToInviteGuest": "In order to invite guests you need to first link your Media Browser account to this server.",
+ "ButtonSync": "Sync",
+ "SyncMedia": "Sync Media",
+ "HeaderCancelSyncJob": "Cancel Sync",
+ "CancelSyncJobConfirmation": "Are you sure you wish to cancel this sync job?",
+ "TabSync": "Sync",
+ "MessagePleaseSelectDeviceToSyncTo": "Please select a device to sync to.",
+ "MessageSyncJobCreated": "Sync job created.",
+ "LabelSyncTo": "Sync to:",
+ "LabelSyncJobName": "Sync job name:",
+ "LabelQuality": "Quality:",
+ "OptionHigh": "High",
+ "OptionMedium": "Medium",
+ "OptionLow": "Low",
+ "HeaderSettings": "Settings",
+ "OptionAutomaticallySyncNewContent": "Automatically sync new content",
+ "OptionAutomaticallySyncNewContentHelp": "New content added to these folders will be automatically synced to the device.",
+ "OptionSyncUnwatchedVideosOnly": "Sync unwatched videos only",
+ "OptionSyncUnwatchedVideosOnlyHelp": "Only unwatched videos will be synced, and videos will be removed from the device as they are watched."
} \ No newline at end of file
diff --git a/MediaBrowser.Server.Implementations/Localization/JavaScript/it.json b/MediaBrowser.Server.Implementations/Localization/JavaScript/it.json
index 5cbb53d29d..8e324b3359 100644
--- a/MediaBrowser.Server.Implementations/Localization/JavaScript/it.json
+++ b/MediaBrowser.Server.Implementations/Localization/JavaScript/it.json
@@ -25,8 +25,8 @@
"NoPluginConfigurationMessage": "Questo Plugin non \u00e8 stato configurato.",
"NoPluginsInstalledMessage": "non ci sono Plugins installati.",
"BrowsePluginCatalogMessage": "Sfoglia il catalogo dei Plugins.",
- "MessageKeyEmailedTo": "Key emailed to {0}.",
- "MessageKeysLinked": "Keys linked.",
+ "MessageKeyEmailedTo": "Chiave inviata email a {0}.",
+ "MessageKeysLinked": "Chiave Linked.",
"HeaderConfirmation": "Conferme",
"MessageKeyUpdated": "Grazie. La vostra chiave supporter \u00e8 stato aggiornato.",
"MessageKeyRemoved": "Grazie. La vostra chiave supporter \u00e8 stata rimossa.",
@@ -41,7 +41,7 @@
"LabelCancelled": "(cancellato)",
"LabelFailed": "(fallito)",
"LabelAbortedByServerShutdown": "(Interrotto dalla chiusura del server)",
- "LabelScheduledTaskLastRan": "Last ran {0}, taking {1}.",
+ "LabelScheduledTaskLastRan": "Ultima esecuzione {0}, taking {1}.",
"HeaderDeleteTaskTrigger": "Elimina Operazione pianificata",
"HeaderTaskTriggers": "Operazione Pianificata",
"MessageDeleteTaskTrigger": "Sei sicuro di voler cancellare questo evento?",
@@ -285,7 +285,7 @@
"LabelPremiereProgram": "PREMIERE",
"LabelHDProgram": "HD",
"HeaderChangeFolderType": "Cambia il tipo di cartella",
- "HeaderChangeFolderTypeHelp": "To change the type, please remove and rebuild the folder with the new type.",
+ "HeaderChangeFolderTypeHelp": "Per modificare il tipo, rimuovere e ricostruire la cartella con il nuovo tipo.",
"HeaderAlert": "Avviso",
"MessagePleaseRestart": "Si prega di riavviare per completare l'aggiornamento.",
"ButtonRestart": "Riavvia",
@@ -321,7 +321,7 @@
"ButtonSelect": "Seleziona",
"ButtonNew": "Nuovo",
"MessageInternetExplorerWebm": "Se utilizzi internet Explorer installa WebM plugin",
- "HeaderVideoError": "Video Error",
+ "HeaderVideoError": "Video Errore",
"ButtonAddToPlaylist": "Aggiungi alla playlist",
"HeaderAddToPlaylist": "Aggiungi alla playlist",
"LabelName": "Nome:",
@@ -447,7 +447,7 @@
"MessageYouHaveALifetimeMembership": "Avete un abbonamento sostenitore vita. \u00c8 possibile fornire ulteriori donazioni in una sola volta o in modo ricorrente utilizzando le seguenti opzioni. Grazie per il sostegno Media Browser.",
"MessageYouHaveAnActiveRecurringMembership": "Si dispone di un attivo {0} appartenenza. \u00c8 possibile aggiornare il vostro piano utilizzando le opzioni di seguito.",
"ButtonDelete": "Elimina",
- "HeaderMediaBrowserAccountAdded": "Media Browser Account Added",
+ "HeaderMediaBrowserAccountAdded": "Media Browser utente aggiunto",
"MessageMediaBrowserAccountAdded": "Media Browser Account Aggiunto",
"MessagePendingMediaBrowserAccountAdded": "L'account Media Browser \u00e8 stato aggiunto a questo utente. Una e-mail sar\u00e0 inviata al proprietario del conto. L'invito dovr\u00e0 essere confermato cliccando su un link all'interno della mail.",
"HeaderMediaBrowserAccountRemoved": "Account Media Browser rimosso",
@@ -533,7 +533,7 @@
"HeaderOtherItems": "Altri elmenti",
"ButtonFullReview": "Trama completa",
"ValueAsRole": "Come {0}",
- "ValueGuestStar": "Guest star",
+ "ValueGuestStar": "Personaggi famosi",
"MediaInfoSize": "Dimensione",
"MediaInfoPath": "Percorso",
"MediaInfoFormat": "Formato",
@@ -626,5 +626,23 @@
"MessagePasswordResetForUsers": "Le password sono state rimesse per i seguenti utenti:",
"HeaderInviteGuest": "Invita Ospite",
"ButtonLinkMyMediaBrowserAccount": "Collega il mio account",
- "MessageConnectAccountRequiredToInviteGuest": "Per invitare gli ospiti \u00e8 necessario collegare prima il tuo account browser media a questo server."
+ "MessageConnectAccountRequiredToInviteGuest": "Per invitare gli ospiti \u00e8 necessario collegare prima il tuo account browser media a questo server.",
+ "ButtonSync": "Sinc.",
+ "SyncMedia": "Sync Media",
+ "HeaderCancelSyncJob": "Cancel Sync",
+ "CancelSyncJobConfirmation": "Are you sure you wish to cancel this sync job?",
+ "TabSync": "Sinc",
+ "MessagePleaseSelectDeviceToSyncTo": "Please select a device to sync to.",
+ "MessageSyncJobCreated": "Sync job created.",
+ "LabelSyncTo": "Sync to:",
+ "LabelSyncJobName": "Sync job name:",
+ "LabelQuality": "Quality:",
+ "OptionHigh": "High",
+ "OptionMedium": "Medium",
+ "OptionLow": "Low",
+ "HeaderSettings": "Settings",
+ "OptionAutomaticallySyncNewContent": "Automatically sync new content",
+ "OptionAutomaticallySyncNewContentHelp": "New content added to these folders will be automatically synced to the device.",
+ "OptionSyncUnwatchedVideosOnly": "Sync unwatched videos only",
+ "OptionSyncUnwatchedVideosOnlyHelp": "Only unwatched videos will be synced, and videos will be removed from the device as they are watched."
} \ No newline at end of file
diff --git a/MediaBrowser.Server.Implementations/Localization/JavaScript/javascript.json b/MediaBrowser.Server.Implementations/Localization/JavaScript/javascript.json
index d0975221e3..8505ed2817 100644
--- a/MediaBrowser.Server.Implementations/Localization/JavaScript/javascript.json
+++ b/MediaBrowser.Server.Implementations/Localization/JavaScript/javascript.json
@@ -634,5 +634,23 @@
"MessagePasswordResetForUsers": "Passwords have been reset for the following users:",
"HeaderInviteGuest": "Invite Guest",
"ButtonLinkMyMediaBrowserAccount": "Link my account now",
- "MessageConnectAccountRequiredToInviteGuest": "In order to invite guests you need to first link your Media Browser account to this server."
+ "MessageConnectAccountRequiredToInviteGuest": "In order to invite guests you need to first link your Media Browser account to this server.",
+ "ButtonSync": "Sync",
+ "SyncMedia": "Sync Media",
+ "HeaderCancelSyncJob": "Cancel Sync",
+ "CancelSyncJobConfirmation": "Are you sure you wish to cancel this sync job?",
+ "TabSync": "Sync",
+ "MessagePleaseSelectDeviceToSyncTo": "Please select a device to sync to.",
+ "MessageSyncJobCreated": "Sync job created.",
+ "LabelSyncTo": "Sync to:",
+ "LabelSyncJobName": "Sync job name:",
+ "LabelQuality": "Quality:",
+ "OptionHigh": "High",
+ "OptionMedium": "Medium",
+ "OptionLow": "Low",
+ "HeaderSettings": "Settings",
+ "OptionAutomaticallySyncNewContent": "Automatically sync new content",
+ "OptionAutomaticallySyncNewContentHelp": "New content added to these folders will be automatically synced to the device.",
+ "OptionSyncUnwatchedVideosOnly": "Sync unwatched videos only",
+ "OptionSyncUnwatchedVideosOnlyHelp": "Only unwatched videos will be synced, and videos will be removed from the device as they are watched."
}
diff --git a/MediaBrowser.Server.Implementations/Localization/JavaScript/kk.json b/MediaBrowser.Server.Implementations/Localization/JavaScript/kk.json
index 371087bc4d..a3f9dc49e5 100644
--- a/MediaBrowser.Server.Implementations/Localization/JavaScript/kk.json
+++ b/MediaBrowser.Server.Implementations/Localization/JavaScript/kk.json
@@ -30,7 +30,7 @@
"HeaderConfirmation": "\u0420\u0430\u0441\u0442\u0430\u0443",
"MessageKeyUpdated": "\u049a\u043e\u043b\u0434\u0430\u0443\u0448\u044b \u043a\u0456\u043b\u0442\u0456\u04a3\u0456\u0437 \u0436\u0430\u04a3\u0430\u0440\u0442\u044b\u043b\u0434\u044b.",
"MessageKeyRemoved": "\u049a\u043e\u043b\u0434\u0430\u0443\u0448\u044b \u043a\u0456\u043b\u0442\u0456\u04a3\u0456\u0437 \u0430\u043b\u0430\u0441\u0442\u0430\u043b\u0434\u044b.",
- "ErrorLaunchingChromecast": "Chromecast \u0456\u0441\u043a\u0435 \u049b\u043e\u0441\u044b\u043b\u0443 \u043a\u0435\u0437\u0456\u043d\u0434\u0435 \u049b\u0430\u0442\u0435 \u043e\u0440\u044b\u043d \u0430\u043b\u0434\u044b. \u0416\u0430\u0431\u0434\u044b\u0493\u044b\u04a3\u044b\u0437 \u0441\u044b\u043c\u0441\u044b\u0437 \u0436\u0435\u043b\u0456\u0433\u0435 \u049b\u043e\u0441\u044b\u043b\u0493\u0430\u043d\u044b\u043d \u0442\u0435\u043a\u0441\u0435\u0440\u0456\u04a3\u0456\u0437.",
+ "ErrorLaunchingChromecast": "Chromecast \u0456\u0441\u043a\u0435 \u049b\u043e\u0441\u044b\u043b\u0443 \u043a\u0435\u0437\u0456\u043d\u0434\u0435 \u049b\u0430\u0442\u0435 \u043e\u0440\u044b\u043d \u0430\u043b\u0434\u044b. \u049a\u04b1\u0440\u044b\u043b\u0493\u044b\u04a3\u044b\u0437 \u0441\u044b\u043c\u0441\u044b\u0437 \u0436\u0435\u043b\u0456\u0433\u0435 \u049b\u043e\u0441\u044b\u043b\u0493\u0430\u043d\u044b\u043d \u0442\u0435\u043a\u0441\u0435\u0440\u0456\u04a3\u0456\u0437.",
"HeaderSearch": "\u0406\u0437\u0434\u0435\u0443",
"LabelArtist": "\u041e\u0440\u044b\u043d\u0434\u0430\u0443\u0448\u044b",
"LabelMovie": "\u0424\u0438\u043b\u044c\u043c",
@@ -119,7 +119,7 @@
"MessagePleaseSelectOneItem": "\u0415\u04a3 \u043a\u0435\u043c\u0456\u043d\u0434\u0435 \u0431\u0456\u0440 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u0442\u0456 \u0442\u0430\u04a3\u0434\u0430\u04a3\u044b\u0437.",
"MessagePleaseSelectTwoItems": "\u0415\u04a3 \u043a\u0435\u043c\u0456\u043d\u0434\u0435 \u0435\u043a\u0456 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u0442\u0456 \u0442\u0430\u04a3\u0434\u0430\u04a3\u044b\u0437.",
"MessageTheFollowingItemsWillBeGrouped": "\u041a\u0435\u043b\u0435\u0441\u0456 \u0442\u0443\u044b\u043d\u0434\u044b\u043b\u0430\u0440 \u0431\u0456\u0440 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u043a\u0435 \u0442\u043e\u043f\u0442\u0430\u0441\u0442\u044b\u0440\u044b\u043b\u0430\u0434\u044b:",
- "MessageConfirmItemGrouping": "Media Browser \u043a\u043b\u0438\u0435\u043d\u0442\u0442\u0435\u0440\u0456 \u0436\u0430\u0431\u0434\u044b\u049b \u0436\u04d9\u043d\u0435 \u0436\u0435\u043b\u0456 \u04e9\u043d\u0456\u043c\u0434\u0456\u043b\u0456\u043a\u0442\u0435\u0440\u0456\u043d\u0435 \u043d\u0435\u0433\u0456\u0437\u0434\u0435\u043b\u0456\u043d\u0456\u043f \u043e\u0439\u043d\u0430\u0442\u0443 \u04af\u0448\u0456\u043d \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0442\u044b \u0442\u04af\u0440\u0434\u0435 \u043e\u04a3\u0442\u0430\u0439\u043b\u044b \u043d\u04b1\u0441\u049b\u0430\u0441\u044b\u043d \u0442\u0430\u04a3\u0434\u0430\u0439\u0434\u044b. \u0428\u044b\u043d\u044b\u043c\u0435\u043d \u0436\u0430\u043b\u0493\u0430\u0441\u0442\u044b\u0440\u0443 \u049b\u0430\u0436\u0435\u0442 \u043f\u0435?",
+ "MessageConfirmItemGrouping": "Media Browser \u043a\u043b\u0438\u0435\u043d\u0442\u0442\u0435\u0440\u0456 \u049b\u04b1\u0440\u044b\u043b\u0493\u044b \u0436\u04d9\u043d\u0435 \u0436\u0435\u043b\u0456 \u04e9\u043d\u0456\u043c\u0434\u0456\u043b\u0456\u043a\u0442\u0435\u0440\u0456\u043d\u0435 \u043d\u0435\u0433\u0456\u0437\u0434\u0435\u043b\u0456\u043d\u0456\u043f \u043e\u0439\u043d\u0430\u0442\u0443 \u04af\u0448\u0456\u043d \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0442\u044b \u0442\u04af\u0440\u0434\u0435 \u043e\u04a3\u0442\u0430\u0439\u043b\u044b \u043d\u04b1\u0441\u049b\u0430\u0441\u044b\u043d \u0442\u0430\u04a3\u0434\u0430\u0439\u0434\u044b. \u0428\u044b\u043d\u044b\u043c\u0435\u043d \u0436\u0430\u043b\u0493\u0430\u0441\u0442\u044b\u0440\u0443 \u049b\u0430\u0436\u0435\u0442 \u043f\u0435?",
"HeaderResume": "\u0416\u0430\u043b\u0493\u0430\u0441\u0442\u044b\u0440\u0443",
"HeaderMyViews": "\u041c\u0435\u043d\u0456\u04a3 \u0430\u0441\u043f\u0435\u043a\u0442\u0442\u0435\u0440\u0456\u043c",
"HeaderLibraryFolders": "\u0422\u0430\u0441\u0443\u0448\u044b \u049b\u0430\u043b\u0442\u0430\u043b\u0430\u0440\u044b",
@@ -194,7 +194,7 @@
"LabelCurrentPath": "\u0410\u0493\u044b\u043c\u0434\u044b\u049b \u0436\u043e\u043b:",
"HeaderSelectMediaPath": "\u0422\u0430\u0441\u0443\u0448\u044b \u0436\u043e\u043b\u044b\u043d \u0442\u0430\u04a3\u0434\u0430\u0443",
"ButtonNetwork": "\u0416\u0435\u043b\u0456",
- "MessageDirectoryPickerInstruction": "\u0416\u0435\u043b\u0456 \u0442\u04af\u0439\u043c\u0435\u0448\u0456\u0433\u0456 \u0431\u0430\u0441\u044b\u043b\u0493\u0430\u043d\u0434\u0430 \u0436\u0430\u0431\u0434\u044b\u049b\u0442\u0430\u0440 \u043e\u0440\u043d\u044b \u0442\u0430\u0431\u044b\u043b\u043c\u0430\u0441\u0430, \u0436\u0435\u043b\u0456\u043b\u0456\u043a \u0436\u043e\u043b\u0434\u0430\u0440 \u049b\u043e\u043b\u043c\u0435\u043d \u0435\u043d\u0433\u0456\u0437\u0456\u043b\u0443\u0456 \u043c\u04af\u043c\u043a\u0456\u043d. \u041c\u044b\u0441\u0430\u043b\u044b, {0} \u043d\u0435\u043c\u0435\u0441\u0435 {1}.",
+ "MessageDirectoryPickerInstruction": "\u0416\u0435\u043b\u0456 \u0442\u04af\u0439\u043c\u0435\u0448\u0456\u0433\u0456 \u0431\u0430\u0441\u044b\u043b\u0493\u0430\u043d\u0434\u0430 \u049b\u04b1\u0440\u044b\u043b\u0493\u044b\u043b\u0430\u0440\u044b\u04a3\u044b\u0437 \u043e\u0440\u043d\u044b \u0442\u0430\u0431\u044b\u043b\u043c\u0430\u0441\u0430, \u0436\u0435\u043b\u0456\u043b\u0456\u043a \u0436\u043e\u043b\u0434\u0430\u0440 \u049b\u043e\u043b\u043c\u0435\u043d \u0435\u043d\u0433\u0456\u0437\u0456\u043b\u0443\u0456 \u043c\u04af\u043c\u043a\u0456\u043d. \u041c\u044b\u0441\u0430\u043b\u044b, {0} \u043d\u0435\u043c\u0435\u0441\u0435 {1}.",
"HeaderMenu": "\u041c\u04d9\u0437\u0456\u0440",
"ButtonOpen": "\u0410\u0448\u0443",
"ButtonOpenInNewTab": "\u0416\u0430\u04a3\u0430 \u049b\u043e\u0439\u044b\u043d\u0434\u044b\u0434\u0430 \u0430\u0448\u0443",
@@ -573,18 +573,18 @@
"LabelShortRatingDescription": "\u0411\u0430\u0493\u0430\u043b\u0430\u0443\u0434\u044b\u04a3 \u049b\u044b\u0441\u049b\u0430 \u0430\u049b\u043f\u0430\u0440\u044b:",
"OptionIRecommendThisItem": "\u041e\u0441\u044b \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u0442\u0456 \u04b1\u0441\u044b\u043d\u0430\u043c\u044b\u043d",
"WebClientTourContent": "\u0416\u0430\u049b\u044b\u043d\u0434\u0430 \u04af\u0441\u0442\u0435\u043b\u0433\u0435\u043d \u0442\u0430\u0441\u0443\u0448\u044b\u0434\u0435\u0440\u0435\u043a\u0442\u0435\u0440\u0434\u0456, \u043a\u0435\u043b\u0435\u0441\u0456 \u044d\u043f\u0438\u0437\u043e\u0434\u0442\u0430\u0440\u0434\u044b \u0436\u04d9\u043d\u0435 \u0442.\u0431. \u049b\u0430\u0440\u0430\u04a3\u044b\u0437. \u0416\u0430\u0441\u044b\u043b \u0448\u0435\u043d\u0431\u0435\u0440\u043b\u0435\u0440 \u0441\u0456\u0437\u0434\u0435 \u049b\u0430\u043d\u0448\u0430 \u043e\u0439\u043d\u0430\u0442\u044b\u043b\u043c\u0430\u0493\u0430\u043d \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u0442\u0435\u0440 \u0431\u0430\u0440\u044b\u043d \u043a\u04e9\u0440\u0441\u0435\u0442\u0435\u0434\u0456.",
- "WebClientTourMovies": "\u0492\u0430\u043b\u0430\u043c\u0442\u043e\u0440 \u0431\u0440\u0430\u0443\u0437\u0435\u0440\u0456 \u0431\u0430\u0440 \u0436\u0430\u0431\u0434\u044b\u049b\u0442\u0430\u0440 \u0430\u0440\u049b\u044b\u043b\u044b \u0444\u0438\u043b\u044c\u043c\u0434\u0435\u0440\u0434\u0456, \u0442\u0440\u0435\u0439\u043b\u0435\u0440\u043b\u0435\u0440\u0434\u0456 \u0436\u04d9\u043d\u0435 \u0442.\u0431. \u043e\u0439\u043d\u0430\u0442\u044b\u04a3\u044b\u0437.",
+ "WebClientTourMovies": "\u0492\u0430\u043b\u0430\u043c\u0442\u043e\u0440 \u0431\u0440\u0430\u0443\u0437\u0435\u0440\u0456 \u0431\u0430\u0440 \u049b\u04b1\u0440\u044b\u043b\u0493\u044b\u043b\u0430\u0440 \u0430\u0440\u049b\u044b\u043b\u044b \u0444\u0438\u043b\u044c\u043c\u0434\u0435\u0440\u0434\u0456, \u0442\u0440\u0435\u0439\u043b\u0435\u0440\u043b\u0435\u0440\u0434\u0456 \u0436\u04d9\u043d\u0435 \u0442.\u0431. \u043e\u0439\u043d\u0430\u0442\u044b\u04a3\u044b\u0437.",
"WebClientTourMouseOver": "\u041c\u0430\u04a3\u044b\u0437\u0434\u044b \u0430\u049b\u043f\u0430\u0440\u0430\u0442\u049b\u0430 \u0436\u044b\u043b\u0434\u0430\u043c \u049b\u0430\u0442\u044b\u043d\u0430\u0441\u0443 \u04af\u0448\u0456\u043d \u049b\u0430\u0439\u0441\u044b\u0431\u0456\u0440 \u043f\u043e\u0441\u0442\u0435\u0440\u0434\u0456\u04a3 \u04b1\u0441\u0442\u0456\u043d\u0434\u0435 \u0442\u0456\u043d\u0442\u0443\u0440\u0434\u0456\u04a3 \u043a\u04e9\u0440\u0441\u0435\u0442\u043a\u0456\u0448\u0456\u043d \u04b1\u0441\u0442\u0430\u043f \u0442\u04b1\u0440\u044b\u04a3\u044b\u0437",
"WebClientTourTapHold": "\u041c\u04d9\u0442\u0456\u043d\u043c\u04d9\u043d\u0434\u0456\u043a \u043c\u04d9\u0437\u0456\u0440 \u04af\u0448\u0456\u043d \u049b\u0430\u0439\u0441\u044b\u0431\u0456\u0440 \u043f\u043e\u0441\u0442\u0435\u0440\u0434\u0456 \u0442\u04af\u0440\u0442\u0456\u043f \u04b1\u0441\u0442\u0430\u043f \u0442\u04b1\u0440\u044b\u04a3\u044b\u0437 \u043d\u0435\u043c\u0435\u0441\u0435 \u0442\u0456\u043d\u0442\u0443\u0456\u0440\u0434\u0456\u04a3 \u043e\u04a3 \u0436\u0430\u049b \u0442\u04af\u0439\u043c\u0435\u0448\u0456\u0433\u0456\u043d \u0431\u0430\u0441\u044b\u04a3\u044b\u0437",
"WebClientTourMetadataManager": "\u041c\u0435\u0442\u0430\u0434\u0435\u0440\u0435\u043a \u0431\u0430\u0441\u049b\u0430\u0440\u0443\u0448\u044b\u0441\u044b\u043d\u0438 \u0430\u0448\u0443 \u04af\u0448\u0456\u043d \u04e8\u04a3\u0434\u0435\u0443 \u0434\u0435\u0433\u0435\u043d\u0434\u0456 \u0431\u0430\u0441\u044b\u04a3\u044b\u0437",
- "WebClientTourPlaylists": "\u041e\u0439\u043d\u0430\u0442\u0443 \u0442\u0456\u0437\u0456\u043c\u0434\u0435\u0440\u0456\u043d \u0436\u04d9\u043d\u0435 \u043b\u0435\u0437\u0434\u0456\u043a \u049b\u043e\u0441\u043f\u0430\u043b\u0430\u0440\u0434\u044b \u0436\u0435\u04a3\u0456\u043b \u0436\u0430\u0441\u0430\u04a3\u044b\u0437, \u0436\u04d9\u043d\u0435 \u043e\u043b\u0430\u0440\u0434\u044b \u04d9\u0440\u049b\u0430\u0439\u0441\u044b \u0436\u0430\u0431\u0434\u044b\u049b\u0442\u0430 \u043e\u0439\u043d\u0430\u0442\u044b\u04a3\u044b\u0437",
+ "WebClientTourPlaylists": "\u041e\u0439\u043d\u0430\u0442\u0443 \u0442\u0456\u0437\u0456\u043c\u0434\u0435\u0440\u0456\u043d \u0436\u04d9\u043d\u0435 \u043b\u0435\u0437\u0434\u0456\u043a \u049b\u043e\u0441\u043f\u0430\u043b\u0430\u0440\u0434\u044b \u0436\u0435\u04a3\u0456\u043b \u0436\u0430\u0441\u0430\u04a3\u044b\u0437, \u0436\u04d9\u043d\u0435 \u043e\u043b\u0430\u0440\u0434\u044b \u04d9\u0440\u049b\u0430\u0439\u0441\u044b \u049b\u04b1\u0440\u044b\u043b\u0493\u044b\u0434\u0430 \u043e\u0439\u043d\u0430\u0442\u044b\u04a3\u044b\u0437",
"WebClientTourCollections": "\u0424\u0438\u043b\u044c\u043c\u0434\u0435\u0440\u0434\u0456 \u0431\u0456\u0440\u0433\u0435 \u0442\u043e\u043f\u0442\u0430\u0443 \u04af\u0448\u0456\u043d \u0444\u0438\u043b\u044c\u043c \u0436\u0438\u044b\u043d\u0442\u044b\u049b\u0442\u0430\u0440\u044b\u043d \u0436\u0430\u0441\u0430\u04a3\u044b\u0437",
"WebClientTourUserPreferences1": "\u041f\u0430\u0439\u0434\u0430\u043b\u0430\u043d\u0443\u0448\u044b \u0442\u0435\u04a3\u0448\u0435\u043b\u0456\u043c\u0434\u0435\u0440\u0456 Media Browser \u049b\u043e\u043b\u0434\u0430\u043d\u0431\u0430\u043b\u0430\u0440\u044b\u043d\u0434\u0430 \u0442\u0430\u0441\u0443\u0448\u044b\u0445\u0430\u043d\u0430\u04a3\u044b\u0437\u0434\u044b \u043a\u04e9\u0440\u0441\u0435\u0442\u0456\u043b\u0443 \u0436\u043e\u043b\u044b\u043d \u0442\u0435\u04a3\u0448\u0435\u0443\u0456\u043d\u0435 \u0441\u0456\u0437\u0433\u0435 \u0440\u04b1\u049b\u0441\u0430\u0442 \u0435\u0442\u0435\u0434\u0456",
"WebClientTourUserPreferences2": "\u04d8\u0440\u0431\u0456\u0440 Media Browser \u049b\u043e\u043b\u0434\u0430\u043d\u0431\u0430\u0441\u044b \u04af\u0448\u0456\u043d, \u0434\u044b\u0431\u044b\u0441 \u043f\u0435\u043d \u0441\u0443\u0431\u0442\u0438\u0442\u0440\u043b\u0435\u0440 \u0442\u0456\u043b\u0434\u0456\u043a \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u043b\u0435\u0440\u0456\u043d \u0431\u0456\u0440 \u0440\u0435\u0442 \u0442\u0435\u04a3\u0448\u0435\u04a3\u0456\u0437",
"WebClientTourUserPreferences3": "\u04b0\u043d\u0430\u0442\u0443\u044b\u04a3\u044b\u0437 \u0431\u043e\u0439\u044b\u043d\u0448\u0430 \u0493\u0430\u043b\u0430\u043c\u0442\u043e\u0440 \u043a\u043b\u0438\u0435\u043d\u0442\u0456\u043d\u0456\u04a3 \u0431\u0430\u0441\u0442\u044b \u0431\u0435\u0442\u0456\u043d \u049b\u0430\u0439\u0442\u0430 \u0440\u0435\u0441\u0456\u043c\u0434\u0435\u04a3\u0456\u0437",
"WebClientTourUserPreferences4": "\u0410\u0440\u0442\u049b\u044b \u0441\u0443\u0440\u0435\u0442\u0442\u0435\u0440\u0434\u0456, \u0442\u0430\u049b\u044b\u0440\u044b\u043f\u0442\u044b\u049b \u04d9\u0443\u0435\u043d\u0434\u0435\u0440\u0434\u0456 \u0436\u04d9\u043d\u0435 \u0441\u044b\u0440\u0442\u049b\u044b \u043e\u0439\u043d\u0430\u0442\u049b\u044b\u0448\u0442\u0430\u0440\u0434\u044b \u0442\u0435\u04a3\u0448\u0435\u04a3\u0456\u0437",
"WebClientTourMobile1": "\u0492\u0430\u043b\u0430\u043c\u0442\u043e\u0440 \u043a\u043b\u0438\u0435\u043d\u0442\u0456 \u0441\u043c\u0430\u0440\u0442\u0444\u043e\u043d\u0434\u0430\u0440\u0434\u0430 \u0436\u04d9\u043d\u0435 \u043f\u043b\u0430\u043d\u0448\u0435\u0442\u0442\u0435\u0440\u0434\u0435 \u0442\u0430\u043c\u0430\u0448\u0430 \u0436\u04b1\u043c\u044b\u0441 \u0456\u0441\u0442\u0435\u0439\u0434\u0456",
- "WebClientTourMobile2": "\u0441\u043e\u043d\u044b\u043c\u0435\u043d \u049b\u0430\u0442\u0430\u0440 \u0431\u0430\u0441\u049b\u0430 \u0436\u0430\u0431\u0434\u044b\u049b\u0442\u0430\u0440\u0434\u044b \u0436\u04d9\u043d\u0435 Media Browser \u049b\u043e\u043b\u0434\u0430\u043d\u0431\u0430\u043b\u0430\u0440\u044b\u043d \u0431\u0430\u0441\u049b\u0430\u0440\u0430\u0434\u044b",
+ "WebClientTourMobile2": "\u0441\u043e\u043d\u044b\u043c\u0435\u043d \u049b\u0430\u0442\u0430\u0440 \u0431\u0430\u0441\u049b\u0430 \u049b\u04b1\u0440\u044b\u043b\u0493\u044b\u043b\u0430\u0440\u0434\u044b \u0436\u04d9\u043d\u0435 Media Browser \u049b\u043e\u043b\u0434\u0430\u043d\u0431\u0430\u043b\u0430\u0440\u044b\u043d \u0431\u0430\u0441\u049b\u0430\u0440\u0430\u0434\u044b",
"MessageEnjoyYourStay": "\u0416\u0430\u0493\u044b\u043c\u0434\u044b \u0435\u0440\u043c\u0435\u043a \u0435\u0442\u0456\u04a3\u0456\u0437",
"DashboardTourDashboard": "\u0421\u0435\u0440\u0432\u0435\u0440\u0434\u0456\u04a3 \u0431\u0430\u049b\u044b\u043b\u0430\u0443 \u0442\u0430\u049b\u0442\u0430\u0441\u044b \u0441\u0435\u0440\u0432\u0435\u0440\u0434\u0456 \u0436\u04d9\u043d\u0435 \u043f\u0430\u0439\u0434\u0430\u043b\u0430\u043d\u0443\u0448\u044b\u043b\u0430\u0440\u0434\u044b \u0431\u0430\u049b\u044b\u043b\u0430\u0443\u044b \u043c\u04af\u043c\u043a\u0456\u043d\u0434\u0456\u0433\u0456\u043d\u0435 \u0440\u04b1\u049b\u0441\u0430\u0442 \u0435\u0442\u0435\u0434\u0456. \u041a\u0456\u043c \u043d\u0435 \u0456\u0441\u0442\u0435\u0433\u0435\u043d\u0456\u043d \u0436\u04d9\u043d\u0435 \u049b\u0430\u0439\u0434\u0430 \u0442\u04b1\u0440\u0493\u0430\u043d\u044b\u043d \u0431\u0456\u043b\u0456\u043f \u0436\u0430\u0442\u0430\u0441\u044b\u0437.",
"DashboardTourUsers": "\u0414\u043e\u0441\u0442\u0430\u0440\u044b\u04a3\u044b\u0437 \u0431\u0435\u043d \u043e\u0442\u0431\u0430\u0441\u044b\u04a3\u044b\u0437 \u04d9\u0440\u049b\u0430\u0439\u0441\u044b\u043d\u0430 \u04e9\u0437\u0456\u043d\u0456\u04a3 \u049b\u04b1\u049b\u044b\u049b\u0442\u0430\u0440\u044b, \u0442\u0430\u0441\u0443\u0448\u044b\u0445\u0430\u043d\u0430 \u049b\u0430\u0442\u044b\u043d\u0430\u0441\u0443\u044b, \u043c\u0430\u0437\u043c\u04b1\u043d \u0431\u0430\u0441\u049b\u0430\u0440\u0443\u044b \u0436\u04d9\u043d\u0435 \u0442.\u0431. \u0431\u0430\u0440 \u0442\u0456\u0440\u043a\u0435\u043b\u0433\u0456\u043b\u0435\u0440\u0456\u043d \u0436\u0435\u04a3\u0456\u043b \u0436\u0430\u0441\u0430\u04a3\u044b\u0437.",
@@ -592,14 +592,14 @@
"DashboardTourChapters": "\u0411\u0435\u0439\u043d\u0435\u043b\u0435\u0440\u0434\u0456 \u049b\u0430\u0440\u0430\u0493\u0430\u043d \u043a\u0435\u0437\u0434\u0435 \u04b1\u043d\u0430\u043c\u0434\u044b\u043b\u0430\u0443 \u043a\u04e9\u0440\u0441\u0435\u0442\u0456\u043c \u04af\u0448\u0456\u043d \u0441\u0430\u0445\u043d\u0430 \u0441\u0443\u0440\u0435\u0442\u0442\u0435\u0440\u0456\u043d \u0442\u0443\u0434\u044b\u0440\u0443\u044b\u043d \u049b\u043e\u0441\u044b\u04a3\u044b\u0437.",
"DashboardTourSubtitles": "\u0411\u0435\u0439\u043d\u0435\u043b\u0435\u0440\u0433\u0435 \u049b\u0430\u0439 \u0442\u0456\u043b\u0434\u0435 \u0431\u043e\u043b\u0441\u044b\u043d \u0441\u0443\u0431\u0442\u0438\u0442\u0440\u043b\u0435\u0440\u0434\u0456 \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0442\u044b \u0442\u04af\u0440\u0434\u0435 \u0436\u04af\u043a\u0442\u0435\u04a3\u0456\u0437.",
"DashboardTourPlugins": "\u041f\u043b\u0430\u0433\u0438\u043d\u0434\u0435\u0440\u0434\u0456, \u043c\u044b\u0441\u0430\u043b\u044b, \u0431\u0435\u0439\u043d\u0435\u043b\u0456\u043a \u0438\u043d\u0442\u0435\u0440\u043d\u0435\u0442-\u0430\u0440\u043d\u0430\u043b\u0430\u0440\u044b\u043d, \u044d\u0444\u0438\u0440\u043b\u0456\u043a \u0442\u0434, \u043c\u0435\u0442\u0430\u0434\u0435\u0440\u0435\u043a\u0442\u0435\u0440 \u0441\u043a\u0430\u043d\u0435\u0440\u043b\u0435\u0440\u0456\u043d \u0436\u0456\u043d\u0435 \u0442.\u0431., \u043e\u0440\u043d\u0430\u0442\u044b\u04a3\u044b\u0437.",
- "DashboardTourNotifications": "\u0421\u0435\u0440\u0432\u0435\u0440 \u043e\u049b\u0438\u0493\u0430\u043b\u0430\u0440\u044b \u0442\u0443\u0440\u0430\u043b\u044b \u0445\u0430\u0431\u0430\u0440\u043b\u0430\u043d\u0434\u044b\u0440\u0443\u043b\u0430\u0440\u0434\u044b \u04b1\u0442\u049b\u044b\u0440 \u0436\u0430\u0431\u0434\u044b\u0493\u044b\u04a3\u044b\u0437\u0493\u0430, \u044d-\u043f\u043e\u0448\u0442\u0430\u04a3\u044b\u0437\u0493\u0430 \u0436\u04d9\u043d\u0435 \u0442.\u0431.\u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0442\u044b \u0442\u04af\u0440\u0434\u0435 \u0436\u0456\u0431\u0435\u0440\u0456\u04a3\u0456\u0437.",
+ "DashboardTourNotifications": "\u0421\u0435\u0440\u0432\u0435\u0440 \u043e\u049b\u0438\u0493\u0430\u043b\u0430\u0440\u044b \u0442\u0443\u0440\u0430\u043b\u044b \u0445\u0430\u0431\u0430\u0440\u043b\u0430\u043d\u0434\u044b\u0440\u0443\u043b\u0430\u0440\u0434\u044b \u04b1\u0442\u049b\u044b\u0440 \u049b\u04b1\u0440\u044b\u043b\u0493\u044b\u04a3\u044b\u0437\u0493\u0430, \u044d-\u043f\u043e\u0448\u0442\u0430\u04a3\u044b\u0437\u0493\u0430 \u0436\u04d9\u043d\u0435 \u0442.\u0431.\u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0442\u044b \u0442\u04af\u0440\u0434\u0435 \u0436\u0456\u0431\u0435\u0440\u0456\u04a3\u0456\u0437.",
"DashboardTourScheduledTasks": "\u0416\u043e\u0441\u043f\u0430\u0440\u043b\u0430\u0493\u0430\u043d \u0442\u0430\u043f\u0441\u044b\u0440\u043c\u0430\u043b\u0430\u0440 \u0430\u0440\u049b\u044b\u043b\u044b \u04b1\u0437\u0430\u049b \u043e\u0440\u044b\u043d\u0434\u0430\u043b\u0430\u0442\u044b\u043d \u04d9\u0440\u0435\u043a\u0435\u0442\u0442\u0435\u0440\u0434\u0456 \u0436\u0435\u04a3\u0456\u043b \u0431\u0430\u0441\u049b\u0430\u0440\u044b\u04a3\u044b\u0437. \u0411\u04b1\u043b\u0430\u0440 \u049b\u0430\u0448\u0430\u043d \u0436\u04d9\u043d\u0435 \u049b\u0430\u043d\u0434\u0430\u0439 \u0436\u0438\u0456\u043b\u0456\u043a\u043f\u0435\u043d \u043e\u0440\u044b\u043d\u0434\u0430\u043b\u0430\u0442\u044b\u043d\u044b\u043d \u0448\u0435\u0448\u0456\u04a3\u0456\u0437.",
"DashboardTourMobile": "Media Browser \u0431\u0430\u049b\u044b\u043b\u0430\u0443 \u0442\u0430\u049b\u0442\u0430\u0441\u044b \u0441\u043c\u0430\u0440\u0442\u0444\u043e\u043d\u0434\u0430\u0440\u0434\u0430 \u0436\u04d9\u043d\u0435 \u043f\u043b\u0430\u043d\u0448\u0435\u0442\u0442\u0435\u0440\u0434\u0435 \u0442\u0430\u043c\u0430\u0448\u0430 \u0436\u04b1\u043c\u044b\u0441 \u0456\u0441\u0442\u0435\u0439\u0434\u0456. \u0421\u0435\u0440\u0432\u0435\u0440\u0456\u04a3\u0456\u0437\u0434\u0456 \u04d9\u0440 \u0443\u0430\u049b\u044b\u0442\u0442\u0430, \u04d9\u0440 \u0436\u0435\u0440\u0434\u0435 \u049b\u043e\u043b\u044b\u04a3\u044b\u0437\u0434\u044b\u04a3 \u0430\u043b\u0430\u049b\u0430\u043d\u044b\u043d\u0430\u043d \u0431\u0430\u0441\u049b\u0430\u0440\u044b\u04a3\u044b\u0437.",
"MessageRefreshQueued": "\u041a\u04e9\u043a\u0435\u0439\u0442\u0435\u0441\u0442\u0456 \u0435\u0442\u0443\u0456 \u043a\u0435\u0437\u0435\u043a\u0442\u0435",
- "TabDevices": "\u0416\u0430\u0431\u0434\u044b\u049b\u0442\u0430\u0440",
+ "TabDevices": "\u049a\u04b1\u0440\u044b\u043b\u0493\u044b\u043b\u0430\u0440",
"DeviceLastUsedByUserName": "{0} \u0430\u0440\u049b\u044b\u043b\u044b \u0435\u04a3 \u043a\u0435\u0439\u0456\u043d\u0433\u0456 \u043f\u0430\u0439\u0434\u0430\u043b\u0430\u043d\u044b\u043b\u0493\u0430\u043d",
- "HeaderDeleteDevice": "\u0416\u0430\u0431\u0434\u044b\u049b\u0442\u044b \u0436\u043e\u044e",
- "DeleteDeviceConfirmation": "\u0428\u044b\u043d\u044b\u043c\u0435\u043d \u043e\u0441\u044b \u0436\u0430\u0431\u0434\u044b\u049b\u0442\u044b \u0436\u043e\u044e \u049b\u0430\u0436\u0435\u0442 \u043f\u0435? \u0411\u04b1\u043b \u043a\u0435\u043b\u0435\u0441\u0456 \u0440\u0435\u0442\u0442\u0435 \u043f\u0430\u0439\u0434\u0430\u043b\u0430\u043d\u0443\u0448\u044b \u043e\u0441\u044b\u0434\u0430\u043d \u043a\u0456\u0440\u0433\u0435\u043d\u0434\u0435 \u049b\u0430\u0439\u0442\u0430 \u043f\u0430\u0439\u0434\u0430 \u0431\u043e\u043b\u0430\u0434\u044b.",
+ "HeaderDeleteDevice": "\u049a\u04b1\u0440\u044b\u043b\u0493\u044b\u043d\u044b \u0436\u043e\u044e",
+ "DeleteDeviceConfirmation": "\u0428\u044b\u043d\u044b\u043c\u0435\u043d \u043e\u0441\u044b \u049b\u04b1\u0440\u044b\u043b\u0493\u044b\u043d\u044b \u0436\u043e\u044e \u049b\u0430\u0436\u0435\u0442 \u043f\u0435? \u0411\u04b1\u043b \u043a\u0435\u043b\u0435\u0441\u0456 \u0440\u0435\u0442\u0442\u0435 \u043f\u0430\u0439\u0434\u0430\u043b\u0430\u043d\u0443\u0448\u044b \u043e\u0441\u044b\u0434\u0430\u043d \u043a\u0456\u0440\u0433\u0435\u043d\u0434\u0435 \u049b\u0430\u0439\u0442\u0430 \u043f\u0430\u0439\u0434\u0430 \u0431\u043e\u043b\u0430\u0434\u044b.",
"LabelEnableCameraUploadFor": "\u041c\u044b\u043d\u0430\u0443 \u04af\u0448\u0456\u043d \u043a\u0430\u043c\u0435\u0440\u0430\u0434\u0430\u043d \u043a\u0435\u0440\u0456 \u049b\u043e\u0442\u0430\u0440\u0443:",
"HeaderSelectUploadPath": "\u041a\u0435\u0440\u0456 \u049b\u043e\u0442\u0430\u0440\u0443 \u0436\u043e\u043b\u044b\u043d \u0442\u0430\u04a3\u0434\u0430\u0443",
"LabelEnableCameraUploadForHelp": "Media Browser \u0456\u0448\u0456\u043d\u0435 \u043a\u0456\u0440\u0433\u0435\u043d\u0434\u0435 \u043a\u0435\u0440\u0456 \u049b\u043e\u0442\u0430\u0440\u0443\u043b\u0430\u0440 \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0442\u044b \u0442\u04af\u0440\u0434\u0435 \u04e9\u043d\u0434\u0456\u043a \u0440\u0435\u0436\u0456\u043c\u0456\u043d\u0434\u0435 \u04e9\u0442\u0435\u0434\u0456.",
@@ -626,5 +626,23 @@
"MessagePasswordResetForUsers": "\u049a\u04b1\u043f\u0438\u044f \u0441\u04e9\u0437\u0434\u0435\u0440 \u043a\u0435\u043b\u0435\u0441\u0456 \u043f\u0430\u0439\u0434\u0430\u043b\u0430\u043d\u0443\u0448\u044b\u043b\u0430\u0440 \u04af\u0448\u0456\u043d \u044b\u0441\u044b\u0440\u044b\u043b\u0434\u044b:",
"HeaderInviteGuest": "\u049a\u043e\u043d\u0430\u049b\u0442\u044b \u0448\u0430\u049b\u044b\u0440\u0443",
"ButtonLinkMyMediaBrowserAccount": "\u0422\u0456\u0440\u043a\u0435\u043b\u0433\u0456\u043c\u0434\u0456 \u0431\u0430\u0439\u043b\u0430\u043d\u044b\u0441\u0442\u044b\u0440\u0443",
- "MessageConnectAccountRequiredToInviteGuest": "\u049a\u043e\u043d\u0430\u049b\u0442\u0430\u0440\u0434\u044b \u0448\u0430\u049b\u044b\u0440\u0443 \u04af\u0448\u0456\u043d \u0435\u04a3 \u0430\u043b\u0434\u044b\u043d\u0434\u0430 \u043e\u0441\u044b \u0441\u0435\u0440\u0432\u0435\u0440\u0433\u0435 Media Browser \u0442\u0456\u0440\u043a\u0435\u043b\u0433\u0456\u04a3\u0456\u0437\u0434\u0456 \u0431\u0430\u0439\u043b\u0430\u043d\u044b\u0441\u0442\u0440\u0443\u044b\u04a3\u044b\u0437 \u049b\u0430\u0436\u0435\u0442."
+ "MessageConnectAccountRequiredToInviteGuest": "\u049a\u043e\u043d\u0430\u049b\u0442\u0430\u0440\u0434\u044b \u0448\u0430\u049b\u044b\u0440\u0443 \u04af\u0448\u0456\u043d \u0435\u04a3 \u0430\u043b\u0434\u044b\u043d\u0434\u0430 \u043e\u0441\u044b \u0441\u0435\u0440\u0432\u0435\u0440\u0433\u0435 Media Browser \u0442\u0456\u0440\u043a\u0435\u043b\u0433\u0456\u04a3\u0456\u0437\u0434\u0456 \u0431\u0430\u0439\u043b\u0430\u043d\u044b\u0441\u0442\u0440\u0443\u044b\u04a3\u044b\u0437 \u049b\u0430\u0436\u0435\u0442.",
+ "ButtonSync": "\u0421\u0438\u043d\u0445\u0440\u043e",
+ "SyncMedia": "Sync Media",
+ "HeaderCancelSyncJob": "Cancel Sync",
+ "CancelSyncJobConfirmation": "Are you sure you wish to cancel this sync job?",
+ "TabSync": "\u0421\u0438\u043d\u0445\u0440\u043e\u043d\u0434\u0430\u0443",
+ "MessagePleaseSelectDeviceToSyncTo": "Please select a device to sync to.",
+ "MessageSyncJobCreated": "Sync job created.",
+ "LabelSyncTo": "Sync to:",
+ "LabelSyncJobName": "Sync job name:",
+ "LabelQuality": "Quality:",
+ "OptionHigh": "High",
+ "OptionMedium": "Medium",
+ "OptionLow": "Low",
+ "HeaderSettings": "Settings",
+ "OptionAutomaticallySyncNewContent": "Automatically sync new content",
+ "OptionAutomaticallySyncNewContentHelp": "New content added to these folders will be automatically synced to the device.",
+ "OptionSyncUnwatchedVideosOnly": "Sync unwatched videos only",
+ "OptionSyncUnwatchedVideosOnlyHelp": "Only unwatched videos will be synced, and videos will be removed from the device as they are watched."
} \ No newline at end of file
diff --git a/MediaBrowser.Server.Implementations/Localization/JavaScript/ms.json b/MediaBrowser.Server.Implementations/Localization/JavaScript/ms.json
index 95d07be553..89aefed9d4 100644
--- a/MediaBrowser.Server.Implementations/Localization/JavaScript/ms.json
+++ b/MediaBrowser.Server.Implementations/Localization/JavaScript/ms.json
@@ -626,5 +626,23 @@
"MessagePasswordResetForUsers": "Passwords have been reset for the following users:",
"HeaderInviteGuest": "Invite Guest",
"ButtonLinkMyMediaBrowserAccount": "Link my account now",
- "MessageConnectAccountRequiredToInviteGuest": "In order to invite guests you need to first link your Media Browser account to this server."
+ "MessageConnectAccountRequiredToInviteGuest": "In order to invite guests you need to first link your Media Browser account to this server.",
+ "ButtonSync": "Sync",
+ "SyncMedia": "Sync Media",
+ "HeaderCancelSyncJob": "Cancel Sync",
+ "CancelSyncJobConfirmation": "Are you sure you wish to cancel this sync job?",
+ "TabSync": "Sync",
+ "MessagePleaseSelectDeviceToSyncTo": "Please select a device to sync to.",
+ "MessageSyncJobCreated": "Sync job created.",
+ "LabelSyncTo": "Sync to:",
+ "LabelSyncJobName": "Sync job name:",
+ "LabelQuality": "Quality:",
+ "OptionHigh": "High",
+ "OptionMedium": "Medium",
+ "OptionLow": "Low",
+ "HeaderSettings": "Settings",
+ "OptionAutomaticallySyncNewContent": "Automatically sync new content",
+ "OptionAutomaticallySyncNewContentHelp": "New content added to these folders will be automatically synced to the device.",
+ "OptionSyncUnwatchedVideosOnly": "Sync unwatched videos only",
+ "OptionSyncUnwatchedVideosOnlyHelp": "Only unwatched videos will be synced, and videos will be removed from the device as they are watched."
} \ No newline at end of file
diff --git a/MediaBrowser.Server.Implementations/Localization/JavaScript/nb.json b/MediaBrowser.Server.Implementations/Localization/JavaScript/nb.json
index 66c5fa8625..a5fd9bb9b4 100644
--- a/MediaBrowser.Server.Implementations/Localization/JavaScript/nb.json
+++ b/MediaBrowser.Server.Implementations/Localization/JavaScript/nb.json
@@ -626,5 +626,23 @@
"MessagePasswordResetForUsers": "Passwords have been reset for the following users:",
"HeaderInviteGuest": "Invite Guest",
"ButtonLinkMyMediaBrowserAccount": "Link my account now",
- "MessageConnectAccountRequiredToInviteGuest": "In order to invite guests you need to first link your Media Browser account to this server."
+ "MessageConnectAccountRequiredToInviteGuest": "In order to invite guests you need to first link your Media Browser account to this server.",
+ "ButtonSync": "Synk",
+ "SyncMedia": "Sync Media",
+ "HeaderCancelSyncJob": "Cancel Sync",
+ "CancelSyncJobConfirmation": "Are you sure you wish to cancel this sync job?",
+ "TabSync": "Synk",
+ "MessagePleaseSelectDeviceToSyncTo": "Please select a device to sync to.",
+ "MessageSyncJobCreated": "Sync job created.",
+ "LabelSyncTo": "Sync to:",
+ "LabelSyncJobName": "Sync job name:",
+ "LabelQuality": "Quality:",
+ "OptionHigh": "High",
+ "OptionMedium": "Medium",
+ "OptionLow": "Low",
+ "HeaderSettings": "Settings",
+ "OptionAutomaticallySyncNewContent": "Automatically sync new content",
+ "OptionAutomaticallySyncNewContentHelp": "New content added to these folders will be automatically synced to the device.",
+ "OptionSyncUnwatchedVideosOnly": "Sync unwatched videos only",
+ "OptionSyncUnwatchedVideosOnlyHelp": "Only unwatched videos will be synced, and videos will be removed from the device as they are watched."
} \ No newline at end of file
diff --git a/MediaBrowser.Server.Implementations/Localization/JavaScript/nl.json b/MediaBrowser.Server.Implementations/Localization/JavaScript/nl.json
index fc53e577e3..c8569dc9fe 100644
--- a/MediaBrowser.Server.Implementations/Localization/JavaScript/nl.json
+++ b/MediaBrowser.Server.Implementations/Localization/JavaScript/nl.json
@@ -610,7 +610,7 @@
"MessageInvitationSentToUser": "Een email is verzonden naar {0} om je uitnodiging om media te delen te accepteren.",
"MessageInvitationSentToNewUser": "Een email is verzonden naar {0} om je uitnodiging aan te melden bij Media Browser",
"HeaderConnectionFailure": "Verbindingsfout",
- "MessageUnableToConnectToServer": "We're unable to connect to the selected server right now. Please try again later.",
+ "MessageUnableToConnectToServer": "Het is momenteel niet mogelijk met de geselecteerde server te verbinden, porbeer het later opnieuw,",
"ButtonSelectServer": "Selecteer server",
"MessagePluginConfigurationRequiresLocalAccess": "Meld svp. op de lokale server aan om deze plugin te configureren.",
"MessageLoggedOutParentalControl": "Toegang is momenteel bepertk, probeer later opnieuw.",
@@ -626,5 +626,23 @@
"MessagePasswordResetForUsers": "Wachtwoorden zijn gereset voor de volgende gebruikers:",
"HeaderInviteGuest": "Nodig gast uit",
"ButtonLinkMyMediaBrowserAccount": "Koppel mijn account nu",
- "MessageConnectAccountRequiredToInviteGuest": "Om gasten uit te kunnen nodigen moet je Media Browser account aan deze server gekoppeld worden."
+ "MessageConnectAccountRequiredToInviteGuest": "Om gasten uit te kunnen nodigen moet je Media Browser account aan deze server gekoppeld worden.",
+ "ButtonSync": "Synchronisatie",
+ "SyncMedia": "Sync Media",
+ "HeaderCancelSyncJob": "Cancel Sync",
+ "CancelSyncJobConfirmation": "Are you sure you wish to cancel this sync job?",
+ "TabSync": "Synchronisatie",
+ "MessagePleaseSelectDeviceToSyncTo": "Please select a device to sync to.",
+ "MessageSyncJobCreated": "Sync job created.",
+ "LabelSyncTo": "Sync to:",
+ "LabelSyncJobName": "Sync job name:",
+ "LabelQuality": "Quality:",
+ "OptionHigh": "High",
+ "OptionMedium": "Medium",
+ "OptionLow": "Low",
+ "HeaderSettings": "Settings",
+ "OptionAutomaticallySyncNewContent": "Automatically sync new content",
+ "OptionAutomaticallySyncNewContentHelp": "New content added to these folders will be automatically synced to the device.",
+ "OptionSyncUnwatchedVideosOnly": "Sync unwatched videos only",
+ "OptionSyncUnwatchedVideosOnlyHelp": "Only unwatched videos will be synced, and videos will be removed from the device as they are watched."
} \ No newline at end of file
diff --git a/MediaBrowser.Server.Implementations/Localization/JavaScript/pl.json b/MediaBrowser.Server.Implementations/Localization/JavaScript/pl.json
index 14acfd9213..98a8b5947c 100644
--- a/MediaBrowser.Server.Implementations/Localization/JavaScript/pl.json
+++ b/MediaBrowser.Server.Implementations/Localization/JavaScript/pl.json
@@ -626,5 +626,23 @@
"MessagePasswordResetForUsers": "Passwords have been reset for the following users:",
"HeaderInviteGuest": "Invite Guest",
"ButtonLinkMyMediaBrowserAccount": "Link my account now",
- "MessageConnectAccountRequiredToInviteGuest": "In order to invite guests you need to first link your Media Browser account to this server."
+ "MessageConnectAccountRequiredToInviteGuest": "In order to invite guests you need to first link your Media Browser account to this server.",
+ "ButtonSync": "Sync",
+ "SyncMedia": "Sync Media",
+ "HeaderCancelSyncJob": "Cancel Sync",
+ "CancelSyncJobConfirmation": "Are you sure you wish to cancel this sync job?",
+ "TabSync": "Sync",
+ "MessagePleaseSelectDeviceToSyncTo": "Please select a device to sync to.",
+ "MessageSyncJobCreated": "Sync job created.",
+ "LabelSyncTo": "Sync to:",
+ "LabelSyncJobName": "Sync job name:",
+ "LabelQuality": "Quality:",
+ "OptionHigh": "High",
+ "OptionMedium": "Medium",
+ "OptionLow": "Low",
+ "HeaderSettings": "Settings",
+ "OptionAutomaticallySyncNewContent": "Automatically sync new content",
+ "OptionAutomaticallySyncNewContentHelp": "New content added to these folders will be automatically synced to the device.",
+ "OptionSyncUnwatchedVideosOnly": "Sync unwatched videos only",
+ "OptionSyncUnwatchedVideosOnlyHelp": "Only unwatched videos will be synced, and videos will be removed from the device as they are watched."
} \ No newline at end of file
diff --git a/MediaBrowser.Server.Implementations/Localization/JavaScript/pt_BR.json b/MediaBrowser.Server.Implementations/Localization/JavaScript/pt_BR.json
index bab01f5a26..492b402ca7 100644
--- a/MediaBrowser.Server.Implementations/Localization/JavaScript/pt_BR.json
+++ b/MediaBrowser.Server.Implementations/Localization/JavaScript/pt_BR.json
@@ -626,5 +626,23 @@
"MessagePasswordResetForUsers": "Foram redefinidas as senhas dos seguintes usu\u00e1rios:",
"HeaderInviteGuest": "Convidar Usu\u00e1rio",
"ButtonLinkMyMediaBrowserAccount": "Conectar minha conta agora",
- "MessageConnectAccountRequiredToInviteGuest": "Para convidar usu\u00e1rios voc\u00ea necessita primeiro conectar sua conta Media Browser com este servidor."
+ "MessageConnectAccountRequiredToInviteGuest": "Para convidar usu\u00e1rios voc\u00ea necessita primeiro conectar sua conta Media Browser com este servidor.",
+ "ButtonSync": "Sincronizar",
+ "SyncMedia": "Sincronizar M\u00eddia",
+ "HeaderCancelSyncJob": "Cancelar Sincroniza\u00e7\u00e3o",
+ "CancelSyncJobConfirmation": "Deseja realmente cancelar esta tarefa de sincroniza\u00e7\u00e3o?",
+ "TabSync": "Sincroniza\u00e7\u00e3o",
+ "MessagePleaseSelectDeviceToSyncTo": "Por favor, selecione um dispositivo para sincronizar.",
+ "MessageSyncJobCreated": "Tarefa de sincroniza\u00e7\u00e3o criada.",
+ "LabelSyncTo": "Sincronizar para:",
+ "LabelSyncJobName": "Nome da tarefa de sincroniza\u00e7\u00e3o:",
+ "LabelQuality": "Qualidade:",
+ "OptionHigh": "Alta",
+ "OptionMedium": "M\u00e9dia",
+ "OptionLow": "Baixa",
+ "HeaderSettings": "Ajustes",
+ "OptionAutomaticallySyncNewContent": "Sincronizar novo conte\u00fado automaticamente",
+ "OptionAutomaticallySyncNewContentHelp": "Novo conte\u00fado adicionado a estas pastas ser\u00e1 automaticamente sincronizado com o dispositivo.",
+ "OptionSyncUnwatchedVideosOnly": "Sincronizar apenas v\u00eddeos n\u00e3o assistidos",
+ "OptionSyncUnwatchedVideosOnlyHelp": "Apenas v\u00eddeos n\u00e3o assistidos ser\u00e3o sincronizados, e os v\u00eddeos ser\u00e3o removidos do dispositivo assim que forem assistidos."
} \ No newline at end of file
diff --git a/MediaBrowser.Server.Implementations/Localization/JavaScript/pt_PT.json b/MediaBrowser.Server.Implementations/Localization/JavaScript/pt_PT.json
index f6433902ea..5007ae4440 100644
--- a/MediaBrowser.Server.Implementations/Localization/JavaScript/pt_PT.json
+++ b/MediaBrowser.Server.Implementations/Localization/JavaScript/pt_PT.json
@@ -626,5 +626,23 @@
"MessagePasswordResetForUsers": "Passwords have been reset for the following users:",
"HeaderInviteGuest": "Invite Guest",
"ButtonLinkMyMediaBrowserAccount": "Link my account now",
- "MessageConnectAccountRequiredToInviteGuest": "In order to invite guests you need to first link your Media Browser account to this server."
+ "MessageConnectAccountRequiredToInviteGuest": "In order to invite guests you need to first link your Media Browser account to this server.",
+ "ButtonSync": "Sincronizar",
+ "SyncMedia": "Sync Media",
+ "HeaderCancelSyncJob": "Cancel Sync",
+ "CancelSyncJobConfirmation": "Are you sure you wish to cancel this sync job?",
+ "TabSync": "Sync",
+ "MessagePleaseSelectDeviceToSyncTo": "Please select a device to sync to.",
+ "MessageSyncJobCreated": "Sync job created.",
+ "LabelSyncTo": "Sync to:",
+ "LabelSyncJobName": "Sync job name:",
+ "LabelQuality": "Quality:",
+ "OptionHigh": "High",
+ "OptionMedium": "Medium",
+ "OptionLow": "Low",
+ "HeaderSettings": "Settings",
+ "OptionAutomaticallySyncNewContent": "Automatically sync new content",
+ "OptionAutomaticallySyncNewContentHelp": "New content added to these folders will be automatically synced to the device.",
+ "OptionSyncUnwatchedVideosOnly": "Sync unwatched videos only",
+ "OptionSyncUnwatchedVideosOnlyHelp": "Only unwatched videos will be synced, and videos will be removed from the device as they are watched."
} \ No newline at end of file
diff --git a/MediaBrowser.Server.Implementations/Localization/JavaScript/ru.json b/MediaBrowser.Server.Implementations/Localization/JavaScript/ru.json
index 02955316a2..ca307fd53e 100644
--- a/MediaBrowser.Server.Implementations/Localization/JavaScript/ru.json
+++ b/MediaBrowser.Server.Implementations/Localization/JavaScript/ru.json
@@ -41,10 +41,10 @@
"LabelCancelled": "(\u043e\u0442\u043c\u0435\u043d\u0435\u043d\u043e)",
"LabelFailed": "(\u043d\u0435\u0443\u0434\u0430\u0447\u043d\u043e)",
"LabelAbortedByServerShutdown": "(\u041f\u0440\u0435\u0440\u0432\u0430\u043d\u043e \u043e\u0442\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435\u043c \u0441\u0435\u0440\u0432\u0435\u0440\u0430)",
- "LabelScheduledTaskLastRan": "\u0412\u044b\u043f\u043e\u043b\u043d\u044f\u043b\u043e\u0441\u044c {0}, \u0437\u0430\u043d\u044f\u043b\u043e {1}.",
- "HeaderDeleteTaskTrigger": "\u0423\u0434\u0430\u043b\u0435\u043d\u0438\u0435 \u0442\u0440\u0438\u0433\u0433\u0435\u0440\u0430 \u0437\u0430\u0434\u0430\u043d\u0438\u044f",
- "HeaderTaskTriggers": "\u0422\u0440\u0438\u0433\u0433\u0435\u0440\u044b \u0437\u0430\u0434\u0430\u043d\u0438\u044f",
- "MessageDeleteTaskTrigger": "\u0412\u044b \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u0445\u043e\u0442\u0438\u0442\u0435 \u0443\u0434\u0430\u043b\u0438\u0442\u044c \u0434\u0430\u043d\u043d\u044b\u0439 \u0442\u0440\u0438\u0433\u0433\u0435\u0440 \u0437\u0430\u0434\u0430\u043d\u0438\u044f?",
+ "LabelScheduledTaskLastRan": "\u0412\u044b\u043f\u043e\u043b\u043d\u044f\u043b\u0430\u0441\u044c {0}, \u0437\u0430\u043d\u044f\u043b\u0430 {1}.",
+ "HeaderDeleteTaskTrigger": "\u0423\u0434\u0430\u043b\u0435\u043d\u0438\u0435 \u0442\u0440\u0438\u0433\u0433\u0435\u0440\u0430 \u0437\u0430\u0434\u0430\u0447\u0438",
+ "HeaderTaskTriggers": "\u0422\u0440\u0438\u0433\u0433\u0435\u0440\u044b \u0437\u0430\u0434\u0430\u0447\u0438",
+ "MessageDeleteTaskTrigger": "\u0412\u044b \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u0445\u043e\u0442\u0438\u0442\u0435 \u0443\u0434\u0430\u043b\u0438\u0442\u044c \u0434\u0430\u043d\u043d\u044b\u0439 \u0442\u0440\u0438\u0433\u0433\u0435\u0440 \u0437\u0430\u0434\u0430\u0447\u0438?",
"MessageNoPluginsInstalled": "\u041d\u0435\u0442 \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u043b\u0435\u043d\u043d\u044b\u0445 \u043f\u043b\u0430\u0433\u0438\u043d\u043e\u0432.",
"LabelVersionInstalled": "\u0423\u0441\u0442\u0430\u043d\u043e\u0432\u043b\u0435\u043d\u0430: {0}",
"LabelNumberReviews": "\u041e\u0442\u0437\u044b\u0432\u044b: {0}",
@@ -62,7 +62,7 @@
"ButtonPause": "\u041f\u0440\u0438\u043e\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u044c",
"ButtonPlay": "\u0412\u043e\u0441\u043f\u0440\u043e\u0438\u0437\u0432\u0435\u0441\u0442\u0438",
"ButtonEdit": "\u041f\u0440\u0430\u0432\u0438\u0442\u044c",
- "ButtonQueue": "\u041f\u043e\u0441\u0442\u0430\u0432\u0438\u0442\u044c \u0432 \u043e\u0447\u0435\u0440\u0435\u0434\u044c",
+ "ButtonQueue": "\u0412 \u043e\u0447\u0435\u0440\u0435\u0434\u044c",
"ButtonPlayTrailer": "\u0412\u043e\u0441\u043f\u0440\u043e\u0438\u0437\u0432\u0435\u0441\u0442\u0438 \u0442\u0440\u0435\u0439\u043b\u0435\u0440",
"ButtonPlaylist": "\u0421\u043f\u0438\u0441\u043e\u043a \u0432\u043e\u0441\u043f\u0440-\u0438\u044f",
"ButtonPreviousTrack": "\u041f\u0440\u0435\u0434\u044b\u0434\u0443\u0449\u0430\u044f \u0434\u043e\u0440\u043e\u0436\u043a\u0430",
@@ -377,7 +377,7 @@
"LabelMetadataSaversHelp": "\u0412\u044b\u0431\u0435\u0440\u0438\u0442\u0435 \u0444\u043e\u0440\u043c\u0430\u0442\u044b \u0444\u0430\u0439\u043b\u043e\u0432, \u043a\u0443\u0434\u0430 \u0431\u0443\u0434\u0443\u0442 \u0441\u043e\u0445\u0440\u0430\u043d\u044f\u0442\u044c\u0441\u044f \u043c\u0435\u0442\u0430\u0434\u0430\u043d\u043d\u044b\u0435.",
"LabelImageFetchers": "\u041e\u0442\u0431\u043e\u0440\u0449\u0438\u043a\u0438 \u0440\u0438\u0441\u0443\u043d\u043a\u043e\u0432:",
"LabelImageFetchersHelp": "\u0412\u043a\u043b\u044e\u0447\u0438\u0442\u0435 \u0438 \u0440\u0430\u043d\u0436\u0438\u0440\u0443\u0439\u0442\u0435 \u043f\u0440\u0435\u0434\u043f\u043e\u0447\u0438\u0442\u0430\u0435\u043c\u044b\u0435 \u043e\u0442\u0431\u043e\u0440\u0449\u0438\u043a\u0438 \u0440\u0438\u0441\u0443\u043d\u043a\u043e\u0432 \u0432 \u043f\u043e\u0440\u044f\u0434\u043a\u0435 \u043f\u0440\u0438\u043e\u0440\u0438\u0442\u0435\u0442\u0430.",
- "ButtonQueueAllFromHere": "\u041f\u043e\u0441\u0442\u0430\u0432\u0438\u0442\u044c \u0432\u0441\u0435 \u0432 \u043e\u0447\u0435\u0440\u0435\u0434\u044c \u043e\u0442\u0441\u044e\u0434\u0430",
+ "ButtonQueueAllFromHere": "\u0412 \u043e\u0447\u0435\u0440\u0435\u0434\u044c \u0432\u0441\u0435 \u043e\u0442\u0441\u044e\u0434\u0430",
"ButtonPlayAllFromHere": "\u0412\u043e\u0441\u043f\u0440\u043e\u0438\u0437\u0432\u0435\u0441\u0442\u0438 \u0432\u0441\u0435 \u043e\u0442\u0441\u044e\u0434\u0430",
"LabelDynamicExternalId": "{0} Id:",
"HeaderIdentify": "\u0420\u0430\u0441\u043f\u043e\u0437\u043d\u0430\u043d\u0438\u0435 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u0430",
@@ -593,9 +593,9 @@
"DashboardTourSubtitles": "\u0410\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438 \u0437\u0430\u0433\u0440\u0443\u0436\u0430\u0439\u0442\u0435 \u0441\u0443\u0431\u0442\u0438\u0442\u0440\u044b \u0434\u043b\u044f \u0432\u0438\u0434\u0435\u043e \u043d\u0430 \u043b\u044e\u0431\u043e\u043c \u044f\u0437\u044b\u043a\u0435.",
"DashboardTourPlugins": "\u0423\u0441\u0442\u0430\u043d\u0430\u0432\u043b\u0438\u0432\u0430\u0439\u0442\u0435 \u043f\u043b\u0430\u0433\u0438\u043d\u044b, \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u0438\u043d\u0442\u0435\u0440\u043d\u0435\u0442-\u043a\u0430\u043d\u0430\u043b\u043e\u0432 \u0432\u0438\u0434\u0435\u043e, \u044d\u0444\u0438\u0440\u043d\u043e\u0433\u043e \u0442\u0432, \u0441\u043a\u0430\u043d\u043d\u0435\u0440\u043e\u0432 \u043c\u0435\u0442\u0430\u0434\u0430\u043d\u043d\u044b\u0445 \u0438 \u0442.\u043f.",
"DashboardTourNotifications": "\u0410\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438 \u043f\u0435\u0440\u0435\u0434\u0430\u0432\u0430\u0439\u0442\u0435 \u0443\u0432\u0435\u0434\u043e\u043c\u043b\u0435\u043d\u0438\u044f \u043e \u0441\u0435\u0440\u0432\u0435\u0440\u043d\u044b\u0445 \u0441\u043e\u0431\u044b\u0442\u0438\u044f\u0445 \u043d\u0430 \u0432\u0430\u0448\u0435 \u043c\u043e\u0431\u0438\u043b\u044c\u043d\u043e\u0435 \u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u0430, \u044d-\u043f\u043e\u0447\u0442\u0443 \u0438 \u0442.\u043f.",
- "DashboardTourScheduledTasks": "\u0421\u0432\u043e\u0431\u043e\u0434\u043d\u043e \u0443\u043f\u0440\u0430\u0432\u043b\u044f\u0439\u0442\u0435 \u0434\u043e\u043b\u0433\u043e\u0432\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u043c\u0438 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u044f\u043c\u0438 \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u043d\u0430\u0437\u043d\u0430\u0447\u0435\u043d\u043d\u044b\u0445 \u0437\u0430\u0434\u0430\u043d\u0438\u0439. \u041f\u0440\u0438\u043d\u0438\u043c\u0430\u0439\u0442\u0435 \u0440\u0435\u0448\u0435\u043d\u0438\u0435 \u043a\u043e\u0433\u0434\u0430 \u043e\u043d\u0438 \u0431\u0443\u0434\u0443\u0442 \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0442\u044c\u0441\u044f, \u0438 \u043d\u0430\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0447\u0430\u0441\u0442\u043e.",
+ "DashboardTourScheduledTasks": "\u0421\u0432\u043e\u0431\u043e\u0434\u043d\u043e \u0443\u043f\u0440\u0430\u0432\u043b\u044f\u0439\u0442\u0435 \u0434\u043e\u043b\u0433\u043e\u0432\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u043c\u0438 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u044f\u043c\u0438 \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u043d\u0430\u0437\u043d\u0430\u0447\u0435\u043d\u043d\u044b\u0445 \u0437\u0430\u0434\u0430\u0447. \u041f\u0440\u0438\u043d\u0438\u043c\u0430\u0439\u0442\u0435 \u0440\u0435\u0448\u0435\u043d\u0438\u0435 \u043a\u043e\u0433\u0434\u0430 \u043e\u043d\u0438 \u0431\u0443\u0434\u0443\u0442 \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0442\u044c\u0441\u044f, \u0438 \u043d\u0430\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0447\u0430\u0441\u0442\u043e.",
"DashboardTourMobile": "\u0418\u043d\u0444\u043e\u043f\u0430\u043d\u0435\u043b\u044c Media Browser \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u043e\u0442\u043b\u0438\u0447\u043d\u043e \u043d\u0430 \u0441\u043c\u0430\u0440\u0442\u0444\u043e\u043d\u0430\u0445 \u0438 \u043f\u043b\u0430\u043d\u0448\u0435\u0442\u0430\u0445. \u0423\u043f\u0440\u0430\u0432\u043b\u044f\u0439\u0442\u0435 \u0441\u0435\u0440\u0432\u0435\u0440\u043e\u043c \u0441 \u0432\u0430\u0448\u0435\u0439 \u043b\u0430\u0434\u043e\u043d\u0438 \u0432 \u043b\u044e\u0431\u043e\u0435 \u0432\u0440\u0435\u043c\u044f, \u0432 \u043b\u044e\u0431\u043e\u043c \u043c\u0435\u0441\u0442\u0435.",
- "MessageRefreshQueued": "\u041f\u043e\u0434\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u0435 \u043f\u043e\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u043e \u0432 \u043e\u0447\u0435\u0440\u0435\u0434\u044c",
+ "MessageRefreshQueued": "\u041f\u043e\u0434\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u0435 \u0432 \u043e\u0447\u0435\u0440\u0435\u0434\u0438",
"TabDevices": "\u0423\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u0430",
"DeviceLastUsedByUserName": "\u041f\u043e\u0441\u043b\u0435\u0434\u043d\u0435\u0435 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435: {0}",
"HeaderDeleteDevice": "\u0423\u0434\u0430\u043b\u0438\u0442\u044c \u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u043e",
@@ -626,5 +626,23 @@
"MessagePasswordResetForUsers": "\u041f\u0430\u0440\u043e\u043b\u0438 \u0431\u044b\u043b\u0438 \u0441\u0431\u0440\u043e\u0448\u0435\u043d\u044b \u0434\u043b\u044f \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0445 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0435\u0439:",
"HeaderInviteGuest": "\u041f\u0440\u0438\u0433\u043b\u0430\u0448\u0435\u043d\u0438\u0435 \u0433\u043e\u0441\u0442\u044f",
"ButtonLinkMyMediaBrowserAccount": "\u0421\u0432\u044f\u0437\u0430\u0442\u044c \u043c\u043e\u044e \u0443\u0447\u0451\u0442\u043d\u0443\u044e \u0437\u0430\u043f\u0438\u0441\u044c",
- "MessageConnectAccountRequiredToInviteGuest": "\u0414\u043b\u044f \u0442\u043e\u0433\u043e, \u0447\u0442\u043e\u0431\u044b \u043f\u0440\u0438\u0433\u043b\u0430\u0448\u0430\u0442\u044c \u0433\u043e\u0441\u0442\u0435\u0439, \u0432\u0430\u043c \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e, \u0432 \u043f\u0435\u0440\u0432\u0443\u044e \u043e\u0447\u0435\u0440\u0435\u0434\u044c, \u0441\u0432\u044f\u0437\u0430\u0442\u044c \u0441\u0432\u043e\u044e \u0443\u0447\u0451\u0442\u043d\u0443\u044e \u0437\u0430\u043f\u0438\u0441\u044c Media Browser \u0441 \u0434\u0430\u043d\u043d\u044b\u043c \u0441\u0435\u0440\u0432\u0435\u0440\u043e\u043c."
+ "MessageConnectAccountRequiredToInviteGuest": "\u0414\u043b\u044f \u0442\u043e\u0433\u043e, \u0447\u0442\u043e\u0431\u044b \u043f\u0440\u0438\u0433\u043b\u0430\u0448\u0430\u0442\u044c \u0433\u043e\u0441\u0442\u0435\u0439, \u0432\u0430\u043c \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e, \u0432 \u043f\u0435\u0440\u0432\u0443\u044e \u043e\u0447\u0435\u0440\u0435\u0434\u044c, \u0441\u0432\u044f\u0437\u0430\u0442\u044c \u0441\u0432\u043e\u044e \u0443\u0447\u0451\u0442\u043d\u0443\u044e \u0437\u0430\u043f\u0438\u0441\u044c Media Browser \u0441 \u0434\u0430\u043d\u043d\u044b\u043c \u0441\u0435\u0440\u0432\u0435\u0440\u043e\u043c.",
+ "ButtonSync": "Sync",
+ "SyncMedia": "\u0421\u0438\u043d\u0445\u0440\u043e\u043d\u0438\u0437\u0430\u0446\u0438\u044f \u043c\u0435\u0434\u0438\u0430\u0434\u0430\u043d\u043d\u044b\u0445",
+ "HeaderCancelSyncJob": "\u041e\u0442\u043c\u0435\u043d\u0430 \u0441\u0438\u043d\u0445\u0440\u043e\u043d\u0438\u0437\u0430\u0446\u0438\u0438",
+ "CancelSyncJobConfirmation": "\u0412\u044b \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u0445\u043e\u0442\u0438\u0442\u0435 \u043e\u0442\u043c\u0435\u043d\u0438\u0442\u044c \u0434\u0430\u043d\u043d\u043e\u0435 \u0437\u0430\u0434\u0430\u043d\u0438\u0435 \u0441\u0438\u043d\u0445\u0440\u043e\u043d\u0438\u0437\u0430\u0446\u0438\u0438?",
+ "TabSync": "Sync",
+ "MessagePleaseSelectDeviceToSyncTo": "\u0412\u044b\u0431\u0435\u0440\u0438\u0442\u0435 \u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u043e \u0434\u043b\u044f \u0441\u0438\u043d\u0445\u0440\u043e\u043d\u0438\u0437\u0430\u0446\u0438\u0438.",
+ "MessageSyncJobCreated": "\u0417\u0430\u0434\u0430\u043d\u0438\u0435 \u0441\u0438\u043d\u0445\u0440\u043e\u043d\u0438\u0437\u0430\u0446\u0438\u0438 \u0441\u043e\u0437\u0434\u0430\u043d\u043e.",
+ "LabelSyncTo": "\u0421\u0438\u043d\u0445\u0440\u043e\u043d\u0438\u0437\u0430\u0446\u0438\u044f \u0441:",
+ "LabelSyncJobName": "\u0418\u043c\u044f \u0437\u0430\u0434\u0430\u043d\u0438\u044f \u0441\u0438\u043d\u0445\u0440\u043e\u043d\u0438\u0437\u0430\u0446\u0438\u0438:",
+ "LabelQuality": "\u041a\u0430\u0447\u0435\u0441\u0442\u0432\u043e:",
+ "OptionHigh": "\u0412\u044b\u0441\u043e\u043a\u043e\u0435",
+ "OptionMedium": "\u0421\u0440\u0435\u0434\u043d\u0435\u0435",
+ "OptionLow": "\u041d\u0438\u0437\u043a\u043e\u0435",
+ "HeaderSettings": "\u041f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u044b",
+ "OptionAutomaticallySyncNewContent": "\u0410\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438 \u0441\u0438\u043d\u0445\u0440\u043e\u043d\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043d\u043e\u0432\u043e\u0435 \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u043d\u0438\u0435",
+ "OptionAutomaticallySyncNewContentHelp": "\u041d\u043e\u0432\u043e\u0435 \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u043d\u0438\u0435, \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u043d\u043e\u0435 \u0432 \u0434\u0430\u043d\u043d\u044b\u0435 \u043f\u0430\u043f\u043a\u0438, \u0431\u0443\u0434\u0435\u0442 \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438 \u0441\u0438\u043d\u0445\u0440\u043e\u043d\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u0442\u044c\u0441\u044f \u0441 \u0434\u0430\u043d\u043d\u044b\u043c \u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u043e\u043c.",
+ "OptionSyncUnwatchedVideosOnly": "\u0421\u0438\u043d\u0445\u0440\u043e\u043d\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0442\u043e\u043b\u044c\u043a\u043e \u043d\u0435\u043f\u0440\u043e\u0441\u043c\u043e\u0442\u0440\u0435\u043d\u043d\u044b\u0435 \u0432\u0438\u0434\u0435\u043e\u0444\u0430\u0439\u043b\u044b.",
+ "OptionSyncUnwatchedVideosOnlyHelp": "\u0422\u043e\u043b\u044c\u043a\u043e \u043d\u0435\u043f\u0440\u043e\u0441\u043c\u043e\u0442\u0440\u0435\u043d\u043d\u044b\u0435 \u0432\u0438\u0434\u0435\u043e\u0444\u0430\u0439\u043b\u044b \u0431\u0443\u0434\u0443\u0442 \u0441\u0438\u043d\u0445\u0440\u043e\u043d\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u0442\u044c\u0441\u044f, \u0430 \u0432\u0438\u0434\u0435\u043e\u0444\u0430\u0439\u043b\u044b \u0431\u0443\u0434\u0443\u0442 \u0438\u0437\u044b\u043c\u0430\u0442\u044c\u0441\u044f \u0441 \u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u0430 \u043f\u043e\u0441\u043b\u0435 \u0438\u0445 \u043f\u0440\u043e\u0441\u043c\u043e\u0442\u0440\u0430."
} \ No newline at end of file
diff --git a/MediaBrowser.Server.Implementations/Localization/JavaScript/sv.json b/MediaBrowser.Server.Implementations/Localization/JavaScript/sv.json
index 95ce375f1a..a0b86f5762 100644
--- a/MediaBrowser.Server.Implementations/Localization/JavaScript/sv.json
+++ b/MediaBrowser.Server.Implementations/Localization/JavaScript/sv.json
@@ -626,5 +626,23 @@
"MessagePasswordResetForUsers": "Passwords have been reset for the following users:",
"HeaderInviteGuest": "Invite Guest",
"ButtonLinkMyMediaBrowserAccount": "Link my account now",
- "MessageConnectAccountRequiredToInviteGuest": "In order to invite guests you need to first link your Media Browser account to this server."
+ "MessageConnectAccountRequiredToInviteGuest": "In order to invite guests you need to first link your Media Browser account to this server.",
+ "ButtonSync": "Synk",
+ "SyncMedia": "Sync Media",
+ "HeaderCancelSyncJob": "Cancel Sync",
+ "CancelSyncJobConfirmation": "Are you sure you wish to cancel this sync job?",
+ "TabSync": "Synk",
+ "MessagePleaseSelectDeviceToSyncTo": "Please select a device to sync to.",
+ "MessageSyncJobCreated": "Sync job created.",
+ "LabelSyncTo": "Sync to:",
+ "LabelSyncJobName": "Sync job name:",
+ "LabelQuality": "Quality:",
+ "OptionHigh": "High",
+ "OptionMedium": "Medium",
+ "OptionLow": "Low",
+ "HeaderSettings": "Settings",
+ "OptionAutomaticallySyncNewContent": "Automatically sync new content",
+ "OptionAutomaticallySyncNewContentHelp": "New content added to these folders will be automatically synced to the device.",
+ "OptionSyncUnwatchedVideosOnly": "Sync unwatched videos only",
+ "OptionSyncUnwatchedVideosOnlyHelp": "Only unwatched videos will be synced, and videos will be removed from the device as they are watched."
} \ No newline at end of file
diff --git a/MediaBrowser.Server.Implementations/Localization/JavaScript/tr.json b/MediaBrowser.Server.Implementations/Localization/JavaScript/tr.json
index 7823981013..e8ecf0de03 100644
--- a/MediaBrowser.Server.Implementations/Localization/JavaScript/tr.json
+++ b/MediaBrowser.Server.Implementations/Localization/JavaScript/tr.json
@@ -626,5 +626,23 @@
"MessagePasswordResetForUsers": "Passwords have been reset for the following users:",
"HeaderInviteGuest": "Invite Guest",
"ButtonLinkMyMediaBrowserAccount": "Link my account now",
- "MessageConnectAccountRequiredToInviteGuest": "In order to invite guests you need to first link your Media Browser account to this server."
+ "MessageConnectAccountRequiredToInviteGuest": "In order to invite guests you need to first link your Media Browser account to this server.",
+ "ButtonSync": "Sync",
+ "SyncMedia": "Sync Media",
+ "HeaderCancelSyncJob": "Cancel Sync",
+ "CancelSyncJobConfirmation": "Are you sure you wish to cancel this sync job?",
+ "TabSync": "Sync",
+ "MessagePleaseSelectDeviceToSyncTo": "Please select a device to sync to.",
+ "MessageSyncJobCreated": "Sync job created.",
+ "LabelSyncTo": "Sync to:",
+ "LabelSyncJobName": "Sync job name:",
+ "LabelQuality": "Quality:",
+ "OptionHigh": "High",
+ "OptionMedium": "Medium",
+ "OptionLow": "Low",
+ "HeaderSettings": "Settings",
+ "OptionAutomaticallySyncNewContent": "Automatically sync new content",
+ "OptionAutomaticallySyncNewContentHelp": "New content added to these folders will be automatically synced to the device.",
+ "OptionSyncUnwatchedVideosOnly": "Sync unwatched videos only",
+ "OptionSyncUnwatchedVideosOnlyHelp": "Only unwatched videos will be synced, and videos will be removed from the device as they are watched."
} \ No newline at end of file
diff --git a/MediaBrowser.Server.Implementations/Localization/JavaScript/vi.json b/MediaBrowser.Server.Implementations/Localization/JavaScript/vi.json
index c2506300cd..e947611565 100644
--- a/MediaBrowser.Server.Implementations/Localization/JavaScript/vi.json
+++ b/MediaBrowser.Server.Implementations/Localization/JavaScript/vi.json
@@ -626,5 +626,23 @@
"MessagePasswordResetForUsers": "Passwords have been reset for the following users:",
"HeaderInviteGuest": "Invite Guest",
"ButtonLinkMyMediaBrowserAccount": "Link my account now",
- "MessageConnectAccountRequiredToInviteGuest": "In order to invite guests you need to first link your Media Browser account to this server."
+ "MessageConnectAccountRequiredToInviteGuest": "In order to invite guests you need to first link your Media Browser account to this server.",
+ "ButtonSync": "Sync",
+ "SyncMedia": "Sync Media",
+ "HeaderCancelSyncJob": "Cancel Sync",
+ "CancelSyncJobConfirmation": "Are you sure you wish to cancel this sync job?",
+ "TabSync": "Sync",
+ "MessagePleaseSelectDeviceToSyncTo": "Please select a device to sync to.",
+ "MessageSyncJobCreated": "Sync job created.",
+ "LabelSyncTo": "Sync to:",
+ "LabelSyncJobName": "Sync job name:",
+ "LabelQuality": "Quality:",
+ "OptionHigh": "High",
+ "OptionMedium": "Medium",
+ "OptionLow": "Low",
+ "HeaderSettings": "Settings",
+ "OptionAutomaticallySyncNewContent": "Automatically sync new content",
+ "OptionAutomaticallySyncNewContentHelp": "New content added to these folders will be automatically synced to the device.",
+ "OptionSyncUnwatchedVideosOnly": "Sync unwatched videos only",
+ "OptionSyncUnwatchedVideosOnlyHelp": "Only unwatched videos will be synced, and videos will be removed from the device as they are watched."
} \ No newline at end of file
diff --git a/MediaBrowser.Server.Implementations/Localization/JavaScript/zh_CN.json b/MediaBrowser.Server.Implementations/Localization/JavaScript/zh_CN.json
index d83f9743dd..ad9a6c6a55 100644
--- a/MediaBrowser.Server.Implementations/Localization/JavaScript/zh_CN.json
+++ b/MediaBrowser.Server.Implementations/Localization/JavaScript/zh_CN.json
@@ -626,5 +626,23 @@
"MessagePasswordResetForUsers": "Passwords have been reset for the following users:",
"HeaderInviteGuest": "Invite Guest",
"ButtonLinkMyMediaBrowserAccount": "Link my account now",
- "MessageConnectAccountRequiredToInviteGuest": "In order to invite guests you need to first link your Media Browser account to this server."
+ "MessageConnectAccountRequiredToInviteGuest": "In order to invite guests you need to first link your Media Browser account to this server.",
+ "ButtonSync": "\u540c\u6b65",
+ "SyncMedia": "Sync Media",
+ "HeaderCancelSyncJob": "Cancel Sync",
+ "CancelSyncJobConfirmation": "Are you sure you wish to cancel this sync job?",
+ "TabSync": "\u540c\u6b65",
+ "MessagePleaseSelectDeviceToSyncTo": "Please select a device to sync to.",
+ "MessageSyncJobCreated": "Sync job created.",
+ "LabelSyncTo": "Sync to:",
+ "LabelSyncJobName": "Sync job name:",
+ "LabelQuality": "Quality:",
+ "OptionHigh": "High",
+ "OptionMedium": "Medium",
+ "OptionLow": "Low",
+ "HeaderSettings": "Settings",
+ "OptionAutomaticallySyncNewContent": "Automatically sync new content",
+ "OptionAutomaticallySyncNewContentHelp": "New content added to these folders will be automatically synced to the device.",
+ "OptionSyncUnwatchedVideosOnly": "Sync unwatched videos only",
+ "OptionSyncUnwatchedVideosOnlyHelp": "Only unwatched videos will be synced, and videos will be removed from the device as they are watched."
} \ No newline at end of file
diff --git a/MediaBrowser.Server.Implementations/Localization/JavaScript/zh_TW.json b/MediaBrowser.Server.Implementations/Localization/JavaScript/zh_TW.json
index 15f5bf4542..7062997043 100644
--- a/MediaBrowser.Server.Implementations/Localization/JavaScript/zh_TW.json
+++ b/MediaBrowser.Server.Implementations/Localization/JavaScript/zh_TW.json
@@ -626,5 +626,23 @@
"MessagePasswordResetForUsers": "Passwords have been reset for the following users:",
"HeaderInviteGuest": "Invite Guest",
"ButtonLinkMyMediaBrowserAccount": "Link my account now",
- "MessageConnectAccountRequiredToInviteGuest": "In order to invite guests you need to first link your Media Browser account to this server."
+ "MessageConnectAccountRequiredToInviteGuest": "In order to invite guests you need to first link your Media Browser account to this server.",
+ "ButtonSync": "Sync",
+ "SyncMedia": "Sync Media",
+ "HeaderCancelSyncJob": "Cancel Sync",
+ "CancelSyncJobConfirmation": "Are you sure you wish to cancel this sync job?",
+ "TabSync": "Sync",
+ "MessagePleaseSelectDeviceToSyncTo": "Please select a device to sync to.",
+ "MessageSyncJobCreated": "Sync job created.",
+ "LabelSyncTo": "Sync to:",
+ "LabelSyncJobName": "Sync job name:",
+ "LabelQuality": "Quality:",
+ "OptionHigh": "High",
+ "OptionMedium": "Medium",
+ "OptionLow": "Low",
+ "HeaderSettings": "Settings",
+ "OptionAutomaticallySyncNewContent": "Automatically sync new content",
+ "OptionAutomaticallySyncNewContentHelp": "New content added to these folders will be automatically synced to the device.",
+ "OptionSyncUnwatchedVideosOnly": "Sync unwatched videos only",
+ "OptionSyncUnwatchedVideosOnlyHelp": "Only unwatched videos will be synced, and videos will be removed from the device as they are watched."
} \ No newline at end of file
diff --git a/MediaBrowser.Server.Implementations/Localization/Server/ar.json b/MediaBrowser.Server.Implementations/Localization/Server/ar.json
index 8d23f8c2ad..cb66848d72 100644
--- a/MediaBrowser.Server.Implementations/Localization/Server/ar.json
+++ b/MediaBrowser.Server.Implementations/Localization/Server/ar.json
@@ -539,7 +539,7 @@
"HeaderRunningTasks": "Running Tasks",
"HeaderActiveDevices": "Active Devices",
"HeaderPendingInstallations": "Pending Installations",
- "HeaerServerInformation": "Server Information",
+ "HeaderServerInformation": "Server Information",
"ButtonRestartNow": "Restart Now",
"ButtonRestart": "Restart",
"ButtonShutdown": "Shutdown",
@@ -1275,5 +1275,9 @@
"HeaderYears": "Years",
"HeaderAddTag": "Add Tag",
"LabelBlockItemsWithTags": "Block items with tags:",
- "LabelTag": "Tag:"
+ "LabelTag": "Tag:",
+ "LabelEnableSingleImageInDidlLimit": "Limit to single embedded image",
+ "LabelEnableSingleImageInDidlLimitHelp": "Some devices will not render properly if multiple images are embedded within Didl.",
+ "TabActivity": "Activity",
+ "TitleSync": "Sync"
} \ No newline at end of file
diff --git a/MediaBrowser.Server.Implementations/Localization/Server/ca.json b/MediaBrowser.Server.Implementations/Localization/Server/ca.json
index cfe8405d08..8af1873921 100644
--- a/MediaBrowser.Server.Implementations/Localization/Server/ca.json
+++ b/MediaBrowser.Server.Implementations/Localization/Server/ca.json
@@ -539,7 +539,7 @@
"HeaderRunningTasks": "Running Tasks",
"HeaderActiveDevices": "Active Devices",
"HeaderPendingInstallations": "Pending Installations",
- "HeaerServerInformation": "Server Information",
+ "HeaderServerInformation": "Server Information",
"ButtonRestartNow": "Restart Now",
"ButtonRestart": "Restart",
"ButtonShutdown": "Shutdown",
@@ -1275,5 +1275,9 @@
"HeaderYears": "Years",
"HeaderAddTag": "Add Tag",
"LabelBlockItemsWithTags": "Block items with tags:",
- "LabelTag": "Tag:"
+ "LabelTag": "Tag:",
+ "LabelEnableSingleImageInDidlLimit": "Limit to single embedded image",
+ "LabelEnableSingleImageInDidlLimitHelp": "Some devices will not render properly if multiple images are embedded within Didl.",
+ "TabActivity": "Activity",
+ "TitleSync": "Sync"
} \ No newline at end of file
diff --git a/MediaBrowser.Server.Implementations/Localization/Server/cs.json b/MediaBrowser.Server.Implementations/Localization/Server/cs.json
index 25d5190b74..240475943e 100644
--- a/MediaBrowser.Server.Implementations/Localization/Server/cs.json
+++ b/MediaBrowser.Server.Implementations/Localization/Server/cs.json
@@ -539,7 +539,7 @@
"HeaderRunningTasks": "B\u011b\u017e\u00edc\u00ed \u00falohy",
"HeaderActiveDevices": "Akt\u00edvn\u00ed za\u0159\u00edzen\u00ed",
"HeaderPendingInstallations": "\u010cekaj\u00edc\u00ed instalace",
- "HeaerServerInformation": "Informace o serveru",
+ "HeaderServerInformation": "Server Information",
"ButtonRestartNow": "Restartovat nyn\u00ed",
"ButtonRestart": "Restart",
"ButtonShutdown": "Vypnout",
@@ -1275,5 +1275,9 @@
"HeaderYears": "Years",
"HeaderAddTag": "Add Tag",
"LabelBlockItemsWithTags": "Block items with tags:",
- "LabelTag": "Tag:"
+ "LabelTag": "Tag:",
+ "LabelEnableSingleImageInDidlLimit": "Limit to single embedded image",
+ "LabelEnableSingleImageInDidlLimitHelp": "Some devices will not render properly if multiple images are embedded within Didl.",
+ "TabActivity": "Activity",
+ "TitleSync": "Sync"
} \ No newline at end of file
diff --git a/MediaBrowser.Server.Implementations/Localization/Server/da.json b/MediaBrowser.Server.Implementations/Localization/Server/da.json
index 6cd18d44eb..c9f2b9cc09 100644
--- a/MediaBrowser.Server.Implementations/Localization/Server/da.json
+++ b/MediaBrowser.Server.Implementations/Localization/Server/da.json
@@ -539,7 +539,7 @@
"HeaderRunningTasks": "Running Tasks",
"HeaderActiveDevices": "Active Devices",
"HeaderPendingInstallations": "Pending Installations",
- "HeaerServerInformation": "Server Information",
+ "HeaderServerInformation": "Server Information",
"ButtonRestartNow": "Restart Now",
"ButtonRestart": "Restart",
"ButtonShutdown": "Shutdown",
@@ -1275,5 +1275,9 @@
"HeaderYears": "Years",
"HeaderAddTag": "Add Tag",
"LabelBlockItemsWithTags": "Block items with tags:",
- "LabelTag": "Tag:"
+ "LabelTag": "Tag:",
+ "LabelEnableSingleImageInDidlLimit": "Limit to single embedded image",
+ "LabelEnableSingleImageInDidlLimitHelp": "Some devices will not render properly if multiple images are embedded within Didl.",
+ "TabActivity": "Activity",
+ "TitleSync": "Sync"
} \ No newline at end of file
diff --git a/MediaBrowser.Server.Implementations/Localization/Server/de.json b/MediaBrowser.Server.Implementations/Localization/Server/de.json
index ecbc4e671c..e4b88c9bd8 100644
--- a/MediaBrowser.Server.Implementations/Localization/Server/de.json
+++ b/MediaBrowser.Server.Implementations/Localization/Server/de.json
@@ -98,7 +98,7 @@
"TabSuggested": "Vorgeschlagen",
"TabLatest": "Neueste",
"TabUpcoming": "Bevorstehend",
- "TabShows": "Shows",
+ "TabShows": "Serien",
"TabEpisodes": "Episoden",
"TabGenres": "Genres",
"TabPeople": "Personen",
@@ -539,7 +539,7 @@
"HeaderRunningTasks": "Laufende Aufgaben",
"HeaderActiveDevices": "Aktive Ger\u00e4te",
"HeaderPendingInstallations": "Ausstehende Installationen",
- "HeaerServerInformation": "Server Information",
+ "HeaderServerInformation": "Server Informationen",
"ButtonRestartNow": "Jetzt neustarten",
"ButtonRestart": "Neu starten",
"ButtonShutdown": "Herunterfahren",
@@ -1080,8 +1080,8 @@
"LabelVoteCount": "Stimmen:",
"LabelMetascore": "Metascore:",
"LabelCriticRating": "Kritiker Bewertung:",
- "LabelCriticRatingSummary": "Kritiker Bewertungszusammenfassung:",
- "LabelAwardSummary": "Auszeichnungszusammenfassung:",
+ "LabelCriticRatingSummary": "Kritikerbewertungen:",
+ "LabelAwardSummary": "Auszeichnungen:",
"LabelWebsite": "Website:",
"LabelTagline": "Tagline:",
"LabelOverview": "\u00dcbersicht:",
@@ -1097,7 +1097,7 @@
"LabelCustomRating": "Eigene Bewertung:",
"LabelBudget": "Budget",
"LabelRevenue": "Einnahmen ($):",
- "LabelOriginalAspectRatio": "Originales Seitenverh\u00e4ltnis:",
+ "LabelOriginalAspectRatio": "Original Seitenverh\u00e4ltnis:",
"LabelPlayers": "Schauspieler:",
"Label3DFormat": "3D Format:",
"HeaderAlternateEpisodeNumbers": "Alternative Episodennummern",
@@ -1273,7 +1273,11 @@
"HeaderParentalRatings": "Altersbeschr\u00e4nkung",
"HeaderVideoTypes": "Videotypen",
"HeaderYears": "Jahre",
- "HeaderAddTag": "Add Tag",
- "LabelBlockItemsWithTags": "Block items with tags:",
- "LabelTag": "Tag:"
+ "HeaderAddTag": "F\u00fcge Tag hinzu",
+ "LabelBlockItemsWithTags": "Blockiere Inhalte mit folgenden Tags:",
+ "LabelTag": "Tag:",
+ "LabelEnableSingleImageInDidlLimit": "Begrenze auf ein eingebundenes Bild",
+ "LabelEnableSingleImageInDidlLimitHelp": "Einige Ger\u00e4te zeigen m\u00f6glicherweise Darstellungsfehler wenn mehrere Bilder mit Didl eingebunden wurden.",
+ "TabActivity": "Activity",
+ "TitleSync": "Sync"
} \ No newline at end of file
diff --git a/MediaBrowser.Server.Implementations/Localization/Server/el.json b/MediaBrowser.Server.Implementations/Localization/Server/el.json
index f6789062a3..7f7213735c 100644
--- a/MediaBrowser.Server.Implementations/Localization/Server/el.json
+++ b/MediaBrowser.Server.Implementations/Localization/Server/el.json
@@ -539,7 +539,7 @@
"HeaderRunningTasks": "Running Tasks",
"HeaderActiveDevices": "Active Devices",
"HeaderPendingInstallations": "Pending Installations",
- "HeaerServerInformation": "Server Information",
+ "HeaderServerInformation": "Server Information",
"ButtonRestartNow": "Restart Now",
"ButtonRestart": "Restart",
"ButtonShutdown": "Shutdown",
@@ -1275,5 +1275,9 @@
"HeaderYears": "Years",
"HeaderAddTag": "Add Tag",
"LabelBlockItemsWithTags": "Block items with tags:",
- "LabelTag": "Tag:"
+ "LabelTag": "Tag:",
+ "LabelEnableSingleImageInDidlLimit": "Limit to single embedded image",
+ "LabelEnableSingleImageInDidlLimitHelp": "Some devices will not render properly if multiple images are embedded within Didl.",
+ "TabActivity": "Activity",
+ "TitleSync": "Sync"
} \ No newline at end of file
diff --git a/MediaBrowser.Server.Implementations/Localization/Server/en_GB.json b/MediaBrowser.Server.Implementations/Localization/Server/en_GB.json
index e497fedc18..5b5d6f46ec 100644
--- a/MediaBrowser.Server.Implementations/Localization/Server/en_GB.json
+++ b/MediaBrowser.Server.Implementations/Localization/Server/en_GB.json
@@ -539,7 +539,7 @@
"HeaderRunningTasks": "Running Tasks",
"HeaderActiveDevices": "Active Devices",
"HeaderPendingInstallations": "Pending Installations",
- "HeaerServerInformation": "Server Information",
+ "HeaderServerInformation": "Server Information",
"ButtonRestartNow": "Restart Now",
"ButtonRestart": "Restart",
"ButtonShutdown": "Shutdown",
@@ -1275,5 +1275,9 @@
"HeaderYears": "Years",
"HeaderAddTag": "Add Tag",
"LabelBlockItemsWithTags": "Block items with tags:",
- "LabelTag": "Tag:"
+ "LabelTag": "Tag:",
+ "LabelEnableSingleImageInDidlLimit": "Limit to single embedded image",
+ "LabelEnableSingleImageInDidlLimitHelp": "Some devices will not render properly if multiple images are embedded within Didl.",
+ "TabActivity": "Activity",
+ "TitleSync": "Sync"
} \ No newline at end of file
diff --git a/MediaBrowser.Server.Implementations/Localization/Server/en_US.json b/MediaBrowser.Server.Implementations/Localization/Server/en_US.json
index d2ec403400..2230ee9720 100644
--- a/MediaBrowser.Server.Implementations/Localization/Server/en_US.json
+++ b/MediaBrowser.Server.Implementations/Localization/Server/en_US.json
@@ -539,7 +539,7 @@
"HeaderRunningTasks": "Running Tasks",
"HeaderActiveDevices": "Active Devices",
"HeaderPendingInstallations": "Pending Installations",
- "HeaerServerInformation": "Server Information",
+ "HeaderServerInformation": "Server Information",
"ButtonRestartNow": "Restart Now",
"ButtonRestart": "Restart",
"ButtonShutdown": "Shutdown",
@@ -1275,5 +1275,9 @@
"HeaderYears": "Years",
"HeaderAddTag": "Add Tag",
"LabelBlockItemsWithTags": "Block items with tags:",
- "LabelTag": "Tag:"
+ "LabelTag": "Tag:",
+ "LabelEnableSingleImageInDidlLimit": "Limit to single embedded image",
+ "LabelEnableSingleImageInDidlLimitHelp": "Some devices will not render properly if multiple images are embedded within Didl.",
+ "TabActivity": "Activity",
+ "TitleSync": "Sync"
} \ No newline at end of file
diff --git a/MediaBrowser.Server.Implementations/Localization/Server/es.json b/MediaBrowser.Server.Implementations/Localization/Server/es.json
index e03198879d..f4bdae125e 100644
--- a/MediaBrowser.Server.Implementations/Localization/Server/es.json
+++ b/MediaBrowser.Server.Implementations/Localization/Server/es.json
@@ -539,7 +539,7 @@
"HeaderRunningTasks": "Tareas en ejecuci\u00f3n",
"HeaderActiveDevices": "Dispositivos activos",
"HeaderPendingInstallations": "Instalaciones pendientes",
- "HeaerServerInformation": "Informaci\u00f3n del servidor",
+ "HeaderServerInformation": "Server Information",
"ButtonRestartNow": "Reiniciar ahora",
"ButtonRestart": "Reiniciar",
"ButtonShutdown": "Apagar",
@@ -1275,5 +1275,9 @@
"HeaderYears": "Years",
"HeaderAddTag": "Add Tag",
"LabelBlockItemsWithTags": "Block items with tags:",
- "LabelTag": "Tag:"
+ "LabelTag": "Tag:",
+ "LabelEnableSingleImageInDidlLimit": "Limit to single embedded image",
+ "LabelEnableSingleImageInDidlLimitHelp": "Some devices will not render properly if multiple images are embedded within Didl.",
+ "TabActivity": "Activity",
+ "TitleSync": "Sync"
} \ No newline at end of file
diff --git a/MediaBrowser.Server.Implementations/Localization/Server/es_MX.json b/MediaBrowser.Server.Implementations/Localization/Server/es_MX.json
index 0e26ffca12..9707bb1562 100644
--- a/MediaBrowser.Server.Implementations/Localization/Server/es_MX.json
+++ b/MediaBrowser.Server.Implementations/Localization/Server/es_MX.json
@@ -539,7 +539,7 @@
"HeaderRunningTasks": "Tareas en Ejecuci\u00f3n",
"HeaderActiveDevices": "Dispositivos Activos",
"HeaderPendingInstallations": "Instalaciones Pendientes",
- "HeaerServerInformation": "Informaci\u00f3n del Servidor",
+ "HeaderServerInformation": "Informaci\u00f3n del Servidor",
"ButtonRestartNow": "Reiniciar Ahora",
"ButtonRestart": "Reiniciar",
"ButtonShutdown": "Apagar",
@@ -1216,7 +1216,7 @@
"HeaderCameraUploadHelp": "Suba a Media Broswer fotos y videos tomados desde sus dispositivos m\u00f3viles de forma autom\u00e1tica.",
"MessageNoDevicesSupportCameraUpload": "Actualmente no cuenta con ning\u00fan dispositivo que soporte subir desde la c\u00e1mara.",
"LabelCameraUploadPath": "Ruta para subir desde la c\u00e1mara:",
- "LabelCameraUploadPathHelp": "Select a custom upload path, if desired. If unspecified a default folder will be used. If using a custom path it will also need to be added in the library setup area.",
+ "LabelCameraUploadPathHelp": "Seleccione una trayectoria personalizada de subida. Si no se especifica, una carpeta por omisi\u00f3n ser\u00e1 usada. Si usa una trayectoria personalizada, tambi\u00e9n ser\u00e1 necesario a\u00f1adirla en el \u00e1rea de configuraci\u00f3n de la biblioteca.",
"LabelCreateCameraUploadSubfolder": "Crear una subcarpeta para cada dispositivo",
"LabelCreateCameraUploadSubfolderHelp": "Se pueden especificar carpetas espec\u00edficas para un dispositivo haciendo clic en \u00e9l desde la p\u00e1gina de Dispositivos.",
"LabelCustomDeviceDisplayName": "Nombre a Desplegar:",
@@ -1273,7 +1273,11 @@
"HeaderParentalRatings": "Clasificaci\u00f3n Parental",
"HeaderVideoTypes": "Tipos de Video",
"HeaderYears": "A\u00f1os",
- "HeaderAddTag": "Add Tag",
- "LabelBlockItemsWithTags": "Block items with tags:",
- "LabelTag": "Tag:"
+ "HeaderAddTag": "Agregar Etiqueta",
+ "LabelBlockItemsWithTags": "Bloquear \u00edtems con etiquetas:",
+ "LabelTag": "Etiqueta:",
+ "LabelEnableSingleImageInDidlLimit": "Limitar a una sola imagen incrustada.",
+ "LabelEnableSingleImageInDidlLimitHelp": "Algunos dispositivos no renderisaran apropiadamente si hay m\u00faltiples im\u00e1genes incrustadas en el Didl",
+ "TabActivity": "Actividad",
+ "TitleSync": "Sincronizando"
} \ No newline at end of file
diff --git a/MediaBrowser.Server.Implementations/Localization/Server/fi.json b/MediaBrowser.Server.Implementations/Localization/Server/fi.json
index 5c25cf4936..c23d5a7086 100644
--- a/MediaBrowser.Server.Implementations/Localization/Server/fi.json
+++ b/MediaBrowser.Server.Implementations/Localization/Server/fi.json
@@ -539,7 +539,7 @@
"HeaderRunningTasks": "Running Tasks",
"HeaderActiveDevices": "Active Devices",
"HeaderPendingInstallations": "Pending Installations",
- "HeaerServerInformation": "Server Information",
+ "HeaderServerInformation": "Server Information",
"ButtonRestartNow": "Restart Now",
"ButtonRestart": "Restart",
"ButtonShutdown": "Shutdown",
@@ -1275,5 +1275,9 @@
"HeaderYears": "Years",
"HeaderAddTag": "Add Tag",
"LabelBlockItemsWithTags": "Block items with tags:",
- "LabelTag": "Tag:"
+ "LabelTag": "Tag:",
+ "LabelEnableSingleImageInDidlLimit": "Limit to single embedded image",
+ "LabelEnableSingleImageInDidlLimitHelp": "Some devices will not render properly if multiple images are embedded within Didl.",
+ "TabActivity": "Activity",
+ "TitleSync": "Sync"
} \ No newline at end of file
diff --git a/MediaBrowser.Server.Implementations/Localization/Server/fr.json b/MediaBrowser.Server.Implementations/Localization/Server/fr.json
index d9517131ed..0361928b4b 100644
--- a/MediaBrowser.Server.Implementations/Localization/Server/fr.json
+++ b/MediaBrowser.Server.Implementations/Localization/Server/fr.json
@@ -539,7 +539,7 @@
"HeaderRunningTasks": "T\u00e2ches en ex\u00e9cution",
"HeaderActiveDevices": "P\u00e9riph\u00e9riques actifs",
"HeaderPendingInstallations": "Installations en suspens",
- "HeaerServerInformation": "Information du serveur",
+ "HeaderServerInformation": "Server Information",
"ButtonRestartNow": "Red\u00e9marrer maintenant",
"ButtonRestart": "Red\u00e9marrer",
"ButtonShutdown": "\u00c9teindre",
@@ -888,7 +888,7 @@
"LabelProtocolInfoHelp": "La valeur qui sera utilis\u00e9e pour r\u00e9pondre aux requ\u00eates GetProtocolInfo du p\u00e9riph\u00e9rique.",
"TabKodiMetadata": "Kodi",
"HeaderKodiMetadataHelp": "Media Browser supporte nativement les m\u00e9tadonn\u00e9es Nfo et les images de Kodi. Pour activer ou d\u00e9sactiver les m\u00e9tadonn\u00e9es Kodi, utiliser l'onglet Avanc\u00e9 pour configurer les options de vos types de m\u00e9dias.",
- "LabelKodiMetadataUser": "Sync user watch data to nfo's for:",
+ "LabelKodiMetadataUser": "Les utilisateurs synchronis\u00e9s voient les donn\u00e9es nfo pour:",
"LabelKodiMetadataUserHelp": "Activer pour garder les donn\u00e9es de visualisation synchronis\u00e9es entre Media Browser et Kodi.",
"LabelKodiMetadataDateFormat": "Format de la date de sortie :",
"LabelKodiMetadataDateFormatHelp": "Toutes les dates du nfo seront lues et \u00e9crites en utilisant ce format.",
@@ -1216,7 +1216,7 @@
"HeaderCameraUploadHelp": "Uploader automatiquement les photos et les vid\u00e9os depuis vos p\u00e9riph\u00e9riques mobiles dans Media Browser.",
"MessageNoDevicesSupportCameraUpload": "Vous n'avez actuellement aucun p\u00e9riph\u00e9riques support\u00e9 par l'upload de la cam\u00e9ra.",
"LabelCameraUploadPath": "R\u00e9pertoire de l'upload de la camera:",
- "LabelCameraUploadPathHelp": "Select a custom upload path, if desired. If unspecified a default folder will be used. If using a custom path it will also need to be added in the library setup area.",
+ "LabelCameraUploadPathHelp": "Si vous le souhaitez, vous pouvez choisir un r\u00e9pertoire d'upload personnalis\u00e9. Si vous ne mettez rien, le r\u00e9pertoire par d\u00e9faut sera utilis\u00e9. Si vous utilisez un r\u00e9pertoire personnalis\u00e9, vous devrez le rajouter \u00e0 la biblioth\u00e8que.",
"LabelCreateCameraUploadSubfolder": "Cr\u00e9er un sous-dossier pour chaque p\u00e9riph\u00e9rique",
"LabelCreateCameraUploadSubfolderHelp": "Des r\u00e9pertoires sp\u00e9cifiques peuvent \u00eatres affect\u00e9 \u00e0 des appareils en cliquant sur l'appareil dans la page des appareils.",
"LabelCustomDeviceDisplayName": "Nom d'affichage:",
@@ -1273,7 +1273,11 @@
"HeaderParentalRatings": "Note parentale",
"HeaderVideoTypes": "Types de vid\u00e9o",
"HeaderYears": "Ann\u00e9es",
- "HeaderAddTag": "Add Tag",
- "LabelBlockItemsWithTags": "Block items with tags:",
- "LabelTag": "Tag:"
+ "HeaderAddTag": "Ajouter un tag",
+ "LabelBlockItemsWithTags": "Bloquer les \u00e9l\u00e9ments contenant les tags:",
+ "LabelTag": "Tag:",
+ "LabelEnableSingleImageInDidlLimit": "Limit to single embedded image",
+ "LabelEnableSingleImageInDidlLimitHelp": "Some devices will not render properly if multiple images are embedded within Didl.",
+ "TabActivity": "Activity",
+ "TitleSync": "Sync"
} \ No newline at end of file
diff --git a/MediaBrowser.Server.Implementations/Localization/Server/he.json b/MediaBrowser.Server.Implementations/Localization/Server/he.json
index 4f4691bd7a..2e90ed5df6 100644
--- a/MediaBrowser.Server.Implementations/Localization/Server/he.json
+++ b/MediaBrowser.Server.Implementations/Localization/Server/he.json
@@ -539,7 +539,7 @@
"HeaderRunningTasks": "\u05de\u05e9\u05d9\u05de\u05d5\u05ea \u05e8\u05e6\u05d5\u05ea",
"HeaderActiveDevices": "\u05de\u05db\u05e9\u05d9\u05e8\u05d9\u05dd \u05e4\u05e2\u05d9\u05dc\u05d9\u05dd",
"HeaderPendingInstallations": "\u05d4\u05ea\u05e7\u05e0\u05d5\u05ea \u05d1\u05d4\u05de\u05ea\u05e0\u05d4",
- "HeaerServerInformation": "\u05de\u05d9\u05d3\u05e2 \u05e2\u05dc \u05d4\u05e9\u05e8\u05ea",
+ "HeaderServerInformation": "Server Information",
"ButtonRestartNow": "\u05d4\u05ea\u05d7\u05dc \u05de\u05d7\u05d3\u05e9 \u05db\u05e2\u05d8",
"ButtonRestart": "\u05d4\u05ea\u05d7\u05e8 \u05de\u05d7\u05d3\u05e9",
"ButtonShutdown": "\u05db\u05d1\u05d4",
@@ -1275,5 +1275,9 @@
"HeaderYears": "Years",
"HeaderAddTag": "Add Tag",
"LabelBlockItemsWithTags": "Block items with tags:",
- "LabelTag": "Tag:"
+ "LabelTag": "Tag:",
+ "LabelEnableSingleImageInDidlLimit": "Limit to single embedded image",
+ "LabelEnableSingleImageInDidlLimitHelp": "Some devices will not render properly if multiple images are embedded within Didl.",
+ "TabActivity": "Activity",
+ "TitleSync": "Sync"
} \ No newline at end of file
diff --git a/MediaBrowser.Server.Implementations/Localization/Server/hr.json b/MediaBrowser.Server.Implementations/Localization/Server/hr.json
index 17c5764bab..2a4612d34f 100644
--- a/MediaBrowser.Server.Implementations/Localization/Server/hr.json
+++ b/MediaBrowser.Server.Implementations/Localization/Server/hr.json
@@ -539,7 +539,7 @@
"HeaderRunningTasks": "Zadatci koji se izvode",
"HeaderActiveDevices": "Aktivni ure\u0111aji",
"HeaderPendingInstallations": "Instalacije u toku",
- "HeaerServerInformation": "Informacije servera",
+ "HeaderServerInformation": "Server Information",
"ButtonRestartNow": "Ponovo pokreni sad",
"ButtonRestart": "Ponovo pokreni",
"ButtonShutdown": "Ugasi",
@@ -1275,5 +1275,9 @@
"HeaderYears": "Years",
"HeaderAddTag": "Add Tag",
"LabelBlockItemsWithTags": "Block items with tags:",
- "LabelTag": "Tag:"
+ "LabelTag": "Tag:",
+ "LabelEnableSingleImageInDidlLimit": "Limit to single embedded image",
+ "LabelEnableSingleImageInDidlLimitHelp": "Some devices will not render properly if multiple images are embedded within Didl.",
+ "TabActivity": "Activity",
+ "TitleSync": "Sync"
} \ No newline at end of file
diff --git a/MediaBrowser.Server.Implementations/Localization/Server/it.json b/MediaBrowser.Server.Implementations/Localization/Server/it.json
index 9780d58560..b306eb3720 100644
--- a/MediaBrowser.Server.Implementations/Localization/Server/it.json
+++ b/MediaBrowser.Server.Implementations/Localization/Server/it.json
@@ -5,7 +5,7 @@
"LabelSwagger": "Swagger",
"LabelStandard": "Standard",
"LabelApiDocumentation": "Api Documentation",
- "LabelDeveloperResources": "Developer Resources",
+ "LabelDeveloperResources": "Risorse programmatori",
"LabelBrowseLibrary": "Esplora la libreria",
"LabelConfigureMediaBrowser": "Configura Media Browser",
"LabelOpenLibraryViewer": "Apri visualizzatore libreria",
@@ -78,7 +78,7 @@
"ButtonAddLocalUser": "Aggiungi Utente locale",
"ButtonInviteUser": "Invita un utente",
"ButtonSave": "Salva",
- "ButtonResetPassword": "Reset Password",
+ "ButtonResetPassword": "Ripristina Password",
"LabelNewPassword": "Nuova Password:",
"LabelNewPasswordConfirm": "Nuova Password Conferma:",
"HeaderCreatePassword": "Crea Password",
@@ -110,7 +110,7 @@
"OptionLikes": "Belli",
"OptionDislikes": "Brutti",
"OptionActors": "Attori",
- "OptionGuestStars": "Guest Stars",
+ "OptionGuestStars": "Personaggi Famosi",
"OptionDirectors": "Registra",
"OptionWriters": "Scrittore",
"OptionProducers": "Produttore",
@@ -539,7 +539,7 @@
"HeaderRunningTasks": "Operazione in corso",
"HeaderActiveDevices": "Dispositivi Connessi",
"HeaderPendingInstallations": "installazioni in coda",
- "HeaerServerInformation": "Informazioni del server",
+ "HeaderServerInformation": "Informazioni Server",
"ButtonRestartNow": "Riavvia Adesso",
"ButtonRestart": "Riavvia",
"ButtonShutdown": "Arresta Server",
@@ -620,7 +620,7 @@
"AdditionalNotificationServices": "Sfoglia il catalogo plugin per installare i servizi di notifica aggiuntivi.",
"OptionAllUsers": "Tutti gli utenti",
"OptionAdminUsers": "Administrators",
- "OptionCustomUsers": "Custom",
+ "OptionCustomUsers": "Personalizza",
"ButtonArrowUp": "Su",
"ButtonArrowDown": "Gi\u00f9",
"ButtonArrowLeft": "Sinistra",
@@ -676,7 +676,7 @@
"HeaderCodecProfile": "Codec Profilo",
"HeaderCodecProfileHelp": "Profili Codec indicano i limiti di un dispositivo durante la riproduzione di codec specifici. Se una limitazione si applica poi saranno trascodificati media, anche se il codec \u00e8 configurato per riproduzione diretta.",
"HeaderContainerProfile": "Profilo Contenitore",
- "HeaderContainerProfileHelp": "Container profiles indicate the limitations of a device when playing specific formats. If a limitation applies then the media will be transcoded, even if the format is configured for direct play.",
+ "HeaderContainerProfileHelp": "i Profili indicano i limiti di un dispositivo quando si riproduce in formati specifici. Se una limitazione si applica poi verranno transcodificati i media, anche se il formato \u00e8 configurato per la riproduzione diretta.",
"OptionProfileVideo": "Video",
"OptionProfileAudio": "Audio",
"OptionProfileVideoAudio": "Video Audio",
@@ -690,7 +690,7 @@
"LabelSupportedMediaTypes": "Tipi di media supportati:",
"TabIdentification": "identificazione",
"HeaderIdentification": "Identificazione",
- "TabDirectPlay": "Direct Play",
+ "TabDirectPlay": "Riproduzione Diretta",
"TabContainers": "contenitori",
"TabCodecs": "Codecs",
"TabResponses": "Risposte",
@@ -731,18 +731,18 @@
"LabelSerialNumber": "Numero di serie",
"LabelDeviceDescription": "Descrizione dispositivo",
"HeaderIdentificationCriteriaHelp": "Inserire almeno un criterio di identificazione.",
- "HeaderDirectPlayProfileHelp": "Add direct play profiles to indicate which formats the device can handle natively.",
+ "HeaderDirectPlayProfileHelp": "Aggiungere \"profili riproduzione diretta\" per indicare che il dispositivo \u00e8 in grado di gestire in modo nativo.",
"HeaderTranscodingProfileHelp": "Aggiungere i profili di transcodifica per indicare quali formati da utilizzare quando \u00e8 richiesta la transcodifica.",
"HeaderResponseProfileHelp": "Profili di risposta forniscono un modo per personalizzare le informazioni inviate al dispositivo durante la riproduzione di alcuni tipi di media.",
"LabelXDlnaCap": "X-Dlna cap:",
"LabelXDlnaCapHelp": "Determines the content of the X_DLNACAP element in the urn:schemas-dlna-org:device-1-0 namespace.",
"LabelXDlnaDoc": "X-Dlna doc:",
- "LabelXDlnaDocHelp": "Determines the content of the X_DLNADOC element in the urn:schemas-dlna-org:device-1-0 namespace.",
+ "LabelXDlnaDocHelp": "Determina il contenuto dell'elemento X_DLNACAP nella urn: schemas-DLNA-org: dispositivo 1-0 namespace.",
"LabelSonyAggregationFlags": "Sony aggregation flags:",
"LabelSonyAggregationFlagsHelp": "Determina il contenuto dell'elemento aggregationFlags nel urn: schemas-sonycom: namespace av.",
"LabelTranscodingContainer": "contenitore:",
"LabelTranscodingVideoCodec": "Video codec:",
- "LabelTranscodingVideoProfile": "Video profile:",
+ "LabelTranscodingVideoProfile": "Video profilo:",
"LabelTranscodingAudioCodec": "Audio codec:",
"OptionEnableM2tsMode": "Attiva modalit\u00e0 M2TS",
"OptionEnableM2tsModeHelp": "Attivare la modalit\u00e0 m2ts durante la codifica di mpegts.",
@@ -771,8 +771,8 @@
"LabelMessageText": "Testo del messaggio:",
"MessageNoAvailablePlugins": "Nessun plugin disponibili.",
"LabelDisplayPluginsFor": "Mostra plugin per:",
- "PluginTabMediaBrowserClassic": "MB Classic",
- "PluginTabMediaBrowserTheater": "MB Theater",
+ "PluginTabMediaBrowserClassic": "MB Classico",
+ "PluginTabMediaBrowserTheater": "MB Teatro",
"LabelEpisodeNamePlain": "Nome Episodio",
"LabelSeriesNamePlain": "Nome Serie",
"ValueSeriesNamePeriod": "Nome Serie",
@@ -939,7 +939,7 @@
"LabelMatchType": "Match type:",
"OptionEquals": "Uguale",
"OptionRegex": "Regex",
- "OptionSubstring": "Substring",
+ "OptionSubstring": "Sottostringa",
"TabView": "Vista",
"TabSort": "Ordina",
"TabFilter": "Filtra",
@@ -1135,7 +1135,7 @@
"OptionActor": "Attore",
"OptionComposer": "Compositore",
"OptionDirector": "Regista",
- "OptionGuestStar": "Guest star",
+ "OptionGuestStar": "Personaggi famosi",
"OptionProducer": "Produttore",
"OptionWriter": "Scrittore",
"LabelAirDays": "In onda da (gg):",
@@ -1160,7 +1160,7 @@
"LabelExtractChaptersDuringLibraryScan": "Estrarre immagini capitolo durante la scansione biblioteca",
"LabelExtractChaptersDuringLibraryScanHelp": "Se abilitata, le immagini capitolo verranno estratti quando i video vengono importati durante la scansione della libreria. Se disabilitata verranno estratti durante le immagini dei capitoli programmati compito, permettendo la scansione biblioteca regolare per completare pi\u00f9 velocemente.",
"LabelConnectGuestUserName": "I loro Utente o email di Media Browser",
- "LabelConnectUserName": "Media Browser username\/email:",
+ "LabelConnectUserName": "Media Browser utente\/email:",
"LabelConnectUserNameHelp": "Collega questo utente a un conto Media Browser per abilitare acceso rapido da Media Browser con qualsiasi applicazione senza dovere conoscere il indirrzo IP.",
"ButtonLearnMoreAboutMediaBrowserConnect": "Scopri di pi\u00f9 su Media Browser Connect",
"LabelExternalPlayers": "Player esterni:",
@@ -1216,7 +1216,7 @@
"HeaderCameraUploadHelp": "Caricare automaticamente foto e video presi dai vostri dispositivi mobili in Media Browser.",
"MessageNoDevicesSupportCameraUpload": "Al momento non si dispone di dispositivi che supportano il caricamento della fotocamera.",
"LabelCameraUploadPath": "Fotocamera percorso di upload:",
- "LabelCameraUploadPathHelp": "Select a custom upload path, if desired. If unspecified a default folder will be used. If using a custom path it will also need to be added in the library setup area.",
+ "LabelCameraUploadPathHelp": "Selezionare un percorso di caricamento personalizzato, se lo si desidera. Se non specificato verr\u00e0 utilizzata una cartella predefinita. Se si utilizza un percorso personalizzato che dovr\u00e0 anche essere aggiunti nella zona di installazione della libreria.",
"LabelCreateCameraUploadSubfolder": "Creare una sottocartella per ogni dispositivo",
"LabelCreateCameraUploadSubfolderHelp": "Cartelle specifici possono essere assegnati a un dispositivo facendo clic su di esso dalla pagina Dispositivi.",
"LabelCustomDeviceDisplayName": "Nome da visualizzare:",
@@ -1275,5 +1275,9 @@
"HeaderYears": "Anni",
"HeaderAddTag": "Add Tag",
"LabelBlockItemsWithTags": "Block items with tags:",
- "LabelTag": "Tag:"
+ "LabelTag": "Tag:",
+ "LabelEnableSingleImageInDidlLimit": "Limit to single embedded image",
+ "LabelEnableSingleImageInDidlLimitHelp": "Some devices will not render properly if multiple images are embedded within Didl.",
+ "TabActivity": "Activity",
+ "TitleSync": "Sync"
} \ No newline at end of file
diff --git a/MediaBrowser.Server.Implementations/Localization/Server/kk.json b/MediaBrowser.Server.Implementations/Localization/Server/kk.json
index 37e00d0d83..c017c3b8fd 100644
--- a/MediaBrowser.Server.Implementations/Localization/Server/kk.json
+++ b/MediaBrowser.Server.Implementations/Localization/Server/kk.json
@@ -235,8 +235,8 @@
"OptionAllowDeleteLibraryContent": "\u0411\u04b1\u043b \u043f\u0430\u0439\u0434\u0430\u043b\u0430\u043d\u0443\u0448\u044b\u0493\u0430 \u0442\u0430\u0441\u0443\u0448\u044b\u0445\u0430\u043d\u0430 \u043c\u0430\u0437\u043c\u04b1\u043d\u044b\u043d \u0436\u043e\u044e \u04af\u0448\u0456\u043d \u0440\u04b1\u049b\u0441\u0430\u0442 \u0435\u0442\u0443",
"OptionAllowManageLiveTv": "\u042d\u0444\u0438\u0440\u043b\u0456\u043a \u0422\u0414 \u0436\u0430\u0437\u0443\u0434\u044b \u0431\u0430\u0441\u049b\u0430\u0440\u0443\u044b\u043d\u0430 \u0440\u0443\u049b\u0441\u0430\u0442 \u0435\u0442\u0443",
"OptionAllowRemoteControlOthers": "\u0411\u04b1\u043b \u043f\u0430\u0439\u0434\u0430\u043b\u0430\u043d\u0443\u0448\u044b\u0493\u0430 \u0431\u0430\u0441\u049b\u0430 \u043f\u0430\u0439\u0434\u0430\u043b\u0430\u043d\u0443\u0448\u044b\u043b\u0430\u0440\u0434\u044b \u049b\u0430\u0448\u044b\u049b\u0442\u0430\u043d \u0431\u0430\u0441\u049b\u0430\u0440\u0443 \u04af\u0448\u0456\u043d \u0440\u04b1\u049b\u0441\u0430\u0442 \u0435\u0442\u0443",
- "OptionAllowRemoteSharedDevices": "\u0411\u04b1\u043b \u043f\u0430\u0439\u0434\u0430\u043b\u0430\u043d\u0443\u0448\u044b\u0493\u0430 \u043e\u0440\u0442\u0430\u049b \u0436\u0430\u0431\u0434\u044b\u049b\u0442\u0430\u0440\u0434\u044b \u049b\u0430\u0448\u044b\u049b\u0442\u0430\u043d \u0431\u0430\u0441\u049b\u0430\u0440\u0443 \u04af\u0448\u0456\u043d \u0440\u04b1\u049b\u0441\u0430\u0442 \u0435\u0442\u0443",
- "OptionAllowRemoteSharedDevicesHelp": "DLNA-\u0436\u0430\u0431\u0434\u044b\u049b\u0442\u0430\u0440\u044b \u043f\u0430\u0439\u0434\u0430\u043b\u0430\u043d\u0443\u0448\u044b \u0431\u0430\u0441\u049b\u0430\u0440\u0493\u0430\u043d\u0448\u0430 \u0434\u0435\u0439\u0456\u043d \u043e\u0440\u0442\u0430\u049b \u0440\u0435\u0442\u0456\u043d\u0434\u0435 \u0435\u0441\u0435\u043f\u0442\u0435\u043b\u0456\u043d\u0435\u0434\u0456.",
+ "OptionAllowRemoteSharedDevices": "\u0411\u04b1\u043b \u043f\u0430\u0439\u0434\u0430\u043b\u0430\u043d\u0443\u0448\u044b\u0493\u0430 \u043e\u0440\u0442\u0430\u049b \u049b\u04b1\u0440\u044b\u043b\u0493\u044b\u043b\u0430\u0440\u0434\u044b \u049b\u0430\u0448\u044b\u049b\u0442\u0430\u043d \u0431\u0430\u0441\u049b\u0430\u0440\u0443 \u04af\u0448\u0456\u043d \u0440\u04b1\u049b\u0441\u0430\u0442 \u0435\u0442\u0443",
+ "OptionAllowRemoteSharedDevicesHelp": "DLNA-\u049b\u04b1\u0440\u044b\u043b\u0493\u044b\u043b\u0430\u0440\u044b \u043f\u0430\u0439\u0434\u0430\u043b\u0430\u043d\u0443\u0448\u044b \u0431\u0430\u0441\u049b\u0430\u0440\u0493\u0430\u043d\u0448\u0430 \u0434\u0435\u0439\u0456\u043d \u043e\u0440\u0442\u0430\u049b \u0440\u0435\u0442\u0456\u043d\u0434\u0435 \u0435\u0441\u0435\u043f\u0442\u0435\u043b\u0456\u043d\u0435\u0434\u0456.",
"HeaderRemoteControl": "\u049a\u0430\u0448\u044b\u049b\u0442\u0430\u043d \u0431\u0430\u0441\u049b\u0430\u0440\u0443",
"OptionMissingTmdbId": "TMDb Id \u0436\u043e\u049b",
"OptionIsHD": "HD",
@@ -539,7 +539,7 @@
"HeaderRunningTasks": "\u041e\u0440\u044b\u043d\u0434\u0430\u043b\u044b\u043f \u0436\u0430\u0442\u049b\u0430\u043d \u0442\u0430\u043f\u0441\u044b\u0440\u043c\u0430\u043b\u0430\u0440",
"HeaderActiveDevices": "\u0411\u0435\u043b\u0441\u0435\u043d\u0434\u0456 \u049b\u04b1\u0440\u044b\u043b\u0493\u044b\u043b\u0430\u0440",
"HeaderPendingInstallations": "\u0411\u04e9\u0433\u0435\u043b\u0456\u0441 \u043e\u0440\u043d\u0430\u0442\u044b\u043c\u0434\u0430\u0440",
- "HeaerServerInformation": "\u0421\u0435\u0440\u0432\u0435\u0440 \u043c\u04d9\u043b\u0456\u043c\u0435\u0442\u0442\u0435\u0440\u0456",
+ "HeaderServerInformation": "\u0421\u0435\u0440\u0432\u0435\u0440 \u043c\u04d9\u043b\u0456\u043c\u0435\u0442\u0456",
"ButtonRestartNow": "\u049a\u0430\u0437\u0456\u0440 \u049b\u0430\u0439\u0442\u0430 \u0456\u0441\u043a\u0435 \u049b\u043e\u0441\u0443",
"ButtonRestart": "\u049a\u0430\u0439\u0442\u0430 \u0456\u0441\u043a\u0435 \u049b\u043e\u0441\u0443",
"ButtonShutdown": "\u0416\u04b1\u043c\u044b\u0441\u0442\u044b \u0430\u044f\u049b\u0442\u0430\u0443",
@@ -571,7 +571,7 @@
"TabPlayTo": "\u049a\u04b1\u0440\u044b\u043b\u0493\u044b\u0434\u0430 \u043e\u0439\u043d\u0430\u0442\u0443",
"LabelEnableDlnaServer": "DLNA \u0441\u0435\u0440\u0432\u0435\u0440\u0456\u043d \u049b\u043e\u0441\u0443",
"LabelEnableDlnaServerHelp": "\u0416\u0435\u043b\u0456\u0434\u0435\u0433\u0456 UPnP \u049b\u04b1\u0440\u044b\u043b\u0493\u044b\u043b\u0430\u0440\u0493\u0430 Media Browser \u043c\u0430\u0437\u043c\u04b1\u043d\u044b\u043d \u0448\u043e\u043b\u0443 \u043c\u0435\u043d \u043e\u0439\u043d\u0430\u0442\u0443 \u04af\u0448\u0456\u043d \u0440\u04b1\u049b\u0441\u0430\u0442 \u0435\u0442\u0443.",
- "LabelEnableBlastAliveMessages": "\u0411\u0435\u043b\u0441\u0435\u043d\u0434\u0456\u043b\u0456\u043a\u0442\u0456 \u0442\u0435\u043a\u0441\u0435\u0440\u0443 \u0445\u0430\u0431\u0430\u0440\u043b\u0430\u0440\u044b\u043d \u043b\u0430\u043f \u0435\u0442\u0443",
+ "LabelEnableBlastAliveMessages": "\u0411\u0435\u043b\u0441\u0435\u043d\u0434\u0456\u043b\u0456\u043a\u0442\u0456 \u0442\u0435\u043a\u0441\u0435\u0440\u0443 \u0445\u0430\u0431\u0430\u0440\u043b\u0430\u0440\u044b\u043d \u0436\u0430\u0443\u0434\u044b\u0440\u0443",
"LabelEnableBlastAliveMessagesHelp": "\u0415\u0433\u0435\u0440 \u0436\u0435\u043b\u0456\u0434\u0435\u0433\u0456 \u0431\u0430\u0441\u049b\u0430 UPnP \u049b\u04b1\u0440\u044b\u043b\u0493\u044b\u043b\u0430\u0440\u044b\u043c\u0435\u043d \u0441\u0435\u0440\u0432\u0435\u0440 \u043d\u044b\u049b \u0442\u0430\u0431\u044b\u043b\u043c\u0430\u0441\u0430 \u0431\u04b1\u043d\u044b \u049b\u043e\u0441\u044b\u04a3\u044b\u0437.",
"LabelBlastMessageInterval": "\u0411\u0435\u043b\u0441\u0435\u043d\u0434\u0456\u043b\u0456\u043a\u0442\u0456 \u0442\u0435\u043a\u0441\u0435\u0440\u0443 \u0445\u0430\u0431\u0430\u0440\u043b\u0430\u0440 \u0430\u0440\u0430\u043b\u044b\u0493\u044b, \u0441",
"LabelBlastMessageIntervalHelp": "\u0421\u0435\u0440\u0432\u0435\u0440 \u0431\u0435\u043b\u0441\u0435\u043d\u0434\u0456\u043b\u0456\u0433\u0456\u043d \u0442\u0435\u043a\u0441\u0435\u0440\u0443 \u0445\u0430\u0431\u0430\u0440\u043b\u0430\u0440\u0434\u044b\u04a3 \u0430\u0440\u0430 \u04b1\u0437\u0430\u049b\u0442\u044b\u0493\u044b\u043d \u0441\u0435\u043a\u0443\u043d\u0434\u0442\u0430\u0440 \u0430\u0440\u049b\u044b\u043b\u044b \u0430\u043d\u044b\u049b\u0442\u0430\u0439\u0434\u044b.",
@@ -674,15 +674,15 @@
"HeaderDirectPlayProfile": "\u0422\u0456\u043a\u0435\u043b\u0435\u0439 \u043e\u0439\u043d\u0430\u0442\u0443 \u043f\u0440\u043e\u0444\u0430\u0439\u043b\u044b",
"HeaderTranscodingProfile": "\u049a\u0430\u0439\u0442\u0430 \u043a\u043e\u0434\u0442\u0430\u0443 \u043f\u0440\u043e\u0444\u0430\u0439\u043b\u044b",
"HeaderCodecProfile": "\u041a\u043e\u0434\u0435\u043a \u043f\u0440\u043e\u0444\u0430\u0439\u043b\u044b",
- "HeaderCodecProfileHelp": "\u041a\u043e\u0434\u0435\u043a \u043f\u0440\u043e\u0444\u0430\u0439\u043b\u0434\u0430\u0440\u044b \u043d\u0430\u049b\u0442\u044b \u043a\u043e\u0434\u0435\u043a\u0442\u0435\u0440 \u0430\u0440\u049b\u044b\u043b\u044b \u043e\u0439\u043d\u0430\u0442\u049b\u0430\u043d\u0434\u0430 \u0436\u0430\u0431\u0434\u044b\u049b\u0442\u044b\u04a3 \u0448\u0435\u043a\u0442\u0435\u0443\u043b\u0435\u0440\u0456\u043d \u043a\u04e9\u0440\u0441\u0435\u0442\u0435\u0434\u0456. \u0415\u0433\u0435\u0440 \u0448\u0435\u043a\u0442\u0435\u0443 \u049b\u043e\u043b\u0434\u0430\u043d\u044b\u043b\u0441\u0430, \u0441\u043e\u043d\u0434\u0430 \u043a\u043e\u0434\u0435\u043a \u0442\u0456\u043a\u0435\u043b\u0435\u0439 \u043e\u0439\u043d\u0430\u0442\u0443 \u04af\u0448\u0456\u043d \u0442\u0435\u04a3\u0448\u0435\u043b\u0441\u0435\u0434\u0435 \u0442\u0430\u0441\u0443\u0448\u044b\u0434\u0435\u0440\u0435\u043a\u0442\u0435\u0440 \u049b\u0430\u0439\u0442\u0430 \u043a\u043e\u0434\u0442\u0430\u043b\u044b\u043d\u0430\u0434\u044b.",
+ "HeaderCodecProfileHelp": "\u041a\u043e\u0434\u0435\u043a \u043f\u0440\u043e\u0444\u0430\u0439\u043b\u0434\u0430\u0440\u044b \u043d\u0430\u049b\u0442\u044b \u043a\u043e\u0434\u0435\u043a\u0442\u0435\u0440 \u0430\u0440\u049b\u044b\u043b\u044b \u043e\u0439\u043d\u0430\u0442\u049b\u0430\u043d\u0434\u0430 \u049b\u04b1\u0440\u044b\u043b\u0493\u044b\u043d\u044b\u04a3 \u0448\u0435\u043a\u0442\u0435\u0443\u043b\u0435\u0440\u0456\u043d \u043a\u04e9\u0440\u0441\u0435\u0442\u0435\u0434\u0456. \u0415\u0433\u0435\u0440 \u0448\u0435\u043a\u0442\u0435\u0443 \u049b\u043e\u043b\u0434\u0430\u043d\u044b\u043b\u0441\u0430, \u0441\u043e\u043d\u0434\u0430 \u043a\u043e\u0434\u0435\u043a \u0442\u0456\u043a\u0435\u043b\u0435\u0439 \u043e\u0439\u043d\u0430\u0442\u0443 \u04af\u0448\u0456\u043d \u0442\u0435\u04a3\u0448\u0435\u043b\u0441\u0435\u0434\u0435 \u0442\u0430\u0441\u0443\u0448\u044b\u0434\u0435\u0440\u0435\u043a\u0442\u0435\u0440 \u049b\u0430\u0439\u0442\u0430 \u043a\u043e\u0434\u0442\u0430\u043b\u044b\u043d\u0430\u0434\u044b.",
"HeaderContainerProfile": "\u041a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440 \u043f\u0440\u043e\u0444\u0430\u0439\u043b\u044b",
- "HeaderContainerProfileHelp": "\u041a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440 \u043f\u0440\u043e\u0444\u0430\u0439\u043b\u0434\u0430\u0440\u044b \u043d\u0430\u049b\u0442\u044b \u043f\u0456\u0448\u0456\u043c\u0434\u0435\u0440 \u0430\u0440\u049b\u044b\u043b\u044b \u043e\u0439\u043d\u0430\u0442\u049b\u0430\u043d\u0434\u0430 \u0436\u0430\u0431\u0434\u044b\u049b\u0442\u044b\u04a3 \u0448\u0435\u043a\u0442\u0435\u0443\u043b\u0435\u0440\u0456\u043d \u043a\u04e9\u0440\u0441\u0435\u0442\u0435\u0434\u0456. \u0415\u0433\u0435\u0440 \u0448\u0435\u043a\u0442\u0435\u0443 \u049b\u043e\u043b\u0434\u0430\u043d\u044b\u043b\u0441\u0430, \u0441\u043e\u043d\u0434\u0430 \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440 \u0442\u0456\u043a\u0435\u043b\u0435\u0439 \u043e\u0439\u043d\u0430\u0442\u0443 \u04af\u0448\u0456\u043d \u0442\u0435\u04a3\u0448\u0435\u043b\u0441\u0435\u0434\u0435 \u0442\u0430\u0441\u0443\u0448\u044b\u0434\u0435\u0440\u0435\u043a\u0442\u0435\u0440 \u049b\u0430\u0439\u0442\u0430 \u043a\u043e\u0434\u0442\u0430\u043b\u044b\u043d\u0430\u0434\u044b.",
+ "HeaderContainerProfileHelp": "\u041a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440 \u043f\u0440\u043e\u0444\u0430\u0439\u043b\u0434\u0430\u0440\u044b \u043d\u0430\u049b\u0442\u044b \u043f\u0456\u0448\u0456\u043c\u0434\u0435\u0440 \u0430\u0440\u049b\u044b\u043b\u044b \u043e\u0439\u043d\u0430\u0442\u049b\u0430\u043d\u0434\u0430 \u049b\u04b1\u0440\u044b\u043b\u0493\u044b\u043d\u044b\u04a3 \u0448\u0435\u043a\u0442\u0435\u0443\u043b\u0435\u0440\u0456\u043d \u043a\u04e9\u0440\u0441\u0435\u0442\u0435\u0434\u0456. \u0415\u0433\u0435\u0440 \u0448\u0435\u043a\u0442\u0435\u0443 \u049b\u043e\u043b\u0434\u0430\u043d\u044b\u043b\u0441\u0430, \u0441\u043e\u043d\u0434\u0430 \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440 \u0442\u0456\u043a\u0435\u043b\u0435\u0439 \u043e\u0439\u043d\u0430\u0442\u0443 \u04af\u0448\u0456\u043d \u0442\u0435\u04a3\u0448\u0435\u043b\u0441\u0435\u0434\u0435 \u0442\u0430\u0441\u0443\u0448\u044b\u0434\u0435\u0440\u0435\u043a\u0442\u0435\u0440 \u049b\u0430\u0439\u0442\u0430 \u043a\u043e\u0434\u0442\u0430\u043b\u044b\u043d\u0430\u0434\u044b.",
"OptionProfileVideo": "\u0411\u0435\u0439\u043d\u0435",
"OptionProfileAudio": "\u0414\u044b\u0431\u044b\u0441",
"OptionProfileVideoAudio": "\u0411\u0435\u0439\u043d\u0435 \u0414\u044b\u0431\u044b\u0441",
"OptionProfilePhoto": "\u0424\u043e\u0442\u043e",
"LabelUserLibrary": "\u041f\u0430\u0439\u0434\u0430\u043b\u0430\u043d\u0443\u0448\u044b \u0442\u0430\u0441\u0443\u0448\u044b\u0445\u0430\u043d\u0430\u0441\u044b",
- "LabelUserLibraryHelp": "\u0416\u0430\u0431\u0434\u044b\u049b\u0442\u0430 \u049b\u0430\u0439 \u043f\u0430\u0439\u0434\u0430\u043b\u0430\u043d\u0443\u0448\u044b \u0442\u0430\u0441\u0443\u0448\u044b\u0445\u0430\u043d\u0430\u0441\u044b\u043d \u0431\u0435\u0439\u043d\u0435\u043b\u0435\u0443\u0456\u043d \u0442\u0430\u04a3\u0434\u0430\u04a3\u044b\u0437. \u04d8\u0434\u0435\u043f\u043a\u0456 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440 \u043c\u04b1\u0440\u0430\u0441\u044b\u043d\u0430 \u0438\u0435\u043b\u0435\u043d\u0443 \u04af\u0448\u0456\u043d \u0431\u043e\u0441 \u049b\u0430\u043b\u0434\u044b\u0440\u044b\u04a3\u044b\u0437.",
+ "LabelUserLibraryHelp": "\u049a\u04b1\u0440\u044b\u043b\u0493\u044b\u0434\u0430 \u049b\u0430\u0439 \u043f\u0430\u0439\u0434\u0430\u043b\u0430\u043d\u0443\u0448\u044b \u0442\u0430\u0441\u0443\u0448\u044b\u0445\u0430\u043d\u0430\u0441\u044b\u043d \u0431\u0435\u0439\u043d\u0435\u043b\u0435\u0443\u0456\u043d \u0442\u0430\u04a3\u0434\u0430\u04a3\u044b\u0437. \u04d8\u0434\u0435\u043f\u043a\u0456 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440 \u043c\u04b1\u0440\u0430\u0441\u044b\u043d\u0430 \u0438\u0435\u043b\u0435\u043d\u0443 \u04af\u0448\u0456\u043d \u0431\u043e\u0441 \u049b\u0430\u043b\u0434\u044b\u0440\u044b\u04a3\u044b\u0437.",
"OptionPlainStorageFolders": "\u0411\u0430\u0440\u043b\u044b\u049b \u049b\u0430\u043b\u0442\u0430\u043b\u0430\u0440\u0434\u044b \u0436\u0430\u0439 \u0441\u0430\u049b\u0442\u0430\u0443 \u049b\u0430\u043b\u0442\u0430\u043b\u0430\u0440\u044b \u0440\u0435\u0442\u0456\u043d\u0434\u0435 \u0431\u0435\u0439\u043d\u0435\u043b\u0435\u0443",
"OptionPlainStorageFoldersHelp": "\u049a\u043e\u0441\u044b\u043b\u0493\u0430\u043d\u0434\u0430, \u0431\u0430\u0440\u043b\u044b\u049b \u049b\u0430\u043b\u0442\u0430\u043b\u0430\u0440 DIDL \u0456\u0448\u0456\u043d\u0434\u0435 \"object.container.person.musicArtist\" \u0441\u0438\u044f\u049b\u0442\u044b \u043d\u0430\u049b\u0442\u044b\u043b\u0430\u0443 \u0442\u04af\u0440\u0456\u043d\u0456\u04a3 \u043e\u0440\u043d\u044b\u043d\u0430 \"object.container.storageFolder\" \u0431\u043e\u043b\u044b\u043f \u0431\u0435\u0439\u043d\u0435\u043b\u0435\u043d\u0435\u0434\u0456.",
"OptionPlainVideoItems": "\u0411\u0430\u0440\u043b\u044b\u049b \u0431\u0435\u0439\u043d\u0435\u043b\u0435\u0440\u0434\u0456 \u0436\u0430\u0439 \u0431\u0435\u0439\u043d\u0435 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u0442\u0435\u0440\u0456 \u0440\u0435\u0442\u0456\u043d\u0434\u0435 \u0431\u0435\u0439\u043d\u0435\u043b\u0435\u0443",
@@ -696,7 +696,7 @@
"TabResponses": "\u04ae\u043d \u049b\u0430\u0442\u0443\u043b\u0430\u0440",
"HeaderProfileInformation": "\u041f\u0440\u043e\u0444\u0430\u0439\u043b \u0430\u049b\u043f\u0430\u0440\u0430\u0442\u044b",
"LabelEmbedAlbumArtDidl": "Didl \u0456\u0448\u0456\u043d\u0435 \u0430\u043b\u044c\u0431\u043e\u043c \u0441\u0443\u0440\u0435\u0442\u0456\u043d \u0435\u043d\u0434\u0456\u0440\u0443",
- "LabelEmbedAlbumArtDidlHelp": "\u041a\u0435\u0439\u0431\u0456\u0440 \u0436\u0430\u0431\u0434\u044b\u049b\u0442\u0430\u0440\u0493\u0430 \u0430\u043b\u044c\u0431\u043e\u043c \u0441\u0443\u0440\u0435\u0442\u0456\u043d \u0430\u043b\u0443 \u04af\u0448\u0456\u043d \u043e\u0441\u044b \u04d9\u0434\u0456\u0441 \u049b\u0430\u0436\u0435\u0442. \u0411\u0430\u0441\u049b\u0430\u043b\u0430\u0440 \u04af\u0448\u0456\u043d, \u043e\u0441\u044b \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440 \u049b\u043e\u0441\u044b\u043b\u0493\u0430\u043d\u0434\u0430, \u043e\u0439\u043d\u0430\u0442\u0443 \u0441\u04d9\u0442\u0441\u0456\u0437 \u0431\u043e\u043b\u0443\u044b \u043c\u04af\u043c\u043a\u0456\u043d.",
+ "LabelEmbedAlbumArtDidlHelp": "\u041a\u0435\u0439\u0431\u0456\u0440 \u049b\u04b1\u0440\u044b\u043b\u0493\u044b\u043b\u0430\u0440\u0493\u0430 \u0430\u043b\u044c\u0431\u043e\u043c \u0441\u0443\u0440\u0435\u0442\u0456\u043d \u0430\u043b\u0443 \u04af\u0448\u0456\u043d \u043e\u0441\u044b \u04d9\u0434\u0456\u0441 \u049b\u0430\u0436\u0435\u0442. \u0411\u0430\u0441\u049b\u0430\u043b\u0430\u0440 \u04af\u0448\u0456\u043d, \u043e\u0441\u044b \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440 \u049b\u043e\u0441\u044b\u043b\u0493\u0430\u043d\u0434\u0430, \u043e\u0439\u043d\u0430\u0442\u0443 \u0441\u04d9\u0442\u0441\u0456\u0437 \u0431\u043e\u043b\u0443\u044b \u043c\u04af\u043c\u043a\u0456\u043d.",
"LabelAlbumArtPN": "\u0410\u043b\u044c\u0431\u043e\u043c \u0441\u0443\u0440\u0435\u0442\u0456 PN:",
"LabelAlbumArtHelp": "PN \u0430\u043b\u044c\u0431\u043e\u043c \u0441\u0443\u0440\u0435\u0442\u0456 \u04af\u0448\u0456\u043d upnp:albumArtURI \u0456\u0448\u0456\u043d\u0434\u0435\u0433\u0456 dlna:profileID \u0442\u04e9\u043b\u0441\u0438\u043f\u0430\u0442\u044b\u043c\u0435\u043d \u0431\u0456\u0440\u0433\u0435 \u043f\u0430\u0439\u0434\u0430\u043b\u0430\u043d\u044b\u043b\u0430\u0434\u044b. \u041a\u0435\u0439\u0431\u0456\u0440 \u043a\u043b\u0438\u0435\u043d\u0442\u0442\u0435\u0440 \u04af\u0448\u0456\u043d \u0441\u0443\u0440\u0435\u0442\u0442\u0456\u04a3 \u04e9\u043b\u0448\u0435\u043c\u0456\u043d\u0435 \u0430\u04a3\u0493\u0430\u0440\u0443\u0441\u044b\u0437 \u043d\u0430\u049b\u0442\u044b \u043c\u04d9\u043d \u049b\u0430\u0436\u0435\u0442.",
"LabelAlbumArtMaxWidth": "\u0410\u043b\u044c\u0431\u043e\u043c \u0441\u0443\u0440\u0435\u0442\u0456\u043d\u0456\u04a3 \u0435\u04a3 \u0436\u043e\u0493\u0430\u0440\u044b \u0435\u043d\u0456:",
@@ -708,9 +708,9 @@
"LabelIconMaxHeight": "\u0411\u0435\u043b\u0433\u0456\u0448\u0435\u043d\u0456\u04a3 \u0435\u04a3 \u0436\u043e\u0493\u0430\u0440\u044b \u0431\u0438\u0456\u0433\u0456:",
"LabelIconMaxHeightHelp": "upnp:icon \u0430\u0440\u049b\u044b\u043b\u044b \u043a\u04e9\u0440\u0441\u0435\u0442\u0435\u0442\u0456\u043d \u0431\u0435\u043b\u0433\u0456\u0448\u0435\u043b\u0435\u0440\u0456\u043d\u0456\u04a3 \u0435\u04a3 \u0436\u043e\u0493\u0430\u0440\u044b \u0430\u0436\u044b\u0440\u0430\u0442\u044b\u043b\u044b\u043c\u0434\u044b\u0493\u044b.",
"LabelIdentificationFieldHelp": "\u0420\u0435\u0433\u0438\u0441\u0442\u0440 \u0435\u0441\u043a\u0435\u0440\u043c\u0435\u0439\u0442\u0456\u043d \u0456\u0448\u043a\u0456 \u0436\u043e\u043b \u043d\u0435\u043c\u0435\u0441\u0435 \u04b1\u0434\u0430\u0439\u044b \u04e9\u0440\u043d\u0435\u043a.",
- "HeaderProfileServerSettingsHelp": "\u0411\u04b1\u043b \u043c\u04d9\u043d\u0434\u0435\u0440 Media Browser \u049b\u0430\u043b\u0430\u0439 \u04e9\u0437\u0456\u043d \u0436\u0430\u0431\u0434\u044b\u049b\u0442\u0430 \u043a\u04e9\u0440\u0441\u0435\u0442\u0435\u0442\u0456\u043d\u0456\u04a3 \u0431\u0430\u0441\u049b\u0430\u0440\u0430\u0434\u044b.",
+ "HeaderProfileServerSettingsHelp": "\u0411\u04b1\u043b \u043c\u04d9\u043d\u0434\u0435\u0440 Media Browser \u049b\u0430\u043b\u0430\u0439 \u04e9\u0437\u0456\u043d \u049b\u04b1\u0440\u044b\u043b\u0493\u044b\u0434\u0430 \u043a\u04e9\u0440\u0441\u0435\u0442\u0435\u0442\u0456\u043d\u0456\u04a3 \u0431\u0430\u0441\u049b\u0430\u0440\u0430\u0434\u044b.",
"LabelMaxBitrate": "\u0415\u04a3 \u0436\u043e\u0493\u0430\u0440\u044b \u049b\u0430\u0440\u049b\u044b\u043d:",
- "LabelMaxBitrateHelp": "\u04e8\u0442\u043a\u0456\u0437\u0443 \u043c\u04af\u043c\u043a\u0456\u043d\u0434\u0456\u0433\u0456 \u0448\u0435\u043a\u0442\u0435\u043b\u0433\u0435\u043d \u043e\u0440\u0442\u0430\u043b\u0430\u0440\u0434\u0430\u0493\u044b \u0435\u04a3 \u0436\u043e\u0493\u0430\u0440\u044b \u049b\u0430\u0440\u049b\u044b\u043d\u044b\u043d, \u043d\u0435\u043c\u0435\u0441\u0435 \u0436\u0430\u0431\u0434\u044b\u049b\u049b\u0430 \u049b\u0430\u0436\u0435\u0442 \u0431\u043e\u043b\u0441\u0430 - \u04e9\u0437 \u0448\u0435\u0433\u0456\u043d \u0430\u043d\u044b\u049b\u0442\u0430\u04a3\u044b\u0437.",
+ "LabelMaxBitrateHelp": "\u04e8\u0442\u043a\u0456\u0437\u0443 \u043c\u04af\u043c\u043a\u0456\u043d\u0434\u0456\u0433\u0456 \u0448\u0435\u043a\u0442\u0435\u043b\u0433\u0435\u043d \u043e\u0440\u0442\u0430\u043b\u0430\u0440\u0434\u0430\u0493\u044b \u0435\u04a3 \u0436\u043e\u0493\u0430\u0440\u044b \u049b\u0430\u0440\u049b\u044b\u043d\u044b\u043d, \u043d\u0435\u043c\u0435\u0441\u0435 \u049b\u04b1\u0440\u044b\u043b\u0493\u044b\u0493\u0430 \u049b\u0430\u0436\u0435\u0442 \u0431\u043e\u043b\u0441\u0430 - \u04e9\u0437 \u0448\u0435\u0433\u0456\u043d \u0430\u043d\u044b\u049b\u0442\u0430\u04a3\u044b\u0437.",
"LabelMaxStreamingBitrate": "\u0415\u04a3 \u0436\u043e\u0493\u0430\u0440\u044b \u0430\u0493\u044b\u043d\u043c\u0435\u043d \u0442\u0430\u0441\u044b\u043c\u0430\u043b\u0434\u0430\u0443 \u049b\u0430\u0440\u049b\u044b\u043d\u044b:",
"LabelMaxStreamingBitrateHelp": "\u0410\u0493\u044b\u043d\u043c\u0435\u043d \u0442\u0430\u0441\u044b\u043c\u0430\u043b\u0434\u0430\u0443 \u043a\u0435\u0437\u0456\u043d\u0434\u0435 \u0435\u04a3 \u0436\u043e\u0493\u0430\u0440\u044b \u049b\u0430\u0440\u049b\u044b\u043d\u0434\u044b \u0430\u043d\u044b\u049b\u0442\u0430\u04a3\u044b\u0437.",
"LabelMaxStaticBitrate": "\u0415\u04a3 \u0436\u043e\u0493\u0430\u0440\u044b \u0441\u0438\u043d\u0445\u0440\u043e\u043d\u0434\u0430\u0443 \u049b\u0430\u0440\u049b\u044b\u043d\u044b:",
@@ -729,11 +729,11 @@
"LabelModelDescription": "\u041c\u043e\u0434\u0435\u043b\u044c \u0441\u0438\u043f\u0430\u0442\u0442\u0430\u043c\u0430\u0441\u044b",
"LabelModelUrl": "\u041c\u043e\u0434\u0435\u043b\u044c url",
"LabelSerialNumber": "\u0421\u0435\u0440\u0438\u044f\u043b\u044b\u049b \u043d\u04e9\u043c\u0456\u0440\u0456",
- "LabelDeviceDescription": "\u0416\u0430\u0431\u0434\u044b\u049b \u0441\u0438\u043f\u0430\u0442\u0442\u0430\u043c\u0430\u0441\u044b",
+ "LabelDeviceDescription": "\u049a\u04b1\u0440\u044b\u043b\u0493\u044b \u0441\u0438\u043f\u0430\u0442\u0442\u0430\u043c\u0430\u0441\u044b",
"HeaderIdentificationCriteriaHelp": "\u0415\u04a3 \u043a\u0435\u043c\u0456\u043d\u0434\u0435 \u0430\u043d\u044b\u049b\u0442\u0430\u0443\u0434\u044b\u04a3 \u0431\u0456\u0440 \u0448\u0430\u0440\u0442\u044b\u043d \u0435\u043d\u0433\u0456\u0437\u0456\u04a3\u0456\u0437.",
- "HeaderDirectPlayProfileHelp": "\u0416\u0430\u0431\u0434\u044b\u049b\u0442\u044b\u04a3 \u049b\u0430\u043d\u0434\u0430\u0439 \u043f\u0456\u0448\u0456\u043c\u0434\u0435\u0440\u0434\u0456 \u04d9\u0434\u0435\u043f\u043a\u0456 \u04e9\u04a3\u0434\u0435\u0442\u0435\u0442\u0456\u043d \u043c\u04af\u043c\u043a\u0456\u043d\u0434\u0456\u0433\u0456\u043d \u043a\u04e9\u0440\u0441\u0435\u0442\u0443 \u04b1\u0448\u0456\u043d \u0442\u0456\u043a\u0435\u043b\u0435\u0439 \u043e\u0439\u043d\u0430\u0442\u0443 \u043f\u0440\u043e\u0444\u0430\u0439\u043b\u0434\u0430\u0440\u044b\u043d \u049b\u043e\u0441\u0443.",
+ "HeaderDirectPlayProfileHelp": "\u049a\u04b1\u0440\u044b\u043b\u0493\u044b\u043d\u044b\u04a3 \u049b\u0430\u043d\u0434\u0430\u0439 \u043f\u0456\u0448\u0456\u043c\u0434\u0435\u0440\u0434\u0456 \u04d9\u0434\u0435\u043f\u043a\u0456 \u04e9\u04a3\u0434\u0435\u0442\u0435\u0442\u0456\u043d \u043c\u04af\u043c\u043a\u0456\u043d\u0434\u0456\u0433\u0456\u043d \u043a\u04e9\u0440\u0441\u0435\u0442\u0443 \u04b1\u0448\u0456\u043d \u0442\u0456\u043a\u0435\u043b\u0435\u0439 \u043e\u0439\u043d\u0430\u0442\u0443 \u043f\u0440\u043e\u0444\u0430\u0439\u043b\u0434\u0430\u0440\u044b\u043d \u049b\u043e\u0441\u0443.",
"HeaderTranscodingProfileHelp": "\u049a\u0430\u0436\u0435\u0442 \u0431\u043e\u043b\u0493\u0430\u043d\u0434\u0430 \u049b\u0430\u043d\u0434\u0430\u0439 \u043f\u0456\u0448\u0456\u043c\u0434\u0435\u0440\u0434\u0456 \u043f\u0430\u0439\u0434\u0430\u043b\u0430\u043d\u0443 \u043c\u0456\u043d\u0434\u0435\u0442\u0456\u043b\u0456\u0433\u0456\u043d \u043a\u04e9\u0440\u0441\u0435\u0442\u0443 \u04b1\u0448\u0456\u043d \u049b\u0430\u0439\u0442\u0430 \u043a\u043e\u0434\u0442\u0430\u0443 \u043f\u0440\u043e\u0444\u0430\u0439\u043b\u0434\u0430\u0440\u044b\u043d \u049b\u043e\u0441\u0443.",
- "HeaderResponseProfileHelp": "\u041a\u0435\u0439\u0431\u0456\u0440 \u0442\u0430\u0441\u0443\u0448\u044b\u0434\u0435\u0440\u0435\u043a\u0442\u0435\u0440 \u0442\u04af\u0440\u043b\u0435\u0440\u0456\u043d \u043e\u0439\u043d\u0430\u0442\u049b\u0430\u043d\u0434\u0430 \u04af\u043d \u049b\u0430\u0442\u0443 \u043f\u0440\u043e\u0444\u0430\u0439\u043b\u0434\u0430\u0440\u044b \u0436\u0430\u0431\u0434\u044b\u049b\u049b\u0430 \u0436\u0456\u0431\u0435\u0440\u0456\u043b\u0435\u0442\u0456\u043d \u0430\u049b\u043f\u0430\u0440\u0430\u0442\u0442\u044b \u0442\u0435\u04a3\u0448\u0435\u0443 \u04af\u0448\u0456\u043d \u0436\u043e\u043b \u0431\u0435\u0440\u0435\u0434\u0456.",
+ "HeaderResponseProfileHelp": "\u041a\u0435\u0439\u0431\u0456\u0440 \u0442\u0430\u0441\u0443\u0448\u044b\u0434\u0435\u0440\u0435\u043a\u0442\u0435\u0440 \u0442\u04af\u0440\u043b\u0435\u0440\u0456\u043d \u043e\u0439\u043d\u0430\u0442\u049b\u0430\u043d\u0434\u0430 \u04af\u043d \u049b\u0430\u0442\u0443 \u043f\u0440\u043e\u0444\u0430\u0439\u043b\u0434\u0430\u0440\u044b \u049b\u04b1\u0440\u044b\u043b\u0493\u044b\u0493\u0430 \u0436\u0456\u0431\u0435\u0440\u0456\u043b\u0435\u0442\u0456\u043d \u0430\u049b\u043f\u0430\u0440\u0430\u0442\u0442\u044b \u0442\u0435\u04a3\u0448\u0435\u0443 \u04af\u0448\u0456\u043d \u0436\u043e\u043b \u0431\u0435\u0440\u0435\u0434\u0456.",
"LabelXDlnaCap": "X-Dlna \u0441\u0438\u043f\u0430\u0442\u0442\u0430\u0440\u044b:",
"LabelXDlnaCapHelp": "urn:schemas-dlna-org:device-1-0 \u0430\u0442\u0430\u0443\u043b\u0430\u0440 \u043a\u0435\u04a3\u0456\u0441\u0442\u0456\u0433\u0456\u043d\u0434\u0435\u0433\u0456 X_DLNACAP \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u0456 \u043c\u0430\u0437\u043c\u04b1\u043d\u044b\u043d \u0430\u043d\u044b\u049b\u0442\u0430\u0439\u0434\u044b.",
"LabelXDlnaDoc": "X-Dlna \u0442\u04d9\u0441\u0456\u043c\u0456:",
@@ -748,7 +748,7 @@
"OptionEnableM2tsModeHelp": "Mpegts \u04af\u0448\u0456\u043d \u043a\u043e\u0434\u0442\u0430\u0443 \u043a\u0435\u0437\u0456\u043d\u0434\u0435 m2ts \u0440\u0435\u0436\u0456\u043c\u0456\u043d \u049b\u043e\u0441\u0443.",
"OptionEstimateContentLength": "\u049a\u0430\u0439\u0442\u0430 \u043a\u043e\u0434\u0442\u0430\u0443 \u043a\u0435\u0437\u0456\u043d\u0434\u0435 \u043c\u0430\u0437\u043c\u04b1\u043d \u04b1\u0437\u044b\u043d\u0434\u044b\u0493\u044b\u043d \u0431\u0430\u0493\u0430\u043b\u0430\u0443",
"OptionReportByteRangeSeekingWhenTranscoding": "\u049a\u0430\u0439\u0442\u0430 \u043a\u043e\u0434\u0442\u0430\u0443 \u043a\u0435\u0437\u0456\u043d\u0434\u0435 \u0441\u0435\u0440\u0432\u0435\u0440 \u0431\u0430\u0439\u0442 \u0456\u0440\u0456\u043a\u0442\u0435\u0443\u0456\u043d \u049b\u043e\u043b\u0434\u0430\u0441\u0430 \u0445\u0430\u0431\u0430\u0440\u043b\u0430\u0443",
- "OptionReportByteRangeSeekingWhenTranscodingHelp": "\u0411\u04b1\u043b \u0443\u0430\u049b\u044b\u0442 \u0456\u0440\u0456\u043a\u0442\u0435\u0443\u0456 \u043e\u043d\u0448\u0430 \u0435\u043c\u0435\u0441 \u043a\u0435\u0439\u0431\u0456\u0440 \u0436\u0430\u0431\u0434\u044b\u049b\u0442\u0430\u0440 \u04af\u0448\u0456\u043d \u049b\u0430\u0436\u0435\u0442.",
+ "OptionReportByteRangeSeekingWhenTranscodingHelp": "\u0411\u04b1\u043b \u0443\u0430\u049b\u044b\u0442 \u0456\u0440\u0456\u043a\u0442\u0435\u0443\u0456 \u043e\u043d\u0448\u0430 \u0435\u043c\u0435\u0441 \u043a\u0435\u0439\u0431\u0456\u0440 \u049b\u04b1\u0440\u044b\u043b\u0493\u044b\u043b\u0430\u0440 \u04af\u0448\u0456\u043d \u049b\u0430\u0436\u0435\u0442.",
"HeaderSubtitleDownloadingHelp": "Media Browser \u0431\u0435\u0439\u043d\u0435\u0444\u0430\u0439\u043b\u0434\u0430\u0440\u0434\u044b \u0441\u043a\u0430\u043d\u0435\u0440\u043b\u0435\u0433\u0435\u043d\u0434\u0435 \u0431\u04b1\u043b \u0436\u043e\u049b \u0441\u0443\u0431\u0442\u0438\u0442\u0440\u043b\u0435\u0440\u0434\u0456 \u0456\u0437\u0434\u0435\u0443 \u0436\u04d9\u043d\u0435 OpenSubtitles.org \u0441\u0438\u044f\u049b\u0442\u044b \u0441\u0443\u0431\u0442\u0438\u0442\u0440\u043b\u0435\u0440 \u0436\u0435\u0442\u043a\u0456\u0437\u0443\u0448\u0456 \u0430\u0440\u049b\u044b\u043b\u044b \u0436\u04af\u043a\u0442\u0435\u043f \u0430\u043b\u0443\u044b \u043c\u04af\u043c\u043a\u0456\u043d.",
"HeaderDownloadSubtitlesFor": "\u0421\u0443\u0431\u0442\u0438\u0442\u0440\u043b\u0435\u0440\u0434\u0456 \u043c\u044b\u043d\u0430\u0493\u0430\u043d \u0436\u04af\u043a\u0442\u0435\u043f \u0430\u043b\u0443:",
"MessageNoChapterProviders": "\u049a\u043e\u0441\u044b\u043c\u0448\u0430 \u0441\u0430\u0445\u043d\u0430 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u043b\u0435\u0440\u0456\u043d \u049b\u043e\u0441\u0443 \u04af\u0448\u0456\u043d ChapterDb \u0441\u0438\u044f\u049b\u0442\u044b \u0441\u0430\u0445\u043d\u0430\u043b\u0430\u0440 \u0436\u0435\u0442\u043a\u0456\u0437\u0443\u0448\u0456 \u043f\u043b\u0430\u0433\u0438\u043d\u0434\u0456 \u043e\u0440\u043d\u0430\u0442\u044b\u04a3\u044b\u0437.",
@@ -794,7 +794,7 @@
"LabelEnableThemeSongsHelp": "\u0415\u0433\u0435\u0440 \u049b\u043e\u0441\u044b\u043b\u0441\u0430, \u0442\u0430\u0441\u0443\u0448\u044b\u0445\u0430\u043d\u0430\u043d\u044b \u0448\u043e\u043b\u044b\u0493\u0430\u043d\u0434\u0430 \u0442\u0430\u049b\u044b\u0440\u044b\u043f\u0442\u044b\u049b \u04d9\u0443\u0435\u043d\u0434\u0435\u0440 \u04e9\u04a3\u0434\u0435 \u043e\u0439\u043d\u0430\u0442\u044b\u043b\u0430\u0434\u044b.",
"LabelEnableBackdropsHelp": "\u0415\u0433\u0435\u0440 \u049b\u043e\u0441\u044b\u043b\u0441\u0430, \u0430\u0440\u0442\u049b\u044b \u0441\u0443\u0440\u0435\u0442\u0442\u0435\u0440 \u0442\u0430\u0441\u0443\u0448\u044b\u0445\u0430\u043d\u0430\u043d\u044b \u0448\u043e\u043b\u044b\u0493\u0430\u043d\u0434\u0430 \u043a\u0435\u0439\u0431\u0456\u0440 \u0431\u0435\u0442\u0442\u0435\u0440\u0434\u0435 \u04e9\u04a3\u0434\u0435 \u0431\u0435\u0439\u043d\u0435\u043b\u0435\u043d\u0435\u0434\u0456.",
"HeaderHomePage": "\u0411\u0430\u0441\u0442\u044b \u0431\u0435\u0442",
- "HeaderSettingsForThisDevice": "\u041e\u0441\u044b \u0436\u0430\u0431\u0434\u044b\u049b\u049b\u0430 \u0430\u0440\u043d\u0430\u043b\u0493\u0430\u043d \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u043b\u0435\u0440",
+ "HeaderSettingsForThisDevice": "\u041e\u0441\u044b \u049b\u04b1\u0440\u044b\u043b\u0493\u044b\u0493\u0430 \u0430\u0440\u043d\u0430\u043b\u0493\u0430\u043d \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u043b\u0435\u0440",
"OptionAuto": "\u0410\u0432\u0442\u043e",
"OptionYes": "\u0418\u04d9",
"OptionNo": "\u0416\u043e\u049b",
@@ -821,13 +821,13 @@
"OptionCommunityMostWatchedSort": "\u0415\u04a3 \u043a\u04e9\u043f \u049b\u0430\u0440\u0430\u043b\u0493\u0430\u043d\u0434\u0430\u0440",
"TabNextUp": "\u041a\u0435\u0437\u0435\u043a\u0442\u0435\u0433\u0456\u043b\u0435\u0440",
"MessageNoMovieSuggestionsAvailable": "\u0415\u0448\u049b\u0430\u043d\u0434\u0430\u0439 \u0444\u0438\u043b\u044c\u043c \u04b1\u0441\u044b\u043d\u044b\u0441\u0442\u0430\u0440\u044b \u0430\u0493\u044b\u043c\u0434\u0430 \u049b\u043e\u043b \u0436\u0435\u0442\u0456\u043c\u0434\u0456 \u0435\u043c\u0435\u0441. \u0424\u0438\u043b\u044c\u043c\u0434\u0435\u0440\u0434\u0456 \u049b\u0430\u0440\u0430\u0443\u0434\u044b \u0436\u04d9\u043d\u0435 \u0431\u0430\u0493\u0430\u043b\u0430\u0443\u0434\u044b \u0431\u0430\u0441\u0442\u0430\u04a3\u044b\u0437, \u0441\u043e\u043d\u0434\u0430 \u0430\u0440\u043d\u0430\u043b\u0493\u0430\u043d \u04b1\u0441\u044b\u043d\u044b\u0442\u0430\u0440\u044b\u04a3\u044b\u0437\u0434\u044b \u043a\u04e9\u0440\u0443 \u04af\u0448\u0456\u043d \u049b\u0430\u0439\u0442\u0430 \u043a\u0435\u043b\u0456\u04a3\u0456\u0437.",
- "MessageNoCollectionsAvailable": "\u0424\u0438\u043b\u044c\u043c\u0434\u0435\u0440\u0434\u0456, \u0441\u0435\u0440\u0438\u0430\u043b\u0434\u0430\u0440\u0434\u044b, \u0430\u043b\u044c\u0431\u043e\u043c\u0434\u0430\u0440\u0434\u044b, \u043a\u0456\u0442\u0430\u043f\u0442\u0430\u0440\u0434\u044b \u0436\u04d9\u043d\u0435 \u043e\u0439\u044b\u043d\u0434\u0430\u0440\u0434\u044b \u0436\u0435\u043a\u0435\u043b\u0435\u043d\u0433\u0435\u043d \u0442\u043e\u043f\u0442\u0430\u0441\u0442\u044b\u0440\u0443 \u04af\u0448\u0456\u043d \u0436\u0438\u044b\u043d\u0442\u044b\u049b\u0442\u0430\u0440 \u043c\u04af\u043c\u043a\u0456\u043d\u0434\u0456\u043a \u0431\u0435\u0440\u0435\u0434\u0456. \u0416\u0438\u044b\u043d\u0442\u044b\u049b\u0442\u0430\u0440\u0434\u044b \u0436\u0430\u0441\u0430\u0439 \u0431\u0430\u0441\u0442\u0430\u0443 \u04af\u0448\u0456\u043d \"\u0416\u0430\u0441\u0430\u0443\" \u0442\u04af\u0439\u043c\u0435\u0448\u0456\u0433\u0456\u043d \u0431\u0430\u0441\u044b\u04a3\u044b\u0437.",
+ "MessageNoCollectionsAvailable": "\u0424\u0438\u043b\u044c\u043c\u0434\u0435\u0440\u0434\u0456, \u0441\u0435\u0440\u0438\u0430\u043b\u0434\u0430\u0440\u0434\u044b, \u0430\u043b\u044c\u0431\u043e\u043c\u0434\u0430\u0440\u0434\u044b, \u043a\u0456\u0442\u0430\u043f\u0442\u0430\u0440\u0434\u044b \u0436\u04d9\u043d\u0435 \u043e\u0439\u044b\u043d\u0434\u0430\u0440\u0434\u044b \u0434\u0430\u0440\u0430\u043b\u0430\u043f \u0442\u043e\u043f\u0442\u0430\u0441\u0442\u044b\u0440\u0443 \u04af\u0448\u0456\u043d \u0436\u0438\u044b\u043d\u0442\u044b\u049b\u0442\u0430\u0440 \u043c\u04af\u043c\u043a\u0456\u043d\u0434\u0456\u043a \u0431\u0435\u0440\u0435\u0434\u0456. \u0416\u0438\u044b\u043d\u0442\u044b\u049b\u0442\u0430\u0440\u0434\u044b \u0436\u0430\u0441\u0430\u0439 \u0431\u0430\u0441\u0442\u0430\u0443 \u04af\u0448\u0456\u043d \"\u0416\u0430\u0441\u0430\u0443\" \u0442\u04af\u0439\u043c\u0435\u0448\u0456\u0433\u0456\u043d \u0431\u0430\u0441\u044b\u04a3\u044b\u0437.",
"MessageNoPlaylistsAvailable": "\u041e\u0439\u043d\u0430\u0442\u0443 \u0442\u0456\u0437\u0456\u043c\u0434\u0435\u0440\u0456 \u0431\u0456\u0440 \u043a\u0435\u0437\u0434\u0435 \u043e\u0439\u043d\u0430\u0442\u0443 \u04af\u0448\u0456\u043d \u043c\u0430\u0437\u043c\u04b1\u043d \u0442\u0456\u0437\u0456\u043c\u0456\u043d \u0436\u0430\u0441\u0430\u0443\u0493\u0430 \u0440\u04b1\u049b\u0441\u0430\u0442 \u0435\u0442\u0435\u0434\u0456. \u041e\u0439\u043d\u0430\u0442\u0443 \u0442\u0456\u0437\u0456\u043c\u0434\u0435\u0440\u0433\u0435 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u0442\u0435\u0440\u0434\u0456 \u04af\u0441\u0442\u0435\u0443 \u04af\u0448\u0456\u043d, \u0442\u0456\u043d\u0442\u0443\u0456\u0440\u0434\u0456\u04a3 \u043e\u04a3 \u0436\u0430\u049b \u0442\u04af\u0439\u043c\u0435\u0448\u0456\u0433\u0456\u043d \u0431\u0430\u0441\u044b\u04a3\u044b\u0437 \u043d\u0435\u043c\u0435\u0441\u0435 \u0442\u04af\u0440\u0442\u0456\u043f \u0436\u04d9\u043d\u0435 \u04b1\u0441\u0442\u0430\u043f \u0442\u04b1\u0440\u044b\u04a3\u044b\u0437, \u0441\u043e\u043d\u0434\u0430 \u041e\u0439\u043d\u0430\u0442\u0443 \u0442\u0456\u0437\u0456\u043c\u0456\u043d\u0435 \u04af\u0441\u0442\u0435\u0443 \u0434\u0435\u0433\u0435\u043d\u0434\u0456 \u0442\u0430\u04a3\u0434\u0430\u04a3\u044b\u0437.",
"MessageNoPlaylistItemsAvailable": "\u041e\u0441\u044b \u043e\u0439\u043d\u0430\u0442\u0443 \u0442\u0456\u0437\u0456\u043c \u0430\u0493\u044b\u043c\u0434\u0430\u0493\u044b \u0443\u0430\u049b\u044b\u0442\u0442\u0430 \u0431\u043e\u0441.",
"HeaderWelcomeToMediaBrowserWebClient": "Media Browser \u0432\u0435\u0431-\u043a\u043b\u0438\u0435\u043d\u0442\u0456\u043d\u0435 \u049b\u043e\u0448 \u043a\u0435\u043b\u0434\u0456\u04a3\u0456\u0437!",
"ButtonDismiss": "\u0416\u0430\u0441\u044b\u0440\u0443",
"ButtonTakeTheTour": "\u0410\u0440\u0430\u043b\u0430\u043f \u0448\u044b\u0493\u044b\u04a3\u044b\u0437",
- "ButtonEditOtherUserPreferences": "\u041e\u0441\u044b \u043f\u0430\u0439\u0434\u0430\u043b\u0430\u043d\u0443\u0448\u044b\u043d\u044b\u04a3 \u043f\u0440\u043e\u0444\u0430\u0439\u043b\u044b\u043d, \u049b\u04b1\u043f\u0438\u044f \u0441\u04e9\u0437\u0456\u043d \u0436\u04d9\u043d\u0435 \u0436\u0435\u043a\u0435 \u0442\u0435\u04a3\u0448\u0435\u043b\u0456\u043c\u0434\u0435\u0440\u0456\u043d \u04e9\u04a3\u0434\u0435\u0443.",
+ "ButtonEditOtherUserPreferences": "\u041e\u0441\u044b \u043f\u0430\u0439\u0434\u0430\u043b\u0430\u043d\u0443\u0448\u044b\u043d\u044b\u04a3 \u043f\u0440\u043e\u0444\u0430\u0439\u043b\u044b\u043d, \u049b\u04b1\u043f\u0438\u044f \u0441\u04e9\u0437\u0456\u043d \u0436\u04d9\u043d\u0435 \u0434\u0430\u0440\u0430 \u0442\u0435\u04a3\u0448\u0435\u043b\u0456\u043c\u0434\u0435\u0440\u0456\u043d \u04e9\u04a3\u0434\u0435\u0443.",
"LabelChannelStreamQuality": "\u0418\u043d\u0442\u0435\u0440\u043d\u0435\u0442 \u0430\u0440\u049b\u044b\u043b\u044b \u0430\u0493\u044b\u043d\u043c\u0435\u043d \u0442\u0430\u0441\u044b\u043c\u0430\u043b\u0434\u0430\u0443 \u0442\u0435\u04a3\u0448\u0435\u043b\u0456\u043c\u0456:",
"LabelChannelStreamQualityHelp": "\u04e8\u0442\u043a\u0456\u0437\u0443 \u043c\u04af\u043c\u043a\u0456\u043d\u0434\u0456\u0433\u0456 \u0442\u04e9\u043c\u0435\u043d \u043e\u0440\u0442\u0430\u0434\u0430, \u0441\u0430\u043f\u0430\u0441\u044b\u043d \u0448\u0435\u043a\u0442\u0435\u0443\u0456 \u0436\u0430\u0442\u044b\u049b\u0442\u0430\u0443 \u0430\u0493\u044b\u043d\u043c\u0435\u043d \u0442\u0430\u0441\u044b\u043c\u0430\u043b\u0434\u0430\u0443 \u04d9\u0441\u0435\u0440\u0456\u043d \u049b\u0430\u043c\u0442\u0430\u043c\u0430\u0441\u044b\u0437 \u0435\u0442\u0443\u0456\u043d\u0435 \u043a\u04e9\u043c\u0435\u043a\u0442\u0435\u0441\u0443\u0456 \u043c\u04af\u043c\u043a\u0456\u043d.",
"OptionBestAvailableStreamQuality": "\u049a\u043e\u043b \u0436\u0435\u0442\u0456\u043c\u0434\u0456 \u0435\u04a3 \u0436\u0430\u049b\u0441\u044b",
@@ -885,7 +885,7 @@
"TitleRemoteControl": "\u049a\u0430\u0448\u044b\u049b\u0442\u0430\u043d \u0431\u0430\u0441\u049b\u0430\u0440\u0443",
"OptionLatestTvRecordings": "\u0415\u04a3 \u043a\u0435\u0439\u0456\u043d\u0433\u0456 \u0436\u0430\u0437\u0431\u0430\u043b\u0430\u0440",
"LabelProtocolInfo": "\u041f\u0440\u043e\u0442\u043e\u049b\u043e\u043b \u0430\u049b\u043f\u0430\u0440\u0430\u0442\u044b:",
- "LabelProtocolInfoHelp": "\u0411\u04b1\u043b \u043c\u04d9\u043d \u0436\u0430\u0431\u0434\u044b\u049b\u0442\u044b\u04a3 GetProtocolInfo \u0441\u04b1\u0440\u0430\u043d\u044b\u0441\u0442\u0430\u0440\u044b\u043d\u0430 \u0436\u0430\u0443\u0430\u043f \u0431\u0435\u0440\u0433\u0435\u043d\u0434\u0435 \u043f\u0430\u0439\u0434\u0430\u043b\u0430\u043d\u044b\u043b\u0430\u0434\u044b.",
+ "LabelProtocolInfoHelp": "\u0411\u04b1\u043b \u043c\u04d9\u043d \u049b\u04b1\u0440\u044b\u043b\u0493\u044b\u043d\u044b\u04a3 GetProtocolInfo \u0441\u04b1\u0440\u0430\u043d\u044b\u0441\u0442\u0430\u0440\u044b\u043d\u0430 \u0436\u0430\u0443\u0430\u043f \u0431\u0435\u0440\u0433\u0435\u043d\u0434\u0435 \u043f\u0430\u0439\u0434\u0430\u043b\u0430\u043d\u044b\u043b\u0430\u0434\u044b.",
"TabKodiMetadata": "Kodi",
"HeaderKodiMetadataHelp": "Media Browser \u0431\u0430\u0493\u0434\u0430\u0440\u043b\u0430\u043c\u0430\u0441\u044b Xbmc NFO \u043c\u0435\u0442\u0430\u0434\u0435\u0440\u0435\u043a\u0442\u0442\u0435\u0440\u0456\u043d\u0456\u04a3 \u0436\u04d9\u043d\u0435 \u0441\u0443\u0440\u0435\u0442\u0442\u0435\u0440\u0456\u043d\u0456\u04a3 \u043a\u0456\u0440\u0456\u043a\u0442\u0456\u0440\u043c\u0435 \u049b\u043e\u043b\u0434\u0430\u0443\u044b\u043d \u049b\u0430\u043c\u0442\u0438\u0434\u044b. Xbmc \u043c\u0435\u0442\u0430\u0434\u0435\u0440\u0435\u043a\u0442\u0435\u0440\u0456\u043d \u049b\u043e\u0441\u0443 \u043d\u0435\u043c\u0435\u0441\u0435 \u04e9\u0448\u0456\u0440\u0443 \u04af\u0448\u0456\u043d \u049a\u044b\u0437\u043c\u0435\u0442\u0442\u0435\u0440 \u049b\u043e\u0439\u044b\u043d\u0434\u044b\u0441\u044b\u043d\u0434\u0430\u0493\u044b \u0442\u0430\u0441\u0443\u0448\u044b \u0442\u04af\u0440\u043b\u0435\u0440\u0456\u043d\u0435 \u0430\u0440\u043d\u0430\u043b\u0493\u0430\u043d \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u043b\u0435\u0440\u0434\u0456 \u043f\u0430\u0439\u0434\u0430\u043b\u0430\u043d\u044b\u04a3\u044b\u0437.",
"LabelKodiMetadataUser": "\u041f\u0430\u0439\u0434\u0430\u043b\u0430\u043d\u0443\u0448\u044b\u043d\u044b\u04a3 \u049b\u0430\u0440\u0430\u0443 \u043a\u04af\u0439\u0456\u043d NFO-\u0444\u0430\u0439\u043b\u0434\u0430\u0440\u044b\u043c\u0435\u043d \u043c\u044b\u043d\u0430\u0443 \u04af\u0448\u0456\u043d \u0441\u0438\u043d\u0445\u0440\u043e\u043d\u0434\u0430\u0443:",
@@ -925,7 +925,7 @@
"HeaderApiKeysHelp": "\u0421\u044b\u0440\u0442\u049b\u044b \u049b\u043e\u043b\u0434\u0430\u043d\u0431\u0430\u043b\u0430\u0440 Media Browser \u0431\u0430\u0493\u0434\u0430\u0440\u043b\u0430\u043c\u0430\u0441\u044b\u043c\u0435\u043d \u049b\u0430\u0442\u044b\u043d\u0430\u0441\u0443 \u04af\u0448\u0456\u043d API \u043a\u0456\u043b\u0442\u0456 \u049b\u0430\u0436\u0435\u0442 \u0435\u0442\u0435\u0434\u0456. \u041a\u0456\u043b\u0442\u0442\u0435\u0440 Media Browser \u0442\u0456\u0440\u043a\u0435\u043b\u0433\u0456\u0441\u0456\u043d\u0435 \u043a\u0456\u0440\u0433\u0435\u043d\u0434\u0435, \u043d\u0435\u043c\u0435\u0441\u0435 \u043a\u0456\u043b\u0442\u0442\u0456 \u049b\u043e\u043b\u0434\u0430\u043d\u0431\u0430\u0493\u0430 \u049b\u043e\u043b\u043c\u0435\u043d \u0440\u04b1\u049b\u0441\u0430\u0442 \u0435\u0442\u0456\u043b\u0433\u0435\u043d\u0434\u0435 \u0431\u0435\u0440\u0456\u043b\u0435\u0434\u0456.",
"HeaderApiKey": "API \u043a\u0456\u043b\u0442\u0456",
"HeaderApp": "\u049a\u043e\u043b\u0434\u0430\u043d\u0431\u0430",
- "HeaderDevice": "\u0416\u0430\u0431\u0434\u044b\u049b",
+ "HeaderDevice": "\u049a\u04b1\u0440\u044b\u043b\u0493\u044b",
"HeaderUser": "\u041f\u0430\u0439\u0434\u0430\u043b\u0430\u043d\u0443\u0448\u044b",
"HeaderDateIssued": "\u0411\u0435\u0440\u0456\u043b\u0433\u0435\u043d \u043a\u04af\u043d\u0456",
"LabelChapterName": "{0}-\u0441\u0430\u0445\u043d\u0430",
@@ -1164,10 +1164,10 @@
"LabelConnectUserNameHelp": "\u0421\u0435\u0440\u0432\u0435\u0440\u0434\u0456\u04a3 IP \u043c\u0435\u043a\u0435\u043d\u0436\u0430\u0439\u044b\u043d \u0431\u0456\u043b\u043c\u0435\u0439 \u0442\u04b1\u0440\u044b\u043f \u04d9\u0440\u049b\u0430\u0439\u0441\u044b Media Browser \u049b\u043e\u043b\u0434\u0430\u043d\u0431\u0430\u0441\u044b\u043d\u0430\u043d \u043a\u0456\u0440\u0443-\u049b\u0430\u0442\u044b\u043d\u0430\u0441\u0442\u044b \u0436\u0435\u04a3\u0456\u043b\u0434\u0435\u0442\u0443\u0456\u043d \u049b\u043e\u0441\u0443 \u04af\u0448\u0456\u043d \u043e\u0441\u044b \u043f\u0430\u0439\u0434\u0430\u043b\u0430\u043d\u0443\u0448\u044b\u043d\u044b Media Browser \u0442\u0456\u0440\u043a\u0435\u043b\u0433\u0456\u0441\u0456\u043d\u0435 \u0431\u0430\u0439\u043b\u0430\u043d\u044b\u0441\u0442\u044b\u0440\u044b\u04a3\u044b\u0437.",
"ButtonLearnMoreAboutMediaBrowserConnect": "Media Browser Connect \u0442\u0443\u0440\u0430\u043b\u044b \u043a\u04e9\u0431\u0456\u0440\u0435\u043a \u0431\u0456\u043b\u0443",
"LabelExternalPlayers": "\u0421\u044b\u0440\u0442\u049b\u044b \u043e\u0439\u043d\u0430\u0442\u049b\u044b\u0448\u0442\u0430\u0440:",
- "LabelExternalPlayersHelp": "\u0421\u044b\u0440\u0442\u049b\u044b \u043e\u0439\u043d\u0430\u0442\u049b\u044b\u0448\u0442\u0430\u0440\u0434\u0430 \u043c\u0430\u0437\u043c\u04b1\u043d\u0434\u044b \u043e\u0439\u043d\u0430\u0442\u0443 \u04af\u0448\u0456\u043d \u0442\u04af\u0439\u043c\u0435\u0448\u0456\u043a\u0442\u0435\u0440\u0434\u0456 \u0431\u0435\u0439\u043d\u0435\u043b\u0435\u0443. \u0411\u04b1\u043b \u0442\u0435\u043a \u049b\u0430\u043d\u0430 URL \u0441\u0445\u0435\u043c\u0430\u043b\u0430\u0440\u044b\u043d \u049b\u043e\u043b\u0434\u0430\u0439\u0442\u044b\u043d, \u04d9\u0434\u0435\u0442\u0442\u0435, Android \u0436\u04d9\u043d\u0435 iOS, \u0436\u0430\u0431\u0434\u044b\u049b\u0442\u0430\u0440\u0434\u0430 \u049b\u043e\u043b \u0436\u0435\u0442\u0456\u043c\u0434\u0456. \u0421\u044b\u0440\u0442\u049b\u044b \u043e\u0439\u043d\u0430\u0442\u049b\u044b\u0448\u0442\u0430\u0440, \u049b\u0430\u0493\u0438\u0434\u0430 \u0431\u043e\u0439\u044b\u043d\u0448\u0430, \u0430\u043b\u044b\u0441\u0442\u0430\u043d \u0431\u0430\u0441\u049b\u0430\u0440\u0443\u0434\u044b \u0436\u04d9\u043d\u0435 \u0436\u0430\u043b\u0493\u0430\u0441\u0442\u044b\u0440\u0443\u0434\u044b \u049b\u043e\u043b\u0434\u0430\u043c\u0430\u0439\u0434\u044b.",
+ "LabelExternalPlayersHelp": "\u0421\u044b\u0440\u0442\u049b\u044b \u043e\u0439\u043d\u0430\u0442\u049b\u044b\u0448\u0442\u0430\u0440\u0434\u0430 \u043c\u0430\u0437\u043c\u04b1\u043d\u0434\u044b \u043e\u0439\u043d\u0430\u0442\u0443 \u04af\u0448\u0456\u043d \u0442\u04af\u0439\u043c\u0435\u0448\u0456\u043a\u0442\u0435\u0440\u0434\u0456 \u0431\u0435\u0439\u043d\u0435\u043b\u0435\u0443. \u0411\u04b1\u043b \u0442\u0435\u043a \u049b\u0430\u043d\u0430 URL \u0441\u0445\u0435\u043c\u0430\u043b\u0430\u0440\u044b\u043d \u049b\u043e\u043b\u0434\u0430\u0439\u0442\u044b\u043d, \u04d9\u0434\u0435\u0442\u0442\u0435, Android \u0436\u04d9\u043d\u0435 iOS, \u049b\u04b1\u0440\u044b\u043b\u0493\u044b\u043b\u0430\u0440\u0434\u0430 \u049b\u043e\u043b \u0436\u0435\u0442\u0456\u043c\u0434\u0456. \u0421\u044b\u0440\u0442\u049b\u044b \u043e\u0439\u043d\u0430\u0442\u049b\u044b\u0448\u0442\u0430\u0440, \u049b\u0430\u0493\u0438\u0434\u0430 \u0431\u043e\u0439\u044b\u043d\u0448\u0430, \u0430\u043b\u044b\u0441\u0442\u0430\u043d \u0431\u0430\u0441\u049b\u0430\u0440\u0443\u0434\u044b \u0436\u04d9\u043d\u0435 \u0436\u0430\u043b\u0493\u0430\u0441\u0442\u044b\u0440\u0443\u0434\u044b \u049b\u043e\u043b\u0434\u0430\u043c\u0430\u0439\u0434\u044b.",
"HeaderSubtitleProfile": "\u0421\u0443\u0431\u0442\u0438\u0442\u0440\u043b\u0435\u0440 \u043f\u0440\u043e\u0444\u0430\u0439\u043b\u044b",
"HeaderSubtitleProfiles": "\u0421\u0443\u0431\u0442\u0438\u0442\u0440\u043b\u0435\u0440 \u043f\u0440\u043e\u0444\u0430\u0439\u043b\u0434\u0430\u0440\u044b",
- "HeaderSubtitleProfilesHelp": "\u0421\u0443\u0431\u0442\u0438\u0442\u0440\u043b\u0435\u0440 \u043f\u0440\u043e\u0444\u0430\u0439\u043b\u044b \u043e\u0441\u044b \u0436\u0430\u0431\u0434\u044b\u049b \u049b\u043e\u043b\u0434\u0430\u0439\u0442\u044b\u043d \u0441\u0443\u0431\u0442\u0438\u0442\u0440\u043b\u0435\u0440 \u043f\u0456\u0448\u0456\u043c\u0434\u0435\u0440\u0456\u043d \u0441\u0438\u043f\u0430\u0442\u0442\u0430\u0439\u0434\u044b.",
+ "HeaderSubtitleProfilesHelp": "\u0421\u0443\u0431\u0442\u0438\u0442\u0440\u043b\u0435\u0440 \u043f\u0440\u043e\u0444\u0430\u0439\u043b\u044b \u043e\u0441\u044b \u049b\u04b1\u0440\u044b\u043b\u0493\u044b\u0434\u0430 \u049b\u043e\u043b\u0434\u0430\u0443\u044b \u0431\u0430\u0440 \u0441\u0443\u0431\u0442\u0438\u0442\u0440\u043b\u0435\u0440 \u043f\u0456\u0448\u0456\u043c\u0434\u0435\u0440\u0456\u043d \u0441\u0438\u043f\u0430\u0442\u0442\u0430\u0439\u0434\u044b.",
"LabelFormat": "\u041f\u0456\u0448\u0456\u043c:",
"LabelMethod": "\u04d8\u0434\u0456\u0441:",
"LabelDidlMode": "DIDL \u0440\u0435\u0436\u0456\u043c\u0456:",
@@ -1210,17 +1210,17 @@
"OptionDateAddedFileTime": "\u0424\u0430\u0439\u043b\u0434\u044b\u04a3 \u0436\u0430\u0441\u0430\u043b\u0493\u0430\u043d \u043a\u04af\u043d\u0456\u043d \u043f\u0430\u0439\u0434\u0430\u043b\u0430\u043d\u0443",
"LabelDateAddedBehaviorHelp": "\u0415\u0433\u0435\u0440 \u043c\u0435\u0442\u0430\u0434\u0435\u0440\u0435\u043a\u0442\u0435\u0440\u0434\u0435 \u043c\u04d9\u043d\u0456 \u0431\u043e\u043b\u0441\u0430, \u0431\u04b1\u043b \u049b\u0430\u0439\u0441\u044b\u0431\u0456\u0440 \u043e\u0441\u044b \u043d\u04b1\u0441\u049b\u0430\u043b\u0430\u0440\u0434\u044b\u04a3 \u0430\u043b\u0434\u044b\u043d\u0434\u0430 \u04d9\u0440\u049b\u0430\u0448\u0430\u043d\u0434\u0430 \u043f\u0430\u0439\u0434\u0430\u043b\u0430\u043d\u044b\u043b\u0430\u0434\u044b.",
"LabelNumberTrailerToPlay": "\u0422\u0440\u0435\u0439\u043b\u0435\u0440\u0434\u0456\u04a3 \u043e\u0439\u043d\u0430\u0442\u044b\u043b\u0443 \u04af\u0448\u0456\u043d \u0441\u0430\u043d\u044b:",
- "TitleDevices": "\u0416\u0430\u0431\u0434\u044b\u049b\u0442\u0430\u0440",
+ "TitleDevices": "\u049a\u04b1\u0440\u044b\u043b\u0493\u044b\u043b\u0430\u0440",
"TabCameraUpload": "\u041a\u0430\u043c\u0435\u0440\u0430\u0434\u0430\u043d \u043a\u0435\u0440\u0456 \u049b\u043e\u0442\u0430\u0440\u0443",
- "TabDevices": "\u0416\u0430\u0431\u0434\u044b\u049b\u0442\u0430\u0440",
- "HeaderCameraUploadHelp": "\u04b0\u0442\u049b\u044b\u0440 \u0436\u0430\u0431\u0434\u044b\u049b\u0442\u0430\u0440\u044b\u04a3\u044b\u0437\u0431\u0435\u043d \u0442\u04af\u0441\u0456\u0440\u0456\u043b\u0433\u0435\u043d \u0444\u043e\u0442\u043e\u0441\u0443\u0440\u0435\u0442\u0442\u0435\u0440 \u043c\u0435\u043d \u0431\u0435\u0439\u043d\u0435\u0444\u0430\u0439\u043b\u0434\u0430\u0440\u0434\u044b Media Browser \u0456\u0448\u0456\u043d\u0435 \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0442\u044b \u0442\u04af\u0440\u0434\u0435 \u049b\u043e\u0442\u0430\u0440\u044b\u043f \u0431\u0435\u0440\u0443.",
- "MessageNoDevicesSupportCameraUpload": "\u0410\u0493\u044b\u043c\u0434\u0430 \u043a\u0430\u043c\u0435\u0440\u0430\u0434\u0430\u043d \u049b\u043e\u0442\u0430\u0440\u044b\u043f \u0431\u0435\u0440\u0435\u0442\u0456\u043d \u0435\u0448\u049b\u0430\u043d\u0434\u0430\u0439 \u0436\u0430\u0431\u0434\u044b\u049b\u0442\u0430\u0440\u044b\u04a3\u044b\u0437 \u0436\u043e\u049b.",
+ "TabDevices": "\u049a\u04b1\u0440\u044b\u043b\u0493\u044b\u043b\u0430\u0440",
+ "HeaderCameraUploadHelp": "\u04b0\u0442\u049b\u044b\u0440 \u049b\u04b1\u0440\u044b\u043b\u0493\u044b\u043b\u0430\u0440\u044b\u04a3\u044b\u0437\u0431\u0435\u043d \u0442\u04af\u0441\u0456\u0440\u0456\u043b\u0433\u0435\u043d \u0444\u043e\u0442\u043e\u0441\u0443\u0440\u0435\u0442\u0442\u0435\u0440 \u043c\u0435\u043d \u0431\u0435\u0439\u043d\u0435\u0444\u0430\u0439\u043b\u0434\u0430\u0440\u0434\u044b Media Browser \u0456\u0448\u0456\u043d\u0435 \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0442\u044b \u0442\u04af\u0440\u0434\u0435 \u049b\u043e\u0442\u0430\u0440\u044b\u043f \u0431\u0435\u0440\u0443.",
+ "MessageNoDevicesSupportCameraUpload": "\u0410\u0493\u044b\u043c\u0434\u0430 \u043a\u0430\u043c\u0435\u0440\u0430\u0434\u0430\u043d \u049b\u043e\u0442\u0430\u0440\u044b\u043f \u0431\u0435\u0440\u0435\u0442\u0456\u043d \u0435\u0448\u049b\u0430\u043d\u0434\u0430\u0439 \u049b\u04b1\u0440\u044b\u043b\u0493\u044b\u043b\u0430\u0440\u044b\u04a3\u044b\u0437 \u0436\u043e\u049b.",
"LabelCameraUploadPath": "\u041a\u0430\u043c\u0435\u0440\u0430\u0434\u0430\u043d \u043a\u0435\u0440\u0456 \u049b\u043e\u0442\u0430\u0440\u0443 \u0436\u043e\u043b\u044b:",
"LabelCameraUploadPathHelp": "\u049a\u0430\u043b\u0430\u0443\u044b\u04a3\u044b\u0437 \u0431\u043e\u0439\u044b\u043d\u0448\u0430 \u0442\u0435\u04a3\u0448\u0435\u043b\u0433\u0435\u043d \u0436\u043e\u043b\u0434\u044b \u0442\u0430\u04a3\u0434\u0430\u04a3\u044b\u0437. \u0415\u0433\u0435\u0440 \u0430\u043d\u044b\u049b\u0442\u0430\u043b\u043c\u0430\u0441\u0430, \u04d9\u0434\u0435\u043f\u043a\u0456 \u049b\u0430\u043b\u0442\u0430 \u043f\u0430\u0439\u0434\u0430\u043b\u0430\u043d\u044b\u043b\u0430\u0434\u044b. \u0415\u0433\u0435\u0440 \u0442\u0435\u04a3\u0448\u0435\u043b\u0435\u0442\u0456\u043d \u0436\u043e\u043b \u043f\u0430\u0439\u0434\u0430\u043b\u0430\u043d\u044b\u043b\u0441\u0430, \u0431\u04b1\u043d\u044b \u0441\u043e\u043d\u0434\u0430\u0439-\u0430\u049b \u0422\u0430\u0441\u0443\u0448\u044b\u0445\u0430\u043d\u0430\u043d\u044b \u043e\u0440\u043d\u0430\u0442\u0443 \u0436\u04d9\u043d\u0435 \u0442\u0435\u04a3\u0448\u0435\u0443 \u0430\u0439\u043c\u0430\u0493\u044b\u043d\u0430 \u04af\u0441\u0442\u0435\u0443 \u049b\u0430\u0436\u0435\u0442.",
- "LabelCreateCameraUploadSubfolder": "\u04d8\u0440\u049b\u0430\u0439\u0441\u044b \u0436\u0430\u0431\u0434\u044b\u049b \u04af\u0448\u0456\u043d \u0456\u0448\u043a\u0456 \u049b\u0430\u043b\u0442\u0430 \u0436\u0430\u0441\u0430\u0443",
- "LabelCreateCameraUploadSubfolderHelp": "\u0416\u0430\u0431\u0434\u044b\u049b\u0442\u0430\u0440 \u0431\u0435\u0442\u0456\u043d\u0434\u0435 \u043d\u04b1\u049b\u044b\u0493\u0430\u043d\u0434\u0430 \u0436\u0430\u0431\u0434\u044b\u049b\u049b\u0430 \u043d\u0430\u049b\u0442\u044b \u049b\u0430\u043b\u0442\u0430\u043b\u0430\u0440 \u0442\u0430\u0493\u0430\u0439\u044b\u043d\u0434\u0430\u043b\u0443\u044b \u043c\u04af\u043c\u043a\u0456\u043d.",
+ "LabelCreateCameraUploadSubfolder": "\u04d8\u0440\u049b\u0430\u0439\u0441\u044b \u049b\u04b1\u0440\u044b\u043b\u0493\u044b \u04af\u0448\u0456\u043d \u0456\u0448\u043a\u0456 \u049b\u0430\u043b\u0442\u0430 \u0436\u0430\u0441\u0430\u0443",
+ "LabelCreateCameraUploadSubfolderHelp": "\u0416\u0430\u0431\u0434\u044b\u049b\u0442\u0430\u0440 \u0431\u0435\u0442\u0456\u043d\u0434\u0435 \u043d\u04b1\u049b\u044b\u0493\u0430\u043d\u0434\u0430 \u049b\u04b1\u0440\u044b\u043b\u0493\u044b\u0493\u0430 \u043d\u0430\u049b\u0442\u044b \u049b\u0430\u043b\u0442\u0430\u043b\u0430\u0440 \u0442\u0430\u0493\u0430\u0439\u044b\u043d\u0434\u0430\u043b\u0443\u044b \u043c\u04af\u043c\u043a\u0456\u043d.",
"LabelCustomDeviceDisplayName": "\u0411\u0435\u0439\u043d\u0435\u043b\u0435\u043d\u0443 \u0430\u0442\u044b:",
- "LabelCustomDeviceDisplayNameHelp": "\u0411\u0435\u0439\u043d\u0435\u043b\u0435\u043d\u0435\u0442\u0456\u043d \u0442\u0435\u04a3\u0448\u0435\u043b\u0433\u0435\u043d \u0430\u0442\u044b\u043d \u04b1\u0441\u044b\u043d\u044b\u04a3\u044b\u0437 \u043d\u0435\u043c\u0435\u0441\u0435 \u0436\u0430\u0431\u0434\u044b\u049b \u0430\u0440\u049b\u044b\u043b\u044b \u0431\u0430\u044f\u043d\u0434\u0430\u043b\u0493\u0430\u043d \u0430\u0442\u044b\u043d \u043f\u0430\u0439\u0434\u0430\u043b\u0430\u043d\u0443 \u04af\u0448\u0456\u043d \u0431\u043e\u0441 \u049b\u0430\u043b\u0434\u044b\u0440\u044b\u04a3\u044b\u0437.",
+ "LabelCustomDeviceDisplayNameHelp": "\u0411\u0435\u0439\u043d\u0435\u043b\u0435\u043d\u0435\u0442\u0456\u043d \u0442\u0435\u04a3\u0448\u0435\u043b\u0433\u0435\u043d \u0430\u0442\u044b\u043d \u04b1\u0441\u044b\u043d\u044b\u04a3\u044b\u0437 \u043d\u0435\u043c\u0435\u0441\u0435 \u049b\u04b1\u0440\u044b\u043b\u0493\u044b \u0430\u0440\u049b\u044b\u043b\u044b \u0431\u0430\u044f\u043d\u0434\u0430\u043b\u0493\u0430\u043d \u0430\u0442\u044b\u043d \u043f\u0430\u0439\u0434\u0430\u043b\u0430\u043d\u0443 \u04af\u0448\u0456\u043d \u0431\u043e\u0441 \u049b\u0430\u043b\u0434\u044b\u0440\u044b\u04a3\u044b\u0437.",
"HeaderInviteUser": "\u041f\u0430\u0439\u0434\u0430\u043b\u0430\u043d\u0443\u0448\u044b\u043d\u044b \u0448\u0430\u049b\u044b\u0440\u0443",
"LabelConnectGuestUserNameHelp": "\u0411\u04b1\u043b \u0434\u043e\u0441\u044b\u04a3\u044b\u0437 Media Browser \u0493\u0430\u043b\u0430\u043c\u0442\u043e\u0440 \u0441\u0430\u0439\u0442\u044b\u043d\u0430 \u043a\u0456\u0440\u0433\u0435\u043d\u0434\u0435 \u049b\u043e\u043b\u0434\u0430\u043d\u0430\u0442\u044b\u043d \u043f\u0430\u0439\u0434\u0430\u043b\u0430\u043d\u0443\u0448\u044b \u0430\u0442\u044b, \u043d\u0435\u043c\u0435\u0441\u0435 \u044d-\u043f\u043e\u0448\u0442\u0430 \u043c\u0435\u043a\u0435\u043d\u0436\u0430\u0439\u044b.",
"HeaderInviteUserHelp": "Media Browser Connect \u0430\u0440\u049b\u044b\u043b\u044b \u0442\u0430\u0441\u0443\u0448\u044b\u0434\u0435\u0440\u0435\u043a\u0442\u0435\u0440\u0434\u0456 \u0434\u043e\u0441\u0442\u0430\u0440\u044b\u04a3\u044b\u0437\u0431\u0435\u043d \u043e\u0440\u0442\u0430\u049b\u0442\u0430\u0441\u0443 \u0431\u04b1\u0440\u044b\u043d\u043d\u0430\u043d \u0434\u0430 \u0436\u0435\u04a3\u0456\u043b\u0434\u0435\u0443 \u0431\u043e\u043b\u0434\u044b.",
@@ -1256,7 +1256,7 @@
"MessageNoServersAvailableToConnect": "\u049a\u043e\u0441\u044b\u043b\u0443 \u04af\u0448\u0456\u043d \u0435\u0448\u049b\u0430\u043d\u0434\u0430\u0439 \u0441\u0435\u0440\u0432\u0435\u0440\u043b\u0435\u0440 \u049b\u043e\u043b \u0436\u0435\u0442\u0456\u043c\u0434\u0456 \u0435\u043c\u0435\u0441. \u0415\u0433\u0435\u0440 \u0441\u0435\u0440\u0432\u0435\u0440\u043c\u0435\u043d \u043e\u0440\u0442\u0430\u049b\u0442\u0430\u0441\u0443\u0493\u0430 \u0448\u0430\u049b\u044b\u0440\u044b\u043b\u0441\u0430\u04a3\u044b\u0437, \u049b\u0430\u0431\u044b\u043b\u0434\u0430\u0443\u044b\u043d \u0442\u04e9\u043c\u0435\u043d\u0434\u0435 \u043d\u0435\u043c\u0435\u0441\u0435 \u044d-\u043f\u043e\u0448\u0442\u0430\u0434\u0430\u0493\u044b \u0441\u0456\u043b\u0442\u0435\u043c\u0435\u043d\u0456 \u043d\u04b1\u049b\u044b\u043f \u043d\u0430\u049b\u0442\u044b\u043b\u0430\u04a3\u044b\u0437.",
"TitleNewUser": "\u0416\u0430\u04a3\u0430 \u043f\u0430\u0439\u0434\u0430\u043b\u0430\u043d\u0443\u0448\u044b",
"ButtonConfigurePassword": "\u049a\u04b1\u043f\u0438\u044f \u0441\u04e9\u0437\u0434\u0456 \u0442\u0435\u04a3\u0448\u0435\u0443",
- "HeaderDashboardUserPassword": "\u041f\u0430\u0439\u0434\u0430\u043b\u0430\u043d\u0443\u0448\u044b\u043b\u044b\u049b \u049b\u04b1\u043f\u0438\u044f \u0441\u04e9\u0437\u0434\u0435\u0440 \u04d9\u0440 \u043f\u0430\u0439\u0434\u0430\u043b\u0430\u043d\u0443\u0448\u044b \u0436\u0435\u043a\u0435 \u043f\u0440\u043e\u0444\u0430\u0439\u043b \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u043b\u0435\u0440\u0456 \u0430\u0440\u049b\u044b\u043b\u044b \u0431\u0430\u0441\u049b\u0430\u0440\u044b\u043b\u0430\u0434\u044b.",
+ "HeaderDashboardUserPassword": "\u041f\u0430\u0439\u0434\u0430\u043b\u0430\u043d\u0443\u0448\u044b\u043b\u044b\u049b \u049b\u04b1\u043f\u0438\u044f \u0441\u04e9\u0437\u0434\u0435\u0440 \u04d9\u0440 \u043f\u0430\u0439\u0434\u0430\u043b\u0430\u043d\u0443\u0448\u044b \u0434\u0430\u0440\u0430 \u043f\u0440\u043e\u0444\u0430\u0439\u043b \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u043b\u0435\u0440\u0456 \u0430\u0440\u049b\u044b\u043b\u044b \u0431\u0430\u0441\u049b\u0430\u0440\u044b\u043b\u0430\u0434\u044b.",
"HeaderLibraryAccess": "\u0422\u0430\u0441\u0443\u0448\u044b\u0445\u0430\u043d\u0430\u0493\u0430 \u049b\u0430\u0442\u044b\u043d\u0430\u0441\u0443",
"HeaderChannelAccess": "\u0410\u0440\u043d\u0430\u0493\u0430 \u049b\u0430\u0442\u044b\u043d\u0430\u0441\u0443",
"HeaderLatestItems": "\u0415\u04a3 \u043a\u0435\u0439\u0456\u043d\u0433\u0456 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u0442\u0435\u0440",
@@ -1273,7 +1273,11 @@
"HeaderParentalRatings": "\u0416\u0430\u0441\u0442\u0430\u0441 \u0441\u0430\u043d\u0430\u0442\u0442\u0430\u0440",
"HeaderVideoTypes": "\u0411\u0435\u0439\u043d\u0435 \u0442\u04af\u0440\u043b\u0435\u0440\u0456",
"HeaderYears": "\u0416\u044b\u043b\u0434\u0430\u0440",
- "HeaderAddTag": "Add Tag",
- "LabelBlockItemsWithTags": "Block items with tags:",
- "LabelTag": "Tag:"
+ "HeaderAddTag": "\u0422\u0435\u0433\u0442\u0456 \u049b\u043e\u0441\u0443",
+ "LabelBlockItemsWithTags": "\u041c\u044b\u043d\u0430\u0434\u0430\u0439 \u0442\u0435\u0433\u0442\u0435\u0440\u0456 \u0431\u0430\u0440 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u0442\u0435\u0440\u0434\u0456 \u049b\u04b1\u0440\u0441\u0430\u0443\u043b\u0430\u0443:",
+ "LabelTag": "\u0422\u0435\u0433:",
+ "LabelEnableSingleImageInDidlLimit": "\u0416\u0430\u043b\u0493\u044b\u0437 \u043a\u0456\u0440\u0456\u0441\u0442\u0456\u0440\u0456\u043b\u0433\u0435\u043d \u0441\u0443\u0440\u0435\u0442\u043a\u0435 \u0448\u0435\u043a\u0442\u0435\u0443",
+ "LabelEnableSingleImageInDidlLimitHelp": "\u0415\u0433\u0435\u0440 \u0431\u0456\u0440\u043d\u0435\u0448\u0435 \u0441\u0443\u0440\u0435\u0442 Didl \u0456\u0448\u0456\u043d\u0435 \u043a\u0456\u0440\u0456\u0441\u0442\u0456\u0440\u0456\u043b\u0441\u0435, \u043a\u0435\u0439\u0431\u0456\u0440 \u049b\u04b1\u0440\u044b\u043b\u0493\u044b\u043b\u0430\u0440\u0434\u0430 \u0442\u0438\u0456\u0441\u0442\u0456 \u0442\u04af\u0440\u0434\u0435 \u0431\u0435\u0439\u043d\u0435\u043b\u0435\u043d\u0431\u0435\u0439\u0434\u0456.",
+ "TabActivity": "Activity",
+ "TitleSync": "Sync"
} \ No newline at end of file
diff --git a/MediaBrowser.Server.Implementations/Localization/Server/ko.json b/MediaBrowser.Server.Implementations/Localization/Server/ko.json
index f88135298a..a4b1ad5bac 100644
--- a/MediaBrowser.Server.Implementations/Localization/Server/ko.json
+++ b/MediaBrowser.Server.Implementations/Localization/Server/ko.json
@@ -539,7 +539,7 @@
"HeaderRunningTasks": "Running Tasks",
"HeaderActiveDevices": "Active Devices",
"HeaderPendingInstallations": "Pending Installations",
- "HeaerServerInformation": "Server Information",
+ "HeaderServerInformation": "Server Information",
"ButtonRestartNow": "Restart Now",
"ButtonRestart": "Restart",
"ButtonShutdown": "Shutdown",
@@ -1275,5 +1275,9 @@
"HeaderYears": "Years",
"HeaderAddTag": "Add Tag",
"LabelBlockItemsWithTags": "Block items with tags:",
- "LabelTag": "Tag:"
+ "LabelTag": "Tag:",
+ "LabelEnableSingleImageInDidlLimit": "Limit to single embedded image",
+ "LabelEnableSingleImageInDidlLimitHelp": "Some devices will not render properly if multiple images are embedded within Didl.",
+ "TabActivity": "Activity",
+ "TitleSync": "Sync"
} \ No newline at end of file
diff --git a/MediaBrowser.Server.Implementations/Localization/Server/ms.json b/MediaBrowser.Server.Implementations/Localization/Server/ms.json
index d0bade196e..dddcb2ef19 100644
--- a/MediaBrowser.Server.Implementations/Localization/Server/ms.json
+++ b/MediaBrowser.Server.Implementations/Localization/Server/ms.json
@@ -539,7 +539,7 @@
"HeaderRunningTasks": "Running Tasks",
"HeaderActiveDevices": "Active Devices",
"HeaderPendingInstallations": "Pending Installations",
- "HeaerServerInformation": "Server Information",
+ "HeaderServerInformation": "Server Information",
"ButtonRestartNow": "Restart Now",
"ButtonRestart": "Restart",
"ButtonShutdown": "Shutdown",
@@ -1275,5 +1275,9 @@
"HeaderYears": "Years",
"HeaderAddTag": "Add Tag",
"LabelBlockItemsWithTags": "Block items with tags:",
- "LabelTag": "Tag:"
+ "LabelTag": "Tag:",
+ "LabelEnableSingleImageInDidlLimit": "Limit to single embedded image",
+ "LabelEnableSingleImageInDidlLimitHelp": "Some devices will not render properly if multiple images are embedded within Didl.",
+ "TabActivity": "Activity",
+ "TitleSync": "Sync"
} \ No newline at end of file
diff --git a/MediaBrowser.Server.Implementations/Localization/Server/nb.json b/MediaBrowser.Server.Implementations/Localization/Server/nb.json
index b2acbc3fef..d8351e587d 100644
--- a/MediaBrowser.Server.Implementations/Localization/Server/nb.json
+++ b/MediaBrowser.Server.Implementations/Localization/Server/nb.json
@@ -539,7 +539,7 @@
"HeaderRunningTasks": "Kj\u00f8rende oppgaver",
"HeaderActiveDevices": "Aktive enheter",
"HeaderPendingInstallations": "ventede installasjoner",
- "HeaerServerInformation": "Server informasjon",
+ "HeaderServerInformation": "Server Information",
"ButtonRestartNow": "Restart N\u00e5",
"ButtonRestart": "Restart",
"ButtonShutdown": "Sl\u00e5 Av",
@@ -1275,5 +1275,9 @@
"HeaderYears": "Years",
"HeaderAddTag": "Add Tag",
"LabelBlockItemsWithTags": "Block items with tags:",
- "LabelTag": "Tag:"
+ "LabelTag": "Tag:",
+ "LabelEnableSingleImageInDidlLimit": "Limit to single embedded image",
+ "LabelEnableSingleImageInDidlLimitHelp": "Some devices will not render properly if multiple images are embedded within Didl.",
+ "TabActivity": "Activity",
+ "TitleSync": "Sync"
} \ No newline at end of file
diff --git a/MediaBrowser.Server.Implementations/Localization/Server/nl.json b/MediaBrowser.Server.Implementations/Localization/Server/nl.json
index 1591b72846..86369aa95d 100644
--- a/MediaBrowser.Server.Implementations/Localization/Server/nl.json
+++ b/MediaBrowser.Server.Implementations/Localization/Server/nl.json
@@ -539,7 +539,7 @@
"HeaderRunningTasks": "Actieve taken",
"HeaderActiveDevices": "Actieve apparaten",
"HeaderPendingInstallations": "In afwachting van installaties",
- "HeaerServerInformation": "Server Informatie",
+ "HeaderServerInformation": "Server informatie",
"ButtonRestartNow": "Nu opnieuw opstarten",
"ButtonRestart": "Herstart",
"ButtonShutdown": "Afsluiten",
@@ -1216,7 +1216,7 @@
"HeaderCameraUploadHelp": "Upload automatisch foto's en video's van je mobiele apparaten naar Media Browser.",
"MessageNoDevicesSupportCameraUpload": "Je hebt op dit moment geen apparaten die camera upload ondersteunen.",
"LabelCameraUploadPath": "Camera upload pad:",
- "LabelCameraUploadPathHelp": "Select a custom upload path, if desired. If unspecified a default folder will be used. If using a custom path it will also need to be added in the library setup area.",
+ "LabelCameraUploadPathHelp": "Geef een eigen upload pad op, indien gewenst. Deze map moet ook aan de bibliotheek instellingen toegevoegd worden. Als er niets opgegeven is wordt de standaard map gebruikt.",
"LabelCreateCameraUploadSubfolder": "Maak een submap voor elk apparaat",
"LabelCreateCameraUploadSubfolderHelp": "Specifieke mappen kunnen aan een apparaat toegekend worden door er op te klikken in de apparaten pagina.",
"LabelCustomDeviceDisplayName": "Weergave naam:",
@@ -1273,7 +1273,11 @@
"HeaderParentalRatings": "Ouderlijke toezicht",
"HeaderVideoTypes": "Video types",
"HeaderYears": "Jaren",
- "HeaderAddTag": "Add Tag",
- "LabelBlockItemsWithTags": "Block items with tags:",
- "LabelTag": "Tag:"
+ "HeaderAddTag": "Voeg tag toe",
+ "LabelBlockItemsWithTags": "Blokkeer items met de tag:",
+ "LabelTag": "Tag:",
+ "LabelEnableSingleImageInDidlLimit": "Beperk tot \u00e9\u00e9n enkele ingesloten afbeelding",
+ "LabelEnableSingleImageInDidlLimitHelp": "Sommige apparaten zullen niet goed weergeven als er meerdere afbeeldingen ingesloten zijn in Didl.",
+ "TabActivity": "Activity",
+ "TitleSync": "Sync"
} \ No newline at end of file
diff --git a/MediaBrowser.Server.Implementations/Localization/Server/pl.json b/MediaBrowser.Server.Implementations/Localization/Server/pl.json
index 0968c1d6a3..677d94d96b 100644
--- a/MediaBrowser.Server.Implementations/Localization/Server/pl.json
+++ b/MediaBrowser.Server.Implementations/Localization/Server/pl.json
@@ -539,7 +539,7 @@
"HeaderRunningTasks": "Running Tasks",
"HeaderActiveDevices": "Active Devices",
"HeaderPendingInstallations": "Pending Installations",
- "HeaerServerInformation": "Server Information",
+ "HeaderServerInformation": "Server Information",
"ButtonRestartNow": "Restart Now",
"ButtonRestart": "Restart",
"ButtonShutdown": "Shutdown",
@@ -1275,5 +1275,9 @@
"HeaderYears": "Years",
"HeaderAddTag": "Add Tag",
"LabelBlockItemsWithTags": "Block items with tags:",
- "LabelTag": "Tag:"
+ "LabelTag": "Tag:",
+ "LabelEnableSingleImageInDidlLimit": "Limit to single embedded image",
+ "LabelEnableSingleImageInDidlLimitHelp": "Some devices will not render properly if multiple images are embedded within Didl.",
+ "TabActivity": "Activity",
+ "TitleSync": "Sync"
} \ No newline at end of file
diff --git a/MediaBrowser.Server.Implementations/Localization/Server/pt_BR.json b/MediaBrowser.Server.Implementations/Localization/Server/pt_BR.json
index ffcc542ecc..1cc4471f94 100644
--- a/MediaBrowser.Server.Implementations/Localization/Server/pt_BR.json
+++ b/MediaBrowser.Server.Implementations/Localization/Server/pt_BR.json
@@ -539,7 +539,7 @@
"HeaderRunningTasks": "Tarefas em Execu\u00e7\u00e3o",
"HeaderActiveDevices": "Dispositivos Ativos",
"HeaderPendingInstallations": "Instala\u00e7\u00f5es Pendentes",
- "HeaerServerInformation": "Informa\u00e7\u00f5es do Servidor",
+ "HeaderServerInformation": "Informa\u00e7\u00e3o do Servidor",
"ButtonRestartNow": "Reiniciar Agora",
"ButtonRestart": "Reiniciar",
"ButtonShutdown": "Desligar",
@@ -1275,5 +1275,9 @@
"HeaderYears": "Anos",
"HeaderAddTag": "Adicionar Tag",
"LabelBlockItemsWithTags": "Bloquear itens com tags:",
- "LabelTag": "Tag:"
+ "LabelTag": "Tag:",
+ "LabelEnableSingleImageInDidlLimit": "Limitar a uma imagem incorporada",
+ "LabelEnableSingleImageInDidlLimitHelp": "Alguns dispositivos n\u00e3o interpretar\u00e3o apropriadamente se m\u00faltiplas imagens estiverem incorporadas dentro do Didl.",
+ "TabActivity": "Atividade",
+ "TitleSync": "Sinc"
} \ No newline at end of file
diff --git a/MediaBrowser.Server.Implementations/Localization/Server/pt_PT.json b/MediaBrowser.Server.Implementations/Localization/Server/pt_PT.json
index 8953c2bf71..0fdcba3495 100644
--- a/MediaBrowser.Server.Implementations/Localization/Server/pt_PT.json
+++ b/MediaBrowser.Server.Implementations/Localization/Server/pt_PT.json
@@ -539,7 +539,7 @@
"HeaderRunningTasks": "Tarefas em Execu\u00e7\u00e3o",
"HeaderActiveDevices": "Dispositivos Ativos",
"HeaderPendingInstallations": "Instala\u00e7\u00f5es Pendentes",
- "HeaerServerInformation": "Informa\u00e7\u00e3o do Servidor",
+ "HeaderServerInformation": "Server Information",
"ButtonRestartNow": "Reiniciar Agora",
"ButtonRestart": "Reiniciar",
"ButtonShutdown": "Encerrar",
@@ -1275,5 +1275,9 @@
"HeaderYears": "Years",
"HeaderAddTag": "Add Tag",
"LabelBlockItemsWithTags": "Block items with tags:",
- "LabelTag": "Tag:"
+ "LabelTag": "Tag:",
+ "LabelEnableSingleImageInDidlLimit": "Limit to single embedded image",
+ "LabelEnableSingleImageInDidlLimitHelp": "Some devices will not render properly if multiple images are embedded within Didl.",
+ "TabActivity": "Activity",
+ "TitleSync": "Sync"
} \ No newline at end of file
diff --git a/MediaBrowser.Server.Implementations/Localization/Server/ru.json b/MediaBrowser.Server.Implementations/Localization/Server/ru.json
index f61b61b34d..1aefd919e6 100644
--- a/MediaBrowser.Server.Implementations/Localization/Server/ru.json
+++ b/MediaBrowser.Server.Implementations/Localization/Server/ru.json
@@ -1,6 +1,6 @@
{
"LabelExit": "\u0412\u044b\u0445\u043e\u0434",
- "LabelVisitCommunity": "\u041f\u043e\u0441\u0435\u0442\u0438\u0442\u044c \u0421\u043e\u043e\u0431\u0449\u0435\u0441\u0442\u0432\u043e",
+ "LabelVisitCommunity": "\u041f\u043e\u0441\u0435\u0449\u0435\u043d\u0438\u0435 \u0421\u043e\u043e\u0431\u0449\u0435\u0441\u0442\u0432\u0430",
"LabelGithub": "\u0420\u0435\u043f\u043e\u0437\u0438\u0442\u043e\u0440\u0438\u0439 Github",
"LabelSwagger": "\u0418\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441 Swagger",
"LabelStandard": "\u0421\u0442\u0430\u043d\u0434\u0430\u0440\u0442",
@@ -31,7 +31,7 @@
"LabelEnableVideoImageExtraction": "\u0412\u043a\u043b\u044e\u0447\u0438\u0442\u044c \u0438\u0437\u0432\u043b\u0435\u0447\u0435\u043d\u0438\u0435 \u0440\u0438\u0441\u0443\u043d\u043a\u0430 \u0438\u0437 \u0432\u0438\u0434\u0435\u043e",
"VideoImageExtractionHelp": "\u0414\u043b\u044f \u0432\u0438\u0434\u0435\u043e, \u0433\u0434\u0435 \u0435\u0449\u0451 \u200b\u200b\u043d\u0435 \u0438\u043c\u0435\u0435\u0442\u0441\u044f \u0440\u0438\u0441\u0443\u043d\u043a\u043e\u0432, \u0438 \u043a\u043e\u0442\u043e\u0440\u044b\u0445 \u043d\u0435 \u0443\u0434\u0430\u043b\u043e\u0441\u044c \u043d\u0430\u0439\u0442\u0438 \u0432 \u0438\u043d\u0442\u0435\u0440\u043d\u0435\u0442\u0435. \u041f\u0440\u0438 \u044d\u0442\u043e\u043c \u0431\u0443\u0434\u0435\u0442 \u043f\u0440\u0438\u0431\u0430\u0432\u043b\u0435\u043d\u043e \u0435\u0449\u0451 \u0432\u0440\u0435\u043c\u0435\u043d\u0438 \u043a \u043f\u0435\u0440\u0432\u043e\u043d\u0430\u0447\u0430\u043b\u044c\u043d\u043e\u043c\u0443 \u0441\u043a\u0430\u043d\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044e \u043c\u0435\u0434\u0438\u0430\u0442\u0435\u043a\u0438, \u043d\u043e \u044d\u0442\u043e \u043f\u0440\u0438\u0432\u0435\u0434\u0451\u0442 \u043a \u0431\u043e\u043b\u0435\u0435 \u043f\u0440\u0438\u0432\u043b\u0435\u043a\u0430\u0442\u0435\u043b\u044c\u043d\u043e\u0439 \u043f\u0440\u0435\u0437\u0435\u043d\u0442\u0430\u0446\u0438\u0438.",
"LabelEnableChapterImageExtractionForMovies": "\u0418\u0437\u0432\u043b\u0435\u043a\u0430\u0442\u044c \u0440\u0438\u0441\u0443\u043d\u043a\u0438 \u0441\u0446\u0435\u043d \u0434\u043b\u044f \u0444\u0438\u043b\u044c\u043c\u043e\u0432",
- "LabelChapterImageExtractionForMoviesHelp": "\u0418\u0437\u0432\u043b\u0435\u0447\u0435\u043d\u0438\u0435 \u0440\u0438\u0441\u0443\u043d\u043a\u043e\u0432 \u0441\u0446\u0435\u043d \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u0438 \u043a\u043b\u0438\u0435\u043d\u0442\u0430\u043c \u0434\u043b\u044f \u043e\u0442\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u044f \u0433\u0440\u0430\u0444\u0438\u0447\u0435\u0441\u043a\u0438\u0445 \u043c\u0435\u043d\u044e \u0432\u044b\u0431\u043e\u0440\u0430 \u0441\u0446\u0435\u043d\u044b. \u0414\u0430\u043d\u043d\u044b\u0439 \u043f\u0440\u043e\u0446\u0435\u0441\u0441 \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u043c\u0435\u0434\u043b\u0435\u043d\u043d\u044b\u043c, \u043d\u0430\u0433\u0440\u0443\u0436\u0430\u0442\u044c \u043f\u0440\u043e\u0446\u0435\u0441\u0441\u043e\u0440 \u0438 \u043c\u043e\u0436\u0435\u0442 \u043f\u043e\u043d\u0430\u0434\u043e\u0431\u0438\u0442\u044c\u0441\u044f \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0433\u0438\u0433\u0430\u0431\u0430\u0439\u0442 \u043f\u0440\u043e\u0441\u0442\u0440\u0430\u043d\u0441\u0442\u0432\u0430. \u041e\u043d \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u043a\u0430\u043a \u0437\u0430\u0434\u0430\u043d\u0438\u0435, \u043d\u0430\u0437\u043d\u0430\u0447\u0435\u043d\u043d\u043e\u0435 \u043d\u0430 4:00 \u0443\u0442\u0440\u0430, \u043e\u0434\u043d\u0430\u043a\u043e, \u0435\u0433\u043e \u043c\u043e\u0436\u043d\u043e \u043f\u0435\u0440\u0435\u043d\u0430\u0441\u0442\u0440\u043e\u0438\u0442\u044c \u0432 \u043e\u0431\u043b\u0430\u0441\u0442\u0438 \u00ab\u041f\u043b\u0430\u043d\u0438\u0440\u043e\u0432\u0449\u0438\u043a\u0430\u00bb. \u041d\u0435 \u0440\u0435\u043a\u043e\u043c\u0435\u043d\u0434\u0443\u0435\u0442\u0441\u044f \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0442\u044c \u0434\u0430\u043d\u043d\u043e\u0435 \u0437\u0430\u0434\u0430\u043d\u0438\u0435 \u0432 \u0447\u0430\u0441\u044b \u043f\u0438\u043a.",
+ "LabelChapterImageExtractionForMoviesHelp": "\u0418\u0437\u0432\u043b\u0435\u0447\u0435\u043d\u0438\u0435 \u0440\u0438\u0441\u0443\u043d\u043a\u043e\u0432 \u0441\u0446\u0435\u043d \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u0438 \u043a\u043b\u0438\u0435\u043d\u0442\u0430\u043c \u0434\u043b\u044f \u043e\u0442\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u044f \u0433\u0440\u0430\u0444\u0438\u0447\u0435\u0441\u043a\u0438\u0445 \u043c\u0435\u043d\u044e \u0432\u044b\u0431\u043e\u0440\u0430 \u0441\u0446\u0435\u043d\u044b. \u0414\u0430\u043d\u043d\u044b\u0439 \u043f\u0440\u043e\u0446\u0435\u0441\u0441 \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u043c\u0435\u0434\u043b\u0435\u043d\u043d\u044b\u043c, \u043d\u0430\u0433\u0440\u0443\u0436\u0430\u0442\u044c \u043f\u0440\u043e\u0446\u0435\u0441\u0441\u043e\u0440 \u0438 \u043c\u043e\u0436\u0435\u0442 \u043f\u043e\u043d\u0430\u0434\u043e\u0431\u0438\u0442\u044c\u0441\u044f \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0433\u0438\u0433\u0430\u0431\u0430\u0439\u0442 \u043f\u0440\u043e\u0441\u0442\u0440\u0430\u043d\u0441\u0442\u0432\u0430. \u041e\u043d \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u043a\u0430\u043a \u0437\u0430\u0434\u0430\u0447\u0430, \u043d\u0430\u0437\u043d\u0430\u0447\u0435\u043d\u043d\u0430\u044f \u043d\u0430 4:00 \u0443\u0442\u0440\u0430, \u043e\u0434\u043d\u0430\u043a\u043e, \u0435\u0433\u043e \u043c\u043e\u0436\u043d\u043e \u043f\u0435\u0440\u0435\u043d\u0430\u0441\u0442\u0440\u043e\u0438\u0442\u044c \u0432 \u043e\u0431\u043b\u0430\u0441\u0442\u0438 \u00ab\u041f\u043b\u0430\u043d\u0438\u0440\u043e\u0432\u0449\u0438\u043a\u0430\u00bb. \u041d\u0435 \u0440\u0435\u043a\u043e\u043c\u0435\u043d\u0434\u0443\u0435\u0442\u0441\u044f \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0442\u044c \u0434\u0430\u043d\u043d\u0443\u044e \u0437\u0430\u0434\u0430\u0447\u0443 \u0432 \u0447\u0430\u0441\u044b \u043f\u0438\u043a.",
"LabelEnableAutomaticPortMapping": "\u0412\u043a\u043b\u044e\u0447\u0438\u0442\u044c \u0430\u0432\u0442\u043e\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u043e\u0435 \u0441\u043e\u043f\u043e\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u043f\u043e\u0440\u0442\u043e\u0432",
"LabelEnableAutomaticPortMappingHelp": "UPnP \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u0438 \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u043e\u0433\u043e \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u043c\u0430\u0440\u0448\u0440\u0443\u0442\u0438\u0437\u0430\u0442\u043e\u0440\u0430 \u0434\u043b\u044f \u0443\u0434\u043e\u0431\u043d\u043e\u0433\u043e \u0432\u043d\u0435\u0448\u043d\u0435\u0433\u043e \u0434\u043e\u0441\u0442\u0443\u043f\u0430.\u042d\u0442\u043e \u043c\u043e\u0436\u0435\u0442 \u043d\u0435 \u0441\u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u0441 \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u044b\u043c\u0438 \u043c\u043e\u0434\u0435\u043b\u044f\u043c\u0438 \u043c\u0430\u0440\u0448\u0440\u0443\u0442\u0438\u0437\u0430\u0442\u043e\u0440\u043e\u0432.",
"ButtonOk": "\u041e\u041a",
@@ -155,7 +155,7 @@
"OptionCriticRating": "\u041e\u0446\u0435\u043d\u043a\u0430 \u043a\u0440\u0438\u0442\u0438\u043a\u043e\u0432",
"OptionVideoBitrate": "\u041f\u043e\u0442\u043e\u043a. \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u044c \u0432\u0438\u0434\u0435\u043e",
"OptionResumable": "\u0412\u043e\u0437\u043e\u0431\u043d\u043e\u0432\u0438\u043c\u044b\u0435",
- "ScheduledTasksHelp": "\u0429\u0451\u043b\u043a\u043d\u0438\u0442\u0435 \u043f\u043e \u0437\u0430\u0434\u0430\u043d\u0438\u044e, \u0447\u0442\u043e\u0431\u044b \u043f\u0435\u0440\u0435\u043d\u0430\u0441\u0442\u0440\u043e\u0438\u0442\u044c \u0435\u0433\u043e \u0440\u0430\u0441\u043f\u0438\u0441\u0430\u043d\u0438\u0435.",
+ "ScheduledTasksHelp": "\u0429\u0451\u043b\u043a\u043d\u0438\u0442\u0435 \u043f\u043e \u0437\u0430\u0434\u0430\u0447\u0435, \u0447\u0442\u043e\u0431\u044b \u043f\u0435\u0440\u0435\u043d\u0430\u0441\u0442\u0440\u043e\u0438\u0442\u044c \u0435\u0433\u043e \u0440\u0430\u0441\u043f\u0438\u0441\u0430\u043d\u0438\u0435.",
"ScheduledTasksTitle": "\u041f\u043b\u0430\u043d\u0438\u0440\u043e\u0432\u0449\u0438\u043a",
"TabMyPlugins": "\u041c\u043e\u0438 \u043f\u043b\u0430\u0433\u0438\u043d\u044b",
"TabCatalog": "\u041a\u0430\u0442\u0430\u043b\u043e\u0433",
@@ -264,7 +264,7 @@
"LabelRunServerAtStartup": "\u0417\u0430\u043f\u0443\u0441\u043a\u0430\u0442\u044c \u0441\u0435\u0440\u0432\u0435\u0440 \u043f\u0440\u0438 \u0441\u0442\u0430\u0440\u0442\u0435 \u0441\u0438\u0441\u0442\u0435\u043c\u044b",
"LabelRunServerAtStartupHelp": "\u041f\u0440\u0438 \u044d\u0442\u043e\u043c \u0431\u0443\u0434\u0435\u0442 \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0442\u044c\u0441\u044f \u0437\u043d\u0430\u0447\u043e\u043a \u0432 \u0441\u0438\u0441\u0442\u0435\u043c\u043d\u043e\u043c \u043b\u043e\u0442\u043a\u0435 \u0432 \u043f\u0440\u043e\u0446\u0435\u0441\u0441\u0435 \u0441\u0442\u0430\u0440\u0442\u0430 Windows. \u0414\u043b\u044f \u0437\u0430\u043f\u0443\u0441\u043a\u0430 \u0441\u043b\u0443\u0436\u0431\u044b Windows, \u0441\u043d\u0438\u043c\u0438\u0442\u0435 \u0444\u043b\u0430\u0436\u043e\u043a \u0438 \u0432\u043a\u043b\u044e\u0447\u0438\u0442\u0435 \u0441\u043b\u0443\u0436\u0431\u0443 \u0438\u0437 \u043a\u043e\u043d\u0441\u043e\u043b\u0438 \u0443\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u044f Windows. \u041f\u043e\u043c\u043d\u0438\u0442\u0435, \u0447\u0442\u043e \u043d\u0435\u0432\u043e\u0437\u043c\u043e\u0436\u043d\u0430 \u043e\u0434\u043d\u043e\u0432\u0440\u0435\u043c\u0435\u043d\u043d\u0430\u044f \u0440\u0430\u0431\u043e\u0442\u0430 \u0438\u0445 \u0432\u043c\u0435\u0441\u0442\u0435, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u0437\u0430\u043a\u0440\u044b\u0442\u044c \u0437\u043d\u0430\u0447\u043e\u043a \u0432 \u043b\u043e\u0442\u043a\u0435 \u0434\u043e \u0437\u0430\u043f\u0443\u0441\u043a\u0430 \u0441\u043b\u0443\u0436\u0431\u044b.",
"ButtonSelectDirectory": "\u0412\u044b\u0431\u0440\u0430\u0442\u044c \u043a\u0430\u0442\u0430\u043b\u043e\u0433",
- "LabelCustomPaths": "\u0423\u043a\u0430\u0436\u0438\u0442\u0435 \u043d\u0435\u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u044b\u0435 \u043f\u0443\u0442\u0438 \u043f\u043e \u0436\u0435\u043b\u0430\u0442\u0435\u043b\u044c\u043d\u044b\u043c \u043d\u0430\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u044f\u043c. \u041e\u0441\u0442\u0430\u0432\u043b\u044f\u0439\u0442\u0435 \u043f\u043e\u043b\u044f \u043f\u0443\u0441\u0442\u044b\u043c\u0438, \u0447\u0442\u043e\u0431\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u044b\u0435.",
+ "LabelCustomPaths": "\u0423\u043a\u0430\u0436\u0438\u0442\u0435 \u043d\u0435\u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u044b\u0435 \u043f\u0443\u0442\u0438 \u043f\u043e \u0436\u0435\u043b\u0430\u0442\u0435\u043b\u044c\u043d\u044b\u043c \u043d\u0430\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u044f\u043c. \u041e\u0441\u0442\u0430\u0432\u043b\u044f\u0439\u0442\u0435 \u043f\u043e\u043b\u044f \u043d\u0435\u0437\u0430\u043f\u043e\u043b\u043d\u0435\u043d\u043d\u044b\u043c\u0438, \u0447\u0442\u043e\u0431\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u044b\u0435.",
"LabelCachePath": "\u041f\u0443\u0442\u044c \u043a\u043e \u043a\u0435\u0448\u0443:",
"LabelCachePathHelp": "\u0423\u043a\u0430\u0436\u0438\u0442\u0435 \u043d\u0435\u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u043e\u0435 \u0440\u0430\u0441\u043f\u043e\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u0434\u043b\u044f \u0444\u0430\u0439\u043b\u043e\u0432 \u0441\u0435\u0440\u0432\u0435\u0440\u043d\u043e\u0433\u043e \u043a\u044d\u0448\u0430, \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u0440\u0438\u0441\u0443\u043d\u043a\u043e\u0432.",
"LabelImagesByNamePath": "\u041f\u0443\u0442\u044c \u043a \u0440\u0438\u0441\u0443\u043d\u043a\u0430\u043c \u0447\u0435\u0440\u0435\u0437 \u0438\u043c\u044f:",
@@ -272,7 +272,7 @@
"LabelMetadataPath": "\u041f\u0443\u0442\u044c \u043a \u043c\u0435\u0442\u0430\u0434\u0430\u043d\u043d\u044b\u043c:",
"LabelMetadataPathHelp": "\u0423\u043a\u0430\u0436\u0438\u0442\u0435 \u043d\u0435\u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u043e\u0435 \u0440\u0430\u0441\u043f\u043e\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u0434\u043b\u044f \u0437\u0430\u0433\u0440\u0443\u0436\u0430\u0435\u043c\u044b\u0445 \u0438\u043b\u043b\u044e\u0441\u0442\u0440\u0430\u0446\u0438\u0439 \u0438 \u043c\u0435\u0442\u0430\u0434\u0430\u043d\u043d\u044b\u0445, \u0435\u0441\u043b\u0438 \u043e\u043d\u0438 \u043d\u0435 \u0445\u0440\u0430\u043d\u044f\u0442\u0441\u044f \u0432 \u043f\u0440\u0435\u0434\u0435\u043b\u0430\u0445 \u043c\u0435\u0434\u0438\u0430\u043f\u0430\u043f\u043e\u043a.",
"LabelTranscodingTempPath": "\u041f\u0443\u0442\u044c \u043a\u043e \u0432\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u043c \u0444\u0430\u0439\u043b\u0430\u043c \u043f\u0435\u0440\u0435\u043a\u043e\u0434\u0438\u0440\u043e\u0432\u043a\u0438:",
- "LabelTranscodingTempPathHelp": "\u0412 \u0434\u0430\u043d\u043d\u043e\u0439 \u043f\u0430\u043f\u043a\u0435 \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u0442\u0441\u044f \u0440\u0430\u0431\u043e\u0447\u0438\u0435 \u0444\u0430\u0439\u043b\u044b, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c\u044b\u0435 \u043f\u0440\u0438 \u043f\u0435\u0440\u0435\u043a\u043e\u0434\u0438\u0440\u043e\u0432\u043a\u0435. \u0423\u043a\u0430\u0436\u0438\u0442\u0435 \u043d\u0435\u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u044b\u0439 \u043f\u0443\u0442\u044c, \u0438\u043b\u0438 \u043e\u0441\u0442\u0430\u0432\u044c\u0442\u0435 \u043f\u0443\u0441\u0442\u044b\u043c, \u0447\u0442\u043e\u0431\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u044b\u0439 \u0432\u043d\u0443\u0442\u0440\u0438 \u043f\u0430\u043f\u043a\u0438 \u0434\u0430\u043d\u043d\u044b\u0445 \u0441\u0435\u0440\u0432\u0435\u0440\u0430.",
+ "LabelTranscodingTempPathHelp": "\u0412 \u0434\u0430\u043d\u043d\u043e\u0439 \u043f\u0430\u043f\u043a\u0435 \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u0442\u0441\u044f \u0440\u0430\u0431\u043e\u0447\u0438\u0435 \u0444\u0430\u0439\u043b\u044b, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c\u044b\u0435 \u043f\u0440\u0438 \u043f\u0435\u0440\u0435\u043a\u043e\u0434\u0438\u0440\u043e\u0432\u043a\u0435. \u0423\u043a\u0430\u0436\u0438\u0442\u0435 \u043d\u0435\u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u044b\u0439 \u043f\u0443\u0442\u044c, \u0438\u043b\u0438 \u043e\u0441\u0442\u0430\u0432\u044c\u0442\u0435 \u043f\u043e\u043b\u0435 \u043d\u0435\u0437\u0430\u043f\u043e\u043b\u043d\u0435\u043d\u043d\u044b\u043c, \u0447\u0442\u043e\u0431\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u044b\u0439 \u0432\u043d\u0443\u0442\u0440\u0438 \u043f\u0430\u043f\u043a\u0438 \u0434\u0430\u043d\u043d\u044b\u0445 \u0441\u0435\u0440\u0432\u0435\u0440\u0430.",
"TabBasics": "\u041e\u0441\u043d\u043e\u0432\u043d\u044b\u0435",
"TabTV": "\u0422\u0412",
"TabGames": "\u0418\u0433\u0440\u044b",
@@ -289,7 +289,7 @@
"LabelAutomaticUpdatesFanartHelp": "\u041f\u0440\u0438 \u0432\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0438, \u043d\u043e\u0432\u044b\u0435 \u0440\u0438\u0441\u0443\u043d\u043a\u0438 \u0431\u0443\u0434\u0443\u0442 \u0437\u0430\u0433\u0440\u0443\u0436\u0435\u043d\u044b \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438, \u0441\u0440\u0430\u0437\u0443 \u043f\u0440\u0438 \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u0438\u0438 \u043d\u0430 fanart.tv. \u0421\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u044e\u0449\u0438\u0435 \u0440\u0438\u0441\u0443\u043d\u043a\u0438 \u043d\u0435 \u0431\u0443\u0434\u0443\u0442 \u0437\u0430\u043c\u0435\u0449\u0430\u0442\u044c\u0441\u044f.",
"LabelAutomaticUpdatesTmdbHelp": "\u041f\u0440\u0438 \u0432\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0438, \u043d\u043e\u0432\u044b\u0435 \u0440\u0438\u0441\u0443\u043d\u043a\u0438 \u0431\u0443\u0434\u0443\u0442 \u0437\u0430\u0433\u0440\u0443\u0436\u0435\u043d\u044b \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438, \u0441\u0440\u0430\u0437\u0443 \u043f\u0440\u0438 \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u0438\u0438 \u043d\u0430 TheMovieDB.org. \u0421\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u044e\u0449\u0438\u0435 \u0440\u0438\u0441\u0443\u043d\u043a\u0438 \u043d\u0435 \u0431\u0443\u0434\u0443\u0442 \u0437\u0430\u043c\u0435\u0449\u0430\u0442\u044c\u0441\u044f.",
"LabelAutomaticUpdatesTvdbHelp": "\u041f\u0440\u0438 \u0432\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0438, \u043d\u043e\u0432\u044b\u0435 \u0440\u0438\u0441\u0443\u043d\u043a\u0438 \u0431\u0443\u0434\u0443\u0442 \u0437\u0430\u0433\u0440\u0443\u0436\u0435\u043d\u044b \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438, \u0441\u0440\u0430\u0437\u0443 \u043f\u0440\u0438 \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u0438\u0438 \u043d\u0430 TheTVDB.com. \u0421\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u044e\u0449\u0438\u0435 \u0440\u0438\u0441\u0443\u043d\u043a\u0438 \u043d\u0435 \u0431\u0443\u0434\u0443\u0442 \u0437\u0430\u043c\u0435\u0449\u0430\u0442\u044c\u0441\u044f.",
- "ExtractChapterImagesHelp": "\u0418\u0437\u0432\u043b\u0435\u0447\u0435\u043d\u0438\u0435 \u0440\u0438\u0441\u0443\u043d\u043a\u043e\u0432 \u0441\u0446\u0435\u043d \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u0438 \u043a\u043b\u0438\u0435\u043d\u0442\u0430\u043c \u0434\u043b\u044f \u043e\u0442\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u044f \u0433\u0440\u0430\u0444\u0438\u0447\u0435\u0441\u043a\u0438\u0445 \u043c\u0435\u043d\u044e \u0432\u044b\u0431\u043e\u0440\u0430 \u0441\u0446\u0435\u043d\u044b. \u0414\u0430\u043d\u043d\u044b\u0439 \u043f\u0440\u043e\u0446\u0435\u0441\u0441 \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u043c\u0435\u0434\u043b\u0435\u043d\u043d\u044b\u043c, \u043d\u0430\u0433\u0440\u0443\u0436\u0430\u0435\u0442 \u043f\u0440\u043e\u0446\u0435\u0441\u0441\u043e\u0440 \u0438 \u043c\u043e\u0436\u0435\u0442 \u043f\u043e\u0442\u0440\u0435\u0431\u043e\u0432\u0430\u0442\u044c\u0441\u044f \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0433\u0438\u0433\u0430\u0431\u0430\u0439\u0442 \u043f\u0440\u043e\u0441\u0442\u0440\u0430\u043d\u0441\u0442\u0432\u0430. \u041e\u043d \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u043f\u0440\u0438 \u043e\u0431\u043d\u0430\u0440\u0443\u0436\u0435\u043d\u0438\u0438 \u043d\u043e\u0432\u044b\u0445 \u0432\u0438\u0434\u0435\u043e, \u0430 \u0442\u0430\u043a\u0436\u0435, \u043a\u0430\u043a \u0437\u0430\u0434\u0430\u043d\u0438\u0435, \u043d\u0430\u0437\u043d\u0430\u0447\u0435\u043d\u043d\u043e\u0435 \u043d\u0430 4:00 \u0443\u0442\u0440\u0430. \u0420\u0430\u0441\u043f\u0438\u0441\u0430\u043d\u0438\u0435 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e \u043f\u0435\u0440\u0435\u043d\u0430\u0441\u0442\u0440\u043e\u0438\u0442\u044c \u0432 \u043e\u0431\u043b\u0430\u0441\u0442\u0438 \u00ab\u041f\u043b\u0430\u043d\u0438\u0440\u043e\u0432\u0449\u0438\u043a\u0430\u00bb. \u041d\u0435 \u0440\u0435\u043a\u043e\u043c\u0435\u043d\u0434\u0443\u0435\u0442\u0441\u044f \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0442\u044c \u0434\u0430\u043d\u043d\u043e\u0435 \u0437\u0430\u0434\u0430\u043d\u0438\u0435 \u0432 \u0447\u0430\u0441\u044b \u043f\u0438\u043a.",
+ "ExtractChapterImagesHelp": "\u0418\u0437\u0432\u043b\u0435\u0447\u0435\u043d\u0438\u0435 \u0440\u0438\u0441\u0443\u043d\u043a\u043e\u0432 \u0441\u0446\u0435\u043d \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u0438 \u043a\u043b\u0438\u0435\u043d\u0442\u0430\u043c \u0434\u043b\u044f \u043e\u0442\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u044f \u0433\u0440\u0430\u0444\u0438\u0447\u0435\u0441\u043a\u0438\u0445 \u043c\u0435\u043d\u044e \u0432\u044b\u0431\u043e\u0440\u0430 \u0441\u0446\u0435\u043d\u044b. \u0414\u0430\u043d\u043d\u044b\u0439 \u043f\u0440\u043e\u0446\u0435\u0441\u0441 \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u043c\u0435\u0434\u043b\u0435\u043d\u043d\u044b\u043c, \u043d\u0430\u0433\u0440\u0443\u0436\u0430\u0435\u0442 \u043f\u0440\u043e\u0446\u0435\u0441\u0441\u043e\u0440 \u0438 \u043c\u043e\u0436\u0435\u0442 \u043f\u043e\u0442\u0440\u0435\u0431\u043e\u0432\u0430\u0442\u044c\u0441\u044f \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0433\u0438\u0433\u0430\u0431\u0430\u0439\u0442 \u043f\u0440\u043e\u0441\u0442\u0440\u0430\u043d\u0441\u0442\u0432\u0430. \u041e\u043d \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u043f\u0440\u0438 \u043e\u0431\u043d\u0430\u0440\u0443\u0436\u0435\u043d\u0438\u0438 \u043d\u043e\u0432\u044b\u0445 \u0432\u0438\u0434\u0435\u043e, \u0430 \u0442\u0430\u043a\u0436\u0435, \u043a\u0430\u043a \u0437\u0430\u0434\u0430\u0447\u0430, \u043d\u0430\u0437\u043d\u0430\u0447\u0435\u043d\u043d\u0430\u044f \u043d\u0430 4:00 \u0443\u0442\u0440\u0430. \u0420\u0430\u0441\u043f\u0438\u0441\u0430\u043d\u0438\u0435 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e \u043f\u0435\u0440\u0435\u043d\u0430\u0441\u0442\u0440\u043e\u0438\u0442\u044c \u0432 \u043e\u0431\u043b\u0430\u0441\u0442\u0438 \u00ab\u041f\u043b\u0430\u043d\u0438\u0440\u043e\u0432\u0449\u0438\u043a\u0430\u00bb. \u041d\u0435 \u0440\u0435\u043a\u043e\u043c\u0435\u043d\u0434\u0443\u0435\u0442\u0441\u044f \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0442\u044c \u0434\u0430\u043d\u043d\u0443\u044e \u0437\u0430\u0434\u0430\u0447\u0443 \u0432 \u0447\u0430\u0441\u044b \u043f\u0438\u043a.",
"LabelMetadataDownloadLanguage": "\u041f\u0440\u0435\u0434\u043f\u043e\u0447\u0438\u0442\u0430\u0435\u043c\u044b\u0439 \u044f\u0437\u044b\u043a \u0437\u0430\u0433\u0440\u0443\u0436\u0430\u0435\u043c\u043e\u0433\u043e:",
"ButtonAutoScroll": "\u0412\u043a\u043b\u044e\u0447\u0438\u0442\u044c \u0430\u0432\u0442\u043e\u043f\u0440\u043e\u043a\u0440\u0443\u0442\u043a\u0443",
"LabelImageSavingConvention": "\u0421\u0442\u0430\u043d\u0434\u0430\u0440\u0442 \u0441\u043e\u0445\u0440\u0430\u043d\u0435\u043d\u0438\u044f \u0440\u0438\u0441\u0443\u043d\u043a\u043e\u0432:",
@@ -365,8 +365,8 @@
"LabelMaxScreenshotsPerItem": "\u041c\u0430\u043a\u0441. \u0447\u0438\u0441\u043b\u043e \u0441\u043d\u0438\u043c\u043a\u043e\u0432 \u044d\u043a\u0440\u0430\u043d\u0430 \u043d\u0430 \u044d\u043b\u0435\u043c\u0435\u043d\u0442:",
"LabelMinBackdropDownloadWidth": "\u041c\u0438\u043d. \u0448\u0438\u0440\u0438\u043d\u0430 \u0437\u0430\u0433\u0440\u0443\u0436\u0430\u0435\u043c\u043e\u0433\u043e \u0437\u0430\u0434\u043d\u0438\u043a\u0430:",
"LabelMinScreenshotDownloadWidth": "\u041c\u0438\u043d. \u0448\u0438\u0440\u0438\u043d\u0430 \u0437\u0430\u0433\u0440\u0443\u0436\u0430\u0435\u043c\u043e\u0433\u043e \u0441\u043d\u0438\u043c\u043a\u0430 \u044d\u043a\u0440\u0430\u043d\u0430:",
- "ButtonAddScheduledTaskTrigger": "\u0414\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u0442\u0440\u0438\u0433\u0433\u0435\u0440 \u0437\u0430\u0434\u0430\u043d\u0438\u044f",
- "HeaderAddScheduledTaskTrigger": "\u0414\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u0442\u0440\u0438\u0433\u0433\u0435\u0440\u0430 \u0437\u0430\u0434\u0430\u043d\u0438\u044f",
+ "ButtonAddScheduledTaskTrigger": "\u0414\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u0442\u0440\u0438\u0433\u0433\u0435\u0440 \u0437\u0430\u0434\u0430\u0447\u0438",
+ "HeaderAddScheduledTaskTrigger": "\u0414\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u0442\u0440\u0438\u0433\u0433\u0435\u0440\u0430 \u0437\u0430\u0434\u0430\u0447\u0438",
"ButtonAdd": "\u0414\u043e\u0431\u0430\u0432\u0438\u0442\u044c",
"LabelTriggerType": "\u0422\u0438\u043f \u0442\u0440\u0438\u0433\u0433\u0435\u0440\u0430:",
"OptionDaily": "\u0415\u0436\u0435\u0434\u043d\u0435\u0432\u043d\u043e",
@@ -458,7 +458,7 @@
"LinkGithub": "\u0420\u0435\u043f\u043e\u0437\u0438\u0442\u043e\u0440\u0438\u0439 Github",
"LinkApiDocumentation": "\u0414\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u044f \u043f\u043e API",
"LabelFriendlyServerName": "\u041f\u043e\u043d\u044f\u0442\u043d\u043e\u0435 \u0438\u043c\u044f \u0441\u0435\u0440\u0432\u0435\u0440\u0430:",
- "LabelFriendlyServerNameHelp": "\u0414\u0430\u043d\u043d\u043e\u0435 \u0438\u043c\u044f \u0431\u0443\u0434\u0435\u0442 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c\u0441\u044f, \u0447\u0442\u043e\u0431\u044b \u0440\u0430\u0441\u043f\u043e\u0437\u043d\u0430\u0442\u044c \u0434\u0430\u043d\u043d\u044b\u0439 \u0441\u0435\u0440\u0432\u0435\u0440. \u0415\u0441\u043b\u0438 \u043e\u0441\u0442\u0430\u0432\u0438\u0442\u044c \u043f\u043e\u043b\u0435 \u043f\u0443\u0441\u0442\u044b\u043c, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u0438\u043c\u044f \u043a\u043e\u043c\u043f\u044c\u044e\u0442\u0435\u0440\u0430.",
+ "LabelFriendlyServerNameHelp": "\u0414\u0430\u043d\u043d\u043e\u0435 \u0438\u043c\u044f \u0431\u0443\u0434\u0435\u0442 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c\u0441\u044f \u0434\u043b\u044f \u0440\u0430\u0441\u043f\u043e\u0437\u043d\u0430\u0432\u0430\u043d\u0438\u044f \u0434\u0430\u043d\u043d\u043e\u0433\u043e \u0441\u0435\u0440\u0432\u0435\u0440\u0430. \u0415\u0441\u043b\u0438 \u043e\u0441\u0442\u0430\u0432\u0438\u0442\u044c \u043f\u043e\u043b\u0435 \u043d\u0435\u0437\u0430\u043f\u043e\u043b\u043d\u0435\u043d\u043d\u044b\u043c, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u0438\u043c\u044f \u043a\u043e\u043c\u043f\u044c\u044e\u0442\u0435\u0440\u0430.",
"LabelPreferredDisplayLanguage": "\u041f\u0440\u0435\u0434\u043f\u043e\u0447\u0438\u0442\u0430\u0435\u043c\u044b\u0439 \u044f\u0437\u044b\u043a \u043e\u0442\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u044f:",
"LabelPreferredDisplayLanguageHelp": "\u041f\u0435\u0440\u0435\u0432\u043e\u0434 Media Browser \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u043f\u0440\u043e\u0435\u043a\u0442\u043e\u043c \u043d\u0430\u0445\u043e\u0434\u044f\u0449\u0438\u043c\u0441\u044f \u0432 \u0440\u0430\u0437\u0432\u0438\u0442\u0438\u0438 \u0438 \u0432\u0441\u0451 \u0435\u0449\u0451 \u043d\u0435 \u0437\u0430\u0432\u0435\u0440\u0448\u0451\u043d.",
"LabelReadHowYouCanContribute": "\u0427\u0438\u0442\u0430\u0439\u0442\u0435 \u043e \u0442\u043e\u043c, \u043a\u0430\u043a \u043c\u043e\u0436\u043d\u043e \u0432\u043d\u0435\u0441\u0442\u0438 \u0441\u0432\u043e\u0439 \u0432\u043a\u043b\u0430\u0434.",
@@ -512,8 +512,8 @@
"AutoOrganizeTvHelp": "\u041f\u0440\u0438 \u0440\u0435\u043e\u0440\u0433\u0430\u043d\u0438\u0437\u0430\u0446\u0438\u0438 \u0422\u0412-\u0444\u0430\u0439\u043b\u043e\u0432, \u044d\u043f\u0438\u0437\u043e\u0434\u044b \u0431\u0443\u0434\u0443\u0442 \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u044b \u0442\u043e\u043b\u044c\u043a\u043e \u0432 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u044e\u0449\u0438\u0435 \u0441\u0435\u0440\u0438\u0430\u043b\u044b. \u041f\u0430\u043f\u043a\u0438 \u0434\u043b\u044f \u043d\u043e\u0432\u044b\u0445 \u0441\u0435\u0440\u0438\u0430\u043b\u043e\u0432 \u043d\u0435 \u0431\u0443\u0434\u0443\u0442 \u0441\u043e\u0437\u0434\u0430\u0432\u0430\u0442\u044c\u0441\u044f.",
"OptionEnableEpisodeOrganization": "\u0412\u043a\u043b\u044e\u0447\u0438\u0442\u044c \u0440\u0435\u043e\u0440\u0433\u0430\u043d\u0438\u0437\u0430\u0446\u0438\u044e \u043d\u043e\u0432\u044b\u0445 \u044d\u043f\u0438\u0437\u043e\u0434\u043e\u0432",
"LabelWatchFolder": "\u041f\u0430\u043f\u043a\u0430 \u043e\u0442\u0441\u043b\u0435\u0436\u0438\u0432\u0430\u043d\u0438\u044f:",
- "LabelWatchFolderHelp": "\u0421\u0435\u0440\u0432\u0435\u0440\u043e\u043c \u0431\u0443\u0434\u0435\u0442 \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u0441\u044f \u043e\u043f\u0440\u043e\u0441 \u0434\u0430\u043d\u043d\u043e\u0439 \u043f\u0430\u043f\u043a\u0438 \u0432 \u0445\u043e\u0434\u0435 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u043d\u0430\u0437\u043d\u0430\u0447\u0435\u043d\u043d\u043e\u0433\u043e \u0437\u0430\u0434\u0430\u043d\u0438\u044f \u00ab\u0420\u0435\u043e\u0440\u0433\u0430\u043d\u0438\u0437\u0430\u0446\u0438\u044f \u043d\u043e\u0432\u044b\u0445 \u043c\u0435\u0434\u0438\u0430\u0444\u0430\u0439\u043b\u043e\u0432\u00bb.",
- "ButtonViewScheduledTasks": "\u041f\u0440\u043e\u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c \u043d\u0430\u0437\u043d\u0430\u0447\u0435\u043d\u043d\u044b\u0435 \u0437\u0430\u0434\u0430\u043d\u0438\u044f",
+ "LabelWatchFolderHelp": "\u0421\u0435\u0440\u0432\u0435\u0440\u043e\u043c \u0431\u0443\u0434\u0435\u0442 \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u0441\u044f \u043e\u043f\u0440\u043e\u0441 \u0434\u0430\u043d\u043d\u043e\u0439 \u043f\u0430\u043f\u043a\u0438 \u0432 \u0445\u043e\u0434\u0435 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u043d\u0430\u0437\u043d\u0430\u0447\u0435\u043d\u043d\u043e\u0439 \u0437\u0430\u0434\u0430\u0447\u0438 \u00ab\u0420\u0435\u043e\u0440\u0433\u0430\u043d\u0438\u0437\u0430\u0446\u0438\u044f \u043d\u043e\u0432\u044b\u0445 \u043c\u0435\u0434\u0438\u0430\u0444\u0430\u0439\u043b\u043e\u0432\u00bb.",
+ "ButtonViewScheduledTasks": "\u041f\u0440\u043e\u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c \u043d\u0430\u0437\u043d\u0430\u0447\u0435\u043d\u043d\u044b\u0435 \u0437\u0430\u0434\u0430\u0447\u0438",
"LabelMinFileSizeForOrganize": "\u041c\u0438\u043d. \u0440\u0430\u0437\u043c\u0435\u0440 \u0444\u0430\u0439\u043b\u0430, \u041c\u0411:",
"LabelMinFileSizeForOrganizeHelp": "\u0411\u0443\u0434\u0443\u0442 \u043f\u0440\u043e\u0438\u0433\u043d\u043e\u0440\u0438\u0440\u043e\u0432\u0430\u043d\u044b \u0444\u0430\u0439\u043b\u044b \u0440\u0430\u0437\u043c\u0435\u0440\u043e\u043c \u043c\u0435\u043d\u0435\u0435 \u0434\u0430\u043d\u043d\u043e\u0433\u043e.",
"LabelSeasonFolderPattern": "\u0428\u0430\u0431\u043b\u043e\u043d \u043f\u0430\u043f\u043a\u0438 \u0441\u0435\u0437\u043e\u043d\u0430:",
@@ -536,10 +536,10 @@
"LabelTransferMethodHelp": "\u041a\u043e\u043f\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u0438\u043b\u0438 \u043f\u0435\u0440\u0435\u043c\u0435\u0449\u0435\u043d\u0438\u0435 \u0444\u0430\u0439\u043b\u043e\u0432 \u0438\u0437 \u043f\u0430\u043f\u043a\u0438 \u043e\u0442\u0441\u043b\u0435\u0436\u0438\u0432\u0430\u043d\u0438\u044f",
"HeaderLatestNews": "\u041f\u043e\u0441\u043b\u0435\u0434\u043d\u0438\u0435 \u043d\u043e\u0432\u043e\u0441\u0442\u0438",
"HeaderHelpImproveMediaBrowser": "\u041f\u043e\u043c\u043e\u0449\u044c \u0432 \u0441\u043e\u0432\u0435\u0440\u0448\u0435\u043d\u0441\u0442\u0432\u043e\u0432\u0430\u043d\u0438\u0438 Media Browser",
- "HeaderRunningTasks": "\u0412\u044b\u043f\u043e\u043b\u043d\u044f\u044e\u0449\u0438\u0435\u0441\u044f \u0437\u0430\u0434\u0430\u043d\u0438\u044f",
+ "HeaderRunningTasks": "\u0412\u044b\u043f\u043e\u043b\u043d\u044f\u044e\u0449\u0438\u0435\u0441\u044f \u0437\u0430\u0434\u0430\u0447\u0438",
"HeaderActiveDevices": "\u0410\u043a\u0442\u0438\u0432\u043d\u044b\u0435 \u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u0430",
"HeaderPendingInstallations": "\u041e\u0442\u043b\u043e\u0436\u0435\u043d\u043d\u044b\u0435 \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0438",
- "HeaerServerInformation": "\u0421\u0432\u0435\u0434\u0435\u043d\u0438\u044f \u043e \u0441\u0435\u0440\u0432\u0435\u0440\u0435",
+ "HeaderServerInformation": "\u0421\u0432\u0435\u0434\u0435\u043d\u0438\u044f \u043e \u0441\u0435\u0440\u0432\u0435\u0440\u0435",
"ButtonRestartNow": "\u041f\u0435\u0440\u0435\u0437\u0430\u043f\u0443\u0441\u0442\u0438\u0442\u044c \u043d\u0435\u043c\u0435\u0434\u043b\u0435\u043d\u043d\u043e",
"ButtonRestart": "\u041f\u0435\u0440\u0435\u0437\u0430\u043f\u0443\u0441\u0442\u0438\u0442\u044c",
"ButtonShutdown": "\u0417\u0430\u0432\u0435\u0440\u0448\u0438\u0442\u044c \u0440\u0430\u0431\u043e\u0442\u0443",
@@ -571,7 +571,7 @@
"TabPlayTo": "\u0412\u043e\u0441\u043f\u0440\u043e\u0438\u0437\u0432\u0435\u0441\u0442\u0438 \u041d\u0430",
"LabelEnableDlnaServer": "\u0412\u043a\u043b\u044e\u0447\u0438\u0442\u044c DLNA-\u0441\u0435\u0440\u0432\u0435\u0440",
"LabelEnableDlnaServerHelp": "UPnP-\u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u0430\u043c \u0432 \u0441\u0435\u0442\u0438 \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u044e\u0442\u0441\u044f \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u0438 \u0434\u043b\u044f \u043f\u0440\u043e\u0441\u043c\u043e\u0442\u0440\u0430 \u0438 \u0432\u043e\u0441\u043f\u0440\u043e\u0438\u0437\u0432\u0435\u0434\u0435\u043d\u0438\u044f \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u043d\u0438\u044f Media Browser.",
- "LabelEnableBlastAliveMessages": "\u0412\u0441\u043f\u043b\u0435\u0441\u043a \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0439 \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0438 \u0430\u043a\u0442\u0438\u0432\u043d\u043e\u0441\u0442\u0438",
+ "LabelEnableBlastAliveMessages": "\u0411\u043e\u043c\u0431\u0430\u0440\u0434\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f\u043c\u0438 \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0438 \u0430\u043a\u0442\u0438\u0432\u043d\u043e\u0441\u0442\u0438",
"LabelEnableBlastAliveMessagesHelp": "\u0412\u043a\u043b\u044e\u0447\u0438\u0442\u0435, \u0435\u0441\u043b\u0438 \u0441\u0435\u0440\u0432\u0435\u0440 \u043d\u0435 \u043e\u0431\u043d\u0430\u0440\u0443\u0436\u0438\u0432\u0430\u0435\u0442\u0441\u044f \u043d\u0430\u0434\u0451\u0436\u043d\u043e \u0434\u0440\u0443\u0433\u0438\u043c\u0438 UPnP \u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u0430\u043c\u0438 \u0432 \u0441\u0435\u0442\u0438.",
"LabelBlastMessageInterval": "\u0418\u043d\u0442\u0435\u0440\u0432\u0430\u043b \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0439 \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0438 \u0430\u043a\u0442\u0438\u0432\u043d\u043e\u0441\u0442\u0438, \u0441",
"LabelBlastMessageIntervalHelp": "\u041e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0435\u0442\u0441\u044f \u0434\u043b\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u044c \u0432 \u0441\u0435\u043a\u0443\u043d\u0434\u0430\u0445 \u043c\u0435\u0436\u0434\u0443 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f\u043c\u0438 \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0438 \u0430\u043a\u0442\u0438\u0432\u043d\u043e\u0441\u0442\u0438 \u0441\u0435\u0440\u0432\u0435\u0440\u0430.",
@@ -601,7 +601,7 @@
"NotificationOptionVideoPlaybackStopped": "\u0412\u043e\u0441\u043f\u0440\u043e\u0438\u0437\u0432\u0435\u0434\u0435\u043d\u0438\u0435 \u0432\u0438\u0434\u0435\u043e \u043e\u0441\u0442\u0430\u043d\u043e\u0432\u043b\u0435\u043d\u043e",
"NotificationOptionAudioPlaybackStopped": "\u0412\u043e\u0441\u043f\u0440\u043e\u0438\u0437\u0432\u0435\u0434\u0435\u043d\u0438\u0435 \u0430\u0443\u0434\u0438\u043e \u043e\u0441\u0442\u0430\u043d\u043e\u0432\u043b\u0435\u043d\u043e",
"NotificationOptionGamePlaybackStopped": "\u0412\u043e\u0441\u043f\u0440\u043e\u0438\u0437\u0432\u0435\u0434\u0435\u043d\u0438\u0435 \u0438\u0433\u0440\u044b \u043e\u0441\u0442\u0430\u043d\u043e\u0432\u043b\u0435\u043d\u043e",
- "NotificationOptionTaskFailed": "\u0421\u0431\u043e\u0439 \u043d\u0430\u0437\u043d\u0430\u0447\u0435\u043d\u043d\u043e\u0433\u043e \u0437\u0430\u0434\u0430\u043d\u0438\u044f",
+ "NotificationOptionTaskFailed": "\u0421\u0431\u043e\u0439 \u043d\u0430\u0437\u043d\u0430\u0447\u0435\u043d\u043d\u043e\u0439 \u0437\u0430\u0434\u0430\u0447\u0438",
"NotificationOptionInstallationFailed": "\u0421\u0431\u043e\u0439 \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0438",
"NotificationOptionNewLibraryContent": "\u041d\u043e\u0432\u043e\u0435 \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u043d\u0438\u0435 \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u043e",
"NotificationOptionNewLibraryContentMultiple": "\u041d\u043e\u0432\u043e\u0435 \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u043d\u0438\u0435 \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u043e (\u043c\u043d\u043e\u0433\u043e\u043a\u0440\u0430\u0442\u043d\u043e)",
@@ -661,8 +661,8 @@
"HeaderLatestMedia": "\u041f\u043e\u0441\u043b\u0435\u0434\u043d\u0438\u0435 \u043c\u0435\u0434\u0438\u0430\u0434\u0430\u043d\u043d\u044b\u0435",
"OptionSpecialFeatures": "\u0414\u043e\u043f. \u043c\u0430\u0442\u0435\u0440\u0438\u0430\u043b\u044b",
"HeaderCollections": "\u041a\u043e\u043b\u043b\u0435\u043a\u0446\u0438\u0438",
- "LabelProfileCodecsHelp": "\u0420\u0430\u0437\u0434\u0435\u043b\u044f\u044e\u0442\u0441\u044f \u0437\u0430\u043f\u044f\u0442\u043e\u0439. \u041c\u043e\u0436\u043d\u043e \u043e\u0441\u0442\u0430\u0432\u0438\u0442\u044c \u043f\u0443\u0441\u0442\u044b\u043c, \u0447\u0442\u043e\u0431\u044b \u043f\u0440\u0438\u043c\u0435\u043d\u044f\u0442\u044c \u0434\u043b\u044f \u0432\u0441\u0435\u0445 \u043a\u043e\u0434\u0435\u043a\u043e\u0432.",
- "LabelProfileContainersHelp": "\u0420\u0430\u0437\u0434\u0435\u043b\u044f\u044e\u0442\u0441\u044f \u0437\u0430\u043f\u044f\u0442\u043e\u0439. \u041c\u043e\u0436\u043d\u043e \u043e\u0441\u0442\u0430\u0432\u0438\u0442\u044c \u043f\u0443\u0441\u0442\u044b\u043c, \u0447\u0442\u043e\u0431\u044b \u043f\u0440\u0438\u043c\u0435\u043d\u044f\u0442\u044c \u0434\u043b\u044f \u0432\u0441\u0435\u0445 \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u043e\u0432.",
+ "LabelProfileCodecsHelp": "\u0420\u0430\u0437\u0434\u0435\u043b\u044f\u044e\u0442\u0441\u044f \u0437\u0430\u043f\u044f\u0442\u043e\u0439. \u041f\u043e\u043b\u0435 \u043c\u043e\u0436\u043d\u043e \u043e\u0441\u0442\u0430\u0432\u0438\u0442\u044c \u043d\u0435\u0437\u0430\u043f\u043e\u043b\u043d\u0435\u043d\u043d\u044b\u043c, \u0447\u0442\u043e\u0431\u044b \u043f\u0440\u0438\u043c\u0435\u043d\u044f\u0442\u044c \u0434\u043b\u044f \u0432\u0441\u0435\u0445 \u043a\u043e\u0434\u0435\u043a\u043e\u0432.",
+ "LabelProfileContainersHelp": "\u0420\u0430\u0437\u0434\u0435\u043b\u044f\u044e\u0442\u0441\u044f \u0437\u0430\u043f\u044f\u0442\u043e\u0439. \u041f\u043e\u043b\u0435 \u043c\u043e\u0436\u043d\u043e \u043e\u0441\u0442\u0430\u0432\u0438\u0442\u044c \u043d\u0435\u0437\u0430\u043f\u043e\u043b\u043d\u0435\u043d\u043d\u044b\u043c, \u0447\u0442\u043e\u0431\u044b \u043f\u0440\u0438\u043c\u0435\u043d\u044f\u0442\u044c \u0434\u043b\u044f \u0432\u0441\u0435\u0445 \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u043e\u0432.",
"HeaderResponseProfile": "\u041f\u0440\u043e\u0444\u0438\u043b\u044c \u043e\u0442\u043a\u043b\u0438\u043a\u0430",
"LabelType": "\u0422\u0438\u043f:",
"LabelPersonRole": "\u0420\u043e\u043b\u044c:",
@@ -682,7 +682,7 @@
"OptionProfileVideoAudio": "\u0412\u0438\u0434\u0435\u043e \u0410\u0443\u0434\u0438\u043e",
"OptionProfilePhoto": "\u0424\u043e\u0442\u043e",
"LabelUserLibrary": "\u041c\u0435\u0434\u0438\u0430\u0442\u0435\u043a\u0430 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f:",
- "LabelUserLibraryHelp": "\u0412\u044b\u0431\u0435\u0440\u0438\u0442\u0435, \u0447\u044c\u044e \u043c\u0435\u0434\u0438\u0430\u0442\u0435\u043a\u0443 \u043e\u0442\u043e\u0431\u0440\u0430\u0436\u0430\u0442\u044c \u043d\u0430 \u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u0435. \u041e\u0441\u0442\u0430\u0432\u044c\u0442\u0435 \u043f\u0443\u0441\u0442\u044b\u043c \u0434\u043b\u044f \u043d\u0430\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u043d\u0438\u044f \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u043e\u0433\u043e \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u0430.",
+ "LabelUserLibraryHelp": "\u0412\u044b\u0431\u0435\u0440\u0438\u0442\u0435, \u0447\u044c\u044e \u043c\u0435\u0434\u0438\u0430\u0442\u0435\u043a\u0443 \u043e\u0442\u043e\u0431\u0440\u0430\u0436\u0430\u0442\u044c \u043d\u0430 \u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u0435. \u041e\u0441\u0442\u0430\u0432\u044c\u0442\u0435 \u043f\u043e\u043b\u0435 \u043d\u0435\u0437\u0430\u043f\u043e\u043b\u043d\u0435\u043d\u043d\u044b\u043c, \u0447\u0442\u043e\u0431\u044b \u043d\u0430\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u044c \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u044b\u0439 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440.",
"OptionPlainStorageFolders": "\u041e\u0442\u043e\u0431\u0440\u0430\u0436\u0430\u0442\u044c \u0432\u0441\u0435 \u043f\u0430\u043f\u043a\u0438, \u043a\u0430\u043a \u043e\u0431\u044b\u0447\u043d\u044b\u0435 \u043f\u0430\u043f\u043a\u0438 \u0445\u0440\u0430\u043d\u0435\u043d\u0438\u044f",
"OptionPlainStorageFoldersHelp": "\u041f\u0440\u0438 \u0432\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0438, \u0432\u0441\u0435 \u043f\u0430\u043f\u043a\u0438 \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u044f\u044e\u0442\u0441\u044f \u0432 DIDL \u043a\u0430\u043a \u00abobject.container.storageFolder\u00bb, \u0432\u043c\u0435\u0441\u0442\u043e \u0431\u043e\u043b\u0435\u0435 \u0441\u043f\u0435\u0446\u0438\u0444\u0438\u0447\u043d\u043e\u0433\u043e \u0442\u0438\u043f\u0430, \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u00abobject.container.person.musicArtist\u00bb.",
"OptionPlainVideoItems": "\u041e\u0442\u043e\u0431\u0440\u0430\u0436\u0430\u0442\u044c \u0432\u0441\u0435 \u0438\u043c\u0435\u044e\u0449\u0438\u0435\u0441\u044f \u0432\u0438\u0434\u0435\u043e, \u043a\u0430\u043a \u043e\u0431\u044b\u0447\u043d\u044b\u0435 \u0432\u0438\u0434\u0435\u043e \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u044b",
@@ -832,9 +832,9 @@
"LabelChannelStreamQualityHelp": "\u0412 \u0441\u0440\u0435\u0434\u0435 \u0441 \u043d\u0438\u0437\u043a\u043e\u0439 \u043f\u0440\u043e\u043f\u0443\u0441\u043a\u043d\u043e\u0439 \u0441\u043f\u043e\u0441\u043e\u0431\u043d\u043e\u0441\u0442\u044c\u044e, \u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u0438\u0435 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0430 \u043c\u043e\u0436\u0435\u0442 \u043f\u043e\u043c\u043e\u0447\u044c \u043e\u0431\u0435\u0441\u043f\u0435\u0447\u0438\u0442\u044c \u0432\u0437\u0430\u0438\u043c\u043e\u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0435 \u0434\u043b\u044f \u043f\u043b\u0430\u0432\u043d\u043e\u0439 \u0442\u0440\u0430\u043d\u0441\u043b\u044f\u0446\u0438\u0438.",
"OptionBestAvailableStreamQuality": "\u041d\u0430\u0438\u043b\u0443\u0447\u0448\u0435\u0435 \u0438\u043c\u0435\u044e\u0449\u0435\u0435\u0441\u044f",
"LabelEnableChannelContentDownloadingFor": "\u0412\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435 \u0437\u0430\u0433\u0440\u0443\u0436\u0430\u0435\u043c\u043e\u0433\u043e \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u043d\u0438\u044f \u043a\u0430\u043d\u0430\u043b\u0430 \u0434\u043b\u044f:",
- "LabelEnableChannelContentDownloadingForHelp": "\u041d\u0430 \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u044b\u0445 \u043a\u0430\u043d\u0430\u043b\u0430\u0445 \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0435\u0442\u0441\u044f \u0437\u0430\u0433\u0440\u0443\u0436\u0430\u0435\u043c\u043e\u0435 \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u043d\u0438\u0435, \u043f\u0440\u0435\u0434\u0432\u0430\u0440\u044f\u044e\u0449\u0435\u0435 \u043f\u0440\u043e\u0441\u043c\u043e\u0442\u0440. \u0412\u043a\u043b\u044e\u0447\u0430\u0439\u0442\u0435 \u043f\u0440\u0438 \u0441\u0440\u0435\u0434\u0430\u0445 \u0441 \u043d\u0438\u0437\u043a\u043e\u0439 \u043f\u0440\u043e\u043f\u0443\u0441\u043a\u043d\u043e\u0439 \u0441\u043f\u043e\u0441\u043e\u0431\u043d\u043e\u0441\u0442\u044c\u044e, \u0447\u0442\u043e\u0431\u044b \u0437\u0430\u0433\u0440\u0443\u0436\u0430\u0442\u044c \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u043d\u0438\u0435 \u043a\u0430\u043d\u0430\u043b\u0430 \u0432 \u043d\u0435\u0440\u0430\u0431\u043e\u0447\u0435\u0435 \u0432\u0440\u0435\u043c\u044f. \u0421\u043e\u0434\u0435\u0440\u0436\u0430\u043d\u0438\u0435 \u0437\u0430\u0433\u0440\u0443\u0436\u0430\u0435\u0442\u0441\u044f \u043a\u0430\u043a \u0447\u0430\u0441\u0442\u044c \u043d\u0430\u0437\u043d\u0430\u0447\u0435\u043d\u043d\u043e\u0433\u043e \u0437\u0430\u0434\u0430\u043d\u0438\u044f \u00ab\u0417\u0430\u0433\u0440\u0443\u0437\u043a\u0430 \u043a\u0430\u043d\u0430\u043b\u043e\u0432\u00bb.",
+ "LabelEnableChannelContentDownloadingForHelp": "\u041d\u0430 \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u044b\u0445 \u043a\u0430\u043d\u0430\u043b\u0430\u0445 \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0435\u0442\u0441\u044f \u0437\u0430\u0433\u0440\u0443\u0436\u0430\u0435\u043c\u043e\u0435 \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u043d\u0438\u0435, \u043f\u0440\u0435\u0434\u0432\u0430\u0440\u044f\u044e\u0449\u0435\u0435 \u043f\u0440\u043e\u0441\u043c\u043e\u0442\u0440. \u0412\u043a\u043b\u044e\u0447\u0430\u0439\u0442\u0435 \u043f\u0440\u0438 \u0441\u0440\u0435\u0434\u0430\u0445 \u0441 \u043d\u0438\u0437\u043a\u043e\u0439 \u043f\u0440\u043e\u043f\u0443\u0441\u043a\u043d\u043e\u0439 \u0441\u043f\u043e\u0441\u043e\u0431\u043d\u043e\u0441\u0442\u044c\u044e, \u0447\u0442\u043e\u0431\u044b \u0437\u0430\u0433\u0440\u0443\u0436\u0430\u0442\u044c \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u043d\u0438\u0435 \u043a\u0430\u043d\u0430\u043b\u0430 \u0432 \u043d\u0435\u0440\u0430\u0431\u043e\u0447\u0435\u0435 \u0432\u0440\u0435\u043c\u044f. \u0421\u043e\u0434\u0435\u0440\u0436\u0430\u043d\u0438\u0435 \u0437\u0430\u0433\u0440\u0443\u0436\u0430\u0435\u0442\u0441\u044f \u043a\u0430\u043a \u0447\u0430\u0441\u0442\u044c \u043d\u0430\u0437\u043d\u0430\u0447\u0435\u043d\u043d\u043e\u0439 \u0437\u0430\u0434\u0430\u0447\u0438 \u00ab\u0417\u0430\u0433\u0440\u0443\u0437\u043a\u0430 \u043a\u0430\u043d\u0430\u043b\u043e\u0432\u00bb.",
"LabelChannelDownloadPath": "\u041f\u0443\u0442\u044c \u0434\u043b\u044f \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u043d\u0438\u044f \u0437\u0430\u0433\u0440\u0443\u0436\u0430\u0435\u043c\u044b\u0445 \u043a\u0430\u043d\u0430\u043b\u043e\u0432:",
- "LabelChannelDownloadPathHelp": "\u0423\u043a\u0430\u0436\u0438\u0442\u0435 \u043d\u0435\u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u044b\u0439 \u043f\u0443\u0442\u044c \u0434\u043b\u044f \u0437\u0430\u0433\u0440\u0443\u0436\u0430\u0435\u043c\u043e\u0433\u043e, \u043f\u043e \u0436\u0435\u043b\u0430\u043d\u0438\u044e. \u041e\u0441\u0442\u0430\u0432\u044c\u0442\u0435 \u043f\u0443\u0441\u0442\u044b\u043c, \u0447\u0442\u043e\u0431\u044b \u0437\u0430\u0433\u0440\u0443\u0436\u0430\u0442\u044c \u0432\u043e \u0432\u043d\u0443\u0442\u0440\u0435\u043d\u043d\u044e\u044e \u043f\u0430\u043f\u043a\u0443 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u043d\u044b\u0445 \u0434\u0430\u043d\u043d\u044b\u0445.",
+ "LabelChannelDownloadPathHelp": "\u0423\u043a\u0430\u0436\u0438\u0442\u0435 \u043d\u0435\u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u044b\u0439 \u043f\u0443\u0442\u044c \u0434\u043b\u044f \u0437\u0430\u0433\u0440\u0443\u0436\u0430\u0435\u043c\u043e\u0433\u043e, \u043f\u043e \u0436\u0435\u043b\u0430\u043d\u0438\u044e. \u041e\u0441\u0442\u0430\u0432\u044c\u0442\u0435 \u043f\u043e\u043b\u0435 \u043d\u0435\u0437\u0430\u043f\u043e\u043b\u043d\u0435\u043d\u043d\u044b\u043c, \u0447\u0442\u043e\u0431\u044b \u0437\u0430\u0433\u0440\u0443\u0436\u0430\u0442\u044c \u0432\u043e \u0432\u043d\u0443\u0442\u0440\u0435\u043d\u043d\u044e\u044e \u043f\u0430\u043f\u043a\u0443 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u043d\u044b\u0445 \u0434\u0430\u043d\u043d\u044b\u0445.",
"LabelChannelDownloadAge": "\u0423\u0434\u0430\u043b\u0435\u043d\u0438\u0435 \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u043d\u0438\u044f \u0447\u0435\u0440\u0435\u0437, \u0434\u043d\u0438:",
"LabelChannelDownloadAgeHelp": "\u0417\u0430\u0433\u0440\u0443\u0436\u0430\u0435\u043c\u043e\u0435 \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u043d\u0438\u0435 \u0441\u0442\u0430\u0440\u0448\u0435 \u0443\u043a\u0430\u0437\u0430\u043d\u043d\u043e\u0433\u043e \u0431\u0443\u0434\u0435\u0442 \u0443\u0434\u0430\u043b\u0435\u043d\u043e. \u041e\u043d\u043e \u043e\u0441\u0442\u0430\u043d\u0435\u0442\u0441\u044f \u0432\u043e\u0441\u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u043c\u044b\u043c \u043f\u043e \u0438\u043d\u0442\u0435\u0440\u043d\u0435\u0442-\u0442\u0440\u0430\u043d\u0441\u043b\u044f\u0446\u0438\u0438.",
"ChannelSettingsFormHelp": "\u0423\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u0435 \u043a\u0430\u043d\u0430\u043b\u044b (\u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440: Trailers \u0438\u043b\u0438 Vimeo) \u0438\u0437 \u043a\u0430\u0442\u0430\u043b\u043e\u0433\u0430 \u043f\u043b\u0430\u0433\u0438\u043d\u043e\u0432.",
@@ -952,11 +952,11 @@
"LabelDateAdded": "\u0414\u0430\u0442\u0430 \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u0438\u044f:",
"HeaderFeatures": "\u041c\u0430\u0442\u0435\u0440\u0438\u0430\u043b\u044b",
"HeaderAdvanced": "\u0414\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u043e",
- "ButtonSync": "\u0421\u0438\u043d\u0445\u0440-\u0442\u044c",
+ "ButtonSync": "Sync",
"TabScheduledTasks": "\u041f\u043b\u0430\u043d\u0438\u0440\u043e\u0432\u0449\u0438\u043a",
"HeaderChapters": "\u0421\u0446\u0435\u043d\u044b",
"HeaderResumeSettings": "\u041f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u044b \u0432\u043e\u0437\u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u044f",
- "TabSync": "\u0421\u0438\u043d\u0445\u0440-\u0438\u044f",
+ "TabSync": "Sync",
"TitleUsers": "\u041f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0438",
"LabelProtocol": "\u041f\u0440\u043e\u0442\u043e\u043a\u043e\u043b:",
"OptionProtocolHttp": "HTTP",
@@ -1010,14 +1010,14 @@
"OptionReportAdultVideos": "\u0412\u0437\u0440\u043e\u0441\u043b\u044b\u0435 \u0432\u0438\u0434\u0435\u043e",
"ButtonMore": "\u0421\u043c. \u0434\u0430\u043b\u0435\u0435",
"HeaderActivity": "\u0414\u0435\u0439\u0441\u0442\u0432\u0438\u044f",
- "ScheduledTaskStartedWithName": "{0} - \u0437\u0430\u043f\u0443\u0449\u0435\u043d\u043e",
- "ScheduledTaskCancelledWithName": "{0} - \u0431\u044b\u043b\u043e \u043e\u0442\u043c\u0435\u043d\u0435\u043d\u043e",
- "ScheduledTaskCompletedWithName": "{0} - \u0437\u0430\u0432\u0435\u0440\u0448\u0435\u043d\u043e",
- "ScheduledTaskFailed": "\u041d\u0430\u0437\u043d\u0430\u0447\u0435\u043d\u043d\u043e\u0435 \u0437\u0430\u0434\u0430\u043d\u0438\u0435 \u0437\u0430\u0432\u0435\u0440\u0448\u0435\u043d\u043e",
+ "ScheduledTaskStartedWithName": "{0} - \u0437\u0430\u043f\u0443\u0449\u0435\u043d\u0430",
+ "ScheduledTaskCancelledWithName": "{0} - \u0431\u044b\u043b\u0430 \u043e\u0442\u043c\u0435\u043d\u0435\u043d\u0430",
+ "ScheduledTaskCompletedWithName": "{0} - \u0437\u0430\u0432\u0435\u0440\u0448\u0435\u043d\u0430",
+ "ScheduledTaskFailed": "\u041d\u0430\u0437\u043d\u0430\u0447\u0435\u043d\u043d\u0430\u044f \u0437\u0430\u0434\u0430\u0447\u0430 \u0437\u0430\u0432\u0435\u0440\u0448\u0435\u043d\u0430",
"PluginInstalledWithName": "{0} - \u0431\u044b\u043b\u043e \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u043b\u0435\u043d\u043e",
"PluginUpdatedWithName": "{0} - \u0431\u044b\u043b\u043e \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u043e",
"PluginUninstalledWithName": "{0} - \u0431\u044b\u043b\u043e \u0443\u0434\u0430\u043b\u0435\u043d\u043e",
- "ScheduledTaskFailedWithName": "{0} - \u043d\u0435\u0443\u0434\u0430\u0447\u043d\u043e",
+ "ScheduledTaskFailedWithName": "{0} - \u043d\u0435\u0443\u0434\u0430\u0447\u043d\u0430",
"ItemAddedWithName": "{0} (\u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u043e \u0432 \u043c\u0435\u0434\u0438\u0430\u0442\u0435\u043a\u0443)",
"ItemRemovedWithName": "{0} (\u0438\u0437\u044a\u044f\u0442\u043e \u0438\u0437 \u043c\u0435\u0434\u0438\u0430\u0442\u0435\u043a\u0438)",
"DeviceOnlineWithName": "{0} - \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435 \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u043b\u0435\u043d\u043e",
@@ -1025,7 +1025,7 @@
"DeviceOfflineWithName": "{0} - \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435 \u043f\u0440\u0435\u0440\u0432\u0430\u043d\u043e",
"UserOfflineFromDevice": "{0} - \u043f\u043e\u0434\u043a\u043b-\u0438\u0435 \u0441 {1} \u043f\u0440\u0435\u0440\u0432\u0430\u043d\u043e",
"SubtitlesDownloadedForItem": "\u0421\u0443\u0431\u0442\u0438\u0442\u0440\u044b \u0434\u043b\u044f {0} \u0437\u0430\u0433\u0440\u0443\u0437\u0438\u043b\u0438\u0441\u044c",
- "SubtitleDownloadFailureForItem": "\u0421\u0443\u0431\u0442\u0438\u0442\u0440\u044b \u0434\u043b\u044f {0} \u043d\u0435 \u0443\u0434\u0430\u043b\u043e\u0441\u044c \u0437\u0430\u0433\u0440\u0443\u0437\u0438\u0442\u044c",
+ "SubtitleDownloadFailureForItem": "\u0421\u0443\u0431\u0442\u0438\u0442\u0440\u044b \u043a {0} \u043d\u0435 \u0443\u0434\u0430\u043b\u043e\u0441\u044c \u0437\u0430\u0433\u0440\u0443\u0437\u0438\u0442\u044c",
"LabelRunningTimeValue": "\u0412\u0440\u0435\u043c\u044f \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f: {0}",
"LabelIpAddressValue": "IP-\u0430\u0434\u0440\u0435\u0441: {0}",
"UserConfigurationUpdatedWithName": "\u041a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u044f \u043f\u043e\u043b\u044c\u0437-\u043b\u044f {0} \u0431\u044b\u043b\u0430 \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0430",
@@ -1119,7 +1119,7 @@
"HeaderTags": "\u0422\u0435\u0433\u0438",
"HeaderMetadataSettings": "\u041f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u044b \u043c\u0435\u0442\u0430\u0434\u0430\u043d\u043d\u044b\u0445",
"LabelLockItemToPreventChanges": "\u0424\u0438\u043a\u0441\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0434\u0430\u043d\u043d\u044b\u0439 \u044d\u043b\u0435\u043c\u0435\u043d\u0442, \u0447\u0442\u043e\u0431\u044b \u0437\u0430\u043f\u0440\u0435\u0442\u0438\u0442\u044c \u0431\u0443\u0434\u0443\u0449\u0438\u0435 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044f",
- "MessageLeaveEmptyToInherit": "\u041e\u0441\u0442\u0430\u0432\u044c\u0442\u0435 \u043f\u0443\u0441\u0442\u044b\u043c, \u0447\u0442\u043e\u0431\u044b \u043d\u0430\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u044c \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u044b \u043e\u0442 \u0440\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u0441\u043a\u043e\u0433\u043e \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u0430, \u0438\u043b\u0438 \u0433\u043b\u043e\u0431\u0430\u043b\u044c\u043d\u043e\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u043f\u043e \u0443\u043c\u043e\u043b\u0447\u0430\u043d\u0438\u044e.",
+ "MessageLeaveEmptyToInherit": "\u041e\u0441\u0442\u0430\u0432\u044c\u0442\u0435 \u043f\u043e\u043b\u0435 \u043d\u0435\u0437\u0430\u043f\u043e\u043b\u043d\u0435\u043d\u043d\u044b\u043c, \u0447\u0442\u043e\u0431\u044b \u043d\u0430\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u044c \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u044b \u043e\u0442 \u0440\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u0441\u043a\u043e\u0433\u043e \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u0430, \u0438\u043b\u0438 \u0433\u043b\u043e\u0431\u0430\u043b\u044c\u043d\u043e\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u043f\u043e \u0443\u043c\u043e\u043b\u0447\u0430\u043d\u0438\u044e.",
"TabDonate": "\u041f\u043e\u0436\u0435\u0440\u0442\u0432\u043e\u0432\u0430\u043d\u0438\u044f",
"HeaderDonationType": "\u0422\u0438\u043f \u043f\u043e\u0436\u0435\u0440\u0442\u0432\u043e\u0432\u0430\u043d\u0438\u044f:",
"OptionMakeOneTimeDonation": "\u0421\u0434\u0435\u043b\u0430\u0442\u044c \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u043e\u0435 \u043f\u043e\u0436\u0435\u0440\u0442\u0432\u043e\u0432\u0430\u043d\u0438\u0435",
@@ -1158,7 +1158,7 @@
"XmlDocumentAttributeListHelp": "\u0414\u0430\u043d\u043d\u044b\u0435 \u0430\u0442\u0440\u0438\u0431\u0443\u0442\u044b \u043f\u0440\u0438\u043c\u0435\u043d\u044f\u044e\u0442\u0441\u044f \u043a\u043e \u043a\u043e\u0440\u043d\u0435\u0432\u043e\u043c\u0443 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u0443 \u043a\u0430\u0436\u0434\u043e\u0433\u043e XML-\u043e\u0442\u043a\u043b\u0438\u043a\u0430.",
"OptionSaveMetadataAsHidden": "\u0421\u043e\u0445\u0440\u0430\u043d\u044f\u0442\u044c \u043c\u0435\u0442\u0430\u0434\u0430\u043d\u043d\u044b\u0435 \u0438 \u0440\u0438\u0441\u0443\u043d\u043a\u0438 \u043a\u0430\u043a \u0441\u043a\u0440\u044b\u0442\u044b\u0435 \u0444\u0430\u0439\u043b\u044b",
"LabelExtractChaptersDuringLibraryScan": "\u0418\u0437\u0432\u043b\u0435\u043a\u0430\u0442\u044c \u0440\u0438\u0441\u0443\u043d\u043a\u0438 \u0441\u0446\u0435\u043d \u0432\u043e \u0432\u0440\u0435\u043c\u044f \u0441\u043a\u0430\u043d\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u043c\u0435\u0434\u0438\u0430\u0442\u0435\u043a\u0438",
- "LabelExtractChaptersDuringLibraryScanHelp": "\u041f\u0440\u0438 \u0432\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0438, \u0440\u0438\u0441\u0443\u043d\u043a\u0438 \u0441\u0446\u0435\u043d \u0431\u0443\u0434\u0443\u0442 \u0438\u0437\u0432\u043b\u0435\u0447\u0435\u043d\u044b, \u043a\u043e\u0433\u0434\u0430 \u0432\u0438\u0434\u0435\u043e \u0438\u043c\u043f\u043e\u0440\u0442\u0438\u0440\u0443\u0435\u0442\u0441\u044f \u0432\u043e \u0432\u0440\u0435\u043c\u044f \u0441\u043a\u0430\u043d\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u043c\u0435\u0434\u0438\u0430\u0442\u0435\u043a\u0438. \u041f\u0440\u0438 \u0432\u044b\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0438, \u043e\u043d\u0438 \u0431\u0443\u0434\u0443\u0442 \u0438\u0437\u0432\u043b\u0435\u0447\u0435\u043d\u044b \u0432 \u0442\u0435\u0447\u0435\u043d\u0438\u0435 \u043d\u0430\u0437\u043d\u0430\u0447\u0435\u043d\u043d\u043e\u0433\u043e \u0437\u0430\u0434\u0430\u043d\u0438\u044f \u00ab\u0420\u0438\u0441\u0443\u043d\u043a\u0438 \u0441\u0446\u0435\u043d\u00bb, \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u044f \u0440\u0435\u0433\u0443\u043b\u044f\u0440\u043d\u043e\u043c\u0443 \u0441\u043a\u0430\u043d\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044e \u043c\u0435\u0434\u0438\u0430\u0442\u0435\u043a\u0438 \u0437\u0430\u0432\u0435\u0440\u0448\u0430\u0442\u044c\u0441\u044f \u0431\u044b\u0441\u0442\u0440\u0435\u0435.",
+ "LabelExtractChaptersDuringLibraryScanHelp": "\u041f\u0440\u0438 \u0432\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0438, \u0440\u0438\u0441\u0443\u043d\u043a\u0438 \u0441\u0446\u0435\u043d \u0431\u0443\u0434\u0443\u0442 \u0438\u0437\u0432\u043b\u0435\u0447\u0435\u043d\u044b, \u043a\u043e\u0433\u0434\u0430 \u0432\u0438\u0434\u0435\u043e \u0438\u043c\u043f\u043e\u0440\u0442\u0438\u0440\u0443\u0435\u0442\u0441\u044f \u0432\u043e \u0432\u0440\u0435\u043c\u044f \u0441\u043a\u0430\u043d\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u043c\u0435\u0434\u0438\u0430\u0442\u0435\u043a\u0438. \u041f\u0440\u0438 \u0432\u044b\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0438, \u043e\u043d\u0438 \u0431\u0443\u0434\u0443\u0442 \u0438\u0437\u0432\u043b\u0435\u0447\u0435\u043d\u044b \u0432 \u0442\u0435\u0447\u0435\u043d\u0438\u0435 \u043d\u0430\u0437\u043d\u0430\u0447\u0435\u043d\u043d\u043e\u0439 \u0437\u0430\u0434\u0430\u0447\u0438 \u00ab\u0420\u0438\u0441\u0443\u043d\u043a\u0438 \u0441\u0446\u0435\u043d\u00bb, \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u044f \u0440\u0435\u0433\u0443\u043b\u044f\u0440\u043d\u043e\u043c\u0443 \u0441\u043a\u0430\u043d\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044e \u043c\u0435\u0434\u0438\u0430\u0442\u0435\u043a\u0438 \u0437\u0430\u0432\u0435\u0440\u0448\u0430\u0442\u044c\u0441\u044f \u0431\u044b\u0441\u0442\u0440\u0435\u0435.",
"LabelConnectGuestUserName": "\u0418\u043c\u044f \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f Media Browser \u0438\u043b\u0438 \u0430\u0434\u0440\u0435\u0441 \u044d-\u043f\u043e\u0447\u0442\u044b:",
"LabelConnectUserName": "\u0418\u043c\u044f \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f Media Browser \/ \u044d-\u043f\u043e\u0447\u0442\u0430:",
"LabelConnectUserNameHelp": "\u0421\u043e\u0435\u0434\u0438\u043d\u0438\u0442\u0435 \u044d\u0442\u043e\u0433\u043e \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f c \u0443\u0447\u0451\u0442\u043d\u043e\u0439 \u0437\u0430\u043f\u0438\u0441\u044c\u044e Media Browser, \u0447\u0442\u043e\u0431\u044b \u0432\u043a\u043b\u044e\u0447\u0438\u0442\u044c \u0434\u043e\u0441\u0442\u0443\u043f \u043a \u0443\u0434\u043e\u0431\u043d\u043e\u043c\u0443 \u0432\u0445\u043e\u0434\u0443 \u0438\u0437 \u043b\u044e\u0431\u043e\u0433\u043e \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f Media Browser \u0431\u0435\u0437 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e\u0441\u0442\u0438 \u0437\u043d\u0430\u0442\u044c IP-\u0430\u0434\u0440\u0435\u0441 \u0441\u0435\u0440\u0432\u0435\u0440\u0430.",
@@ -1220,7 +1220,7 @@
"LabelCreateCameraUploadSubfolder": "\u0421\u043e\u0437\u0434\u0430\u0432\u0430\u0442\u044c \u043f\u043e\u0434\u043f\u0430\u043f\u043a\u0443 \u0434\u043b\u044f \u043a\u0430\u0436\u0434\u043e\u0433\u043e \u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u0430",
"LabelCreateCameraUploadSubfolderHelp": "\u0421\u043f\u0435\u0446\u0438\u0444\u0438\u0447\u0435\u0441\u043a\u0438\u0435 \u043f\u0430\u043f\u043a\u0438 \u043c\u043e\u0433\u0443\u0442 \u0431\u044b\u0442\u044c \u043d\u0430\u0437\u043d\u0430\u0447\u0435\u043d\u044b \u0434\u043b\u044f \u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u0430 \u043f\u0440\u0438 \u0449\u0435\u043b\u0447\u043a\u0435 \u043d\u0430 \u043d\u0451\u043c \u0441\u043e \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u044b \"\u0423\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u0430\".",
"LabelCustomDeviceDisplayName": "\u041e\u0442\u043e\u0431\u0440\u0430\u0436\u0430\u0435\u043c\u043e\u0435 \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u0435:",
- "LabelCustomDeviceDisplayNameHelp": "\u041f\u0440\u0438\u0432\u0435\u0434\u0438\u0442\u0435 \u043d\u0430\u0441\u0442\u0440\u0430\u0438\u0432\u0430\u0435\u043c\u043e\u0435 \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u0435 \u0434\u043b\u044f \u043e\u0442\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u044f \u0438\u043b\u0438 \u043e\u0441\u0442\u0430\u0432\u044c\u0442\u0435 \u043f\u0443\u0441\u0442\u044b\u043c, \u0447\u0442\u043e\u0431\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u0435 \u0441\u043e\u043e\u0431\u0449\u0451\u043d\u043d\u043e\u0435 \u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u043e\u043c.",
+ "LabelCustomDeviceDisplayNameHelp": "\u041f\u0440\u0438\u0432\u0435\u0434\u0438\u0442\u0435 \u043d\u0430\u0441\u0442\u0440\u0430\u0438\u0432\u0430\u0435\u043c\u043e\u0435 \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u0435 \u0434\u043b\u044f \u043e\u0442\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u044f \u0438\u043b\u0438 \u043e\u0441\u0442\u0430\u0432\u044c\u0442\u0435 \u043f\u043e\u043b\u0435 \u043d\u0435\u0437\u0430\u043f\u043e\u043b\u043d\u0435\u043d\u043d\u044b\u043c, \u0447\u0442\u043e\u0431\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u0435, \u0441\u043e\u043e\u0431\u0449\u0451\u043d\u043d\u043e\u0435 \u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u043e\u043c.",
"HeaderInviteUser": "\u041f\u0440\u0438\u0433\u043b\u0430\u0448\u0435\u043d\u0438\u0435 \u0434\u043b\u044f \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f",
"LabelConnectGuestUserNameHelp": "\u0418\u043c\u044f \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f, \u043a\u043e\u0442\u043e\u0440\u044b\u043c \u0432\u0430\u0448 \u0434\u0440\u0443\u0433 \u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u0434\u043b\u044f \u0432\u0445\u043e\u0434\u0430 \u043d\u0430 \u0432\u0435\u0431-\u0441\u0430\u0439\u0442 Media Browser, \u0438\u043b\u0438 \u0430\u0434\u0440\u0435\u0441 \u044d-\u043f\u043e\u0447\u0442\u044b.",
"HeaderInviteUserHelp": "Media Browser Connect \u0443\u043f\u0440\u043e\u0449\u0430\u0435\u0442 \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u0434\u0440\u0443\u0437\u044c\u044f\u043c \u043e\u0431\u0449\u0435\u0433\u043e \u0434\u043e\u0441\u0442\u0443\u043f\u0430 \u043a \u0432\u0430\u0448\u0438\u043c \u043c\u0435\u0434\u0438\u0430\u0434\u0430\u043d\u043d\u044b\u043c.",
@@ -1273,7 +1273,11 @@
"HeaderParentalRatings": "\u0412\u043e\u0437\u0440\u0430\u0441\u0442\u043d\u0430\u044f \u043a\u0430\u0442\u0435\u0433\u043e\u0440\u0438\u044f",
"HeaderVideoTypes": "\u0422\u0438\u043f\u044b \u0432\u0438\u0434\u0435\u043e",
"HeaderYears": "\u0413\u043e\u0434\u044b",
- "HeaderAddTag": "Add Tag",
- "LabelBlockItemsWithTags": "Block items with tags:",
- "LabelTag": "Tag:"
+ "HeaderAddTag": "\u0414\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u0442\u0435\u0433\u0430",
+ "LabelBlockItemsWithTags": "\u0411\u043b\u043e\u043a\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u043e\u0432 \u0441 \u0442\u0435\u0433\u0430\u043c\u0438:",
+ "LabelTag": "\u0422\u0435\u0433:",
+ "LabelEnableSingleImageInDidlLimit": "\u041e\u0433\u0440\u0430\u043d\u0438\u0447\u0438\u0442\u044c \u0434\u043e \u0435\u0434\u0438\u043d\u0441\u0442\u0432\u0435\u043d\u043d\u043e\u0433\u043e \u0432\u043d\u0435\u0434\u0440\u0451\u043d\u043d\u043e\u0433\u043e \u0440\u0438\u0441\u0443\u043d\u043a\u0430",
+ "LabelEnableSingleImageInDidlLimitHelp": "\u041d\u0435\u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u0430 \u043d\u0435 \u0431\u0443\u0434\u0443\u0442 \u043e\u0442\u0440\u0438\u0441\u043e\u0432\u044b\u0432\u0430\u0442\u044c \u043d\u043e\u0440\u043c\u0430\u043b\u044c\u043d\u043e, \u0435\u0441\u043b\u0438 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0440\u0438\u0441\u0443\u043d\u043a\u043e\u0432 \u0432\u043d\u0435\u0434\u0440\u044f\u044e\u0442\u0441\u044f \u0432\u043d\u0443\u0442\u0440\u0438 Didl.",
+ "TabActivity": "\u0414\u0435\u0439\u0441\u0442\u0432\u0438\u044f",
+ "TitleSync": "\u0421\u0438\u043d\u0445\u0440\u043e\u043d\u0438\u0437\u0430\u0446\u0438\u044f"
} \ No newline at end of file
diff --git a/MediaBrowser.Server.Implementations/Localization/Server/server.json b/MediaBrowser.Server.Implementations/Localization/Server/server.json
index 117a5c4079..6bb24be2b3 100644
--- a/MediaBrowser.Server.Implementations/Localization/Server/server.json
+++ b/MediaBrowser.Server.Implementations/Localization/Server/server.json
@@ -542,7 +542,7 @@
"HeaderRunningTasks": "Running Tasks",
"HeaderActiveDevices": "Active Devices",
"HeaderPendingInstallations": "Pending Installations",
- "HeaerServerInformation": "Server Information",
+ "HeaderServerInformation": "Server Information",
"ButtonRestartNow": "Restart Now",
"ButtonRestart": "Restart",
"ButtonShutdown": "Shutdown",
@@ -1291,5 +1291,9 @@
"HeaderYears": "Years",
"HeaderAddTag": "Add Tag",
"LabelBlockItemsWithTags": "Block items with tags:",
- "LabelTag": "Tag:"
+ "LabelTag": "Tag:",
+ "LabelEnableSingleImageInDidlLimit": "Limit to single embedded image",
+ "LabelEnableSingleImageInDidlLimitHelp": "Some devices will not render properly if multiple images are embedded within Didl.",
+ "TabActivity": "Activity",
+ "TitleSync": "Sync"
}
diff --git a/MediaBrowser.Server.Implementations/Localization/Server/sv.json b/MediaBrowser.Server.Implementations/Localization/Server/sv.json
index 96c059ba9f..47bd0edab9 100644
--- a/MediaBrowser.Server.Implementations/Localization/Server/sv.json
+++ b/MediaBrowser.Server.Implementations/Localization/Server/sv.json
@@ -539,7 +539,7 @@
"HeaderRunningTasks": "P\u00e5g\u00e5ende aktiviteter",
"HeaderActiveDevices": "Aktiva enheter",
"HeaderPendingInstallations": "V\u00e4ntande installationer",
- "HeaerServerInformation": "Serverinformation",
+ "HeaderServerInformation": "Server Information",
"ButtonRestartNow": "Starta om nu",
"ButtonRestart": "Starta om",
"ButtonShutdown": "St\u00e4ng av",
@@ -1275,5 +1275,9 @@
"HeaderYears": "Years",
"HeaderAddTag": "Add Tag",
"LabelBlockItemsWithTags": "Block items with tags:",
- "LabelTag": "Tag:"
+ "LabelTag": "Tag:",
+ "LabelEnableSingleImageInDidlLimit": "Limit to single embedded image",
+ "LabelEnableSingleImageInDidlLimitHelp": "Some devices will not render properly if multiple images are embedded within Didl.",
+ "TabActivity": "Activity",
+ "TitleSync": "Sync"
} \ No newline at end of file
diff --git a/MediaBrowser.Server.Implementations/Localization/Server/tr.json b/MediaBrowser.Server.Implementations/Localization/Server/tr.json
index edaeb8d9ca..7b2c6fd1cf 100644
--- a/MediaBrowser.Server.Implementations/Localization/Server/tr.json
+++ b/MediaBrowser.Server.Implementations/Localization/Server/tr.json
@@ -539,7 +539,7 @@
"HeaderRunningTasks": "Running Tasks",
"HeaderActiveDevices": "Active Devices",
"HeaderPendingInstallations": "Pending Installations",
- "HeaerServerInformation": "Sunucu bilgisi",
+ "HeaderServerInformation": "Server Information",
"ButtonRestartNow": "Restart Now",
"ButtonRestart": "Restart",
"ButtonShutdown": "Shutdown",
@@ -1275,5 +1275,9 @@
"HeaderYears": "Years",
"HeaderAddTag": "Add Tag",
"LabelBlockItemsWithTags": "Block items with tags:",
- "LabelTag": "Tag:"
+ "LabelTag": "Tag:",
+ "LabelEnableSingleImageInDidlLimit": "Limit to single embedded image",
+ "LabelEnableSingleImageInDidlLimitHelp": "Some devices will not render properly if multiple images are embedded within Didl.",
+ "TabActivity": "Activity",
+ "TitleSync": "Sync"
} \ No newline at end of file
diff --git a/MediaBrowser.Server.Implementations/Localization/Server/vi.json b/MediaBrowser.Server.Implementations/Localization/Server/vi.json
index dc9b093646..687faab0e2 100644
--- a/MediaBrowser.Server.Implementations/Localization/Server/vi.json
+++ b/MediaBrowser.Server.Implementations/Localization/Server/vi.json
@@ -539,7 +539,7 @@
"HeaderRunningTasks": "Running Tasks",
"HeaderActiveDevices": "Active Devices",
"HeaderPendingInstallations": "Pending Installations",
- "HeaerServerInformation": "Server Information",
+ "HeaderServerInformation": "Server Information",
"ButtonRestartNow": "Restart Now",
"ButtonRestart": "Restart",
"ButtonShutdown": "Shutdown",
@@ -1275,5 +1275,9 @@
"HeaderYears": "Years",
"HeaderAddTag": "Add Tag",
"LabelBlockItemsWithTags": "Block items with tags:",
- "LabelTag": "Tag:"
+ "LabelTag": "Tag:",
+ "LabelEnableSingleImageInDidlLimit": "Limit to single embedded image",
+ "LabelEnableSingleImageInDidlLimitHelp": "Some devices will not render properly if multiple images are embedded within Didl.",
+ "TabActivity": "Activity",
+ "TitleSync": "Sync"
} \ No newline at end of file
diff --git a/MediaBrowser.Server.Implementations/Localization/Server/zh_CN.json b/MediaBrowser.Server.Implementations/Localization/Server/zh_CN.json
index 204bd93305..15324d40f6 100644
--- a/MediaBrowser.Server.Implementations/Localization/Server/zh_CN.json
+++ b/MediaBrowser.Server.Implementations/Localization/Server/zh_CN.json
@@ -539,7 +539,7 @@
"HeaderRunningTasks": "\u8fd0\u884c\u7684\u4efb\u52a1",
"HeaderActiveDevices": "\u6d3b\u52a8\u7684\u8bbe\u5907",
"HeaderPendingInstallations": "\u7b49\u5f85\u5b89\u88c5",
- "HeaerServerInformation": "\u670d\u52a1\u5668\u4fe1\u606f",
+ "HeaderServerInformation": "Server Information",
"ButtonRestartNow": "\u73b0\u5728\u91cd\u542f",
"ButtonRestart": "\u91cd\u542f",
"ButtonShutdown": "\u5173\u673a",
@@ -1275,5 +1275,9 @@
"HeaderYears": "Years",
"HeaderAddTag": "Add Tag",
"LabelBlockItemsWithTags": "Block items with tags:",
- "LabelTag": "Tag:"
+ "LabelTag": "Tag:",
+ "LabelEnableSingleImageInDidlLimit": "Limit to single embedded image",
+ "LabelEnableSingleImageInDidlLimitHelp": "Some devices will not render properly if multiple images are embedded within Didl.",
+ "TabActivity": "Activity",
+ "TitleSync": "Sync"
} \ No newline at end of file
diff --git a/MediaBrowser.Server.Implementations/Localization/Server/zh_TW.json b/MediaBrowser.Server.Implementations/Localization/Server/zh_TW.json
index 97fd408eb2..7f52d8d730 100644
--- a/MediaBrowser.Server.Implementations/Localization/Server/zh_TW.json
+++ b/MediaBrowser.Server.Implementations/Localization/Server/zh_TW.json
@@ -539,7 +539,7 @@
"HeaderRunningTasks": "Running Tasks",
"HeaderActiveDevices": "Active Devices",
"HeaderPendingInstallations": "Pending Installations",
- "HeaerServerInformation": "Server Information",
+ "HeaderServerInformation": "Server Information",
"ButtonRestartNow": "Restart Now",
"ButtonRestart": "Restart",
"ButtonShutdown": "Shutdown",
@@ -1275,5 +1275,9 @@
"HeaderYears": "Years",
"HeaderAddTag": "Add Tag",
"LabelBlockItemsWithTags": "Block items with tags:",
- "LabelTag": "Tag:"
+ "LabelTag": "Tag:",
+ "LabelEnableSingleImageInDidlLimit": "Limit to single embedded image",
+ "LabelEnableSingleImageInDidlLimitHelp": "Some devices will not render properly if multiple images are embedded within Didl.",
+ "TabActivity": "Activity",
+ "TitleSync": "Sync"
} \ No newline at end of file
diff --git a/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj b/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj
index 3abcf83b6b..514b7b1f1f 100644
--- a/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj
+++ b/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj
@@ -51,7 +51,7 @@
</Reference>
<Reference Include="MediaBrowser.Naming, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
- <HintPath>..\packages\MediaBrowser.Naming.1.0.0.12\lib\portable-net45+sl4+wp71+win8+wpa81\MediaBrowser.Naming.dll</HintPath>
+ <HintPath>..\packages\MediaBrowser.Naming.1.0.0.16\lib\portable-net45+sl4+wp71+win8+wpa81\MediaBrowser.Naming.dll</HintPath>
</Reference>
<Reference Include="Mono.Nat, Version=1.2.21.0, Culture=neutral, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
@@ -121,6 +121,7 @@
<Compile Include="Devices\DeviceManager.cs" />
<Compile Include="Devices\DeviceRepository.cs" />
<Compile Include="Devices\CameraUploadsFolder.cs" />
+ <Compile Include="Drawing\ImageExtensions.cs" />
<Compile Include="Drawing\ImageHeader.cs" />
<Compile Include="Drawing\PercentPlayedDrawer.cs" />
<Compile Include="Drawing\PlayedIndicatorDrawer.cs" />
@@ -178,9 +179,10 @@
<Compile Include="Intros\DefaultIntroProvider.cs" />
<Compile Include="IO\LibraryMonitor.cs" />
<Compile Include="Library\CoreResolutionIgnoreRule.cs" />
- <Compile Include="Library\EntityResolutionHelper.cs" />
<Compile Include="Library\LibraryManager.cs" />
+ <Compile Include="Library\LocalTrailerPostScanTask.cs" />
<Compile Include="Library\MusicManager.cs" />
+ <Compile Include="Library\PathExtensions.cs" />
<Compile Include="Library\Resolvers\BaseVideoResolver.cs" />
<Compile Include="Library\Resolvers\PhotoAlbumResolver.cs" />
<Compile Include="Library\Resolvers\PhotoResolver.cs" />
@@ -192,7 +194,6 @@
<Compile Include="Library\Resolvers\Audio\MusicArtistResolver.cs" />
<Compile Include="Library\Resolvers\ItemResolver.cs" />
<Compile Include="Library\Resolvers\FolderResolver.cs" />
- <Compile Include="Library\Resolvers\LocalTrailerResolver.cs" />
<Compile Include="Library\Resolvers\Movies\BoxSetResolver.cs" />
<Compile Include="Library\Resolvers\Movies\MovieResolver.cs" />
<Compile Include="Library\Resolvers\TV\EpisodeResolver.cs" />
@@ -302,8 +303,10 @@
<Compile Include="Sync\AppSyncProvider.cs" />
<Compile Include="Sync\CloudSyncProvider.cs" />
<Compile Include="Sync\MockSyncProvider.cs" />
+ <Compile Include="Sync\SyncJobProcessor.cs" />
<Compile Include="Sync\SyncManager.cs" />
<Compile Include="Sync\SyncRepository.cs" />
+ <Compile Include="Sync\SyncScheduledTask.cs" />
<Compile Include="Themes\AppThemeManager.cs" />
<Compile Include="TV\TVSeriesManager.cs" />
<Compile Include="Udp\UdpMessageReceivedEventArgs.cs" />
diff --git a/MediaBrowser.Server.Implementations/Playlists/ManualPlaylistsFolder.cs b/MediaBrowser.Server.Implementations/Playlists/ManualPlaylistsFolder.cs
index 3d0e36ead3..89395a00b5 100644
--- a/MediaBrowser.Server.Implementations/Playlists/ManualPlaylistsFolder.cs
+++ b/MediaBrowser.Server.Implementations/Playlists/ManualPlaylistsFolder.cs
@@ -18,7 +18,7 @@ namespace MediaBrowser.Server.Implementations.Playlists
{
return base.IsVisible(user) && GetRecursiveChildren(user, false)
.OfType<Playlist>()
- .Any(i => string.Equals(i.OwnerUserId, user.Id.ToString("N")));
+ .Any(i => i.IsVisible(user));
}
protected override IEnumerable<BaseItem> GetEligibleChildrenForRecursiveChildren(User user)
diff --git a/MediaBrowser.Server.Implementations/Playlists/PlaylistManager.cs b/MediaBrowser.Server.Implementations/Playlists/PlaylistManager.cs
index 852959312a..8da9ba2226 100644
--- a/MediaBrowser.Server.Implementations/Playlists/PlaylistManager.cs
+++ b/MediaBrowser.Server.Implementations/Playlists/PlaylistManager.cs
@@ -115,10 +115,15 @@ namespace MediaBrowser.Server.Implementations.Playlists
{
Name = name,
Parent = parentFolder,
- Path = path,
- OwnerUserId = options.UserId
+ Path = path
};
+ playlist.Shares.Add(new Share
+ {
+ UserId = options.UserId,
+ CanEdit = true
+ });
+
playlist.SetMediaType(options.MediaType);
await parentFolder.AddChild(playlist, CancellationToken.None).ConfigureAwait(false);
diff --git a/MediaBrowser.Server.Implementations/ScheduledTasks/RefreshMediaLibraryTask.cs b/MediaBrowser.Server.Implementations/ScheduledTasks/RefreshMediaLibraryTask.cs
index 97dfb2c5dd..0ac53c9878 100644
--- a/MediaBrowser.Server.Implementations/ScheduledTasks/RefreshMediaLibraryTask.cs
+++ b/MediaBrowser.Server.Implementations/ScheduledTasks/RefreshMediaLibraryTask.cs
@@ -12,7 +12,7 @@ namespace MediaBrowser.Server.Implementations.ScheduledTasks
/// <summary>
/// Class RefreshMediaLibraryTask
/// </summary>
- public class RefreshMediaLibraryTask : IScheduledTask
+ public class RefreshMediaLibraryTask : IScheduledTask, IHasKey
{
/// <summary>
/// The _library manager
@@ -88,5 +88,10 @@ namespace MediaBrowser.Server.Implementations.ScheduledTasks
return "Library";
}
}
+
+ public string Key
+ {
+ get { return "RefreshLibrary"; }
+ }
}
}
diff --git a/MediaBrowser.Server.Implementations/Sync/MockSyncProvider.cs b/MediaBrowser.Server.Implementations/Sync/MockSyncProvider.cs
index bc079ad809..7d29446b92 100644
--- a/MediaBrowser.Server.Implementations/Sync/MockSyncProvider.cs
+++ b/MediaBrowser.Server.Implementations/Sync/MockSyncProvider.cs
@@ -10,7 +10,7 @@ namespace MediaBrowser.Server.Implementations.Sync
{
public string Name
{
- get { return "Dummy Sync"; }
+ get { return "Test Sync"; }
}
public IEnumerable<SyncTarget> GetSyncTargets()
@@ -19,8 +19,8 @@ namespace MediaBrowser.Server.Implementations.Sync
{
new SyncTarget
{
- Id = "mock".GetMD5().ToString("N"),
- Name = "Mock Sync"
+ Id = GetType().Name.GetMD5().ToString("N"),
+ Name = Name
}
};
}
diff --git a/MediaBrowser.Server.Implementations/Sync/SyncJobProcessor.cs b/MediaBrowser.Server.Implementations/Sync/SyncJobProcessor.cs
new file mode 100644
index 0000000000..1976c05404
--- /dev/null
+++ b/MediaBrowser.Server.Implementations/Sync/SyncJobProcessor.cs
@@ -0,0 +1,395 @@
+using MediaBrowser.Controller.Entities;
+using MediaBrowser.Controller.Entities.Audio;
+using MediaBrowser.Controller.Library;
+using MediaBrowser.Controller.Sync;
+using MediaBrowser.Model.Dlna;
+using MediaBrowser.Model.Dto;
+using MediaBrowser.Model.Logging;
+using MediaBrowser.Model.MediaInfo;
+using MediaBrowser.Model.Session;
+using MediaBrowser.Model.Sync;
+using MoreLinq;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Threading;
+using System.Threading.Tasks;
+
+namespace MediaBrowser.Server.Implementations.Sync
+{
+ public class SyncJobProcessor
+ {
+ private readonly ILibraryManager _libraryManager;
+ private readonly ISyncRepository _syncRepo;
+ private readonly ISyncManager _syncManager;
+ private readonly ILogger _logger;
+ private readonly IUserManager _userManager;
+
+ public SyncJobProcessor(ILibraryManager libraryManager, ISyncRepository syncRepo, ISyncManager syncManager, ILogger logger, IUserManager userManager)
+ {
+ _libraryManager = libraryManager;
+ _syncRepo = syncRepo;
+ _syncManager = syncManager;
+ _logger = logger;
+ _userManager = userManager;
+ }
+
+ public void ProcessJobItem(SyncJob job, SyncJobItem jobItem, SyncTarget target)
+ {
+
+ }
+
+ public async Task EnsureJobItems(SyncJob job)
+ {
+ var user = _userManager.GetUserById(job.UserId);
+
+ if (user == null)
+ {
+ throw new InvalidOperationException("Cannot proceed with sync because user no longer exists.");
+ }
+
+ var items = GetItemsForSync(job.RequestedItemIds, user)
+ .ToList();
+
+ var jobItems = _syncRepo.GetJobItems(new SyncJobItemQuery
+ {
+ JobId = job.Id
+
+ }).Items.ToList();
+
+ foreach (var item in items)
+ {
+ var itemId = item.Id.ToString("N");
+
+ var jobItem = jobItems.FirstOrDefault(i => string.Equals(i.ItemId, itemId, StringComparison.OrdinalIgnoreCase));
+
+ if (jobItem != null)
+ {
+ continue;
+ }
+
+ jobItem = new SyncJobItem
+ {
+ Id = Guid.NewGuid().ToString("N"),
+ ItemId = itemId,
+ JobId = job.Id,
+ TargetId = job.TargetId,
+ DateCreated = DateTime.UtcNow
+ };
+
+ await _syncRepo.Create(jobItem).ConfigureAwait(false);
+
+ jobItems.Add(jobItem);
+ }
+
+ jobItems = jobItems
+ .OrderBy(i => i.DateCreated)
+ .ToList();
+
+ await UpdateJobStatus(job, jobItems).ConfigureAwait(false);
+ }
+
+ private Task UpdateJobStatus(SyncJob job)
+ {
+ if (job == null)
+ {
+ throw new ArgumentNullException("job");
+ }
+
+ var result = _syncRepo.GetJobItems(new SyncJobItemQuery
+ {
+ JobId = job.Id
+ });
+
+ return UpdateJobStatus(job, result.Items.ToList());
+ }
+
+ private Task UpdateJobStatus(SyncJob job, List<SyncJobItem> jobItems)
+ {
+ job.ItemCount = jobItems.Count;
+
+ double pct = 0;
+
+ foreach (var item in jobItems)
+ {
+ if (item.Status == SyncJobItemStatus.Failed || item.Status == SyncJobItemStatus.Completed)
+ {
+ pct += 100;
+ }
+ else
+ {
+ pct += item.Progress ?? 0;
+ }
+ }
+
+ if (job.ItemCount > 0)
+ {
+ pct /= job.ItemCount;
+ job.Progress = pct;
+ }
+ else
+ {
+ job.Progress = null;
+ }
+
+ if (pct >= 100)
+ {
+ if (jobItems.Any(i => i.Status == SyncJobItemStatus.Failed))
+ {
+ job.Status = SyncJobStatus.CompletedWithError;
+ }
+ else
+ {
+ job.Status = SyncJobStatus.Completed;
+ }
+ }
+ else if (pct.Equals(0))
+ {
+ job.Status = SyncJobStatus.Queued;
+ }
+ else
+ {
+ job.Status = SyncJobStatus.InProgress;
+ }
+
+ return _syncRepo.Update(job);
+ }
+
+ public IEnumerable<BaseItem> GetItemsForSync(IEnumerable<string> itemIds, User user)
+ {
+ return itemIds
+ .SelectMany(i => GetItemsForSync(i, user))
+ .Where(_syncManager.SupportsSync)
+ .DistinctBy(i => i.Id);
+ }
+
+ private IEnumerable<BaseItem> GetItemsForSync(string id, User user)
+ {
+ var item = _libraryManager.GetItemById(id);
+
+ if (item == null)
+ {
+ return new List<BaseItem>();
+ }
+
+ return GetItemsForSync(item, user);
+ }
+
+ private IEnumerable<BaseItem> GetItemsForSync(BaseItem item, User user)
+ {
+ var itemByName = item as IItemByName;
+ if (itemByName != null)
+ {
+ var items = user.RootFolder
+ .GetRecursiveChildren(user);
+
+ return itemByName.GetTaggedItems(items);
+ }
+
+ if (item.IsFolder)
+ {
+ var folder = (Folder)item;
+ var items = folder.GetRecursiveChildren(user);
+
+ items = items.Where(i => !i.IsFolder);
+
+ if (!folder.IsPreSorted)
+ {
+ items = items.OrderBy(i => i.SortName);
+ }
+
+ return items;
+ }
+
+ return new[] { item };
+ }
+
+ public async Task EnsureSyncJobs(CancellationToken cancellationToken)
+ {
+ var jobResult = _syncRepo.GetJobs(new SyncJobQuery
+ {
+ IsCompleted = false
+ });
+
+ foreach (var job in jobResult.Items)
+ {
+ cancellationToken.ThrowIfCancellationRequested();
+
+ if (job.SyncNewContent)
+ {
+ await EnsureJobItems(job).ConfigureAwait(false);
+ }
+ }
+ }
+
+ public async Task Sync(IProgress<double> progress, CancellationToken cancellationToken)
+ {
+ await EnsureSyncJobs(cancellationToken).ConfigureAwait(false);
+
+ var result = _syncRepo.GetJobItems(new SyncJobItemQuery
+ {
+ IsCompleted = false
+ });
+
+ var jobItems = result.Items;
+ var index = 0;
+
+ foreach (var item in jobItems)
+ {
+ double percent = index;
+ percent /= result.TotalRecordCount;
+
+ progress.Report(100 * percent);
+
+ cancellationToken.ThrowIfCancellationRequested();
+
+ if (item.Status == SyncJobItemStatus.Queued)
+ {
+ await ProcessJobItem(item, cancellationToken).ConfigureAwait(false);
+ }
+
+ var job = _syncRepo.GetJob(item.JobId);
+ await UpdateJobStatus(job).ConfigureAwait(false);
+
+ index++;
+ }
+ }
+
+ private async Task ProcessJobItem(SyncJobItem jobItem, CancellationToken cancellationToken)
+ {
+ var item = _libraryManager.GetItemById(jobItem.ItemId);
+ if (item == null)
+ {
+ jobItem.Status = SyncJobItemStatus.Failed;
+ _logger.Error("Unable to locate library item for JobItem {0}, ItemId {1}", jobItem.Id, jobItem.ItemId);
+ await _syncRepo.Update(jobItem).ConfigureAwait(false);
+ return;
+ }
+
+ var deviceProfile = _syncManager.GetDeviceProfile(jobItem.TargetId);
+ if (deviceProfile == null)
+ {
+ jobItem.Status = SyncJobItemStatus.Failed;
+ _logger.Error("Unable to locate SyncTarget for JobItem {0}, SyncTargetId {1}", jobItem.Id, jobItem.TargetId);
+ await _syncRepo.Update(jobItem).ConfigureAwait(false);
+ return;
+ }
+
+ jobItem.Progress = 0;
+ jobItem.Status = SyncJobItemStatus.Converting;
+
+ var video = item as Video;
+ if (video != null)
+ {
+ jobItem.OutputPath = await Sync(jobItem, video, deviceProfile, cancellationToken).ConfigureAwait(false);
+ }
+
+ else if (item is Audio)
+ {
+ jobItem.OutputPath = await Sync(jobItem, (Audio)item, deviceProfile, cancellationToken).ConfigureAwait(false);
+ }
+
+ else if (item is Photo)
+ {
+ jobItem.OutputPath = await Sync(jobItem, (Photo)item, deviceProfile, cancellationToken).ConfigureAwait(false);
+ }
+
+ else if (item is Game)
+ {
+ jobItem.OutputPath = await Sync(jobItem, (Game)item, deviceProfile, cancellationToken).ConfigureAwait(false);
+ }
+
+ else if (item is Book)
+ {
+ jobItem.OutputPath = await Sync(jobItem, (Book)item, deviceProfile, cancellationToken).ConfigureAwait(false);
+ }
+
+ jobItem.Progress = 50;
+ jobItem.Status = SyncJobItemStatus.Transferring;
+ await _syncRepo.Update(jobItem).ConfigureAwait(false);
+ }
+
+ private async Task<string> Sync(SyncJobItem jobItem, Video item, DeviceProfile profile, CancellationToken cancellationToken)
+ {
+ var options = new VideoOptions
+ {
+ Context = EncodingContext.Streaming,
+ ItemId = item.Id.ToString("N"),
+ DeviceId = jobItem.TargetId,
+ Profile = profile,
+ MediaSources = item.GetMediaSources(false).ToList()
+ };
+
+ var streamInfo = new StreamBuilder().BuildVideoItem(options);
+ var mediaSource = streamInfo.MediaSource;
+
+ if (streamInfo.PlayMethod != PlayMethod.Transcode)
+ {
+ if (mediaSource.Protocol == MediaProtocol.File)
+ {
+ return mediaSource.Path;
+ }
+ if (mediaSource.Protocol == MediaProtocol.Http)
+ {
+ return await DownloadFile(jobItem, mediaSource, cancellationToken).ConfigureAwait(false);
+ }
+ throw new InvalidOperationException(string.Format("Cannot direct stream {0} protocol", mediaSource.Protocol));
+ }
+
+ // TODO: Transcode
+ return mediaSource.Path;
+ }
+
+ private async Task<string> Sync(SyncJobItem jobItem, Audio item, DeviceProfile profile, CancellationToken cancellationToken)
+ {
+ var options = new AudioOptions
+ {
+ Context = EncodingContext.Streaming,
+ ItemId = item.Id.ToString("N"),
+ DeviceId = jobItem.TargetId,
+ Profile = profile,
+ MediaSources = item.GetMediaSources(false).ToList()
+ };
+
+ var streamInfo = new StreamBuilder().BuildAudioItem(options);
+ var mediaSource = streamInfo.MediaSource;
+
+ if (streamInfo.PlayMethod != PlayMethod.Transcode)
+ {
+ if (mediaSource.Protocol == MediaProtocol.File)
+ {
+ return mediaSource.Path;
+ }
+ if (mediaSource.Protocol == MediaProtocol.Http)
+ {
+ return await DownloadFile(jobItem, mediaSource, cancellationToken).ConfigureAwait(false);
+ }
+ throw new InvalidOperationException(string.Format("Cannot direct stream {0} protocol", mediaSource.Protocol));
+ }
+
+ // TODO: Transcode
+ return mediaSource.Path;
+ }
+
+ private async Task<string> Sync(SyncJobItem jobItem, Photo item, DeviceProfile profile, CancellationToken cancellationToken)
+ {
+ return item.Path;
+ }
+
+ private async Task<string> Sync(SyncJobItem jobItem, Game item, DeviceProfile profile, CancellationToken cancellationToken)
+ {
+ return item.Path;
+ }
+
+ private async Task<string> Sync(SyncJobItem jobItem, Book item, DeviceProfile profile, CancellationToken cancellationToken)
+ {
+ return item.Path;
+ }
+
+ private async Task<string> DownloadFile(SyncJobItem jobItem, MediaSourceInfo mediaSource, CancellationToken cancellationToken)
+ {
+ // TODO: Download
+ return mediaSource.Path;
+ }
+ }
+}
diff --git a/MediaBrowser.Server.Implementations/Sync/SyncManager.cs b/MediaBrowser.Server.Implementations/Sync/SyncManager.cs
index 263bfb6ad0..b3c7e6202e 100644
--- a/MediaBrowser.Server.Implementations/Sync/SyncManager.cs
+++ b/MediaBrowser.Server.Implementations/Sync/SyncManager.cs
@@ -1,11 +1,11 @@
-using System.IO;
-using MediaBrowser.Common.Extensions;
+using MediaBrowser.Common.Extensions;
using MediaBrowser.Controller.Drawing;
using MediaBrowser.Controller.Entities;
using MediaBrowser.Controller.Entities.Audio;
+using MediaBrowser.Controller.Entities.TV;
using MediaBrowser.Controller.Library;
using MediaBrowser.Controller.Sync;
-using MediaBrowser.Model.Devices;
+using MediaBrowser.Model.Dlna;
using MediaBrowser.Model.Entities;
using MediaBrowser.Model.Logging;
using MediaBrowser.Model.Querying;
@@ -24,15 +24,17 @@ namespace MediaBrowser.Server.Implementations.Sync
private readonly ISyncRepository _repo;
private readonly IImageProcessor _imageProcessor;
private readonly ILogger _logger;
+ private readonly IUserManager _userManager;
private ISyncProvider[] _providers = { };
- public SyncManager(ILibraryManager libraryManager, ISyncRepository repo, IImageProcessor imageProcessor, ILogger logger)
+ public SyncManager(ILibraryManager libraryManager, ISyncRepository repo, IImageProcessor imageProcessor, ILogger logger, IUserManager userManager)
{
_libraryManager = libraryManager;
_repo = repo;
_imageProcessor = imageProcessor;
_logger = logger;
+ _userManager = userManager;
}
public void AddParts(IEnumerable<ISyncProvider> providers)
@@ -42,11 +44,22 @@ namespace MediaBrowser.Server.Implementations.Sync
public async Task<SyncJobCreationResult> CreateJob(SyncJobRequest request)
{
- var items = GetItemsForSync(request.ItemIds).ToList();
+ var processor = new SyncJobProcessor(_libraryManager, _repo, this, _logger, _userManager);
- if (items.Count == 1)
+ var user = _userManager.GetUserById(request.UserId);
+
+ var items = processor
+ .GetItemsForSync(request.ItemIds, user)
+ .ToList();
+
+ if (items.Any(i => !SupportsSync(i)))
+ {
+ throw new ArgumentException("Item does not support sync.");
+ }
+
+ if (string.IsNullOrWhiteSpace(request.Name) && request.ItemIds.Count == 1)
{
- request.Name = GetDefaultName(items[0]);
+ request.Name = GetDefaultName(_libraryManager.GetItemById(request.ItemIds[0]));
}
if (string.IsNullOrWhiteSpace(request.Name))
@@ -66,16 +79,26 @@ namespace MediaBrowser.Server.Implementations.Sync
TargetId = target.Id,
UserId = request.UserId,
UnwatchedOnly = request.UnwatchedOnly,
- Limit = request.Limit,
- LimitType = request.LimitType,
+ ItemLimit = request.ItemLimit,
RequestedItemIds = request.ItemIds,
DateCreated = DateTime.UtcNow,
DateLastModified = DateTime.UtcNow,
- ItemCount = 1
+ SyncNewContent = request.SyncNewContent,
+ RemoveWhenWatched = request.RemoveWhenWatched,
+ ItemCount = items.Count,
+ Quality = request.Quality
};
+ // It's just a static list
+ if (!items.Any(i => i.IsFolder || i is IItemByName))
+ {
+ job.SyncNewContent = false;
+ }
+
await _repo.Create(job).ConfigureAwait(false);
+ await processor.EnsureJobItems(job).ConfigureAwait(false);
+
return new SyncJobCreationResult
{
Job = GetJob(jobId)
@@ -93,8 +116,9 @@ namespace MediaBrowser.Server.Implementations.Sync
private void FillMetadata(SyncJob job)
{
- var item = GetItemsForSync(job.RequestedItemIds)
- .FirstOrDefault();
+ var item = job.RequestedItemIds
+ .Select(_libraryManager.GetItemById)
+ .FirstOrDefault(i => i != null);
if (item != null)
{
@@ -130,7 +154,7 @@ namespace MediaBrowser.Server.Implementations.Sync
public Task CancelJob(string id)
{
- throw new NotImplementedException();
+ return _repo.DeleteJob(id);
}
public SyncJob GetJob(string id)
@@ -152,10 +176,15 @@ namespace MediaBrowser.Server.Implementations.Sync
return provider.GetSyncTargets().Select(i => new SyncTarget
{
Name = i.Name,
- Id = providerId + "-" + i.Id
+ Id = GetSyncTargetId(providerId, i)
});
}
+ private string GetSyncTargetId(string providerId, SyncTarget target)
+ {
+ return (providerId + "-" + target.Id).GetMD5().ToString("N");
+ }
+
private ISyncProvider GetSyncProvider(SyncTarget target)
{
var providerId = target.Id.Split(new[] { '-' }, 2).First();
@@ -165,75 +194,75 @@ namespace MediaBrowser.Server.Implementations.Sync
private string GetSyncProviderId(ISyncProvider provider)
{
- return (provider.GetType().Name + provider.Name).GetMD5().ToString("N");
+ return (provider.GetType().Name).GetMD5().ToString("N");
}
public bool SupportsSync(BaseItem item)
{
- if (item.LocationType == LocationType.Virtual)
+ if (string.Equals(item.MediaType, MediaType.Video, StringComparison.OrdinalIgnoreCase) ||
+ string.Equals(item.MediaType, MediaType.Audio, StringComparison.OrdinalIgnoreCase) ||
+ string.Equals(item.MediaType, MediaType.Photo, StringComparison.OrdinalIgnoreCase) ||
+ string.Equals(item.MediaType, MediaType.Game, StringComparison.OrdinalIgnoreCase) ||
+ string.Equals(item.MediaType, MediaType.Book, StringComparison.OrdinalIgnoreCase))
{
- return false;
- }
+ if (item.LocationType == LocationType.Virtual)
+ {
+ return false;
+ }
- if (string.Equals(item.MediaType, MediaType.Audio, StringComparison.OrdinalIgnoreCase) ||
- string.Equals(item.MediaType, MediaType.Video, StringComparison.OrdinalIgnoreCase))
- {
- if (item.RunTimeTicks.HasValue)
+ if (!item.RunTimeTicks.HasValue)
+ {
+ return false;
+ }
+
+ var video = item as Video;
+ if (video != null)
{
- var video = item as Video;
+ if (video.VideoType == VideoType.Iso)
+ {
+ return false;
+ }
- if (video != null)
+ if (video.IsStacked)
{
- if (video.VideoType != VideoType.VideoFile)
- {
- return false;
- }
-
- if (video.IsMultiPart)
- {
- return false;
- }
+ return false;
}
+ }
- return true;
+ var game = item as Game;
+ if (game != null)
+ {
+ if (game.IsMultiPart)
+ {
+ return false;
+ }
}
- return false;
+ return true;
}
- return false;
+ return item.LocationType == LocationType.FileSystem || item is Season;
}
- private IEnumerable<BaseItem> GetItemsForSync(IEnumerable<string> itemIds)
+ private string GetDefaultName(BaseItem item)
{
- return itemIds.SelectMany(GetItemsForSync).DistinctBy(i => i.Id);
+ return item.Name;
}
- private IEnumerable<BaseItem> GetItemsForSync(string id)
+ public DeviceProfile GetDeviceProfile(string targetId)
{
- var item = _libraryManager.GetItemById(id);
-
- if (item == null)
+ foreach (var provider in _providers)
{
- throw new ArgumentException("Item with Id " + id + " not found.");
- }
-
- if (!SupportsSync(item))
- {
- throw new ArgumentException("Item with Id " + id + " does not support sync.");
+ foreach (var target in GetSyncTargets(provider, null))
+ {
+ if (string.Equals(target.Id, targetId, StringComparison.OrdinalIgnoreCase))
+ {
+ return provider.GetDeviceProfile(target);
+ }
+ }
}
- return GetItemsForSync(item);
- }
-
- private IEnumerable<BaseItem> GetItemsForSync(BaseItem item)
- {
- return new[] { item };
- }
-
- private string GetDefaultName(BaseItem item)
- {
- return item.Name;
+ return null;
}
}
}
diff --git a/MediaBrowser.Server.Implementations/Sync/SyncRepository.cs b/MediaBrowser.Server.Implementations/Sync/SyncRepository.cs
index 65da74f9e5..c7ffbb27f3 100644
--- a/MediaBrowser.Server.Implementations/Sync/SyncRepository.cs
+++ b/MediaBrowser.Server.Implementations/Sync/SyncRepository.cs
@@ -23,6 +23,7 @@ namespace MediaBrowser.Server.Implementations.Sync
private readonly IServerApplicationPaths _appPaths;
private readonly CultureInfo _usCulture = new CultureInfo("en-US");
+ private IDbCommand _deleteJobCommand;
private IDbCommand _saveJobCommand;
private IDbCommand _saveJobItemCommand;
@@ -34,16 +35,16 @@ namespace MediaBrowser.Server.Implementations.Sync
public async Task Initialize()
{
- var dbFile = Path.Combine(_appPaths.DataPath, "sync.db");
+ var dbFile = Path.Combine(_appPaths.DataPath, "sync4.db");
_connection = await SqliteExtensions.ConnectToDb(dbFile, _logger).ConfigureAwait(false);
string[] queries = {
- "create table if not exists SyncJobs (Id GUID PRIMARY KEY, TargetId TEXT NOT NULL, Name TEXT NOT NULL, Quality TEXT NOT NULL, Status TEXT NOT NULL, Progress FLOAT, UserId TEXT NOT NULL, ItemIds TEXT NOT NULL, UnwatchedOnly BIT, SyncLimit BigInt, LimitType TEXT, IsDynamic BIT, DateCreated DateTime, DateLastModified DateTime, ItemCount int)",
+ "create table if not exists SyncJobs (Id GUID PRIMARY KEY, TargetId TEXT NOT NULL, Name TEXT NOT NULL, Quality TEXT NOT NULL, Status TEXT NOT NULL, Progress FLOAT, UserId TEXT NOT NULL, ItemIds TEXT NOT NULL, UnwatchedOnly BIT, ItemLimit INT, RemoveWhenWatched BIT, SyncNewContent BIT, DateCreated DateTime, DateLastModified DateTime, ItemCount int)",
"create index if not exists idx_SyncJobs on SyncJobs(Id)",
- "create table if not exists SyncJobItems (Id GUID PRIMARY KEY, ItemId TEXT, JobId TEXT, OutputPath TEXT, Status TEXT, TargetId TEXT)",
+ "create table if not exists SyncJobItems (Id GUID PRIMARY KEY, ItemId TEXT, JobId TEXT, OutputPath TEXT, Status TEXT, TargetId TEXT, DateCreated DateTime, Progress FLOAT)",
"create index if not exists idx_SyncJobItems on SyncJobs(Id)",
//pragmas
@@ -59,8 +60,12 @@ namespace MediaBrowser.Server.Implementations.Sync
private void PrepareStatements()
{
+ _deleteJobCommand = _connection.CreateCommand();
+ _deleteJobCommand.CommandText = "delete from SyncJobs where Id=@Id; delete from SyncJobItems where JobId=@Id";
+ _deleteJobCommand.Parameters.Add(_deleteJobCommand, "@Id");
+
_saveJobCommand = _connection.CreateCommand();
- _saveJobCommand.CommandText = "replace into SyncJobs (Id, TargetId, Name, Quality, Status, Progress, UserId, ItemIds, UnwatchedOnly, SyncLimit, LimitType, IsDynamic, DateCreated, DateLastModified, ItemCount) values (@Id, @TargetId, @Name, @Quality, @Status, @Progress, @UserId, @ItemIds, @UnwatchedOnly, @SyncLimit, @LimitType, @IsDynamic, @DateCreated, @DateLastModified, @ItemCount)";
+ _saveJobCommand.CommandText = "replace into SyncJobs (Id, TargetId, Name, Quality, Status, Progress, UserId, ItemIds, UnwatchedOnly, ItemLimit, RemoveWhenWatched, SyncNewContent, DateCreated, DateLastModified, ItemCount) values (@Id, @TargetId, @Name, @Quality, @Status, @Progress, @UserId, @ItemIds, @UnwatchedOnly, @ItemLimit, @RemoveWhenWatched, @SyncNewContent, @DateCreated, @DateLastModified, @ItemCount)";
_saveJobCommand.Parameters.Add(_saveJobCommand, "@Id");
_saveJobCommand.Parameters.Add(_saveJobCommand, "@TargetId");
@@ -71,25 +76,28 @@ namespace MediaBrowser.Server.Implementations.Sync
_saveJobCommand.Parameters.Add(_saveJobCommand, "@UserId");
_saveJobCommand.Parameters.Add(_saveJobCommand, "@ItemIds");
_saveJobCommand.Parameters.Add(_saveJobCommand, "@UnwatchedOnly");
- _saveJobCommand.Parameters.Add(_saveJobCommand, "@SyncLimit");
- _saveJobCommand.Parameters.Add(_saveJobCommand, "@LimitType");
- _saveJobCommand.Parameters.Add(_saveJobCommand, "@IsDynamic");
+ _saveJobCommand.Parameters.Add(_saveJobCommand, "@ItemLimit");
+ _saveJobCommand.Parameters.Add(_saveJobCommand, "@RemoveWhenWatched");
+ _saveJobCommand.Parameters.Add(_saveJobCommand, "@SyncNewContent");
_saveJobCommand.Parameters.Add(_saveJobCommand, "@DateCreated");
_saveJobCommand.Parameters.Add(_saveJobCommand, "@DateLastModified");
_saveJobCommand.Parameters.Add(_saveJobCommand, "@ItemCount");
_saveJobItemCommand = _connection.CreateCommand();
- _saveJobItemCommand.CommandText = "replace into SyncJobItems (Id, ItemId, JobId, OutputPath, Status, TargetId) values (@Id, @ItemId, @JobId, @OutputPath, @Status, @TargetId)";
+ _saveJobItemCommand.CommandText = "replace into SyncJobItems (Id, ItemId, JobId, OutputPath, Status, TargetId, DateCreated, Progress) values (@Id, @ItemId, @JobId, @OutputPath, @Status, @TargetId, @DateCreated, @Progress)";
_saveJobItemCommand.Parameters.Add(_saveJobCommand, "@Id");
_saveJobItemCommand.Parameters.Add(_saveJobCommand, "@ItemId");
_saveJobItemCommand.Parameters.Add(_saveJobCommand, "@JobId");
_saveJobItemCommand.Parameters.Add(_saveJobCommand, "@OutputPath");
_saveJobItemCommand.Parameters.Add(_saveJobCommand, "@Status");
+ _saveJobItemCommand.Parameters.Add(_saveJobCommand, "@TargetId");
+ _saveJobItemCommand.Parameters.Add(_saveJobCommand, "@DateCreated");
+ _saveJobItemCommand.Parameters.Add(_saveJobCommand, "@Progress");
}
- private const string BaseJobSelectText = "select Id, TargetId, Name, Quality, Status, Progress, UserId, ItemIds, UnwatchedOnly, SyncLimit, LimitType, IsDynamic, DateCreated, DateLastModified, ItemCount from SyncJobs";
- private const string BaseJobItemSelectText = "select Id, ItemId, JobId, OutputPath, Status, TargetId from SyncJobItems";
+ private const string BaseJobSelectText = "select Id, TargetId, Name, Quality, Status, Progress, UserId, ItemIds, UnwatchedOnly, ItemLimit, RemoveWhenWatched, SyncNewContent, DateCreated, DateLastModified, ItemCount from SyncJobs";
+ private const string BaseJobItemSelectText = "select Id, ItemId, JobId, OutputPath, Status, TargetId, DateCreated, Progress from SyncJobItems";
public SyncJob GetJob(string id)
{
@@ -100,6 +108,11 @@ namespace MediaBrowser.Server.Implementations.Sync
var guid = new Guid(id);
+ if (guid == Guid.Empty)
+ {
+ throw new ArgumentNullException("id");
+ }
+
using (var cmd = _connection.CreateCommand())
{
cmd.CommandText = BaseJobSelectText + " where Id=@Id";
@@ -159,15 +172,12 @@ namespace MediaBrowser.Server.Implementations.Sync
if (!reader.IsDBNull(9))
{
- info.Limit = reader.GetInt64(9);
+ info.ItemLimit = reader.GetInt32(9);
}
- if (!reader.IsDBNull(10))
- {
- info.LimitType = (SyncLimitType)Enum.Parse(typeof(SyncLimitType), reader.GetString(10), true);
- }
+ info.RemoveWhenWatched = reader.GetBoolean(10);
+ info.SyncNewContent = reader.GetBoolean(11);
- info.IsDynamic = reader.GetBoolean(11);
info.DateCreated = reader.GetDateTime(12).ToUniversalTime();
info.DateLastModified = reader.GetDateTime(13).ToUniversalTime();
info.ItemCount = reader.GetInt32(14);
@@ -206,9 +216,9 @@ namespace MediaBrowser.Server.Implementations.Sync
_saveJobCommand.GetParameter(index++).Value = job.UserId;
_saveJobCommand.GetParameter(index++).Value = string.Join(",", job.RequestedItemIds.ToArray());
_saveJobCommand.GetParameter(index++).Value = job.UnwatchedOnly;
- _saveJobCommand.GetParameter(index++).Value = job.Limit;
- _saveJobCommand.GetParameter(index++).Value = job.LimitType;
- _saveJobCommand.GetParameter(index++).Value = job.IsDynamic;
+ _saveJobCommand.GetParameter(index++).Value = job.ItemLimit;
+ _saveJobCommand.GetParameter(index++).Value = job.RemoveWhenWatched;
+ _saveJobCommand.GetParameter(index++).Value = job.SyncNewContent;
_saveJobCommand.GetParameter(index++).Value = job.DateCreated;
_saveJobCommand.GetParameter(index++).Value = job.DateLastModified;
_saveJobCommand.GetParameter(index++).Value = job.ItemCount;
@@ -250,6 +260,62 @@ namespace MediaBrowser.Server.Implementations.Sync
}
}
+ public async Task DeleteJob(string id)
+ {
+ if (string.IsNullOrWhiteSpace(id))
+ {
+ throw new ArgumentNullException("id");
+ }
+
+ await _writeLock.WaitAsync().ConfigureAwait(false);
+
+ IDbTransaction transaction = null;
+
+ try
+ {
+ transaction = _connection.BeginTransaction();
+
+ var index = 0;
+
+ _deleteJobCommand.GetParameter(index++).Value = new Guid(id);
+
+ _deleteJobCommand.Transaction = transaction;
+
+ _deleteJobCommand.ExecuteNonQuery();
+
+ transaction.Commit();
+ }
+ catch (OperationCanceledException)
+ {
+ if (transaction != null)
+ {
+ transaction.Rollback();
+ }
+
+ throw;
+ }
+ catch (Exception e)
+ {
+ _logger.ErrorException("Failed to save record:", e);
+
+ if (transaction != null)
+ {
+ transaction.Rollback();
+ }
+
+ throw;
+ }
+ finally
+ {
+ if (transaction != null)
+ {
+ transaction.Dispose();
+ }
+
+ _writeLock.Release();
+ }
+ }
+
public QueryResult<SyncJob> GetJobs(SyncJobQuery query)
{
if (query == null)
@@ -263,8 +329,24 @@ namespace MediaBrowser.Server.Implementations.Sync
var whereClauses = new List<string>();
- var startIndex = query.StartIndex ?? 0;
+ if (query.IsCompleted.HasValue)
+ {
+ if (query.IsCompleted.Value)
+ {
+ whereClauses.Add("Status=@Status");
+ }
+ else
+ {
+ whereClauses.Add("Status<>@Status");
+ }
+ cmd.Parameters.Add(cmd, "@Status", DbType.String).Value = SyncJobStatus.Completed.ToString();
+ }
+ var whereTextWithoutPaging = whereClauses.Count == 0 ?
+ string.Empty :
+ " where " + string.Join(" AND ", whereClauses.ToArray());
+
+ var startIndex = query.StartIndex ?? 0;
if (startIndex > 0)
{
whereClauses.Add(string.Format("Id NOT IN (SELECT Id FROM SyncJobs ORDER BY DateLastModified DESC LIMIT {0})",
@@ -283,7 +365,7 @@ namespace MediaBrowser.Server.Implementations.Sync
cmd.CommandText += " LIMIT " + query.Limit.Value.ToString(_usCulture);
}
- cmd.CommandText += "; select count (Id) from SyncJobs";
+ cmd.CommandText += "; select count (Id) from SyncJobs" + whereTextWithoutPaging;
var list = new List<SyncJob>();
var count = 0;
@@ -328,7 +410,7 @@ namespace MediaBrowser.Server.Implementations.Sync
{
if (reader.Read())
{
- return GetSyncJobItem(reader);
+ return GetJobItem(reader);
}
}
}
@@ -336,6 +418,87 @@ namespace MediaBrowser.Server.Implementations.Sync
return null;
}
+ public QueryResult<SyncJobItem> GetJobItems(SyncJobItemQuery query)
+ {
+ if (query == null)
+ {
+ throw new ArgumentNullException("query");
+ }
+
+ using (var cmd = _connection.CreateCommand())
+ {
+ cmd.CommandText = BaseJobItemSelectText;
+
+ var whereClauses = new List<string>();
+
+ if (!string.IsNullOrWhiteSpace(query.JobId))
+ {
+ whereClauses.Add("JobId=@JobId");
+ cmd.Parameters.Add(cmd, "@JobId", DbType.String).Value = query.JobId;
+ }
+
+ if (query.IsCompleted.HasValue)
+ {
+ if (query.IsCompleted.Value)
+ {
+ whereClauses.Add("Status=@Status");
+ }
+ else
+ {
+ whereClauses.Add("Status<>@Status");
+ }
+ cmd.Parameters.Add(cmd, "@Status", DbType.String).Value = SyncJobStatus.Completed.ToString();
+ }
+
+ var whereTextWithoutPaging = whereClauses.Count == 0 ?
+ string.Empty :
+ " where " + string.Join(" AND ", whereClauses.ToArray());
+
+ var startIndex = query.StartIndex ?? 0;
+ if (startIndex > 0)
+ {
+ whereClauses.Add(string.Format("Id NOT IN (SELECT Id FROM SyncJobItems ORDER BY DateCreated LIMIT {0})",
+ startIndex.ToString(_usCulture)));
+ }
+
+ if (whereClauses.Count > 0)
+ {
+ cmd.CommandText += " where " + string.Join(" AND ", whereClauses.ToArray());
+ }
+
+ cmd.CommandText += " ORDER BY DateCreated";
+
+ if (query.Limit.HasValue)
+ {
+ cmd.CommandText += " LIMIT " + query.Limit.Value.ToString(_usCulture);
+ }
+
+ cmd.CommandText += "; select count (Id) from SyncJobItems" + whereTextWithoutPaging;
+
+ var list = new List<SyncJobItem>();
+ var count = 0;
+
+ using (var reader = cmd.ExecuteReader(CommandBehavior.SequentialAccess))
+ {
+ while (reader.Read())
+ {
+ list.Add(GetJobItem(reader));
+ }
+
+ if (reader.NextResult() && reader.Read())
+ {
+ count = reader.GetInt32(0);
+ }
+ }
+
+ return new QueryResult<SyncJobItem>()
+ {
+ Items = list.ToArray(),
+ TotalRecordCount = count
+ };
+ }
+ }
+
public Task Create(SyncJobItem jobItem)
{
return Update(jobItem);
@@ -364,6 +527,8 @@ namespace MediaBrowser.Server.Implementations.Sync
_saveJobItemCommand.GetParameter(index++).Value = jobItem.OutputPath;
_saveJobItemCommand.GetParameter(index++).Value = jobItem.Status;
_saveJobItemCommand.GetParameter(index++).Value = jobItem.TargetId;
+ _saveJobItemCommand.GetParameter(index++).Value = jobItem.DateCreated;
+ _saveJobItemCommand.GetParameter(index++).Value = jobItem.Progress;
_saveJobItemCommand.Transaction = transaction;
@@ -402,7 +567,7 @@ namespace MediaBrowser.Server.Implementations.Sync
}
}
- private SyncJobItem GetSyncJobItem(IDataReader reader)
+ private SyncJobItem GetJobItem(IDataReader reader)
{
var info = new SyncJobItem
{
@@ -418,11 +583,18 @@ namespace MediaBrowser.Server.Implementations.Sync
if (!reader.IsDBNull(4))
{
- info.Status = (SyncJobStatus)Enum.Parse(typeof(SyncJobStatus), reader.GetString(4), true);
+ info.Status = (SyncJobItemStatus)Enum.Parse(typeof(SyncJobItemStatus), reader.GetString(4), true);
}
info.TargetId = reader.GetString(5);
+ info.DateCreated = reader.GetDateTime(6);
+
+ if (!reader.IsDBNull(7))
+ {
+ info.Progress = reader.GetDouble(7);
+ }
+
return info;
}
diff --git a/MediaBrowser.Server.Implementations/Sync/SyncScheduledTask.cs b/MediaBrowser.Server.Implementations/Sync/SyncScheduledTask.cs
new file mode 100644
index 0000000000..0199516806
--- /dev/null
+++ b/MediaBrowser.Server.Implementations/Sync/SyncScheduledTask.cs
@@ -0,0 +1,62 @@
+using MediaBrowser.Common.ScheduledTasks;
+using MediaBrowser.Controller.Library;
+using MediaBrowser.Controller.Sync;
+using MediaBrowser.Model.Logging;
+using System;
+using System.Collections.Generic;
+using System.Threading;
+using System.Threading.Tasks;
+
+namespace MediaBrowser.Server.Implementations.Sync
+{
+ public class SyncScheduledTask : IScheduledTask
+ {
+ private readonly ILibraryManager _libraryManager;
+ private readonly ISyncRepository _syncRepo;
+ private readonly ISyncManager _syncManager;
+ private readonly ILogger _logger;
+ private readonly IUserManager _userManager;
+
+ public SyncScheduledTask(ILibraryManager libraryManager, ISyncRepository syncRepo, ISyncManager syncManager, ILogger logger, IUserManager userManager)
+ {
+ _libraryManager = libraryManager;
+ _syncRepo = syncRepo;
+ _syncManager = syncManager;
+ _logger = logger;
+ _userManager = userManager;
+ }
+
+ public string Name
+ {
+ get { return "Sync"; }
+ }
+
+ public string Description
+ {
+ get { return "Runs scheduled sync jobs"; }
+ }
+
+ public string Category
+ {
+ get
+ {
+ return "Library";
+ }
+ }
+
+ public Task Execute(CancellationToken cancellationToken, IProgress<double> progress)
+ {
+ return new SyncJobProcessor(_libraryManager, _syncRepo, _syncManager, _logger, _userManager).Sync(progress,
+ cancellationToken);
+ }
+
+ public IEnumerable<ITaskTrigger> GetDefaultTriggers()
+ {
+ return new ITaskTrigger[]
+ {
+ new IntervalTrigger { Interval = TimeSpan.FromHours(3) },
+ new StartupTrigger{ DelayMs = Convert.ToInt32(TimeSpan.FromMinutes(5).TotalMilliseconds)}
+ };
+ }
+ }
+}
diff --git a/MediaBrowser.Server.Implementations/packages.config b/MediaBrowser.Server.Implementations/packages.config
index 634e8a9794..0174526504 100644
--- a/MediaBrowser.Server.Implementations/packages.config
+++ b/MediaBrowser.Server.Implementations/packages.config
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
- <package id="MediaBrowser.Naming" version="1.0.0.12" targetFramework="net45" />
+ <package id="MediaBrowser.Naming" version="1.0.0.16" targetFramework="net45" />
<package id="Mono.Nat" version="1.2.21.0" targetFramework="net45" />
<package id="morelinq" version="1.1.0" targetFramework="net45" />
</packages> \ No newline at end of file
diff --git a/MediaBrowser.Server.Mac/readme.txt b/MediaBrowser.Server.Mac/readme.txt
new file mode 100644
index 0000000000..e0833ebbba
--- /dev/null
+++ b/MediaBrowser.Server.Mac/readme.txt
@@ -0,0 +1,13 @@
+Instructions for deploying a new build:
+
+1. Download source code
+
+2. In resources folder, remove dashboard-ui, then re-add from the WebDashboard project, making sure to link the files, rather than copy. This will pick up any web client changes since the last deployment.
+
+3. Repeat the process for swagger-ui, if ServiceStack has been updated since the last release. If in doubt, just do it.
+
+4. Commit and push the changes to the Mac project
+
+5. Build the installer
+
+6. Proceed as normal and tag the builds in github \ No newline at end of file
diff --git a/MediaBrowser.Server.Startup.Common/ApplicationHost.cs b/MediaBrowser.Server.Startup.Common/ApplicationHost.cs
index 7360f1915d..1d69cd3252 100644
--- a/MediaBrowser.Server.Startup.Common/ApplicationHost.cs
+++ b/MediaBrowser.Server.Startup.Common/ApplicationHost.cs
@@ -346,6 +346,7 @@ namespace MediaBrowser.Server.Startup.Common
new RenameXbmcOptions(ServerConfigurationManager).Run();
new RenameXmlOptions(ServerConfigurationManager).Run();
new DeprecatePlugins(ApplicationPaths).Run();
+ new DeleteDlnaProfiles(ApplicationPaths).Run();
}
/// <summary>
@@ -389,8 +390,8 @@ namespace MediaBrowser.Server.Startup.Common
AuthenticationRepository = await GetAuthenticationRepository().ConfigureAwait(false);
RegisterSingleInstance(AuthenticationRepository);
- //SyncRepository = await GetSyncRepository().ConfigureAwait(false);
- //RegisterSingleInstance(SyncRepository);
+ SyncRepository = await GetSyncRepository().ConfigureAwait(false);
+ RegisterSingleInstance(SyncRepository);
UserManager = new UserManager(LogManager.GetLogger("UserManager"), ServerConfigurationManager, UserRepository, XmlSerializer, NetworkManager, () => ImageProcessor, () => DtoService, () => ConnectManager, this);
RegisterSingleInstance(UserManager);
@@ -428,7 +429,7 @@ namespace MediaBrowser.Server.Startup.Common
ImageProcessor = new ImageProcessor(LogManager.GetLogger("ImageProcessor"), ServerConfigurationManager.ApplicationPaths, FileSystemManager, JsonSerializer, MediaEncoder);
RegisterSingleInstance(ImageProcessor);
- SyncManager = new SyncManager(LibraryManager, SyncRepository, ImageProcessor, LogManager.GetLogger("SyncManager"));
+ SyncManager = new SyncManager(LibraryManager, SyncRepository, ImageProcessor, LogManager.GetLogger("SyncManager"), UserManager);
RegisterSingleInstance(SyncManager);
DtoService = new DtoService(Logger, LibraryManager, UserDataManager, ItemRepository, ImageProcessor, ServerConfigurationManager, FileSystemManager, ProviderManager, () => ChannelManager, SyncManager, this);
@@ -446,7 +447,7 @@ namespace MediaBrowser.Server.Startup.Common
SessionManager = new SessionManager(UserDataManager, ServerConfigurationManager, Logger, UserRepository, LibraryManager, UserManager, musicManager, DtoService, ImageProcessor, ItemRepository, JsonSerializer, this, HttpClient, AuthenticationRepository, DeviceManager);
RegisterSingleInstance(SessionManager);
- var newsService = new Server.Implementations.News.NewsService(ApplicationPaths, JsonSerializer);
+ var newsService = new Implementations.News.NewsService(ApplicationPaths, JsonSerializer);
RegisterSingleInstance<INewsService>(newsService);
var fileOrganizationService = new FileOrganizationService(TaskManager, FileOrganizationRepository, LogManager.GetLogger("FileOrganizationService"), LibraryMonitor, LibraryManager, ServerConfigurationManager, FileSystemManager, ProviderManager);
@@ -481,7 +482,7 @@ namespace MediaBrowser.Server.Startup.Common
UserViewManager = new UserViewManager(LibraryManager, LocalizationManager, FileSystemManager, UserManager, ChannelManager, LiveTvManager, ApplicationPaths, playlistManager);
RegisterSingleInstance(UserViewManager);
- var contentDirectory = new ContentDirectory(dlnaManager, UserDataManager, ImageProcessor, LibraryManager, ServerConfigurationManager, UserManager, LogManager.GetLogger("UpnpContentDirectory"), HttpClient, LocalizationManager);
+ var contentDirectory = new ContentDirectory(dlnaManager, UserDataManager, ImageProcessor, LibraryManager, ServerConfigurationManager, UserManager, LogManager.GetLogger("UpnpContentDirectory"), HttpClient, LocalizationManager, ChannelManager);
RegisterSingleInstance<IContentDirectory>(contentDirectory);
NotificationManager = new NotificationManager(LogManager, UserManager, ServerConfigurationManager);
@@ -950,11 +951,6 @@ namespace MediaBrowser.Server.Startup.Common
var localAddresses = NetworkManager.GetLocalIpAddresses()
.ToList();
- if (localAddresses.Count < 2)
- {
- return localAddresses;
- }
-
var httpServerAddresses = HttpServer.LocalEndPoints
.Select(i => i.Split(':').FirstOrDefault())
.Where(i => !string.IsNullOrEmpty(i))
@@ -967,7 +963,7 @@ namespace MediaBrowser.Server.Startup.Common
if (matchedAddresses.Count == 0)
{
- return localAddresses.Take(1);
+ return localAddresses;
}
return matchedAddresses;
diff --git a/MediaBrowser.Server.Startup.Common/MediaBrowser.Server.Startup.Common.csproj b/MediaBrowser.Server.Startup.Common/MediaBrowser.Server.Startup.Common.csproj
index db525e8e45..b133f78e74 100644
--- a/MediaBrowser.Server.Startup.Common/MediaBrowser.Server.Startup.Common.csproj
+++ b/MediaBrowser.Server.Startup.Common/MediaBrowser.Server.Startup.Common.csproj
@@ -63,6 +63,7 @@
<Compile Include="FFMpeg\FFMpegInfo.cs" />
<Compile Include="FFMpeg\FFmpegValidator.cs" />
<Compile Include="INativeApp.cs" />
+ <Compile Include="Migrations\DeleteDlnaProfiles.cs" />
<Compile Include="Migrations\DeprecatePlugins.cs" />
<Compile Include="Migrations\IVersionMigration.cs" />
<Compile Include="Migrations\MigrateUserFolders.cs" />
diff --git a/MediaBrowser.Server.Startup.Common/Migrations/DeleteDlnaProfiles.cs b/MediaBrowser.Server.Startup.Common/Migrations/DeleteDlnaProfiles.cs
new file mode 100644
index 0000000000..8fe841ffce
--- /dev/null
+++ b/MediaBrowser.Server.Startup.Common/Migrations/DeleteDlnaProfiles.cs
@@ -0,0 +1,42 @@
+using MediaBrowser.Controller;
+using System.IO;
+
+namespace MediaBrowser.Server.Startup.Common.Migrations
+{
+ public class DeleteDlnaProfiles : IVersionMigration
+ {
+ private readonly IServerApplicationPaths _appPaths;
+
+ public DeleteDlnaProfiles(IServerApplicationPaths appPaths)
+ {
+ _appPaths = appPaths;
+ }
+
+ public void Run()
+ {
+ RemoveProfile("Android");
+ RemoveProfile("Windows Phone");
+ RemoveProfile("Windows 8 RT");
+ }
+
+ private void RemoveProfile(string filename)
+ {
+ try
+ {
+ File.Delete(Path.Combine(_appPaths.ConfigurationDirectoryPath, "dlna", "system", filename + ".xml"));
+ }
+ catch
+ {
+
+ }
+ try
+ {
+ File.Delete(Path.Combine(_appPaths.ConfigurationDirectoryPath, "dlna", "user", filename + ".xml"));
+ }
+ catch
+ {
+
+ }
+ }
+ }
+}
diff --git a/MediaBrowser.ServerApplication/App.config b/MediaBrowser.ServerApplication/App.config
index 8fef47d73f..94dd9ee733 100644
--- a/MediaBrowser.ServerApplication/App.config
+++ b/MediaBrowser.ServerApplication/App.config
@@ -12,7 +12,7 @@
<targets async="true"></targets>
</nlog>
<appSettings>
- <add key="DebugProgramDataPath" value="..\..\..\..\ProgramData-Server" />
+ <add key="DebugProgramDataPath" value="..\..\..\ProgramData-Server" />
<add key="ReleaseProgramDataPath" value="%ApplicationData%\MediaBrowser-Server" />
<add key="ClientSettingsProvider.ServiceUri" value="" />
</appSettings>
diff --git a/MediaBrowser.Tests/Dlna/StreamBuilderTests.cs b/MediaBrowser.Tests/Dlna/StreamBuilderTests.cs
deleted file mode 100644
index d2a579838b..0000000000
--- a/MediaBrowser.Tests/Dlna/StreamBuilderTests.cs
+++ /dev/null
@@ -1,78 +0,0 @@
-using MediaBrowser.Model.Dlna;
-using MediaBrowser.Model.Dlna.Profiles;
-using MediaBrowser.Model.Dto;
-using MediaBrowser.Model.Entities;
-using Microsoft.VisualStudio.TestTools.UnitTesting;
-using System;
-using System.Collections.Generic;
-
-namespace MediaBrowser.Tests.Dlna
-{
- [TestClass]
- public class StreamBuilderTests
- {
- [TestMethod]
- public void TestVideoProfile()
- {
- var profile = new AndroidProfile(true, false, new[]
- {
- "high",
- "baseline",
- "constrained baseline"
- });
-
- var builder = new StreamBuilder();
-
- var mediaSources = new List<MediaSourceInfo>
- {
- new MediaSourceInfo
- {
- Bitrate = 6200000,
- Container = "mkv",
- Path= "\\server\\test.mkv",
- Protocol = Model.MediaInfo.MediaProtocol.File,
- RunTimeTicks = TimeSpan.FromMinutes(60).Ticks,
- VideoType = VideoType.VideoFile,
- Type = MediaSourceType.Default,
- MediaStreams = new List<MediaStream>
- {
- new MediaStream
- {
- Codec = "H264",
- Type = MediaStreamType.Video,
- Profile = "High",
- IsCabac = true
- },
- new MediaStream
- {
- Codec = "AC3",
- Type = MediaStreamType.Audio
- }
- }
- }
- };
-
- var options = new VideoOptions
- {
- Context = EncodingContext.Streaming,
- DeviceId = Guid.NewGuid().ToString(),
- ItemId = Guid.NewGuid().ToString(),
- Profile = profile,
- MediaSources = mediaSources
- };
-
- var streamInfo = builder.BuildVideoItem(options);
-
- var url = streamInfo.ToDlnaUrl("http://localhost:8096");
-
- var containsHighProfile = url.IndexOf(";high;", StringComparison.OrdinalIgnoreCase) != -1;
- var containsBaseline = url.IndexOf(";baseline;", StringComparison.OrdinalIgnoreCase) != -1;
-
- Assert.IsTrue(containsHighProfile);
- Assert.IsFalse(containsBaseline);
-
- var isHls = url.IndexOf("master.m3u8?", StringComparison.OrdinalIgnoreCase) != -1;
- Assert.IsTrue(isHls);
- }
- }
-}
diff --git a/MediaBrowser.Tests/MediaBrowser.Tests.csproj b/MediaBrowser.Tests/MediaBrowser.Tests.csproj
index b4755e9c5a..f93a2612ac 100644
--- a/MediaBrowser.Tests/MediaBrowser.Tests.csproj
+++ b/MediaBrowser.Tests/MediaBrowser.Tests.csproj
@@ -50,7 +50,6 @@
</Otherwise>
</Choose>
<ItemGroup>
- <Compile Include="Dlna\StreamBuilderTests.cs" />
<Compile Include="MediaEncoding\Subtitles\AssParserTests.cs" />
<Compile Include="MediaEncoding\Subtitles\SrtParserTests.cs" />
<Compile Include="MediaEncoding\Subtitles\VttWriterTest.cs" />
diff --git a/MediaBrowser.WebDashboard/Api/PackageCreator.cs b/MediaBrowser.WebDashboard/Api/PackageCreator.cs
index 39fcce57d7..b3a1bf84a8 100644
--- a/MediaBrowser.WebDashboard/Api/PackageCreator.cs
+++ b/MediaBrowser.WebDashboard/Api/PackageCreator.cs
@@ -354,7 +354,6 @@ namespace MediaBrowser.WebDashboard.Api
"connectlogin.js",
"dashboardgeneral.js",
"dashboardpage.js",
- "dashboardsync.js",
"device.js",
"devices.js",
"devicesupload.js",
@@ -451,6 +450,8 @@ namespace MediaBrowser.WebDashboard.Api
"songs.js",
"supporterkeypage.js",
"supporterpage.js",
+ "syncactivity.js",
+ "syncsettings.js",
"episodes.js",
"thememediaplayer.js",
"tvgenres.js",
diff --git a/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj b/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj
index 6b872d55fe..d8e6561ab1 100644
--- a/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj
+++ b/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj
@@ -102,6 +102,9 @@
<Content Include="dashboard-ui\scripts\selectserver.js">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
+ <Content Include="dashboard-ui\scripts\syncsettings.js">
+ <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
+ </Content>
<Content Include="dashboard-ui\scripts\usernew.js">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
@@ -111,6 +114,9 @@
<Content Include="dashboard-ui\selectserver.html">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
+ <Content Include="dashboard-ui\syncsettings.html">
+ <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
+ </Content>
<Content Include="dashboard-ui\thirdparty\apiclient\connectservice.js">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
@@ -399,7 +405,7 @@
<Content Include="dashboard-ui\dashboardgeneral.html">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
- <Content Include="dashboard-ui\dashboardsync.html">
+ <Content Include="dashboard-ui\syncactivity.html">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="dashboard-ui\device.html">
@@ -735,7 +741,7 @@
<Content Include="dashboard-ui\scripts\dashboardgeneral.js">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
- <Content Include="dashboard-ui\scripts\dashboardsync.js">
+ <Content Include="dashboard-ui\scripts\syncactivity.js">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="dashboard-ui\scripts\device.js">
diff --git a/MediaBrowser.XbmcMetadata/Images/XbmcImageSaver.cs b/MediaBrowser.XbmcMetadata/Images/XbmcImageSaver.cs
index 6071db6b5a..054a7eabbe 100644
--- a/MediaBrowser.XbmcMetadata/Images/XbmcImageSaver.cs
+++ b/MediaBrowser.XbmcMetadata/Images/XbmcImageSaver.cs
@@ -1,8 +1,8 @@
-using MediaBrowser.Controller.Drawing;
-using MediaBrowser.Controller.Entities;
+using MediaBrowser.Controller.Entities;
using MediaBrowser.Controller.Entities.Audio;
using MediaBrowser.Controller.Entities.TV;
using MediaBrowser.Controller.Providers;
+using MediaBrowser.Model.Drawing;
using MediaBrowser.Model.Entities;
using System;
using System.Collections.Generic;
@@ -252,7 +252,7 @@ namespace MediaBrowser.XbmcMetadata.Images
{
return zeroIndexFilename;
}
-
+
var filenames = images.Select(i => Path.GetFileNameWithoutExtension(i.Path)).ToList();
var current = 1;
diff --git a/MediaBrowser.XbmcMetadata/Providers/BaseVideoNfoProvider.cs b/MediaBrowser.XbmcMetadata/Providers/BaseVideoNfoProvider.cs
index 36c2f66f53..8119c162c0 100644
--- a/MediaBrowser.XbmcMetadata/Providers/BaseVideoNfoProvider.cs
+++ b/MediaBrowser.XbmcMetadata/Providers/BaseVideoNfoProvider.cs
@@ -46,7 +46,7 @@ namespace MediaBrowser.XbmcMetadata.Providers
{
var path = item.Path;
- return Path.Combine(path, fileSystem.GetFileNameWithoutExtension(path) + ".nfo");
+ return Path.Combine(path, Path.GetFileName(path) + ".nfo");
}
return Path.ChangeExtension(item.Path, ".nfo");
diff --git a/MediaBrowser.XbmcMetadata/Providers/MovieNfoProvider.cs b/MediaBrowser.XbmcMetadata/Providers/MovieNfoProvider.cs
index 1b979c3789..6c9949fc2f 100644
--- a/MediaBrowser.XbmcMetadata/Providers/MovieNfoProvider.cs
+++ b/MediaBrowser.XbmcMetadata/Providers/MovieNfoProvider.cs
@@ -26,13 +26,4 @@ namespace MediaBrowser.XbmcMetadata.Providers
{
}
}
-
- public class TrailerNfoProvider : BaseVideoNfoProvider<Trailer>
- {
- public TrailerNfoProvider(IFileSystem fileSystem, ILogger logger, IConfigurationManager config)
- : base(fileSystem, logger, config)
- {
- }
- }
-
} \ No newline at end of file
diff --git a/MediaBrowser.XbmcMetadata/Savers/MovieNfoSaver.cs b/MediaBrowser.XbmcMetadata/Savers/MovieNfoSaver.cs
index 9313a4d154..bfb2b916ec 100644
--- a/MediaBrowser.XbmcMetadata/Savers/MovieNfoSaver.cs
+++ b/MediaBrowser.XbmcMetadata/Savers/MovieNfoSaver.cs
@@ -32,7 +32,7 @@ namespace MediaBrowser.XbmcMetadata.Savers
{
var path = item.ContainingFolderPath;
- return Path.Combine(path, fileSystem.GetFileNameWithoutExtension(path) + ".nfo");
+ return Path.Combine(path, Path.GetFileName(path) + ".nfo");
}
return Path.ChangeExtension(item.Path, ".nfo");
diff --git a/MediaBrowser.sln b/MediaBrowser.sln
index b04f445560..22c2fdc249 100644
--- a/MediaBrowser.sln
+++ b/MediaBrowser.sln
@@ -59,11 +59,6 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MediaBrowser.Server.Startup
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
- Debug_Ubuntu|Any CPU = Debug_Ubuntu|Any CPU
- Debug_Ubuntu|Mixed Platforms = Debug_Ubuntu|Mixed Platforms
- Debug_Ubuntu|Win32 = Debug_Ubuntu|Win32
- Debug_Ubuntu|x64 = Debug_Ubuntu|x64
- Debug_Ubuntu|x86 = Debug_Ubuntu|x86
Debug|Any CPU = Debug|Any CPU
Debug|Mixed Platforms = Debug|Mixed Platforms
Debug|Win32 = Debug|Win32
@@ -74,11 +69,6 @@ Global
Release Mono|Win32 = Release Mono|Win32
Release Mono|x64 = Release Mono|x64
Release Mono|x86 = Release Mono|x86
- Release_Ubuntu|Any CPU = Release_Ubuntu|Any CPU
- Release_Ubuntu|Mixed Platforms = Release_Ubuntu|Mixed Platforms
- Release_Ubuntu|Win32 = Release_Ubuntu|Win32
- Release_Ubuntu|x64 = Release_Ubuntu|x64
- Release_Ubuntu|x86 = Release_Ubuntu|x86
Release|Any CPU = Release|Any CPU
Release|Mixed Platforms = Release|Mixed Platforms
Release|Win32 = Release|Win32
@@ -86,13 +76,6 @@ Global
Release|x86 = Release|x86
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
- {17E1F4E6-8ABD-4FE5-9ECF-43D4B6087BA2}.Debug_Ubuntu|Any CPU.ActiveCfg = Debug|Any CPU
- {17E1F4E6-8ABD-4FE5-9ECF-43D4B6087BA2}.Debug_Ubuntu|Any CPU.Build.0 = Debug|Any CPU
- {17E1F4E6-8ABD-4FE5-9ECF-43D4B6087BA2}.Debug_Ubuntu|Mixed Platforms.ActiveCfg = Debug|Any CPU
- {17E1F4E6-8ABD-4FE5-9ECF-43D4B6087BA2}.Debug_Ubuntu|Mixed Platforms.Build.0 = Debug|Any CPU
- {17E1F4E6-8ABD-4FE5-9ECF-43D4B6087BA2}.Debug_Ubuntu|Win32.ActiveCfg = Debug|Any CPU
- {17E1F4E6-8ABD-4FE5-9ECF-43D4B6087BA2}.Debug_Ubuntu|x64.ActiveCfg = Debug|Any CPU
- {17E1F4E6-8ABD-4FE5-9ECF-43D4B6087BA2}.Debug_Ubuntu|x86.ActiveCfg = Debug|Any CPU
{17E1F4E6-8ABD-4FE5-9ECF-43D4B6087BA2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{17E1F4E6-8ABD-4FE5-9ECF-43D4B6087BA2}.Debug|Any CPU.Build.0 = Debug|Any CPU
{17E1F4E6-8ABD-4FE5-9ECF-43D4B6087BA2}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
@@ -108,13 +91,6 @@ Global
{17E1F4E6-8ABD-4FE5-9ECF-43D4B6087BA2}.Release Mono|Win32.ActiveCfg = Release Mono|Any CPU
{17E1F4E6-8ABD-4FE5-9ECF-43D4B6087BA2}.Release Mono|x64.ActiveCfg = Release Mono|Any CPU
{17E1F4E6-8ABD-4FE5-9ECF-43D4B6087BA2}.Release Mono|x86.ActiveCfg = Release Mono|Any CPU
- {17E1F4E6-8ABD-4FE5-9ECF-43D4B6087BA2}.Release_Ubuntu|Any CPU.ActiveCfg = Release Mono|Any CPU
- {17E1F4E6-8ABD-4FE5-9ECF-43D4B6087BA2}.Release_Ubuntu|Any CPU.Build.0 = Release Mono|Any CPU
- {17E1F4E6-8ABD-4FE5-9ECF-43D4B6087BA2}.Release_Ubuntu|Mixed Platforms.ActiveCfg = Release Mono|Any CPU
- {17E1F4E6-8ABD-4FE5-9ECF-43D4B6087BA2}.Release_Ubuntu|Mixed Platforms.Build.0 = Release Mono|Any CPU
- {17E1F4E6-8ABD-4FE5-9ECF-43D4B6087BA2}.Release_Ubuntu|Win32.ActiveCfg = Release Mono|Any CPU
- {17E1F4E6-8ABD-4FE5-9ECF-43D4B6087BA2}.Release_Ubuntu|x64.ActiveCfg = Release Mono|Any CPU
- {17E1F4E6-8ABD-4FE5-9ECF-43D4B6087BA2}.Release_Ubuntu|x86.ActiveCfg = Release Mono|Any CPU
{17E1F4E6-8ABD-4FE5-9ECF-43D4B6087BA2}.Release|Any CPU.ActiveCfg = Release|Any CPU
{17E1F4E6-8ABD-4FE5-9ECF-43D4B6087BA2}.Release|Any CPU.Build.0 = Release|Any CPU
{17E1F4E6-8ABD-4FE5-9ECF-43D4B6087BA2}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
@@ -123,13 +99,6 @@ Global
{17E1F4E6-8ABD-4FE5-9ECF-43D4B6087BA2}.Release|x64.ActiveCfg = Release|Any CPU
{17E1F4E6-8ABD-4FE5-9ECF-43D4B6087BA2}.Release|x86.ActiveCfg = Release|Any CPU
{17E1F4E6-8ABD-4FE5-9ECF-43D4B6087BA2}.Release|x86.Build.0 = Release|Any CPU
- {4FD51AC5-2C16-4308-A993-C3A84F3B4582}.Debug_Ubuntu|Any CPU.ActiveCfg = Debug|Any CPU
- {4FD51AC5-2C16-4308-A993-C3A84F3B4582}.Debug_Ubuntu|Any CPU.Build.0 = Debug|Any CPU
- {4FD51AC5-2C16-4308-A993-C3A84F3B4582}.Debug_Ubuntu|Mixed Platforms.ActiveCfg = Debug|Any CPU
- {4FD51AC5-2C16-4308-A993-C3A84F3B4582}.Debug_Ubuntu|Mixed Platforms.Build.0 = Debug|Any CPU
- {4FD51AC5-2C16-4308-A993-C3A84F3B4582}.Debug_Ubuntu|Win32.ActiveCfg = Debug|Any CPU
- {4FD51AC5-2C16-4308-A993-C3A84F3B4582}.Debug_Ubuntu|x64.ActiveCfg = Debug|Any CPU
- {4FD51AC5-2C16-4308-A993-C3A84F3B4582}.Debug_Ubuntu|x86.ActiveCfg = Debug|Any CPU
{4FD51AC5-2C16-4308-A993-C3A84F3B4582}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{4FD51AC5-2C16-4308-A993-C3A84F3B4582}.Debug|Any CPU.Build.0 = Debug|Any CPU
{4FD51AC5-2C16-4308-A993-C3A84F3B4582}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
@@ -145,13 +114,6 @@ Global
{4FD51AC5-2C16-4308-A993-C3A84F3B4582}.Release Mono|Win32.ActiveCfg = Release Mono|Any CPU
{4FD51AC5-2C16-4308-A993-C3A84F3B4582}.Release Mono|x64.ActiveCfg = Release Mono|Any CPU
{4FD51AC5-2C16-4308-A993-C3A84F3B4582}.Release Mono|x86.ActiveCfg = Release Mono|Any CPU
- {4FD51AC5-2C16-4308-A993-C3A84F3B4582}.Release_Ubuntu|Any CPU.ActiveCfg = Release Mono|Any CPU
- {4FD51AC5-2C16-4308-A993-C3A84F3B4582}.Release_Ubuntu|Any CPU.Build.0 = Release Mono|Any CPU
- {4FD51AC5-2C16-4308-A993-C3A84F3B4582}.Release_Ubuntu|Mixed Platforms.ActiveCfg = Release Mono|Any CPU
- {4FD51AC5-2C16-4308-A993-C3A84F3B4582}.Release_Ubuntu|Mixed Platforms.Build.0 = Release Mono|Any CPU
- {4FD51AC5-2C16-4308-A993-C3A84F3B4582}.Release_Ubuntu|Win32.ActiveCfg = Release Mono|Any CPU
- {4FD51AC5-2C16-4308-A993-C3A84F3B4582}.Release_Ubuntu|x64.ActiveCfg = Release Mono|Any CPU
- {4FD51AC5-2C16-4308-A993-C3A84F3B4582}.Release_Ubuntu|x86.ActiveCfg = Release Mono|Any CPU
{4FD51AC5-2C16-4308-A993-C3A84F3B4582}.Release|Any CPU.ActiveCfg = Release|Any CPU
{4FD51AC5-2C16-4308-A993-C3A84F3B4582}.Release|Any CPU.Build.0 = Release|Any CPU
{4FD51AC5-2C16-4308-A993-C3A84F3B4582}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
@@ -160,13 +122,6 @@ Global
{4FD51AC5-2C16-4308-A993-C3A84F3B4582}.Release|x64.ActiveCfg = Release|Any CPU
{4FD51AC5-2C16-4308-A993-C3A84F3B4582}.Release|x86.ActiveCfg = Release|Any CPU
{4FD51AC5-2C16-4308-A993-C3A84F3B4582}.Release|x86.Build.0 = Release|Any CPU
- {9142EEFA-7570-41E1-BFCC-468BB571AF2F}.Debug_Ubuntu|Any CPU.ActiveCfg = Debug|Any CPU
- {9142EEFA-7570-41E1-BFCC-468BB571AF2F}.Debug_Ubuntu|Any CPU.Build.0 = Debug|Any CPU
- {9142EEFA-7570-41E1-BFCC-468BB571AF2F}.Debug_Ubuntu|Mixed Platforms.ActiveCfg = Debug|Any CPU
- {9142EEFA-7570-41E1-BFCC-468BB571AF2F}.Debug_Ubuntu|Mixed Platforms.Build.0 = Debug|Any CPU
- {9142EEFA-7570-41E1-BFCC-468BB571AF2F}.Debug_Ubuntu|Win32.ActiveCfg = Debug|Any CPU
- {9142EEFA-7570-41E1-BFCC-468BB571AF2F}.Debug_Ubuntu|x64.ActiveCfg = Debug|Any CPU
- {9142EEFA-7570-41E1-BFCC-468BB571AF2F}.Debug_Ubuntu|x86.ActiveCfg = Debug|Any CPU
{9142EEFA-7570-41E1-BFCC-468BB571AF2F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{9142EEFA-7570-41E1-BFCC-468BB571AF2F}.Debug|Any CPU.Build.0 = Debug|Any CPU
{9142EEFA-7570-41E1-BFCC-468BB571AF2F}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
@@ -182,13 +137,6 @@ Global
{9142EEFA-7570-41E1-BFCC-468BB571AF2F}.Release Mono|Win32.ActiveCfg = Release Mono|Any CPU
{9142EEFA-7570-41E1-BFCC-468BB571AF2F}.Release Mono|x64.ActiveCfg = Release Mono|Any CPU
{9142EEFA-7570-41E1-BFCC-468BB571AF2F}.Release Mono|x86.ActiveCfg = Release Mono|Any CPU
- {9142EEFA-7570-41E1-BFCC-468BB571AF2F}.Release_Ubuntu|Any CPU.ActiveCfg = Release Mono|Any CPU
- {9142EEFA-7570-41E1-BFCC-468BB571AF2F}.Release_Ubuntu|Any CPU.Build.0 = Release Mono|Any CPU
- {9142EEFA-7570-41E1-BFCC-468BB571AF2F}.Release_Ubuntu|Mixed Platforms.ActiveCfg = Release Mono|Any CPU
- {9142EEFA-7570-41E1-BFCC-468BB571AF2F}.Release_Ubuntu|Mixed Platforms.Build.0 = Release Mono|Any CPU
- {9142EEFA-7570-41E1-BFCC-468BB571AF2F}.Release_Ubuntu|Win32.ActiveCfg = Release Mono|Any CPU
- {9142EEFA-7570-41E1-BFCC-468BB571AF2F}.Release_Ubuntu|x64.ActiveCfg = Release Mono|Any CPU
- {9142EEFA-7570-41E1-BFCC-468BB571AF2F}.Release_Ubuntu|x86.ActiveCfg = Release Mono|Any CPU
{9142EEFA-7570-41E1-BFCC-468BB571AF2F}.Release|Any CPU.ActiveCfg = Release|Any CPU
{9142EEFA-7570-41E1-BFCC-468BB571AF2F}.Release|Any CPU.Build.0 = Release|Any CPU
{9142EEFA-7570-41E1-BFCC-468BB571AF2F}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
@@ -197,13 +145,6 @@ Global
{9142EEFA-7570-41E1-BFCC-468BB571AF2F}.Release|x64.ActiveCfg = Release|Any CPU
{9142EEFA-7570-41E1-BFCC-468BB571AF2F}.Release|x86.ActiveCfg = Release|Any CPU
{9142EEFA-7570-41E1-BFCC-468BB571AF2F}.Release|x86.Build.0 = Release|Any CPU
- {7EEEB4BB-F3E8-48FC-B4C5-70F0FFF8329B}.Debug_Ubuntu|Any CPU.ActiveCfg = Debug|Any CPU
- {7EEEB4BB-F3E8-48FC-B4C5-70F0FFF8329B}.Debug_Ubuntu|Any CPU.Build.0 = Debug|Any CPU
- {7EEEB4BB-F3E8-48FC-B4C5-70F0FFF8329B}.Debug_Ubuntu|Mixed Platforms.ActiveCfg = Debug|Any CPU
- {7EEEB4BB-F3E8-48FC-B4C5-70F0FFF8329B}.Debug_Ubuntu|Mixed Platforms.Build.0 = Debug|Any CPU
- {7EEEB4BB-F3E8-48FC-B4C5-70F0FFF8329B}.Debug_Ubuntu|Win32.ActiveCfg = Debug|Any CPU
- {7EEEB4BB-F3E8-48FC-B4C5-70F0FFF8329B}.Debug_Ubuntu|x64.ActiveCfg = Debug|Any CPU
- {7EEEB4BB-F3E8-48FC-B4C5-70F0FFF8329B}.Debug_Ubuntu|x86.ActiveCfg = Debug|Any CPU
{7EEEB4BB-F3E8-48FC-B4C5-70F0FFF8329B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{7EEEB4BB-F3E8-48FC-B4C5-70F0FFF8329B}.Debug|Any CPU.Build.0 = Debug|Any CPU
{7EEEB4BB-F3E8-48FC-B4C5-70F0FFF8329B}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
@@ -219,13 +160,6 @@ Global
{7EEEB4BB-F3E8-48FC-B4C5-70F0FFF8329B}.Release Mono|Win32.ActiveCfg = Release Mono|Any CPU
{7EEEB4BB-F3E8-48FC-B4C5-70F0FFF8329B}.Release Mono|x64.ActiveCfg = Release Mono|Any CPU
{7EEEB4BB-F3E8-48FC-B4C5-70F0FFF8329B}.Release Mono|x86.ActiveCfg = Release Mono|Any CPU
- {7EEEB4BB-F3E8-48FC-B4C5-70F0FFF8329B}.Release_Ubuntu|Any CPU.ActiveCfg = Release Mono|Any CPU
- {7EEEB4BB-F3E8-48FC-B4C5-70F0FFF8329B}.Release_Ubuntu|Any CPU.Build.0 = Release Mono|Any CPU
- {7EEEB4BB-F3E8-48FC-B4C5-70F0FFF8329B}.Release_Ubuntu|Mixed Platforms.ActiveCfg = Release Mono|Any CPU
- {7EEEB4BB-F3E8-48FC-B4C5-70F0FFF8329B}.Release_Ubuntu|Mixed Platforms.Build.0 = Release Mono|Any CPU
- {7EEEB4BB-F3E8-48FC-B4C5-70F0FFF8329B}.Release_Ubuntu|Win32.ActiveCfg = Release Mono|Any CPU
- {7EEEB4BB-F3E8-48FC-B4C5-70F0FFF8329B}.Release_Ubuntu|x64.ActiveCfg = Release Mono|Any CPU
- {7EEEB4BB-F3E8-48FC-B4C5-70F0FFF8329B}.Release_Ubuntu|x86.ActiveCfg = Release Mono|Any CPU
{7EEEB4BB-F3E8-48FC-B4C5-70F0FFF8329B}.Release|Any CPU.ActiveCfg = Release|Any CPU
{7EEEB4BB-F3E8-48FC-B4C5-70F0FFF8329B}.Release|Any CPU.Build.0 = Release|Any CPU
{7EEEB4BB-F3E8-48FC-B4C5-70F0FFF8329B}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
@@ -234,13 +168,6 @@ Global
{7EEEB4BB-F3E8-48FC-B4C5-70F0FFF8329B}.Release|x64.ActiveCfg = Release|Any CPU
{7EEEB4BB-F3E8-48FC-B4C5-70F0FFF8329B}.Release|x86.ActiveCfg = Release|Any CPU
{7EEEB4BB-F3E8-48FC-B4C5-70F0FFF8329B}.Release|x86.Build.0 = Release|Any CPU
- {5624B7B5-B5A7-41D8-9F10-CC5611109619}.Debug_Ubuntu|Any CPU.ActiveCfg = Debug|Any CPU
- {5624B7B5-B5A7-41D8-9F10-CC5611109619}.Debug_Ubuntu|Any CPU.Build.0 = Debug|Any CPU
- {5624B7B5-B5A7-41D8-9F10-CC5611109619}.Debug_Ubuntu|Mixed Platforms.ActiveCfg = Debug|Any CPU
- {5624B7B5-B5A7-41D8-9F10-CC5611109619}.Debug_Ubuntu|Mixed Platforms.Build.0 = Debug|Any CPU
- {5624B7B5-B5A7-41D8-9F10-CC5611109619}.Debug_Ubuntu|Win32.ActiveCfg = Debug|Any CPU
- {5624B7B5-B5A7-41D8-9F10-CC5611109619}.Debug_Ubuntu|x64.ActiveCfg = Debug|Any CPU
- {5624B7B5-B5A7-41D8-9F10-CC5611109619}.Debug_Ubuntu|x86.ActiveCfg = Debug|Any CPU
{5624B7B5-B5A7-41D8-9F10-CC5611109619}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{5624B7B5-B5A7-41D8-9F10-CC5611109619}.Debug|Any CPU.Build.0 = Debug|Any CPU
{5624B7B5-B5A7-41D8-9F10-CC5611109619}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
@@ -256,13 +183,6 @@ Global
{5624B7B5-B5A7-41D8-9F10-CC5611109619}.Release Mono|Win32.ActiveCfg = Release Mono|Any CPU
{5624B7B5-B5A7-41D8-9F10-CC5611109619}.Release Mono|x64.ActiveCfg = Release Mono|Any CPU
{5624B7B5-B5A7-41D8-9F10-CC5611109619}.Release Mono|x86.ActiveCfg = Release Mono|Any CPU
- {5624B7B5-B5A7-41D8-9F10-CC5611109619}.Release_Ubuntu|Any CPU.ActiveCfg = Release Mono|Any CPU
- {5624B7B5-B5A7-41D8-9F10-CC5611109619}.Release_Ubuntu|Any CPU.Build.0 = Release Mono|Any CPU
- {5624B7B5-B5A7-41D8-9F10-CC5611109619}.Release_Ubuntu|Mixed Platforms.ActiveCfg = Release Mono|Any CPU
- {5624B7B5-B5A7-41D8-9F10-CC5611109619}.Release_Ubuntu|Mixed Platforms.Build.0 = Release Mono|Any CPU
- {5624B7B5-B5A7-41D8-9F10-CC5611109619}.Release_Ubuntu|Win32.ActiveCfg = Release Mono|Any CPU
- {5624B7B5-B5A7-41D8-9F10-CC5611109619}.Release_Ubuntu|x64.ActiveCfg = Release Mono|Any CPU
- {5624B7B5-B5A7-41D8-9F10-CC5611109619}.Release_Ubuntu|x86.ActiveCfg = Release Mono|Any CPU
{5624B7B5-B5A7-41D8-9F10-CC5611109619}.Release|Any CPU.ActiveCfg = Release|Any CPU
{5624B7B5-B5A7-41D8-9F10-CC5611109619}.Release|Any CPU.Build.0 = Release|Any CPU
{5624B7B5-B5A7-41D8-9F10-CC5611109619}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
@@ -271,13 +191,6 @@ Global
{5624B7B5-B5A7-41D8-9F10-CC5611109619}.Release|x64.ActiveCfg = Release|Any CPU
{5624B7B5-B5A7-41D8-9F10-CC5611109619}.Release|x86.ActiveCfg = Release|Any CPU
{5624B7B5-B5A7-41D8-9F10-CC5611109619}.Release|x86.Build.0 = Release|Any CPU
- {C4D2573A-3FD3-441F-81AF-174AC4CD4E1D}.Debug_Ubuntu|Any CPU.ActiveCfg = Debug|Any CPU
- {C4D2573A-3FD3-441F-81AF-174AC4CD4E1D}.Debug_Ubuntu|Any CPU.Build.0 = Debug|Any CPU
- {C4D2573A-3FD3-441F-81AF-174AC4CD4E1D}.Debug_Ubuntu|Mixed Platforms.ActiveCfg = Debug|Any CPU
- {C4D2573A-3FD3-441F-81AF-174AC4CD4E1D}.Debug_Ubuntu|Mixed Platforms.Build.0 = Debug|Any CPU
- {C4D2573A-3FD3-441F-81AF-174AC4CD4E1D}.Debug_Ubuntu|Win32.ActiveCfg = Debug|Any CPU
- {C4D2573A-3FD3-441F-81AF-174AC4CD4E1D}.Debug_Ubuntu|x64.ActiveCfg = Debug|Any CPU
- {C4D2573A-3FD3-441F-81AF-174AC4CD4E1D}.Debug_Ubuntu|x86.ActiveCfg = Debug|Any CPU
{C4D2573A-3FD3-441F-81AF-174AC4CD4E1D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{C4D2573A-3FD3-441F-81AF-174AC4CD4E1D}.Debug|Any CPU.Build.0 = Debug|Any CPU
{C4D2573A-3FD3-441F-81AF-174AC4CD4E1D}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
@@ -292,13 +205,6 @@ Global
{C4D2573A-3FD3-441F-81AF-174AC4CD4E1D}.Release Mono|Win32.ActiveCfg = Release Mono|Any CPU
{C4D2573A-3FD3-441F-81AF-174AC4CD4E1D}.Release Mono|x64.ActiveCfg = Release Mono|Any CPU
{C4D2573A-3FD3-441F-81AF-174AC4CD4E1D}.Release Mono|x86.ActiveCfg = Release Mono|Any CPU
- {C4D2573A-3FD3-441F-81AF-174AC4CD4E1D}.Release_Ubuntu|Any CPU.ActiveCfg = Release Mono|Any CPU
- {C4D2573A-3FD3-441F-81AF-174AC4CD4E1D}.Release_Ubuntu|Any CPU.Build.0 = Release Mono|Any CPU
- {C4D2573A-3FD3-441F-81AF-174AC4CD4E1D}.Release_Ubuntu|Mixed Platforms.ActiveCfg = Release Mono|Any CPU
- {C4D2573A-3FD3-441F-81AF-174AC4CD4E1D}.Release_Ubuntu|Mixed Platforms.Build.0 = Release Mono|Any CPU
- {C4D2573A-3FD3-441F-81AF-174AC4CD4E1D}.Release_Ubuntu|Win32.ActiveCfg = Release Mono|Any CPU
- {C4D2573A-3FD3-441F-81AF-174AC4CD4E1D}.Release_Ubuntu|x64.ActiveCfg = Release Mono|Any CPU
- {C4D2573A-3FD3-441F-81AF-174AC4CD4E1D}.Release_Ubuntu|x86.ActiveCfg = Release Mono|Any CPU
{C4D2573A-3FD3-441F-81AF-174AC4CD4E1D}.Release|Any CPU.ActiveCfg = Release|Any CPU
{C4D2573A-3FD3-441F-81AF-174AC4CD4E1D}.Release|Any CPU.Build.0 = Release|Any CPU
{C4D2573A-3FD3-441F-81AF-174AC4CD4E1D}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
@@ -306,13 +212,6 @@ Global
{C4D2573A-3FD3-441F-81AF-174AC4CD4E1D}.Release|Win32.ActiveCfg = Release|Any CPU
{C4D2573A-3FD3-441F-81AF-174AC4CD4E1D}.Release|x64.ActiveCfg = Release|Any CPU
{C4D2573A-3FD3-441F-81AF-174AC4CD4E1D}.Release|x86.ActiveCfg = Release|Any CPU
- {2E781478-814D-4A48-9D80-BFF206441A65}.Debug_Ubuntu|Any CPU.ActiveCfg = Debug|Any CPU
- {2E781478-814D-4A48-9D80-BFF206441A65}.Debug_Ubuntu|Any CPU.Build.0 = Debug|Any CPU
- {2E781478-814D-4A48-9D80-BFF206441A65}.Debug_Ubuntu|Mixed Platforms.ActiveCfg = Debug|Any CPU
- {2E781478-814D-4A48-9D80-BFF206441A65}.Debug_Ubuntu|Mixed Platforms.Build.0 = Debug|Any CPU
- {2E781478-814D-4A48-9D80-BFF206441A65}.Debug_Ubuntu|Win32.ActiveCfg = Debug|Any CPU
- {2E781478-814D-4A48-9D80-BFF206441A65}.Debug_Ubuntu|x64.ActiveCfg = Debug|Any CPU
- {2E781478-814D-4A48-9D80-BFF206441A65}.Debug_Ubuntu|x86.ActiveCfg = Debug|Any CPU
{2E781478-814D-4A48-9D80-BFF206441A65}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{2E781478-814D-4A48-9D80-BFF206441A65}.Debug|Any CPU.Build.0 = Debug|Any CPU
{2E781478-814D-4A48-9D80-BFF206441A65}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
@@ -327,13 +226,6 @@ Global
{2E781478-814D-4A48-9D80-BFF206441A65}.Release Mono|Win32.ActiveCfg = Release Mono|Any CPU
{2E781478-814D-4A48-9D80-BFF206441A65}.Release Mono|x64.ActiveCfg = Release Mono|Any CPU
{2E781478-814D-4A48-9D80-BFF206441A65}.Release Mono|x86.ActiveCfg = Release Mono|Any CPU
- {2E781478-814D-4A48-9D80-BFF206441A65}.Release_Ubuntu|Any CPU.ActiveCfg = Release Mono|Any CPU
- {2E781478-814D-4A48-9D80-BFF206441A65}.Release_Ubuntu|Any CPU.Build.0 = Release Mono|Any CPU
- {2E781478-814D-4A48-9D80-BFF206441A65}.Release_Ubuntu|Mixed Platforms.ActiveCfg = Release Mono|Any CPU
- {2E781478-814D-4A48-9D80-BFF206441A65}.Release_Ubuntu|Mixed Platforms.Build.0 = Release Mono|Any CPU
- {2E781478-814D-4A48-9D80-BFF206441A65}.Release_Ubuntu|Win32.ActiveCfg = Release Mono|Any CPU
- {2E781478-814D-4A48-9D80-BFF206441A65}.Release_Ubuntu|x64.ActiveCfg = Release Mono|Any CPU
- {2E781478-814D-4A48-9D80-BFF206441A65}.Release_Ubuntu|x86.ActiveCfg = Release Mono|Any CPU
{2E781478-814D-4A48-9D80-BFF206441A65}.Release|Any CPU.ActiveCfg = Release|Any CPU
{2E781478-814D-4A48-9D80-BFF206441A65}.Release|Any CPU.Build.0 = Release|Any CPU
{2E781478-814D-4A48-9D80-BFF206441A65}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
@@ -341,13 +233,6 @@ Global
{2E781478-814D-4A48-9D80-BFF206441A65}.Release|Win32.ActiveCfg = Release|Any CPU
{2E781478-814D-4A48-9D80-BFF206441A65}.Release|x64.ActiveCfg = Release|Any CPU
{2E781478-814D-4A48-9D80-BFF206441A65}.Release|x86.ActiveCfg = Release|Any CPU
- {657B5410-7C3B-4806-9753-D254102CE537}.Debug_Ubuntu|Any CPU.ActiveCfg = Debug|Any CPU
- {657B5410-7C3B-4806-9753-D254102CE537}.Debug_Ubuntu|Any CPU.Build.0 = Debug|Any CPU
- {657B5410-7C3B-4806-9753-D254102CE537}.Debug_Ubuntu|Mixed Platforms.ActiveCfg = Debug|Any CPU
- {657B5410-7C3B-4806-9753-D254102CE537}.Debug_Ubuntu|Mixed Platforms.Build.0 = Debug|Any CPU
- {657B5410-7C3B-4806-9753-D254102CE537}.Debug_Ubuntu|Win32.ActiveCfg = Debug|Any CPU
- {657B5410-7C3B-4806-9753-D254102CE537}.Debug_Ubuntu|x64.ActiveCfg = Debug|Any CPU
- {657B5410-7C3B-4806-9753-D254102CE537}.Debug_Ubuntu|x86.ActiveCfg = Debug|Any CPU
{657B5410-7C3B-4806-9753-D254102CE537}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{657B5410-7C3B-4806-9753-D254102CE537}.Debug|Any CPU.Build.0 = Debug|Any CPU
{657B5410-7C3B-4806-9753-D254102CE537}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
@@ -362,13 +247,6 @@ Global
{657B5410-7C3B-4806-9753-D254102CE537}.Release Mono|Win32.ActiveCfg = Release|Any CPU
{657B5410-7C3B-4806-9753-D254102CE537}.Release Mono|x64.ActiveCfg = Release|Any CPU
{657B5410-7C3B-4806-9753-D254102CE537}.Release Mono|x86.ActiveCfg = Release|Any CPU
- {657B5410-7C3B-4806-9753-D254102CE537}.Release_Ubuntu|Any CPU.ActiveCfg = Release|Any CPU
- {657B5410-7C3B-4806-9753-D254102CE537}.Release_Ubuntu|Any CPU.Build.0 = Release|Any CPU
- {657B5410-7C3B-4806-9753-D254102CE537}.Release_Ubuntu|Mixed Platforms.ActiveCfg = Release|Any CPU
- {657B5410-7C3B-4806-9753-D254102CE537}.Release_Ubuntu|Mixed Platforms.Build.0 = Release|Any CPU
- {657B5410-7C3B-4806-9753-D254102CE537}.Release_Ubuntu|Win32.ActiveCfg = Release|Any CPU
- {657B5410-7C3B-4806-9753-D254102CE537}.Release_Ubuntu|x64.ActiveCfg = Release|Any CPU
- {657B5410-7C3B-4806-9753-D254102CE537}.Release_Ubuntu|x86.ActiveCfg = Release|Any CPU
{657B5410-7C3B-4806-9753-D254102CE537}.Release|Any CPU.ActiveCfg = Release|Any CPU
{657B5410-7C3B-4806-9753-D254102CE537}.Release|Any CPU.Build.0 = Release|Any CPU
{657B5410-7C3B-4806-9753-D254102CE537}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
@@ -376,13 +254,6 @@ Global
{657B5410-7C3B-4806-9753-D254102CE537}.Release|Win32.ActiveCfg = Release|Any CPU
{657B5410-7C3B-4806-9753-D254102CE537}.Release|x64.ActiveCfg = Release|Any CPU
{657B5410-7C3B-4806-9753-D254102CE537}.Release|x86.ActiveCfg = Release|Any CPU
- {E22BFD35-0FCD-4A85-978A-C22DCD73A081}.Debug_Ubuntu|Any CPU.ActiveCfg = Debug|Any CPU
- {E22BFD35-0FCD-4A85-978A-C22DCD73A081}.Debug_Ubuntu|Any CPU.Build.0 = Debug|Any CPU
- {E22BFD35-0FCD-4A85-978A-C22DCD73A081}.Debug_Ubuntu|Mixed Platforms.ActiveCfg = Debug|Any CPU
- {E22BFD35-0FCD-4A85-978A-C22DCD73A081}.Debug_Ubuntu|Mixed Platforms.Build.0 = Debug|Any CPU
- {E22BFD35-0FCD-4A85-978A-C22DCD73A081}.Debug_Ubuntu|Win32.ActiveCfg = Debug|Any CPU
- {E22BFD35-0FCD-4A85-978A-C22DCD73A081}.Debug_Ubuntu|x64.ActiveCfg = Debug|Any CPU
- {E22BFD35-0FCD-4A85-978A-C22DCD73A081}.Debug_Ubuntu|x86.ActiveCfg = Debug|Any CPU
{E22BFD35-0FCD-4A85-978A-C22DCD73A081}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{E22BFD35-0FCD-4A85-978A-C22DCD73A081}.Debug|Any CPU.Build.0 = Debug|Any CPU
{E22BFD35-0FCD-4A85-978A-C22DCD73A081}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
@@ -397,13 +268,6 @@ Global
{E22BFD35-0FCD-4A85-978A-C22DCD73A081}.Release Mono|Win32.ActiveCfg = Release|Any CPU
{E22BFD35-0FCD-4A85-978A-C22DCD73A081}.Release Mono|x64.ActiveCfg = Release|Any CPU
{E22BFD35-0FCD-4A85-978A-C22DCD73A081}.Release Mono|x86.ActiveCfg = Release|Any CPU
- {E22BFD35-0FCD-4A85-978A-C22DCD73A081}.Release_Ubuntu|Any CPU.ActiveCfg = Release|Any CPU
- {E22BFD35-0FCD-4A85-978A-C22DCD73A081}.Release_Ubuntu|Any CPU.Build.0 = Release|Any CPU
- {E22BFD35-0FCD-4A85-978A-C22DCD73A081}.Release_Ubuntu|Mixed Platforms.ActiveCfg = Release|Any CPU
- {E22BFD35-0FCD-4A85-978A-C22DCD73A081}.Release_Ubuntu|Mixed Platforms.Build.0 = Release|Any CPU
- {E22BFD35-0FCD-4A85-978A-C22DCD73A081}.Release_Ubuntu|Win32.ActiveCfg = Release|Any CPU
- {E22BFD35-0FCD-4A85-978A-C22DCD73A081}.Release_Ubuntu|x64.ActiveCfg = Release|Any CPU
- {E22BFD35-0FCD-4A85-978A-C22DCD73A081}.Release_Ubuntu|x86.ActiveCfg = Release|Any CPU
{E22BFD35-0FCD-4A85-978A-C22DCD73A081}.Release|Any CPU.ActiveCfg = Release|Any CPU
{E22BFD35-0FCD-4A85-978A-C22DCD73A081}.Release|Any CPU.Build.0 = Release|Any CPU
{E22BFD35-0FCD-4A85-978A-C22DCD73A081}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
@@ -411,13 +275,6 @@ Global
{E22BFD35-0FCD-4A85-978A-C22DCD73A081}.Release|Win32.ActiveCfg = Release|Any CPU
{E22BFD35-0FCD-4A85-978A-C22DCD73A081}.Release|x64.ActiveCfg = Release|Any CPU
{E22BFD35-0FCD-4A85-978A-C22DCD73A081}.Release|x86.ActiveCfg = Release|Any CPU
- {442B5058-DCAF-4263-BB6A-F21E31120A1B}.Debug_Ubuntu|Any CPU.ActiveCfg = Debug|Any CPU
- {442B5058-DCAF-4263-BB6A-F21E31120A1B}.Debug_Ubuntu|Any CPU.Build.0 = Debug|Any CPU
- {442B5058-DCAF-4263-BB6A-F21E31120A1B}.Debug_Ubuntu|Mixed Platforms.ActiveCfg = Debug|Any CPU
- {442B5058-DCAF-4263-BB6A-F21E31120A1B}.Debug_Ubuntu|Mixed Platforms.Build.0 = Debug|Any CPU
- {442B5058-DCAF-4263-BB6A-F21E31120A1B}.Debug_Ubuntu|Win32.ActiveCfg = Debug|Any CPU
- {442B5058-DCAF-4263-BB6A-F21E31120A1B}.Debug_Ubuntu|x64.ActiveCfg = Debug|Any CPU
- {442B5058-DCAF-4263-BB6A-F21E31120A1B}.Debug_Ubuntu|x86.ActiveCfg = Debug|Any CPU
{442B5058-DCAF-4263-BB6A-F21E31120A1B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{442B5058-DCAF-4263-BB6A-F21E31120A1B}.Debug|Any CPU.Build.0 = Debug|Any CPU
{442B5058-DCAF-4263-BB6A-F21E31120A1B}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
@@ -432,13 +289,6 @@ Global
{442B5058-DCAF-4263-BB6A-F21E31120A1B}.Release Mono|Win32.ActiveCfg = Release Mono|Any CPU
{442B5058-DCAF-4263-BB6A-F21E31120A1B}.Release Mono|x64.ActiveCfg = Release Mono|Any CPU
{442B5058-DCAF-4263-BB6A-F21E31120A1B}.Release Mono|x86.ActiveCfg = Release Mono|Any CPU
- {442B5058-DCAF-4263-BB6A-F21E31120A1B}.Release_Ubuntu|Any CPU.ActiveCfg = Release Mono|Any CPU
- {442B5058-DCAF-4263-BB6A-F21E31120A1B}.Release_Ubuntu|Any CPU.Build.0 = Release Mono|Any CPU
- {442B5058-DCAF-4263-BB6A-F21E31120A1B}.Release_Ubuntu|Mixed Platforms.ActiveCfg = Release Mono|Any CPU
- {442B5058-DCAF-4263-BB6A-F21E31120A1B}.Release_Ubuntu|Mixed Platforms.Build.0 = Release Mono|Any CPU
- {442B5058-DCAF-4263-BB6A-F21E31120A1B}.Release_Ubuntu|Win32.ActiveCfg = Release Mono|Any CPU
- {442B5058-DCAF-4263-BB6A-F21E31120A1B}.Release_Ubuntu|x64.ActiveCfg = Release Mono|Any CPU
- {442B5058-DCAF-4263-BB6A-F21E31120A1B}.Release_Ubuntu|x86.ActiveCfg = Release Mono|Any CPU
{442B5058-DCAF-4263-BB6A-F21E31120A1B}.Release|Any CPU.ActiveCfg = Release|Any CPU
{442B5058-DCAF-4263-BB6A-F21E31120A1B}.Release|Any CPU.Build.0 = Release|Any CPU
{442B5058-DCAF-4263-BB6A-F21E31120A1B}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
@@ -446,13 +296,6 @@ Global
{442B5058-DCAF-4263-BB6A-F21E31120A1B}.Release|Win32.ActiveCfg = Release|Any CPU
{442B5058-DCAF-4263-BB6A-F21E31120A1B}.Release|x64.ActiveCfg = Release|Any CPU
{442B5058-DCAF-4263-BB6A-F21E31120A1B}.Release|x86.ActiveCfg = Release|Any CPU
- {D729ADB1-1C01-428D-B680-8EFACD687B2A}.Debug_Ubuntu|Any CPU.ActiveCfg = Debug|Any CPU
- {D729ADB1-1C01-428D-B680-8EFACD687B2A}.Debug_Ubuntu|Any CPU.Build.0 = Debug|Any CPU
- {D729ADB1-1C01-428D-B680-8EFACD687B2A}.Debug_Ubuntu|Mixed Platforms.ActiveCfg = Debug|Any CPU
- {D729ADB1-1C01-428D-B680-8EFACD687B2A}.Debug_Ubuntu|Mixed Platforms.Build.0 = Debug|Any CPU
- {D729ADB1-1C01-428D-B680-8EFACD687B2A}.Debug_Ubuntu|Win32.ActiveCfg = Debug|Any CPU
- {D729ADB1-1C01-428D-B680-8EFACD687B2A}.Debug_Ubuntu|x64.ActiveCfg = Debug|Any CPU
- {D729ADB1-1C01-428D-B680-8EFACD687B2A}.Debug_Ubuntu|x86.ActiveCfg = Debug|Any CPU
{D729ADB1-1C01-428D-B680-8EFACD687B2A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{D729ADB1-1C01-428D-B680-8EFACD687B2A}.Debug|Any CPU.Build.0 = Debug|Any CPU
{D729ADB1-1C01-428D-B680-8EFACD687B2A}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
@@ -467,13 +310,6 @@ Global
{D729ADB1-1C01-428D-B680-8EFACD687B2A}.Release Mono|Win32.ActiveCfg = Release|Any CPU
{D729ADB1-1C01-428D-B680-8EFACD687B2A}.Release Mono|x64.ActiveCfg = Release|Any CPU
{D729ADB1-1C01-428D-B680-8EFACD687B2A}.Release Mono|x86.ActiveCfg = Release|Any CPU
- {D729ADB1-1C01-428D-B680-8EFACD687B2A}.Release_Ubuntu|Any CPU.ActiveCfg = Release|Any CPU
- {D729ADB1-1C01-428D-B680-8EFACD687B2A}.Release_Ubuntu|Any CPU.Build.0 = Release|Any CPU
- {D729ADB1-1C01-428D-B680-8EFACD687B2A}.Release_Ubuntu|Mixed Platforms.ActiveCfg = Release|Any CPU
- {D729ADB1-1C01-428D-B680-8EFACD687B2A}.Release_Ubuntu|Mixed Platforms.Build.0 = Release|Any CPU
- {D729ADB1-1C01-428D-B680-8EFACD687B2A}.Release_Ubuntu|Win32.ActiveCfg = Release|Any CPU
- {D729ADB1-1C01-428D-B680-8EFACD687B2A}.Release_Ubuntu|x64.ActiveCfg = Release|Any CPU
- {D729ADB1-1C01-428D-B680-8EFACD687B2A}.Release_Ubuntu|x86.ActiveCfg = Release|Any CPU
{D729ADB1-1C01-428D-B680-8EFACD687B2A}.Release|Any CPU.ActiveCfg = Release|Any CPU
{D729ADB1-1C01-428D-B680-8EFACD687B2A}.Release|Any CPU.Build.0 = Release|Any CPU
{D729ADB1-1C01-428D-B680-8EFACD687B2A}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
@@ -481,17 +317,8 @@ Global
{D729ADB1-1C01-428D-B680-8EFACD687B2A}.Release|Win32.ActiveCfg = Release|Any CPU
{D729ADB1-1C01-428D-B680-8EFACD687B2A}.Release|x64.ActiveCfg = Release|Any CPU
{D729ADB1-1C01-428D-B680-8EFACD687B2A}.Release|x86.ActiveCfg = Release|Any CPU
- {94ADE4D3-B7EC-45CD-A200-CC469433072B}.Debug_Ubuntu|Any CPU.ActiveCfg = Debug|Any CPU
- {94ADE4D3-B7EC-45CD-A200-CC469433072B}.Debug_Ubuntu|Any CPU.Build.0 = Debug|Any CPU
- {94ADE4D3-B7EC-45CD-A200-CC469433072B}.Debug_Ubuntu|Mixed Platforms.ActiveCfg = Debug|x86
- {94ADE4D3-B7EC-45CD-A200-CC469433072B}.Debug_Ubuntu|Mixed Platforms.Build.0 = Debug|x86
- {94ADE4D3-B7EC-45CD-A200-CC469433072B}.Debug_Ubuntu|Win32.ActiveCfg = Debug|x86
- {94ADE4D3-B7EC-45CD-A200-CC469433072B}.Debug_Ubuntu|Win32.Build.0 = Debug|x86
- {94ADE4D3-B7EC-45CD-A200-CC469433072B}.Debug_Ubuntu|x64.ActiveCfg = Debug|Any CPU
- {94ADE4D3-B7EC-45CD-A200-CC469433072B}.Debug_Ubuntu|x86.ActiveCfg = Debug|x86
- {94ADE4D3-B7EC-45CD-A200-CC469433072B}.Debug_Ubuntu|x86.Build.0 = Debug|x86
- {94ADE4D3-B7EC-45CD-A200-CC469433072B}.Debug|Any CPU.ActiveCfg = Debug|x86
- {94ADE4D3-B7EC-45CD-A200-CC469433072B}.Debug|Any CPU.Build.0 = Debug|x86
+ {94ADE4D3-B7EC-45CD-A200-CC469433072B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {94ADE4D3-B7EC-45CD-A200-CC469433072B}.Debug|Any CPU.Build.0 = Debug|Any CPU
{94ADE4D3-B7EC-45CD-A200-CC469433072B}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
{94ADE4D3-B7EC-45CD-A200-CC469433072B}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
{94ADE4D3-B7EC-45CD-A200-CC469433072B}.Debug|Win32.ActiveCfg = Debug|Any CPU
@@ -505,29 +332,13 @@ Global
{94ADE4D3-B7EC-45CD-A200-CC469433072B}.Release Mono|x64.ActiveCfg = Release|Any CPU
{94ADE4D3-B7EC-45CD-A200-CC469433072B}.Release Mono|x86.ActiveCfg = Release|x86
{94ADE4D3-B7EC-45CD-A200-CC469433072B}.Release Mono|x86.Build.0 = Release|x86
- {94ADE4D3-B7EC-45CD-A200-CC469433072B}.Release_Ubuntu|Any CPU.ActiveCfg = Release|Any CPU
- {94ADE4D3-B7EC-45CD-A200-CC469433072B}.Release_Ubuntu|Any CPU.Build.0 = Release|Any CPU
- {94ADE4D3-B7EC-45CD-A200-CC469433072B}.Release_Ubuntu|Mixed Platforms.ActiveCfg = Release|x86
- {94ADE4D3-B7EC-45CD-A200-CC469433072B}.Release_Ubuntu|Mixed Platforms.Build.0 = Release|x86
- {94ADE4D3-B7EC-45CD-A200-CC469433072B}.Release_Ubuntu|Win32.ActiveCfg = Release|x86
- {94ADE4D3-B7EC-45CD-A200-CC469433072B}.Release_Ubuntu|Win32.Build.0 = Release|x86
- {94ADE4D3-B7EC-45CD-A200-CC469433072B}.Release_Ubuntu|x64.ActiveCfg = Release|Any CPU
- {94ADE4D3-B7EC-45CD-A200-CC469433072B}.Release_Ubuntu|x86.ActiveCfg = Release|x86
- {94ADE4D3-B7EC-45CD-A200-CC469433072B}.Release_Ubuntu|x86.Build.0 = Release|x86
- {94ADE4D3-B7EC-45CD-A200-CC469433072B}.Release|Any CPU.ActiveCfg = Release|x86
- {94ADE4D3-B7EC-45CD-A200-CC469433072B}.Release|Any CPU.Build.0 = Release|x86
+ {94ADE4D3-B7EC-45CD-A200-CC469433072B}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {94ADE4D3-B7EC-45CD-A200-CC469433072B}.Release|Any CPU.Build.0 = Release|Any CPU
{94ADE4D3-B7EC-45CD-A200-CC469433072B}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
{94ADE4D3-B7EC-45CD-A200-CC469433072B}.Release|Mixed Platforms.Build.0 = Release|Any CPU
{94ADE4D3-B7EC-45CD-A200-CC469433072B}.Release|Win32.ActiveCfg = Release|Any CPU
{94ADE4D3-B7EC-45CD-A200-CC469433072B}.Release|x64.ActiveCfg = Release|Any CPU
{94ADE4D3-B7EC-45CD-A200-CC469433072B}.Release|x86.ActiveCfg = Release|Any CPU
- {734098EB-6DC1-4DD0-A1CA-3140DCD2737C}.Debug_Ubuntu|Any CPU.ActiveCfg = Debug|Any CPU
- {734098EB-6DC1-4DD0-A1CA-3140DCD2737C}.Debug_Ubuntu|Any CPU.Build.0 = Debug|Any CPU
- {734098EB-6DC1-4DD0-A1CA-3140DCD2737C}.Debug_Ubuntu|Mixed Platforms.ActiveCfg = Debug|Any CPU
- {734098EB-6DC1-4DD0-A1CA-3140DCD2737C}.Debug_Ubuntu|Mixed Platforms.Build.0 = Debug|Any CPU
- {734098EB-6DC1-4DD0-A1CA-3140DCD2737C}.Debug_Ubuntu|Win32.ActiveCfg = Debug|Any CPU
- {734098EB-6DC1-4DD0-A1CA-3140DCD2737C}.Debug_Ubuntu|x64.ActiveCfg = Debug|Any CPU
- {734098EB-6DC1-4DD0-A1CA-3140DCD2737C}.Debug_Ubuntu|x86.ActiveCfg = Debug|Any CPU
{734098EB-6DC1-4DD0-A1CA-3140DCD2737C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{734098EB-6DC1-4DD0-A1CA-3140DCD2737C}.Debug|Any CPU.Build.0 = Debug|Any CPU
{734098EB-6DC1-4DD0-A1CA-3140DCD2737C}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
@@ -542,13 +353,6 @@ Global
{734098EB-6DC1-4DD0-A1CA-3140DCD2737C}.Release Mono|Win32.ActiveCfg = Release Mono|Any CPU
{734098EB-6DC1-4DD0-A1CA-3140DCD2737C}.Release Mono|x64.ActiveCfg = Release Mono|Any CPU
{734098EB-6DC1-4DD0-A1CA-3140DCD2737C}.Release Mono|x86.ActiveCfg = Release Mono|Any CPU
- {734098EB-6DC1-4DD0-A1CA-3140DCD2737C}.Release_Ubuntu|Any CPU.ActiveCfg = Release Mono|Any CPU
- {734098EB-6DC1-4DD0-A1CA-3140DCD2737C}.Release_Ubuntu|Any CPU.Build.0 = Release Mono|Any CPU
- {734098EB-6DC1-4DD0-A1CA-3140DCD2737C}.Release_Ubuntu|Mixed Platforms.ActiveCfg = Release Mono|Any CPU
- {734098EB-6DC1-4DD0-A1CA-3140DCD2737C}.Release_Ubuntu|Mixed Platforms.Build.0 = Release Mono|Any CPU
- {734098EB-6DC1-4DD0-A1CA-3140DCD2737C}.Release_Ubuntu|Win32.ActiveCfg = Release Mono|Any CPU
- {734098EB-6DC1-4DD0-A1CA-3140DCD2737C}.Release_Ubuntu|x64.ActiveCfg = Release Mono|Any CPU
- {734098EB-6DC1-4DD0-A1CA-3140DCD2737C}.Release_Ubuntu|x86.ActiveCfg = Release Mono|Any CPU
{734098EB-6DC1-4DD0-A1CA-3140DCD2737C}.Release|Any CPU.ActiveCfg = Release|Any CPU
{734098EB-6DC1-4DD0-A1CA-3140DCD2737C}.Release|Any CPU.Build.0 = Release|Any CPU
{734098EB-6DC1-4DD0-A1CA-3140DCD2737C}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
@@ -556,13 +360,6 @@ Global
{734098EB-6DC1-4DD0-A1CA-3140DCD2737C}.Release|Win32.ActiveCfg = Release|Any CPU
{734098EB-6DC1-4DD0-A1CA-3140DCD2737C}.Release|x64.ActiveCfg = Release|Any CPU
{734098EB-6DC1-4DD0-A1CA-3140DCD2737C}.Release|x86.ActiveCfg = Release|Any CPU
- {0BD82FA6-EB8A-4452-8AF5-74F9C3849451}.Debug_Ubuntu|Any CPU.ActiveCfg = Debug|Any CPU
- {0BD82FA6-EB8A-4452-8AF5-74F9C3849451}.Debug_Ubuntu|Any CPU.Build.0 = Debug|Any CPU
- {0BD82FA6-EB8A-4452-8AF5-74F9C3849451}.Debug_Ubuntu|Mixed Platforms.ActiveCfg = Debug|Any CPU
- {0BD82FA6-EB8A-4452-8AF5-74F9C3849451}.Debug_Ubuntu|Mixed Platforms.Build.0 = Debug|Any CPU
- {0BD82FA6-EB8A-4452-8AF5-74F9C3849451}.Debug_Ubuntu|Win32.ActiveCfg = Debug|Any CPU
- {0BD82FA6-EB8A-4452-8AF5-74F9C3849451}.Debug_Ubuntu|x64.ActiveCfg = Debug|Any CPU
- {0BD82FA6-EB8A-4452-8AF5-74F9C3849451}.Debug_Ubuntu|x86.ActiveCfg = Debug|Any CPU
{0BD82FA6-EB8A-4452-8AF5-74F9C3849451}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{0BD82FA6-EB8A-4452-8AF5-74F9C3849451}.Debug|Any CPU.Build.0 = Debug|Any CPU
{0BD82FA6-EB8A-4452-8AF5-74F9C3849451}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
@@ -577,13 +374,6 @@ Global
{0BD82FA6-EB8A-4452-8AF5-74F9C3849451}.Release Mono|Win32.ActiveCfg = Release Mono|Any CPU
{0BD82FA6-EB8A-4452-8AF5-74F9C3849451}.Release Mono|x64.ActiveCfg = Release Mono|Any CPU
{0BD82FA6-EB8A-4452-8AF5-74F9C3849451}.Release Mono|x86.ActiveCfg = Release Mono|Any CPU
- {0BD82FA6-EB8A-4452-8AF5-74F9C3849451}.Release_Ubuntu|Any CPU.ActiveCfg = Release Mono|Any CPU
- {0BD82FA6-EB8A-4452-8AF5-74F9C3849451}.Release_Ubuntu|Any CPU.Build.0 = Release Mono|Any CPU
- {0BD82FA6-EB8A-4452-8AF5-74F9C3849451}.Release_Ubuntu|Mixed Platforms.ActiveCfg = Release Mono|Any CPU
- {0BD82FA6-EB8A-4452-8AF5-74F9C3849451}.Release_Ubuntu|Mixed Platforms.Build.0 = Release Mono|Any CPU
- {0BD82FA6-EB8A-4452-8AF5-74F9C3849451}.Release_Ubuntu|Win32.ActiveCfg = Release Mono|Any CPU
- {0BD82FA6-EB8A-4452-8AF5-74F9C3849451}.Release_Ubuntu|x64.ActiveCfg = Release Mono|Any CPU
- {0BD82FA6-EB8A-4452-8AF5-74F9C3849451}.Release_Ubuntu|x86.ActiveCfg = Release Mono|Any CPU
{0BD82FA6-EB8A-4452-8AF5-74F9C3849451}.Release|Any CPU.ActiveCfg = Release|Any CPU
{0BD82FA6-EB8A-4452-8AF5-74F9C3849451}.Release|Any CPU.Build.0 = Release|Any CPU
{0BD82FA6-EB8A-4452-8AF5-74F9C3849451}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
@@ -591,13 +381,6 @@ Global
{0BD82FA6-EB8A-4452-8AF5-74F9C3849451}.Release|Win32.ActiveCfg = Release|Any CPU
{0BD82FA6-EB8A-4452-8AF5-74F9C3849451}.Release|x64.ActiveCfg = Release|Any CPU
{0BD82FA6-EB8A-4452-8AF5-74F9C3849451}.Release|x86.ActiveCfg = Release|Any CPU
- {4A4402D4-E910-443B-B8FC-2C18286A2CA0}.Debug_Ubuntu|Any CPU.ActiveCfg = Debug|Any CPU
- {4A4402D4-E910-443B-B8FC-2C18286A2CA0}.Debug_Ubuntu|Any CPU.Build.0 = Debug|Any CPU
- {4A4402D4-E910-443B-B8FC-2C18286A2CA0}.Debug_Ubuntu|Mixed Platforms.ActiveCfg = Debug|Any CPU
- {4A4402D4-E910-443B-B8FC-2C18286A2CA0}.Debug_Ubuntu|Mixed Platforms.Build.0 = Debug|Any CPU
- {4A4402D4-E910-443B-B8FC-2C18286A2CA0}.Debug_Ubuntu|Win32.ActiveCfg = Debug|Any CPU
- {4A4402D4-E910-443B-B8FC-2C18286A2CA0}.Debug_Ubuntu|x64.ActiveCfg = Debug|Any CPU
- {4A4402D4-E910-443B-B8FC-2C18286A2CA0}.Debug_Ubuntu|x86.ActiveCfg = Debug|Any CPU
{4A4402D4-E910-443B-B8FC-2C18286A2CA0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{4A4402D4-E910-443B-B8FC-2C18286A2CA0}.Debug|Any CPU.Build.0 = Debug|Any CPU
{4A4402D4-E910-443B-B8FC-2C18286A2CA0}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
@@ -612,13 +395,6 @@ Global
{4A4402D4-E910-443B-B8FC-2C18286A2CA0}.Release Mono|Win32.ActiveCfg = Release Mono|Any CPU
{4A4402D4-E910-443B-B8FC-2C18286A2CA0}.Release Mono|x64.ActiveCfg = Release Mono|Any CPU
{4A4402D4-E910-443B-B8FC-2C18286A2CA0}.Release Mono|x86.ActiveCfg = Release Mono|Any CPU
- {4A4402D4-E910-443B-B8FC-2C18286A2CA0}.Release_Ubuntu|Any CPU.ActiveCfg = Release Mono|Any CPU
- {4A4402D4-E910-443B-B8FC-2C18286A2CA0}.Release_Ubuntu|Any CPU.Build.0 = Release Mono|Any CPU
- {4A4402D4-E910-443B-B8FC-2C18286A2CA0}.Release_Ubuntu|Mixed Platforms.ActiveCfg = Release Mono|Any CPU
- {4A4402D4-E910-443B-B8FC-2C18286A2CA0}.Release_Ubuntu|Mixed Platforms.Build.0 = Release Mono|Any CPU
- {4A4402D4-E910-443B-B8FC-2C18286A2CA0}.Release_Ubuntu|Win32.ActiveCfg = Release Mono|Any CPU
- {4A4402D4-E910-443B-B8FC-2C18286A2CA0}.Release_Ubuntu|x64.ActiveCfg = Release Mono|Any CPU
- {4A4402D4-E910-443B-B8FC-2C18286A2CA0}.Release_Ubuntu|x86.ActiveCfg = Release Mono|Any CPU
{4A4402D4-E910-443B-B8FC-2C18286A2CA0}.Release|Any CPU.ActiveCfg = Release|Any CPU
{4A4402D4-E910-443B-B8FC-2C18286A2CA0}.Release|Any CPU.Build.0 = Release|Any CPU
{4A4402D4-E910-443B-B8FC-2C18286A2CA0}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
@@ -626,13 +402,6 @@ Global
{4A4402D4-E910-443B-B8FC-2C18286A2CA0}.Release|Win32.ActiveCfg = Release|Any CPU
{4A4402D4-E910-443B-B8FC-2C18286A2CA0}.Release|x64.ActiveCfg = Release|Any CPU
{4A4402D4-E910-443B-B8FC-2C18286A2CA0}.Release|x86.ActiveCfg = Release|Any CPU
- {23499896-B135-4527-8574-C26E926EA99E}.Debug_Ubuntu|Any CPU.ActiveCfg = Debug|Any CPU
- {23499896-B135-4527-8574-C26E926EA99E}.Debug_Ubuntu|Any CPU.Build.0 = Debug|Any CPU
- {23499896-B135-4527-8574-C26E926EA99E}.Debug_Ubuntu|Mixed Platforms.ActiveCfg = Debug|Any CPU
- {23499896-B135-4527-8574-C26E926EA99E}.Debug_Ubuntu|Mixed Platforms.Build.0 = Debug|Any CPU
- {23499896-B135-4527-8574-C26E926EA99E}.Debug_Ubuntu|Win32.ActiveCfg = Debug|Any CPU
- {23499896-B135-4527-8574-C26E926EA99E}.Debug_Ubuntu|x64.ActiveCfg = Debug|Any CPU
- {23499896-B135-4527-8574-C26E926EA99E}.Debug_Ubuntu|x86.ActiveCfg = Debug|Any CPU
{23499896-B135-4527-8574-C26E926EA99E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{23499896-B135-4527-8574-C26E926EA99E}.Debug|Any CPU.Build.0 = Debug|Any CPU
{23499896-B135-4527-8574-C26E926EA99E}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
@@ -647,13 +416,6 @@ Global
{23499896-B135-4527-8574-C26E926EA99E}.Release Mono|Win32.ActiveCfg = Release|Any CPU
{23499896-B135-4527-8574-C26E926EA99E}.Release Mono|x64.ActiveCfg = Release|Any CPU
{23499896-B135-4527-8574-C26E926EA99E}.Release Mono|x86.ActiveCfg = Release|Any CPU
- {23499896-B135-4527-8574-C26E926EA99E}.Release_Ubuntu|Any CPU.ActiveCfg = Release|Any CPU
- {23499896-B135-4527-8574-C26E926EA99E}.Release_Ubuntu|Any CPU.Build.0 = Release|Any CPU
- {23499896-B135-4527-8574-C26E926EA99E}.Release_Ubuntu|Mixed Platforms.ActiveCfg = Release|Any CPU
- {23499896-B135-4527-8574-C26E926EA99E}.Release_Ubuntu|Mixed Platforms.Build.0 = Release|Any CPU
- {23499896-B135-4527-8574-C26E926EA99E}.Release_Ubuntu|Win32.ActiveCfg = Release|Any CPU
- {23499896-B135-4527-8574-C26E926EA99E}.Release_Ubuntu|x64.ActiveCfg = Release|Any CPU
- {23499896-B135-4527-8574-C26E926EA99E}.Release_Ubuntu|x86.ActiveCfg = Release|Any CPU
{23499896-B135-4527-8574-C26E926EA99E}.Release|Any CPU.ActiveCfg = Release|Any CPU
{23499896-B135-4527-8574-C26E926EA99E}.Release|Any CPU.Build.0 = Release|Any CPU
{23499896-B135-4527-8574-C26E926EA99E}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
@@ -661,13 +423,6 @@ Global
{23499896-B135-4527-8574-C26E926EA99E}.Release|Win32.ActiveCfg = Release|Any CPU
{23499896-B135-4527-8574-C26E926EA99E}.Release|x64.ActiveCfg = Release|Any CPU
{23499896-B135-4527-8574-C26E926EA99E}.Release|x86.ActiveCfg = Release|Any CPU
- {7EF9F3E0-697D-42F3-A08F-19DEB5F84392}.Debug_Ubuntu|Any CPU.ActiveCfg = Debug|Any CPU
- {7EF9F3E0-697D-42F3-A08F-19DEB5F84392}.Debug_Ubuntu|Any CPU.Build.0 = Debug|Any CPU
- {7EF9F3E0-697D-42F3-A08F-19DEB5F84392}.Debug_Ubuntu|Mixed Platforms.ActiveCfg = Debug|Any CPU
- {7EF9F3E0-697D-42F3-A08F-19DEB5F84392}.Debug_Ubuntu|Mixed Platforms.Build.0 = Debug|Any CPU
- {7EF9F3E0-697D-42F3-A08F-19DEB5F84392}.Debug_Ubuntu|Win32.ActiveCfg = Debug|Any CPU
- {7EF9F3E0-697D-42F3-A08F-19DEB5F84392}.Debug_Ubuntu|x64.ActiveCfg = Debug|Any CPU
- {7EF9F3E0-697D-42F3-A08F-19DEB5F84392}.Debug_Ubuntu|x86.ActiveCfg = Debug|Any CPU
{7EF9F3E0-697D-42F3-A08F-19DEB5F84392}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{7EF9F3E0-697D-42F3-A08F-19DEB5F84392}.Debug|Any CPU.Build.0 = Debug|Any CPU
{7EF9F3E0-697D-42F3-A08F-19DEB5F84392}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
@@ -682,13 +437,6 @@ Global
{7EF9F3E0-697D-42F3-A08F-19DEB5F84392}.Release Mono|Win32.ActiveCfg = Release|Any CPU
{7EF9F3E0-697D-42F3-A08F-19DEB5F84392}.Release Mono|x64.ActiveCfg = Release|Any CPU
{7EF9F3E0-697D-42F3-A08F-19DEB5F84392}.Release Mono|x86.ActiveCfg = Release|Any CPU
- {7EF9F3E0-697D-42F3-A08F-19DEB5F84392}.Release_Ubuntu|Any CPU.ActiveCfg = Release|Any CPU
- {7EF9F3E0-697D-42F3-A08F-19DEB5F84392}.Release_Ubuntu|Any CPU.Build.0 = Release|Any CPU
- {7EF9F3E0-697D-42F3-A08F-19DEB5F84392}.Release_Ubuntu|Mixed Platforms.ActiveCfg = Release|Any CPU
- {7EF9F3E0-697D-42F3-A08F-19DEB5F84392}.Release_Ubuntu|Mixed Platforms.Build.0 = Release|Any CPU
- {7EF9F3E0-697D-42F3-A08F-19DEB5F84392}.Release_Ubuntu|Win32.ActiveCfg = Release|Any CPU
- {7EF9F3E0-697D-42F3-A08F-19DEB5F84392}.Release_Ubuntu|x64.ActiveCfg = Release|Any CPU
- {7EF9F3E0-697D-42F3-A08F-19DEB5F84392}.Release_Ubuntu|x86.ActiveCfg = Release|Any CPU
{7EF9F3E0-697D-42F3-A08F-19DEB5F84392}.Release|Any CPU.ActiveCfg = Release|Any CPU
{7EF9F3E0-697D-42F3-A08F-19DEB5F84392}.Release|Any CPU.Build.0 = Release|Any CPU
{7EF9F3E0-697D-42F3-A08F-19DEB5F84392}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
@@ -696,13 +444,6 @@ Global
{7EF9F3E0-697D-42F3-A08F-19DEB5F84392}.Release|Win32.ActiveCfg = Release|Any CPU
{7EF9F3E0-697D-42F3-A08F-19DEB5F84392}.Release|x64.ActiveCfg = Release|Any CPU
{7EF9F3E0-697D-42F3-A08F-19DEB5F84392}.Release|x86.ActiveCfg = Release|Any CPU
- {6E4145E4-C6D4-4E4D-94F2-87188DB6E239}.Debug_Ubuntu|Any CPU.ActiveCfg = Debug|Any CPU
- {6E4145E4-C6D4-4E4D-94F2-87188DB6E239}.Debug_Ubuntu|Any CPU.Build.0 = Debug|Any CPU
- {6E4145E4-C6D4-4E4D-94F2-87188DB6E239}.Debug_Ubuntu|Mixed Platforms.ActiveCfg = Debug|Any CPU
- {6E4145E4-C6D4-4E4D-94F2-87188DB6E239}.Debug_Ubuntu|Mixed Platforms.Build.0 = Debug|Any CPU
- {6E4145E4-C6D4-4E4D-94F2-87188DB6E239}.Debug_Ubuntu|Win32.ActiveCfg = Debug|Any CPU
- {6E4145E4-C6D4-4E4D-94F2-87188DB6E239}.Debug_Ubuntu|x64.ActiveCfg = Debug|Any CPU
- {6E4145E4-C6D4-4E4D-94F2-87188DB6E239}.Debug_Ubuntu|x86.ActiveCfg = Debug|Any CPU
{6E4145E4-C6D4-4E4D-94F2-87188DB6E239}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{6E4145E4-C6D4-4E4D-94F2-87188DB6E239}.Debug|Any CPU.Build.0 = Debug|Any CPU
{6E4145E4-C6D4-4E4D-94F2-87188DB6E239}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
@@ -717,13 +458,6 @@ Global
{6E4145E4-C6D4-4E4D-94F2-87188DB6E239}.Release Mono|Win32.ActiveCfg = Release|Any CPU
{6E4145E4-C6D4-4E4D-94F2-87188DB6E239}.Release Mono|x64.ActiveCfg = Release|Any CPU
{6E4145E4-C6D4-4E4D-94F2-87188DB6E239}.Release Mono|x86.ActiveCfg = Release|Any CPU
- {6E4145E4-C6D4-4E4D-94F2-87188DB6E239}.Release_Ubuntu|Any CPU.ActiveCfg = Release|Any CPU
- {6E4145E4-C6D4-4E4D-94F2-87188DB6E239}.Release_Ubuntu|Any CPU.Build.0 = Release|Any CPU
- {6E4145E4-C6D4-4E4D-94F2-87188DB6E239}.Release_Ubuntu|Mixed Platforms.ActiveCfg = Release|Any CPU
- {6E4145E4-C6D4-4E4D-94F2-87188DB6E239}.Release_Ubuntu|Mixed Platforms.Build.0 = Release|Any CPU
- {6E4145E4-C6D4-4E4D-94F2-87188DB6E239}.Release_Ubuntu|Win32.ActiveCfg = Release|Any CPU
- {6E4145E4-C6D4-4E4D-94F2-87188DB6E239}.Release_Ubuntu|x64.ActiveCfg = Release|Any CPU
- {6E4145E4-C6D4-4E4D-94F2-87188DB6E239}.Release_Ubuntu|x86.ActiveCfg = Release|Any CPU
{6E4145E4-C6D4-4E4D-94F2-87188DB6E239}.Release|Any CPU.ActiveCfg = Release|Any CPU
{6E4145E4-C6D4-4E4D-94F2-87188DB6E239}.Release|Any CPU.Build.0 = Release|Any CPU
{6E4145E4-C6D4-4E4D-94F2-87188DB6E239}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
@@ -731,15 +465,6 @@ Global
{6E4145E4-C6D4-4E4D-94F2-87188DB6E239}.Release|Win32.ActiveCfg = Release|Any CPU
{6E4145E4-C6D4-4E4D-94F2-87188DB6E239}.Release|x64.ActiveCfg = Release|Any CPU
{6E4145E4-C6D4-4E4D-94F2-87188DB6E239}.Release|x86.ActiveCfg = Release|Any CPU
- {175A9388-F352-4586-A6B4-070DED62B644}.Debug_Ubuntu|Any CPU.ActiveCfg = Debug|Any CPU
- {175A9388-F352-4586-A6B4-070DED62B644}.Debug_Ubuntu|Any CPU.Build.0 = Debug|Any CPU
- {175A9388-F352-4586-A6B4-070DED62B644}.Debug_Ubuntu|Mixed Platforms.ActiveCfg = Debug|x86
- {175A9388-F352-4586-A6B4-070DED62B644}.Debug_Ubuntu|Mixed Platforms.Build.0 = Debug|x86
- {175A9388-F352-4586-A6B4-070DED62B644}.Debug_Ubuntu|Win32.ActiveCfg = Debug|x86
- {175A9388-F352-4586-A6B4-070DED62B644}.Debug_Ubuntu|Win32.Build.0 = Debug|x86
- {175A9388-F352-4586-A6B4-070DED62B644}.Debug_Ubuntu|x64.ActiveCfg = Debug|Any CPU
- {175A9388-F352-4586-A6B4-070DED62B644}.Debug_Ubuntu|x86.ActiveCfg = Debug|x86
- {175A9388-F352-4586-A6B4-070DED62B644}.Debug_Ubuntu|x86.Build.0 = Debug|x86
{175A9388-F352-4586-A6B4-070DED62B644}.Debug|Any CPU.ActiveCfg = Debug|x86
{175A9388-F352-4586-A6B4-070DED62B644}.Debug|Any CPU.Build.0 = Debug|x86
{175A9388-F352-4586-A6B4-070DED62B644}.Debug|Mixed Platforms.ActiveCfg = Debug|x86
@@ -758,15 +483,6 @@ Global
{175A9388-F352-4586-A6B4-070DED62B644}.Release Mono|x64.ActiveCfg = Release Mono|Any CPU
{175A9388-F352-4586-A6B4-070DED62B644}.Release Mono|x86.ActiveCfg = Release Mono|x86
{175A9388-F352-4586-A6B4-070DED62B644}.Release Mono|x86.Build.0 = Release Mono|x86
- {175A9388-F352-4586-A6B4-070DED62B644}.Release_Ubuntu|Any CPU.ActiveCfg = Release Mono|Any CPU
- {175A9388-F352-4586-A6B4-070DED62B644}.Release_Ubuntu|Any CPU.Build.0 = Release Mono|Any CPU
- {175A9388-F352-4586-A6B4-070DED62B644}.Release_Ubuntu|Mixed Platforms.ActiveCfg = Release Mono|x86
- {175A9388-F352-4586-A6B4-070DED62B644}.Release_Ubuntu|Mixed Platforms.Build.0 = Release Mono|x86
- {175A9388-F352-4586-A6B4-070DED62B644}.Release_Ubuntu|Win32.ActiveCfg = Release Mono|x86
- {175A9388-F352-4586-A6B4-070DED62B644}.Release_Ubuntu|Win32.Build.0 = Release Mono|x86
- {175A9388-F352-4586-A6B4-070DED62B644}.Release_Ubuntu|x64.ActiveCfg = Release Mono|Any CPU
- {175A9388-F352-4586-A6B4-070DED62B644}.Release_Ubuntu|x86.ActiveCfg = Release Mono|x86
- {175A9388-F352-4586-A6B4-070DED62B644}.Release_Ubuntu|x86.Build.0 = Release Mono|x86
{175A9388-F352-4586-A6B4-070DED62B644}.Release|Any CPU.ActiveCfg = Release|Any CPU
{175A9388-F352-4586-A6B4-070DED62B644}.Release|Mixed Platforms.ActiveCfg = Release|x86
{175A9388-F352-4586-A6B4-070DED62B644}.Release|Mixed Platforms.Build.0 = Release|x86
@@ -775,13 +491,6 @@ Global
{175A9388-F352-4586-A6B4-070DED62B644}.Release|x64.ActiveCfg = Release|Any CPU
{175A9388-F352-4586-A6B4-070DED62B644}.Release|x86.ActiveCfg = Release|x86
{175A9388-F352-4586-A6B4-070DED62B644}.Release|x86.Build.0 = Release|x86
- {B90AB8F2-1BFF-4568-A3FD-2A338A435A75}.Debug_Ubuntu|Any CPU.ActiveCfg = Debug|Any CPU
- {B90AB8F2-1BFF-4568-A3FD-2A338A435A75}.Debug_Ubuntu|Any CPU.Build.0 = Debug|Any CPU
- {B90AB8F2-1BFF-4568-A3FD-2A338A435A75}.Debug_Ubuntu|Mixed Platforms.ActiveCfg = Debug|Any CPU
- {B90AB8F2-1BFF-4568-A3FD-2A338A435A75}.Debug_Ubuntu|Mixed Platforms.Build.0 = Debug|Any CPU
- {B90AB8F2-1BFF-4568-A3FD-2A338A435A75}.Debug_Ubuntu|Win32.ActiveCfg = Debug|Any CPU
- {B90AB8F2-1BFF-4568-A3FD-2A338A435A75}.Debug_Ubuntu|x64.ActiveCfg = Debug|Any CPU
- {B90AB8F2-1BFF-4568-A3FD-2A338A435A75}.Debug_Ubuntu|x86.ActiveCfg = Debug|Any CPU
{B90AB8F2-1BFF-4568-A3FD-2A338A435A75}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{B90AB8F2-1BFF-4568-A3FD-2A338A435A75}.Debug|Any CPU.Build.0 = Debug|Any CPU
{B90AB8F2-1BFF-4568-A3FD-2A338A435A75}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
@@ -796,13 +505,6 @@ Global
{B90AB8F2-1BFF-4568-A3FD-2A338A435A75}.Release Mono|Win32.ActiveCfg = Release|Any CPU
{B90AB8F2-1BFF-4568-A3FD-2A338A435A75}.Release Mono|x64.ActiveCfg = Release|Any CPU
{B90AB8F2-1BFF-4568-A3FD-2A338A435A75}.Release Mono|x86.ActiveCfg = Release|Any CPU
- {B90AB8F2-1BFF-4568-A3FD-2A338A435A75}.Release_Ubuntu|Any CPU.ActiveCfg = Release|Any CPU
- {B90AB8F2-1BFF-4568-A3FD-2A338A435A75}.Release_Ubuntu|Any CPU.Build.0 = Release|Any CPU
- {B90AB8F2-1BFF-4568-A3FD-2A338A435A75}.Release_Ubuntu|Mixed Platforms.ActiveCfg = Release|Any CPU
- {B90AB8F2-1BFF-4568-A3FD-2A338A435A75}.Release_Ubuntu|Mixed Platforms.Build.0 = Release|Any CPU
- {B90AB8F2-1BFF-4568-A3FD-2A338A435A75}.Release_Ubuntu|Win32.ActiveCfg = Release|Any CPU
- {B90AB8F2-1BFF-4568-A3FD-2A338A435A75}.Release_Ubuntu|x64.ActiveCfg = Release|Any CPU
- {B90AB8F2-1BFF-4568-A3FD-2A338A435A75}.Release_Ubuntu|x86.ActiveCfg = Release|Any CPU
{B90AB8F2-1BFF-4568-A3FD-2A338A435A75}.Release|Any CPU.ActiveCfg = Release|Any CPU
{B90AB8F2-1BFF-4568-A3FD-2A338A435A75}.Release|Any CPU.Build.0 = Release|Any CPU
{B90AB8F2-1BFF-4568-A3FD-2A338A435A75}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
@@ -814,7 +516,4 @@ Global
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
- GlobalSection(Performance) = preSolution
- HasPerformanceSessions = true
- EndGlobalSection
EndGlobal
diff --git a/Nuget/MediaBrowser.Common.Internal.nuspec b/Nuget/MediaBrowser.Common.Internal.nuspec
index 1a0b144b02..c7cfeb9b8d 100644
--- a/Nuget/MediaBrowser.Common.Internal.nuspec
+++ b/Nuget/MediaBrowser.Common.Internal.nuspec
@@ -2,7 +2,7 @@
<package xmlns="http://schemas.microsoft.com/packaging/2011/08/nuspec.xsd">
<metadata>
<id>MediaBrowser.Common.Internal</id>
- <version>3.0.510</version>
+ <version>3.0.517</version>
<title>MediaBrowser.Common.Internal</title>
<authors>Luke</authors>
<owners>ebr,Luke,scottisafool</owners>
@@ -12,7 +12,7 @@
<description>Contains common components shared by Media Browser Theater and Media Browser Server. Not intended for plugin developer consumption.</description>
<copyright>Copyright © Media Browser 2013</copyright>
<dependencies>
- <dependency id="MediaBrowser.Common" version="3.0.510" />
+ <dependency id="MediaBrowser.Common" version="3.0.517" />
<dependency id="NLog" version="3.1.0.0" />
<dependency id="SimpleInjector" version="2.6.1" />
<dependency id="sharpcompress" version="0.10.2" />
diff --git a/Nuget/MediaBrowser.Common.nuspec b/Nuget/MediaBrowser.Common.nuspec
index 717d3c9347..16aa7b0246 100644
--- a/Nuget/MediaBrowser.Common.nuspec
+++ b/Nuget/MediaBrowser.Common.nuspec
@@ -2,7 +2,7 @@
<package xmlns="http://schemas.microsoft.com/packaging/2011/08/nuspec.xsd">
<metadata>
<id>MediaBrowser.Common</id>
- <version>3.0.510</version>
+ <version>3.0.517</version>
<title>MediaBrowser.Common</title>
<authors>Media Browser Team</authors>
<owners>ebr,Luke,scottisafool</owners>
diff --git a/Nuget/MediaBrowser.Model.Signed.nuspec b/Nuget/MediaBrowser.Model.Signed.nuspec
index 74126bbbf7..aa1acad97c 100644
--- a/Nuget/MediaBrowser.Model.Signed.nuspec
+++ b/Nuget/MediaBrowser.Model.Signed.nuspec
@@ -2,7 +2,7 @@
<package xmlns="http://schemas.microsoft.com/packaging/2011/08/nuspec.xsd">
<metadata>
<id>MediaBrowser.Model.Signed</id>
- <version>3.0.510</version>
+ <version>3.0.517</version>
<title>MediaBrowser.Model - Signed Edition</title>
<authors>Media Browser Team</authors>
<owners>ebr,Luke,scottisafool</owners>
diff --git a/Nuget/MediaBrowser.Server.Core.nuspec b/Nuget/MediaBrowser.Server.Core.nuspec
index ce0baf19e7..70c9ce9f30 100644
--- a/Nuget/MediaBrowser.Server.Core.nuspec
+++ b/Nuget/MediaBrowser.Server.Core.nuspec
@@ -2,7 +2,7 @@
<package xmlns="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd">
<metadata>
<id>MediaBrowser.Server.Core</id>
- <version>3.0.510</version>
+ <version>3.0.517</version>
<title>Media Browser.Server.Core</title>
<authors>Media Browser Team</authors>
<owners>ebr,Luke,scottisafool</owners>
@@ -12,7 +12,7 @@
<description>Contains core components required to build plugins for Media Browser Server.</description>
<copyright>Copyright © Media Browser 2013</copyright>
<dependencies>
- <dependency id="MediaBrowser.Common" version="3.0.510" />
+ <dependency id="MediaBrowser.Common" version="3.0.517" />
</dependencies>
</metadata>
<files>
diff --git a/SharedVersion.cs b/SharedVersion.cs
index e2d728f80b..b3958af167 100644
--- a/SharedVersion.cs
+++ b/SharedVersion.cs
@@ -1,8 +1,4 @@
using System.Reflection;
-#if (DEBUG)
-[assembly: AssemblyVersion("3.0.*")]
-#else
//[assembly: AssemblyVersion("3.0.*")]
-[assembly: AssemblyVersion("3.0.5445.6")]
-#endif
+[assembly: AssemblyVersion("3.0.5462.0")]