1"""
2Library for interacting with Pushover API
3
4.. versionadded:: 2016.3.0
5"""
6
7import http.client
8import logging
9from urllib.parse import urlencode, urljoin
10
11import salt.utils.http
12from salt.version import __version__
13
14log = logging.getLogger(__name__)
15
16
17def query(
18    function,
19    token=None,
20    api_version="1",
21    method="POST",
22    header_dict=None,
23    data=None,
24    query_params=None,
25    opts=None,
26):
27    """
28    PushOver object method function to construct and execute on the API URL.
29
30    :param token:       The PushOver api key.
31    :param api_version: The PushOver API version to use, defaults to version 1.
32    :param function:    The PushOver api function to perform.
33    :param method:      The HTTP method, e.g. GET or POST.
34    :param data:        The data to be sent for POST method.
35    :return:            The json response from the API call or False.
36    """
37
38    ret = {"message": "", "res": True}
39
40    pushover_functions = {
41        "message": {"request": "messages.json", "response": "status"},
42        "validate_user": {"request": "users/validate.json", "response": "status"},
43        "validate_sound": {"request": "sounds.json", "response": "status"},
44    }
45
46    api_url = "https://api.pushover.net"
47    base_url = urljoin(api_url, api_version + "/")
48    path = pushover_functions.get(function).get("request")
49    url = urljoin(base_url, path, False)
50
51    if not query_params:
52        query_params = {}
53
54    decode = True
55    if method == "DELETE":
56        decode = False
57
58    result = salt.utils.http.query(
59        url,
60        method,
61        params=query_params,
62        data=data,
63        header_dict=header_dict,
64        decode=decode,
65        decode_type="json",
66        text=True,
67        status=True,
68        cookies=True,
69        persist_session=True,
70        opts=opts,
71    )
72
73    if result.get("status", None) == http.client.OK:
74        response = pushover_functions.get(function).get("response")
75        if response in result and result[response] == 0:
76            ret["res"] = False
77        ret["message"] = result
78        return ret
79    else:
80        try:
81            if "response" in result and result[response] == 0:
82                ret["res"] = False
83            ret["message"] = result
84        except ValueError:
85            ret["res"] = False
86            ret["message"] = result
87        return ret
88
89
90def validate_sound(sound, token):
91    """
92    Send a message to a Pushover user or group.
93    :param sound:       The sound that we want to verify
94    :param token:       The PushOver token.
95    """
96    ret = {"message": "Sound is invalid", "res": False}
97    parameters = dict()
98    parameters["token"] = token
99
100    response = query(function="validate_sound", method="GET", query_params=parameters)
101
102    if response["res"]:
103        if "message" in response:
104            _message = response.get("message", "")
105            if "status" in _message:
106                if _message.get("dict", {}).get("status", "") == 1:
107                    sounds = _message.get("dict", {}).get("sounds", "")
108                    if sound in sounds:
109                        ret["message"] = "Valid sound {}.".format(sound)
110                        ret["res"] = True
111                    else:
112                        ret["message"] = "Warning: {} not a valid sound.".format(sound)
113                        ret["res"] = False
114                else:
115                    ret["message"] = "".join(_message.get("dict", {}).get("errors"))
116    return ret
117
118
119def validate_user(user, device, token):
120    """
121    Send a message to a Pushover user or group.
122    :param user:        The user or group name, either will work.
123    :param device:      The device for the user.
124    :param token:       The PushOver token.
125    """
126    res = {"message": "User key is invalid", "result": False}
127
128    parameters = dict()
129    parameters["user"] = user
130    parameters["token"] = token
131    if device:
132        parameters["device"] = device
133
134    response = query(
135        function="validate_user",
136        method="POST",
137        header_dict={"Content-Type": "application/x-www-form-urlencoded"},
138        data=urlencode(parameters),
139    )
140
141    if response["res"]:
142        if "message" in response:
143            _message = response.get("message", "")
144            if "status" in _message:
145                if _message.get("dict", {}).get("status", None) == 1:
146                    res["result"] = True
147                    res["message"] = "User key is valid."
148                else:
149                    res["result"] = False
150                    res["message"] = "".join(_message.get("dict", {}).get("errors"))
151    return res
152