diff options
Diffstat (limited to 'beinc_weechat.py')
| -rw-r--r-- | beinc_weechat.py | 416 |
1 files changed, 196 insertions, 220 deletions
diff --git a/beinc_weechat.py b/beinc_weechat.py index 132a22a..c1a1e1e 100644 --- a/beinc_weechat.py +++ b/beinc_weechat.py | |||
| @@ -1,7 +1,7 @@ | |||
| 1 | # -*- coding: utf-8 -*- | 1 | # -*- coding: utf-8 -*- |
| 2 | 2 | ||
| 3 | # Blackmore's Enhanced IRC-Notification Collection (BEINC) v3.0 | 3 | # Blackmore's Enhanced IRC-Notification Collection (BEINC) v4.0 |
| 4 | # Copyright (C) 2013-2019 Simeon Simeonov | 4 | # Copyright (C) 2013-2020 Simeon Simeonov |
| 5 | 5 | ||
| 6 | # This program is free software: you can redistribute it and/or modify | 6 | # This program is free software: you can redistribute it and/or modify |
| 7 | # it under the terms of the GNU General Public License as published by | 7 | # it under the terms of the GNU General Public License as published by |
| @@ -15,35 +15,25 @@ | |||
| 15 | 15 | ||
| 16 | # You should have received a copy of the GNU General Public License | 16 | # You should have received a copy of the GNU General Public License |
| 17 | # along with this program. If not, see <http://www.gnu.org/licenses/>. | 17 | # along with this program. If not, see <http://www.gnu.org/licenses/>. |
| 18 | 18 | """BEINC client for Weechat""" | |
| 19 | |||
| 20 | import datetime | 19 | import datetime |
| 21 | import json | 20 | import json |
| 22 | import os | 21 | import os |
| 23 | import socket | 22 | import socket |
| 24 | import ssl | 23 | import ssl |
| 25 | import sys | 24 | import urllib.parse |
| 25 | import urllib.request | ||
| 26 | 26 | ||
| 27 | import weechat | 27 | import weechat |
| 28 | 28 | ||
| 29 | PY2 = sys.version_info[0] == 2 | ||
| 30 | PY3 = sys.version_info[0] == 3 | ||
| 31 | |||
| 32 | if PY3: | ||
| 33 | from urllib.parse import urlencode | ||
| 34 | from urllib.request import urlopen | ||
| 35 | else: | ||
| 36 | from urllib import urlencode | ||
| 37 | from urllib2 import urlopen | ||
| 38 | |||
| 39 | 29 | ||
| 40 | __author__ = 'Simeon Simeonov' | 30 | __author__ = 'Simeon Simeonov' |
| 41 | __version__ = '3.0' | 31 | __version__ = '4.0' |
| 42 | __license__ = 'GPL3' | 32 | __license__ = 'GPL3' |
| 43 | 33 | ||
| 44 | 34 | ||
| 45 | enabled = True | 35 | enabled = True |
| 46 | global_values = dict() | 36 | global_values = {} |
| 47 | 37 | ||
| 48 | # few constants # | 38 | # few constants # |
| 49 | BEINC_POLICY_NONE = 0 | 39 | BEINC_POLICY_NONE = 0 |
| @@ -52,322 +42,317 @@ BEINC_POLICY_LIST_ONLY = 2 | |||
| 52 | BEINC_CURRENT_CONFIG_VERSION = 2 | 42 | BEINC_CURRENT_CONFIG_VERSION = 2 |
| 53 | 43 | ||
| 54 | 44 | ||
| 55 | class WeechatTarget(object): | 45 | class WeechatTarget: |
| 56 | """ | 46 | """ |
| 57 | The target (destination) class | 47 | The target (destination) class |
| 48 | |||
| 58 | Each remote destination is represented as a WeechatTarget object | 49 | Each remote destination is represented as a WeechatTarget object |
| 59 | """ | 50 | """ |
| 60 | 51 | ||
| 61 | def __init__(self, target_dict): | 52 | def __init__(self, target_dict): |
| 62 | """ | 53 | """ |
| 63 | target_dict: the config-dictionary node that represents this instance | 54 | :param target_dict: The config-dict node that represents this instance |
| 55 | :type target_dict: dict | ||
| 64 | """ | 56 | """ |
| 65 | self.__name = target_dict.get('name', '') | 57 | self._name = target_dict.get('name', '') |
| 66 | if self.__name == '': | 58 | if self._name == '': |
| 67 | raise Exception('"name" not defined for target') | 59 | raise Exception('"name" not defined for target') |
| 68 | self.__url = target_dict.get('target_url', '') | 60 | self._url = target_dict.get('target_url', '') |
| 69 | if self.__url == '': | 61 | if self._url == '': |
| 70 | raise Exception('"target_url" not defined for target') | 62 | raise Exception('"target_url" not defined for target') |
| 71 | self.__password = target_dict.get('target_password', '') | 63 | self._password = target_dict.get('target_password', '') |
| 72 | self.__pm_title_template = target_dict.get('pm_title_template', | 64 | self._pm_title_template = target_dict.get('pm_title_template', |
| 73 | '%s @ %S') | 65 | '%s @ %S') |
| 74 | self.__pm_message_template = target_dict.get('pm_message_template', | 66 | self._pm_message_template = target_dict.get('pm_message_template', |
| 75 | '%m') | 67 | '%m') |
| 76 | self.__cm_title_template = target_dict.get('cm_title_template', | 68 | self._cm_title_template = target_dict.get('cm_title_template', |
| 77 | '%c @ %S') | 69 | '%c @ %S') |
| 78 | self.__cm_message_template = target_dict.get('cm_message_template', | 70 | self._cm_message_template = target_dict.get('cm_message_template', |
| 79 | '%s -> %m') | 71 | '%s -> %m') |
| 80 | self.__nm_title_template = target_dict.get('nm_title_template', | 72 | self._nm_title_template = target_dict.get('nm_title_template', |
| 81 | '%c @ %S') | 73 | '%c @ %S') |
| 82 | self.__nm_message_template = target_dict.get('nm_message_template', | 74 | self._nm_message_template = target_dict.get('nm_message_template', |
| 83 | '%s -> %m') | 75 | '%s -> %m') |
| 84 | self.__chans = set(target_dict.get('channel_list', list())) | 76 | self._chans = set(target_dict.get('channel_list', [])) |
| 85 | self.__nicks = set(target_dict.get('nick_list', list())) | 77 | self._nicks = set(target_dict.get('nick_list', [])) |
| 86 | self.__chan_messages_policy = int(target_dict.get( | 78 | self._chan_messages_policy = int(target_dict.get( |
| 87 | 'channel_messages_policy', | 79 | 'channel_messages_policy', |
| 88 | BEINC_POLICY_LIST_ONLY)) | 80 | BEINC_POLICY_LIST_ONLY)) |
| 89 | self.__priv_messages_policy = int(target_dict.get( | 81 | self._priv_messages_policy = int(target_dict.get( |
| 90 | 'private_messages_policy', | 82 | 'private_messages_policy', |
| 91 | BEINC_POLICY_ALL)) | 83 | BEINC_POLICY_ALL)) |
| 92 | self.__notifications_policy = int(target_dict.get( | 84 | self._notifications_policy = int(target_dict.get( |
| 93 | 'notifications_policy', | 85 | 'notifications_policy', |
| 94 | BEINC_POLICY_ALL)) | 86 | BEINC_POLICY_ALL)) |
| 95 | self.__cert_file = target_dict.get('target_cert_file') | 87 | self._cert_file = target_dict.get('target_cert_file') |
| 96 | self.__timestamp_format = target_dict.get('target_timestamp_format', | 88 | self._timestamp_format = target_dict.get('target_timestamp_format', |
| 97 | '%H:%M:%S') | 89 | '%H:%M:%S') |
| 98 | self.__debug = bool(target_dict.get('debug', False)) | 90 | self._debug = bool(target_dict.get('debug', False)) |
| 99 | self.__enabled = bool(target_dict.get('enabled', True)) | 91 | self._enabled = bool(target_dict.get('enabled', True)) |
| 100 | self.__socket_timeout = int(target_dict.get('socket_timeout', 3)) | 92 | self._socket_timeout = int(target_dict.get('socket_timeout', 3)) |
| 101 | self.__ssl_ciphers = target_dict.get('ssl_ciphers', '') | 93 | self._ssl_ciphers = target_dict.get('ssl_ciphers', '') |
| 102 | self.__disable_hostname_check = bool( | 94 | self._disable_hostname_check = bool( |
| 103 | target_dict.get('disable-hostname-check', False)) | 95 | target_dict.get('disable-hostname-check', False)) |
| 104 | self.__ssl_version = target_dict.get('ssl_version', 'auto') | 96 | self._ssl_version = target_dict.get('ssl_version', 'auto') |
| 105 | self.__last_message = None # datetime.datetime instance | 97 | self._last_message = None # datetime.datetime instance |
| 106 | self.__context = None | 98 | self._context = None |
| 107 | self.__context_setup() | 99 | self._context_setup() |
| 108 | 100 | ||
| 109 | @property | 101 | @property |
| 110 | def name(self): | 102 | def name(self): |
| 111 | """ | 103 | """Target name (read-only property)""" |
| 112 | Target name (read-only property) | 104 | return self._name |
| 113 | """ | ||
| 114 | return self.__name | ||
| 115 | 105 | ||
| 116 | @property | 106 | @property |
| 117 | def chans(self): | 107 | def chans(self): |
| 118 | """ | 108 | """Target channel list (read-only property)""" |
| 119 | Target channel list (read-only property) | 109 | return self._chans |
| 120 | """ | ||
| 121 | return self.__chans | ||
| 122 | 110 | ||
| 123 | @property | 111 | @property |
| 124 | def nicks(self): | 112 | def nicks(self): |
| 125 | """ | 113 | """Target nick list (read-only property)""" |
| 126 | Target nick list (read-only property) | 114 | return self._nicks |
| 127 | """ | ||
| 128 | return self.__nicks | ||
| 129 | 115 | ||
| 130 | @property | 116 | @property |
| 131 | def channel_messages_policy(self): | 117 | def channel_messages_policy(self): |
| 132 | """ | 118 | """The target's channel messages policy (read-only property)""" |
| 133 | The target's channel messages policy (read-only property) | 119 | return self._chan_messages_policy |
| 134 | """ | ||
| 135 | return self.__chan_messages_policy | ||
| 136 | 120 | ||
| 137 | @property | 121 | @property |
| 138 | def private_messages_policy(self): | 122 | def private_messages_policy(self): |
| 139 | """ | 123 | """The target's private messages policy (read-only property)""" |
| 140 | The target's private messages policy (read-only property) | 124 | return self._priv_messages_policy |
| 141 | """ | ||
| 142 | return self.__priv_messages_policy | ||
| 143 | 125 | ||
| 144 | @property | 126 | @property |
| 145 | def notifications_policy(self): | 127 | def notifications_policy(self): |
| 146 | """ | 128 | """The target's notifications policy (read-only property)""" |
| 147 | The target's notifications policy (read-only property) | 129 | return self._notifications_policy |
| 148 | """ | ||
| 149 | return self.__notifications_policy | ||
| 150 | 130 | ||
| 151 | @property | 131 | @property |
| 152 | def enabled(self): | 132 | def enabled(self): |
| 153 | """ | 133 | """The target's enabled status (bool property)""" |
| 154 | The target's enabled status (bool property) | 134 | return self._enabled |
| 155 | """ | ||
| 156 | return self.__enabled | ||
| 157 | 135 | ||
| 158 | @enabled.setter | 136 | @enabled.setter |
| 159 | def enabled(self, value): | 137 | def enabled(self, value): |
| 160 | """ | 138 | """The target's enabled status (bool property)""" |
| 161 | The target's enabled status (bool property) | 139 | self._enabled = value |
| 162 | """ | ||
| 163 | self.__enabled = value | ||
| 164 | 140 | ||
| 165 | def __repr__(self): | 141 | def __repr__(self): |
| 166 | """ | 142 | """repr() implementation""" |
| 167 | """ | ||
| 168 | last_message = 'never' | 143 | last_message = 'never' |
| 169 | if self.__last_message is not None: | 144 | if self._last_message is not None: |
| 170 | last_message = self.__last_message.strftime('%Y-%m-%d %H:%M:%S') | 145 | last_message = self._last_message.strftime('%Y-%m-%d %H:%M:%S') |
| 171 | return ('name: {0}\nurl: {1}\nenabled: {2}\nchannel_list: {3}\n' | 146 | return ('name: {0}\nurl: {1}\nenabled: {2}\nchannel_list: {3}\n' |
| 172 | 'nick_list: {4}\nchannel_messages_policy: {5}\n' | 147 | 'nick_list: {4}\nchannel_messages_policy: {5}\n' |
| 173 | 'private_messages_policy: {6}\nnotifications_policy: {7}\n' | 148 | 'private_messages_policy: {6}\nnotifications_policy: {7}\n' |
| 174 | 'last message: {8}\nsocket timeout: {9}\nssl-version: {10}\n' | 149 | 'last message: {8}\nsocket timeout: {9}\nssl-version: {10}\n' |
| 175 | 'ciphers: {11}\ndisable hostname check: {12}\n' | 150 | 'ciphers: {11}\ndisable hostname check: {12}\n' |
| 176 | 'debug: {13}\n\n'.format( | 151 | 'debug: {13}\n\n'.format( |
| 177 | self.__name, | 152 | self._name, |
| 178 | self.__url, | 153 | self._url, |
| 179 | 'yes' if self.__enabled else 'no', | 154 | 'yes' if self._enabled else 'no', |
| 180 | ', '.join(self.__chans), | 155 | ', '.join(self._chans), |
| 181 | ', '.join(self.__nicks), | 156 | ', '.join(self._nicks), |
| 182 | self.__chan_messages_policy, | 157 | self._chan_messages_policy, |
| 183 | self.__priv_messages_policy, | 158 | self._priv_messages_policy, |
| 184 | self.__notifications_policy, | 159 | self._notifications_policy, |
| 185 | last_message, | 160 | last_message, |
| 186 | self.__socket_timeout, | 161 | self._socket_timeout, |
| 187 | self.__ssl_version, | 162 | self._ssl_version, |
| 188 | self.__ssl_ciphers or 'auto', | 163 | self._ssl_ciphers or 'auto', |
| 189 | 'yes' if self.__disable_hostname_check else 'no', | 164 | 'yes' if self._disable_hostname_check else 'no', |
| 190 | 'yes' if self.__debug else 'no')) | 165 | 'yes' if self._debug else 'no')) |
| 191 | 166 | ||
| 192 | def send_private_message_notification(self, values): | 167 | def send_private_message_notification(self, values): |
| 193 | """ | 168 | """ |
| 194 | sends a private message notification to the represented target | 169 | Sends a private message notification to the represented target |
| 195 | 170 | ||
| 196 | values: dict pupulated by the irc msg-handler | 171 | :param value: Dict pupulated by the irc msg-handler |
| 172 | :type value: dict | ||
| 197 | """ | 173 | """ |
| 198 | try: | 174 | try: |
| 199 | title = self.__fetch_formatted_str(self.__pm_title_template, | 175 | title = self._fetch_formatted_str(self._pm_title_template, |
| 200 | values) | 176 | values) |
| 201 | message = self.__fetch_formatted_str( | 177 | message = self._fetch_formatted_str( |
| 202 | self.__pm_message_template, | 178 | self._pm_message_template, |
| 203 | values) | 179 | values) |
| 204 | if not self.__send_beinc_message(title, message) and self.__debug: | 180 | if not self._send_beinc_message(title, message) and self._debug: |
| 205 | beinc_prnt( | 181 | beinc_prnt( |
| 206 | 'BEINC DEBUG: send_private_message_notification-ERROR ' | 182 | f'BEINC DEBUG: send_private_message_notification-ERROR ' |
| 207 | 'for "{0}": __send_beinc_message -> False'.format( | 183 | f'for "{self._name}": _send_beinc_message -> False') |
| 208 | self.__name)) | ||
| 209 | except Exception as e: | 184 | except Exception as e: |
| 210 | if self.__debug: | 185 | if self._debug: |
| 211 | beinc_prnt( | 186 | beinc_prnt( |
| 212 | 'BEINC DEBUG: send_private_message_notification-ERROR ' | 187 | f'BEINC DEBUG: send_private_message_notification-ERROR ' |
| 213 | 'for "{0}": {1}'.format(self.__name, e)) | 188 | f'for "{self._name}": {e}') |
| 214 | 189 | ||
| 215 | def send_channel_message_notification(self, values): | 190 | def send_channel_message_notification(self, values): |
| 216 | """ | 191 | """ |
| 217 | sends a channel message notification to the represented target | 192 | Sends a channel message notification to the represented target |
| 218 | 193 | ||
| 219 | values: dict pupulated by the irc msg-handler | 194 | :param value: Dict pupulated by the irc msg-handler |
| 195 | :type value: dict | ||
| 220 | """ | 196 | """ |
| 221 | try: | 197 | try: |
| 222 | title = self.__fetch_formatted_str(self.__cm_title_template, | 198 | title = self._fetch_formatted_str(self._cm_title_template, |
| 223 | values) | 199 | values) |
| 224 | message = self.__fetch_formatted_str(self.__cm_message_template, | 200 | message = self._fetch_formatted_str(self._cm_message_template, |
| 225 | values) | 201 | values) |
| 226 | if not self.__send_beinc_message(title, message) and self.__debug: | 202 | if not self._send_beinc_message(title, message) and self._debug: |
| 227 | beinc_prnt( | 203 | beinc_prnt( |
| 228 | 'BEINC DEBUG: send_channel_message_notification-ERROR ' | 204 | f'BEINC DEBUG: send_channel_message_notification-ERROR ' |
| 229 | 'for "{0}": __send_beinc_message -> False'.format( | 205 | f'for "{self._name}": _send_beinc_message -> False') |
| 230 | self.__name)) | ||
| 231 | except Exception as e: | 206 | except Exception as e: |
| 232 | if self.__debug: | 207 | if self._debug: |
| 233 | beinc_prnt( | 208 | beinc_prnt( |
| 234 | 'BEINC DEBUG: send_channel_message_notification-ERROR ' | 209 | f'BEINC DEBUG: send_channel_message_notification-ERROR ' |
| 235 | 'for "{0}": {1}'.format(self.__name, e)) | 210 | f'for "{self._name}": {e}') |
| 236 | 211 | ||
| 237 | def send_notify_message_notification(self, values): | 212 | def send_notify_message_notification(self, values): |
| 238 | """ | 213 | """ |
| 239 | sends a notify message notification to the represented target | 214 | Sends a notify message notification to the represented target |
| 240 | 215 | ||
| 241 | values: dict pupulated by the irc msg-handler | 216 | :param value: Dict pupulated by the irc msg-handler |
| 217 | :type value: dict | ||
| 242 | """ | 218 | """ |
| 243 | try: | 219 | try: |
| 244 | title = self.__fetch_formatted_str(self.__nm_title_template, | 220 | title = self._fetch_formatted_str(self._nm_title_template, |
| 245 | values) | 221 | values) |
| 246 | message = self.__fetch_formatted_str(self.__nm_message_template, | 222 | message = self._fetch_formatted_str(self._nm_message_template, |
| 247 | values) | 223 | values) |
| 248 | if not self.__send_beinc_message(title, message) and self.__debug: | 224 | if not self._send_beinc_message(title, message) and self._debug: |
| 249 | beinc_prnt( | 225 | beinc_prnt( |
| 250 | 'BEINC DEBUG: send_notify_message_notification-ERROR ' | 226 | f'BEINC DEBUG: send_notify_message_notification-ERROR ' |
| 251 | 'for "{0}": __send_beinc_message -> False'.format( | 227 | f'for "{self._name}": _send_beinc_message -> False') |
| 252 | self.__name)) | ||
| 253 | except Exception as e: | 228 | except Exception as e: |
| 254 | if self.__debug: | 229 | if self._debug: |
| 255 | beinc_prnt( | 230 | beinc_prnt( |
| 256 | 'BEINC DEBUG: send_notify_message_notification-ERROR ' | 231 | f'BEINC DEBUG: send_notify_message_notification-ERROR ' |
| 257 | 'for "{0}": {1}'.format(self.__name, e)) | 232 | f'for "{self._name}": {e}') |
| 258 | 233 | ||
| 259 | def send_broadcast_notification(self, message): | 234 | def send_broadcast_notification(self, message): |
| 260 | """ | 235 | """ |
| 261 | sends a 'pure' broadcast / test message notification | 236 | Sends a 'pure' broadcast / test message notification |
| 262 | to the represented target | 237 | to the represented target |
| 263 | 238 | ||
| 264 | message: a single message string | 239 | :param message: A single message string |
| 240 | :type message: str | ||
| 265 | """ | 241 | """ |
| 266 | try: | 242 | try: |
| 267 | title = 'BEINC broadcast' | 243 | title = 'BEINC broadcast' |
| 268 | if not self.__send_beinc_message(title, message) and self.__debug: | 244 | if not self._send_beinc_message(title, message) and self._debug: |
| 269 | beinc_prnt( | 245 | beinc_prnt( |
| 270 | 'BEINC DEBUG: send_broadcast_notification-ERROR ' | 246 | f'BEINC DEBUG: send_broadcast_notification-ERROR ' |
| 271 | 'for "{0}": __send_beinc_message -> False'.format( | 247 | f'for "{self._name}": _send_beinc_message -> False') |
| 272 | self.__name)) | ||
| 273 | except Exception as e: | 248 | except Exception as e: |
| 274 | if self.__debug: | 249 | if self._debug: |
| 275 | beinc_prnt( | 250 | beinc_prnt( |
| 276 | 'BEINC DEBUG: send_broadcast_notification-ERROR ' | 251 | f'BEINC DEBUG: send_broadcast_notification-ERROR ' |
| 277 | 'for "{0}": {1}'.format(self.__name, e)) | 252 | f'for "{self._name}": {e}') |
| 278 | 253 | ||
| 279 | def __context_setup(self): | 254 | def _context_setup(self): |
| 280 | """ | 255 | """Sets up the SSL context""" |
| 281 | """ | 256 | if self._context is not None: |
| 282 | if self.__context is not None: | ||
| 283 | return True | 257 | return True |
| 284 | try: | 258 | try: |
| 285 | context = ssl.SSLContext(ssl.PROTOCOL_TLSv1_2) | 259 | context = ssl.SSLContext(ssl.PROTOCOL_TLSv1_2) |
| 286 | context.verify_mode = ssl.CERT_NONE | 260 | context.verify_mode = ssl.CERT_NONE |
| 287 | if self.__cert_file: | 261 | if self._cert_file: |
| 288 | context.verify_mode = ssl.CERT_REQUIRED | 262 | context.verify_mode = ssl.CERT_REQUIRED |
| 289 | context.load_verify_locations(cafile=os.path.expanduser( | 263 | context.load_verify_locations(cafile=os.path.expanduser( |
| 290 | self.__cert_file)) | 264 | self._cert_file)) |
| 291 | context.check_hostname = bool( | 265 | context.check_hostname = bool( |
| 292 | not self.__disable_hostname_check) | 266 | not self._disable_hostname_check) |
| 293 | if self.__ssl_ciphers and self.__ssl_ciphers != 'auto': | 267 | if self._ssl_ciphers and self._ssl_ciphers != 'auto': |
| 294 | context.set_ciphers(self.__ssl_ciphers) | 268 | context.set_ciphers(self._ssl_ciphers) |
| 295 | self.__context = context | 269 | self._context = context |
| 296 | return True | 270 | return True |
| 297 | except ssl.SSLError as e: | 271 | except ssl.SSLError as e: |
| 298 | if self.__debug: | 272 | if self._debug: |
| 299 | beinc_prnt('BEINC DEBUG: SSL/TLS error: {0}\n'.format(e)) | 273 | beinc_prnt(f'BEINC DEBUG: SSL/TLS error: {e}\n') |
| 300 | except Exception as e: | 274 | except Exception as e: |
| 301 | if self.__debug: | 275 | if self._debug: |
| 302 | beinc_prnt('BEINC DEBUG: Generic context error: {0}\n'.format( | 276 | beinc_prnt(f'BEINC DEBUG: Generic context error: {e}\n') |
| 303 | e)) | 277 | self._context = None |
| 304 | self.__context = None | ||
| 305 | return False | 278 | return False |
| 306 | 279 | ||
| 307 | def __fetch_formatted_str(self, template, values): | 280 | def _fetch_formatted_str(self, template, values): |
| 308 | """ | 281 | """ |
| 309 | returns a formatted string by replacing the defined | 282 | Returns a formatted string by replacing the defined |
| 310 | macros in 'template' the the corresponding values from 'values' | 283 | macros in 'template' the the corresponding values from 'values' |
| 311 | 284 | ||
| 312 | values: dict | 285 | :param template: The template to use |
| 313 | template: str | 286 | :type template: str |
| 287 | |||
| 288 | :param values: The values dict | ||
| 289 | :type values: dict | ||
| 290 | |||
| 291 | :return: The formatted string | ||
| 292 | :rtype: str | ||
| 314 | """ | 293 | """ |
| 315 | timestamp = datetime.datetime.now().strftime(self.__timestamp_format) | 294 | timestamp = datetime.datetime.now().strftime(self._timestamp_format) |
| 316 | replacements = {'%S': values['server'], | 295 | replacements = {'%S': values['server'], |
| 317 | '%s': values['source_nick'], | 296 | '%s': values['source_nick'], |
| 318 | '%c': values['channel'], | 297 | '%c': values['channel'], |
| 319 | '%m': values['message'], | 298 | '%m': values['message'], |
| 320 | '%t': timestamp, | 299 | '%t': timestamp, |
| 321 | '%p': u'BEINC', | 300 | '%p': 'BEINC', |
| 322 | '%n': values['own_nick']} | 301 | '%n': values['own_nick']} |
| 323 | for key, value in replacements.items(): | 302 | for key, value in replacements.items(): |
| 324 | template = template.replace(key, value) | 303 | template = template.replace(key, value) |
| 325 | return template.encode('utf-8') | 304 | return template |
| 326 | 305 | ||
| 327 | def __send_beinc_message(self, title, message): | 306 | def _send_beinc_message(self, title, message): |
| 328 | """ | 307 | """ |
| 329 | the function implements the BEINC "protocol" by generating a simple | 308 | The method implements the BEINC "protocol" by generating a simple |
| 330 | POST request | 309 | POST request |
| 310 | |||
| 311 | :param title: The title | ||
| 312 | :type title: str | ||
| 313 | |||
| 314 | :param message: The message | ||
| 315 | :type message: str | ||
| 316 | |||
| 317 | :return: The status | ||
| 318 | :rtype: bool | ||
| 331 | """ | 319 | """ |
| 332 | try: | 320 | try: |
| 333 | if self.__context is None and not self.__context_setup(): | 321 | if self._context is None and not self._context_setup(): |
| 334 | return False | 322 | return False |
| 335 | response = urlopen( | 323 | response = urllib.request.urlopen( |
| 336 | self.__url, | 324 | self._url, |
| 337 | data=urlencode( | 325 | data=urllib.parse.urlencode( |
| 338 | ( | 326 | ( |
| 339 | ('resource_name', self.__name), | 327 | ('resource_name', self._name), |
| 340 | ('password', self.__password), | 328 | ('password', self._password), |
| 341 | ('title', title), | 329 | ('title', title), |
| 342 | ('message', message) | 330 | ('message', message) |
| 343 | )).encode('utf-8'), | 331 | )).encode('utf-8'), |
| 344 | timeout=self.__socket_timeout, | 332 | timeout=self._socket_timeout, |
| 345 | context=self.__context) | 333 | context=self._context) |
| 346 | response_dict = json.loads(response.read().decode('utf-8')) | 334 | response_dict = json.loads(response.read().decode('utf-8')) |
| 347 | if response.code != 200: | 335 | if response.code != 200: |
| 348 | raise socket.error(response_dict.get('message', '')) | 336 | raise socket.error(response_dict.get('message', '')) |
| 349 | if self.__debug: | 337 | if self._debug: |
| 350 | beinc_prnt('BEINC DEBUG: Server responded: {0}'.format( | 338 | beinc_prnt('BEINC DEBUG: Server responded: {0}'.format( |
| 351 | response_dict.get('message'))) | 339 | response_dict.get('message'))) |
| 352 | self.__last_message = datetime.datetime.now() | 340 | self._last_message = datetime.datetime.now() |
| 353 | return True | 341 | return True |
| 354 | except ssl.SSLError as e: | 342 | except ssl.SSLError as e: |
| 355 | if self.__debug: | 343 | if self._debug: |
| 356 | beinc_prnt('BEINC DEBUG: SSL/TLS error: {0}\n'.format(e)) | 344 | beinc_prnt(f'BEINC DEBUG: SSL/TLS error: {e}\n') |
| 357 | except socket.error as e: | 345 | except socket.error as e: |
| 358 | if self.__debug: | 346 | if self._debug: |
| 359 | beinc_prnt('BEINC DEBUG: Connection error: {0}\n'.format(e)) | 347 | beinc_prnt(f'BEINC DEBUG: Connection error: {e}\n') |
| 360 | except Exception as e: | 348 | except Exception as e: |
| 361 | if self.__debug: | 349 | if self._debug: |
| 362 | beinc_prnt('BEINC DEBUG: Unable to send message: {0}\n'.format( | 350 | beinc_prnt(f'BEINC DEBUG: Unable to send message: {e}\n') |
| 363 | e)) | ||
| 364 | return False | 351 | return False |
| 365 | 352 | ||
| 366 | 353 | ||
| 367 | def beinc_prnt(message_str): | 354 | def beinc_prnt(message_str): |
| 368 | """ | 355 | """wrapper around weechat.prnt""" |
| 369 | wrapper around weechat.prnt | ||
| 370 | """ | ||
| 371 | if global_values['use_current_buffer']: | 356 | if global_values['use_current_buffer']: |
| 372 | weechat.prnt(weechat.current_buffer(), message_str) | 357 | weechat.prnt(weechat.current_buffer(), message_str) |
| 373 | else: | 358 | else: |
| @@ -375,9 +360,7 @@ def beinc_prnt(message_str): | |||
| 375 | 360 | ||
| 376 | 361 | ||
| 377 | def beinc_cmd_broadcast_handler(cmd_tokens): | 362 | def beinc_cmd_broadcast_handler(cmd_tokens): |
| 378 | """ | 363 | """handles: '/beinc broadcast' command actions""" |
| 379 | handles: '/beinc broadcast' command actions | ||
| 380 | """ | ||
| 381 | if not cmd_tokens: | 364 | if not cmd_tokens: |
| 382 | beinc_prnt('beinc broadcast <message>') | 365 | beinc_prnt('beinc broadcast <message>') |
| 383 | return weechat.WEECHAT_RC_OK | 366 | return weechat.WEECHAT_RC_OK |
| @@ -388,9 +371,7 @@ def beinc_cmd_broadcast_handler(cmd_tokens): | |||
| 388 | 371 | ||
| 389 | 372 | ||
| 390 | def beinc_cmd_target_handler(cmd_tokens): | 373 | def beinc_cmd_target_handler(cmd_tokens): |
| 391 | """ | 374 | """handles: '/beinc target' command actions""" |
| 392 | handles: '/beinc target' command actions | ||
| 393 | """ | ||
| 394 | if not cmd_tokens or cmd_tokens[0] not in ['list', 'enable', 'disable']: | 375 | if not cmd_tokens or cmd_tokens[0] not in ['list', 'enable', 'disable']: |
| 395 | beinc_prnt('beinc target [ list | enable <name> | disable <name> ]') | 376 | beinc_prnt('beinc target [ list | enable <name> | disable <name> ]') |
| 396 | return weechat.WEECHAT_RC_OK | 377 | return weechat.WEECHAT_RC_OK |
| @@ -410,10 +391,10 @@ def beinc_cmd_target_handler(cmd_tokens): | |||
| 410 | for target in target_list: | 391 | for target in target_list: |
| 411 | if target.name == name: | 392 | if target.name == name: |
| 412 | target.enabled = True | 393 | target.enabled = True |
| 413 | beinc_prnt('target "{0}" enabled'.format(name)) | 394 | beinc_prnt(f'target "{name}" enabled') |
| 414 | break | 395 | break |
| 415 | else: | 396 | else: |
| 416 | beinc_prnt('no matching target for "{0}"'.format(name)) | 397 | beinc_prnt(f'no matching target for "{name}"') |
| 417 | elif cmd_tokens[0] == 'disable': | 398 | elif cmd_tokens[0] == 'disable': |
| 418 | if not cmd_tokens[1:]: | 399 | if not cmd_tokens[1:]: |
| 419 | beinc_prnt('missing a name-argument') | 400 | beinc_prnt('missing a name-argument') |
| @@ -422,17 +403,15 @@ def beinc_cmd_target_handler(cmd_tokens): | |||
| 422 | for target in target_list: | 403 | for target in target_list: |
| 423 | if target.name == name: | 404 | if target.name == name: |
| 424 | target.enabled = False | 405 | target.enabled = False |
| 425 | beinc_prnt('target "{0}" disabled'.format(name)) | 406 | beinc_prnt(f'target "{name}" disabled') |
| 426 | break | 407 | break |
| 427 | else: | 408 | else: |
| 428 | beinc_prnt('no matching target for "{0}"'.format(name)) | 409 | beinc_prnt(f'no matching target for "{name}"') |
| 429 | return weechat.WEECHAT_RC_OK | 410 | return weechat.WEECHAT_RC_OK |
| 430 | 411 | ||
| 431 | 412 | ||
| 432 | def beinc_command(data, buffer_obj, args): | 413 | def beinc_command(data, buffer_obj, args): |
| 433 | """ | 414 | """Callback function handling the Weechat's /beinc command""" |
| 434 | Callback function handling the Weechat's /beinc command | ||
| 435 | """ | ||
| 436 | global enabled | 415 | global enabled |
| 437 | cmd_tokens = args.split() | 416 | cmd_tokens = args.split() |
| 438 | if not cmd_tokens: | 417 | if not cmd_tokens: |
| @@ -457,15 +436,13 @@ def beinc_command(data, buffer_obj, args): | |||
| 457 | 436 | ||
| 458 | 437 | ||
| 459 | def beinc_privmsg_handler(data, signal, signal_data): | 438 | def beinc_privmsg_handler(data, signal, signal_data): |
| 460 | """ | 439 | """Callback function the *PRIVMSG* IRC messages hooked by Weechat""" |
| 461 | Callback function the *PRIVMSG* IRC messages hooked by Weechat | ||
| 462 | """ | ||
| 463 | if not enabled: | 440 | if not enabled: |
| 464 | return weechat.WEECHAT_RC_OK | 441 | return weechat.WEECHAT_RC_OK |
| 465 | prvmsg_dict = weechat.info_get_hashtable('irc_message_parse', | 442 | prvmsg_dict = weechat.info_get_hashtable('irc_message_parse', |
| 466 | {'message': signal_data}) | 443 | {'message': signal_data}) |
| 467 | # packing the privmsg handler values | 444 | # packing the privmsg handler values |
| 468 | ph_values = dict() | 445 | ph_values = {} |
| 469 | ph_values['server'] = signal.split(',')[0] | 446 | ph_values['server'] = signal.split(',')[0] |
| 470 | ph_values['own_nick'] = weechat.info_get('irc_nick', ph_values['server']) | 447 | ph_values['own_nick'] = weechat.info_get('irc_nick', ph_values['server']) |
| 471 | ph_values['channel'] = prvmsg_dict['arguments'].split(':')[0].strip() | 448 | ph_values['channel'] = prvmsg_dict['arguments'].split(':')[0].strip() |
| @@ -529,8 +506,8 @@ def beinc_init(): | |||
| 529 | global global_values | 506 | global global_values |
| 530 | 507 | ||
| 531 | # global chans/nicks sets are used to speed up the filtering | 508 | # global chans/nicks sets are used to speed up the filtering |
| 532 | global_values = dict() | 509 | global_values = {} |
| 533 | target_list = list() | 510 | target_list = [] |
| 534 | custom_error = '' | 511 | custom_error = '' |
| 535 | global_values['global_channel_messages_policy'] = False | 512 | global_values['global_channel_messages_policy'] = False |
| 536 | global_values['global_private_messages_policy'] = False | 513 | global_values['global_private_messages_policy'] = False |
| @@ -541,7 +518,7 @@ def beinc_init(): | |||
| 541 | beinc_config_file_str = os.path.join( | 518 | beinc_config_file_str = os.path.join( |
| 542 | weechat.info_get('weechat_dir', ''), | 519 | weechat.info_get('weechat_dir', ''), |
| 543 | 'beinc_weechat.json') | 520 | 'beinc_weechat.json') |
| 544 | beinc_prnt('Parsing {0}...'.format(beinc_config_file_str)) | 521 | beinc_prnt(f'Parsing {beinc_config_file_str}...') |
| 545 | custom_error = 'load error' | 522 | custom_error = 'load error' |
| 546 | with open(beinc_config_file_str, 'r') as fp: | 523 | with open(beinc_config_file_str, 'r') as fp: |
| 547 | config_dict = json.load(fp, encoding='utf-8') | 524 | config_dict = json.load(fp, encoding='utf-8') |
| @@ -562,7 +539,7 @@ def beinc_init(): | |||
| 562 | try: | 539 | try: |
| 563 | new_target = WeechatTarget(target) | 540 | new_target = WeechatTarget(target) |
| 564 | except Exception as e: | 541 | except Exception as e: |
| 565 | beinc_prnt('Unable to add target: {0}'.format(e)) | 542 | beinc_prnt(f'Unable to add target: {e}') |
| 566 | continue | 543 | continue |
| 567 | if new_target.channel_messages_policy: | 544 | if new_target.channel_messages_policy: |
| 568 | global_values['global_channel_messages_policy'] = True | 545 | global_values['global_channel_messages_policy'] = True |
| @@ -571,12 +548,11 @@ def beinc_init(): | |||
| 571 | if new_target.notifications_policy: | 548 | if new_target.notifications_policy: |
| 572 | global_values['global_notifications_policy'] = True | 549 | global_values['global_notifications_policy'] = True |
| 573 | target_list.append(new_target) | 550 | target_list.append(new_target) |
| 574 | beinc_prnt('BEINC target "{0}" added'.format(new_target.name)) | 551 | beinc_prnt(f'BEINC target "{new_target.name}" added') |
| 575 | beinc_prnt('Done!') | 552 | beinc_prnt('Done!') |
| 576 | except Exception as e: | 553 | except Exception as e: |
| 577 | beinc_prnt('ERROR: unable to parse {0}: {1} - {2}\n' | 554 | beinc_prnt(f'ERROR: unable to parse {beinc_config_file_str}: ' |
| 578 | 'BEINC is now disabled'.format( | 555 | f'{custom_error} - {e}\nBEINC is now disabled') |
| 579 | beinc_config_file_str, custom_error, e)) | ||
| 580 | enabled = False | 556 | enabled = False |
| 581 | # do not return error / exit the script | 557 | # do not return error / exit the script |
| 582 | # in order to give a smoother opportunity to fix a 'broken' config | 558 | # in order to give a smoother opportunity to fix a 'broken' config |
