summaryrefslogtreecommitdiff
path: root/beinc_poller.py
diff options
context:
space:
mode:
authorSimeon Simeonov2017-05-12 13:25:43 +0200
committerSimeon Simeonov2017-05-12 13:25:43 +0200
commitdf917f55d6fbbe899942c5c4947444702b0b3fcd (patch)
tree670dac84d222ef0f263f8e2612fc536bc0eac5b3 /beinc_poller.py
parent1336daa7a6383bc4ed723c914fa5ee8b4e967b26 (diff)
Make beinc_weechat.py BEINC 3 compatible
Diffstat (limited to 'beinc_poller.py')
-rwxr-xr-xbeinc_poller.py132
1 files changed, 31 insertions, 101 deletions
diff --git a/beinc_poller.py b/beinc_poller.py
index aaf2d05..e84ad71 100755
--- a/beinc_poller.py
+++ b/beinc_poller.py
@@ -1,4 +1,4 @@
1#!/usr/bin/env python 1#!/usr/bin/env python3
2# -*- coding: utf-8 -*- 2# -*- coding: utf-8 -*-
3 3
4# Blackmore's Enhanced IRC-Notification Collection (BEINC) v3.0 4# Blackmore's Enhanced IRC-Notification Collection (BEINC) v3.0
@@ -21,7 +21,7 @@
21import argparse 21import argparse
22import errno 22import errno
23import getpass 23import getpass
24import httplib 24import json
25import os 25import os
26import sched 26import sched
27import socket 27import socket
@@ -29,6 +29,9 @@ import ssl
29import sys 29import sys
30import time 30import time
31 31
32from urllib.parse import urlencode
33from urllib.request import urlopen
34
32try: 35try:
33 import notify2 as pynotify 36 import notify2 as pynotify
34except ImportError as e: 37except ImportError as e:
@@ -40,66 +43,6 @@ __version__ = '3.0'
40__license__ = 'GPL3' 43__license__ = 'GPL3'
41 44
42 45
43class BEINCCustomHTTPSConnection(httplib.HTTPConnection):
44 """
45 This class allows communication via SSL.
46
47 It is a reimplementation of httplib.HTTPSConnection and
48 allows the server certificate to be validated against CA
49 This functionality lacks in Python < 2.7.9
50 """
51 default_port = httplib.HTTPS_PORT
52
53 def __init__(self, host, port=None, key_file=None, cert_file=None,
54 strict=None, timeout=socket._GLOBAL_DEFAULT_TIMEOUT,
55 source_address=None, custom_ssl_options={}):
56 httplib.HTTPConnection.__init__(self, host, port, strict, timeout,
57 source_address)
58 self.key_file = key_file
59 self.cert_file = cert_file
60 self.custom_ssl_options = custom_ssl_options
61
62 def connect(self):
63 "Connect to a host on a given (SSL) port."
64 sock = socket.create_connection((self.host, self.port),
65 self.timeout, self.source_address)
66 if self._tunnel_host:
67 self.sock = sock
68 self._tunnel()
69 self.sock = ssl.wrap_socket(sock,
70 self.key_file,
71 self.cert_file,
72 **self.custom_ssl_options)
73
74
75class BEINCCustomSafeTransport(xmlrpclib.Transport):
76 """
77 Provides an alternative HTTPS transport for clients running on Python<2.7.9
78 """
79
80 def __init__(self, use_datetime=0, custom_ssl_options={}):
81 xmlrpclib.Transport.__init__(self, use_datetime=use_datetime)
82 self.custom_ssl_options = custom_ssl_options
83
84 def make_connection(self, host):
85 if self._connection and host == self._connection[0]:
86 return self._connection[1]
87 try:
88 HTTPS = BEINCCustomHTTPSConnection
89 except AttributeError:
90 raise NotImplementedError(
91 "your version of httplib doesn't support HTTPS"
92 )
93 else:
94 chost, self._extra_headers, x509 = self.get_host_info(host)
95 self._connection = host, HTTPS(
96 chost,
97 None,
98 custom_ssl_options=self.custom_ssl_options,
99 **(x509 or {}))
100 return self._connection[1]
101
102
103def display_notification(args, title, message): 46def display_notification(args, title, message):
104 """ 47 """
105 A wrapper function for displaying a single notification 48 A wrapper function for displaying a single notification
@@ -116,7 +59,8 @@ def display_notification(args, title, message):
116 'Terminating...\n') 59 'Terminating...\n')
117 if not pynotify.init('BEINC Notify'): 60 if not pynotify.init('BEINC Notify'):
118 raise Exception('There was a problem with libnotify\n') 61 raise Exception('There was a problem with libnotify\n')
119 notification_obj = pynotify.Notification(' ') 62 notification_obj = pynotify.Notification(summary=title,
63 message=message)
120 notification_obj.timeout = 1000 * args.osd_timeout 64 notification_obj.timeout = 1000 * args.osd_timeout
121 notification_obj.set_category('im.received') 65 notification_obj.set_category('im.received')
122 notification_obj.show() 66 notification_obj.show()
@@ -133,46 +77,34 @@ def poll_notifications(scheduler, args):
133 args: the argparse processed command-line arguments 77 args: the argparse processed command-line arguments
134 """ 78 """
135 try: 79 try:
136 ssl_version = BEINC_SSL_METHODS.get(args.ssl_version, 80 context = ssl.SSLContext(ssl.PROTOCOL_TLSv1_2)
137 ssl.PROTOCOL_SSLv23) 81 context.verify_mode = ssl.CERT_NONE
138 if sys.hexversion >= 0x20709f0: 82 if args.cert:
139 # Python >= 2.7.9 83 context.verify_mode = ssl.CERT_REQUIRED
140 context = ssl.SSLContext(ssl_version) 84 context.load_verify_locations(cafile=os.path.expanduser(args.cert))
141 context.verify_mode = ssl.CERT_NONE 85 context.check_hostname = bool(not args.disable_hostname_check)
142 if args.cert: 86 if args.ciphers:
143 context.verify_mode = ssl.CERT_REQUIRED 87 context.set_ciphers(args.ciphers)
144 context.load_verify_locations(os.path.expanduser(args.cert)) 88 response = urlopen(
145 context.check_hostname = bool(not args.disable_hostname_check) 89 args.url,
146 if args.ciphers: 90 data=urlencode(
147 context.set_ciphers(args.ciphers) 91 (
148 transport = xmlrpclib.SafeTransport(context=context) 92 ('resource_name', args.rname),
149 else: 93 ('password', args.password)
150 # Python < 2.7.9 94 )).encode('utf-8'),
151 ssl_options = {} 95 timeout=args.socket_timeout,
152 ssl_options['ssl_version'] = ssl_version 96 context=context)
153 if args.cert: 97 response_dict = json.loads(response.read().decode('utf-8'))
154 ssl_options['ca_certs'] = os.path.expanduser(args.cert) 98 if response.code != 200:
155 ssl_options['cert_reqs'] = ssl.CERT_REQUIRED 99 raise socket.error(response_dict.get('message', ''))
156 if args.ciphers: 100 for entry in response_dict['data']['messages']:
157 ssl_options['ciphers'] = args.ciphers 101 display_notification(args,
158 transport = BEINCCustomSafeTransport( 102 entry.get('title', ''),
159 custom_ssl_options=ssl_options) 103 entry.get('message', ''))
160 server = xmlrpclib.ServerProxy(args.url,
161 transport=transport)
162 res_list = server.pull(args.rname, args.password)
163 for entry in res_list:
164 title = entry.get('title', '')
165 message = entry.get('message', '')
166 display_notification(args, title, message)
167 scheduler.enter(args.frequency, 104 scheduler.enter(args.frequency,
168 1, 105 1,
169 poll_notifications, 106 poll_notifications,
170 (scheduler, args)) 107 (scheduler, args))
171 except xmlrpclib.Fault as fault:
172 sys.stderr.write(
173 'BEINC server answered with errorCode={0}: {1}\n'.format(
174 fault.faultCode,
175 fault.faultString))
176 except ssl.SSLError as e: 108 except ssl.SSLError as e:
177 sys.stderr.write('BEINC SSL/TLS error: {0}\n'.format(e)) 109 sys.stderr.write('BEINC SSL/TLS error: {0}\n'.format(e))
178 sys.exit(errno.EPERM) 110 sys.exit(errno.EPERM)
@@ -277,8 +209,6 @@ def main():
277 except Exception as e: 209 except Exception as e:
278 sys.stderr.write('Unable to open password file: {0}'.format(e)) 210 sys.stderr.write('Unable to open password file: {0}'.format(e))
279 sys.exit(1) 211 sys.exit(1)
280 if args.socket_timeout:
281 socket.setdefaulttimeout(args.socket_timeout)
282 scheduler = sched.scheduler(time.time, time.sleep) 212 scheduler = sched.scheduler(time.time, time.sleep)
283 scheduler.enter(args.frequency, 213 scheduler.enter(args.frequency,
284 1, 214 1,