Allow Access to ListItem Properties via JSON-RPC
#16
perhaps @Montellese can confirm whether or not "additionalProperties" would be the correct way to retrieve the value of custom ListItem properties.

after a bit of hacking around in the source-code, this seems to be working (but i have no idea whether it's even remotely valid to implement it like this):

diff:
diff --git a/xbmc/interfaces/json-rpc/FileItemHandler.cpp b/xbmc/interfaces/json-rpc/FileItemHandler.cpp
index badf8a97d0..f79c4a9e1f 100644
--- a/xbmc/interfaces/json-rpc/FileItemHandler.cpp
+++ b/xbmc/interfaces/json-rpc/FileItemHandler.cpp
@@ -233,6 +233,12 @@ void CFileItemHandler::HandleFileItemList(const char *ID, bool allowFile, const
       fields.insert(field->asString());
   }
 
+  if (parameterObject.isMember("additionalProperties") && parameterObject["additionalProperties"].isArray())
+  {
+    for (CVariant::const_iterator_array field = parameterObject["additionalProperties"].begin_array(); field != parameterObject["additionalProperties"].end_array(); field++)
+      fields.insert(field->asString());
+  }
+
   result[resultname].reserve(static_cast<size_t>(end - start));
   for (int i = start; i < end; i++)
   {
diff --git a/xbmc/interfaces/json-rpc/schema/methods.json b/xbmc/interfaces/json-rpc/schema/methods.json
index 856dda7490..8edb404551 100644
--- a/xbmc/interfaces/json-rpc/schema/methods.json
+++ b/xbmc/interfaces/json-rpc/schema/methods.json
@@ -640,6 +640,7 @@
       { "name": "directory", "type": "string", "required": true },
       { "name": "media", "$ref": "Files.Media", "default": "files" },
       { "name": "properties", "$ref": "List.Fields.Files" },
+      { "name": "additionalProperties", "type": "array", "items": { "type": "string" } },
       { "name": "sort", "$ref": "List.Sort" },
       { "name": "limits", "$ref": "List.Limits", "description": "Limits are applied after getting the directory content thus retrieval is not faster when they are applied." }
     ],


json example:
json:
xbmc.executeJSONRPC('{"jsonrpc": "2.0", "method": "Files.GetDirectory", "params": {"directory": "plugin://plugin.test/", "media":"video", "properties":["genre", "director"], "additionalProperties":["foo", "bar"]}, "id": 1}')
Do not PM or e-mail Team-Kodi members directly asking for support.
Always read the Forum rules, Kodi online-manual, FAQ, Help and Search the forum before posting.
Reply
#17
I appreciate the answer back! If you seem to have a working snippet there, that's definitely good news.

However, I'm not sure that's how I understood it to work.

"additionalProperties" as a JSON schema parameter seems to just tell it how to handle the situation where unexpected fields exist in "properties", rather than being its own list of fields.
Reply
#18
(2020-06-24, 00:42)ronie Wrote: json example:
json:
xbmc.executeJSONRPC('{"jsonrpc": "2.0", "method": "Files.GetDirectory", "params": {"directory": "plugin://plugin.test/", "media":"video", "properties":["genre", "director"], "additionalProperties":["foo", "bar"]}, "id": 1}')

Does this return the values of ListItem.Property(foo) and ListItem.Property(bar) within the return from the API?
Reply
#19
let me start by saying, i have to agree my code example is very likely not how additionalProperties should be implemented.
but yes, it does work. you can get all custom listitem properties that have been set by a plugin.

for instance, if a plugin uses:
python:
listitem.setProperty("foo", "Some vlaue")

you can retrieve the 'foo' property using that json query.
Do not PM or e-mail Team-Kodi members directly asking for support.
Always read the Forum rules, Kodi online-manual, FAQ, Help and Search the forum before posting.
Reply
#20
@ronie was "additionalProperties" tested?. I'll have to whip up something up to check it out...
Image Lunatixz - Kodi / Beta repository
Image PseudoTV - Forum | Website | Youtube | Help?
Reply
#21
yes, i have tested the diff i've posted.
Do not PM or e-mail Team-Kodi members directly asking for support.
Always read the Forum rules, Kodi online-manual, FAQ, Help and Search the forum before posting.
Reply
#22
To be fair, while digging in the code, that was the basic implementation I saw being feasible. If it's working, that seems like a very reasonable solution that it appears would cover my use case, at least.

EDIT: I should mention that in regards to this pull request, it should probably be tested against Files.GetFileDetails as well, to maintain API consistency.
Reply
#23
(2020-06-25, 02:00)ronie Wrote: yes, i have tested the diff i've posted.
Awesome, Thanks!!
Image Lunatixz - Kodi / Beta repository
Image PseudoTV - Forum | Website | Youtube | Help?
Reply
#24
If the proposed changes do indeed function as expected in a test build, would it be possible to get them merged? I'll run a test build tonight to find out Big Grin

EDIT: Also, since it appears the required changes should be minimal, would it then be possible to backport to Leia in the meantime until Matrix is deemed stable?
Reply
#25
I had to make a couple other changes in order to allow the properties to be sent back to me correctly, as well as supporting Files.GetFileDetails (I think, anyways Big Grin)
diff:
diff --git a/xbmc/interfaces/json-rpc/FileItemHandler.cpp b/xbmc/interfaces/json-rpc/FileItemHandler.cpp
index badf8a97d0..3cd7bdbf26 100644
--- a/xbmc/interfaces/json-rpc/FileItemHandler.cpp
+++ b/xbmc/interfaces/json-rpc/FileItemHandler.cpp
@@ -232,6 +232,12 @@ void CFileItemHandler::HandleFileItemList(const char *ID, bool allowFile, const
     for (CVariant::const_iterator_array field = parameterObject["properties"].begin_array(); field != parameterObject["properties"].end_array(); field++)
       fields.insert(field->asString());
   }
+  
+  if (parameterObject.isMember("additionalProperties") && parameterObject["additionalProperties"].isArray())
+  {
+    for (CVariant::const_iterator_array prop = parameterObject["additionalProperties"].begin_array(); prop != parameterObject["additionalProperties"].end_array(); prop++)
+      fields.insert(prop->asString());
+  }
 
   result[resultname].reserve(static_cast<size_t>(end - start));
   for (int i = start; i < end; i++)
@@ -251,6 +257,12 @@ void CFileItemHandler::HandleFileItem(const char *ID, bool allowFile, const char
     for (CVariant::const_iterator_array field = parameterObject["properties"].begin_array(); field != parameterObject["properties"].end_array(); field++)
       fields.insert(field->asString());
   }
+  
+  if (parameterObject.isMember("additionalProperties") && parameterObject["additionalProperties"].isArray())
+  {
+    for (CVariant::const_iterator_array prop = parameterObject["additionalProperties"].begin_array(); prop != parameterObject["additionalProperties"].end_array(); prop++)
+      fields.insert(prop->asString());
+  }
 
   HandleFileItem(ID, allowFile, resultname, item, parameterObject, fields, result, append, thumbLoader);
 }
