New client-server architecture

Introduction
---------------
As discussed on #112 and #104 , pyqode 2.0 will need a brand new client-server architecture. I will quickly resume the issues and limitations we have with the current system, the goals of the new architecture and a brief preview of what the next api will look like.

Fixes #102, fixes #98. Once it has been done, pyqode will drop python2 support the client side code
base (#112).

Issues and limitations
---------------------------

- user cannot choose the interpreter to use to run the server code, this will cause problem if we switch to python3 for the code base as jedi, pyflask, pep8 are bound to the interpreter, we would lose the ability to support python2 syntax.
- the server is shared among QCodeEdit instances, this cause problems such as #102 because pickle is used to serialise data before sending through the socket.
- while the multiprocessing claims to supports cx_Freeze, its a pain to set it up. It would be way easier for us and for the user if he could write and freeze its own server script
- tools such as jedi does not work well when used from a frozen application because the interpreter does not have a complete standard lib,... This is very limitating, its impossible to use pyqode to create a frozen python IDE for windows. Adding the ability to select the interpreter would solve this.
- I have seen some cases where the server process didn't stop with the Qt application, leaving zombie processes.
 
Goals for the next design
--------------------------------

- allow user to select a custom interpreter
- simple api for selecting the worker to execute remotely
- get rid of pickle, json seems to be a very good replacement solution
- full support for python2 on the server side. This is a mandatory for all pyqode.core and pyqode.python workers. Other pyqode extensions for other languages don't really care about that and will probably use the defaul interpreter
- allow the user to write its own server script. Don't worry this will be very simple (1 line of code in the main function). That way you will have full control over the configuration of your server script
- 1 client-server pair per QCodeEdit instance
- no more zombie processes!

New design solutions
---------------------------
- server side will be implemented using the socketserver module and will use a json based messaging system with a simple ```header+payload``` protocol
- client side will be implemented using the QtNetwork module which fits nicely with the GUI event loop.
- use fully qualified name to define the worker function/callable to execute remotely. The public API will actually just require you to pass the class of the worker (```request_work(MyWorker, args='Code'```)
- a request is identified by a uuid
- you can link a callaback with a request on client side to get notified when the results are available
- use QProcess to control the server process, no more zombie processes!

Here is what the server script you will have to write will look like:

``` python
import sys
from pyqode.core.api import server
if __name__ == '__main__':
    import sys
    print("running with python %d.%d.%d" % (sys.version_info[:3]))
    # run the server
    server.run()
```

And here is what you will have to do with QCodeEdit to start the client-server pair:
```python
code_edit = QCodeEdit()
# run server with python2, the gui is a python3 script.
code_edit.start_server('path/to/my_server_script.py', '/usr/bin/python')
code_edit.open_file(...)
.
.
.
# request work (typically in a Mode)
self.editor.request_work(MyWorker, args={'code': self.editor.toPlainText()},                         
                                       on_receive=self._on_results_available)
```

Status of this PR
----------------------

The client-server api is ready, is fully documented and has been integrated into the rest of the code. Test have been written but some are still failing on travis. Once they pass I will merge this in the develop 2 branch.

Here is an example of the client api:

```python
import logging
from pyqode.core.api.client import JsonTcpClient
from pyqode.core.api import server, workers

def send_request():
    client.request_work(workers.echo,
                        {'code': 'print("Python is nice")',
                         'line': 1,
                         'column': 8,
                         'encoding': 'utf-8',
                         'path': '/a/path/to/a/file'},
                         on_receive=callback)
    QtCore.QTimer.singleShot(1000, send_request)

def callback(status, results):
    logging.debug('Yeah I got results from the server: '
                  '(status=%r, results=%r)' % (status, results))

if __name__ == "__main__":
    logging.basicConfig(level=logging.DEBUG)
    app = QtGui.QApplication(sys.argv)
    window = QtGui.QPlainTextEdit()
    client = JsonTcpClient(window)
    client.start(server.__file__, 'python')
    client.connected.connect(send_request)
    window.show()
    app.exec_()
    client.close()

``` 
which outputs:

```
/usr/bin/python3m /home/colin/dev/pyqode/core/pyqode/core/api/client.py
DEBUG:pyqode-client:running with python 3.3.2
DEBUG:pyqode-client:starting server process: python /home/colin/dev/pyqode/core/pyqode/core/api/server.py 55324
DEBUG:pyqode-client:server process started
DEBUG:pyqode-server:running with python 2.7.5
DEBUG:pyqode-client:connected to server: 127.0.0.1:55324
DEBUG:pyqode-client:sending request: {'data': {'column': 8, 'path': '/a/path/to/a/file', 'line': 1, 'encoding': 'utf-8', 'code': 'print("Python is nice")'}, 'request_id': 'd1d047ae-bd6c-4bea-93b2-a7d47513587e', 'worker': 'pyqode.core.api.workers.echo'}
DEBUG:pyqode-server:request received: {u'worker': u'pyqode.core.api.workers.echo', u'data': {u'column': 8, u'path': u'/a/path/to/a/file', u'line': 1, u'code': u'print("Python is nice")', u'encoding': u'utf-8'}, u'request_id': u'd1d047ae-bd6c-4bea-93b2-a7d47513587e'}
DEBUG:pyqode-server:echo worker running
DEBUG:pyqode-server:sending response: {'status': True, 'results': {u'column': 8, u'path': u'/a/path/to/a/file', u'line': 1, u'code': u'print("Python is nice")', u'encoding': u'utf-8'}, 'request_id': u'd1d047ae-bd6c-4bea-93b2-a7d47513587e'}
DEBUG:pyqode-client:response received: {'results': {'column': 8, 'path': '/a/path/to/a/file', 'line': 1, 'encoding': 'utf-8', 'code': 'print("Python is nice")'}, 'request_id': 'd1d047ae-bd6c-4bea-93b2-a7d47513587e', 'status': True}
DEBUG:root:Yeah I got results from the server: (status=True, results={'column': 8, 'path': '/a/path/to/a/file', 'line': 1, 'encoding': 'utf-8', 'code': 'print("Python is nice")'})
DEBUG:pyqode-client:sending request: {'data': {'column': 8, 'path': '/a/path/to/a/file', 'line': 1, 'encoding': 'utf-8', 'code': 'print("Python is nice")'}, 'request_id': '7c153dbf-fd59-4c5e-8d23-d1f5db1d0bf3', 'worker': 'pyqode.core.api.workers.echo'}
DEBUG:pyqode-server:request received: {u'worker': u'pyqode.core.api.workers.echo', u'data': {u'column': 8, u'path': u'/a/path/to/a/file', u'line': 1, u'code': u'print("Python is nice")', u'encoding': u'utf-8'}, u'request_id': u'7c153dbf-fd59-4c5e-8d23-d1f5db1d0bf3'}
DEBUG:pyqode-server:echo worker running
DEBUG:pyqode-server:sending response: {'status': True, 'results': {u'column': 8, u'path': u'/a/path/to/a/file', u'line': 1, u'code': u'print("Python is nice")', u'encoding': u'utf-8'}, 'request_id': u'7c153dbf-fd59-4c5e-8d23-d1f5db1d0bf3'}
DEBUG:pyqode-client:response received: {'results': {'column': 8, 'path': '/a/path/to/a/file', 'line': 1, 'encoding': 'utf-8', 'code': 'print("Python is nice")'}, 'request_id': '7c153dbf-fd59-4c5e-8d23-d1f5db1d0bf3', 'status': True}
DEBUG:root:Yeah I got results from the server: (status=True, results={'column': 8, 'path': '/a/path/to/a/file', 'line': 1, 'encoding': 'utf-8', 'code': 'print("Python is nice")'})
DEBUG:pyqode-client:sending request: 'shutdown'
DEBUG:pyqode-client:server process finished with exit code 0

Process finished with exit code 0
```