"""A python module to retrieve information from Ombi. For license information, see the LICENSE.txt file. """ import logging _LOGGER = logging.getLogger(__name__) _BASE_URL = "http{ssl}://{host}:{port}/{urlbase}api/v1/" def request(f): r = f().json() if r["isError"]: raise OmbiError(r["errorMessage"]) return r class Ombi(object): """A class for handling connections with an Ombi instance.""" def __init__( self, ssl, username, host, port, urlbase="", api_key=None, password=None ): self._base_url = _BASE_URL.format( ssl="s" if ssl else "", host=host, port=port, urlbase=urlbase ) self._api_key = api_key self._username = username self._password = password self._auth = None def test_connection(self): self._request_connection(path="Status") def _request_connection(self, path, post_data=None, auth=True): import requests url = f"{self._base_url}{path}" headers = {"UserName": self._username} if auth: headers.update(**self._auth) try: if post_data is None: res = requests.get(url=url, headers=headers, timeout=8) else: res = requests.post(url=url, headers=headers, json=post_data, timeout=8) res.raise_for_status() res.json() return res except TypeError: raise OmbiError("No authentication type set.") except requests.exceptions.Timeout: raise OmbiError("Request timed out. Check port configuration.") except requests.exceptions.ConnectionError: raise OmbiError("Connection error. Check host configuration.") except requests.exceptions.TooManyRedirects: raise OmbiError("Too many redirects.") except requests.exceptions.HTTPError as err: status = err.response.status_code if status == 401: raise OmbiError("Unauthorized error. Check authentication credentials.") else: raise OmbiError(f"HTTP Error {status}. Check SSL configuration.") except ValueError: raise OmbiError("ValueError. Check urlbase configuration.") def authenticate(self): if self._api_key: self._auth = {"ApiKey": self._api_key} return credentials = {"userName": self._username, "password": self._password} token = ( self._request_connection(path="Token", post_data=credentials, auth=False) .json() .get("access_token") ) self._auth = {"Authorization": f"Bearer {token}"} def search_movie(self, query): return self._request_connection(f"Search/movie/{query}").json() def search_tv(self, query): return self._request_connection(f"Search/tv/{query}").json() def search_music_album(self, query): return self._request_connection(f"Search/music/album/{query}").json() def request_movie(self, movie_id): data = {"theMovieDbId": movie_id} request(lambda: self._request_connection(path="Request/movie", post_data=data)) def request_tv( self, tv_id, request_all=False, request_latest=False, request_first=False ): data = { "tvDbId": tv_id, "latestSeason": request_latest, "requestAll": request_all, "firstSeason": request_first, } request(lambda: self._request_connection(path="Request/tv", post_data=data)) def request_music(self, album_id): data = {"foreignAlbumId": album_id} request(lambda: self._request_connection(path="Request/music", post_data=data)) @property def movie_requests(self): requests = self._request_connection("Request/movie/total").text return 0 if requests is None else requests @property def tv_requests(self): requests = self._request_connection("Request/tv/total").text return 0 if requests is None else requests @property def music_requests(self): requests = self._request_connection("Request/music/total").text return 0 if requests is None else requests @property def total_requests(self): return self._request_connection("Request/count").json() class OmbiError(Exception): pass