summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--beinc_server.json1
-rwxr-xr-xbeinc_server.py205
-rwxr-xr-xbins_server.py140
3 files changed, 168 insertions, 178 deletions
diff --git a/beinc_server.json b/beinc_server.json
index 0604d36..1743239 100644
--- a/beinc_server.json
+++ b/beinc_server.json
@@ -11,6 +11,7 @@
11 "name": "test", 11 "name": "test",
12 "password": "changeme", 12 "password": "changeme",
13 "osd_system": "none", 13 "osd_system": "none",
14 "osd_timeout": 5000,
14 "queue_size": 4 15 "queue_size": 4
15 } 16 }
16 ] 17 ]
diff --git a/beinc_server.py b/beinc_server.py
index a39dd05..cad8d61 100755
--- a/beinc_server.py
+++ b/beinc_server.py
@@ -15,6 +15,154 @@ __version__ = '1.0-beta'
15__license__ = "GPL3" 15__license__ = "GPL3"
16 16
17 17
18BEINC_OSD_TYPE_NONE = 0
19BEINC_OSD_TYPE_PYNOTIFY = 1
20
21
22
23class BEINCInstance(object):
24 """
25 """
26
27 def __init__(self, instance_dict):
28 """
29 """
30 self.__instance_dict = instance_dict
31 try:
32 self.__name = instance_dict['name']
33 self.__osd_type = BEINC_OSD_TYPE_NONE
34 self.__password = instance_dict['password']
35 self.__queue_size = int(instance_dict['queue_size'])
36 self.__message_queue = list()
37 self.__osd_notification = None
38
39 except Exception as e:
40 sys.stderr.write(
41 'Instance processing error {0}:\n{1}\n'.format(self.__name,
42 e))
43 sys.exit(1)
44
45
46 if instance_dict['osd_system'].lower() == 'pynotify':
47 if not pynotify:
48 sys.stderr.write(
49 'This server does not possess pynotify capability\n')
50 sys.stderr.write(
51 "Remove the instance {0} or define it with 'osd_system': 'none'")
52 sys.exit(1)
53
54 try:
55 self.__osd_notification = pynotify.Notification(' ')
56 self.__osd_notification.set_timeout(
57 instance_dict['osd_timeout'])
58 self.__osd_notification.set_property(
59 'app_name',
60 '{0} {1}'.format(sys.argv[0], __version__))
61 except Exception as e:
62 sys.stderr.write(
63 'Unable to set up a notification object for {0} ({1})\n')
64 sys.exit(1)
65
66 self.__osd_type = BEINC_OSD_TYPE_PYNOTIFY
67
68
69 @property
70 def name(self):
71 """
72 name-property for the server instance
73 """
74 return self.__name
75
76
77 @property
78 def queueable(self):
79 """
80 name-property for the server instance
81 """
82 return bool(self.__queue_size)
83
84
85 def password_match(self, password):
86 """
87 Returns True if 'passowrd' matches the instance-password,
88 otherwise - False
89 """
90 if self.__password == password:
91 return True
92
93 return False
94
95
96 def send_message(self, title, message):
97 """
98 Displays or enqueues the message,
99 depending on the instance's type in regard to the osd_system
100 """
101 if self.__osd_type == BEINC_OSD_TYPE_PYNOTIFY:
102 self.__send_pynotify_messaage(title, message)
103 else:
104 self.____send_message_to_queue(title, message)
105
106
107 def get_queue(self):
108 """
109 Reruens a json representation of the message queue
110 """
111 jstr = json.dumps(self.__message_queue)
112 self.__message_queue = list()
113 return jstr
114
115
116 def __send_pynotify_messaage(self, title, message):
117 """
118 Displays pynotify message
119 """
120
121 self.__osd_notification.set_properties(summary=title, body=message)
122 self.__osd_notification.show()
123
124
125 def __send_message_to_queue(self, title, message):
126 """
127 Enqueues the message
128 """
129
130 if len(self.__message_queue) >= self.__queue_size:
131 self.__message_queue.pop(0)
132
133 self.__message_queue.append({'title': title, 'message': message})
134
135
136
137def beinc_instance_login(method):
138 """
139 decorator for checking login credentials
140 """
141
142 def tmp_func(self, *args, **kwargs):
143
144 if not args:
145 raise cherrypy.HTTPError(400)
146
147 print('args: {0}'.format(args))
148 print('kwargs: {0}'.format(kwargs))
149 print(cherrypy.request.config)
150
151 try:
152 instance = self.__instances(args[0])
153 except Exception as e:
154 raise cherrypy.HTTPError('403 Forbidden',
155 'Wrong instance or password')
156
157 if not instance.password_match(kwargs.get('password')):
158 raise cherrypy.HTTPError('403 Forbidden',
159 'Wrong instance or password')
160
161 method(self, *args, **kwargs)
162
163 return tmp_func
164
165
18 166
19class WebNotifyServer(object): 167class WebNotifyServer(object):
20 168
@@ -23,15 +171,13 @@ class WebNotifyServer(object):
23 """ 171 """
24 self.__config = config 172 self.__config = config
25 self.__instances = dict() 173 self.__instances = dict()
26 self.__queues = dict()
27 174
28 try: 175 try:
29 for instance in self.__config['server']['instances']: 176 for instance in self.__config['server']['instances']:
30 self.__queues[instance['name']] = list() 177 self.__instances[instance['name']] = BEINCInstance(instance)
31 self.__instances[instance['name']] = instance
32 178
33 except Exception as e: 179 except Exception as e:
34 sys.stderr.write('Unable to initialize queues: {0}'.format(e)) 180 sys.stderr.write('Unable to initialize queues: {0}\n'.format(e))
35 sys.exit(1) 181 sys.exit(1)
36 182
37 183
@@ -52,47 +198,20 @@ class WebNotifyServer(object):
52 198
53 199
54 @cherrypy.expose 200 @cherrypy.expose
201 @beinc_instance_login
55 def push(self, *args, **kwargs): 202 def push(self, *args, **kwargs):
56 203
57 if not args: 204 instance = self.__instances(args[0])
58 raise cherrypy.HTTPError(400)
59
60 print('args: {0}'.format(args))
61 print('kwargs: {0}'.format(kwargs))
62
63 instance = self.__get_instance(args[0])
64
65 if not kwargs.get('password') == instance['password']:
66 raise cherrypy.HTTPError('403 Forbidden',
67 'Wrong instance or password')
68
69 return 'OK' 205 return 'OK'
70 206
71 207
72 def __get_instance(self, name): 208 @cherrypy.expose
73 """ 209 @beinc_instance_login
74 returns a matching 'instance' dictionary 210 def pull(self, *args, **kwargs):
75
76 cherrypy.HTTPError - "403 Forbidden" is raised if no
77 instance matches 'name'
78 """
79
80 try:
81 for instance in self.__config['server']['instances']:
82 if name == instance['name']:
83 return instance
84
85 except Exception as e:
86 raise cherrypy.HTTPError('403 Forbidden',
87 'Wrong instance or password: {0}'.format(e))
88
89 raise cherrypy.HTTPError("403 Forbidden", "Wrong instance or password")
90 211
212 instance = self.__instances(args[0])
213 return 'OK'
91 214
92 # mappings = [
93 # (r'^/push/', push),
94 # (r'^.*$', default),
95 # ]
96 215
97 216
98def main(): 217def main():
@@ -152,6 +271,16 @@ def main():
152 }) 271 })
153 272
154 try: 273 try:
274 import pynotify
275 if not pynotify.init("BEINC Notify"):
276 sys.stderr.write('pynotify.init failed! Exiting...\n')
277 sys.exit(1)
278 except Exception as e:
279 sys.stderr.write(
280 'Notice: pynotify support unavailable ({0})\n'.format(e))
281 pynotify = False
282
283 try:
155 cherrypy.quickstart(WebNotifyServer(config_dict)) 284 cherrypy.quickstart(WebNotifyServer(config_dict))
156 285
157 except Exception as e: 286 except Exception as e:
diff --git a/bins_server.py b/bins_server.py
deleted file mode 100755
index 68ccb74..0000000
--- a/bins_server.py
+++ /dev/null
@@ -1,140 +0,0 @@
1#!/usr/bin/env python
2# -*- coding: utf-8 -*-
3
4import argparse
5import getpass
6import json
7import os
8import sys
9
10import cherrypy
11
12import settings
13
14
15class CustomSocketServer(SocketServer.TCPServer):
16
17 def __init__(self, server_address, RequestHandlerClass, queue):
18 SocketServer.TCPServer.__init__(self,
19 server_address,
20 RequestHandlerClass)
21 self.queue = queue
22
23
24class MyTCPHandler(SocketServer.StreamRequestHandler):
25 """
26 The RequestHandler class for our server.
27
28 It is instantiated once per connection to the server, and must
29 override the handle() method to implement communication to the
30 client.
31 """
32
33 def handle(self):
34
35 data = self.rfile.readline().strip()
36
37 if self.server.queue.qsize() > 3:
38 self.server.queue.get()
39
40 self.server.queue.put(data)
41 #print(self.data)
42
43
44class WebNotifyServer(object):
45
46 def __init__(self, queue):
47 self.queue = queue
48
49 @cherrypy.expose
50 def notifications(self):
51
52 entry_list = list()
53
54 while not self.queue.empty():
55 entry_list.append(self.queue.get(False))
56
57 #print (json.dumps(entry_list, sort_keys=True, indent=4))
58 return json.dumps(entry_list)
59
60
61def socket_server(queue):
62
63 try:
64 server = CustomSocketServer((settings.SOCKET_SERVER_HOST,
65 settings.SOCKET_SERVER_PORT),
66 MyTCPHandler,
67 queue)
68 server.serve_forever()
69
70 except Exception as e:
71 sys.stderr.write("SocketServer error: {0}".format(e))
72 sys.exit(1)
73
74 sys.exit(0)
75
76
77
78def web_server(queue):
79
80 cherrypy.config.update({
81 'server.socket_host': settings.WEB_SERVER_HOST,
82 'server.socket_port': settings.WEB_SERVER_PORT,
83 'server.ssl_module': 'pyopenssl',
84 'server.ssl_certificate': settings.WEB_SERVER_CERT,
85 'server.ssl_private_key': settings.WEB_SERVER_KEY,
86 })
87
88 try:
89
90 cherrypy.quickstart(WebNotifyServer(queue))
91
92 except Exception as e:
93 sys.stderr.write("WebServer error: {0}".format(e))
94 sys.exit(1)
95
96 sys.exit(0)
97
98
99def main():
100
101 parser = argparse.ArgumentParser(description='The following options are available')
102
103
104 parser.add_argument('-d',
105 action='store_true',
106 dest='daemonize',
107 default=False,
108 help='daemonize the server process')
109
110 parser.add_argument('-H', '--hostname',
111 metavar='HOSTNAME',
112 type=str,
113 dest='hostname',
114 default='127.0.0.1',
115 help="Server IP / hostname")
116
117 parser.add_argument('-P', '--port',
118 metavar='PORT',
119 type=int,
120 dest='port',
121 default='9998',
122 help="Server port")
123
124 parser.add_argument('-p', '--password',
125 metavar='PASSWORD',
126 type=str,
127 dest='password',
128 help="Access password for the BOINS server")
129
130 parser.add_argument('-v', '--version',
131 action='version',
132 version='%(prog)s {0}'.format(__VERSION__),
133 help='display program-version and exit')
134
135
136
137 sys.exit(0)
138
139if __name__ == "__main__":
140 main()