Advertisement
Guest User

Untitled

a guest
Feb 22nd, 2017
176
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 3.91 KB | None | 0 0
  1. import json
  2.  
  3. from channels.channel import Group
  4.  
  5. from . import __version__
  6. from .exceptions import *
  7. from .signals import user_connect, user_disconnect, keepalive
  8. from .utils import serializable
  9.  
  10.  
  11. class Msg:
  12.  
  13.     def __init__(self, entity=None, data={}, action=None, status='success', msg='', cmd_id=None):
  14.         self.entity = entity
  15.         self.data = data
  16.         self.action = action
  17.         self.status = status
  18.         self.msg = msg
  19.         self.cmd_id = cmd_id
  20.  
  21.     def json(self):
  22.         return json.dumps(serializable({'entity': self.entity, 'data': self.data, 'action': self.action,
  23.                                         'status': self.status, 'msg': self.msg, 'cmd_id': self.cmd_id}))
  24.  
  25.  
  26. class RegisterEngine(type):
  27.     def __init__(cls, name, bases, attrs):
  28.         if not getattr(cls, 'ACTIONS', None):
  29.             setattr(cls, 'ACTIONS', {})
  30.  
  31.         for key, val in attrs.items():
  32.             action = getattr(val, 'action', None)
  33.             if action is not None:
  34.                 cls.ACTIONS[key] = action
  35.  
  36.         if not name == 'Engine' and len(cls.ACTIONS.keys()):
  37.             cls.ACTIONS_CLASSES.append(cls)
  38.  
  39.  
  40. def action(*args):
  41.     def decorator(f):
  42.         f.action = tuple(args)
  43.         return f
  44.     return decorator
  45.  
  46.  
  47. class Engine(metaclass=RegisterEngine):
  48.  
  49.     ACTIONS_CLASSES = []
  50.  
  51.     def __init__(self, *args, **kwargs):
  52.         self.message = args[0]
  53.         super().__init__()
  54.  
  55.     @classmethod
  56.     def get_actions(cls):
  57.         actions = {}
  58.         for c in cls.ACTIONS_CLASSES:
  59.             actions.update(c.ACTIONS)
  60.         return actions
  61.  
  62.     @classmethod
  63.     def get_actions_json(cls):
  64.         actions = {}
  65.         for c in cls.ACTIONS_CLASSES:
  66.             actions.update(c.ACTIONS)
  67.         return json.dumps(actions)
  68.  
  69.     @classmethod
  70.     def connect(cls, message):
  71.         # send ACK
  72.         msg = Msg(entity='--SERVICE--', action='init',
  73.                   data={'version': __version__, 'actions': cls.get_actions()}).json()
  74.         message.reply_channel.send({'text': msg})
  75.         user_connect.send(sender=message, user=message.user)
  76.  
  77.     @classmethod
  78.     def disconnect(cls, message):
  79.         user_disconnect.send(sender=message, user=message.user)
  80.  
  81.     @classmethod
  82.     def keepalive(cls, message):
  83.         keepalive.send(sender=message)
  84.  
  85.     @classmethod
  86.     def dispatch(cls, message):
  87.         try:
  88.             msg_content = json.loads(message.content['text'])
  89.  
  90.             action = msg_content.get('action', None)
  91.             if not action:
  92.                 raise BadMessage('Action not specified.')
  93.  
  94.             engine = None
  95.             for c in cls.ACTIONS_CLASSES:
  96.                 if action in c.ACTIONS:
  97.                     engine = c(message)
  98.             if not engine:
  99.                 raise BadMessage('Action method "{}" not found in registry.'.format(action))
  100.  
  101.             _method = engine.ACTIONS.get(action, None)
  102.             if _method is None:
  103.                 raise BadMessage('Action method "{}" not implemented.'.format(action))
  104.  
  105.             args = ()
  106.             for a in _method:
  107.                 arg = msg_content.get(a, None)
  108.                 if not arg:
  109.                     raise BadMessage('Argument "{}" of method "{}" not specified.'.format(a, action))
  110.                 args += (arg,)
  111.  
  112.             method = getattr(engine, action)
  113.             return method(*args)
  114.  
  115.         except Exception as e:
  116.             print(e)
  117.             message.reply_channel.send({'text': e.__repr__()})
  118.  
  119.  
  120.     def add(self, group):
  121.         Group(group).add(self.message.reply_channel)
  122.  
  123.     def discard(self, group):
  124.         Group(group).discard(self.message.reply_channel)
  125.  
  126.     def send(self, msg, to=None):
  127.         if not to:
  128.             to = self.message.reply_channel
  129.         to.send({'text': msg.json() if isinstance(msg, Msg) else msg})
  130.  
  131.     def send_to_group(self, group, msg):
  132.         self.send(msg, to=Group(group))
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement