Utilities/BackgroundClient.py

Tue, 31 Dec 2013 18:03:31 +0100

author
T.Rzepka <Tobias.Rzepka@gmail.com>
date
Tue, 31 Dec 2013 18:03:31 +0100
branch
BgService
changeset 3159
02cb2adb4868
child 3173
1fb284abe46e
permissions
-rw-r--r--

First implementation for the BackgroundService.

3159
02cb2adb4868 First implementation for the BackgroundService.
T.Rzepka <Tobias.Rzepka@gmail.com>
parents:
diff changeset
1 # -*- coding: utf-8 -*-
02cb2adb4868 First implementation for the BackgroundService.
T.Rzepka <Tobias.Rzepka@gmail.com>
parents:
diff changeset
2
02cb2adb4868 First implementation for the BackgroundService.
T.Rzepka <Tobias.Rzepka@gmail.com>
parents:
diff changeset
3 # Copyright (c) 2013 - 2014 Detlev Offenbach <detlev@die-offenbachs.de>
02cb2adb4868 First implementation for the BackgroundService.
T.Rzepka <Tobias.Rzepka@gmail.com>
parents:
diff changeset
4 #
02cb2adb4868 First implementation for the BackgroundService.
T.Rzepka <Tobias.Rzepka@gmail.com>
parents:
diff changeset
5
02cb2adb4868 First implementation for the BackgroundService.
T.Rzepka <Tobias.Rzepka@gmail.com>
parents:
diff changeset
6 """
02cb2adb4868 First implementation for the BackgroundService.
T.Rzepka <Tobias.Rzepka@gmail.com>
parents:
diff changeset
7 Module implementing a Qt free version of a background client for the various
02cb2adb4868 First implementation for the BackgroundService.
T.Rzepka <Tobias.Rzepka@gmail.com>
parents:
diff changeset
8 checkers and other python interpreter dependent functions.
02cb2adb4868 First implementation for the BackgroundService.
T.Rzepka <Tobias.Rzepka@gmail.com>
parents:
diff changeset
9 """
02cb2adb4868 First implementation for the BackgroundService.
T.Rzepka <Tobias.Rzepka@gmail.com>
parents:
diff changeset
10
02cb2adb4868 First implementation for the BackgroundService.
T.Rzepka <Tobias.Rzepka@gmail.com>
parents:
diff changeset
11 from __future__ import unicode_literals
02cb2adb4868 First implementation for the BackgroundService.
T.Rzepka <Tobias.Rzepka@gmail.com>
parents:
diff changeset
12 try:
02cb2adb4868 First implementation for the BackgroundService.
T.Rzepka <Tobias.Rzepka@gmail.com>
parents:
diff changeset
13 bytes = unicode #__IGNORE_WARNING__
02cb2adb4868 First implementation for the BackgroundService.
T.Rzepka <Tobias.Rzepka@gmail.com>
parents:
diff changeset
14 except NameError:
02cb2adb4868 First implementation for the BackgroundService.
T.Rzepka <Tobias.Rzepka@gmail.com>
parents:
diff changeset
15 pass
02cb2adb4868 First implementation for the BackgroundService.
T.Rzepka <Tobias.Rzepka@gmail.com>
parents:
diff changeset
16
02cb2adb4868 First implementation for the BackgroundService.
T.Rzepka <Tobias.Rzepka@gmail.com>
parents:
diff changeset
17 import json
02cb2adb4868 First implementation for the BackgroundService.
T.Rzepka <Tobias.Rzepka@gmail.com>
parents:
diff changeset
18 import os
02cb2adb4868 First implementation for the BackgroundService.
T.Rzepka <Tobias.Rzepka@gmail.com>
parents:
diff changeset
19 import socket
02cb2adb4868 First implementation for the BackgroundService.
T.Rzepka <Tobias.Rzepka@gmail.com>
parents:
diff changeset
20 import struct
02cb2adb4868 First implementation for the BackgroundService.
T.Rzepka <Tobias.Rzepka@gmail.com>
parents:
diff changeset
21 import sys
02cb2adb4868 First implementation for the BackgroundService.
T.Rzepka <Tobias.Rzepka@gmail.com>
parents:
diff changeset
22 from zlib import adler32
02cb2adb4868 First implementation for the BackgroundService.
T.Rzepka <Tobias.Rzepka@gmail.com>
parents:
diff changeset
23
02cb2adb4868 First implementation for the BackgroundService.
T.Rzepka <Tobias.Rzepka@gmail.com>
parents:
diff changeset
24 if __name__ == '__main__':
02cb2adb4868 First implementation for the BackgroundService.
T.Rzepka <Tobias.Rzepka@gmail.com>
parents:
diff changeset
25 # Add Eric basepath to sys.path to be able to import modules which are
02cb2adb4868 First implementation for the BackgroundService.
T.Rzepka <Tobias.Rzepka@gmail.com>
parents:
diff changeset
26 # laying not only below Utilities
02cb2adb4868 First implementation for the BackgroundService.
T.Rzepka <Tobias.Rzepka@gmail.com>
parents:
diff changeset
27 path = os.path.dirname(sys.argv[0])
02cb2adb4868 First implementation for the BackgroundService.
T.Rzepka <Tobias.Rzepka@gmail.com>
parents:
diff changeset
28 path = os.path.dirname(path)
02cb2adb4868 First implementation for the BackgroundService.
T.Rzepka <Tobias.Rzepka@gmail.com>
parents:
diff changeset
29 sys.path.append(path)
02cb2adb4868 First implementation for the BackgroundService.
T.Rzepka <Tobias.Rzepka@gmail.com>
parents:
diff changeset
30
02cb2adb4868 First implementation for the BackgroundService.
T.Rzepka <Tobias.Rzepka@gmail.com>
parents:
diff changeset
31 from Plugins.CheckerPlugins.SyntaxChecker import SyntaxCheck
02cb2adb4868 First implementation for the BackgroundService.
T.Rzepka <Tobias.Rzepka@gmail.com>
parents:
diff changeset
32
02cb2adb4868 First implementation for the BackgroundService.
T.Rzepka <Tobias.Rzepka@gmail.com>
parents:
diff changeset
33
02cb2adb4868 First implementation for the BackgroundService.
T.Rzepka <Tobias.Rzepka@gmail.com>
parents:
diff changeset
34 class BackgroundClient(object):
02cb2adb4868 First implementation for the BackgroundService.
T.Rzepka <Tobias.Rzepka@gmail.com>
parents:
diff changeset
35 """
02cb2adb4868 First implementation for the BackgroundService.
T.Rzepka <Tobias.Rzepka@gmail.com>
parents:
diff changeset
36 Class implementing the main part of the background client.
02cb2adb4868 First implementation for the BackgroundService.
T.Rzepka <Tobias.Rzepka@gmail.com>
parents:
diff changeset
37 """
02cb2adb4868 First implementation for the BackgroundService.
T.Rzepka <Tobias.Rzepka@gmail.com>
parents:
diff changeset
38 def __init__(self, host, port):
02cb2adb4868 First implementation for the BackgroundService.
T.Rzepka <Tobias.Rzepka@gmail.com>
parents:
diff changeset
39 """
02cb2adb4868 First implementation for the BackgroundService.
T.Rzepka <Tobias.Rzepka@gmail.com>
parents:
diff changeset
40 Constructor of the BackgroundClient class.
02cb2adb4868 First implementation for the BackgroundService.
T.Rzepka <Tobias.Rzepka@gmail.com>
parents:
diff changeset
41
02cb2adb4868 First implementation for the BackgroundService.
T.Rzepka <Tobias.Rzepka@gmail.com>
parents:
diff changeset
42 @param host ip address the background service is listening
02cb2adb4868 First implementation for the BackgroundService.
T.Rzepka <Tobias.Rzepka@gmail.com>
parents:
diff changeset
43 @param port port of the background service
02cb2adb4868 First implementation for the BackgroundService.
T.Rzepka <Tobias.Rzepka@gmail.com>
parents:
diff changeset
44 """
02cb2adb4868 First implementation for the BackgroundService.
T.Rzepka <Tobias.Rzepka@gmail.com>
parents:
diff changeset
45 self.connection = socket.create_connection((host, port))
02cb2adb4868 First implementation for the BackgroundService.
T.Rzepka <Tobias.Rzepka@gmail.com>
parents:
diff changeset
46 ver = b'2' if sys.version_info[0] == 2 else b'3'
02cb2adb4868 First implementation for the BackgroundService.
T.Rzepka <Tobias.Rzepka@gmail.com>
parents:
diff changeset
47 self.connection.sendall(ver)
02cb2adb4868 First implementation for the BackgroundService.
T.Rzepka <Tobias.Rzepka@gmail.com>
parents:
diff changeset
48 self.connection.settimeout(0.25)
02cb2adb4868 First implementation for the BackgroundService.
T.Rzepka <Tobias.Rzepka@gmail.com>
parents:
diff changeset
49
02cb2adb4868 First implementation for the BackgroundService.
T.Rzepka <Tobias.Rzepka@gmail.com>
parents:
diff changeset
50 def __send(self, fx, fn, data):
02cb2adb4868 First implementation for the BackgroundService.
T.Rzepka <Tobias.Rzepka@gmail.com>
parents:
diff changeset
51 """
02cb2adb4868 First implementation for the BackgroundService.
T.Rzepka <Tobias.Rzepka@gmail.com>
parents:
diff changeset
52 Private method to send a job response back to the BackgroundService.
02cb2adb4868 First implementation for the BackgroundService.
T.Rzepka <Tobias.Rzepka@gmail.com>
parents:
diff changeset
53
02cb2adb4868 First implementation for the BackgroundService.
T.Rzepka <Tobias.Rzepka@gmail.com>
parents:
diff changeset
54 @param fx remote function name to execute (str)
02cb2adb4868 First implementation for the BackgroundService.
T.Rzepka <Tobias.Rzepka@gmail.com>
parents:
diff changeset
55 @param fn filename for identification (str)
02cb2adb4868 First implementation for the BackgroundService.
T.Rzepka <Tobias.Rzepka@gmail.com>
parents:
diff changeset
56 @param data return value(s) (any basic datatype)
02cb2adb4868 First implementation for the BackgroundService.
T.Rzepka <Tobias.Rzepka@gmail.com>
parents:
diff changeset
57 """
02cb2adb4868 First implementation for the BackgroundService.
T.Rzepka <Tobias.Rzepka@gmail.com>
parents:
diff changeset
58 packedData = json.dumps([fx, fn, data])
02cb2adb4868 First implementation for the BackgroundService.
T.Rzepka <Tobias.Rzepka@gmail.com>
parents:
diff changeset
59 if sys.version_info[0] == 3:
02cb2adb4868 First implementation for the BackgroundService.
T.Rzepka <Tobias.Rzepka@gmail.com>
parents:
diff changeset
60 packedData = bytes(packedData, 'utf-8')
02cb2adb4868 First implementation for the BackgroundService.
T.Rzepka <Tobias.Rzepka@gmail.com>
parents:
diff changeset
61 header = struct.pack(
02cb2adb4868 First implementation for the BackgroundService.
T.Rzepka <Tobias.Rzepka@gmail.com>
parents:
diff changeset
62 b'!II', len(packedData), adler32(packedData) & 0xffffffff)
02cb2adb4868 First implementation for the BackgroundService.
T.Rzepka <Tobias.Rzepka@gmail.com>
parents:
diff changeset
63 self.connection.sendall(header)
02cb2adb4868 First implementation for the BackgroundService.
T.Rzepka <Tobias.Rzepka@gmail.com>
parents:
diff changeset
64 self.connection.sendall(packedData)
02cb2adb4868 First implementation for the BackgroundService.
T.Rzepka <Tobias.Rzepka@gmail.com>
parents:
diff changeset
65
02cb2adb4868 First implementation for the BackgroundService.
T.Rzepka <Tobias.Rzepka@gmail.com>
parents:
diff changeset
66 def run(self):
02cb2adb4868 First implementation for the BackgroundService.
T.Rzepka <Tobias.Rzepka@gmail.com>
parents:
diff changeset
67 """
02cb2adb4868 First implementation for the BackgroundService.
T.Rzepka <Tobias.Rzepka@gmail.com>
parents:
diff changeset
68 Implement the main loop of the client.
02cb2adb4868 First implementation for the BackgroundService.
T.Rzepka <Tobias.Rzepka@gmail.com>
parents:
diff changeset
69 """
02cb2adb4868 First implementation for the BackgroundService.
T.Rzepka <Tobias.Rzepka@gmail.com>
parents:
diff changeset
70 while True:
02cb2adb4868 First implementation for the BackgroundService.
T.Rzepka <Tobias.Rzepka@gmail.com>
parents:
diff changeset
71 try:
02cb2adb4868 First implementation for the BackgroundService.
T.Rzepka <Tobias.Rzepka@gmail.com>
parents:
diff changeset
72 header = self.connection.recv(8) # __IGNORE_EXCEPTION__
02cb2adb4868 First implementation for the BackgroundService.
T.Rzepka <Tobias.Rzepka@gmail.com>
parents:
diff changeset
73 except socket.timeout:
02cb2adb4868 First implementation for the BackgroundService.
T.Rzepka <Tobias.Rzepka@gmail.com>
parents:
diff changeset
74 continue
02cb2adb4868 First implementation for the BackgroundService.
T.Rzepka <Tobias.Rzepka@gmail.com>
parents:
diff changeset
75 except socket.error:
02cb2adb4868 First implementation for the BackgroundService.
T.Rzepka <Tobias.Rzepka@gmail.com>
parents:
diff changeset
76 # Leave main loop if connection was closed.
02cb2adb4868 First implementation for the BackgroundService.
T.Rzepka <Tobias.Rzepka@gmail.com>
parents:
diff changeset
77 break
02cb2adb4868 First implementation for the BackgroundService.
T.Rzepka <Tobias.Rzepka@gmail.com>
parents:
diff changeset
78 # Leave main loop if connection was closed.
02cb2adb4868 First implementation for the BackgroundService.
T.Rzepka <Tobias.Rzepka@gmail.com>
parents:
diff changeset
79 if not header:
02cb2adb4868 First implementation for the BackgroundService.
T.Rzepka <Tobias.Rzepka@gmail.com>
parents:
diff changeset
80 break
02cb2adb4868 First implementation for the BackgroundService.
T.Rzepka <Tobias.Rzepka@gmail.com>
parents:
diff changeset
81
02cb2adb4868 First implementation for the BackgroundService.
T.Rzepka <Tobias.Rzepka@gmail.com>
parents:
diff changeset
82 length, datahash = struct.unpack(b'!II', header)
02cb2adb4868 First implementation for the BackgroundService.
T.Rzepka <Tobias.Rzepka@gmail.com>
parents:
diff changeset
83
02cb2adb4868 First implementation for the BackgroundService.
T.Rzepka <Tobias.Rzepka@gmail.com>
parents:
diff changeset
84 packedData = b''
02cb2adb4868 First implementation for the BackgroundService.
T.Rzepka <Tobias.Rzepka@gmail.com>
parents:
diff changeset
85 while len(packedData) < length:
02cb2adb4868 First implementation for the BackgroundService.
T.Rzepka <Tobias.Rzepka@gmail.com>
parents:
diff changeset
86 packedData += self.connection.recv(length - len(packedData))
02cb2adb4868 First implementation for the BackgroundService.
T.Rzepka <Tobias.Rzepka@gmail.com>
parents:
diff changeset
87
02cb2adb4868 First implementation for the BackgroundService.
T.Rzepka <Tobias.Rzepka@gmail.com>
parents:
diff changeset
88 assert adler32(packedData) & 0xffffffff == datahash, \
02cb2adb4868 First implementation for the BackgroundService.
T.Rzepka <Tobias.Rzepka@gmail.com>
parents:
diff changeset
89 'Hashes not equal'
02cb2adb4868 First implementation for the BackgroundService.
T.Rzepka <Tobias.Rzepka@gmail.com>
parents:
diff changeset
90 if sys.version_info[0] == 3:
02cb2adb4868 First implementation for the BackgroundService.
T.Rzepka <Tobias.Rzepka@gmail.com>
parents:
diff changeset
91 packedData = packedData.decode('utf-8')
02cb2adb4868 First implementation for the BackgroundService.
T.Rzepka <Tobias.Rzepka@gmail.com>
parents:
diff changeset
92 fx, fn, data = json.loads(packedData)
02cb2adb4868 First implementation for the BackgroundService.
T.Rzepka <Tobias.Rzepka@gmail.com>
parents:
diff changeset
93 if fx == 'syntax':
02cb2adb4868 First implementation for the BackgroundService.
T.Rzepka <Tobias.Rzepka@gmail.com>
parents:
diff changeset
94 ret = SyntaxCheck.syntaxAndPyflakesCheck(fn, *data)
02cb2adb4868 First implementation for the BackgroundService.
T.Rzepka <Tobias.Rzepka@gmail.com>
parents:
diff changeset
95 elif fx == 'style':
02cb2adb4868 First implementation for the BackgroundService.
T.Rzepka <Tobias.Rzepka@gmail.com>
parents:
diff changeset
96 print(data)
02cb2adb4868 First implementation for the BackgroundService.
T.Rzepka <Tobias.Rzepka@gmail.com>
parents:
diff changeset
97 elif fx == 'indent':
02cb2adb4868 First implementation for the BackgroundService.
T.Rzepka <Tobias.Rzepka@gmail.com>
parents:
diff changeset
98 pass
02cb2adb4868 First implementation for the BackgroundService.
T.Rzepka <Tobias.Rzepka@gmail.com>
parents:
diff changeset
99 else:
02cb2adb4868 First implementation for the BackgroundService.
T.Rzepka <Tobias.Rzepka@gmail.com>
parents:
diff changeset
100 continue
02cb2adb4868 First implementation for the BackgroundService.
T.Rzepka <Tobias.Rzepka@gmail.com>
parents:
diff changeset
101
02cb2adb4868 First implementation for the BackgroundService.
T.Rzepka <Tobias.Rzepka@gmail.com>
parents:
diff changeset
102 self.__send(fx, fn, ret)
02cb2adb4868 First implementation for the BackgroundService.
T.Rzepka <Tobias.Rzepka@gmail.com>
parents:
diff changeset
103
02cb2adb4868 First implementation for the BackgroundService.
T.Rzepka <Tobias.Rzepka@gmail.com>
parents:
diff changeset
104 self.connection.close()
02cb2adb4868 First implementation for the BackgroundService.
T.Rzepka <Tobias.Rzepka@gmail.com>
parents:
diff changeset
105 sys.exit()
02cb2adb4868 First implementation for the BackgroundService.
T.Rzepka <Tobias.Rzepka@gmail.com>
parents:
diff changeset
106
02cb2adb4868 First implementation for the BackgroundService.
T.Rzepka <Tobias.Rzepka@gmail.com>
parents:
diff changeset
107 def __unhandled_exception(self, exctype, excval, exctb):
02cb2adb4868 First implementation for the BackgroundService.
T.Rzepka <Tobias.Rzepka@gmail.com>
parents:
diff changeset
108 """
02cb2adb4868 First implementation for the BackgroundService.
T.Rzepka <Tobias.Rzepka@gmail.com>
parents:
diff changeset
109 Private method called to report an uncaught exception.
02cb2adb4868 First implementation for the BackgroundService.
T.Rzepka <Tobias.Rzepka@gmail.com>
parents:
diff changeset
110
02cb2adb4868 First implementation for the BackgroundService.
T.Rzepka <Tobias.Rzepka@gmail.com>
parents:
diff changeset
111 @param exctype the type of the exception
02cb2adb4868 First implementation for the BackgroundService.
T.Rzepka <Tobias.Rzepka@gmail.com>
parents:
diff changeset
112 @param excval data about the exception
02cb2adb4868 First implementation for the BackgroundService.
T.Rzepka <Tobias.Rzepka@gmail.com>
parents:
diff changeset
113 @param exctb traceback for the exception
02cb2adb4868 First implementation for the BackgroundService.
T.Rzepka <Tobias.Rzepka@gmail.com>
parents:
diff changeset
114 """
02cb2adb4868 First implementation for the BackgroundService.
T.Rzepka <Tobias.Rzepka@gmail.com>
parents:
diff changeset
115 # TODO: Wrap arguments so they can be serialized by JSON
02cb2adb4868 First implementation for the BackgroundService.
T.Rzepka <Tobias.Rzepka@gmail.com>
parents:
diff changeset
116 self.__send(
02cb2adb4868 First implementation for the BackgroundService.
T.Rzepka <Tobias.Rzepka@gmail.com>
parents:
diff changeset
117 'exception', '?', [str(exctype), str(excval), str(exctb)])
02cb2adb4868 First implementation for the BackgroundService.
T.Rzepka <Tobias.Rzepka@gmail.com>
parents:
diff changeset
118
02cb2adb4868 First implementation for the BackgroundService.
T.Rzepka <Tobias.Rzepka@gmail.com>
parents:
diff changeset
119 if __name__ == '__main__':
02cb2adb4868 First implementation for the BackgroundService.
T.Rzepka <Tobias.Rzepka@gmail.com>
parents:
diff changeset
120 if len(sys.argv) != 3:
02cb2adb4868 First implementation for the BackgroundService.
T.Rzepka <Tobias.Rzepka@gmail.com>
parents:
diff changeset
121 print('Host and port parameters are missing. Abort.')
02cb2adb4868 First implementation for the BackgroundService.
T.Rzepka <Tobias.Rzepka@gmail.com>
parents:
diff changeset
122 sys.exit(1)
02cb2adb4868 First implementation for the BackgroundService.
T.Rzepka <Tobias.Rzepka@gmail.com>
parents:
diff changeset
123
02cb2adb4868 First implementation for the BackgroundService.
T.Rzepka <Tobias.Rzepka@gmail.com>
parents:
diff changeset
124 host, port = sys.argv[1:]
02cb2adb4868 First implementation for the BackgroundService.
T.Rzepka <Tobias.Rzepka@gmail.com>
parents:
diff changeset
125 backgroundClient = BackgroundClient(host, int(port))
02cb2adb4868 First implementation for the BackgroundService.
T.Rzepka <Tobias.Rzepka@gmail.com>
parents:
diff changeset
126 # set the system exception handling function to ensure, that
02cb2adb4868 First implementation for the BackgroundService.
T.Rzepka <Tobias.Rzepka@gmail.com>
parents:
diff changeset
127 # we report on all unhandled exceptions
02cb2adb4868 First implementation for the BackgroundService.
T.Rzepka <Tobias.Rzepka@gmail.com>
parents:
diff changeset
128 sys.excepthook = backgroundClient._BackgroundClient__unhandled_exception
02cb2adb4868 First implementation for the BackgroundService.
T.Rzepka <Tobias.Rzepka@gmail.com>
parents:
diff changeset
129 # Start the main loop
02cb2adb4868 First implementation for the BackgroundService.
T.Rzepka <Tobias.Rzepka@gmail.com>
parents:
diff changeset
130 backgroundClient.run()

eric ide

mercurial