1"""
2Display if a Twitch channel is currently streaming or not.
3
4Configuration parameters:
5    cache_timeout: how often we refresh this module in seconds
6        (default 60)
7    client_id: Your client id. Create your own key at https://dev.twitch.tv
8        (default None)
9    format: Display format when online
10        (default "{display_name} is live!")
11    format_offline: Display format when offline
12        (default "{display_name} is offline.")
13    stream_name: name of streamer(twitch.tv/<stream_name>)
14        (default None)
15
16Format placeholders:
17    {display_name} streamer display name, eg Ultrabug
18
19Color options:
20    color_bad: Stream offline
21    color_good: Stream is live
22
23Client ID:
24    Example settings when creating your app at https://dev.twitch.tv
25
26    Name: <your_name>_py3status
27    OAuth Redirect URI: https://localhost
28    Application Category: Application Integration
29
30
31@author Alex Caswell horatioesf@virginmedia.com
32@license BSD
33
34SAMPLE OUTPUT
35{'color': '#00FF00', 'full_text': 'exotic_bug is live!'}
36
37offline
38{'color': '#FF0000', 'full_text': 'exotic_bug is offline!'}
39"""
40
41STRING_MISSING = "missing {}"
42
43
44class Py3status:
45    """
46    """
47
48    # available configuration parameters
49    cache_timeout = 60
50    client_id = None
51    format = "{display_name} is live!"
52    format_offline = "{display_name} is offline."
53    stream_name = None
54
55    class Meta:
56        deprecated = {
57            "remove": [{"param": "format_invalid", "msg": "obsolete"}],
58            "rename_placeholder": [
59                {
60                    "placeholder": "stream_name",
61                    "new": "display_name",
62                    "format_strings": ["format"],
63                }
64            ],
65        }
66
67    def post_config_hook(self):
68        for config_name in ["client_id", "stream_name"]:
69            if not getattr(self, config_name, None):
70                raise Exception(STRING_MISSING.format(config_name))
71
72        self.headers = {"Client-ID": self.client_id}
73        base_api = "https://api.twitch.tv/kraken/"
74        self.url = {
75            "users": base_api + f"users/{self.stream_name}",
76            "streams": base_api + f"streams/{self.stream_name}",
77        }
78        self.users = {}
79
80    def _get_twitch_data(self, url):
81        try:
82            response = self.py3.request(url, headers=self.headers)
83        except self.py3.RequestException:
84            return {}
85        data = response.json()
86        if not data:
87            data = vars(response)
88            error = data.get("_error_message")
89            if error:
90                self.py3.error("{} {}".format(error, data["_status_code"]))
91        return data
92
93    def twitch(self):
94        twitch_data = self.users
95        current_format = ""
96        color = None
97
98        if not twitch_data:
99            self.users = self._get_twitch_data(self.url["users"])
100            twitch_data.update(self.users)
101
102        streams = self._get_twitch_data(self.url["streams"])
103        if streams:
104            twitch_data.update(streams)
105            if twitch_data["stream"]:
106                color = self.py3.COLOR_GOOD
107                current_format = self.format
108            else:
109                color = self.py3.COLOR_BAD
110                current_format = self.format_offline
111
112        response = {
113            "cached_until": self.py3.time_in(self.cache_timeout),
114            "full_text": self.py3.safe_format(current_format, twitch_data),
115        }
116        if color:
117            response["color"] = color
118        return response
119
120
121if __name__ == "__main__":
122    """
123    Run module in test mode.
124    """
125    from py3status.module_test import module_test
126
127    module_test(Py3status)
128