Jump to content

could some one give me a hand parsing collection items C#?


chef

Recommended Posts

chef

Hi there,

 

I could sure use some help. I can't seem to get the items inside a collection folder.

 

I can get the Item Collection Folder okay:

        public List<BaseItem> GetCollectionItems(string userName, string collectionName)
        {
            var results = LibraryManager.GetItemsResult(new InternalItemsQuery
            {
                User   = UserManager.GetUserByName(userName.AsSpan()),
                Parent = LibraryManager.GetItemById(GetLibraryId("Collections")), //Where GetLibraryId function does return the proper GUID
                Name   = collectionName
            });

            Logger.Info($"Result Count is: {results.Items.Length}"); //It return the collection parent I want using 'collectionName' (ex. The Avengers Collection)
                        
            return result.Items.ToList();
        }

But then I get stumped.

 

I've tried to use the collection folder baseItem like this:

            var collectionItems = LibraryManager.GetItemsResult(new InternalItemsQuery()
            {
                Parent = results.Items[0]  //this is the baseItem for sure
            });

but no results...

 

I was expecting all the Movies in the Collection.

 

 

I've also tried using ParentIds like this:


            var collectionItems = LibraryManager.GetItemsResult(new InternalItemsQuery()
            {
                ParentIds = new[] {results.Items[0].InternalId},
                
            });
  

I've also tried:

            var collectionItem = LibraryManager.GetItemList(new InternalItemsQuery()
            {
                Parent = results.Items[0],
                User = UserManager.GetUserByName(userName.AsSpan()),
                IncludeItemTypes = new[] { "Movie" }
            });

            Logger.Info($"Result Count is: {collectionItem.Length}");

What on Earth am I doing wrong?

 

Thanks to anyone who has a moment to help.

Edited by chef
Link to comment
Share on other sites

chef

Well, I tried "AppearsInItemIds" byt to no success  :unsure:

            var results = LibraryManager.GetItemsResult(new InternalItemsQuery
            {
                User   = UserManager.GetUserByName(userName.AsSpan()),
                Parent = LibraryManager.GetItemById(GetLibraryId("Collections")),
                Name   = collectionName
            });
            Logger.Info($"Result Count is: {results.TotalRecordCount}");
            
            var collectionList = LibraryManager.GetInternalItemIds(new InternalItemsQuery()
            {
                AppearsInItemIds = new[] {results.Items[0].InternalId}
            });

            Logger.Info($"CollectionList Count is: {collectionList.Length}");

I can still get the Collection parent, but CollectionList still has zero results returned

Link to comment
Share on other sites

chef

I read this post by post by @PenkethBoy: https://emby.media/community/index.php?/topic/77705-more-collections-endpoints/

 

This endpoint does return Collection Item Data, but in the LibraryManager you have the choice to either use "Parent" which is a BaseItem, or ParentIds which is a List/Array of InternalIds.

 

I have tried both and the result is always zero.

 

I have also tried using LibraryManager to parse the entire movie collection, and used "AppearsInIds" (which was the collection Id) to limit results, which returns empty. 

 

Do I have wrap my own Collection Item request using the information in PenkethBoy's thread?

 

How do you get the individual BaseItems in a Collection?

Edited by chef
Link to comment
Share on other sites

chef

@@Luke, sorry to bother you, I'm getting nowhere here. 

 

is there a way to get the collection id from each movie baseitem with an item query, if I can't seem drill deeper into a collection item.items?

Link to comment
Share on other sites

The property you are looking for is "ListItemIds" I think as apposed to appearsIn (which is for music artists).

  • Like 1
Link to comment
Share on other sites

chef

The property you are looking for is "ListItemIds" I think as apposed to appearsIn (which is for music artists).

Uh! Thank you, if it wasn't for physical distancing, I'd hug you.

 

@@ebr

  • Like 1
Link to comment
Share on other sites

  • 1 year later...
chef
7 hours ago, bakes82 said:

@chef You have code to create a collection and add items to it some place?

I'll take a look. It's been a while since I tried to create library items.

Link to comment
Share on other sites

bakes82
3 hours ago, chef said:

I'll take a look. It's been a while since I tried to create library items.

Stop looking at intros :P  You need to write a book on how this horrible api works lol.  My dart game is getting pretty good over here.

  • Haha 1
Link to comment
Share on other sites

chef

There is an endpoint for a CollectionService.

It has a POST which creates a collection.

Is there anything in the ILibraryManager?

Or is there some kind of ICollectionsManager.

 

 

