#
# fileclient.py
#
# A client library for the simple file transfer server for Series 60 Python environment.
#
# Copyright (c) 2005 Nokia Corporation
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import os
import sys
import binascii
import ntpath
symbianbasename=ntpath.basename
class fileclient:
def __init__(self,sock,verbose=0):
self.sock=sock
self.verbose=verbose
if verbose:
self.log=sys.stdout.write
else:
self.log=lambda x:0
def recvdata(self):
#self.log("Waiting for content length..."
header_lines=[self.readline() for x in range(2)]
header=dict([x.rstrip().split(': ') for x in header_lines])
content_length=int(header['Content-Length'])
crc32=int(header['CRC32'])
self.log("Content-Length: %d"%content_length+"\n")
recvbytes=0
content=[]
#self.log("Receiving data...")
while recvbytes<content_length:
recvstring=self.sock.recv(min(content_length-recvbytes,2048))
recvbytes+=len(recvstring)
self.log("Received: %d bytes (%3.1f%%)\r"%(recvbytes,(100.*recvbytes/content_length)))
sys.stdout.flush()
content.append(recvstring)
self.log("Received: %d bytes. "%(recvbytes)+"\n")
content=''.join(content)
if crc32 != binascii.crc32(content):
raise IOError("CRC error while receiving data")
return content
def senddata(self,data):
#print "Sending data..."
self.log("Content-Length: %d"%len(data)+"\n")
self.write('Content-Length: '+str(len(data))+'\n'+
'CRC32: '+str(binascii.crc32(data))+'\n')
sentbytes=0
# Send the data in little bits because the Bluetooth serial
# connection may lose data on large sends.
MAX_SEND=2048
while sentbytes<len(data):
n=min(len(data)-sentbytes,MAX_SEND)
self.write(data[sentbytes:sentbytes+n])
sentbytes+=n
self.log("Sent: %d bytes (%3.1f%%)\r"%(sentbytes,(100.*sentbytes/len(data))))
sys.stdout.flush()
self.log("Sent: %d bytes. "%(sentbytes)+"\n")
def get(self,filename):
self.log("get "+filename+"\n")
self.write("get "+repr(filename)+"\n")
return self.recvdata()
def put(self,filename,content):
self.log("put "+filename+"\n")
# self.write("put "+repr(filename)+" "+str(len(content))+'\n')
self.write("put "+repr(filename)+"\n")
self.senddata(content)
def download(self,remotefile,localfile=None):
if localfile is None:
localfile=symbianbasename(remotefile)
content=self.get(remotefile)
f=open(localfile,'wb')
f.write(content)
f.close()
def upload(self,remotefile,localfile=None):
if localfile is None:
localfile=symbianbasename(remotefile)
f=open(localfile,'rb')
content=f.read()
f.close()
self.put(remotefile,content)
def eval(self,expr):
self.log("eval "+expr+"\n")
self.write("eval\n")# "+repr(expr)+"\n")
self.senddata(repr(expr))
result=eval(self.recvdata())
if result[0]!=0:
raise "Exception on server side: "+''.join(result[1])
else:
return result[1]
def exec_(self,expr):
self.log("exec "+expr+"\n")
self.write("exec\n")
self.senddata(repr(expr))
#self.write("exec "+repr(expr)+"\n")
result=eval(self.recvdata())
if result[0]!=0:
raise "Exception on server side: "+''.join(result[1])
def killserver(self):
self.log("Sending quit command to server..."+"\n")
self.write('quit\n')
def readline(self):
s=[]
while 1:
c=self.sock.recv(1)
if c=='':
continue
#self.sock.send(c)
s.append(c)
# We support just sane line-endings here.
if c=='\n':
break
return ''.join(s)
def write(self,msg):
self.sock.send(msg)
class filesocket:
def __init__(self,file):
self.file=file
def recv(self,n=1):
return self.file.read(n)
def send(self,msg):
n=self.file.write(msg)
self.file.flush()
return n
def connect(port='/dev/ttyS4',use_tcp=0,verbose=0):
if use_tcp:
import socket
s=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
addr=('127.0.0.1',1025)
print "Connecting via TCP to "+`addr`+"...",
sys.stdout.flush()
s.connect(addr)
client=fileclient(s,verbose)
print "ok."
else:
print "Connecting to serial port "+port+"...",
sys.stdout.flush()
f=open(port,'r+b',0)
fs=filesocket(f)
client=fileclient(fs,verbose)
print "ok."
return client