Python - Watch a folder for new .zip file and upload via FTP

1.8k views Asked by At

I am working on creating a script to watch a folder, grab any new .zip files, and then upload them via FTP to a predetermined area. Right now FTP testing is being performed Locally, since the environment isnt yet created.

The strategy I am taking is to first, unzip into a local folder. Then, perform ftplib.storbinary , on the file from the local folder, to the ftpdestination. However, the unzipping process appears to be working but I am getting a "file does not exist" error, all though I can see it in the folder itself.

Also, is there anyway to unzip directly into an FTP location? I havent been able to find a way hence the approach I am taking.

Thanks, local ftp info removed from code. All paths that are relevant in this code will be changed, most likely to dynamic fashion, but for now this is a local environment

extractZip2.py

import zipfile
import ftplib
import os
import logging
import time

from socket import error as socket_error


#Logging Setup
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger('__name__')

FTPaddress = ''
FTPusername = ''
FTPpassword = ''
ftp_destination_location  = ''

path_to_watch = "C:/Users/206420055/Desktop/test2/"
before = dict ([(f,None) for f in os.listdir(path_to_watch)])

temp_destination_location = "C:/Users/206420055/Desktop/temp/"


def unzip(fullPath,temporaryPath):
    with zipfile.ZipFile(fullPath, "r") as z :
        logger.info("Unzipping {0}".format(fullPath))
        z.extractall(temporaryPath)
        logger.info("Unzipped into local directory     {0}".format(temp_destination_location))


def check_or_create_ftp(session, folder):
    """
    Checks to see if necessary folder for currenttab is available. 
    Creates the folder if not found, and enters it.
    """
    if folder not in session.nlst():
        logger.info('Directory for {0} does not exist, creating directory\n'.format(folder))
        session.mkd(folder)

    session.cwd(folder)

def check_or_create(temp_destination):
    """
    Checks to see if local savepath exists. Will create savepath if not exists.
"""
    if not os.path.exists(temp_destination):
        logger.info('Directory for %s does not exist, creating directory\n' % temp_destination)
        os.makedirs(str(temp_destination))


def transfer(address,username,password,filename,destination):
    logger.info("Creating Session")
    try:
        session = session_init(address,username,password,destination)
    except (socket_error,ftplib.error_perm) as e:
        logger.error(str(e))
        logger.error("Error in Session Init")
    else:
        try:
            logger.info("Sending File {0}".format(filename))
            send_file(session,filename)
        except (IOError, OSError, ftplib.error_perm) as e:
            logger.error(e)

def session_init(address,username,password,path):
    session = ftplib.FTP(address,username,password)
    check_or_create_ftp(session,path)
    logger.info("Session Established")
    return session

def send_file(session,filename):
    file = open(filename,'rb')
    logger.info('Sending File : STOR '+filename)
    session.storbinary('STOR '+ filename, file)
    file.close()

def delete_local_files(savepath, file):
    logger.info("Cleaning Up Folder {0}".format(savepath))
    os.remove(file)


while 1:
    time.sleep(5)
    after = dict ([(f,None) for f in os.listdir(path_to_watch)])
    added = [f for f in after if not f in before]
    removed = [f for f in before if not f in after]
    if added: print "Added: ",", ".join(added)
    before = after

    check_or_create(temp_destination_location)
    if added : 
        for file in added:
            print file
            if file.endswith('.zip'):
                unzip(path_to_watch+file, temp_destination_location)
                temp_files = os.listdir(temp_destination_location)
                print("Temp Files {0}".format(temp_files))
                for tf in temp_files:
                    print("TF {0}".format(tf))
                    transfer(FTPaddress,FTPusername,FTPpassword,tf,ftp_destination_location)
                #delete_local_files(temp_destination_location,tf)
        else:
            pass

edit: adding error image

ftp error

Seen above, we see the file in the temp folder. But the console obviously shows the error.

1

There are 1 answers

4
Joran Beasley On BEST ANSWER

just change it to

from glob import glob
zips_in_path = dict ([(f,None) for f in glob("{base_path}/*.zip".format(base_path = path_to_watch)])

os.listdir does not include the path_to_watch part of the path it is just the filenames, however glob does.

so you could also do

after = dict ([(os.path.join(path_to_watch,f),None) for f in os.listdir(path_to_watch)])

using either of these methods you should be able to get the full path to the files in the path