0
|
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
|