Skip to content

Label edits do not apply when batch editing #1475

Closed

Description

@CollinHeist

Describe the Bug

When batch editing library.batchMultiEdits(), the label edits (specifically the removal) to an episode are not properly applying.

Code Snippets

plex = PlexServer('URL', 'TOKEN')

# Add label to be removed
episode = plex.fetchItem(13312)
episode.addLabel('Example')

# Attempt to remove label
library = plex.library.section('LIBRARY NAME')
library.batchMultiEdits([episode])
episode.removeLabel(['Example'])
library.saveMultiEdits()

Expected Behavior

I expect label edits to properly apply whether batch edits are being used or not.

Additional Context

I am creating this issue for another person, as I've been unable to recreate the issue on my end.

Operating System and Version

N/A

Plex Media Server Version

N/A

Python Version

N/A

PlexAPI Version

4.15.16

Activity

  1. JonnyWong16 commented on Oct 29, 2024

    @JonnyWong16
    Collaborator

    Your code snippet should say library.removeLabel(['Example']).

    I also cannot reproduce the issue.

    >>> from plexapi.server import PlexServer
    >>> plex = PlexServer()
    >>> episode = plex.fetchItem(3233)
    >>> episode.labels
    []
    >>> episode.addLabel('Example')
    >>> episode.reload()
    >>> episode.labels
    [<Label:20698:Example>]
    
    >>> library = plex.library.section('TV Shows (Test)')
    >>> library.batchMultiEdits([episode]) 
    >>> library.removeLabel(['Example']) 
    >>> library.saveMultiEdits()
    >>> episode.reload()
    >>> episode.labels
    []

    This appears to be a problem with that user's own Plex Media Server database. They should check for database corruption and optimize their database.

  2. CollinHeist commented on Oct 29, 2024

    @CollinHeist
    Author

    @JonnyWong16 Thanks for the quick response.

    Your code snippet should say library.removeLabel(['Example'])

    I am calling episode.removeLabel(['Example']) because that is the same API call made in the past (before swapping to batch edits), and that works for me (and all but this one user). Does calling this method on the library only remove the label from the batched episode? If I should be calling that on the library, perhaps that's the issue? I couldn't find much information on using these batched operations in the docs.

    This appears to be a problem with that user's own Plex Media Server database. They should check for database corruption and optimize their database.

    I am inclined to agree with you there. I've reviewed the API calls made to Plex and have not seen any issues (although the exact format of label removal is a bit convoluted), and obviously have not had issues with anyone else. I'll make that suggestion.

  3. CollinHeist commented on Oct 29, 2024

    @CollinHeist
    Author

    Oh I should add that in this case the episode labels show as removed within the API (e.g. printing the labels after the fact shows no removed label), but the XML of the episode itself shows the "removed" label still present.

  4. JonnyWong16 commented on Oct 29, 2024

    @JonnyWong16
    Collaborator

    library.removeLabel(['Example']) edits the batched items passed into batchMultiEdits().

    episode.removeLabel(['Example']) is just editing the one episode. You're not doing any of the batching.

    For example, this doesn't make sense.

    library.batchMultiEdits([episode1, episode2, episode3, episode4])
    episode1.removeLabel('Example')
    library.saveMultiEdits()  # What happened to episode2, episode3, and episode4?

    There's an example in the documentation:
    https://python-plexapi.readthedocs.io/en/latest/modules/library.html#plexapi.library.LibrarySection.batchMultiEdits

    If it's in the XML data then it should be parsed into PlexAPI. I can't see any way it can show up in the XML but not parsed.

    I checked the episode I edited on my server and there is no label in the XML data.

  5. CollinHeist commented on Oct 29, 2024

    @CollinHeist
    Author

    Makes sense - I was assuming it was modifying the methods for the batched objects in some way so that the API calls were only submitted after the saveMultiEdits() call - but it does seem more clear that it's a library-level operation.

    If it's in the XML data then it should be parsed into PlexAPI. I can't see any way it can show up in the XML but not parsed. I checked the episode I edited on my server and there is no label in the XML data.

    That was my understanding/observation as well. I'll follow up with the user and suggest the DB corruption / optimization. Thanks!

  6. CollinHeist commented on Nov 6, 2024

    @CollinHeist
    Author

    @JonnyWong16 Hey, sorry for the ping, would you be able to comment on the expected behavior here?

    plex = PlexServer('URL', 'TOKEN')
    
    episode = plex.fetchItem(13312)
    episode.addLabel('remove_me')
    
    library = plex.library.section('LIBRARY NAME')
    library.batchMultiEdits([episode])
    
    episode.removeLabel(['remove_me'])
    
    library.addLabel(['Another Label'])
    library.saveMultiEdits()

    I've noticed that this results in the Another Label being added, but remove_me not being removed, which seems like unintended behavior (and was actually the root cause of the prior issue). I understand it is counterintuitive to add a label to episode in this way (not via batch edits).

  7. JonnyWong16 commented on Nov 6, 2024

    @JonnyWong16
    Collaborator

    I tested your code snippet and it works as expected if I run the code to the end. The episode had Another Label and did not have remove_me.

    I did find a small quirk if you stop before the saveMultiEdits(). The episode.removeLabel(['remove_me']) actually doesn't run because the library has multi-edit enabled. This is unexpected to me and is counter to what I said in my previous comment. I expected the episode to have no labels at this point.

    What I expected:

    plex = PlexServer('URL', 'TOKEN')
    
    episode = plex.fetchItem(13312)
    episode.addLabel('remove_me')  # `remove_me` label added
    
    library = plex.library.section('LIBRARY NAME')
    library.batchMultiEdits([episode])
    
    episode.removeLabel(['remove_me'])  # `remove_me` label removed
    
    library.addLabel(['Another Label'])  # `Another Label` waiting for saving multi-edits to add
    
    # episode has no labels
    library.saveMultiEdits()
    # episode only has `Another Label`

    What actually happened:

    plex = PlexServer('URL', 'TOKEN')
    
    episode = plex.fetchItem(13312)
    episode.addLabel('remove_me')  # `remove_me` label added
    
    library = plex.library.section('LIBRARY NAME')
    library.batchMultiEdits([episode])
    
    episode.removeLabel(['remove_me'])  # `remove_me` label waiting for saving multi-edits to remove
    
    library.addLabel(['Another Label'])  # `Another Label` waiting for saving multi-edits to add
    
    # episode has `remove_me` label
    library.saveMultiEdits()
    # episode only has `Another Label`
  8. CollinHeist commented on Nov 6, 2024

    @CollinHeist
    Author

    There must be a difference in behavior when doing add/remove operations, I had mixed up the two for my example - can you run:

    plex = PlexServer('URL', 'TOKEN')
    
    episode = plex.fetchItem(12345)
    library = plex.library.section('LIBRARY')
    
    episode.addLabel(['remove_me'])
    
    library.batchMultiEdits([episode])
    library.removeLabel(['remove_me'])
    episode.addLabel(['add_me'])
    
    library.saveMultiEdits()

    In this scenario on my and three other users' PCs, the multi edit label (remove_me) is not removed, and the episode label (add_me) is added. Are you able to replicate this?

  9. JonnyWong16 commented on Nov 6, 2024

    @JonnyWong16
    Collaborator

    Okay, I can reproduce the issue with that order of operations. I think the problem is the add function appends based on the current list of tags.

    I don't know if this requires a fix, but I might have an idea. Or just don't use individual episode operations inside multi-edit per my original comment.

  10. JonnyWong16 commented on Nov 6, 2024

    @JonnyWong16
    Collaborator

    The fix is actually really easy. Just need to change this one line.

    https://github.com/pkkid/python-plexapi/blob/aba6b9862fa8898bf24da55e1fc859548a9bcbf6/plexapi/library.py#L1743

            if isinstance(self._edits, dict) and items is None:

    Note: this will fix the behaviour of doing episode.addLabel() inside a multi-edit to only change the one episode. i.e. What I expected to happen per my previous comment. So if you are using multi-edit, you must use library.addLabel().

  11. added a commit that references this issue on Nov 6, 2024
    ac8b28c
  12. CollinHeist commented on Nov 6, 2024

    @CollinHeist
    Author

    That's great news, glad it's an easy fix/change. After that fix I'll also start properly using the multi edits, and that should be this issue resolved. Thanks

  13. added a commit that references this issue on Nov 16, 2024
    4a8f748
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions