From 60f47b04174d016cc86c6e06fdaf0794c3d14216 Mon Sep 17 00:00:00 2001 From: Simeon Simeonov Date: Wed, 7 May 2014 22:28:48 +0200 Subject: Git server / generic client and weechat client completed --- beinc_server.py | 148 +++++++++++++++++++++++++++++--------------------------- 1 file changed, 77 insertions(+), 71 deletions(-) (limited to 'beinc_server.py') diff --git a/beinc_server.py b/beinc_server.py index 8687da3..d4dd3c3 100755 --- a/beinc_server.py +++ b/beinc_server.py @@ -1,18 +1,42 @@ #!/usr/bin/env python # -*- coding: utf-8 -*- +# Blackmore's Enhanced IRC-Notification Collection (BEINC) v1.0 +# Copyright (C) 2013-2014 Simeon Simeonov + +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + + import argparse +import errno import getpass import json import os +import random import sys import cherrypy +try: + import pynotify +except ImportError as e: + pynotify = None + __author__ = 'Simeon Simeonov' -__version__ = '1.0-beta' -__license__ = "GPL3" +__version__ = '1.0' +__license__ = 'GPL3' BEINC_OSD_TYPE_NONE = 0 @@ -33,40 +57,35 @@ class BEINCInstance(object): self.__osd_type = BEINC_OSD_TYPE_NONE self.__osd_notification = None - try: - self.__name = instance_dict['name'] - self.__password = instance_dict['password'] - self.__queue_size = int(instance_dict['queue_size']) - - except Exception as e: - sys.stderr.write( - 'Instance processing error {0}:\n{1}\n'.format(self.__name, - e)) - sys.exit(1) + self.__name = instance_dict.get('name') + self.__password = instance_dict.get('password', '') + self.__queue_size = int(instance_dict.get('queue_size', 3)) if instance_dict['osd_system'].lower() == 'pynotify': + self.__queue_size = 0 # disable queueing if not pynotify: sys.stderr.write( 'This server does not possess pynotify capability\n') sys.stderr.write( 'Remove the instance {0}'.format(self.__name)) sys.stderr.write("or define it with 'osd_system': 'none'\n") - sys.exit(1) + sys.exit(errno.EPERM) try: self.__osd_notification = pynotify.Notification(' ') self.__osd_notification.set_timeout( - instance_dict['osd_timeout']) + int(instance_dict.get('osd_timeout', 5000))) self.__osd_notification.set_property( 'app_name', '{0} {1}'.format(sys.argv[0], __version__)) except Exception as e: sys.stderr.write( 'Unable to set up a notification object for {0} ({1})\n') - sys.exit(1) + sys.exit(errno.EPERM) self.__osd_type = BEINC_OSD_TYPE_PYNOTIFY + @property def name(self): """ @@ -129,34 +148,25 @@ def beinc_instance_login(method): """ decorator for checking login credentials """ - from functools import wraps - @wraps(method) - def tmp_func(self, *args, **kwargs): + def wrapper(self, *args, **kwargs): if not args: - raise cherrypy.HTTPError(400) - - print('args: {0}'.format(args)) - print('kwargs: {0}'.format(kwargs)) - print(cherrypy.request.config) - print('args[0]: {0} ({1})'.format(args[0], str(type(args[0])))) - print('instances: {0}'.format(str(self.__instances))) + raise cherrypy.HTTPError(status = 404) try: - instance = self.__instances[args[0]] + instance = self.instances[args[0]] except Exception as e: - sys.stderr.write('Wrong instance or password: {0}\n'.format(e)) - raise cherrypy.HTTPError('403 Forbidden', - 'Wrong instance or password') + raise cherrypy.HTTPError(status = 401, + message = 'Wrong instance or password') if not instance.password_match(kwargs.get('password')): - raise cherrypy.HTTPError('403 Forbidden', - 'Wrong instance or password') + raise cherrypy.HTTPError(status = 401, + message = 'Wrong instance or password') return method(self, *args, **kwargs) - return tmp_func + return wrapper class WebNotifyServer(object): @@ -167,15 +177,32 @@ class WebNotifyServer(object): self.__config = config self.__instances = dict() + # initialize pynotify if the module exists and if needed + if pynotify: + for instance in self.__config['server']['instances']: + # check if we have at least one instance that uses pynotify + # before initializing it + if instance.get('osd_system', '').lower() == 'pynotify': + if not pynotify.init('BEINC Notify'): + sys.stderr.write('pynotify.init failed! Exiting...\n') + sys.exit(1) + break try: for instance in self.__config['server']['instances']: self.__instances[instance['name']] = BEINCInstance(instance) print('Instance "{0}" added'.format(instance['name'])) except Exception as e: - sys.stderr.write('Unable to initialize queues: {0}\n'.format(e)) + sys.stderr.write('Unable to create instance "{0}": {1}\n'.format( + instance['name'], + e)) sys.exit(1) + + @property + def instances(self): + return self.__instances + @cherrypy.expose def index(self): """ @@ -190,33 +217,14 @@ class WebNotifyServer(object): """ return 'default' + @cherrypy.expose + @beinc_instance_login def push(self, *args, **kwargs): - print('push called') - - if not args: - raise cherrypy.HTTPError(400) - - # print('args: {0}'.format(args)) - # print('kwargs: {0}'.format(unicode(kwargs))) - # print(cherrypy.request.config) - # print('args[0]: {0} ({1})'.format(args[0], str(type(args[0])))) - # print('instances: {0}'.format(str(self.__instances))) - - try: - instance = self.__instances[args[0]] - except Exception as e: - sys.stderr.write('Wrong instance or password\n') - #print('DEBUG: {0}'.format(e)) - raise cherrypy.HTTPError('403 Forbidden', - 'Wrong instance or password') - if not instance.password_match(kwargs.get('password')): - sys.stderr.write('Wrong instance or password\n') - raise cherrypy.HTTPError('403 Forbidden', - 'Wrong instance or password') + instance = self.__instances[args[0]] -# instance = self.__instances[args[0]] + print('**kwargs: {0}'.format(str(kwargs))) title = kwargs.get('title', '') message = kwargs.get('message', '') try: @@ -229,12 +237,19 @@ class WebNotifyServer(object): e)) raise cherrypy.HTTPError(500, 'Unable to send message') + @cherrypy.expose @beinc_instance_login def pull(self, *args, **kwargs): - instance = self.__instances(args[0]) - return 'OK' + instance = self.__instances[args[0]] + if not instance.queueable: + raise cherrypy.HTTPError( + status = 405, + message = 'BEINC instance "{0}" does not support queuing'.format( + instance.name)) + + return instance.get_queue() def main(): @@ -283,7 +298,7 @@ def main(): except Exception as e: sys.stderr.write('Unable to parse {0}: {1}'.format(args.config_file, e)) - sys.exit(1) + sys.exit(errno.EIO) cherrypy.config.update({ 'server.socket_host': args.hostname, @@ -292,20 +307,11 @@ def main(): 'server.ssl_certificate': config_dict['server']['general']['ssl_certificate'], 'server.ssl_private_key': config_dict['server']['general']['ssl_private_key'], 'tools.encode.on': True, - 'tools.encode.encoding': 'utf-8' + 'tools.encode.encoding': 'utf-8', + 'tools.log_tracebacks.on': False, + 'request.show_tracebacks': False }) - global pynotify - try: - import pynotify - if not pynotify.init('BEINC Notify'): - sys.stderr.write('pynotify.init failed! Exiting...\n') - sys.exit(1) - except Exception as e: - sys.stderr.write( - 'Notice: pynotify support unavailable ({0})\n'.format(e)) - pynotify = False - try: cherrypy.quickstart(WebNotifyServer(config_dict)) -- cgit v1.3