mplClient2.py 8 KB
Newer Older
1
2
from . import socket, AF_INET, SOCK_STREAM
import pickle
Yori Fournier's avatar
Yori Fournier committed
3
4
5
#from .signal import Signal, Status, Answer
#from .signal import Query as Server_Query
from . import Query, Status, Answer, Signal
6
from . import DBUG,WARN,SPCE,SEVR,INFO
Yori Fournier's avatar
Yori Fournier committed
7
from . import MplUnpickler
8
9
10
from . import MyData

debug = True
11

12
13
class MplClient2():
    
14
    def __init__(self):
15
        
16
        self.host,self.port = (None,None)
17
18
19
20
        
        # just a list of names
        self.currentRemoteData = []

21
22
23
24
25
26
    def connect(self,con):
    
        self.host,self.port = con # give (IP,PORT)
        self.sock = socket(AF_INET,SOCK_STREAM)
        self.sock.connect(con)
        self.connected = True
Yori Fournier's avatar
Yori Fournier committed
27

28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
    def disconnect(self):
        ''' shutdown socket. Warning: If server and client are local the client can not shut down the port because the server has still a handle on it'''
        print('closing the connection...')
        #~ self.sock.shutdown(socket.SHUT_WR)  
        self.sock.close()
        self.connected = False
        print('closing the connection... DONE')
        
    def reset_connection(self,new_con = None):
        
        self.disconnect()
        if new_con is not None :
            self.connect(con)
        else : # try to use the old values
            if (self.host is not None) and (self.port is not None) :
                self.connect((self.host,self.port))
            else :
                print('connection not initialized with correct values:')
                print('please provide host,port. currently host: ',self.host,' , port:',self.port)
47
48
        
    def send(self,sig):
49
        """ Sending a Type derived from Signal through the socket after 'pickling' it"""
50
51
52
        wf = self.sock.makefile(mode='wb')
        if debug:
            print('sending ',type(sig),' with content \"',sig.content,'\"')
53
54
55
56
        try :
            pickle.dump(sig,wf)
        except :
            return False
57
58
59
60
61
62
63
64
65
        wf.close()
        return True

    def waitForSignal(self):
        # wait for signal
        # unpickel
        
        rf = self.sock.makefile(mode='rb')
        try :
Yori Fournier's avatar
Yori Fournier committed
66
67
            unpickler = MplUnpickler(rf)
            response = unpickler.load()
68
            if debug and isinstance(response,Signal):
69
70
                print('CLIENT Received: {} with content \"{}\"'.format(type(response),response.content))
        except EOFError :
71
72
73
74
            print('no answer received - or connection closed unexpectedly')
            response = None
        except :
            print('unknown error while waiting for response')
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
            response = None
        rf.close()
        if isinstance(response,Signal) :
            return response
        
    def testStatusSig(self,orgQuery,statusSig) :
        if isinstance(statusSig,Status) :
            if statusSig.value :
                if debug :
                    print ('request type ',orgQuery.queryType,' successful' )
                return True
            else :
                if debug :
                    print('something went wrong on the server side handling request type',orgQuery.queryType)
                    print(statusSig.content)
                return False
        else :
92
            print('request type ',orgQuery.queryType,' returned unknown status type')
93
94
95
96
97
98
99
100
101
102
103
            return False
        
    def readData(self,ioFunction, dataName, *args, **kwargs) :
        # create a Signal of type Query with arguments
        query = Query(Query.READDATA,{'func' : ioFunction, 'dataname' : dataName,'args' : args,'kwargs': kwargs})
        status = self.send(query)
        if not status :
            print('something went wrong with the sending of readData request...')
        statusSig = self.waitForSignal()
        return self.testStatusSig(query,statusSig)

104
    def listRemoteData(self):
105
106
107
        """ The server retuns a list with the content of its G_RAWDATA 
        
        """
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
        query = Query(Query.LISTDATA,None)
        status = self.send(query)
        if not status :
            print('something went wrong with the sending of readData request...')
        answer = self.waitForSignal()
        if isinstance(answer,Answer) :
            return answer.content
        elif isinstance(answer,Status):
            print(answer.content)
            return None
    
    def getData(self, dataname) :
        """ The server returns the actual data known under "dataname" warning: this can possibly be HUGE
        
        """
        query = Query(Query.GETDATA,dataname)
        status = self.send(query)
        if not status :
            print('something went wrong with the sending of readData request...')
        answer = self.waitForSignal()
        if isinstance(answer,Answer) :
            return answer.content
        elif isinstance(answer,Status):
            print(answer.content)
            return None
133
        
134
    def newSyncFigure(self, figname, dataname, *args, **kwargs) :
135
136
137
138
139
140
141
142
        '''
        Send a query NEWSYNCFIGURE to the server
        wait for the status.
        if status ok then sync.
        '''
        # create a Signal of type Query with args
        query = Query(Query.NEWSYNCFIGURE,{'figClassName' : figname.__name__, "dataName" : dataname, 'args' : args, 'kwargs' : kwargs})
        status = self.send(query)
143
        
144
        if not status :
145
            print('something went wrong with the sending of newSincFigure request...')
146
        answer = self.waitForSignal()
147
148
        
        # try to create a figure of the same class on the client side
149
        if isinstance(answer,Answer) :
150
            print('trying to create a figure of the same class on the client side')
151
            fig = figname( dataname, *args, **kwargs)
152
            # Link the temporary Sync Figure
153
            fig.syncID = answer.content
154
            fig.client = self
155
156
157
158
159
160
161
162
            return fig
            
        elif isinstance(answer,Status) :
            self.testStatusSig(query,answer)
            return None
        else :
            print('an unknown error occured')
            return None
163
    
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
    def updateSyncFigure(self,syncID,kwargs) :
       ''' Send a UPDATE_SYNC_FIGURE query to the server. 
       
       wait for the status 
       if status ok then sync.
       '''
       # create a signal with args
       query = Query(Query.UPDATESYNCFIGURE,(syncID,kwargs))
       self.send(query)
       statusSig = self.waitForSignal()
    
       if statusSig.value :
            return True
       else:
            return False
        
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
    def deleteSyncFigure(self,syncID):
        '''
        Send a DELETESYNCFIGURE query to the server. 

        If the FigID is known delete it from G_FIGURES (server)
        wait for the confirmation status 
        if status ok then proceed deletion.
        '''
        # create a signal with syncID as content
        query = Query(Query.DELETESYNCFIGURE,syncID)
        status = self.send(query)
        
        statusSig = self.waitForSignal()
        if status and statusSig.value:
            return True
        else:
            print('The remote figure could not be deleted')
            print statusSig.content
            return False
199
200
201
202
203
204
205
206

    # SYNC FIGURE FORMAT RAWDATA ---------------------------------------
    def syncFigFormatRawData(self, syncID):
        ''' Send a FORMAT_SYNC_FIGURE query to the server. 
        wait for the answer
        if answer not empty then set data to answer's value.
        '''

207
        # Send the signal with syncID as content
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
        signal = Query(Query.SYNCFIGFORMATRAWDATA,syncID)
        status = self.send(signal)

        if debug:
            if not status:
                print(INFO+'Sent Signal')

        formatedData = self.waitForSignal()

        if not isinstance(formatedData,Answer) :
            print(WARN + 'The server could not format the rawdata.')
            
            if isinstance(formatedData,Status) :
                if formatedData.value :
                    print('This should not happen')
                else :
                    print('instead if answer a error was received')
            datas = (None,)                
        else :
            # set the figure data to answerSig.value
228
            datas = formatedData.content
229
        return datas