# Path: soco/exceptions.py
# class DIDLMetadataError(CannotCreateDIDLMetadata):
# 
#     """Raised if a data container class cannot create the DIDL metadata due to
#     missing information.
# 
#     For backward compatibility, this is currently a subclass of
#     `CannotCreateDIDLMetadata`. In a future version, it will likely become
#     a direct subclass of `SoCoException`.
#     """
# 
# Path: soco/utils.py
# def really_unicode(in_string):
#     """Make a string unicode. Really.
# 
#     Ensure ``in_string`` is returned as unicode through a series of
#     progressively relaxed decodings.
# 
#     Args:
#         in_string (str): The string to convert.
# 
#     Returns:
#         str: Unicode.
# 
#     Raises:
#         ValueError
#     """
#     if isinstance(in_string, bytes):
#         for args in (("utf-8",), ("latin-1",), ("ascii", "replace")):
#             try:
#                 # pylint: disable=star-args
#                 in_string = in_string.decode(*args)
#                 break
#             except UnicodeDecodeError:
#                 continue
#     if not isinstance(in_string, str):
#         raise ValueError("%s is not a string at all." % in_string)
#     return in_string
# 
# def first_cap(string):
#     """Return upper cased first character"""
#     return string[0].upper() + string[1:]


import textwrap
import warnings
from .exceptions import DIDLMetadataError
from .utils import really_unicode, first_cap
from .xml import XML, ns_tag
from .data_structure_quirks import apply_resource_quirks
            from . import data_structures_entry
    # We know that the string starts with "object." so -1 indexing is safe
    parts = didl_class.split(".")
    # If it is a Sonos favorite, form the name as the class component
    # before with "Favorite" added. So:
    # object.item.audioItem.audioBroadcast.sonos-favorite
    # turns into
    # DidlAudioBroadcastFavorite
    if parts[-1] == "sonos-favorite" and len(parts) >= 2:
        return "Didl" + first_cap(parts[-2]) + "Favorite"

    # For any other class, for the name as the concatenation of all
    # the class components that are not UPnP core classes. So:
    # object.container.playlistContainer.sameArtist
    # Turns into:
    # DidlSameArtist
    search_parts = parts[:]
    new_parts = []
    # Strip the components one by one and check whether the base is known
    while search_parts:
        new_parts.append(search_parts[-1])
        search_parts = search_parts[:-1]
        search_class = ".".join(search_parts)
        if search_class in _OFFICIAL_CLASSES:
            break

    # For class path last parts that contain the word list, capitalize it
    if new_parts[0].endswith("list"):
        new_parts[0] = new_parts[0].replace("list", "List")
    new_parts = reversed(new_parts)


# Path: soco/exceptions.py
# class DIDLMetadataError(CannotCreateDIDLMetadata):
# 
#     """Raised if a data container class cannot create the DIDL metadata due to
#     missing information.
# 
#     For backward compatibility, this is currently a subclass of
#     `CannotCreateDIDLMetadata`. In a future version, it will likely become
#     a direct subclass of `SoCoException`.
#     """
# 
# Path: soco/utils.py
# def really_unicode(in_string):
#     """Make a string unicode. Really.
# 
#     Ensure ``in_string`` is returned as unicode through a series of
#     progressively relaxed decodings.
# 
#     Args:
#         in_string (str): The string to convert.
# 
#     Returns:
#         str: Unicode.
# 
#     Raises:
#         ValueError
#     """
#     if isinstance(in_string, bytes):
#         for args in (("utf-8",), ("latin-1",), ("ascii", "replace")):
#             try:
#                 # pylint: disable=star-args
#                 in_string = in_string.decode(*args)
#                 break
#             except UnicodeDecodeError:
#                 continue
#     if not isinstance(in_string, str):
#         raise ValueError("%s is not a string at all." % in_string)
#     return in_string
# 
# def first_cap(string):
#     """Return upper cased first character"""
#     return string[0].upper() + string[1:]


# Path: soco/data_structures.py
import textwrap
import warnings
from .exceptions import DIDLMetadataError
from .utils import really_unicode, first_cap
from .xml import XML, ns_tag
from .data_structure_quirks import apply_resource_quirks
            from . import data_structures_entry

    # We know that the string starts with "object." so -1 indexing is safe
    parts = didl_class.split(".")
    # If it is a Sonos favorite, form the name as the class component
    # before with "Favorite" added. So:
    # object.item.audioItem.audioBroadcast.sonos-favorite
    # turns into
    # DidlAudioBroadcastFavorite
    if parts[-1] == "sonos-favorite" and len(parts) >= 2:
        return "Didl" + first_cap(parts[-2]) + "Favorite"

    # For any other class, for the name as the concatenation of all
    # the class components that are not UPnP core classes. So:
    # object.container.playlistContainer.sameArtist
    # Turns into:
    # DidlSameArtist
    search_parts = parts[:]
    new_parts = []
    # Strip the components one by one and check whether the base is known
    while search_parts:
        new_parts.append(search_parts[-1])
        search_parts = search_parts[:-1]
        search_class = ".".join(search_parts)
        if search_class in _OFFICIAL_CLASSES:
            break

    # For class path last parts that contain the word list, capitalize it
    if new_parts[0].endswith("list"):
        new_parts[0] = new_parts[0].replace("list", "List")
    new_parts = reversed(new_parts)


    return "Didl" + "".join(first_cap(s) for s in new_parts)