Skip to content

Conversation

@heros-os
Copy link

@heros-os heros-os commented Jan 3, 2026

  • Add get_cast_items() method to ListGetItemDetails base class
  • Add get_cast_directory() method for populating cast containers
  • Create ListGetMovieCast, ListGetTVShowCast, and ListGetEpisodeCast classes
  • Cast members populated as individual ListItems with name, role, and thumbnail
  • Provides foundation for script.skinvariables to fix issue #1553
  • Includes comprehensive documentation and examples
  • No breaking changes, fully backward compatible

- Add get_cast_items() method to ListGetItemDetails base class
- Add get_cast_directory() method for populating cast containers
- Create ListGetMovieCast, ListGetTVShowCast, and ListGetEpisodeCast classes
- Cast members populated as individual ListItems with name, role, and thumbnail
- Provides foundation for script.skinvariables to fix issue #1553
- Includes comprehensive documentation and examples
- No breaking changes, fully backward compatible
Copilot AI review requested due to automatic review settings January 3, 2026 15:15
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This pull request adds cast container functionality to enable skinners to populate secondary containers with cast member information from movies, TV shows, and episodes. The implementation extends the existing ListGetItemDetails base class with new methods and introduces three specialized classes for handling cast data retrieval via Kodi's JSON-RPC API.

Key changes include:

  • Addition of get_cast_items() and get_cast_directory() methods to the base class for retrieving and populating cast data
  • Creation of three new classes (ListGetMovieCast, ListGetTVShowCast, ListGetEpisodeCast) that provide dedicated cast container support
  • Comprehensive documentation and examples showing integration patterns for script.skinvariables

Reviewed changes

Copilot reviewed 5 out of 5 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
resources/modules/jurialmunkey/jrpcid.py Adds cast retrieval methods to base class and three new cast-specific classes that fetch cast data via JSON-RPC and populate containers with actor ListItems
examples_cast_container.py Provides comprehensive Python examples demonstrating usage patterns, plugin routing integration, and skin XML implementation examples
IMPLEMENTATION_SUMMARY.md Documents the technical implementation details, data flow, integration steps, and usage examples for developers
CAST_QUICK_REFERENCE.md Quick reference guide for both developers and skinners showing common usage patterns and troubleshooting tips
CAST_CONTAINER_IMPLEMENTATION.md Detailed implementation guide covering problem statement, solution architecture, skin integration, and testing recommendations

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +313 to +323
def get_cast_items(self, dbid):
"""
Get cast members from the JSON-RPC response and create list items for each.
This creates a secondary container with cast information.
Returns a list of tuples (path, ListItem, is_folder)
"""
method = self.jrpc_method
params = {
self.jrpc_id: self.jrpc_idtype(dbid),
"properties": ["cast"]
}
Copy link

Copilot AI Jan 3, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The get_cast_items method doesn't validate or handle the case where dbid is None or 0. The existing get_items method (lines 295-311) has a check "if dbid else []" to return an empty list for invalid dbids. Consider adding similar validation here to ensure consistent behavior and prevent unnecessary JSON-RPC calls with invalid database IDs.

