0

At my company we have a scale that checks the weights of boxes before loading them into a truck. In the case the box contains more or less product than acceptable, the box is rejected and delivered to another conveyor belt. The electronic scale keeps a record of the performance of the operation. Files are stored in the scale's disk and accessed using ftp from a nearby desktop computer. My boss wants the reports to be automatically emailed to his account so he doesn't need to go to that facility just to check the rejections of the day before. I started writing a program in Python to do that, but got stucked in the part about retrieving the file from the folder. Here is my code:

#This program tries to retrieve the latest report and send it by email.
import urllib
import shutil
import ftplib
import os
import sys
import glob
import time
import datetime
import smtplib
import email

#Define the server and folder where the reports are stored.
carpetaftp = "/reports/"

#This function looks for the last file in the folder.
def obtenerultimoarchivo(camino):
    for cur_path, dirnames, filenames in os.walk(camino):
        for filename in filenames:
            datos_archivo = os.stat(filename)
            tiempo_archivo = datos_archivo.st_mtime

#Connects to an ftp folder and downloads the last report.
def descargareporteftp(carpetaftp):
    ftp = ftplib.FTP("server.scale.com")
    ftp.login()
    ftp.cwd(carpetaftp)
    #Uses 'ultimoreporte.pdf' as a copy of the last report.
    archivo = open('C:\\Balanza\\Reportes\\ultimoreporte.pdf',"wb")
    ftp.retrbinary("RETR " + obtenerultimoarchivo(),archivo.write)
    archivo.close()
    return archivo

#The function enviaemail() sends an email with an attachment.
def enviaemail(destinatario, adjunto):
    remitente = "electronic_scale@email.com.uy"
    msg = email.MIMEMultipart()
    msg['From'] = remitente
    msg['To'] = destinatario
    msg['Subject'] = "Ultimo informe de la balanza."
    adjunto = open('C:\\Balanza\\Reportes\\ultimoreporte.pdf', 'rb')
    attach = email.MIMENonMultipart('application', 'pdf')
    payload = base64.b64encode(adjunto.read()).decode('ascii')
    attach.set_payload(payload)
    attach['Content-Transfer-Encoding'] = 'base64'
    adjunto.close()
    attach.add_header('Content-Disposition', 'attachment', filename = 'ultimoreporte.pdf')
    msg.attach(attach)
    server = smtplib.SMTP('smtp.email.com.uy')
    server.login('electronic_scale@email.com.uy', 'thermofischer')
    server.sendmail('electronic_scale@email.com.uy',destinatario, msg.as_string())
    server.quit()


#The main routine, to retrieve the last report and send it by email.
adjunto = descargareporteftp(carpetaftp)
print("Reporte descargado")
enviaemail('myemail@email.com.uy',reporte)
print("Reporte enviado")
  • You cant use os.walk to find remote files. You should use ftp list if you don't know what file you need. Also you aren't passing obtenerultimoarchivo function anything. – cmd Mar 26 '13 at 15:03
  • 'obtenerultimoarchivo()' is inside 'descargareporteftp()'. I will check ftp list. Thanks. – Gustavo Sosa Mar 26 '13 at 19:52

1 Answers1

0

Here is a dirty way I found by making a mistake:

If no file is specified in a urllib retrieve command it will return and list of files in the directory (as in an ls command).

So using this, the code does the following:

  1. Retrieve a list of files in the FTP folder and save file locally
  2. Read the file and find the last entry on the list
  3. Retrieve the last file from the FTP folder

    import urllib
    
    def retrieve(address,output):
       # Run the ftp retrieve command here
       urllib.urlretrieve(address, output)
       # Flush the urllib so that we can download a second file
       urllib.urlcleanup()
    
    def main():
       #let's build the ftp address here:
       usr = "usrname"
       psswrd = "password"
       host = "host.com"
       path = "/foo/bar/"
       list_file = "list"
       address = 'ftp://%s:%s@%s%s' % (usr,psswrd,host,path)
       print "Getting file listing from: " + address
    
       # Retrieve the list
       retrieve(address,list_file)
    
       # read a text file as a list of lines
       # find the last line, change to a file you have
       list_file_reader = open ( 'list',"r" )
       lineList = list_file_reader.readlines()
       last_file = lineList[-1].split(' ')[-1:][0].rstrip()
    
       output = "wanted_file.dat"
       address = 'ftp://%s:%s@%s%s%s' % (usr,psswrd,host,path,last_file)
    
       # Retrieve the file you are actually looking for
       retrieve(address, output)
    
       print address
    
    main()
    

This is certainly no the most efficient way, but it works in my scenario.

References:

Python: download a file over an FTP server

https://www.daniweb.com/programming/software-development/threads/24544/how-do-i-read-the-last-line-of-a-text-file

Downloading second file from ftp fails

FredFury
  • 2,286
  • 1
  • 22
  • 27