ginjaninja 537 Posted February 3, 2023 Share Posted February 3, 2023 Before i tried to create my own horrible custom method with different case statements and banged my head for another day, i just wanted to check there wasn't a built in method that could get the immediate children of any Parent in c#; be the parent a Boxset, Playlist, Series, Season, Album ie any Type capable of being a parent? I wonder how many different Types of parent there are, in terms of how their children are determined, maybe i would just need a few cases. The web api has a single generic method on /items with ParentId. Perhaps If there isnt an inbuilt c# method, is it possible for a plugin to returns items from the web api? does anyone have some precooked code for querying the/a web api from c#? ie returning a list of Baseitems by interpreting the returned json from an API get. (i actually only need a list of InternalIds). thank you. Link to comment Share on other sites More sharing options...
Luke 37133 Posted February 4, 2023 Share Posted February 4, 2023 The server equivalent would be .GetItems Link to comment Share on other sites More sharing options...
ginjaninja 537 Posted February 7, 2023 Author Share Posted February 7, 2023 On 04/02/2023 at 01:25, Luke said: The server equivalent would be .GetItems Thanks Luke, please treat me like a novice. What exposes this method please. Perhaps i should have said im writing a plugin.. Im used to LibraryManager via ILibraryManager and that doesnt have this method. When I look in reference, Getitems is talked about under rest API, should i/can i use the rest api in a plugin? (FWIW i cant find a method in LibraryManager that works for all parent types). Link to comment Share on other sites More sharing options...
Cheesegeezer 3088 Posted February 7, 2023 Share Posted February 7, 2023 (edited) 2 hours ago, ginjaninja said: Thanks Luke, please treat me like a novice. What exposes this method please. Perhaps i should have said im writing a plugin.. Im used to LibraryManager via ILibraryManager and that doesnt have this method. When I look in reference, Getitems is talked about under rest API, should i/can i use the rest api in a plugin? (FWIW i cant find a method in LibraryManager that works for all parent types). Yep you can, you just need to implement the IHTTPClient in Emby or use the .net HTTPClient, return the response in either and deserialise the JSON to a properties class. Something like this (using built in .net HTTPClient - initialise from the constructor) public async Task<List<ItemInfoModel>> GetLatestItems(string parentId) { JsonSerializerOptions _jsonSerializerOptions = new() { PropertyNameCaseInsensitive = true, Converters = { new JsonStringEnumConverter(JsonNamingPolicy.CamelCase) }}; List<ItemInfoModel> baseItems = new List<ItemInfoModel>(); string url = string.Format(_apiCalls.GetLatestItemsApi(parentId)); HttpResponseMessage response = await _httpClient.GetAsync(url); if (response.IsSuccessStatusCode) { var json = await response.Content.ReadAsStringAsync(); try { baseItems = JsonSerializer.Deserialize<List<ItemInfoModel>>(json, _jsonSerializerOptions); } catch (Exception e) { Debug.WriteLine(e); } } return baseItems; } and i also initialise the my APICalls class in the constructor. this is just a class that holds all the direct api calls i need to make public string BaseApiUrl() { return string.Format("{0}/emby/", Authentication.EndpointAddress); } public string UserBasedCall(string request) { // const url = `${serverAddress}/emby/Users/${userId}/${request}&api_key=${authToken}`; var call = BaseApiUrl() + "Users/" + Authentication.CurrentUserId + "/" + request + "api_key=" + Authentication.AuthToken; return call; } public string GetLatestItemsApi(string folderId) { var request = "Items/Latest?Recursive=true&Limit=20&ParentId=" + folderId + "&EnableImages=true&EnableUserData=true&"; return string.Format(UserBasedCall(request)); } Edited February 7, 2023 by Cheesegeezer Link to comment Share on other sites More sharing options...
ginjaninja 537 Posted February 7, 2023 Author Share Posted February 7, 2023 (edited) Thanks @Cheesegeezer this looks very helpful, i will circle back to http method if necessary. @LukeI have since found .GetItems on ItemRepository, while ItemRepository.GetItems works for eg Series I can not make it work if the parent is a collection (by specifying the parent in the query), similar to how LibraryManager.GetItemList does not work for collections (without structuring the query for collection ids). How sure are you .GetItems should be able to find the children of any parent type, with the same query ie specifying the parent? I was using it thus. var queryList = new InternalItemsQuery { Parent = parentitem //also tried. //ParentIds = new[] { parentitem.InternalId } }; var children = ItemRepository.GetItems(queryList); thanks Edited February 7, 2023 by ginjaninja Link to comment Share on other sites More sharing options...
Luke 37133 Posted February 9, 2023 Share Posted February 9, 2023 On 2/7/2023 at 10:39 AM, ginjaninja said: Thanks @Cheesegeezer this looks very helpful, i will circle back to http method if necessary. @LukeI have since found .GetItems on ItemRepository, while ItemRepository.GetItems works for eg Series I can not make it work if the parent is a collection (by specifying the parent in the query), similar to how LibraryManager.GetItemList does not work for collections (without structuring the query for collection ids). How sure are you .GetItems should be able to find the children of any parent type, with the same query ie specifying the parent? I was using it thus. var queryList = new InternalItemsQuery { Parent = parentitem //also tried. //ParentIds = new[] { parentitem.InternalId } }; var children = ItemRepository.GetItems(queryList); thanks avoid (never) talking to ItemRepository directly. Get the parent item you need, and then call it's own folder.GetItems method. Link to comment Share on other sites More sharing options...
ginjaninja 537 Posted February 10, 2023 Author Share Posted February 10, 2023 16 hours ago, Luke said: avoid (never) talking to ItemRepository directly. Get the parent item you need, and then call it's own folder.GetItems method. Thanks Luke, It sounds like each parent item type has its own different GetItems Method and there is not a one size fits all method to get the children of any parent. In that case i may be better off with the HTTP api in this instance, speed and performance are not relevant to my application. Link to comment Share on other sites More sharing options...
ginjaninja 537 Posted February 20, 2023 Author Share Posted February 20, 2023 On 09/02/2023 at 17:06, Luke said: avoid (never) talking to ItemRepository directly. Get the parent item you need, and then call it's own folder.GetItems method. Hi Luke, so i have the parent item (Type BaseItem)....how do i access its folder.GetItems method please...?perhaps using Playlist as the parent item as an example? Spoiler Do i need to cast it as another type? i see that the Folder type has method GetChildren and i see the Playlist type has method eg getPlaylistItems .. Link to comment Share on other sites More sharing options...
chef 3748 Posted February 20, 2023 Share Posted February 20, 2023 On 2/7/2023 at 8:41 AM, Cheesegeezer said: Yep you can, you just need to implement the IHTTPClient in Emby or use the .net HTTPClient, return the response in either and deserialise the JSON to a properties class. Something like this (using built in .net HTTPClient - initialise from the constructor) public async Task<List<ItemInfoModel>> GetLatestItems(string parentId) { JsonSerializerOptions _jsonSerializerOptions = new() { PropertyNameCaseInsensitive = true, Converters = { new JsonStringEnumConverter(JsonNamingPolicy.CamelCase) }}; List<ItemInfoModel> baseItems = new List<ItemInfoModel>(); string url = string.Format(_apiCalls.GetLatestItemsApi(parentId)); HttpResponseMessage response = await _httpClient.GetAsync(url); if (response.IsSuccessStatusCode) { var json = await response.Content.ReadAsStringAsync(); try { baseItems = JsonSerializer.Deserialize<List<ItemInfoModel>>(json, _jsonSerializerOptions); } catch (Exception e) { Debug.WriteLine(e); } } return baseItems; } and i also initialise the my APICalls class in the constructor. this is just a class that holds all the direct api calls i need to make public string BaseApiUrl() { return string.Format("{0}/emby/", Authentication.EndpointAddress); } public string UserBasedCall(string request) { // const url = `${serverAddress}/emby/Users/${userId}/${request}&api_key=${authToken}`; var call = BaseApiUrl() + "Users/" + Authentication.CurrentUserId + "/" + request + "api_key=" + Authentication.AuthToken; return call; } public string GetLatestItemsApi(string folderId) { var request = "Items/Latest?Recursive=true&Limit=20&ParentId=" + folderId + "&EnableImages=true&EnableUserData=true&"; return string.Format(UserBasedCall(request)); } Cheese, do you have to lookup the API token each time for these url calls that aren't yet part of the API? When you are going to hit an endpoint, and need an API key, what does the method look like to get the saved key? Link to comment Share on other sites More sharing options...
ginjaninja 537 Posted February 20, 2023 Author Share Posted February 20, 2023 1 hour ago, chef said: Cheese, do you have to lookup the API token each time for these url calls that aren't yet part of the API? When you are going to hit an endpoint, and need an API key, what does the method look like to get the saved key? @chef my experience from using http api in powershell suggests using an apikey maybe a 'poors mans equivalent' of properly authenticating and getting the auth token and using that as the api key in the URI syntax..i recall (not 100%) there are some user based endpoints of the api that are better used via an auth token then a system api key (ie needed to make them work).. I guess the downside of a user auth token vs a system api key would be your plugin config would have to allow the user to store an admins un/pw in your plugins config. @chef do you you know how to go from a baseitem to expose the methods on eg a type Playlist or some other (folder) type by any chance? Link to comment Share on other sites More sharing options...
chef 3748 Posted February 20, 2023 Share Posted February 20, 2023 19 minutes ago, ginjaninja said: @chef my experience from using http api in powershell suggests using an apikey maybe a 'poors mans equivalent' of properly authenticating and getting the auth token and using that as the api key in the URI syntax..i recall (not 100%) there are some user based endpoints of the api that are better used via an auth token then a system api key (ie needed to make them work).. I guess the downside of a user auth token vs a system api key would be your plugin config would have to allow the user to store an admins un/pw in your plugins config. @chef do you you know how to go from a baseitem to expose the methods on eg a type Playlist or some other (folder) type by any chance? Which methods? There are certain methods on baseItems, like "FindParent<>", and there is a Get method for children (which I believe is referring to file system children), there is also GetMediaSources, or GetMediaStreams. Is that what you mean? Perhaps, when dealing with playlists, you would have to request each playlist item specifically by InternalId. Select all the InteralIds of your playlist items and use the "Ids[]" parameter of the InternalItemsQuery to get all the baseItem data for those elements. Link to comment Share on other sites More sharing options...
ginjaninja 537 Posted February 20, 2023 Author Share Posted February 20, 2023 (edited) 2 hours ago, chef said: Which methods? There are certain methods on baseItems, like "FindParent<>", and there is a Get method for children (which I believe is referring to file system children), there is also GetMediaSources, or GetMediaStreams. Is that what you mean? Perhaps, when dealing with playlists, you would have to request each playlist item specifically by InternalId. Select all the InteralIds of your playlist items and use the "Ids[]" parameter of the InternalItemsQuery to get all the baseItem data for those elements. against the overall goal that i am trying to the find the children of any BaseItem, and there doesnt seem to a BaseItem method to find the children of any BaseItem type (eg children of a Playlist) and @Luke's comment " then call it's own folder.GetItems method." and that objects of type Folder and Playlist have a .GetItems() method . Do you know how i go from a BaseItem object (which happens to be of type Playlist) to the methods on a Playlist in c#...(assuming thats what i need to do?) eg you cant do ....BaseItem.GetItems(InternalItemsQuery); Spoiler This is a total guess but highlights one idea i had to get to the methods on a Playlist from a BaseItem, it even gets past intellisense but creates an exception on run..is this on the right track? var queryList = new InternalItemsQuery { Parent = parentitem, }; var children = (parentitem as Playlist).GetChildren(queryList); or in the interests of making 1 bit of progress and asking an even clearer question with a more definite answer...do you know the code to go from a BaseItem (which is a Playlist) to a list of the members of the Playlist - either the BaseItem members or the Ids whatevers easier...)? thanks. Edited February 20, 2023 by ginjaninja Link to comment Share on other sites More sharing options...
Cheesegeezer 3088 Posted February 20, 2023 Share Posted February 20, 2023 (edited) Hey fellas, I’ll get back to you tomorrow, in depth. but if you are creating your own app or endpoint requirements in c#, then each api call needs to be authenticated to get the info you want you can then store and utilise it. but if you are already authenticated, like we are for plugins, etc then you should be using emby’s library interfaces or create your own and inject those dependencies to the plugin. You can also create a apikey in the server to use, so you can add it to a static constants class in your plugin/interface to reuse anywhere in your code, nice and easily. Edited February 20, 2023 by Cheesegeezer Link to comment Share on other sites More sharing options...
Luke 37133 Posted February 20, 2023 Share Posted February 20, 2023 The playlist will also have a .GetItems method that you can call. Link to comment Share on other sites More sharing options...
ginjaninja 537 Posted February 21, 2023 Author Share Posted February 21, 2023 (edited) 16 hours ago, Luke said: The playlist will also have a .GetItems method that you can call. Hi Luke, thanks for your help.. i appreciate this is probably very simple...but i dont know how to go from a BaseItem to a Playlist, please can you give an example of the c# code that would take you from a BaseItem to a Playlist which you could then call .GetItems on? edit oooh this worked... var children = (parentitem as Folder).GetItems(queryList); without an exception. Spoiler var children = (parentitem as Playlist).GetItems(queryList); causes an exception..would love to understand the underlying reasons why...and or wether im doing it right? Edited February 21, 2023 by ginjaninja 1 Link to comment Share on other sites More sharing options...
Cheesegeezer 3088 Posted February 21, 2023 Share Posted February 21, 2023 1 hour ago, ginjaninja said: Hi Luke, thanks for your help.. i appreciate this is probably very simple...but i dont know how to go from a BaseItem to a Playlist, please can you give an example of the c# code that would take you from a BaseItem to a Playlist which you could then call .GetItems on? edit oooh this worked... var children = (parentitem as Folder).GetItems(queryList); without an exception. Reveal hidden contents var children = (parentitem as Playlist).GetItems(queryList); causes an exception..would love to understand the underlying reasons why...and or wether im doing it right? I been playing with this, this morning and failed to figure it out too!! Well done matey Link to comment Share on other sites More sharing options...
Recommended Posts
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 accountSign in
Already have an account? Sign in here.
Sign In Now