public MediaItemQuery(MediaItemQuery other) { _filter = other.Filter; _necessaryRequestedMIATypeIDs = new HashSet <Guid>(other._necessaryRequestedMIATypeIDs); _optionalRequestedMIATypeIDs = new HashSet <Guid>(other._optionalRequestedMIATypeIDs); _sortInformation = other._sortInformation; }
public bool TryGetFanArt(FanArtConstants.FanArtMediaType mediaType, FanArtConstants.FanArtType fanArtType, string name, int maxWidth, int maxHeight, bool singleRandom, out IList<FanArtImage> result) { result = null; if (mediaType != FanArtConstants.FanArtMediaType.Album || fanArtType != FanArtConstants.FanArtType.Poster || string.IsNullOrEmpty(name)) return false; IMediaLibrary mediaLibrary = ServiceRegistration.Get<IMediaLibrary>(false); if (mediaLibrary == null) return false; IFilter filter = new RelationalFilter(AudioAspect.ATTR_ALBUM, RelationalOperator.EQ, name); MediaItemQuery query = new MediaItemQuery(NECESSARY_MIAS, filter) { Limit = 1, // Only one needed SortInformation = new List<SortInformation> { new SortInformation(AudioAspect.ATTR_ALBUM, SortDirection.Ascending) } }; var items = mediaLibrary.Search(query, false); result = new List<FanArtImage>(); foreach (var mediaItem in items) { byte[] textureData; if (!MediaItemAspect.TryGetAttribute(mediaItem.Aspects, ThumbnailLargeAspect.ATTR_THUMBNAIL, out textureData)) continue; // Only one record required result.Add(new FanArtImage(name, textureData)); return true; } return true; }
public MediaLibraryQueryViewSpecification(string viewDisplayName, IFilter filter, IEnumerable<Guid> necessaryMIATypeIDs, IEnumerable<Guid> optionalMIATypeIDs, bool onlyOnline) : base(viewDisplayName, necessaryMIATypeIDs, optionalMIATypeIDs) { _filter = filter; _query = new MediaItemQuery(necessaryMIATypeIDs, optionalMIATypeIDs, filter); _onlyOnline = onlyOnline; }
public MediaItemQuery(MediaItemQuery other) { _filter = other.Filter; _subqueryFilter = other.SubqueryFilter; _necessaryRequestedMIATypeIDs = new HashSet <Guid>(other._necessaryRequestedMIATypeIDs); _optionalRequestedMIATypeIDs = new HashSet <Guid>(other._optionalRequestedMIATypeIDs); _sortInformation = other._sortInformation; _limit = other.Limit; _offset = other.Offset; }
public static CompiledMediaItemQuery Compile(MIA_Management miaManagement, MediaItemQuery query) { IDictionary<Guid, MediaItemAspectMetadata> availableMIATypes = miaManagement.ManagedMediaItemAspectTypes; ICollection<MediaItemAspectMetadata> necessaryMIATypes = new List<MediaItemAspectMetadata>(); ICollection<MediaItemAspectMetadata> optionalMIATypes = new List<MediaItemAspectMetadata>(); // Raise exception if necessary MIA types are not present foreach (Guid miaTypeID in query.NecessaryRequestedMIATypeIDs) { MediaItemAspectMetadata miam; if (!availableMIATypes.TryGetValue(miaTypeID, out miam)) throw new InvalidDataException("Necessary requested MIA type '{0}' is not present in the media library", miaTypeID); necessaryMIATypes.Add(miam); } // For optional MIA types, we don't raise an exception if the type is not present foreach (Guid miaTypeID in query.OptionalRequestedMIATypeIDs) { MediaItemAspectMetadata miam; if (!availableMIATypes.TryGetValue(miaTypeID, out miam)) continue; optionalMIATypes.Add(miam); } // Maps (all selected main) MIAM.Attributes to QueryAttributes IDictionary<MediaItemAspectMetadata.AttributeSpecification, QueryAttribute> mainSelectedAttributes = new Dictionary<MediaItemAspectMetadata.AttributeSpecification, QueryAttribute>(); // Attributes selected in explicit queries ICollection<MediaItemAspectMetadata.AttributeSpecification> explicitSelectAttributes = new List<MediaItemAspectMetadata.AttributeSpecification>(); // Allocate selected attributes to main query and explicit selects ICollection<Guid> requestedMIATypeIDs = CollectionUtils.UnionSet( query.NecessaryRequestedMIATypeIDs, query.OptionalRequestedMIATypeIDs); foreach (Guid miaTypeID in requestedMIATypeIDs) { MediaItemAspectMetadata miam; if (!availableMIATypes.TryGetValue(miaTypeID, out miam)) // If one of the necessary MIA types is not available, an exception was raised above. So we only // come to here if an optional MIA type is not present - simply ignore that. continue; foreach (MediaItemAspectMetadata.AttributeSpecification attr in miam.AttributeSpecifications.Values) { if (attr.Cardinality == Cardinality.Inline || attr.Cardinality == Cardinality.ManyToOne) mainSelectedAttributes[attr] = new QueryAttribute(attr); else explicitSelectAttributes.Add(attr); } } return new CompiledMediaItemQuery(miaManagement, necessaryMIATypes, optionalMIATypes, mainSelectedAttributes, explicitSelectAttributes, query.Filter, query.SortInformation); }
protected void FillList(IContentDirectory contentDirectory, Guid[] necessaryMIAs, ItemsList list, MediaItemToListItemAction converterAction) { MediaItemQuery query = new MediaItemQuery(necessaryMIAs, null) { Limit = (uint)QueryLimit, // Last 5 imported items SortInformation = new List<SortInformation> { new SortInformation(ImporterAspect.ATTR_DATEADDED, SortDirection.Descending) } }; var items = contentDirectory.Search(query, false); list.Clear(); foreach (MediaItem mediaItem in items) { PlayableMediaItem listItem = converterAction(mediaItem); listItem.Command = new MethodDelegateCommand(() => PlayItemsModel.CheckQueryPlayAction(listItem.MediaItem)); list.Add(listItem); } list.FireChange(); }
protected internal override void ReLoadItemsAndSubViewSpecifications(out IList<MediaItem> mediaItems, out IList<ViewSpecification> subViewSpecifications) { mediaItems = null; subViewSpecifications = new List<ViewSpecification>(); IContentDirectory cd = ServiceRegistration.Get<IServerConnectionManager>().ContentDirectory; if (cd == null) return; try { MediaItemQuery query = new MediaItemQuery(_necessaryMIATypeIds, _optionalMIATypeIds, _filter) { Limit = Consts.MAX_NUM_ITEMS_VISIBLE }; mediaItems = cd.Search(query, true); } catch (UPnPRemoteException e) { ServiceRegistration.Get<ILogger>().Error("SimpleTextSearchViewSpecification.ReLoadItemsAndSubViewSpecifications: Error requesting server", e); mediaItems = new List<MediaItem>(); } }
public override IEnumerable<MediaItem> GetAllMediaItems() { IContentDirectory cd = ServiceRegistration.Get<IServerConnectionManager>().ContentDirectory; if (cd == null) return new List<MediaItem>(); MediaItemQuery query = new MediaItemQuery( _necessaryMIATypeIds, _optionalMIATypeIds, new BooleanCombinationFilter(BooleanOperator.And, new IFilter[] { new RelationalFilter(ProviderResourceAspect.ATTR_SYSTEM_ID, RelationalOperator.EQ, _systemId), new LikeFilter(ProviderResourceAspect.ATTR_RESOURCE_ACCESSOR_PATH, SqlUtils.LikeEscape(_basePath.Serialize(), '\\') + "%", '\\', true) })); return cd.Search(query, false); }
public MediaItemQuery(MediaItemQuery other) { _filter = other.Filter; _necessaryRequestedMIATypeIDs = new HashSet<Guid>(other._necessaryRequestedMIATypeIDs); _optionalRequestedMIATypeIDs = new HashSet<Guid>(other._optionalRequestedMIATypeIDs); _sortInformation = other._sortInformation; }
public bool SyncSeries() { try { TestStatus = "[Trakt.SyncSeries]"; Guid[] types = { MediaAspect.ASPECT_ID, SeriesAspect.ASPECT_ID }; MediaItemQuery mediaItemQuery = new MediaItemQuery(types, null, null); var contentDirectory = ServiceRegistration.Get<IServerConnectionManager>().ContentDirectory; if (contentDirectory == null) { TestStatus = "[Trakt.MediaLibraryNotConnected]"; return false; } var episodes = contentDirectory.Search(mediaItemQuery, true); var series = episodes.ToLookup(GetSeriesKey); foreach (var serie in series) { var imdbId = serie.Select(episode => { string value; return MediaItemAspect.TryGetAttribute(episode.Aspects, SeriesAspect.ATTR_IMDB_ID, out value) ? value : null; }).FirstOrDefault(value => !string.IsNullOrWhiteSpace(value)); var tvdbId = serie.Select(episode => { int value; return MediaItemAspect.TryGetAttribute(episode.Aspects, SeriesAspect.ATTR_TVDB_ID, out value) ? value : 0; }).FirstOrDefault(value => value != 0); TraktEpisodeSync syncData = new TraktEpisodeSync { UserName = Username, Password = Password, EpisodeList = new List<TraktEpisodeSync.Episode>(), Title = serie.Key, Year = serie.Min(e => { int year; string seriesTitle; GetSeriesTitleAndYear(e, out seriesTitle, out year); return year; }).ToString() }; if (!string.IsNullOrWhiteSpace(imdbId)) syncData.IMDBID = imdbId; if (tvdbId > 0) syncData.SeriesID = tvdbId.ToString(); HashSet<TraktEpisodeSync.Episode> uniqueEpisodes = new HashSet<TraktEpisodeSync.Episode>(); foreach (var episode in serie) { string seriesTitle; int year = 0; if (!GetSeriesTitle /*AndYear*/(episode, out seriesTitle /*, out year*/)) continue; // First send all movies to Trakt that we have so they appear in library CollectionUtils.AddAll(uniqueEpisodes, ToSeries(episode)); } syncData.EpisodeList = uniqueEpisodes.ToList(); TraktSyncModes traktSyncMode = TraktSyncModes.library; var response = TraktAPI.SyncEpisodeLibrary(syncData, traktSyncMode); ServiceRegistration.Get<ILogger>().Info("Trakt.tv: Series '{0}' '{1}': {2}{3}", syncData.Title, traktSyncMode, response.Message, response.Error); // Then send only the watched movies as "seen" uniqueEpisodes.Clear(); foreach (var seenEpisode in episodes.Where(IsWatched)) CollectionUtils.AddAll(uniqueEpisodes, ToSeries(seenEpisode)); syncData.EpisodeList = uniqueEpisodes.ToList(); traktSyncMode = TraktSyncModes.seen; response = TraktAPI.SyncEpisodeLibrary(syncData, traktSyncMode); ServiceRegistration.Get<ILogger>().Info("Trakt.tv: Series '{0}' '{1}': {2}{3}", syncData.Title, traktSyncMode, response.Message, response.Error); return true; } } catch (Exception ex) { ServiceRegistration.Get<ILogger>().Error("Trakt.tv: Exception while synchronizing media library.", ex); } return false; }
public IList<MediaItem> Search(MediaItemQuery query, bool onlyOnline) { CpAction action = GetAction("Search"); String onlineStateStr = SerializeOnlineState(onlyOnline); IList<object> inParameters = new List<object> {query, onlineStateStr}; IList<object> outParameters = action.InvokeAction(inParameters); return (IList<MediaItem>) outParameters[0]; }
public IList<MediaItem> LoadCustomPlaylist(IList<Guid> mediaItemIds, IEnumerable<Guid> necessaryMIATypes, IEnumerable<Guid> optionalMIATypes, uint? offset = null, uint? limit = null) { IFilter filter = new MediaItemIdFilter(mediaItemIds); MediaItemQuery query = new MediaItemQuery(necessaryMIATypes, optionalMIATypes, filter); query.Limit = limit; query.Offset = offset; // Sort media items IDictionary<Guid, MediaItem> searchResult = new Dictionary<Guid, MediaItem>(); foreach (MediaItem item in Search(query, false)) searchResult[item.MediaItemId] = item; IList<MediaItem> result = new List<MediaItem>(searchResult.Count); foreach (Guid mediaItemId in mediaItemIds) { MediaItem item; if (searchResult.TryGetValue(mediaItemId, out item)) result.Add(item); } return result; }
public IList<MediaItem> Search(MediaItemQuery query, bool filterOnlyOnline) { // We add the provider resource aspect to the necessary aspect types be able to filter online systems MediaItemQuery executeQuery = filterOnlyOnline ? new MediaItemQuery( query.NecessaryRequestedMIATypeIDs.Union(new Guid[] {ProviderResourceAspect.ASPECT_ID}), query.OptionalRequestedMIATypeIDs, AddOnlyOnlineFilter(query.Filter)) : query; executeQuery.Limit = query.Limit; executeQuery.Offset = query.Offset; CompiledMediaItemQuery cmiq = CompiledMediaItemQuery.Compile(_miaManagement, executeQuery); IList<MediaItem> items = cmiq.QueryList(); IList<MediaItem> result = new List<MediaItem>(items.Count); if (filterOnlyOnline && !query.NecessaryRequestedMIATypeIDs.Contains(ProviderResourceAspect.ASPECT_ID)) { // The provider resource aspect was not requested and thus has to be removed from the result items foreach (MediaItem item in items) { item.Aspects.Remove(ProviderResourceAspect.ASPECT_ID); result.Add(item); } } else result = items; return result; }
static UPnPError OnSearch(DvAction action, IList<object> inParams, out IList<object> outParams, CallContext context) { // In parameters var containerId = (string)inParams[0]; var searchCriteria = inParams[1].ToString(); var filter = inParams[2].ToString(); var startingIndex = Convert.ToInt32(inParams[3]); var requestedCount = Convert.ToInt32(inParams[4]); var sortCriteria = (string)inParams[5]; // Out parameters int numberReturned = 0; int totalMatches = 0; int containterUpdateId = 0; UPnPContentDirectorySearch query = new UPnPContentDirectorySearch(); StringWriter sw = new StringWriter(); query.Construct(searchCriteria, sw); query.searchCrit(); PegNode pn = query.GetRoot(); string xml = ParserHelper.PegNodeToXml(pn, searchCriteria); Logger.Debug("MediaServer - Parsed: \"{0}\" to make \"{1}\"", searchCriteria, xml); var parentDirectoryId = containerId == "0" ? Guid.Empty : MarshallingHelper.DeserializeGuid(containerId); var necessaryMIATypes = new List<Guid> {DirectoryAspect.ASPECT_ID}; var searchQuery = new MediaItemQuery(necessaryMIATypes, null); //searchQuery.Filter var searchItems = ServiceRegistration.Get<IMediaLibrary>().Search(searchQuery, true); /* foreach (var item in browseItems) { } */ outParams = new List<object>(3) { numberReturned, totalMatches, containterUpdateId }; return null; }
public bool SyncSeries() { TraktLogger.Info("Series Library Starting Sync"); // store list of series ids so we can update the episode counts // of any series that syncback watched flags var seriesToUpdateEpisodeCounts = new HashSet<int>(); #region Get online data from cache #region UnWatched / Watched List<TraktCache.EpisodeWatched> traktWatchedEpisodes = null; // get all episodes on trakt that are marked as 'unseen' var traktUnWatchedEpisodes = TraktCache.GetUnWatchedEpisodesFromTrakt().ToNullableList(); if (traktUnWatchedEpisodes == null) { TraktLogger.Error("Error getting tv shows unwatched from trakt.tv server, unwatched and watched sync will be skipped"); } else { TraktLogger.Info("Found {0} unwatched tv episodes in trakt.tv library", traktUnWatchedEpisodes.Count()); // now get all episodes on trakt that are marked as 'seen' or 'watched' (this will be cached already when working out unwatched) traktWatchedEpisodes = TraktCache.GetWatchedEpisodesFromTrakt().ToNullableList(); if (traktWatchedEpisodes == null) { TraktLogger.Error("Error getting tv shows watched from trakt.tv server, watched sync will be skipped"); } else { TraktLogger.Info("Found {0} watched tv episodes in trakt.tv library", traktWatchedEpisodes.Count()); } } #endregion #region Collection // get all episodes on trakt that are marked as in 'collection' var traktCollectedEpisodes = TraktCache.GetCollectedEpisodesFromTrakt().ToNullableList(); if (traktCollectedEpisodes == null) { TraktLogger.Error("Error getting tv episode collection from trakt.tv server"); } else { TraktLogger.Info("Found {0} tv episodes in trakt.tv collection", traktCollectedEpisodes.Count()); } #endregion #region Ratings #region Episodes //var traktRatedEpisodes = TraktCache.GetRatedEpisodesFromTrakt().ToNullableList(); //if (traktRatedEpisodes == null) //{ // TraktLogger.Error("Error getting rated episodes from trakt.tv server"); //} //else //{ // TraktLogger.Info("Found {0} rated tv episodes in trakt.tv library", traktRatedEpisodes.Count()); //} #endregion #region Shows //var traktRatedShows = TraktCache.GetRatedShowsFromTrakt().ToNullableList(); //if (traktRatedShows == null) //{ // TraktLogger.Error("Error getting rated shows from trakt.tv server"); //} //else //{ // TraktLogger.Info("Found {0} rated tv shows in trakt.tv library", traktRatedShows.Count()); //} #endregion #region Seasons //var traktRatedSeasons = TraktCache.GetRatedSeasonsFromTrakt().ToNullableList(); //if (traktRatedSeasons == null) //{ // TraktLogger.Error("Error getting rated seasons from trakt.tv server"); //} //else //{ // TraktLogger.Info("Found {0} rated tv seasons in trakt.tv library", traktRatedSeasons.Count()); //} #endregion #endregion #region Watchlist #region Shows //var traktWatchlistedShows = TraktCache.GetWatchlistedShowsFromTrakt(); //if (traktWatchlistedShows == null) //{ // TraktLogger.Error("Error getting watchlisted shows from trakt.tv server"); //} //else //{ // TraktLogger.Info("Found {0} watchlisted tv shows in trakt.tv library", traktWatchlistedShows.Count()); //} #endregion #region Seasons //var traktWatchlistedSeasons = TraktCache.GetWatchlistedSeasonsFromTrakt(); //if (traktWatchlistedSeasons == null) //{ // TraktLogger.Error("Error getting watchlisted seasons from trakt.tv server"); //} //else //{ // TraktLogger.Info("Found {0} watchlisted tv seasons in trakt.tv library", traktWatchlistedSeasons.Count()); //} #endregion #region Episodes //var traktWatchlistedEpisodes = TraktCache.GetWatchlistedEpisodesFromTrakt(); //if (traktWatchlistedEpisodes == null) //{ // TraktLogger.Error("Error getting watchlisted episodes from trakt.tv server"); //} //else //{ // TraktLogger.Info("Found {0} watchlisted tv episodes in trakt.tv library", traktWatchlistedEpisodes.Count()); //} #endregion #endregion #endregion if (traktCollectedEpisodes != null) { try { TestStatus = "[Trakt.SyncSeries]"; Guid[] types = { MediaAspect.ASPECT_ID, SeriesAspect.ASPECT_ID, VideoAspect.ASPECT_ID, ImporterAspect.ASPECT_ID}; MediaItemQuery mediaItemQuery = new MediaItemQuery(types, null, null); var contentDirectory = ServiceRegistration.Get<IServerConnectionManager>().ContentDirectory; if (contentDirectory == null) { TestStatus = "[Trakt.MediaLibraryNotConnected]"; return false; } #region Get data from local database var localEpisodes = contentDirectory.Search(mediaItemQuery, true); int episodeCount = localEpisodes.Count; TraktLogger.Info("Found {0} total episodes in local database", episodeCount); // get the episodes that we have watched var localWatchedEpisodes = localEpisodes.Where(IsWatched).ToList(); TraktLogger.Info("Found {0} episodes watched in tvseries database", localWatchedEpisodes.Count); #endregion #region Add episodes to watched history at trakt.tv int showCount = 0; int iSyncCounter = 0; if (traktWatchedEpisodes != null) { var syncWatchedShows = GetWatchedShowsForSyncEx(localWatchedEpisodes, traktWatchedEpisodes); TraktLogger.Info("Found {0} local tv show(s) with {1} watched episode(s) to add to trakt.tv watched history", syncWatchedShows.Shows.Count, syncWatchedShows.Shows.Sum(sh => sh.Seasons.Sum(se => se.Episodes.Count()))); showCount = syncWatchedShows.Shows.Count; foreach (var show in syncWatchedShows.Shows) { int showEpisodeCount = show.Seasons.Sum(s => s.Episodes.Count()); TraktLogger.Info("Adding tv show [{0}/{1}] to trakt.tv episode watched history, Episode Count = '{2}', Show Title = '{3}', Show Year = '{4}', Show TVDb ID = '{5}', Show IMDb ID = '{6}'", ++iSyncCounter, showCount, showEpisodeCount, show.Title, show.Year.HasValue ? show.Year.ToString() : "<empty>", show.Ids.Tvdb, show.Ids.Imdb ?? "<empty>"); show.Seasons.ForEach(s => s.Episodes.ForEach(e => { TraktLogger.Info("Adding episode to trakt.tv watched history, Title = '{0} - {1}x{2}', Watched At = '{3}'", show.Title, s.Number, e.Number, e.WatchedAt.ToLogString()); })); // only sync one show at a time regardless of batch size in settings var pagedShows = new List<TraktSyncShowWatchedEx>(); pagedShows.Add(show); var response = TraktAPI.AddShowsToWatchedHistoryEx(new TraktSyncShowsWatchedEx { Shows = pagedShows }); TraktLogger.LogTraktResponse<TraktSyncResponse>(response); // only add to cache if it was a success // note: we don't get back the same object type so makes it hard to figure out what failed if (response != null && response.Added != null && response.Added.Episodes == showEpisodeCount) { // update local cache TraktCache.AddEpisodesToWatchHistory(show); } } } #endregion #region Add episodes to collection at trakt.tv if (traktCollectedEpisodes != null) { var syncCollectedShows = GetCollectedShowsForSyncEx(localEpisodes, traktCollectedEpisodes); TraktLogger.Info("Found {0} local tv show(s) with {1} collected episode(s) to add to trakt.tv collection", syncCollectedShows.Shows.Count, syncCollectedShows.Shows.Sum(sh => sh.Seasons.Sum(se => se.Episodes.Count()))); iSyncCounter = 0; showCount = syncCollectedShows.Shows.Count; foreach (var show in syncCollectedShows.Shows) { int showEpisodeCount = show.Seasons.Sum(s => s.Episodes.Count()); TraktLogger.Info("Adding tv show [{0}/{1}] to trakt.tv episode collection, Episode Count = '{2}', Show Title = '{3}', Show Year = '{4}', Show TVDb ID = '{5}', Show IMDb ID = '{6}'", ++iSyncCounter, showCount, showEpisodeCount, show.Title, show.Year.HasValue ? show.Year.ToString() : "<empty>", show.Ids.Tvdb, show.Ids.Imdb ?? "<empty>"); show.Seasons.ForEach(s => s.Episodes.ForEach(e => { TraktLogger.Info("Adding episode to trakt.tv collection, Title = '{0} - {1}x{2}', Collected At = '{3}', Audio Channels = '{4}', Audio Codec = '{5}', Resolution = '{6}', Media Type = '{7}', Is 3D = '{8}'", show.Title, s.Number, e.Number, e.CollectedAt.ToLogString(), e.AudioChannels.ToLogString(), e.AudioCodec.ToLogString(), e.Resolution.ToLogString(), e.MediaType.ToLogString(), e.Is3D); })); // only sync one show at a time regardless of batch size in settings var pagedShows = new List<TraktSyncShowCollectedEx>(); pagedShows.Add(show); var response = TraktAPI.AddShowsToCollectonEx(new TraktSyncShowsCollectedEx { Shows = pagedShows }); TraktLogger.LogTraktResponse<TraktSyncResponse>(response); // only add to cache if it was a success if (response != null && response.Added != null && response.Added.Episodes == showEpisodeCount) { // update local cache TraktCache.AddEpisodesToCollection(show); } } } #endregion return true; } catch (Exception ex) { ServiceRegistration.Get<ILogger>().Error("Trakt.tv: Exception while synchronizing media library.", ex); } } return false; }