public void TestUPnPSongArtistContains() { string text = "(upnp:class derivedfrom \"object.item.audioItem\" and (dc:creator contains \"four\" or upnp:artist contains \"five \\\" six\"))"; SearchExp exp = SearchParser.Parse(text); IList <Guid> types = new List <Guid>(); IFilter filter = SearchParser.Convert(exp, types); Console.WriteLine(text + " -> filter=" + filter + " types=[" + string.Join(",", types) + "]"); Assert.Contains(AudioAspect.ASPECT_ID, (ICollection)types, "Types"); Assert.IsTrue(filter is BooleanCombinationFilter, "Top level"); BooleanCombinationFilter topFilter = filter as BooleanCombinationFilter; Assert.AreEqual(BooleanOperator.Or, topFilter.Operator, "Top level operator"); Assert.IsTrue(topFilter.Operands is IList <IFilter>, "Top level"); IList <IFilter> operands = (IList <IFilter>)topFilter.Operands; Assert.IsTrue(operands[0] is LikeFilter, "First operand"); LikeFilter filter1 = (LikeFilter)operands[0]; Assert.AreEqual(AudioAspect.ATTR_ARTISTS, filter1.AttributeType, "Attribute"); Assert.AreEqual("%four%", filter1.Expression, "Expression"); Assert.IsTrue(operands[0] is LikeFilter, "Second operand"); LikeFilter filter2 = (LikeFilter)operands[1]; Assert.AreEqual(AudioAspect.ATTR_ARTISTS, filter2.AttributeType, "Attribute"); Assert.AreEqual("%five \" six%", filter2.Expression, "Expression"); }
public void TestUPnPImage() { string text = "upnp:class derivedfrom \"object.item.imageItem\" and @refID exists false"; SearchExp exp = SearchParser.Parse(text); IList <Guid> types = new List <Guid>(); IFilter filter = SearchParser.Convert(exp, types); Console.WriteLine(text + " -> filter=" + filter + " types=[" + string.Join(",", types) + "]"); Assert.Contains(ImageAspect.ASPECT_ID, (ICollection)types, "Types"); }
public void TestUPnPTitle() { string text = "(dc:title contains \"two\")"; SearchExp exp = SearchParser.Parse(text); IList <Guid> types = new List <Guid>(); IFilter filter = SearchParser.Convert(exp, types); Console.WriteLine(text + " -> filter=" + filter + " types=[" + string.Join(",", types) + "]"); Assert.IsTrue(filter is LikeFilter, "Filter"); LikeFilter filter1 = filter as LikeFilter; Assert.AreEqual(MediaAspect.ATTR_TITLE, filter1.AttributeType, "Attribute"); Assert.AreEqual("%two%", filter1.Expression, "Expression"); }
public void TestUPnPAlbumContains() { string text = "(upnp:class = \"object.container.album.musicAlbum\" and dc:title contains \"three\")"; SearchExp exp = SearchParser.Parse(text); IList <Guid> types = new List <Guid>(); IFilter filter = SearchParser.Convert(exp, types); Console.WriteLine(text + " -> filter=" + filter + " types=[" + string.Join(",", types) + "]"); Assert.Contains(AudioAspect.ASPECT_ID, (ICollection)types, "Types"); Assert.IsTrue(filter is LikeFilter, "Filter"); LikeFilter filter1 = filter as LikeFilter; Assert.AreEqual(AudioAspect.ATTR_ALBUM, filter1.AttributeType, "Attribute"); Assert.AreEqual("%three%", filter1.Expression, "Expression"); }
public void TestUPnPTrackContains() { string text = "(upnp:class derivedfrom \"object.item.audioItem\" and dc:title contains \"nine\")"; SearchExp exp = SearchParser.Parse(text); IList <Guid> types = new List <Guid>(); IFilter filter = SearchParser.Convert(exp, types); Console.WriteLine(text + " -> filter=" + filter + " types=[" + string.Join(",", types) + "]"); Assert.Contains(AudioAspect.ASPECT_ID, (ICollection)types, "Types"); Assert.IsTrue(filter is LikeFilter, "Filter"); LikeFilter filter1 = filter as LikeFilter; Assert.AreEqual(MediaAspect.ATTR_TITLE, filter1.AttributeType, "Attribute"); Assert.AreEqual("%nine%", filter1.Expression, "Expression"); }
private static UPnPError OnSearch(DvAction action, IList <object> inParams, out IList <object> outParams, CallContext context) { outParams = new List <object>(); string objectId = "?"; try { // In parameters objectId = (string)inParams[0]; var searchCriteria = inParams[1].ToString(); var filter = inParams[2].ToString(); var startingIndex = Convert.ToUInt32(inParams[3]); var requestedCount = Convert.ToUInt32(inParams[4]); var sortCriteria = (string)inParams[5]; string fileRequest; if (objectId.Contains('/')) { fileRequest = objectId.Substring(objectId.IndexOf('/') + 1); objectId = objectId.Substring(0, objectId.IndexOf('/') - 1); } Logger.Debug( "MediaServer - entry OnSearch(objectId=\"{0}\",searchCriteria=\"{1}\",filter=\"{2}\",startingIndex=\"{3}\",requestedCount=\"{4}\",sortCriteria=\"{5}\")", objectId, searchCriteria, filter, startingIndex, requestedCount, sortCriteria); // Out parameters int numberReturned = 0; int totalMatches = 0; IPAddress ip = ProfileManager.ResolveIpAddress(context.Request?.RemoteIpAddress); EndPointSettings deviceClient = ProfileManager.DetectProfileAsync(context.Request).Result; if (deviceClient?.Profile == null) { return(null); } deviceClient.InitializeAsync(ip.ToString()).Wait(); GenericContentDirectoryFilter deviceFilter = GenericContentDirectoryFilter.GetContentFilter(deviceClient.Profile.DirectoryContentFilter); var newObjectId = deviceFilter.FilterObjectId(objectId, true); if (newObjectId == null) { Logger.Debug("MediaServer: Request for container ID {0} ignored", objectId); return(null); } if (objectId != newObjectId) { Logger.Debug("MediaServer: Request for container ID {0} intercepted, changing it to {1}", objectId, newObjectId); objectId = newObjectId; } //TODO: DNLA clients use this ID to determine if the any content was changed/added to the container since last request int containterUpdateId = 0; SearchExp exp = SearchParser.Parse(searchCriteria); ISet <Guid> necessaryMIATypes = new HashSet <Guid>(); necessaryMIATypes.Add(MediaAspect.ASPECT_ID); necessaryMIATypes.Add(ProviderResourceAspect.ASPECT_ID); IFilter searchFilter = SearchParser.Convert(exp, necessaryMIATypes); ISet <Guid> optionalMIATypes = new HashSet <Guid>(); if (necessaryMIATypes.Contains(VideoAspect.ASPECT_ID) == false) { optionalMIATypes.Add(VideoAspect.ASPECT_ID); optionalMIATypes.Add(VideoStreamAspect.ASPECT_ID); } if (necessaryMIATypes.Contains(AudioAspect.ASPECT_ID) == false) { optionalMIATypes.Add(AudioAspect.ASPECT_ID); } if (necessaryMIATypes.Contains(ImageAspect.ASPECT_ID) == false) { optionalMIATypes.Add(ImageAspect.ASPECT_ID); } optionalMIATypes.Add(DirectoryAspect.ASPECT_ID); optionalMIATypes.Add(SeriesAspect.ASPECT_ID); optionalMIATypes.Add(SeasonAspect.ASPECT_ID); BasicContainer tempContainer = new BasicContainer("TEMP", deviceClient); searchFilter = tempContainer.AppendUserFilter(searchFilter, necessaryMIATypes); MediaItemQuery searchQuery = new MediaItemQuery(necessaryMIATypes, optionalMIATypes, searchFilter); searchQuery.Offset = startingIndex; searchQuery.Limit = requestedCount; Logger.Debug("MediaServer - OnSearch query {0}", searchQuery); IList <MediaItem> items = ServiceRegistration.Get <IMediaLibrary>().Search(searchQuery, true, deviceClient.UserId ?? deviceClient.ClientId, false); var msgBuilder = new GenericDidlMessageBuilder(); var o = deviceClient.RootContainer.FindObject(objectId); if (o == null) { // We failed to find the container requested // throw error! throw new ArgumentException("ObjectID not found"); } IEnumerable <IDirectoryObject> objects = items .OrderBy(s => MediaItemAspect.TryGetAspect(s.Aspects, MediaAspect.Metadata, out var aspect) ? aspect.GetAttributeValue <string>(MediaAspect.ATTR_SORT_TITLE) : "") .Select(item => MediaLibraryHelper.InstansiateMediaLibraryObject(item, (BasicContainer)o)); msgBuilder.BuildAll(filter, objects); numberReturned = items.Count; totalMatches = items.Count; var xml = msgBuilder.ToString(); outParams = new List <object>(4) { xml, numberReturned, totalMatches, containterUpdateId }; Logger.Debug( "MediaServer - exit OnSearch(objectId=\"{0}\"...) = (numberReturned=\"{1}\",totalMatches=\"{2}\",containerUpdateId=\"{3}\") {4}", objectId, numberReturned, totalMatches, containterUpdateId, xml); } catch (Exception ex) { Logger.Error("MediaServer - OnSearch(objectId=\"{0}\"...) error", ex, objectId); } // This upnp action doesn't have a return type. return(null); }