importsocketimportoptparseimportjson,os,sysclassClientHandler:def __init__(self):"""获取 Terminal 指令参数"""self.op=optparse.OptionParser()
self.op.add_option('-s', '--server', dest='server')
self.op.add_option('-p', '--port', dest='port')
self.op.add_option('-u', '--username', dest='username')
self.op.add_option('-w', '--password', dest='password')
self.options, self.args=self.op.parse_args()
self.mainpath=os.path.dirname(os.path.abspath(__file__))
self.verify_args()
self.make_connection()defverify_args(self):"""解析从 Terminal 获取的指令参数"""server=self.options.server
port=int(self.options.port)
username=self.options.username
password=self.options.passwordif 0 < port <= 65535:returnTrueelse:
exit('端口号必须介于 0~65535之间')defmake_connection(self):"""获取socket连接"""self.tcp=socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.tcp.connect((self.options.server, int(self.options.port),))definteractive(self):"""通讯"""flag=self.auth()ifflag:whileTrue:
cmdinfo=input('%s >>>'%self.curdir).strip()
cmdlist=cmdinfo.split()ifcmdlist[0]:ifhasattr(self,cmdlist[0]):
func=getattr(self,cmdlist[0])
func(cmdlist)else:print('指令不正确')else:pass
defauth(self):"""验证"""username=self.options.username
password=self.options.passwordif username is None or password isNone:
username= input('username:')
password= input('password:')
data={'action': 'auth','username': username,'password': password,
}
self.tcp.send(json.dumps(data).encode('GBK'))
data=self.response()if data['state_code'] ==200:print(data)
self.user=username
self.curdir=usernamereturnTrueelse:print(data)returnFalsedefput(self,cmdlist):
action,localpath,targetpath=cmdlist
localpath=os.path.join(self.mainpath,localpath)
filename=os.path.basename(localpath)
filesize=os.stat(localpath).st_size
data={'action':action,'targetpath':targetpath,'filename':filename,'filesize':filesize
}
self.tcp.sendall(json.dumps(data).encode('utf-8'))
data=self.response()if data['state_code'] ==800: #文件不存在,可以上传!
self.read(localpath,filesize,'rb')elif data['state_code'] ==801: #断点续传
choices=input('do you want continue? [Y/N]:')if choices.upper()=='Y':
self.tcp.sendall('Y'.encode('utf-8'))
position=self.tcp.recv(1024).decode('utf-8')
has_send=int(position)
self.read(localpath,filesize,'rb',has_send=has_send)elif choices.upper() =='N':
self.tcp.sendall('N'.encode('utf-8'))elif data['state_code'] ==802: #文件已经存在
print(data)return
def read(self,filename,filesize,mode,has_send=0):
f=open(filename,mode)
f.seek(has_send)while has_send
data=f.read(200)
self.tcp.sendall(data)
has_send+=len(data)
self.show_progress(has_send,filesize)
f.close()print('upload finish')defshow_progress(self,has_send,filesize):
rate=float(has_send)/float(filesize)
rate=int(rate*100)
sys.stdout.write('%s%% %s\r'%(rate,'*'*rate))defls(self,cmdlist):
action=cmdlist[0]
data={'action': action,
}
self.tcp.sendall(json.dumps(data).encode('utf-8'))
data= self.tcp.recv(1024).decode('utf-8')print(data)defcd(self,cmdlist):
action,dirname=cmdlist
data={'action': action,'dirname':dirname
}
self.tcp.sendall(json.dumps(data).encode('utf-8'))
data= self.tcp.recv(1024).decode('utf-8')
self.curdir=os.path.basename(data)defmakedir(self,cmdlist):
action,dirname=cmdlist
data={'action': action,'dirname':dirname
}
self.tcp.sendall(json.dumps(data).encode('utf-8'))
data= self.tcp.recv(1024).decode('utf-8')print(data)defresponse(self):
data= self.tcp.recv(1024).decode('GBK')
data=json.loads(data)returndata
client=ClientHandler()
client.interactive()