diff --git a/xbmc/interfaces/json-rpc/schema/methods.json b/xbmc/interfaces/json-rpc/schema/methods.json
index 079eb7efea..e0d5e93400 100644
--- a/xbmc/interfaces/json-rpc/schema/methods.json
+++ b/xbmc/interfaces/json-rpc/schema/methods.json
@@ -640,6 +640,7 @@
       { "name": "directory", "type": "string", "required": true },
       { "name": "media", "$ref": "Files.Media", "default": "files" },
       { "name": "properties", "$ref": "List.Fields.Files" },
+      { "name": "additionalProperties", "type": "array", "items": { "type": "string" } },
       { "name": "sort", "$ref": "List.Sort" },
       { "name": "limits", "$ref": "List.Limits", "description": "Limits are applied after getting the directory content thus retrieval is not faster when they are applied." }
     ],
@@ -659,7 +660,8 @@
     "params": [
       { "name": "file", "type": "string", "required": true, "description": "Full path to the file" },
       { "name": "media", "$ref": "Files.Media", "default": "files" },
-      { "name": "properties", "$ref": "List.Fields.Files" }
+      { "name": "properties", "$ref": "List.Fields.Files" },
+      { "name": "additionalProperties", "type": "array", "items": { "type": "string" } }
     ],
     "returns": {
       "type": "object",
diff --git a/xbmc/interfaces/json-rpc/schema/types.json b/xbmc/interfaces/json-rpc/schema/types.json
index bf755dc5bf..2ada81c52c 100644
--- a/xbmc/interfaces/json-rpc/schema/types.json
+++ b/xbmc/interfaces/json-rpc/schema/types.json
@@ -1593,7 +1593,8 @@
       "size": { "type": "integer", "description": "Size of the file in bytes" },
       "lastmodified": { "type": "string" },
       "mimetype": { "type": "string" }
-    }
+    },
+    "additionalProperties": { "type": "string" }
   },
   "List.Items.Sources": {
     "type": "array",


My query looks like:
json:
{"jsonrpc":"2.0","id":15,"method":"Files.GetDirectory","params":{"directory":"plugin://plugin.video.themoviedb.helper/?info=trending_week&nextpage=True&type=movie","media":"video","properties":["genre","director"],"additionalProperties":["tmdb_id"]}}
And a sample file from the response:
json:
{ "director": [ "David Koepp" ], "file": "plugin://plugin.video.themoviedb.helper/?info=details&type=movie&tmdb_id=514593&nextpage=True", "filetype": "directory", "genre": [ "Horror", "Mystery" ], "label": "You Should Have Left", "type": "movie", "tmdb_id": "514593" }

I would consider this an acceptable solution, but haven't tested possible ramifications (if any) on other parts of the API.
Reply
#26
https://github.com/xbmc/xbmc/pull/18106
Reply

Logout Mark Read Team Forum Stats Members Help
Allow Access to ListItem Properties via JSON-RPC0