File: kodiupdate.py

package info (click to toggle)
beets 2.5.1-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 8,016 kB
  • sloc: python: 46,429; javascript: 8,018; xml: 334; sh: 261; makefile: 125
file content (105 lines) | stat: -rw-r--r-- 3,383 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
# This file is part of beets.
# Copyright 2017, Pauli Kettunen.
#
# Permission is hereby granted, free of charge, to any person obtaining
# a copy of this software and associated documentation files (the
# "Software"), to deal in the Software without restriction, including
# without limitation the rights to use, copy, modify, merge, publish,
# distribute, sublicense, and/or sell copies of the Software, and to
# permit persons to whom the Software is furnished to do so, subject to
# the following conditions:
#
# The above copyright notice and this permission notice shall be
# included in all copies or substantial portions of the Software.

"""Updates a Kodi library whenever the beets library is changed.
This is based on the Plex Update plugin.

Put something like the following in your config.yaml to configure:
    kodi:
        host: localhost
        port: 8080
        user: user
        pwd: secret
"""

import requests

from beets.plugins import BeetsPlugin


def update_kodi(host, port, user, password):
    """Sends request to the Kodi api to start a library refresh."""
    url = f"http://{host}:{port}/jsonrpc"

    """Content-Type: application/json is mandatory
    according to the kodi jsonrpc documentation"""

    headers = {"Content-Type": "application/json"}

    # Create the payload. Id seems to be mandatory.
    payload = {"jsonrpc": "2.0", "method": "AudioLibrary.Scan", "id": 1}
    r = requests.post(
        url,
        auth=(user, password),
        json=payload,
        headers=headers,
        timeout=10,
    )

    return r


class KodiUpdate(BeetsPlugin):
    def __init__(self):
        super().__init__("kodi")

        # Adding defaults.
        self.config.add(
            [{"host": "localhost", "port": 8080, "user": "kodi", "pwd": "kodi"}]
        )

        self.config["user"].redact = True
        self.config["pwd"].redact = True
        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"""
        self.register_listener("cli_exit", self.update)

    def update(self, lib):
        """When the client exists try to send refresh request to Kodi server."""
        self._log.info("Requesting a Kodi library update...")

        kodi = self.config.get()

        # Backwards compatibility in case not configured as an array
        if not isinstance(kodi, list):
            kodi = [kodi]

        for instance in kodi:
            # Try to send update request.
            try:
                r = update_kodi(
                    instance["host"],
                    instance["port"],
                    instance["user"],
                    instance["pwd"],
                )
                r.raise_for_status()

                json = r.json()
                if json.get("result") != "OK":
                    self._log.warning(
                        "Kodi update failed: JSON response was {0!r}", json
                    )
                    continue

                self._log.info(
                    "Kodi update triggered for {}:{}",
                    instance["host"],
                    instance["port"],
                )
            except requests.exceptions.RequestException as e:
                self._log.warning("Kodi update failed: {}", str(e))
                continue