src/extras/fileserver/fileclient.py
changeset 0 ca70ae20a155
equal deleted inserted replaced
-1:000000000000 0:ca70ae20a155
       
     1 #
       
     2 # fileclient.py 
       
     3 #
       
     4 # A client library for the simple file transfer server for Series 60 Python environment.
       
     5 #     
       
     6 # Copyright (c) 2005 Nokia Corporation
       
     7 #
       
     8 # Licensed under the Apache License, Version 2.0 (the "License");
       
     9 # you may not use this file except in compliance with the License.
       
    10 # You may obtain a copy of the License at
       
    11 #
       
    12 #     http://www.apache.org/licenses/LICENSE-2.0
       
    13 #
       
    14 # Unless required by applicable law or agreed to in writing, software
       
    15 # distributed under the License is distributed on an "AS IS" BASIS,
       
    16 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
       
    17 # See the License for the specific language governing permissions and
       
    18 # limitations under the License.
       
    19 
       
    20 
       
    21 import os
       
    22 import sys
       
    23 import binascii
       
    24 import ntpath
       
    25 
       
    26 symbianbasename=ntpath.basename
       
    27 
       
    28 class fileclient:
       
    29     def __init__(self,sock,verbose=0):
       
    30         self.sock=sock
       
    31         self.verbose=verbose
       
    32         if verbose:
       
    33             self.log=sys.stdout.write
       
    34         else:
       
    35             self.log=lambda x:0        
       
    36     def recvdata(self):
       
    37         #self.log("Waiting for content length..."
       
    38         header_lines=[self.readline() for x in range(2)]
       
    39         header=dict([x.rstrip().split(': ') for x in header_lines])
       
    40         content_length=int(header['Content-Length'])
       
    41         crc32=int(header['CRC32'])
       
    42         self.log("Content-Length: %d"%content_length+"\n")
       
    43         recvbytes=0
       
    44         content=[]
       
    45         #self.log("Receiving data...")
       
    46         while recvbytes<content_length:
       
    47             recvstring=self.sock.recv(min(content_length-recvbytes,2048))
       
    48             recvbytes+=len(recvstring)
       
    49             self.log("Received: %d bytes (%3.1f%%)\r"%(recvbytes,(100.*recvbytes/content_length)))
       
    50             sys.stdout.flush()
       
    51             content.append(recvstring)
       
    52         self.log("Received: %d bytes.        "%(recvbytes)+"\n")
       
    53         content=''.join(content)
       
    54         if crc32 != binascii.crc32(content):
       
    55             raise IOError("CRC error while receiving data")
       
    56         return content
       
    57     def senddata(self,data):
       
    58         #print "Sending data..."
       
    59         self.log("Content-Length: %d"%len(data)+"\n")
       
    60         self.write('Content-Length: '+str(len(data))+'\n'+
       
    61                    'CRC32: '+str(binascii.crc32(data))+'\n')
       
    62         sentbytes=0        
       
    63         # Send the data in little bits because the Bluetooth serial
       
    64         # connection may lose data on large sends.
       
    65         MAX_SEND=2048
       
    66         while sentbytes<len(data):
       
    67             n=min(len(data)-sentbytes,MAX_SEND)
       
    68             self.write(data[sentbytes:sentbytes+n])
       
    69             sentbytes+=n
       
    70             self.log("Sent: %d bytes (%3.1f%%)\r"%(sentbytes,(100.*sentbytes/len(data))))
       
    71             sys.stdout.flush()
       
    72         self.log("Sent: %d bytes.            "%(sentbytes)+"\n")
       
    73     def get(self,filename):
       
    74         self.log("get "+filename+"\n")
       
    75         self.write("get "+repr(filename)+"\n")
       
    76         return self.recvdata()
       
    77     def put(self,filename,content):
       
    78         self.log("put "+filename+"\n")
       
    79 #        self.write("put "+repr(filename)+" "+str(len(content))+'\n')
       
    80         self.write("put "+repr(filename)+"\n")
       
    81         self.senddata(content)
       
    82     def download(self,remotefile,localfile=None):
       
    83         if localfile is None:
       
    84             localfile=symbianbasename(remotefile)
       
    85         content=self.get(remotefile)
       
    86         f=open(localfile,'wb')
       
    87         f.write(content)
       
    88         f.close()
       
    89     def upload(self,remotefile,localfile=None):
       
    90         if localfile is None:
       
    91             localfile=symbianbasename(remotefile)
       
    92         f=open(localfile,'rb')
       
    93         content=f.read()
       
    94         f.close()
       
    95         self.put(remotefile,content)            
       
    96     def eval(self,expr):
       
    97         self.log("eval "+expr+"\n")
       
    98         self.write("eval\n")# "+repr(expr)+"\n")
       
    99         self.senddata(repr(expr))
       
   100         result=eval(self.recvdata())
       
   101         if result[0]!=0:
       
   102             raise "Exception on server side: "+''.join(result[1])
       
   103         else:
       
   104             return result[1]
       
   105     def exec_(self,expr):
       
   106         self.log("exec "+expr+"\n")
       
   107         self.write("exec\n")
       
   108         self.senddata(repr(expr))
       
   109         #self.write("exec "+repr(expr)+"\n")
       
   110         result=eval(self.recvdata())
       
   111         if result[0]!=0:
       
   112             raise "Exception on server side: "+''.join(result[1])
       
   113     def killserver(self):
       
   114         self.log("Sending quit command to server..."+"\n")
       
   115         self.write('quit\n')
       
   116     def readline(self):
       
   117         s=[]
       
   118         while 1:
       
   119             c=self.sock.recv(1)
       
   120             if c=='':
       
   121                 continue
       
   122             #self.sock.send(c)
       
   123             s.append(c)
       
   124             # We support just sane line-endings here.
       
   125             if c=='\n':
       
   126                 break
       
   127         return ''.join(s)
       
   128     def write(self,msg):
       
   129         self.sock.send(msg)
       
   130     
       
   131 class filesocket:
       
   132     def __init__(self,file):
       
   133         self.file=file
       
   134     def recv(self,n=1):
       
   135         return self.file.read(n)
       
   136     def send(self,msg):
       
   137         n=self.file.write(msg)
       
   138         self.file.flush()
       
   139         return n
       
   140 
       
   141 def connect(port='/dev/ttyS4',use_tcp=0,verbose=0):
       
   142     if use_tcp:
       
   143         import socket
       
   144         s=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
       
   145         addr=('127.0.0.1',1025)
       
   146         print "Connecting via TCP to "+`addr`+"...",
       
   147         sys.stdout.flush()
       
   148         s.connect(addr)
       
   149         client=fileclient(s,verbose)
       
   150         print "ok."
       
   151     else:
       
   152         print "Connecting to serial port "+port+"...",
       
   153         sys.stdout.flush()
       
   154         f=open(port,'r+b',0)
       
   155         fs=filesocket(f)
       
   156         client=fileclient(fs,verbose)
       
   157         print "ok."
       
   158     return client