#!/usr/bin/env python3
import sys
assert sys.version >= '3.3', 'Please use Python 3.3 or higher.'

import argparse
import logging
import os
import ssl
import json

import asyncio
import aiohttp
import aiohttp.server

class DataviewVLCController():
    def pause():
      print("Pause() called")
      return True
    
    def set_volume(volume):
      print("set_volume(): " + str(volume))
      return "OK"
      return True
    
    def mute():
      print("mute() called")
      return True
    
    def unmute():
      print("unmute() called")
      return True

class DataviewRPCServer(asyncio.Protocol):
    def __init__(self, dispatch_functions):
        self.dispatch_functions = dispatch_functions

    def connection_made(self, transport):
        peername = transport.get_extra_info('peername')
        print('Connection from {}'.format(peername))
        self.transport = transport

    def data_received(self, data):
        response = {}
        message = data.decode()
        
        try:
            payload = json.loads(message)
        except Exception:
            response = {"jsonrpc": "2.0", "error": {"code": -32700, "message": "Parse error"}, "id": None}
            self.transport.write(str.encode(json.dumps(response) + "\n"))
            return

        try:
            if payload['jsonrpc'] != '2.0':
                response = {"jsonrpc": "2.0", "error": {"code": -32600, "message": "Invalid Request"}, "id": null}
                self.transport.write(str.encode(json.dumps(response) + "\n"))
                return
            response['jsonrpc'] = '2.0'
            response['id'] = payload['id']
        except Exception:
            pass

        if payload['method'] not in self.dispatch_functions:
              response = {"jsonrpc": "2.0", "error": {"code": -32601, "message": "Method not found"}, "id": payload['id']},
              self.transport.write(str.encode(json.dumps(response) + "\n"))
              return
        #try:
        response['result'] = self.dispatch_functions[payload['method']](*payload['params'])
        #except Exception as e:
        #    print(e)
        #    pass
            
        
        print('Data received: {!r}'.format(message))

        print('Send: {!r}'.format(json.dumps(response)))
        self.transport.write(str.encode(json.dumps(response) + "\n"))

        print('Close the client socket')
        #self.transport.close()

ARGS = argparse.ArgumentParser(description="Run simple http server.")
ARGS.add_argument(
    '--host', action="store", dest='host',
    default='127.0.0.1', help='Host name')
ARGS.add_argument(
    '--port', action="store", dest='port',
    default=8080, type=int, help='Port number')
ARGS.add_argument(
    '--tlscert', action="store", dest='certfile', help='TLS X.509 certificate file.')
ARGS.add_argument(
    '--tlskey', action="store", dest='keyfile', help='TLS key file.')

def main():
    args = ARGS.parse_args()

    if ':' in args.host:
        args.host, port = args.host.split(':', 1)
        args.port = int(port)

    here = os.path.join(os.path.dirname(__file__), 'tests')

    sslcontext = ssl.SSLContext(ssl.PROTOCOL_SSLv23) # TODO python 3.4+ check
    sslcontext.load_cert_chain(args.certfile, args.keyfile)

    loop = asyncio.get_event_loop()
    f = loop.create_server(
        lambda: DataviewRPCServer(
          {'pause': lambda: DataviewVLCController.pause(),
            'set_volume': lambda volume: DataviewVLCController.set_volume(volume),
            'mute': lambda: DataviewVLCController.mute(),
            'unmute': lambda: DataviewVLCController.unmute()
          }
        ),
        args.host, args.port,
        ssl = sslcontext)
    svr = loop.run_until_complete(f)
    socks = svr.sockets
    print('Server started. Waiting for connections on ', socks[0].getsockname())
    try:
        loop.run_forever()
    except KeyboardInterrupt:
        pass

if __name__ == '__main__':
    main()

@@ -268,117 +268,344 @@
     
-print(%22Pause() called%22)%0A      return True%0A    %0A    def set_volume(volume):%0A      print(%22set_volume(): %22 + str
+%22%22%22%0A      Pause the audio stream.%0A      NOTE: vlc's CLI interface only allows toggle of pause and is_playing does not consider pause state%0A      %22%22%22%0A      command = %22pause%22%0A      return True%0A    %0A    def set_volume(volume):%0A      %22%22%22%0A      Sets the volume for the current player instance%0A      %22%22%22%0A      command = %22volume %7B%7D%22.format(int
 (vol
@@ -606,24 +606,31 @@
 nt(volume))%0A
+      %0A
       return
@@ -634,30 +634,77 @@
 urn 
-%22OK%22
+True
 %0A    
+%0A 
   
-return True
+ def play(url):%0A      command = %22enqueue %7B%7D%22.format(url)
 %0A   
@@ -713,32 +713,51 @@
     def mute():%0A
+      command = %22%22%0A
       print(%22mut
@@ -806,24 +806,43 @@
 f unmute():%0A
+      command = %22%22%0A
       print(
@@ -877,16 +877,66 @@
 urn True
+%0A    %0A    def _send_to_server(command):%0A      pass
 %0A%0Aclass 

Add command stubs