summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xbeinc_poller.py182
-rw-r--r--beinc_server.json17
-rwxr-xr-xbeinc_server.py63
3 files changed, 226 insertions, 36 deletions
diff --git a/beinc_poller.py b/beinc_poller.py
new file mode 100755
index 0000000..aba6353
--- /dev/null
+++ b/beinc_poller.py
@@ -0,0 +1,182 @@
1#!/usr/bin/env python
2# -*- coding: utf-8 -*-
3
4# Blackmore's Enhanced IRC-Notification Collection (BEINC) v1.0
5# Copyright (C) 2013-2014 Simeon Simeonov
6
7# This program is free software: you can redistribute it and/or modify
8# it under the terms of the GNU General Public License as published by
9# the Free Software Foundation, either version 3 of the License, or
10# (at your option) any later version.
11
12# This program is distributed in the hope that it will be useful,
13# but WITHOUT ANY WARRANTY; without even the implied warranty of
14# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15# GNU General Public License for more details.
16
17# You should have received a copy of the GNU General Public License
18# along with this program. If not, see <http://www.gnu.org/licenses/>.
19
20
21import argparse
22import errno
23import getpass
24import httplib
25import json
26import os
27import sched
28import socket
29import ssl
30import sys
31import time
32import urllib
33import urllib2
34
35try:
36 import pynotify
37except ImportError as e:
38 sys.stderr.write('A working pynotify library is required by BEINC-poller\n')
39 sys.exit(1)
40
41
42__author__ = 'Simeon Simeonov'
43__version__ = '1.0'
44__license__ = 'GPL3'
45
46
47class ValidHTTPSConnection(httplib.HTTPConnection):
48 """
49 Implements a simple CERT verification functionality
50 """
51
52 default_port = httplib.HTTPS_PORT
53
54 def __init__(self, *args, **kwargs):
55 httplib.HTTPConnection.__init__(self, *args, **kwargs)
56
57 def connect(self):
58 sock = socket.create_connection((self.host, self.port),
59 self.timeout, self.source_address)
60 if self._tunnel_host:
61 self.sock = sock
62 self._tunnel()
63 self.sock = ssl.wrap_socket(sock,
64 ca_certs=global_beinc_cert_file,
65 cert_reqs=ssl.CERT_REQUIRED)
66
67
68class ValidHTTPSHandler(urllib2.HTTPSHandler):
69 """
70 Implements a simple CERT verification functionality
71 """
72
73 def https_open(self, req):
74 return self.do_open(ValidHTTPSConnection, req)
75
76
77def poll_notifications(scheduler, args):
78 """
79 """
80 try:
81 post_values = {'password': args.password}
82 data = urllib.urlencode(post_values)
83 req = urllib2.Request(args.url, data)
84 if args.cert: # check for cert validity
85 global global_beinc_cert_file # ugly hack
86 global_beinc_cert_file = args.cert
87 opener = urllib2.build_opener(ValidHTTPSHandler)
88 response = opener.open(req)
89 else: # ... or don't
90 response = urllib2.urlopen(req)
91 res_code = response.code
92 res_str = response.read()
93 if res_code == 200 and args.debug:
94 print('Server responded: OK')
95 print('Body:\n{0}'.format(res_str))
96 res_list = json.loads(res_str)
97 print(type(res_list))
98 response.close()
99 scheduler.enter(args.frequency,
100 1,
101 poll_notifications,
102 (scheduler, args))
103 except urllib2.HTTPError as e:
104 sys.stderr.write('BEINC-server error ({0} - {1})\n'.format(e.code,
105 e.reason))
106 except Exception as e:
107 sys.stderr.write('BEINC-poller error: {0}\n'.format(e))
108 sys.exit(errno.EPERM)
109
110
111def main():
112 parser = argparse.ArgumentParser(
113 description='The following options are available')
114 parser.add_argument(
115 'url',
116 metavar='URL',
117 type=str,
118 help='BEINC destination URL')
119 parser.add_argument(
120 '-c', '--cert-file',
121 metavar='FILE',
122 type=str,
123 dest='cert',
124 default='',
125 help='BEINC CA-cert to check the server-cert against (default: None)')
126 parser.add_argument(
127 '-d',
128 action='store_true',
129 dest='daemonize',
130 default=False,
131 help='Run the poller-process in the background')
132 parser.add_argument(
133 '-D', '--debug',
134 action='store_true',
135 dest='debug',
136 default=False,
137 help='Run the poller-process in debug-mode (disables daemonize)')
138 parser.add_argument(
139 '-f', '--frequency',
140 metavar='SECONDS',
141 type=int,
142 dest='frequency',
143 default=10,
144 help='Polling frequency in seconds (default: 10)')
145 parser.add_argument(
146 '-p', '--password',
147 metavar='PASSWORD',
148 type=str,
149 dest='password',
150 default='',
151 help='BEINC taget-password (default & recommended: prompt for passwd)')
152 parser.add_argument(
153 '-t', '--osd-timeout',
154 metavar='MILLISECONDS',
155 type=int,
156 dest='osd_timeout',
157 default=5000,
158 help='OSD timeout (default: 5000)')
159 parser.add_argument(
160 '-v', '--version',
161 action='version',
162 version='%(prog)s {0}'.format(__version__),
163 help='display program-version and exit')
164 args = parser.parse_args()
165 if not args.password:
166 try:
167 args.password = getpass.getpass()
168 except Exception as e:
169 sys.stderr.write('Prompt terminated\n')
170 sys.exit(errno.EACCES)
171
172 if not pynotify.init('BEINC Notify'):
173 sys.stderr.write('There was a problem with libnotify\n')
174 sys.exit(1)
175
176 sc = sched.scheduler(time.time, time.sleep)
177 sc.enter(args.frequency, 1, poll_notifications, (sc, args))
178 sc.run()
179
180
181if __name__ == '__main__':
182 main()
diff --git a/beinc_server.json b/beinc_server.json
index 46674ed..a6c5e0d 100644
--- a/beinc_server.json
+++ b/beinc_server.json
@@ -3,9 +3,9 @@
3 "general": { 3 "general": {
4 "ssl_module": "pyopenssl", 4 "ssl_module": "pyopenssl",
5 "ssl_private_key": "key.pem", 5 "ssl_private_key": "key.pem",
6 "ssl_certificate": "cert.crt" 6 "ssl_certificate": "cert.crt",
7 "daemonize": 1
7 }, 8 },
8
9 "instances": [ 9 "instances": [
10 { 10 {
11 "name": "test", 11 "name": "test",
@@ -16,7 +16,6 @@
16 } 16 }
17 ] 17 ]
18 }, 18 },
19
20 "irc_client": { 19 "irc_client": {
21 "use_current_buffer": 0, 20 "use_current_buffer": 0,
22 "targets": [ 21 "targets": [
@@ -45,7 +44,15 @@
45 } 44 }
46 ] 45 ]
47 }, 46 },
48 47 "poller": {
48 "target_url": "https://10.0.0.2:9898/pull/secondtest",
49 "target_password": "changeme",
50 "target_cert_file": "",
51 "polling_interval": 5,
52 "osd_system": "pynotify",
53 "osd_timeout": 5000,
54 "daemonize": 1,
55 "debug": 1,
56 },
49 "config_version": 1 57 "config_version": 1
50
51} 58}
diff --git a/beinc_server.py b/beinc_server.py
index 05568b6..1ed5563 100755
--- a/beinc_server.py
+++ b/beinc_server.py
@@ -235,35 +235,39 @@ def main():
235 235
236 parser = argparse.ArgumentParser( 236 parser = argparse.ArgumentParser(
237 description='The following options are available') 237 description='The following options are available')
238 parser.add_argument('-d', 238 parser.add_argument(
239 action='store_true', 239 '-d',
240 dest='daemonize', 240 action='store_true',
241 default=False, 241 dest='daemonize',
242 help='daemonize the server process') 242 default=False,
243 parser.add_argument('-H', '--hostname', 243 help='Run the BEINC-server in the background')
244 metavar='HOSTNAME', 244 parser.add_argument(
245 type=str, 245 '-H', '--hostname',
246 dest='hostname', 246 metavar='HOSTNAME',
247 default='127.0.0.1', 247 type=str,
248 help="Server IP / hostname") 248 dest='hostname',
249 parser.add_argument('-p', '--port', 249 default='127.0.0.1',
250 metavar='PORT', 250 help='BEINC server IP / hostname (default: 127.0.0.1)')
251 type=int, 251 parser.add_argument(
252 dest='port', 252 '-p', '--port',
253 default=9998, 253 metavar='PORT',
254 help="Server port") 254 type=int,
255 parser.add_argument('-c', '--config-file', 255 dest='port',
256 metavar='FILE', 256 default=9998,
257 type=str, 257 help='BEINC server port (default: 9998)')
258 default=os.path.expanduser('~/.beinc_server.json'), 258 parser.add_argument(
259 dest='config_file', 259 '-f', '--config-file',
260 help="config file") 260 metavar='FILE',
261 parser.add_argument('-v', '--version', 261 type=str,
262 action='version', 262 default=os.path.expanduser('~/.beinc_server.json'),
263 version='%(prog)s {0}'.format(__version__), 263 dest='config_file',
264 help='display program-version and exit') 264 help='BEINC config file (default: ~/.beinc_server.json)')
265 parser.add_argument(
266 '-v', '--version',
267 action='version',
268 version='%(prog)s {0}'.format(__version__),
269 help='Display program-version and exit')
265 args = parser.parse_args() 270 args = parser.parse_args()
266
267 try: 271 try:
268 with open(args.config_file, 'r') as fp: 272 with open(args.config_file, 'r') as fp:
269 config_dict = json.load(fp) 273 config_dict = json.load(fp)
@@ -271,7 +275,6 @@ def main():
271 sys.stderr.write('Unable to parse {0}: {1}'.format(args.config_file, 275 sys.stderr.write('Unable to parse {0}: {1}'.format(args.config_file,
272 e)) 276 e))
273 sys.exit(errno.EIO) 277 sys.exit(errno.EIO)
274
275 ssl_certificate = config_dict['server']['general']['ssl_certificate'] 278 ssl_certificate = config_dict['server']['general']['ssl_certificate']
276 ssl_private_key = config_dict['server']['general']['ssl_private_key'] 279 ssl_private_key = config_dict['server']['general']['ssl_private_key']
277 cherrypy.config.update({ 280 cherrypy.config.update({
@@ -285,13 +288,11 @@ def main():
285 'tools.log_tracebacks.on': False, 288 'tools.log_tracebacks.on': False,
286 'request.show_tracebacks': False 289 'request.show_tracebacks': False
287 }) 290 })
288
289 try: 291 try:
290 cherrypy.quickstart(WebNotifyServer(config_dict)) 292 cherrypy.quickstart(WebNotifyServer(config_dict))
291 except Exception as e: 293 except Exception as e:
292 sys.stderr.write("WebServer error: {0}".format(e)) 294 sys.stderr.write("WebServer error: {0}".format(e))
293 sys.exit(1) 295 sys.exit(1)
294
295 sys.exit(0) 296 sys.exit(0)
296 297
297 298