Work has definitely gotten in the way the last couple days. I apologize my response is pretty late. 😬

Edited by chef
Link to comment
Share on other sites

  • 10 months later...
ginjaninja

@chef ive tried to make use of your learning here to get the members of a collection (and also later will be attempting members of a playlist).

Specifying ParentIds works fine for eg Series but not if the parentitem is a collection, so i search and found this suggestion of using ListItemIds.. but i cant make it work (am on beta), can you point out where im going wrong please.

private long MakeHash(BaseItem parentitem)
        {
            var queryList = new InternalItemsQuery
            {
                //Recursive = true,
                //ParentIds = new[] { parentitem.InternalId },
                ListItemIds= new[] { parentitem.InternalId },
                //DtoOptions = new DtoOptions(true)

            };
            List<BaseItem> children = new List<BaseItem>();
            children = LibraryManager.GetItemList(queryList).ToList();

 

Link to comment
Share on other sites

Absolutely! I just have to finish work first.

Just off the top of my head, I would do an initial query for collections (using IncludeItemTypes = new[]{"collection"})

That will return all the collection items.

From there, I would use the GetItemList and passing the collection you want it's contents of.

Did I answer that okay?

What is the end goal? You want the items inside a collection? 

 

Edited by chef
Link to comment
Share on other sites

Cheesegeezer
2 hours ago, ginjaninja said:

@chef ive tried to make use of your learning here to get the members of a collection (and also later will be attempting members of a playlist).

Specifying ParentIds works fine for eg Series but not if the parentitem is a collection, so i search and found this suggestion of using ListItemIds.. but i cant make it work (am on beta), can you point out where im going wrong please.

private long MakeHash(BaseItem parentitem)
        {
            var queryList = new InternalItemsQuery
            {
                //Recursive = true,
                //ParentIds = new[] { parentitem.InternalId },
                ListItemIds= new[] { parentitem.InternalId },
                //DtoOptions = new DtoOptions(true)

            };
            List<BaseItem> children = new List<BaseItem>();
            children = LibraryManager.GetItemList(queryList).ToList();

 

Looks like your query is asking two separate queries in the same query. 
 

you either want the items from the parentID or you want the item id’s from a parent id. Sounds the same but very different. You should also specify the item.Type you want to return. 

Link to comment
Share on other sites

I do this, don't know if it will help.

public QueryResult<BaseItem> GetItemsResult(long id, string[] types, User user)
        {
            var result = LibraryManager.GetItemsResult(new InternalItemsQuery(user)
            {
                Parent = LibraryManager.GetItemById(id),
                IncludeItemTypes = types,
                Recursive = true
            });
            return result;
        }

        public QueryResult<BaseItem> GetItemsResult(BaseItem parent, string[] types, User user)
        {
            var result = LibraryManager.GetItemsResult(new InternalItemsQuery(user)
            {
                Parent = parent,
                IncludeItemTypes = types,
                Recursive = true
            });
            return result;
        }

 

Link to comment
Share on other sites

Just now, chef said:

I do this, don't know if it will help.

public QueryResult<BaseItem> GetItemsResult(long id, string[] types, User user)
        {
            var result = LibraryManager.GetItemsResult(new InternalItemsQuery(user)
            {
                Parent = LibraryManager.GetItemById(id),
                IncludeItemTypes = types,
                Recursive = true
            });
            return result;
        }

        public QueryResult<BaseItem> GetItemsResult(BaseItem parent, string[] types, User user)
        {
            var result = LibraryManager.GetItemsResult(new InternalItemsQuery(user)
            {
                Parent = parent,
                IncludeItemTypes = types,
                Recursive = true
            });
            return result;
        }

 

Those methods are just overloaded in the class. They return the same data. One just takes in an InternalId (long int), and the other the entire BaseItem. 

Link to comment
Share on other sites

ginjaninja

Thank you for help. After 5 hours of banging my head against a brick wall, thinking this is trivial in the rest? api, trying @chef's code (without user), banging my head a bit more, i saw this in the linked thread...

image.thumb.png.1d4e2c4cd73fcc6f4cbdc4ba92f06159.png

I wonder if you have to use LibraryManager.GetItemResult with the user parameter as per Chefs code to get the children of a collection? Im thinking there must be a "non user" way  but it would be good to prove the point and use chefs code as you have got it work.

This would be the first time ive worked with users in C#, could anyone share some code to instantiate a User object to package inside an InternItemsQuery for  GetItemResults please?

Ideally i would want to instantiate a generic "Root Privilege User" available on any system, for use in a generic distributed plugin is that possible, does such a user exist?


So far for user code i have guestimated...

Spoiler

 

image.png.4688bb6a88d7cd020d2e1408b7dfa1db.png

 

image.png.381bd462624049b781feea613bfc39f9.png

a user on the system with rights to collection members. baseitem parentitem is a collection "_For Mum"

image.png.42bf5675548646cce790da8ba78d2497.png

image.png.5c147d104cdc85cfce0d4ff38442f65c.png

 

(I know my parentitem contains Movies and Series).. No joy... ch contains no results as viewed in Visual Studio debugger with a collection, works fine with a series.

 

 

Edited by ginjaninja
Link to comment
Share on other sites

Cheesegeezer

Is you want this to be for admins only.

use the following condition

if(user.Policy.IsAdministrator)

do work

else return 

  • Thanks 1
Link to comment
Share on other sites

Or leave user out of the parameter to get a useless query result. 

User is optional. 

  • Agree 1
Link to comment
Share on other sites

ginjaninja

Im stuck then. I followed the code ...i get children of series but i dont get children of BoxSets (Collections).

Just to confirm @chef.. do you believe this code structure will give you the members of a BoxSet (Collection).

or to get to the point another way. I believe you started this thread because you couldnt get the members of a collection...what is the bit of learning that allowed you to get the members of a collection please?

 

image.png.925097a56bc11bd5c9505e55d47a41be.png

 

Edited by ginjaninja
Link to comment
Share on other sites

23 minutes ago, ginjaninja said:

Im stuck then. I followed the code ...i get children of series but i dont get children of BoxSets (Collections).

Just to confirm @chef.. do you believe this code structure will give you the members of a BoxSet (Collection).

or to get to the point another way. I believe you started this thread because you couldnt get the members of a collection...what is the bit of learning that allowed you to get the members of a collection please?

 

image.png.925097a56bc11bd5c9505e55d47a41be.png

 

 "LibraryManager.QueryItems"

Hold on I have samples 

 

Edited by chef
Link to comment
Share on other sites

In the following example the method returns  the items in a collection.

 

        public List<BaseItem> GetCollectionItems(BaseItem collection)
        {
            var collectionResult = LibraryManager.QueryItems(new InternalItemsQuery()
            {
                CollectionIds  = new[] { collection.InternalId },
                EnableAutoSort = true,
                OrderBy        = new[] { ItemSortBy.PremiereDate }.Select(i => new ValueTuple<string, SortOrder>(i, SortOrder.Ascending)).ToArray(),

            });
            return collectionResult.Items.ToList();
        }

 

I hope that helps :) 

EDIT:there is no need to place the administrator param in the query. Sorry, I'm on my phone and I can't edit it. 

EDIT: I've fixed the code sample, it should be correct now. ctrl-C, ctrl-V 😃

Edited by chef
Link to comment
Share on other sites

ginjaninja

Thanks @chef. So QueryItems is a method for getting members of a collection...

image.png.6cc1225e219ec3f2532c7ab6f8935d68.png

I have just noticed that collection membership data is also available on children via collections.Dto.linkedItemInfo which is available through the other LibraryManager methods like GetItemsResults (may need DtoOptions = true)

image.png.d8cb173d6efbbf0a6e93654b44747fcc.png

In a twist of irony, 8hrs into this investigation, ive since learnt that Collections have a "DataLastSaved" property which seems to get updated when its members change, so after all that i didnt need to define my own method to determine change with the members of the collection 🙂....still learnt alot. thanks again @chef @Cheesegeezer.

  • Like 1
Link to comment
Share on other sites

5 minutes ago, ginjaninja said:

Thanks @chef. So QueryItems is a method for getting members of a collection...

image.png.6cc1225e219ec3f2532c7ab6f8935d68.png

I have just noticed that collection membership data is also available on children via collections.Dto.linkedItemInfo which is available through the other LibraryManager methods like GetItemsResults (may need DtoOptions = true)

image.png.d8cb173d6efbbf0a6e93654b44747fcc.png

In a twist of irony, 8hrs into this investigation, ive since learnt that Collections have a "DataLastSaved" property which seems to get updated when its members change, so after all that i didnt need to define my own method to determine change with the members of the collection 🙂....still learnt alot. thanks again @chef @Cheesegeezer.

If you want to get the entire Data Transfer Object of the BaseItem, then you need to implement the IDtoService.

Use the DtoService to request the entire object.

 

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...