python FTP download file with certain name - python

I have this FTP with folder and it contains these files:
pw201602042000.nc,
pw201602042010.nc,
pw201602042020.nc,
pw201602042030.nc,
pw201602042040.nc,
pw201602042050.nc,
pw201602042100.nc,
pw201602042110.nc,
pw201602042120.nc,
pw201602042130.nc,
pw201602042140.nc,
pw201602042150.nc,
pw201602042200.nc
how to download only file ending with 00?
from ftplib import FTP
server = FTP("ip/serveradress")
server.login("user", "password")
server.retrlines("LIST")
server.cwd("Folder")
server.sendcmd("TYPE i") # ready for file transfer
server.retrbinary("RETR %s"%("pw201602042300.nc"), open("pw", "wb").write)

when you obtained the list of files as list_of_files, just use fnmatch to match the file names according to wildcard:
list_of_files = server.retrlines("LIST")
dest_dir = "."
for name in list_of_files:
if fnmatch.fnmatch(name,"*00.nc"):
with open(os.path.join(dest_dir,name), "wb") as f:
server.retrbinary("RETR {}".format(name), f.write)
(note that you're writing the files on the same "pw" output file, I changed that, reusing the original name and provided a destination directory variable, and protecting the open in a with block to ensure file is closed when exiting the block)

Related

How to add password to zip file

I use this script to make zipped backup of important folder but because after 5th backup files is moves to Recycle Bin and show to everyone I am looking for setpassword opinion to protect deleted zips or even better delete old zips but permanently (not move in Recycle Bin).
from datetime import datetime
from pathlib import Path
import zipfile
OBJECT_TO_BACKUP = '/home/etre/test/' # The file or directory to backup
BACKUP_DIRECTORY = '/home/etre/test-backup/' # The location to store the backups in
MAX_BACKUP_AMOUNT = 5 # The maximum amount of backups to have in BACKUP_DIRECTORY
object_to_backup_path = Path(OBJECT_TO_BACKUP)
backup_directory_path = Path(BACKUP_DIRECTORY)
assert object_to_backup_path.exists() # Validate the object we are about to backup exists before we continue
# Validate the backup directory exists and create if required
backup_directory_path.mkdir(parents=True, exist_ok=True)
# Get the amount of past backup zips in the backup directory already
existing_backups = [
x for x in backup_directory_path.iterdir()
if x.is_file() and x.suffix == '.zip' and x.name.startswith('backup-')
]
# Enforce max backups and delete oldest if there will be too many after the new backup
oldest_to_newest_backup_by_name = list(sorted(existing_backups, key=lambda f: f.name))
while len(oldest_to_newest_backup_by_name) >= MAX_BACKUP_AMOUNT: # >= because we will have another soon
backup_to_delete = oldest_to_newest_backup_by_name.pop(0)
backup_to_delete.unlink()
# Create zip file (for both file and folder options)
backup_file_name = f'backup-{datetime.now().strftime("%Y%m%d%H%M%S")}-{object_to_backup_path.name}.zip'
zip_file = zipfile.ZipFile(str(backup_directory_path / backup_file_name), mode='w')
if object_to_backup_path.is_file():
# If the object to write is a file, write the file
zip_file.write(
object_to_backup_path.absolute(),
arcname=object_to_backup_path.name,
compress_type=zipfile.ZIP_DEFLATED
)
elif object_to_backup_path.is_dir():
# If the object to write is a directory, write all the files
for file in object_to_backup_path.glob('**/*'):
if file.is_file():
zip_file.write(
file.absolute(),
arcname=str(file.relative_to(object_to_backup_path)),
compress_type=zipfile.ZIP_DEFLATED
)
# Close the created zip file
zip_file.close()
I tried this
` zip_file.write(
object_to_backup_path.absolute(),
arcname=object_to_backup_path.name,
compress_type=zipfile.ZIP_DEFLATED
setpassword(b'1234')
`
Official Python Zip File documentation is available here
the following code useful:
from zipfile import ZipFile
import zipfile
myzip = ZipFile('test.zip')
myzip.setpassword(b"asasasasasas")
myzip.extract(member='Roughwork/pretify.html',pwd=b"asasasasasas")
Syntax:
ZipFile.extract(member, file_path=None , pwd=None)
Parameters:
members: It specifies the name of files to be extracted.
file_path: location where archive file needs to be extracted, if file_path is None then contents of zip file will be extracted to the current working directory
pwd: the password used for encrypted files, By default pwd is None.
useful link..

Skip list of filenames from txt file with os.walk

I would like to upload files that users dump into a shared folder to an FTP site. Only certain files must be uploaded based on a pattern in the filename, and that works. I would like to avoid uploading files that have been uploaded in the past. A simple solution would be to move the files to a subdirectory once uploaded, but users whish for the files to remain where they are.
I was thinking of writing a filename to a text file when each iteration of the loops makes an update. Populating the text file works.
Excluding directories with os.walk is mentioned in many articles and I can get that to work fine, but excluding a list of filenames seems to be a bit more obscure
This is what I have so far:
import ftplib
import os
import os.path
import fnmatch
## set local path variables
dir = 'c:/Temp'
hist_path = 'C:/Temp/hist.txt'
pattern = '*SomePattern*'
## make the ftp connection and set appropriate working directory
ftp = ftplib.FTP('ftp.someserver.com')
ftp.login('someuser', 'somepassword')
ftp.cwd('somedirectory')
## make a list of previously uploaded files
hist_list = open(hist_path, 'r')
hist_content = hist_list.read()
# print(hist_content)
## loop through the files and upload them to the FTP as above
for root, dirs, files in os.walk(dir):
for fname in fnmatch.filter(files, pattern): # this filters for filenames that include the pattern
## upload each file to the ftp
os.chdir(dir)
full_fname = os.path.join(root, fname)
ftp.storbinary('STOR ' + fname, open(full_fname, 'rb'))
## add an entry for each file into the historical uploads log
f = open(hist_path, 'a')
f.write(fname + '\n')
f.close()
Any help would be appreciated

How to copy a complete ziped folder to target using ftp in python?

I have to copy a ziped folder using ftplib as follows:
ftp = FTP('ip')
ftp.login(user='user', passwd = 'pass')
filename= "D:/sample.zip"
ftp.storlines("STOR " + os.path.basename(filename), open(filename,"r"))
On the remote the sample folder does gets copied but it is just '1kb' size in actual its size is 2963Kb. So, could you help me out how shall i copy the complete ziped folder on the remote.
Firstly, use storbinary() and not storlines. The latter is for ASCII files.
And since zip files are binary, the file should be opened in binary mode:
ftp.storbinary("STOR " + os.path.basename(filename), open(filename, "rb"))

How to download a file from 3ftp sites

I have a list of ftp sites ( eg:10 ) in text file and i need to download the last created file from ftp sites. Is this possible. This is my code :
import os
from ftplib import FTP
ftp = FTP("xxx.xx.xx.xx1", "USERNAME1", "PASSWORD1")
ftp = FTP("xxx.xx.xx.xx2", "USERNAME2", "PASSWORD2")
ftp = FTP("xxx.xx.xx.xx3", "USERNAME3", "PASSWORD3")
ftp = FTP("xxx.xx.xx.xx4", "USERNAME4", "PASSWORD4")
ftp = FTP("xxx.xx.xx.xx5", "USERNAME5", "PASSWORD5")
ftp.login()
ftp.retrlines("LIST")
ftp.cwd("SmythIN/2014-10-29") --- here i have a folder created by current date ...how can i pass current date folder i change directory.
ftp.cwd("subFolder") # or ftp.cwd("folderOne/subFolder")
listing = []
ftp.retrlines("LIST", listing.append)
words = listing[0].split(None, 8)
filename = words[-1].lstrip()
# download the file
local_filename = os.path.join(r"c:\myfolder", filename)
lf = open(local_filename, "wb")
ftp.retrbinary("RETR " + filename, lf.write, 8*1024)
lf.close()
updated code :
ftp.cwd("SmythIN/2014-10-29")- the directory with today date is already created.
Just looping through the servers and pulling the last file within specified directories (if I understand your question correctly) is straight forward. Remembering what server each file came from should not be problematic either since you can use different local directories on your local machine or edit the filename as the file transfers. Here is my suggestions (to be modified to your application of course):
import os
from ftplib import FTP
# read in text file containing server login information and jam into dictionary
with open('server_file.txt','r') as tmp:
servers = {}
for r in tmp.read().split('\n'):
rs = r.split(',') # split r by comma
servers[rs[0]] = {'uname':rs[1],'pwd':[rs[2]]}
# if you want to create a new directory to save the file to
heute = dt.datetime.strftime(dt.datetime.today(),'%Y%m%d')
if os.path.isdir('my_dir' + heute)==False:
os.mkdir('my_dir' + heute)
for s in servers:
ftp = FTP(s,servers[s]['uname'],servers[s]['pwd'])
ftp.cwd('desired_subdir')
# if you want to download the last file I would us nlst
with open('local_file','wb') as lf:
ftp.retrbinary('RETR' + ftp.nlst()[-1], lf.write, 8*1024)

os.renames for ftp in python

I want to move a large number of files from a windows system to a unix ftp server using python. I have a csv which has the current full path and filename and the new base bath to send it to (see here for an example dataset).
I have got a script using os.renames to do the transfer and directory creation in windows but can figure out a way to easily do it via ftp.
import os, glob, arcpy, csv, sys, shutil, datetime
top=os.getcwd()
RootOutput = top
startpath=top
FileList = csv.reader(open('FileList.csv'))
filecount=0
successcount=0
errorcount=0
# Copy/Move to FTP when required
ftp = ftplib.FTP('xxxxxx')
ftp.login('xxxx', 'xxxx')
directory = '/TransferredData'
ftp.cwd(directory)
##f = open(RootOutput+'\\Success_LOG.txt', 'a')
##f.write("Log of files Succesfully processed. RESULT of process run #:"+str(datetime.datetime.now())+"\n")
##f.close()
##
for File in FileList:
infile=File[0]
# local network ver
#outfile=RootOutput+File[4]
#os.renames(infile, outfile)
# ftp netowrk ver
# outfile=RootOutput+File[4]
# ftp.mkd(directory)
print infile, outfile
I tried the process in http://forums.arcgis.com/threads/17047-Upload-file-to-FTP-using-Python-ftplib but this is for moving all files in a directory, I have the old and new full file names and just need it to create the intermediate directories.
Thanks,
The following might work (untested):
def mkpath(ftp, path):
path = path.rsplit('/', 1)[0] # parent directory
if not path:
return
try:
ftp.cwd(path)
except ftplib.error_perm:
mkpath(ftp, path)
ftp.mkd(path)
ftp = FTP(...)
directory = '/TransferredData/'
for File in FileList:
infile = File[0]
outfile = File[4].split('\\') # need forward slashes in FTP
outfile = directory + '/'.join(outfile)
mkpath(ftp, outfile)
ftp.storbinary('STOR '+outfile, open(infile, 'rb'))

Categories

Resources