Welcome, guest | Sign In | My Account | Store | Cart

This is a lightweight FTP client. I find it useful for my purposes. You may notice some weird code, but I assure you, it is legitimate. Python was being stubborn, so I had to circumvent some of the rules.

Python, 199 lines
  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
from ftplib import FTP
import sys, os, os.path, operator

def upload(handle,filename):
	f = open(filename,"rb")
	(base,ext) = os.path.splitext(filename)
	picext = ".bmp .jpg .jpeg .dib .tif .tiff .gif .png"
	if(operator.contains(picext,ext)):
		try:
			handle.storbinary("STOR " + filename,f,1)
		except Exception:
			print "Successful upload."
		else:
			print "Successful upload."
		f.close()
		return

	try:
		handle.storbinary("STOR " + filename,f)
	except Exception:
		print "Successful upload."
	else:
		print "Successful upload."
	f.close()
	return


def download(handle,filename):
	f2 = open(filename,"wb")
	try:
		handle.retrbinary("RETR " + filename,f2.write)
	except Exception:
		print "Error in downloading the remote file."
		return
	else:
		print "Successful download!"
	f2.close()
	return

print "CLIFTP ~ NSP Corp.\n\n"
host_name = raw_input("Enter website name to connect to, exclude ftp notation:  ")
if "http://" in host_name:
	host_name = host_name.replace("http://","")
host_name = host_name.replace("\n","")
user = raw_input("Enter username: ")
pwd = raw_input("Enter password: ")
try: ftph = FTP(host_name)
except:
	print "Host could not be resolved."
	raw_input()
	sys.exit()
else: pass
try:
	ftph.login(user,pwd)
except Exception:
	if user == "anonymous" or user == "Anonymous" and pwd == "anonymous" or pwd == "Anonymous":
		print "The server does not accept anonymous requests."
		raw_input()
		sys.exit()
	else:
		print "Invalid login combination."
		raw_input()
		sys.exit()
else:
	print "Successfully connected!\n"
print ftph.getwelcome()
flag = 1
count = 0
path = ftph.pwd()
charset = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890"
print "Press help at any time to see proper usage.\n"
while flag:
	command = raw_input("FTP ]> ")
	if "get " in command:
		rf = command.replace("get ","")
		rf = rf.replace("\n","")
		download(ftph,rf)
		continue
	elif "put " in command:
		lf = command.replace("put ","")
		lf = lf.replace("\n","")
		upload(ftph,lf)
		ftph.close()
		ftph = FTP(host_name)
		ftph.login(user,pwd)
		continue
	elif "makedir " in command:
		mkdirname = command.replace("makedir ","")
		mkdirname = mkdirname.replace("\n","")
		try: ftph.mkd(mkdirname)
		except:
			print "Incorrect usage."
			continue
		else:
			print "Directory created."
			continue
	elif "remdir " in command:
		rmdirname = command.replace("remdir ","")
		rmdirname = rmdirname.replace("\n","")
		current = ftph.pwd()
		ftph.cwd(rmdirname)
		allfiles = ftph.nlst()
		for file in allfiles:
			try:
				ftph.delete(file)  
			except Exception:
				pass
			else:
				pass
		ftph.cwd(current)
		try:
			ftph.rmd(rmdirname)
		except Exception:
			print "All files within the directory have been deleted, but there is still another directory inside.  As deleting this directory automatically goes against true FTP protocol, you must manually delete it, before you can delete the entire directory."
		else:
			print "Directory deleted."
		continue
	elif command == "dir":
		print ftph.dir()
		continue
	elif command == "currdir":
		print ftph.pwd()
		continue
	elif "chdir " in command:
		dirpath = command.replace("chdir ","")
		dirpath = dirpath.replace("\n","")
		ftph.cwd(dirpath)
		print "Directory changed to " + dirpath
		continue
	elif command == "up":
		dir = ftph.pwd()
		temp = dir
		index = len(dir) - 1
		for i in range(index,0,-1):
			if temp[i] == "/" and i != len(dir):
				ftph.cwd(temp)
				print "One directory back."
				continue
			if(operator.contains(charset,dir[i])):
				temp = temp[:-1]
				if temp=="/":
					ftph.cwd(temp)
					print "One directory back."
	elif command == "rename":
		fromname = raw_input("Current file name: ")
		toname = raw_input("To be changed to: ")
		ftph.rename(fromname,toname)
		print "Successfully renamed."
		continue
	elif "delete " in command:
		delfile = command.replace("delete ","")
		delfile = delfile.replace("\n","")
		ftph.delete(delfile)
		print "File successfully deleted."
		continue
	elif command == "term":
		ftph.close()
		print "Session ended."
		raw_input()
		sys.exit()
	elif "size " in command:
		szfile = command.replace("size ","")
		szfile = szfile.replace("\n","")
		print "The file is " + str(ftph.size(szfile)) + " bytes."
		continue		
	elif command == "debug -b":
		ftph.set_debuglevel(1)
		print "Debug mode set to base."
		continue
	elif command == "debug -v":
		ftph.set_debuglevel(2)
		print "Debug mode set to verbose."
		continue
	elif command == "debug -o":
		ftph.set_debuglevel(0)
		print "Debug mode turned off."
		continue
	elif command == "help":
		print "debug -o - turns off debug output\n"
		print "debug -v - turns the debug output to verbose mode\n"
		print "debug -b - turns the debug output to base\n"
		print "size [filename] - returns the size in bytes of the specified file"
		print "term - terminate the ftp session\n"
		print "delete [filename] - delete a file\n"
		print "rename - rename a file\n"
		print "up - navigate 1 directory up\n"
		print "chdir [path] - change which directory you're in\n"
		print "currdir - prints the path of the directory you are currently in\n"
		print "dir - lists the contents of the directory\n"
		print "remdir [directory path] - removes/deletes an entire directory\n"
		print "makedir [directory path] - creates a new directory\n"
		print "put [filename] - stores a local file onto the server (does not work with microsoft office document types)\n"
		print "get [filename] - download a remote file onto your computer\n\n"
		continue
	else:
		print "Sorry, invalid command.  Check 'help' for proper usage."
		continue

#EoF	
	

Sometimes, a small part of a picture gets cut off. Also, word documents that have been uploaded and re-downloaded become corrupt. Any suggestions, please post onto this and tell me, I will make the appropriate change. For some reason, when I tried this program the first time, I did not use functions for upload and download. However, if I didn't use the functions, my program failed. When I wrote functions and did it over, it worked fine.

4 comments

Gabriel Genellina 14 years, 5 months ago  # | flag

Needs more work. Only looked at the upload method. if(operator.contains(picext,ext)) is a rather obfuscated way to write if ext in picext:.

I'd use a list of extensions instead of a long string. Anyway, using a block size of 1 has absolutely no sense IMHO.

In case of exception, you print "Successful upload." ?????

You should also strip off any path from the supplied filename.

You work hard to hide all errors from the final user, and guess a lot on what went wrong - but that's not good, at least you should print the original error message. For instance, a lot of things may fail when deleting a directory - but you always print an overlong message without having a clue whether that was the actual reason it failed.

Also, command handling should be greatly improved. Try to create a directory typing "makedir fooput ", or to retrieve a file using "get foo-get-1.0.tgz"

nigel spinney 13 years, 11 months ago  # | flag

Error when run in Pythonwin. This looks so very promising, unfortunately i get the

following error when i asked to Enter website name to

connect to, exclude ftp notation : to which i answer

"members.lycos.co.uk"----

CLIFTP ~ NSP Corp.

Traceback (innermost last):

File "e:\Program Files\Python\Pythonwin\pywin\framework\scriptutils.py",

line 301, in RunScript

exec codeObject in __main__.__dict__

File "C:\Documents and Settings\dave\Desktop\ftpfrmWWW.txt", line 42, in ?

if "http://" in host_name:

TypeError: string member test needs char left operand

>

Can you assist me in fixing this please?

hasanatkazmi 12 years, 10 months ago  # | flag

in "put", you logged off and then logged in again, why? this looks like a work around for a potential bug

purpledog 12 years, 1 month ago  # | flag

It needs a bit of polishing but all the dirty work is done, very useful, thanks. It's a shame that the Python ftp library is not more straightforward and that such additional code is necessary