Copilot uses AI. Check for mistakes.
Comment on lines +369 to +370
This can be used to fill Container(50) or any other container.
"""
Copy link

Copilot AI Jan 3, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The get_cast_directory method accepts **kwargs but doesn't use them or pass them to get_cast_items. This is inconsistent with the base implementation pattern. Either remove the unused **kwargs parameter or document why it's kept for future compatibility.

Suggested change
This can be used to fill Container(50) or any other container.
"""
This can be used to fill Container(50) or any other container.
:param dbid: Database identifier for the item whose cast is being listed.
:param kwargs: Accepted for API compatibility with other get_*_directory
methods and reserved for future use; currently unused.
"""
# kwargs are intentionally unused but kept for API/interface compatibility.
if kwargs:
pass

Copilot uses AI. Check for mistakes.
Comment on lines +457 to +489
def get_directory(self, dbid, **kwargs):
items = self.get_cast_items(dbid)
self.add_items(items, container_content='actors')


class ListGetTVShowCast(ListGetItemDetails):
"""
Get cast information for a TV show and populate a container with cast members.
Each list item represents a cast member with name, role, and thumbnail.
"""
jrpc_method = JSON_RPC_LOOKUPS['tvshowid']['method']
jrpc_key = JSON_RPC_LOOKUPS['tvshowid']['key']
jrpc_id = "tvshowid"
jrpc_idtype = int

def get_directory(self, dbid, **kwargs):
items = self.get_cast_items(dbid)
self.add_items(items, container_content='actors')


class ListGetEpisodeCast(ListGetItemDetails):
"""
Get cast information for an episode and populate a container with cast members.
Each list item represents a cast member with name, role, and thumbnail.
"""
jrpc_method = JSON_RPC_LOOKUPS['episodeid']['method']
jrpc_key = JSON_RPC_LOOKUPS['episodeid']['key']
jrpc_id = "episodeid"
jrpc_idtype = int

def get_directory(self, dbid, **kwargs):
items = self.get_cast_items(dbid)
self.add_items(items, container_content='actors')
Copy link

Copilot AI Jan 3, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The three cast classes (ListGetMovieCast, ListGetTVShowCast, ListGetEpisodeCast) override get_directory with identical implementations. This duplicated code violates the DRY principle. Since the base class already has get_cast_directory that does exactly this, consider either removing these get_directory overrides and having users call get_cast_directory directly, or move this common implementation to the base class get_directory when dealing with cast classes.

Copilot uses AI. Check for mistakes.
Copy link
Owner

@jurialmunkey jurialmunkey Jan 5, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@heros-os - Please address copilot comments by creating a parent class ListGetCast which the child types can inherit

Comment on lines +447 to +489
class ListGetMovieCast(ListGetItemDetails):
"""
Get cast information for a movie and populate a container with cast members.
Each list item represents a cast member with name, role, and thumbnail.
"""
jrpc_method = JSON_RPC_LOOKUPS['movieid']['method']
jrpc_key = JSON_RPC_LOOKUPS['movieid']['key']
jrpc_id = "movieid"
jrpc_idtype = int

def get_directory(self, dbid, **kwargs):
items = self.get_cast_items(dbid)
self.add_items(items, container_content='actors')


class ListGetTVShowCast(ListGetItemDetails):
"""
Get cast information for a TV show and populate a container with cast members.
Each list item represents a cast member with name, role, and thumbnail.
"""
jrpc_method = JSON_RPC_LOOKUPS['tvshowid']['method']
jrpc_key = JSON_RPC_LOOKUPS['tvshowid']['key']
jrpc_id = "tvshowid"
jrpc_idtype = int

def get_directory(self, dbid, **kwargs):
items = self.get_cast_items(dbid)
self.add_items(items, container_content='actors')


class ListGetEpisodeCast(ListGetItemDetails):
"""
Get cast information for an episode and populate a container with cast members.
Each list item represents a cast member with name, role, and thumbnail.
"""
jrpc_method = JSON_RPC_LOOKUPS['episodeid']['method']
jrpc_key = JSON_RPC_LOOKUPS['episodeid']['key']
jrpc_id = "episodeid"
jrpc_idtype = int

def get_directory(self, dbid, **kwargs):
items = self.get_cast_items(dbid)
self.add_items(items, container_content='actors')
Copy link

Copilot AI Jan 3, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The cast classes don't define several class attributes that are defined in the base class and other subclasses: jrpc_properties, jrpc_sublookups, item_dbtype, item_library, and container_content. While these aren't used by the overridden get_directory method, it's inconsistent with the pattern established by other subclasses (ListGetMovieDetails, ListGetTVShowDetails, etc.). Consider adding these attributes for consistency, or document why they're intentionally omitted.

Copilot uses AI. Check for mistakes.
Comment on lines +457 to +489
def get_directory(self, dbid, **kwargs):
items = self.get_cast_items(dbid)
self.add_items(items, container_content='actors')


class ListGetTVShowCast(ListGetItemDetails):
"""
Get cast information for a TV show and populate a container with cast members.
Each list item represents a cast member with name, role, and thumbnail.
"""
jrpc_method = JSON_RPC_LOOKUPS['tvshowid']['method']
jrpc_key = JSON_RPC_LOOKUPS['tvshowid']['key']
jrpc_id = "tvshowid"
jrpc_idtype = int

def get_directory(self, dbid, **kwargs):
items = self.get_cast_items(dbid)
self.add_items(items, container_content='actors')


class ListGetEpisodeCast(ListGetItemDetails):
"""
Get cast information for an episode and populate a container with cast members.
Each list item represents a cast member with name, role, and thumbnail.
"""
jrpc_method = JSON_RPC_LOOKUPS['episodeid']['method']
jrpc_key = JSON_RPC_LOOKUPS['episodeid']['key']
jrpc_id = "episodeid"
jrpc_idtype = int

def get_directory(self, dbid, **kwargs):
items = self.get_cast_items(dbid)
self.add_items(items, container_content='actors')
Copy link
Owner

@jurialmunkey jurialmunkey Jan 5, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@heros-os - Please address copilot comments by creating a parent class ListGetCast which the child types can inherit

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please remove this file.

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove this file. Documentation should be done in the wiki. Too much LLM crud.

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove this file. Docs go in wiki

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove this file. Docs go in wiki

return []

cast_items = []
for idx, cast_member in enumerate(cast):
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why are you enumerating. Cast is unordered in database so index position is irrelevant. Needs to be sorted by order key.

name = cast_member.get('name', '')
role = cast_member.get('role', '')
thumbnail = cast_member.get('thumbnail', '')
order = cast_member.get('order', idx)
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Position in database is not relevant. Order should not fallback to index.

listitem.setProperty('thumbnail', thumbnail)

# Add to items list
cast_items.append(('', listitem, False))
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Construction of listitem should be done in a function or class so that a list comprehension can be used.

# Add to items list
cast_items.append(('', listitem, False))

return cast_items
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

list is unordered


return items

def get_cast_items(self, dbid):
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This function should not be part of this class. Class is specifically a parent class for getting details about a single item. Adding another method here for cast is incorrect.

items = self.get_items(dbid, **kwargs)
self.add_items(items, container_content=self.container_content)

def get_cast_directory(self, dbid, **kwargs):
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is not the right place for this method. Create a separate class for getting cast instead of pinning it into the item details look up class.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants