From ef6b90b8e6e6c317fcda85a392c79324f91250db Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Tue, 25 Oct 2016 15:02:04 -0400 Subject: make controller project portable --- .../Library/Resolvers/SpecialFolderResolver.cs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'MediaBrowser.Server.Implementations/Library/Resolvers/SpecialFolderResolver.cs') diff --git a/MediaBrowser.Server.Implementations/Library/Resolvers/SpecialFolderResolver.cs b/MediaBrowser.Server.Implementations/Library/Resolvers/SpecialFolderResolver.cs index 7bb66ed89..7a6198a00 100644 --- a/MediaBrowser.Server.Implementations/Library/Resolvers/SpecialFolderResolver.cs +++ b/MediaBrowser.Server.Implementations/Library/Resolvers/SpecialFolderResolver.cs @@ -5,7 +5,9 @@ using MediaBrowser.Controller.Resolvers; using System; using System.IO; using System.Linq; -using CommonIO; +using MediaBrowser.Common.IO; +using MediaBrowser.Controller.IO; +using MediaBrowser.Model.IO; namespace MediaBrowser.Server.Implementations.Library.Resolvers { @@ -67,7 +69,7 @@ namespace MediaBrowser.Server.Implementations.Library.Resolvers try { - return (i.Attributes & FileAttributes.Directory) != FileAttributes.Directory && + return !i.IsDirectory && string.Equals(".collection", i.Extension, StringComparison.OrdinalIgnoreCase); } catch (IOException) -- cgit v1.2.3 From 3eb4091808735858b01855d298226d239be464af Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Thu, 3 Nov 2016 02:37:52 -0400 Subject: move additional classes to new server lib --- .../Activity/ActivityManager.cs | 56 + Emby.Server.Implementations/Dto/DtoService.cs | 1609 ++++++++++ .../Emby.Server.Implementations.csproj | 99 +- .../FileOrganization/EpisodeFileOrganizer.cs | 834 ++++++ .../FileOrganization/Extensions.cs | 33 + .../FileOrganization/FileOrganizationNotifier.cs | 80 + .../FileOrganization/FileOrganizationService.cs | 283 ++ .../FileOrganization/NameUtils.cs | 81 + .../FileOrganization/OrganizerScheduledTask.cs | 101 + .../FileOrganization/TvFolderOrganizer.cs | 210 ++ .../Library/CoreResolutionIgnoreRule.cs | 148 + .../Library/LibraryManager.cs | 3066 +++++++++++++++++++ .../Library/LocalTrailerPostScanTask.cs | 102 + .../Library/MediaSourceManager.cs | 651 +++++ .../Library/MusicManager.cs | 157 + .../Library/PathExtensions.cs | 45 + .../Library/ResolverHelper.cs | 183 ++ .../Library/Resolvers/Audio/AudioResolver.cs | 68 + .../Library/Resolvers/Audio/MusicAlbumResolver.cs | 173 ++ .../Library/Resolvers/Audio/MusicArtistResolver.cs | 94 + .../Library/Resolvers/BaseVideoResolver.cs | 297 ++ .../Library/Resolvers/FolderResolver.cs | 56 + .../Library/Resolvers/ItemResolver.cs | 62 + .../Library/Resolvers/Movies/BoxSetResolver.cs | 77 + .../Library/Resolvers/Movies/MovieResolver.cs | 541 ++++ .../Library/Resolvers/PhotoAlbumResolver.cs | 56 + .../Library/Resolvers/PhotoResolver.cs | 103 + .../Library/Resolvers/PlaylistResolver.cs | 42 + .../Library/Resolvers/SpecialFolderResolver.cs | 85 + .../Library/Resolvers/TV/EpisodeResolver.cs | 75 + .../Library/Resolvers/TV/SeasonResolver.cs | 62 + .../Library/Resolvers/TV/SeriesResolver.cs | 251 ++ .../Library/Resolvers/VideoResolver.cs | 45 + .../Library/SearchEngine.cs | 275 ++ .../Library/UserViewManager.cs | 292 ++ .../Library/Validators/ArtistsPostScanTask.cs | 44 + .../Library/Validators/ArtistsValidator.cs | 84 + .../Library/Validators/GameGenresPostScanTask.cs | 45 + .../Library/Validators/GameGenresValidator.cs | 74 + .../Library/Validators/GenresPostScanTask.cs | 42 + .../Library/Validators/GenresValidator.cs | 75 + .../Library/Validators/MusicGenresPostScanTask.cs | 45 + .../Library/Validators/MusicGenresValidator.cs | 75 + .../Library/Validators/PeopleValidator.cs | 172 ++ .../Library/Validators/StudiosPostScanTask.cs | 45 + .../Library/Validators/StudiosValidator.cs | 74 + .../Library/Validators/YearsPostScanTask.cs | 55 + .../Logging/PatternsLogger.cs | 63 + .../Persistence/CleanDatabaseScheduledTask.cs | 361 +++ .../ScheduledTasks/RefreshMediaLibraryTask.cs | 96 + .../Sorting/AirTimeComparer.cs | 71 + .../Sorting/AiredEpisodeOrderComparer.cs | 160 + .../Sorting/AlbumArtistComparer.cs | 47 + .../Sorting/AlbumComparer.cs | 46 + .../Sorting/AlphanumComparator.cs | 99 + .../Sorting/ArtistComparer.cs | 51 + .../Sorting/BudgetComparer.cs | 39 + .../Sorting/CommunityRatingComparer.cs | 29 + .../Sorting/CriticRatingComparer.cs | 37 + .../Sorting/DateCreatedComparer.cs | 33 + .../Sorting/DateLastMediaAddedComparer.cs | 69 + .../Sorting/DatePlayedComparer.cs | 69 + .../Sorting/GameSystemComparer.cs | 54 + .../Sorting/IsFavoriteOrLikeComparer.cs | 58 + .../Sorting/IsFolderComparer.cs | 39 + .../Sorting/IsPlayedComparer.cs | 58 + .../Sorting/IsUnplayedComparer.cs | 58 + .../Sorting/MetascoreComparer.cs | 41 + .../Sorting/NameComparer.cs | 33 + .../Sorting/OfficialRatingComparer.cs | 40 + .../Sorting/PlayCountComparer.cs | 63 + .../Sorting/PlayersComparer.cs | 46 + .../Sorting/PremiereDateComparer.cs | 59 + .../Sorting/ProductionYearComparer.cs | 52 + .../Sorting/RandomComparer.cs | 33 + .../Sorting/RevenueComparer.cs | 39 + .../Sorting/RuntimeComparer.cs | 32 + .../Sorting/SeriesSortNameComparer.cs | 37 + .../Sorting/SortNameComparer.cs | 33 + .../Sorting/StartDateComparer.cs | 47 + .../Sorting/StudioComparer.cs | 30 + Emby.Server.Implementations/packages.config | 5 + .../Activity/ActivityManager.cs | 56 - .../Dto/DtoService.cs | 1609 ---------- .../FileOrganization/EpisodeFileOrganizer.cs | 831 ------ .../FileOrganization/Extensions.cs | 33 - .../FileOrganization/FileOrganizationNotifier.cs | 80 - .../FileOrganization/FileOrganizationService.cs | 283 -- .../FileOrganization/NameUtils.cs | 96 - .../FileOrganization/OrganizerScheduledTask.cs | 101 - .../FileOrganization/TvFolderOrganizer.cs | 210 -- .../IO/FileRefresher.cs | 22 +- .../IO/LibraryMonitor.cs | 9 +- .../Library/CoreResolutionIgnoreRule.cs | 148 - .../Library/LibraryManager.cs | 3067 -------------------- .../Library/LocalTrailerPostScanTask.cs | 102 - .../Library/MediaSourceManager.cs | 648 ----- .../Library/MusicManager.cs | 157 - .../Library/PathExtensions.cs | 45 - .../Library/ResolverHelper.cs | 183 -- .../Library/Resolvers/Audio/AudioResolver.cs | 68 - .../Library/Resolvers/Audio/MusicAlbumResolver.cs | 173 -- .../Library/Resolvers/Audio/MusicArtistResolver.cs | 94 - .../Library/Resolvers/BaseVideoResolver.cs | 297 -- .../Library/Resolvers/FolderResolver.cs | 56 - .../Library/Resolvers/ItemResolver.cs | 62 - .../Library/Resolvers/Movies/BoxSetResolver.cs | 77 - .../Library/Resolvers/Movies/MovieResolver.cs | 541 ---- .../Library/Resolvers/PhotoAlbumResolver.cs | 56 - .../Library/Resolvers/PhotoResolver.cs | 103 - .../Library/Resolvers/PlaylistResolver.cs | 42 - .../Library/Resolvers/SpecialFolderResolver.cs | 85 - .../Library/Resolvers/TV/EpisodeResolver.cs | 75 - .../Library/Resolvers/TV/SeasonResolver.cs | 62 - .../Library/Resolvers/TV/SeriesResolver.cs | 251 -- .../Library/Resolvers/VideoResolver.cs | 45 - .../Library/SearchEngine.cs | 280 -- .../Library/UserViewManager.cs | 292 -- .../Library/Validators/ArtistsPostScanTask.cs | 44 - .../Library/Validators/ArtistsValidator.cs | 84 - .../Library/Validators/GameGenresPostScanTask.cs | 45 - .../Library/Validators/GameGenresValidator.cs | 74 - .../Library/Validators/GenresPostScanTask.cs | 42 - .../Library/Validators/GenresValidator.cs | 75 - .../Library/Validators/MusicGenresPostScanTask.cs | 45 - .../Library/Validators/MusicGenresValidator.cs | 75 - .../Library/Validators/PeopleValidator.cs | 172 -- .../Library/Validators/StudiosPostScanTask.cs | 45 - .../Library/Validators/StudiosValidator.cs | 74 - .../Library/Validators/YearsPostScanTask.cs | 55 - .../LiveTv/EmbyTV/EmbyTV.cs | 45 +- .../MediaBrowser.Server.Implementations.csproj | 79 - .../Persistence/CleanDatabaseScheduledTask.cs | 360 --- .../ScheduledTasks/RefreshMediaLibraryTask.cs | 96 - .../Sorting/AirTimeComparer.cs | 71 - .../Sorting/AiredEpisodeOrderComparer.cs | 160 - .../Sorting/AlbumArtistComparer.cs | 47 - .../Sorting/AlbumComparer.cs | 46 - .../Sorting/AlphanumComparator.cs | 99 - .../Sorting/ArtistComparer.cs | 51 - .../Sorting/BudgetComparer.cs | 39 - .../Sorting/CommunityRatingComparer.cs | 29 - .../Sorting/CriticRatingComparer.cs | 37 - .../Sorting/DateCreatedComparer.cs | 33 - .../Sorting/DateLastMediaAddedComparer.cs | 69 - .../Sorting/DatePlayedComparer.cs | 69 - .../Sorting/GameSystemComparer.cs | 54 - .../Sorting/IsFavoriteOrLikeComparer.cs | 58 - .../Sorting/IsFolderComparer.cs | 39 - .../Sorting/IsPlayedComparer.cs | 58 - .../Sorting/IsUnplayedComparer.cs | 58 - .../Sorting/MetascoreComparer.cs | 41 - .../Sorting/NameComparer.cs | 33 - .../Sorting/OfficialRatingComparer.cs | 40 - .../Sorting/PlayCountComparer.cs | 63 - .../Sorting/PlayersComparer.cs | 46 - .../Sorting/PremiereDateComparer.cs | 59 - .../Sorting/ProductionYearComparer.cs | 52 - .../Sorting/RandomComparer.cs | 33 - .../Sorting/RevenueComparer.cs | 39 - .../Sorting/RuntimeComparer.cs | 32 - .../Sorting/SeriesSortNameComparer.cs | 37 - .../Sorting/SortNameComparer.cs | 33 - .../Sorting/StartDateComparer.cs | 47 - .../Sorting/StudioComparer.cs | 30 - .../ApplicationHost.cs | 11 +- .../Migrations/DbMigration.cs | 1 + 167 files changed, 13394 insertions(+), 13318 deletions(-) create mode 100644 Emby.Server.Implementations/Activity/ActivityManager.cs create mode 100644 Emby.Server.Implementations/Dto/DtoService.cs create mode 100644 Emby.Server.Implementations/FileOrganization/EpisodeFileOrganizer.cs create mode 100644 Emby.Server.Implementations/FileOrganization/Extensions.cs create mode 100644 Emby.Server.Implementations/FileOrganization/FileOrganizationNotifier.cs create mode 100644 Emby.Server.Implementations/FileOrganization/FileOrganizationService.cs create mode 100644 Emby.Server.Implementations/FileOrganization/NameUtils.cs create mode 100644 Emby.Server.Implementations/FileOrganization/OrganizerScheduledTask.cs create mode 100644 Emby.Server.Implementations/FileOrganization/TvFolderOrganizer.cs create mode 100644 Emby.Server.Implementations/Library/CoreResolutionIgnoreRule.cs create mode 100644 Emby.Server.Implementations/Library/LibraryManager.cs create mode 100644 Emby.Server.Implementations/Library/LocalTrailerPostScanTask.cs create mode 100644 Emby.Server.Implementations/Library/MediaSourceManager.cs create mode 100644 Emby.Server.Implementations/Library/MusicManager.cs create mode 100644 Emby.Server.Implementations/Library/PathExtensions.cs create mode 100644 Emby.Server.Implementations/Library/ResolverHelper.cs create mode 100644 Emby.Server.Implementations/Library/Resolvers/Audio/AudioResolver.cs create mode 100644 Emby.Server.Implementations/Library/Resolvers/Audio/MusicAlbumResolver.cs create mode 100644 Emby.Server.Implementations/Library/Resolvers/Audio/MusicArtistResolver.cs create mode 100644 Emby.Server.Implementations/Library/Resolvers/BaseVideoResolver.cs create mode 100644 Emby.Server.Implementations/Library/Resolvers/FolderResolver.cs create mode 100644 Emby.Server.Implementations/Library/Resolvers/ItemResolver.cs create mode 100644 Emby.Server.Implementations/Library/Resolvers/Movies/BoxSetResolver.cs create mode 100644 Emby.Server.Implementations/Library/Resolvers/Movies/MovieResolver.cs create mode 100644 Emby.Server.Implementations/Library/Resolvers/PhotoAlbumResolver.cs create mode 100644 Emby.Server.Implementations/Library/Resolvers/PhotoResolver.cs create mode 100644 Emby.Server.Implementations/Library/Resolvers/PlaylistResolver.cs create mode 100644 Emby.Server.Implementations/Library/Resolvers/SpecialFolderResolver.cs create mode 100644 Emby.Server.Implementations/Library/Resolvers/TV/EpisodeResolver.cs create mode 100644 Emby.Server.Implementations/Library/Resolvers/TV/SeasonResolver.cs create mode 100644 Emby.Server.Implementations/Library/Resolvers/TV/SeriesResolver.cs create mode 100644 Emby.Server.Implementations/Library/Resolvers/VideoResolver.cs create mode 100644 Emby.Server.Implementations/Library/SearchEngine.cs create mode 100644 Emby.Server.Implementations/Library/UserViewManager.cs create mode 100644 Emby.Server.Implementations/Library/Validators/ArtistsPostScanTask.cs create mode 100644 Emby.Server.Implementations/Library/Validators/ArtistsValidator.cs create mode 100644 Emby.Server.Implementations/Library/Validators/GameGenresPostScanTask.cs create mode 100644 Emby.Server.Implementations/Library/Validators/GameGenresValidator.cs create mode 100644 Emby.Server.Implementations/Library/Validators/GenresPostScanTask.cs create mode 100644 Emby.Server.Implementations/Library/Validators/GenresValidator.cs create mode 100644 Emby.Server.Implementations/Library/Validators/MusicGenresPostScanTask.cs create mode 100644 Emby.Server.Implementations/Library/Validators/MusicGenresValidator.cs create mode 100644 Emby.Server.Implementations/Library/Validators/PeopleValidator.cs create mode 100644 Emby.Server.Implementations/Library/Validators/StudiosPostScanTask.cs create mode 100644 Emby.Server.Implementations/Library/Validators/StudiosValidator.cs create mode 100644 Emby.Server.Implementations/Library/Validators/YearsPostScanTask.cs create mode 100644 Emby.Server.Implementations/Logging/PatternsLogger.cs create mode 100644 Emby.Server.Implementations/Persistence/CleanDatabaseScheduledTask.cs create mode 100644 Emby.Server.Implementations/ScheduledTasks/RefreshMediaLibraryTask.cs create mode 100644 Emby.Server.Implementations/Sorting/AirTimeComparer.cs create mode 100644 Emby.Server.Implementations/Sorting/AiredEpisodeOrderComparer.cs create mode 100644 Emby.Server.Implementations/Sorting/AlbumArtistComparer.cs create mode 100644 Emby.Server.Implementations/Sorting/AlbumComparer.cs create mode 100644 Emby.Server.Implementations/Sorting/AlphanumComparator.cs create mode 100644 Emby.Server.Implementations/Sorting/ArtistComparer.cs create mode 100644 Emby.Server.Implementations/Sorting/BudgetComparer.cs create mode 100644 Emby.Server.Implementations/Sorting/CommunityRatingComparer.cs create mode 100644 Emby.Server.Implementations/Sorting/CriticRatingComparer.cs create mode 100644 Emby.Server.Implementations/Sorting/DateCreatedComparer.cs create mode 100644 Emby.Server.Implementations/Sorting/DateLastMediaAddedComparer.cs create mode 100644 Emby.Server.Implementations/Sorting/DatePlayedComparer.cs create mode 100644 Emby.Server.Implementations/Sorting/GameSystemComparer.cs create mode 100644 Emby.Server.Implementations/Sorting/IsFavoriteOrLikeComparer.cs create mode 100644 Emby.Server.Implementations/Sorting/IsFolderComparer.cs create mode 100644 Emby.Server.Implementations/Sorting/IsPlayedComparer.cs create mode 100644 Emby.Server.Implementations/Sorting/IsUnplayedComparer.cs create mode 100644 Emby.Server.Implementations/Sorting/MetascoreComparer.cs create mode 100644 Emby.Server.Implementations/Sorting/NameComparer.cs create mode 100644 Emby.Server.Implementations/Sorting/OfficialRatingComparer.cs create mode 100644 Emby.Server.Implementations/Sorting/PlayCountComparer.cs create mode 100644 Emby.Server.Implementations/Sorting/PlayersComparer.cs create mode 100644 Emby.Server.Implementations/Sorting/PremiereDateComparer.cs create mode 100644 Emby.Server.Implementations/Sorting/ProductionYearComparer.cs create mode 100644 Emby.Server.Implementations/Sorting/RandomComparer.cs create mode 100644 Emby.Server.Implementations/Sorting/RevenueComparer.cs create mode 100644 Emby.Server.Implementations/Sorting/RuntimeComparer.cs create mode 100644 Emby.Server.Implementations/Sorting/SeriesSortNameComparer.cs create mode 100644 Emby.Server.Implementations/Sorting/SortNameComparer.cs create mode 100644 Emby.Server.Implementations/Sorting/StartDateComparer.cs create mode 100644 Emby.Server.Implementations/Sorting/StudioComparer.cs create mode 100644 Emby.Server.Implementations/packages.config delete mode 100644 MediaBrowser.Server.Implementations/Activity/ActivityManager.cs delete mode 100644 MediaBrowser.Server.Implementations/Dto/DtoService.cs delete mode 100644 MediaBrowser.Server.Implementations/FileOrganization/EpisodeFileOrganizer.cs delete mode 100644 MediaBrowser.Server.Implementations/FileOrganization/Extensions.cs delete mode 100644 MediaBrowser.Server.Implementations/FileOrganization/FileOrganizationNotifier.cs delete mode 100644 MediaBrowser.Server.Implementations/FileOrganization/FileOrganizationService.cs delete mode 100644 MediaBrowser.Server.Implementations/FileOrganization/NameUtils.cs delete mode 100644 MediaBrowser.Server.Implementations/FileOrganization/OrganizerScheduledTask.cs delete mode 100644 MediaBrowser.Server.Implementations/FileOrganization/TvFolderOrganizer.cs delete mode 100644 MediaBrowser.Server.Implementations/Library/CoreResolutionIgnoreRule.cs delete mode 100644 MediaBrowser.Server.Implementations/Library/LibraryManager.cs delete mode 100644 MediaBrowser.Server.Implementations/Library/LocalTrailerPostScanTask.cs delete mode 100644 MediaBrowser.Server.Implementations/Library/MediaSourceManager.cs delete mode 100644 MediaBrowser.Server.Implementations/Library/MusicManager.cs delete mode 100644 MediaBrowser.Server.Implementations/Library/PathExtensions.cs delete mode 100644 MediaBrowser.Server.Implementations/Library/ResolverHelper.cs delete mode 100644 MediaBrowser.Server.Implementations/Library/Resolvers/Audio/AudioResolver.cs delete mode 100644 MediaBrowser.Server.Implementations/Library/Resolvers/Audio/MusicAlbumResolver.cs delete mode 100644 MediaBrowser.Server.Implementations/Library/Resolvers/Audio/MusicArtistResolver.cs delete mode 100644 MediaBrowser.Server.Implementations/Library/Resolvers/BaseVideoResolver.cs delete mode 100644 MediaBrowser.Server.Implementations/Library/Resolvers/FolderResolver.cs delete mode 100644 MediaBrowser.Server.Implementations/Library/Resolvers/ItemResolver.cs delete mode 100644 MediaBrowser.Server.Implementations/Library/Resolvers/Movies/BoxSetResolver.cs delete mode 100644 MediaBrowser.Server.Implementations/Library/Resolvers/Movies/MovieResolver.cs delete mode 100644 MediaBrowser.Server.Implementations/Library/Resolvers/PhotoAlbumResolver.cs delete mode 100644 MediaBrowser.Server.Implementations/Library/Resolvers/PhotoResolver.cs delete mode 100644 MediaBrowser.Server.Implementations/Library/Resolvers/PlaylistResolver.cs delete mode 100644 MediaBrowser.Server.Implementations/Library/Resolvers/SpecialFolderResolver.cs delete mode 100644 MediaBrowser.Server.Implementations/Library/Resolvers/TV/EpisodeResolver.cs delete mode 100644 MediaBrowser.Server.Implementations/Library/Resolvers/TV/SeasonResolver.cs delete mode 100644 MediaBrowser.Server.Implementations/Library/Resolvers/TV/SeriesResolver.cs delete mode 100644 MediaBrowser.Server.Implementations/Library/Resolvers/VideoResolver.cs delete mode 100644 MediaBrowser.Server.Implementations/Library/SearchEngine.cs delete mode 100644 MediaBrowser.Server.Implementations/Library/UserViewManager.cs delete mode 100644 MediaBrowser.Server.Implementations/Library/Validators/ArtistsPostScanTask.cs delete mode 100644 MediaBrowser.Server.Implementations/Library/Validators/ArtistsValidator.cs delete mode 100644 MediaBrowser.Server.Implementations/Library/Validators/GameGenresPostScanTask.cs delete mode 100644 MediaBrowser.Server.Implementations/Library/Validators/GameGenresValidator.cs delete mode 100644 MediaBrowser.Server.Implementations/Library/Validators/GenresPostScanTask.cs delete mode 100644 MediaBrowser.Server.Implementations/Library/Validators/GenresValidator.cs delete mode 100644 MediaBrowser.Server.Implementations/Library/Validators/MusicGenresPostScanTask.cs delete mode 100644 MediaBrowser.Server.Implementations/Library/Validators/MusicGenresValidator.cs delete mode 100644 MediaBrowser.Server.Implementations/Library/Validators/PeopleValidator.cs delete mode 100644 MediaBrowser.Server.Implementations/Library/Validators/StudiosPostScanTask.cs delete mode 100644 MediaBrowser.Server.Implementations/Library/Validators/StudiosValidator.cs delete mode 100644 MediaBrowser.Server.Implementations/Library/Validators/YearsPostScanTask.cs delete mode 100644 MediaBrowser.Server.Implementations/Persistence/CleanDatabaseScheduledTask.cs delete mode 100644 MediaBrowser.Server.Implementations/ScheduledTasks/RefreshMediaLibraryTask.cs delete mode 100644 MediaBrowser.Server.Implementations/Sorting/AirTimeComparer.cs delete mode 100644 MediaBrowser.Server.Implementations/Sorting/AiredEpisodeOrderComparer.cs delete mode 100644 MediaBrowser.Server.Implementations/Sorting/AlbumArtistComparer.cs delete mode 100644 MediaBrowser.Server.Implementations/Sorting/AlbumComparer.cs delete mode 100644 MediaBrowser.Server.Implementations/Sorting/AlphanumComparator.cs delete mode 100644 MediaBrowser.Server.Implementations/Sorting/ArtistComparer.cs delete mode 100644 MediaBrowser.Server.Implementations/Sorting/BudgetComparer.cs delete mode 100644 MediaBrowser.Server.Implementations/Sorting/CommunityRatingComparer.cs delete mode 100644 MediaBrowser.Server.Implementations/Sorting/CriticRatingComparer.cs delete mode 100644 MediaBrowser.Server.Implementations/Sorting/DateCreatedComparer.cs delete mode 100644 MediaBrowser.Server.Implementations/Sorting/DateLastMediaAddedComparer.cs delete mode 100644 MediaBrowser.Server.Implementations/Sorting/DatePlayedComparer.cs delete mode 100644 MediaBrowser.Server.Implementations/Sorting/GameSystemComparer.cs delete mode 100644 MediaBrowser.Server.Implementations/Sorting/IsFavoriteOrLikeComparer.cs delete mode 100644 MediaBrowser.Server.Implementations/Sorting/IsFolderComparer.cs delete mode 100644 MediaBrowser.Server.Implementations/Sorting/IsPlayedComparer.cs delete mode 100644 MediaBrowser.Server.Implementations/Sorting/IsUnplayedComparer.cs delete mode 100644 MediaBrowser.Server.Implementations/Sorting/MetascoreComparer.cs delete mode 100644 MediaBrowser.Server.Implementations/Sorting/NameComparer.cs delete mode 100644 MediaBrowser.Server.Implementations/Sorting/OfficialRatingComparer.cs delete mode 100644 MediaBrowser.Server.Implementations/Sorting/PlayCountComparer.cs delete mode 100644 MediaBrowser.Server.Implementations/Sorting/PlayersComparer.cs delete mode 100644 MediaBrowser.Server.Implementations/Sorting/PremiereDateComparer.cs delete mode 100644 MediaBrowser.Server.Implementations/Sorting/ProductionYearComparer.cs delete mode 100644 MediaBrowser.Server.Implementations/Sorting/RandomComparer.cs delete mode 100644 MediaBrowser.Server.Implementations/Sorting/RevenueComparer.cs delete mode 100644 MediaBrowser.Server.Implementations/Sorting/RuntimeComparer.cs delete mode 100644 MediaBrowser.Server.Implementations/Sorting/SeriesSortNameComparer.cs delete mode 100644 MediaBrowser.Server.Implementations/Sorting/SortNameComparer.cs delete mode 100644 MediaBrowser.Server.Implementations/Sorting/StartDateComparer.cs delete mode 100644 MediaBrowser.Server.Implementations/Sorting/StudioComparer.cs (limited to 'MediaBrowser.Server.Implementations/Library/Resolvers/SpecialFolderResolver.cs') diff --git a/Emby.Server.Implementations/Activity/ActivityManager.cs b/Emby.Server.Implementations/Activity/ActivityManager.cs new file mode 100644 index 000000000..b6095f082 --- /dev/null +++ b/Emby.Server.Implementations/Activity/ActivityManager.cs @@ -0,0 +1,56 @@ +using MediaBrowser.Common.Events; +using MediaBrowser.Controller.Library; +using MediaBrowser.Model.Activity; +using MediaBrowser.Model.Events; +using MediaBrowser.Model.Logging; +using MediaBrowser.Model.Querying; +using System; +using System.Linq; +using System.Threading.Tasks; + +namespace Emby.Server.Implementations.Activity +{ + public class ActivityManager : IActivityManager + { + public event EventHandler> EntryCreated; + + private readonly IActivityRepository _repo; + private readonly ILogger _logger; + private readonly IUserManager _userManager; + + public ActivityManager(ILogger logger, IActivityRepository repo, IUserManager userManager) + { + _logger = logger; + _repo = repo; + _userManager = userManager; + } + + public async Task Create(ActivityLogEntry entry) + { + entry.Id = Guid.NewGuid().ToString("N"); + entry.Date = DateTime.UtcNow; + + await _repo.Create(entry).ConfigureAwait(false); + + EventHelper.FireEventIfNotNull(EntryCreated, this, new GenericEventArgs(entry), _logger); + } + + public QueryResult GetActivityLogEntries(DateTime? minDate, int? startIndex, int? limit) + { + var result = _repo.GetActivityLogEntries(minDate, startIndex, limit); + + foreach (var item in result.Items.Where(i => !string.IsNullOrWhiteSpace(i.UserId))) + { + var user = _userManager.GetUserById(item.UserId); + + if (user != null) + { + var dto = _userManager.GetUserDto(user); + item.UserPrimaryImageTag = dto.PrimaryImageTag; + } + } + + return result; + } + } +} diff --git a/Emby.Server.Implementations/Dto/DtoService.cs b/Emby.Server.Implementations/Dto/DtoService.cs new file mode 100644 index 000000000..85549439b --- /dev/null +++ b/Emby.Server.Implementations/Dto/DtoService.cs @@ -0,0 +1,1609 @@ +using MediaBrowser.Common; +using MediaBrowser.Controller.Channels; +using MediaBrowser.Controller.Configuration; +using MediaBrowser.Controller.Devices; +using MediaBrowser.Controller.Drawing; +using MediaBrowser.Controller.Dto; +using MediaBrowser.Controller.Entities; +using MediaBrowser.Controller.Entities.Audio; +using MediaBrowser.Controller.Entities.Movies; +using MediaBrowser.Controller.Entities.TV; +using MediaBrowser.Controller.Library; +using MediaBrowser.Controller.LiveTv; +using MediaBrowser.Controller.Persistence; +using MediaBrowser.Controller.Providers; +using MediaBrowser.Controller.Sync; +using MediaBrowser.Model.Drawing; +using MediaBrowser.Model.Dto; +using MediaBrowser.Model.Entities; +using MediaBrowser.Model.Logging; +using MediaBrowser.Model.Querying; +using MediaBrowser.Model.Sync; +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Threading.Tasks; +using MediaBrowser.Common.IO; +using MediaBrowser.Controller.IO; +using MediaBrowser.Model.IO; +using MediaBrowser.Model.Extensions; + +namespace Emby.Server.Implementations.Dto +{ + public class DtoService : IDtoService + { + private readonly ILogger _logger; + private readonly ILibraryManager _libraryManager; + private readonly IUserDataManager _userDataRepository; + private readonly IItemRepository _itemRepo; + + private readonly IImageProcessor _imageProcessor; + private readonly IServerConfigurationManager _config; + private readonly IFileSystem _fileSystem; + private readonly IProviderManager _providerManager; + + private readonly Func _channelManagerFactory; + private readonly ISyncManager _syncManager; + private readonly IApplicationHost _appHost; + private readonly Func _deviceManager; + private readonly Func _mediaSourceManager; + private readonly Func _livetvManager; + + public DtoService(ILogger logger, ILibraryManager libraryManager, IUserDataManager userDataRepository, IItemRepository itemRepo, IImageProcessor imageProcessor, IServerConfigurationManager config, IFileSystem fileSystem, IProviderManager providerManager, Func channelManagerFactory, ISyncManager syncManager, IApplicationHost appHost, Func deviceManager, Func mediaSourceManager, Func livetvManager) + { + _logger = logger; + _libraryManager = libraryManager; + _userDataRepository = userDataRepository; + _itemRepo = itemRepo; + _imageProcessor = imageProcessor; + _config = config; + _fileSystem = fileSystem; + _providerManager = providerManager; + _channelManagerFactory = channelManagerFactory; + _syncManager = syncManager; + _appHost = appHost; + _deviceManager = deviceManager; + _mediaSourceManager = mediaSourceManager; + _livetvManager = livetvManager; + } + + /// + /// Converts a BaseItem to a DTOBaseItem + /// + /// The item. + /// The fields. + /// The user. + /// The owner. + /// Task{DtoBaseItem}. + /// item + public BaseItemDto GetBaseItemDto(BaseItem item, List fields, User user = null, BaseItem owner = null) + { + var options = new DtoOptions + { + Fields = fields + }; + + return GetBaseItemDto(item, options, user, owner); + } + + public async Task> GetBaseItemDtos(IEnumerable items, DtoOptions options, User user = null, BaseItem owner = null) + { + if (items == null) + { + throw new ArgumentNullException("items"); + } + + if (options == null) + { + throw new ArgumentNullException("options"); + } + + var syncDictionary = GetSyncedItemProgress(options); + + var list = new List(); + var programTuples = new List>(); + var channelTuples = new List>(); + + foreach (var item in items) + { + var dto = await GetBaseItemDtoInternal(item, options, user, owner).ConfigureAwait(false); + + var tvChannel = item as LiveTvChannel; + if (tvChannel != null) + { + channelTuples.Add(new Tuple(dto, tvChannel)); + } + else if (item is LiveTvProgram) + { + programTuples.Add(new Tuple(item, dto)); + } + + var byName = item as IItemByName; + + if (byName != null) + { + if (options.Fields.Contains(ItemFields.ItemCounts)) + { + var libraryItems = byName.GetTaggedItems(new InternalItemsQuery(user) + { + Recursive = true + }); + + SetItemByNameInfo(item, dto, libraryItems.ToList(), user); + } + } + + FillSyncInfo(dto, item, options, user, syncDictionary); + + list.Add(dto); + } + + if (programTuples.Count > 0) + { + await _livetvManager().AddInfoToProgramDto(programTuples, options.Fields, user).ConfigureAwait(false); + } + + if (channelTuples.Count > 0) + { + _livetvManager().AddChannelInfo(channelTuples, options, user); + } + + return list; + } + + public BaseItemDto GetBaseItemDto(BaseItem item, DtoOptions options, User user = null, BaseItem owner = null) + { + var syncDictionary = GetSyncedItemProgress(options); + + var dto = GetBaseItemDtoInternal(item, options, user, owner).Result; + var tvChannel = item as LiveTvChannel; + if (tvChannel != null) + { + var list = new List> { new Tuple(dto, tvChannel) }; + _livetvManager().AddChannelInfo(list, options, user); + } + else if (item is LiveTvProgram) + { + var list = new List> { new Tuple(item, dto) }; + var task = _livetvManager().AddInfoToProgramDto(list, options.Fields, user); + Task.WaitAll(task); + } + + var byName = item as IItemByName; + + if (byName != null) + { + if (options.Fields.Contains(ItemFields.ItemCounts)) + { + SetItemByNameInfo(item, dto, GetTaggedItems(byName, user), user); + } + + FillSyncInfo(dto, item, options, user, syncDictionary); + return dto; + } + + FillSyncInfo(dto, item, options, user, syncDictionary); + + return dto; + } + + private List GetTaggedItems(IItemByName byName, User user) + { + var items = byName.GetTaggedItems(new InternalItemsQuery(user) + { + Recursive = true + + }).ToList(); + + return items; + } + + public Dictionary GetSyncedItemProgress(DtoOptions options) + { + if (!options.Fields.Contains(ItemFields.BasicSyncInfo) && + !options.Fields.Contains(ItemFields.SyncInfo)) + { + return new Dictionary(); + } + + var deviceId = options.DeviceId; + if (string.IsNullOrWhiteSpace(deviceId)) + { + return new Dictionary(); + } + + var caps = _deviceManager().GetCapabilities(deviceId); + if (caps == null || !caps.SupportsSync) + { + return new Dictionary(); + } + + return _syncManager.GetSyncedItemProgresses(new SyncJobItemQuery + { + TargetId = deviceId, + Statuses = new[] + { + SyncJobItemStatus.Converting, + SyncJobItemStatus.Queued, + SyncJobItemStatus.Transferring, + SyncJobItemStatus.ReadyToTransfer, + SyncJobItemStatus.Synced + } + }); + } + + public void FillSyncInfo(IEnumerable> tuples, DtoOptions options, User user) + { + if (options.Fields.Contains(ItemFields.BasicSyncInfo) || + options.Fields.Contains(ItemFields.SyncInfo)) + { + var syncProgress = GetSyncedItemProgress(options); + + foreach (var tuple in tuples) + { + var item = tuple.Item1; + + FillSyncInfo(tuple.Item2, item, options, user, syncProgress); + } + } + } + + private void FillSyncInfo(IHasSyncInfo dto, BaseItem item, DtoOptions options, User user, Dictionary syncProgress) + { + var hasFullSyncInfo = options.Fields.Contains(ItemFields.SyncInfo); + + if (!options.Fields.Contains(ItemFields.BasicSyncInfo) && + !hasFullSyncInfo) + { + return; + } + + if (dto.SupportsSync ?? false) + { + SyncedItemProgress syncStatus; + if (syncProgress.TryGetValue(dto.Id, out syncStatus)) + { + if (syncStatus.Status == SyncJobItemStatus.Synced) + { + dto.SyncPercent = 100; + } + else + { + dto.SyncPercent = syncStatus.Progress; + } + + if (hasFullSyncInfo) + { + dto.HasSyncJob = true; + dto.SyncStatus = syncStatus.Status; + } + } + } + } + + private async Task GetBaseItemDtoInternal(BaseItem item, DtoOptions options, User user = null, BaseItem owner = null) + { + var fields = options.Fields; + + if (item == null) + { + throw new ArgumentNullException("item"); + } + + if (fields == null) + { + throw new ArgumentNullException("fields"); + } + + var dto = new BaseItemDto + { + ServerId = _appHost.SystemId + }; + + if (item.SourceType == SourceType.Channel) + { + dto.SourceType = item.SourceType.ToString(); + } + + if (fields.Contains(ItemFields.People)) + { + AttachPeople(dto, item); + } + + if (fields.Contains(ItemFields.PrimaryImageAspectRatio)) + { + try + { + AttachPrimaryImageAspectRatio(dto, item); + } + catch (Exception ex) + { + // Have to use a catch-all unfortunately because some .net image methods throw plain Exceptions + _logger.ErrorException("Error generating PrimaryImageAspectRatio for {0}", ex, item.Name); + } + } + + if (fields.Contains(ItemFields.DisplayPreferencesId)) + { + dto.DisplayPreferencesId = item.DisplayPreferencesId.ToString("N"); + } + + if (user != null) + { + await AttachUserSpecificInfo(dto, item, user, options).ConfigureAwait(false); + } + + var hasMediaSources = item as IHasMediaSources; + if (hasMediaSources != null) + { + if (fields.Contains(ItemFields.MediaSources)) + { + if (user == null) + { + dto.MediaSources = _mediaSourceManager().GetStaticMediaSources(hasMediaSources, true).ToList(); + } + else + { + dto.MediaSources = _mediaSourceManager().GetStaticMediaSources(hasMediaSources, true, user).ToList(); + } + } + } + + if (fields.Contains(ItemFields.Studios)) + { + AttachStudios(dto, item); + } + + AttachBasicFields(dto, item, owner, options); + + var collectionFolder = item as ICollectionFolder; + if (collectionFolder != null) + { + dto.OriginalCollectionType = collectionFolder.CollectionType; + + dto.CollectionType = user == null ? + collectionFolder.CollectionType : + collectionFolder.GetViewType(user); + } + + if (fields.Contains(ItemFields.CanDelete)) + { + dto.CanDelete = user == null + ? item.CanDelete() + : item.CanDelete(user); + } + + if (fields.Contains(ItemFields.CanDownload)) + { + dto.CanDownload = user == null + ? item.CanDownload() + : item.CanDownload(user); + } + + if (fields.Contains(ItemFields.Etag)) + { + dto.Etag = item.GetEtag(user); + } + + if (item is ILiveTvRecording) + { + _livetvManager().AddInfoToRecordingDto(item, dto, user); + } + + return dto; + } + + public BaseItemDto GetItemByNameDto(BaseItem item, DtoOptions options, List taggedItems, Dictionary syncProgress, User user = null) + { + var dto = GetBaseItemDtoInternal(item, options, user).Result; + + if (taggedItems != null && options.Fields.Contains(ItemFields.ItemCounts)) + { + SetItemByNameInfo(item, dto, taggedItems, user); + } + + FillSyncInfo(dto, item, options, user, syncProgress); + + return dto; + } + + private void SetItemByNameInfo(BaseItem item, BaseItemDto dto, List taggedItems, User user = null) + { + if (item is MusicArtist) + { + dto.AlbumCount = taggedItems.Count(i => i is MusicAlbum); + dto.MusicVideoCount = taggedItems.Count(i => i is MusicVideo); + dto.SongCount = taggedItems.Count(i => i is Audio); + } + else if (item is MusicGenre) + { + dto.ArtistCount = taggedItems.Count(i => i is MusicArtist); + dto.AlbumCount = taggedItems.Count(i => i is MusicAlbum); + dto.MusicVideoCount = taggedItems.Count(i => i is MusicVideo); + dto.SongCount = taggedItems.Count(i => i is Audio); + } + else if (item is GameGenre) + { + dto.GameCount = taggedItems.Count(i => i is Game); + } + else + { + // This populates them all and covers Genre, Person, Studio, Year + + dto.ArtistCount = taggedItems.Count(i => i is MusicArtist); + dto.AlbumCount = taggedItems.Count(i => i is MusicAlbum); + dto.EpisodeCount = taggedItems.Count(i => i is Episode); + dto.GameCount = taggedItems.Count(i => i is Game); + dto.MovieCount = taggedItems.Count(i => i is Movie); + dto.TrailerCount = taggedItems.Count(i => i is Trailer); + dto.MusicVideoCount = taggedItems.Count(i => i is MusicVideo); + dto.SeriesCount = taggedItems.Count(i => i is Series); + dto.ProgramCount = taggedItems.Count(i => i is LiveTvProgram); + dto.SongCount = taggedItems.Count(i => i is Audio); + } + + dto.ChildCount = taggedItems.Count; + } + + /// + /// Attaches the user specific info. + /// + private async Task AttachUserSpecificInfo(BaseItemDto dto, BaseItem item, User user, DtoOptions dtoOptions) + { + var fields = dtoOptions.Fields; + + if (item.IsFolder) + { + var folder = (Folder)item; + + if (dtoOptions.EnableUserData) + { + dto.UserData = await _userDataRepository.GetUserDataDto(item, dto, user).ConfigureAwait(false); + } + + if (!dto.ChildCount.HasValue && item.SourceType == SourceType.Library) + { + dto.ChildCount = GetChildCount(folder, user); + } + + if (fields.Contains(ItemFields.CumulativeRunTimeTicks)) + { + dto.CumulativeRunTimeTicks = item.RunTimeTicks; + } + + if (fields.Contains(ItemFields.DateLastMediaAdded)) + { + dto.DateLastMediaAdded = folder.DateLastMediaAdded; + } + } + + else + { + if (dtoOptions.EnableUserData) + { + dto.UserData = _userDataRepository.GetUserDataDto(item, user).Result; + } + } + + dto.PlayAccess = item.GetPlayAccess(user); + + if (fields.Contains(ItemFields.BasicSyncInfo) || fields.Contains(ItemFields.SyncInfo)) + { + var userCanSync = user != null && user.Policy.EnableSync; + if (userCanSync && _syncManager.SupportsSync(item)) + { + dto.SupportsSync = true; + } + } + + if (fields.Contains(ItemFields.SeasonUserData)) + { + var episode = item as Episode; + + if (episode != null) + { + var season = episode.Season; + + if (season != null) + { + dto.SeasonUserData = await _userDataRepository.GetUserDataDto(season, user).ConfigureAwait(false); + } + } + } + + var userView = item as UserView; + if (userView != null) + { + dto.HasDynamicCategories = userView.ContainsDynamicCategories(user); + } + + var collectionFolder = item as ICollectionFolder; + if (collectionFolder != null) + { + dto.HasDynamicCategories = false; + } + } + + private int GetChildCount(Folder folder, User user) + { + // Right now this is too slow to calculate for top level folders on a per-user basis + // Just return something so that apps that are expecting a value won't think the folders are empty + if (folder is ICollectionFolder || folder is UserView) + { + return new Random().Next(1, 10); + } + + return folder.GetChildCount(user); + } + + /// + /// Gets client-side Id of a server-side BaseItem + /// + /// The item. + /// System.String. + /// item + public string GetDtoId(BaseItem item) + { + if (item == null) + { + throw new ArgumentNullException("item"); + } + + return item.Id.ToString("N"); + } + + /// + /// Converts a UserItemData to a DTOUserItemData + /// + /// The data. + /// DtoUserItemData. + /// + public UserItemDataDto GetUserItemDataDto(UserItemData data) + { + if (data == null) + { + throw new ArgumentNullException("data"); + } + + return new UserItemDataDto + { + IsFavorite = data.IsFavorite, + Likes = data.Likes, + PlaybackPositionTicks = data.PlaybackPositionTicks, + PlayCount = data.PlayCount, + Rating = data.Rating, + Played = data.Played, + LastPlayedDate = data.LastPlayedDate, + Key = data.Key + }; + } + private void SetBookProperties(BaseItemDto dto, Book item) + { + dto.SeriesName = item.SeriesName; + } + private void SetPhotoProperties(BaseItemDto dto, Photo item) + { + dto.Width = item.Width; + dto.Height = item.Height; + dto.CameraMake = item.CameraMake; + dto.CameraModel = item.CameraModel; + dto.Software = item.Software; + dto.ExposureTime = item.ExposureTime; + dto.FocalLength = item.FocalLength; + dto.ImageOrientation = item.Orientation; + dto.Aperture = item.Aperture; + dto.ShutterSpeed = item.ShutterSpeed; + + dto.Latitude = item.Latitude; + dto.Longitude = item.Longitude; + dto.Altitude = item.Altitude; + dto.IsoSpeedRating = item.IsoSpeedRating; + + var album = item.AlbumEntity; + + if (album != null) + { + dto.Album = album.Name; + dto.AlbumId = album.Id.ToString("N"); + } + } + + private void SetMusicVideoProperties(BaseItemDto dto, MusicVideo item) + { + if (!string.IsNullOrEmpty(item.Album)) + { + var parentAlbum = _libraryManager.GetItemList(new InternalItemsQuery + { + IncludeItemTypes = new[] { typeof(MusicAlbum).Name }, + Name = item.Album + + }).FirstOrDefault(); + + if (parentAlbum != null) + { + dto.AlbumId = GetDtoId(parentAlbum); + } + } + + dto.Album = item.Album; + } + + private void SetGameProperties(BaseItemDto dto, Game item) + { + dto.Players = item.PlayersSupported; + dto.GameSystem = item.GameSystem; + dto.MultiPartGameFiles = item.MultiPartGameFiles; + } + + private void SetGameSystemProperties(BaseItemDto dto, GameSystem item) + { + dto.GameSystem = item.GameSystemName; + } + + private List GetImageTags(BaseItem item, List images) + { + return images + .Select(p => GetImageCacheTag(item, p)) + .Where(i => i != null) + .ToList(); + } + + private string GetImageCacheTag(BaseItem item, ImageType type) + { + try + { + return _imageProcessor.GetImageCacheTag(item, type); + } + catch (Exception ex) + { + _logger.ErrorException("Error getting {0} image info", ex, type); + return null; + } + } + + private string GetImageCacheTag(BaseItem item, ItemImageInfo image) + { + try + { + return _imageProcessor.GetImageCacheTag(item, image); + } + catch (Exception ex) + { + _logger.ErrorException("Error getting {0} image info for {1}", ex, image.Type, image.Path); + return null; + } + } + + /// + /// Attaches People DTO's to a DTOBaseItem + /// + /// The dto. + /// The item. + /// Task. + private void AttachPeople(BaseItemDto dto, BaseItem item) + { + // Ordering by person type to ensure actors and artists are at the front. + // This is taking advantage of the fact that they both begin with A + // This should be improved in the future + var people = _libraryManager.GetPeople(item).OrderBy(i => i.SortOrder ?? int.MaxValue) + .ThenBy(i => + { + if (i.IsType(PersonType.Actor)) + { + return 0; + } + if (i.IsType(PersonType.GuestStar)) + { + return 1; + } + if (i.IsType(PersonType.Director)) + { + return 2; + } + if (i.IsType(PersonType.Writer)) + { + return 3; + } + if (i.IsType(PersonType.Producer)) + { + return 4; + } + if (i.IsType(PersonType.Composer)) + { + return 4; + } + + return 10; + }) + .ToList(); + + var list = new List(); + + var dictionary = people.Select(p => p.Name) + .Distinct(StringComparer.OrdinalIgnoreCase).Select(c => + { + try + { + return _libraryManager.GetPerson(c); + } + catch (Exception ex) + { + _logger.ErrorException("Error getting person {0}", ex, c); + return null; + } + + }).Where(i => i != null) + .DistinctBy(i => i.Name, StringComparer.OrdinalIgnoreCase) + .ToDictionary(i => i.Name, StringComparer.OrdinalIgnoreCase); + + for (var i = 0; i < people.Count; i++) + { + var person = people[i]; + + var baseItemPerson = new BaseItemPerson + { + Name = person.Name, + Role = person.Role, + Type = person.Type + }; + + Person entity; + + if (dictionary.TryGetValue(person.Name, out entity)) + { + baseItemPerson.PrimaryImageTag = GetImageCacheTag(entity, ImageType.Primary); + baseItemPerson.Id = entity.Id.ToString("N"); + list.Add(baseItemPerson); + } + } + + dto.People = list.ToArray(); + } + + /// + /// Attaches the studios. + /// + /// The dto. + /// The item. + /// Task. + private void AttachStudios(BaseItemDto dto, BaseItem item) + { + var studios = item.Studios.ToList(); + + dto.Studios = new StudioDto[studios.Count]; + + var dictionary = studios.Distinct(StringComparer.OrdinalIgnoreCase).Select(name => + { + try + { + return _libraryManager.GetStudio(name); + } + catch (IOException ex) + { + _logger.ErrorException("Error getting studio {0}", ex, name); + return null; + } + }) + .Where(i => i != null) + .DistinctBy(i => i.Name, StringComparer.OrdinalIgnoreCase) + .ToDictionary(i => i.Name, StringComparer.OrdinalIgnoreCase); + + for (var i = 0; i < studios.Count; i++) + { + var studio = studios[i]; + + var studioDto = new StudioDto + { + Name = studio + }; + + Studio entity; + + if (dictionary.TryGetValue(studio, out entity)) + { + studioDto.Id = entity.Id.ToString("N"); + studioDto.PrimaryImageTag = GetImageCacheTag(entity, ImageType.Primary); + } + + dto.Studios[i] = studioDto; + } + } + + /// + /// Gets the chapter info dto. + /// + /// The chapter info. + /// The item. + /// ChapterInfoDto. + private ChapterInfoDto GetChapterInfoDto(ChapterInfo chapterInfo, BaseItem item) + { + var dto = new ChapterInfoDto + { + Name = chapterInfo.Name, + StartPositionTicks = chapterInfo.StartPositionTicks + }; + + if (!string.IsNullOrEmpty(chapterInfo.ImagePath)) + { + dto.ImageTag = GetImageCacheTag(item, new ItemImageInfo + { + Path = chapterInfo.ImagePath, + Type = ImageType.Chapter, + DateModified = chapterInfo.ImageDateModified + }); + } + + return dto; + } + + public List GetChapterInfoDtos(BaseItem item) + { + return _itemRepo.GetChapters(item.Id) + .Select(c => GetChapterInfoDto(c, item)) + .ToList(); + } + + /// + /// Sets simple property values on a DTOBaseItem + /// + /// The dto. + /// The item. + /// The owner. + /// The options. + private void AttachBasicFields(BaseItemDto dto, BaseItem item, BaseItem owner, DtoOptions options) + { + var fields = options.Fields; + + if (fields.Contains(ItemFields.DateCreated)) + { + dto.DateCreated = item.DateCreated; + } + + if (fields.Contains(ItemFields.DisplayMediaType)) + { + dto.DisplayMediaType = item.DisplayMediaType; + } + + if (fields.Contains(ItemFields.Settings)) + { + dto.LockedFields = item.LockedFields; + dto.LockData = item.IsLocked; + dto.ForcedSortName = item.ForcedSortName; + } + dto.Container = item.Container; + + var hasBudget = item as IHasBudget; + if (hasBudget != null) + { + if (fields.Contains(ItemFields.Budget)) + { + dto.Budget = hasBudget.Budget; + } + + if (fields.Contains(ItemFields.Revenue)) + { + dto.Revenue = hasBudget.Revenue; + } + } + + dto.EndDate = item.EndDate; + + if (fields.Contains(ItemFields.HomePageUrl)) + { + dto.HomePageUrl = item.HomePageUrl; + } + + if (fields.Contains(ItemFields.ExternalUrls)) + { + dto.ExternalUrls = _providerManager.GetExternalUrls(item).ToArray(); + } + + if (fields.Contains(ItemFields.Tags)) + { + dto.Tags = item.Tags; + } + + if (fields.Contains(ItemFields.Keywords)) + { + dto.Keywords = item.Keywords; + } + + var hasAspectRatio = item as IHasAspectRatio; + if (hasAspectRatio != null) + { + dto.AspectRatio = hasAspectRatio.AspectRatio; + } + + if (fields.Contains(ItemFields.Metascore)) + { + var hasMetascore = item as IHasMetascore; + if (hasMetascore != null) + { + dto.Metascore = hasMetascore.Metascore; + } + } + + if (fields.Contains(ItemFields.AwardSummary)) + { + var hasAwards = item as IHasAwards; + if (hasAwards != null) + { + dto.AwardSummary = hasAwards.AwardSummary; + } + } + + var backdropLimit = options.GetImageLimit(ImageType.Backdrop); + if (backdropLimit > 0) + { + dto.BackdropImageTags = GetImageTags(item, item.GetImages(ImageType.Backdrop).Take(backdropLimit).ToList()); + } + + if (fields.Contains(ItemFields.ScreenshotImageTags)) + { + var screenshotLimit = options.GetImageLimit(ImageType.Screenshot); + if (screenshotLimit > 0) + { + dto.ScreenshotImageTags = GetImageTags(item, item.GetImages(ImageType.Screenshot).Take(screenshotLimit).ToList()); + } + } + + if (fields.Contains(ItemFields.Genres)) + { + dto.Genres = item.Genres; + } + + if (options.EnableImages) + { + dto.ImageTags = new Dictionary(); + + // Prevent implicitly captured closure + var currentItem = item; + foreach (var image in currentItem.ImageInfos.Where(i => !currentItem.AllowsMultipleImages(i.Type)) + .ToList()) + { + if (options.GetImageLimit(image.Type) > 0) + { + var tag = GetImageCacheTag(item, image); + + if (tag != null) + { + dto.ImageTags[image.Type] = tag; + } + } + } + } + + dto.Id = GetDtoId(item); + dto.IndexNumber = item.IndexNumber; + dto.ParentIndexNumber = item.ParentIndexNumber; + + if (item.IsFolder) + { + dto.IsFolder = true; + } + else if (item is IHasMediaSources) + { + dto.IsFolder = false; + } + + dto.MediaType = item.MediaType; + dto.LocationType = item.LocationType; + if (item.IsHD.HasValue && item.IsHD.Value) + { + dto.IsHD = item.IsHD; + } + dto.Audio = item.Audio; + + if (fields.Contains(ItemFields.Settings)) + { + dto.PreferredMetadataCountryCode = item.PreferredMetadataCountryCode; + dto.PreferredMetadataLanguage = item.PreferredMetadataLanguage; + } + + dto.CriticRating = item.CriticRating; + + if (fields.Contains(ItemFields.CriticRatingSummary)) + { + dto.CriticRatingSummary = item.CriticRatingSummary; + } + + var hasTrailers = item as IHasTrailers; + if (hasTrailers != null) + { + dto.LocalTrailerCount = hasTrailers.GetTrailerIds().Count; + } + + var hasDisplayOrder = item as IHasDisplayOrder; + if (hasDisplayOrder != null) + { + dto.DisplayOrder = hasDisplayOrder.DisplayOrder; + } + + var userView = item as UserView; + if (userView != null) + { + dto.CollectionType = userView.ViewType; + } + + if (fields.Contains(ItemFields.RemoteTrailers)) + { + dto.RemoteTrailers = hasTrailers != null ? + hasTrailers.RemoteTrailers : + new List(); + } + + dto.Name = item.Name; + dto.OfficialRating = item.OfficialRating; + + if (fields.Contains(ItemFields.Overview)) + { + dto.Overview = item.Overview; + } + + if (fields.Contains(ItemFields.OriginalTitle)) + { + dto.OriginalTitle = item.OriginalTitle; + } + + if (fields.Contains(ItemFields.ShortOverview)) + { + dto.ShortOverview = item.ShortOverview; + } + + if (fields.Contains(ItemFields.ParentId)) + { + var displayParentId = item.DisplayParentId; + if (displayParentId.HasValue) + { + dto.ParentId = displayParentId.Value.ToString("N"); + } + } + + AddInheritedImages(dto, item, options, owner); + + if (fields.Contains(ItemFields.Path)) + { + dto.Path = GetMappedPath(item); + } + + dto.PremiereDate = item.PremiereDate; + dto.ProductionYear = item.ProductionYear; + + if (fields.Contains(ItemFields.ProviderIds)) + { + dto.ProviderIds = item.ProviderIds; + } + + dto.RunTimeTicks = item.RunTimeTicks; + + if (fields.Contains(ItemFields.SortName)) + { + dto.SortName = item.SortName; + } + + if (fields.Contains(ItemFields.CustomRating)) + { + dto.CustomRating = item.CustomRating; + } + + if (fields.Contains(ItemFields.Taglines)) + { + if (!string.IsNullOrWhiteSpace(item.Tagline)) + { + dto.Taglines = new List { item.Tagline }; + } + + if (dto.Taglines == null) + { + dto.Taglines = new List(); + } + } + + dto.Type = item.GetClientTypeName(); + dto.CommunityRating = item.CommunityRating; + + if (fields.Contains(ItemFields.VoteCount)) + { + dto.VoteCount = item.VoteCount; + } + + //if (item.IsFolder) + //{ + // var folder = (Folder)item; + + // if (fields.Contains(ItemFields.IndexOptions)) + // { + // dto.IndexOptions = folder.IndexByOptionStrings.ToArray(); + // } + //} + + var supportsPlaceHolders = item as ISupportsPlaceHolders; + if (supportsPlaceHolders != null) + { + dto.IsPlaceHolder = supportsPlaceHolders.IsPlaceHolder; + } + + // Add audio info + var audio = item as Audio; + if (audio != null) + { + dto.Album = audio.Album; + dto.ExtraType = audio.ExtraType; + + var albumParent = audio.AlbumEntity; + + if (albumParent != null) + { + dto.AlbumId = GetDtoId(albumParent); + + dto.AlbumPrimaryImageTag = GetImageCacheTag(albumParent, ImageType.Primary); + } + + //if (fields.Contains(ItemFields.MediaSourceCount)) + //{ + // Songs always have one + //} + } + + var hasArtist = item as IHasArtist; + if (hasArtist != null) + { + dto.Artists = hasArtist.Artists; + + var artistItems = _libraryManager.GetArtists(new InternalItemsQuery + { + EnableTotalRecordCount = false, + ItemIds = new[] { item.Id.ToString("N") } + }); + + dto.ArtistItems = artistItems.Items + .Select(i => + { + var artist = i.Item1; + return new NameIdPair + { + Name = artist.Name, + Id = artist.Id.ToString("N") + }; + }) + .ToList(); + + // Include artists that are not in the database yet, e.g., just added via metadata editor + var foundArtists = artistItems.Items.Select(i => i.Item1.Name).ToList(); + dto.ArtistItems.AddRange(hasArtist.Artists + .Except(foundArtists, new DistinctNameComparer()) + .Select(i => + { + // This should not be necessary but we're seeing some cases of it + if (string.IsNullOrWhiteSpace(i)) + { + return null; + } + + var artist = _libraryManager.GetArtist(i); + if (artist != null) + { + return new NameIdPair + { + Name = artist.Name, + Id = artist.Id.ToString("N") + }; + } + + return null; + + }).Where(i => i != null)); + } + + var hasAlbumArtist = item as IHasAlbumArtist; + if (hasAlbumArtist != null) + { + dto.AlbumArtist = hasAlbumArtist.AlbumArtists.FirstOrDefault(); + + var artistItems = _libraryManager.GetAlbumArtists(new InternalItemsQuery + { + EnableTotalRecordCount = false, + ItemIds = new[] { item.Id.ToString("N") } + }); + + dto.AlbumArtists = artistItems.Items + .Select(i => + { + var artist = i.Item1; + return new NameIdPair + { + Name = artist.Name, + Id = artist.Id.ToString("N") + }; + }) + .ToList(); + } + + // Add video info + var video = item as Video; + if (video != null) + { + dto.VideoType = video.VideoType; + dto.Video3DFormat = video.Video3DFormat; + dto.IsoType = video.IsoType; + + if (video.HasSubtitles) + { + dto.HasSubtitles = video.HasSubtitles; + } + + if (video.AdditionalParts.Count != 0) + { + dto.PartCount = video.AdditionalParts.Count + 1; + } + + if (fields.Contains(ItemFields.MediaSourceCount)) + { + var mediaSourceCount = video.MediaSourceCount; + if (mediaSourceCount != 1) + { + dto.MediaSourceCount = mediaSourceCount; + } + } + + if (fields.Contains(ItemFields.Chapters)) + { + dto.Chapters = GetChapterInfoDtos(item); + } + + dto.ExtraType = video.ExtraType; + } + + if (fields.Contains(ItemFields.MediaStreams)) + { + // Add VideoInfo + var iHasMediaSources = item as IHasMediaSources; + + if (iHasMediaSources != null) + { + List mediaStreams; + + if (dto.MediaSources != null && dto.MediaSources.Count > 0) + { + mediaStreams = dto.MediaSources.Where(i => new Guid(i.Id) == item.Id) + .SelectMany(i => i.MediaStreams) + .ToList(); + } + else + { + mediaStreams = _mediaSourceManager().GetStaticMediaSources(iHasMediaSources, true).First().MediaStreams; + } + + dto.MediaStreams = mediaStreams; + } + } + + var hasSpecialFeatures = item as IHasSpecialFeatures; + if (hasSpecialFeatures != null) + { + var specialFeatureCount = hasSpecialFeatures.SpecialFeatureIds.Count; + + if (specialFeatureCount > 0) + { + dto.SpecialFeatureCount = specialFeatureCount; + } + } + + // Add EpisodeInfo + var episode = item as Episode; + if (episode != null) + { + dto.IndexNumberEnd = episode.IndexNumberEnd; + dto.SeriesName = episode.SeriesName; + + if (fields.Contains(ItemFields.AlternateEpisodeNumbers)) + { + dto.DvdSeasonNumber = episode.DvdSeasonNumber; + dto.DvdEpisodeNumber = episode.DvdEpisodeNumber; + dto.AbsoluteEpisodeNumber = episode.AbsoluteEpisodeNumber; + } + + if (fields.Contains(ItemFields.SpecialEpisodeNumbers)) + { + dto.AirsAfterSeasonNumber = episode.AirsAfterSeasonNumber; + dto.AirsBeforeEpisodeNumber = episode.AirsBeforeEpisodeNumber; + dto.AirsBeforeSeasonNumber = episode.AirsBeforeSeasonNumber; + } + + var seasonId = episode.SeasonId; + if (seasonId.HasValue) + { + dto.SeasonId = seasonId.Value.ToString("N"); + } + + dto.SeasonName = episode.SeasonName; + + var seriesId = episode.SeriesId; + if (seriesId.HasValue) + { + dto.SeriesId = seriesId.Value.ToString("N"); + } + + Series episodeSeries = null; + + if (fields.Contains(ItemFields.SeriesGenres)) + { + episodeSeries = episodeSeries ?? episode.Series; + if (episodeSeries != null) + { + dto.SeriesGenres = episodeSeries.Genres.ToList(); + } + } + + //if (fields.Contains(ItemFields.SeriesPrimaryImage)) + { + episodeSeries = episodeSeries ?? episode.Series; + if (episodeSeries != null) + { + dto.SeriesPrimaryImageTag = GetImageCacheTag(episodeSeries, ImageType.Primary); + } + } + + if (fields.Contains(ItemFields.SeriesStudio)) + { + episodeSeries = episodeSeries ?? episode.Series; + if (episodeSeries != null) + { + dto.SeriesStudio = episodeSeries.Studios.FirstOrDefault(); + } + } + } + + // Add SeriesInfo + var series = item as Series; + if (series != null) + { + dto.AirDays = series.AirDays; + dto.AirTime = series.AirTime; + dto.SeriesStatus = series.Status; + + dto.AnimeSeriesIndex = series.AnimeSeriesIndex; + } + + // Add SeasonInfo + var season = item as Season; + if (season != null) + { + dto.SeriesName = season.SeriesName; + + var seriesId = season.SeriesId; + if (seriesId.HasValue) + { + dto.SeriesId = seriesId.Value.ToString("N"); + } + + series = null; + + if (fields.Contains(ItemFields.SeriesStudio)) + { + series = series ?? season.Series; + if (series != null) + { + dto.SeriesStudio = series.Studios.FirstOrDefault(); + } + } + + if (fields.Contains(ItemFields.SeriesPrimaryImage)) + { + series = series ?? season.Series; + if (series != null) + { + dto.SeriesPrimaryImageTag = GetImageCacheTag(series, ImageType.Primary); + } + } + } + + var game = item as Game; + + if (game != null) + { + SetGameProperties(dto, game); + } + + var gameSystem = item as GameSystem; + + if (gameSystem != null) + { + SetGameSystemProperties(dto, gameSystem); + } + + var musicVideo = item as MusicVideo; + if (musicVideo != null) + { + SetMusicVideoProperties(dto, musicVideo); + } + + var book = item as Book; + if (book != null) + { + SetBookProperties(dto, book); + } + + if (item.ProductionLocations.Count > 0 || item is Movie) + { + dto.ProductionLocations = item.ProductionLocations.ToArray(); + } + + var photo = item as Photo; + if (photo != null) + { + SetPhotoProperties(dto, photo); + } + + dto.ChannelId = item.ChannelId; + + if (item.SourceType == SourceType.Channel && !string.IsNullOrWhiteSpace(item.ChannelId)) + { + var channel = _libraryManager.GetItemById(item.ChannelId); + if (channel != null) + { + dto.ChannelName = channel.Name; + } + } + } + + private void AddInheritedImages(BaseItemDto dto, BaseItem item, DtoOptions options, BaseItem owner) + { + var logoLimit = options.GetImageLimit(ImageType.Logo); + var artLimit = options.GetImageLimit(ImageType.Art); + var thumbLimit = options.GetImageLimit(ImageType.Thumb); + var backdropLimit = options.GetImageLimit(ImageType.Backdrop); + + if (logoLimit == 0 && artLimit == 0 && thumbLimit == 0 && backdropLimit == 0) + { + return; + } + + BaseItem parent = null; + var isFirst = true; + + while (((!dto.HasLogo && logoLimit > 0) || (!dto.HasArtImage && artLimit > 0) || (!dto.HasThumb && thumbLimit > 0) || parent is Series) && + (parent = parent ?? (isFirst ? item.GetParent() ?? owner : parent)) != null) + { + if (parent == null) + { + break; + } + + var allImages = parent.ImageInfos; + + if (logoLimit > 0 && !dto.HasLogo && dto.ParentLogoItemId == null) + { + var image = allImages.FirstOrDefault(i => i.Type == ImageType.Logo); + + if (image != null) + { + dto.ParentLogoItemId = GetDtoId(parent); + dto.ParentLogoImageTag = GetImageCacheTag(parent, image); + } + } + if (artLimit > 0 && !dto.HasArtImage && dto.ParentArtItemId == null) + { + var image = allImages.FirstOrDefault(i => i.Type == ImageType.Art); + + if (image != null) + { + dto.ParentArtItemId = GetDtoId(parent); + dto.ParentArtImageTag = GetImageCacheTag(parent, image); + } + } + if (thumbLimit > 0 && !dto.HasThumb && (dto.ParentThumbItemId == null || parent is Series)) + { + var image = allImages.FirstOrDefault(i => i.Type == ImageType.Thumb); + + if (image != null) + { + dto.ParentThumbItemId = GetDtoId(parent); + dto.ParentThumbImageTag = GetImageCacheTag(parent, image); + } + } + if (backdropLimit > 0 && !dto.HasBackdrop) + { + var images = allImages.Where(i => i.Type == ImageType.Backdrop).Take(backdropLimit).ToList(); + + if (images.Count > 0) + { + dto.ParentBackdropItemId = GetDtoId(parent); + dto.ParentBackdropImageTags = GetImageTags(parent, images); + } + } + + isFirst = false; + parent = parent.GetParent(); + } + } + + private string GetMappedPath(BaseItem item) + { + var path = item.Path; + + var locationType = item.LocationType; + + if (locationType == LocationType.FileSystem || locationType == LocationType.Offline) + { + path = _libraryManager.GetPathAfterNetworkSubstitution(path, item); + } + + return path; + } + + /// + /// Attaches the primary image aspect ratio. + /// + /// The dto. + /// The item. + /// Task. + public void AttachPrimaryImageAspectRatio(IItemDto dto, IHasImages item) + { + dto.PrimaryImageAspectRatio = GetPrimaryImageAspectRatio(item); + } + + public double? GetPrimaryImageAspectRatio(IHasImages item) + { + var imageInfo = item.GetImageInfo(ImageType.Primary, 0); + + if (imageInfo == null || !imageInfo.IsLocalFile) + { + return null; + } + + ImageSize size; + + try + { + size = _imageProcessor.GetImageSize(imageInfo); + } + catch + { + //_logger.ErrorException("Failed to determine primary image aspect ratio for {0}", ex, path); + return null; + } + + var supportedEnhancers = _imageProcessor.GetSupportedEnhancers(item, ImageType.Primary).ToList(); + + foreach (var enhancer in supportedEnhancers) + { + try + { + size = enhancer.GetEnhancedImageSize(item, ImageType.Primary, 0, size); + } + catch (Exception ex) + { + _logger.ErrorException("Error in image enhancer: {0}", ex, enhancer.GetType().Name); + } + } + + var width = size.Width; + var height = size.Height; + + if (width == 0 || height == 0) + { + return null; + } + + var photo = item as Photo; + if (photo != null && photo.Orientation.HasValue) + { + switch (photo.Orientation.Value) + { + case ImageOrientation.LeftBottom: + case ImageOrientation.LeftTop: + case ImageOrientation.RightBottom: + case ImageOrientation.RightTop: + var temp = height; + height = width; + width = temp; + break; + } + } + + return width / height; + } + } +} diff --git a/Emby.Server.Implementations/Emby.Server.Implementations.csproj b/Emby.Server.Implementations/Emby.Server.Implementations.csproj index af093d53f..11b3393c8 100644 --- a/Emby.Server.Implementations/Emby.Server.Implementations.csproj +++ b/Emby.Server.Implementations/Emby.Server.Implementations.csproj @@ -13,7 +13,7 @@ en-US 512 {786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} - Profile75 + Profile7 v4.5 @@ -52,6 +52,7 @@ Properties\SharedVersion.cs + @@ -60,18 +61,112 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + + + ..\packages\MediaBrowser.Naming.1.0.0.57\lib\portable-net45+sl4+wp71+win8+wpa81\MediaBrowser.Naming.dll + True + + + ..\packages\Patterns.Logging.1.0.0.4\lib\portable-net45+dnxcore50+sl4+wp71+win8+wpa81\Patterns.Logging.dll + True + + + + + + + +