Kometa-Team / ImageMaid

Python 3 Script for Cleaning Up Images in Plex
MIT License
255 stars 12 forks source link

[Feature]: Remove dependency on Plex database #17

Closed JonnyWong16 closed 6 months ago

JonnyWong16 commented 1 year ago

Describe the Feature Request

The resource folder path can be found purely using the Plex API.

Example code:

from hashlib import sha1
from pathlib import Path
from plexapi.server import PlexServer

PMS_DIRECTORY = Path('Plex Media Server')
METADATA_DIRECTORY = PMS_DIRECTORY / 'Metadata'
METADATA_FOLDER_MAP = {
    'movie': 'Movies',
    'show': 'TV Shows',
    'season': 'TV Shows',
    'episode': 'TV Shows',
    'artist': 'Artists',
    'album': 'Albums',
    'track': 'Albums',
    'photo': 'Photos',
    'collection': 'Collections',
    'playlist': 'Playlists'
}

def get_items(section):
    for item in section.all():
        yield item

        if item.type in ('show', 'artist'):
            for child in item:
                yield child

                if child.type in ('season', 'album'):
                    for grandchild in child:
                        yield grandchild

    if section.type != 'photo':
        for item in section.collections():
            yield item

    for item in section.playlists():
        yield item

def get_resources(item):
    for method in ('posters', 'arts', 'themes'):
        for resource in getattr(item, method, lambda: [])():
            yield resource

def build_resource_path(item, resource):
    if item.type == 'season':
        guid = item.parentGuid
    elif item.type == 'episode':
        guid = item.grandparentGuid
    elif item.type == 'track':
        guid = item.parentGuid
    else:
        guid = item.guid

    guid_hash = sha1(guid.encode('utf-8')).hexdigest()
    resource_path = resource.ratingKey.split('://')[-1]

    return (
        METADATA_DIRECTORY / METADATA_FOLDER_MAP[item.type]
        / guid_hash[0] / f"{guid_hash[1:]}.bundle"
        / 'Uploads' / resource_path
    )

def process_resource(item, resource):
    resource_path = build_resource_path(item, resource)

    # Do whatever you want with the resource (delete, move, etc.)
    print(item, resource_path)

if __name__ == '__main__':
    plex = PlexServer()

    for section in plex.library.sections():
        for item in get_items(section):
            for resource in get_resources(item):
                # Uploaded resource and not currently selected
                if resource.ratingKey.startswith('upload://') and not resource.selected:
                    process_resource(item, resource)