"""Updates an Plex library whenever the beets library is changed.

Plex Home users enter the Plex Token to enable updating.
Put something like the following in your config.yaml to configure:
    plex:
        host: localhost
        port: 32400
        token: token
"""
from __future__ import (division, absolute_import, print_function,
                        unicode_literals)

import requests
from urlparse import urljoin
from urllib import urlencode
import xml.etree.ElementTree as ET
from beets import config
from beets.plugins import BeetsPlugin


def get_music_section(host, port, token, library_name):
    """Getting the section key for the music library in Plex.
    """
    api_endpoint = append_token('library/sections', token)
    url = urljoin('http://{0}:{1}'.format(host, port), api_endpoint)

    # Sends request.
    r = requests.get(url)

    # Parse xml tree and extract music section key.
    tree = ET.fromstring(r.text)
    for child in tree.findall('Directory'):
        if child.get('title') == library_name:
            return child.get('key')


def update_plex(host, port, token, library_name):
    """Sends request to the Plex api to start a library refresh.
    """
    # Getting section key and build url.
    section_key = get_music_section(host, port, token, library_name)
    api_endpoint = 'library/sections/{0}/refresh'.format(section_key)
    api_endpoint = append_token(api_endpoint, token)
    url = urljoin('http://{0}:{1}'.format(host, port), api_endpoint)

    # Sends request and returns requests object.
    r = requests.get(url)
    return r


def append_token(url, token):
    """Appends the Plex Home token to the api call if required.
    """
    if token:
        url += '?' + urlencode({'X-Plex-Token': token})
    return url


class PlexUpdate(BeetsPlugin):
    def __init__(self):
        super(PlexUpdate, self).__init__()

        # Adding defaults.
        config['plex'].add({
            u'host': u'localhost',
            u'port': 32400,
            u'token': u'',
            u'library_name': u'Music'})

        self.register_listener('database_change', self.listen_for_db_change)

    def listen_for_db_change(self, lib, model):
        """Listens for beets db change and register the update for the end"""
        self.register_listener('cli_exit', self.update)

    def update(self, lib):
        """When the client exists try to send refresh request to Plex server.
        """
        self._log.info('Updating Plex library...')

        # Try to send update request.
        try:
            update_plex(
                config['plex']['host'].get(),
                config['plex']['port'].get(),
                config['plex']['token'].get(),
                config['plex']['library_name'].get())
            self._log.info('... started.')

        except requests.exceptions.RequestException:
            self._log.warning('Update failed.')

beetsplug/plexupdate.py
"""Updates an Plex library whenever the beets library is changed.

Plex Home users enter the Plex Token to enable updating.
Put something like the following in your config.yaml to configure:
    plex:
        host: localhost
        port: 32400
        token: token
"""
from __future__ import (division, absolute_import, print_function,
                        unicode_literals)

import requests
from urlparse import urljoin
from urllib import urlencode
import xml.etree.ElementTree as ET
from beets import config
from beets.plugins import BeetsPlugin


def get_music_section(host, port, token, library_name):
    """Getting the section key for the music library in Plex.
    """
    api_endpoint = append_token('library/sections', token)
    url = urljoin('http://{0}:{1}'.format(host, port), api_endpoint)

    # Sends request.
    r = requests.get(url)

    # Parse xml tree and extract music section key.
    tree = ET.fromstring(r.content)
    for child in tree.findall('Directory'):
        if child.get('title') == library_name:
            return child.get('key')


def update_plex(host, port, token, library_name):
    """Sends request to the Plex api to start a library refresh.
    """
    # Getting section key and build url.
    section_key = get_music_section(host, port, token, library_name)
    api_endpoint = 'library/sections/{0}/refresh'.format(section_key)
    api_endpoint = append_token(api_endpoint, token)
    url = urljoin('http://{0}:{1}'.format(host, port), api_endpoint)

    # Sends request and returns requests object.
    r = requests.get(url)
    return r


def append_token(url, token):
    """Appends the Plex Home token to the api call if required.
    """
    if token:
        url += '?' + urlencode({'X-Plex-Token': token})
    return url


class PlexUpdate(BeetsPlugin):
    def __init__(self):
        super(PlexUpdate, self).__init__()

        # Adding defaults.
        config['plex'].add({
            u'host': u'localhost',
            u'port': 32400,
            u'token': u'',
            u'library_name': u'Music'})

        self.register_listener('database_change', self.listen_for_db_change)

    def listen_for_db_change(self, lib, model):
        """Listens for beets db change and register the update for the end"""
        self.register_listener('cli_exit', self.update)

    def update(self, lib):
        """When the client exists try to send refresh request to Plex server.
        """
        self._log.info('Updating Plex library...')

        # Try to send update request.
        try:
            update_plex(
                config['plex']['host'].get(),
                config['plex']['port'].get(),
                config['plex']['token'].get(),
                config['plex']['library_name'].get())
            self._log.info('... started.')

        except requests.exceptions.RequestException:
            self._log.warning('Update failed.')

beetsplug/plexupdate.py
diff --git a/beetsplug/plexupdate.py b/beetsplug/plexupdate.py
index 340bcdf4d4..8cb1d375d6 100644
--- a/beetsplug/plexupdate.py
+++ b/beetsplug/plexupdate.py
@@ -28,7 +28,7 @@ def get_music_section(host, port, token, library_name):
     r = requests.get(url)
 
     # Parse xml tree and extract music section key.
-    tree = ET.fromstring(r.text)
+    tree = ET.fromstring(r.content)
     for child in tree.findall('Directory'):
         if child.get('title') == library_name:
             return child.get('key')

plexupdate plugin crashed
Every time after import plexupdate plugin crashed with this error:

```
Traceback (most recent call last):
  File "/usr/local/bin/beet", line 9, in <module>
    load_entry_point('beets==1.3.15', 'console_scripts', 'beet')()
  File "/usr/local/lib/python2.7/dist-packages/beets/ui/__init__.py", line 1163, in main
    _raw_main(args)
  File "/usr/local/lib/python2.7/dist-packages/beets/ui/__init__.py", line 1155, in _raw_main
    plugins.send('cli_exit', lib=lib)
  File "/usr/local/lib/python2.7/dist-packages/beets/plugins.py", line 458, in send
    result = handler(**arguments)
  File "/usr/local/lib/python2.7/dist-packages/beets/plugins.py", line 123, in wrapper
    return func(*args, **kwargs)
  File "/usr/local/lib/python2.7/dist-packages/beetsplug/plexupdate.py", line 87, in update
    config['plex']['library_name'].get())
  File "/usr/local/lib/python2.7/dist-packages/beetsplug/plexupdate.py", line 41, in update_plex
    section_key = get_music_section(host, port, token, library_name)
  File "/usr/local/lib/python2.7/dist-packages/beetsplug/plexupdate.py", line 31, in get_music_section
    tree = ET.fromstring(r.raw)
  File "/usr/lib/python2.7/xml/etree/ElementTree.py", line 1300, in XML
    parser.feed(text)
  File "/usr/lib/python2.7/xml/etree/ElementTree.py", line 1640, in feed
    self._parser.Parse(data, 0)
TypeError: must be string or read-only buffer, not HTTPResponse
```

