-3

I have following Python 2.7 script.

The script iterates through a CSV file that contains filenames, it then looks on an FTP server to try and find the filenames.

However, I get an error when the file isn't found on the ftp:

error local variable 'newfile' referenced before assignment

Ideally, I want the script to just move on to the next row in the file, if it can't find the previous file on the ftp. How would I do this? Thanks in advance.

def googleclouda(googlefile): 



    import time
    import pysftp 
    import sys
    import os
    from os import path
    from datetime import datetime
    import calendar
    import zipfile
    import re

    os.chdir("C:\Users\\xxx\python\\xxx\\")  

    oftp = pysftp.Connection(host="xxxxxx", username="xxxxxx", password="xxxxxx")
    d = datetime.utcnow()
    unixtime=calendar.timegm(d.utctimetuple())
    month = datetime.now().strftime("%m") 
    string = googlefile+month+".*\.txt$"  

    possibleFiles = oftp.listdir("/") 
    for filename in possibleFiles:
            filedate = re.search(string, filename)  
            if filedate:
                newfile = filename

    timestamp  = oftp.stat(newfile).st_atime 
    if timestamp  > unixtime - 604800:  
        newtime=unixtime + 3600 
        gaamfile='file_123_26807_' 
        zipname = gaamfile+str(newtime)+'.sync.zip' 
        create_zip = zipfile.ZipFile(zipname, 'w', zipfile.ZIP_DEFLATED) 
        oftp.get(newfile, newfile)
        oftp.close()
        newfilename = gaamfile+str(newtime)+'.sync' 
        os.rename(newfile, newfilename)
        create_zip.write(newfilename)  
        create_zip.close()
        print newfile
    else: 
        print "No files found"


filecsv = 'filelist.csv' 

with open(filecsv, 'r') as f:
    for line in f:
        if not line.startswith('\n'): 
            googlefile = line.strip() 
            googleclouda(googlefile)
Vikas Periyadath
  • 3,088
  • 1
  • 21
  • 33
Nick Edwards
  • 55
  • 1
  • 10

3 Answers3

0

Your problem is with this bit of code:

for filename in possibleFiles:
        filedate = re.search(string, filename)  
        if filedate:
            newfile = filename

newfile only gets defined if filedate. Either:

  • Check your inputs so if filedate returns True.
  • Place all subsequent code under the if clause (via extra indentation) so that it only get executed if filedate == True.
jpp
  • 159,742
  • 34
  • 281
  • 339
  • Thanks for your help. Would you be able to share some example code of how I would implement your suggestions? Cheers – Nick Edwards Feb 15 '18 at 12:31
  • @NickEdwards. Unfortunately, I can't, as you haven't provided a reproducible example, or clarified what you want your output to be. – jpp Feb 15 '18 at 12:36
  • The script works until it reaches a file name in the CSV that is not on the FTP. The output is that the script just moves onto the next row in the csv and continues as is. I can't include the ftp credentials to replicate as there is sensitive data on there. Cheers – Nick Edwards Feb 15 '18 at 12:40
0

Try changing this:

            if filedate:
                newfile = filename

into this:

            if filedate and filename is not none:
                newfile = filename
ProgLover
  • 541
  • 6
  • 12
0

The issue is on this line:

timestamp  = oftp.stat(newfile).st_atime

If newfile is not assigned previously based on the if condition, you will reference it even if it's not assigned.

In the beginning of your script, as suggested by @cco, you can also set newfile to an empty string: newfile = ''

You should structure so that the rest is only processed if newfile is assigned. You can add a condition on newfile.


Also, if I'm not mistaken, the following lines should be part of the for loop. Otherwise newfile will only contain the last filename found. It will be overwritten each time with the next one found.

timestamp  = oftp.stat(newfile).st_atime 
        if timestamp  > unixtime - 604800:  
            newtime=unixtime + 3600 
            gaamfile='file_123_26807_' 
            zipname = gaamfile+str(newtime)+'.sync.zip' 
            create_zip = zipfile.ZipFile(zipname, 'w', zipfile.ZIP_DEFLATED) 
            oftp.get(newfile, newfile)
            oftp.close()
            newfilename = gaamfile+str(newtime)+'.sync' 
            os.rename(newfile, newfilename)
            create_zip.write(newfilename)  
            create_zip.close()
            print newfile
        else: 
            print "No files found"
Kevin Lemaire
  • 949
  • 2
  • 12
  • 36
  • 1
    This will still throw an error if `filedate` is not set. You need to set `newfile` to a falsy value (`0` or `None`, presumably) before the loop. – cco Feb 15 '18 at 09:40
  • @KevinLemaire - Thanks for your help. Appreciate it. Would you be able to show me an example of how I should implement your suggestions? – Nick Edwards Feb 15 '18 at 11:22