src/extras/fileserver/fileserver.py
changeset 0 ca70ae20a155
equal deleted inserted replaced
-1:000000000000 0:ca70ae20a155
       
     1 # fileserver.py
       
     2 #
       
     3 # A simple file transfer server for Series 60 Python environment.
       
     4 #     
       
     5 # Copyright (c) 2005 Nokia Corporation
       
     6 #
       
     7 # Licensed under the Apache License, Version 2.0 (the "License");
       
     8 # you may not use this file except in compliance with the License.
       
     9 # You may obtain a copy of the License at
       
    10 #
       
    11 #     http://www.apache.org/licenses/LICENSE-2.0
       
    12 #
       
    13 # Unless required by applicable law or agreed to in writing, software
       
    14 # distributed under the License is distributed on an "AS IS" BASIS,
       
    15 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
       
    16 # See the License for the specific language governing permissions and
       
    17 # limitations under the License.
       
    18 
       
    19 
       
    20 import binascii
       
    21 
       
    22 #DEBUGLOG=lambda x: sys.stdout.write(x+"\n")
       
    23 DEBUGLOG=lambda x: 0
       
    24 
       
    25 def file_checksums(filelist):
       
    26     retval={}
       
    27     for fname in filelist:
       
    28         try: 
       
    29             f=open(fname,'rb')
       
    30             checksum=binascii.crc32(f.read())
       
    31             f.close()
       
    32         except:
       
    33             checksum=None
       
    34         retval[fname]=checksum
       
    35     return retval
       
    36 
       
    37 class fileserver:
       
    38     def __init__(self,sock):
       
    39         self.sock=sock
       
    40         self.commands={'quit': self.cmd_quit,
       
    41                        'get': self.cmd_get,
       
    42                        'put': self.cmd_put,
       
    43                        'exec': self.cmd_exec,
       
    44                        'eval': self.cmd_eval}
       
    45     def cmd_quit(self,line):
       
    46         self.finished=True
       
    47     def cmd_invalid(self,line):
       
    48         print >>sys.stderr,'Invalid command '+line,
       
    49         self.finished=True        
       
    50     def cmd_get(self,cmdline):
       
    51         filename=eval(cmdline[4:])
       
    52         DEBUGLOG("get "+filename)
       
    53         f=open(filename,'rb')
       
    54         content=f.read()
       
    55         f.close()
       
    56         self.senddata(content)
       
    57     def cmd_put(self,cmdline):
       
    58         words=cmdline.split()
       
    59         filename=eval(words[1])
       
    60         DEBUGLOG("put "+filename)
       
    61         content=self.recvdata()
       
    62         f=open(filename,'wb')
       
    63         f.write(content)
       
    64         f.close()
       
    65         print "Wrote %d bytes to %s."%(len(content),filename)
       
    66     def senddata(self,data):
       
    67         DEBUGLOG("Content-Length: %d"%len(data))
       
    68         self.write('Content-Length: '+str(len(data))+'\n'+
       
    69                    'CRC32: '+str(binascii.crc32(data))+'\n')
       
    70         sentbytes=0        
       
    71         # Send the data in little bits because the Bluetooth serial
       
    72         # connection may lose data on large sends.
       
    73         MAX_SEND=2048
       
    74         while sentbytes<len(data):
       
    75             n=min(len(data),MAX_SEND)
       
    76             self.write(data[sentbytes:sentbytes+n])
       
    77             sentbytes+=n
       
    78         print "Sent %d bytes."%sentbytes
       
    79     def recvdata(self):
       
    80         DEBUGLOG("Waiting for data...")
       
    81         header_lines=[self.readline() for x in range(2)]
       
    82         header=dict([x.rstrip().split(': ') for x in header_lines])
       
    83         content_length=int(header['Content-Length'])
       
    84         crc32=int(header['CRC32'])
       
    85         DEBUGLOG("Content-Length: %d"%content_length)
       
    86         recvbytes=0
       
    87         content=[]
       
    88         DEBUGLOG("Receiving data...")
       
    89         while recvbytes<content_length:
       
    90             recvstring=self.sock.recv(min(content_length-recvbytes,2048))
       
    91             recvbytes+=len(recvstring)
       
    92             #print "Received: %d bytes (%3.1f%%)\r"%(recvbytes,(100.*recvbytes/content_length)),
       
    93             content.append(recvstring)
       
    94         print "Received %d bytes."%recvbytes
       
    95         content=''.join(content)
       
    96         if crc32 != binascii.crc32(content):
       
    97             print "*** CRC error!"        
       
    98         return content
       
    99     def cmd_exec(self,cmdline):
       
   100 #        command=eval(cmdline[5:])
       
   101         command=eval(self.recvdata())
       
   102         DEBUGLOG("exec "+command)
       
   103         try:
       
   104             exec command in globals()
       
   105             result=(0,'')
       
   106         except:
       
   107             import traceback
       
   108             result=(1,apply(traceback.format_exception,sys.exc_info()))
       
   109         self.senddata(repr(result))
       
   110 
       
   111     def cmd_eval(self,cmdline):
       
   112         expr=eval(self.recvdata())
       
   113         #expr=eval(cmdline[5:])
       
   114         DEBUGLOG("eval "+expr)
       
   115         # two eval's because we need to first get rid of one level of
       
   116         # quoting.
       
   117         result=''
       
   118         try:
       
   119             value=eval(expr,globals())
       
   120             result=(0,value)
       
   121         except:
       
   122             import traceback
       
   123             result=(1,apply(traceback.format_exception,sys.exc_info()))
       
   124         self.senddata(repr(result))
       
   125 
       
   126     def readline(self):
       
   127         s=[]
       
   128         while 1:
       
   129             c=self.sock.recv(1)
       
   130             #self.sock.send(c)
       
   131             s.append(c)
       
   132             # We support just sane line-endings here.
       
   133             if c=='\n':
       
   134                 break
       
   135         return ''.join(s)
       
   136     def write(self,msg):
       
   137         self.sock.send(msg)
       
   138     def run(self):
       
   139         self.finished=False
       
   140         while not self.finished:
       
   141             cmdline=self.readline().rstrip()
       
   142             print "Received: "+cmdline
       
   143             words=cmdline.split()
       
   144             if len(words)>0:
       
   145                 cmd=words[0]
       
   146                 DEBUGLOG("Running command: "+cmdline)
       
   147                 self.commands.get(cmd,self.cmd_invalid)(cmdline)
       
   148 
       
   149 if __name__ == '__main__':
       
   150     import sys
       
   151     from e32socket import *
       
   152     import e32
       
   153     if not e32.is_ui_thread():
       
   154         f=open('c:/pythonout.txt','at')
       
   155         sys.stdout=f
       
   156         sys.stderr=f
       
   157 
       
   158     print "Starting server"
       
   159     use_tcp=0
       
   160     
       
   161     if use_tcp:
       
   162         s=socket(AF_INET,SOCK_STREAM)
       
   163         addr=('127.0.0.1',1025)
       
   164         s.bind(addr)
       
   165         s.listen(1)
       
   166     
       
   167         while 1:
       
   168             print "Waiting"
       
   169             (sock,remoteaddr)=s.accept()
       
   170             print "Connected"
       
   171             server=fileserver(sock)
       
   172             try:
       
   173                 server.run()
       
   174             except:
       
   175                 import traceback
       
   176                 traceback.print_exc()
       
   177             sock.close()
       
   178     else:
       
   179         s=socket(AF_BT,SOCK_STREAM)
       
   180         try:
       
   181             f=open('c:/system/apps/python/fileserver_conf.txt')
       
   182             conf=eval(f.read())
       
   183             f.close()
       
   184             addr=conf['target']
       
   185         except:
       
   186             addr=('00:20:e0:76:c3:52',10)
       
   187             conf={}
       
   188         #addr=('00:20:e0:76:c3:52',9)
       
   189         print "Connecting to "+`addr`
       
   190         s.connect(addr)
       
   191         server=fileserver(s)
       
   192         try:
       
   193             server.run()
       
   194         except:
       
   195             import traceback
       
   196             traceback.print_exc()
       
   197         s.close()
       
   198         print "Server finished."
       
   199