Я хотел бы записать сценарий Python, который позволяет мне удалять файлы из FTP-сервера после того, как они достигли определенного возраста. Я подготовил scipt ниже, но он бросает сообщение об ошибке: WindowsError: [Error 3] The system cannot find the path specified: '/test123/*.*'
У кого-то есть идея, как решить этот вопрос?Заранее спасибо!
import os, time
from ftplib import FTP
ftp = FTP('127.0.0.1')
print "Automated FTP Maintainance"
print 'Logging in.'
ftp.login('admin', 'admin')
# This is the directory that we want to go to
path = 'test123'
print 'Changing to:' + path
ftp.cwd(path)
files = ftp.retrlines('LIST')
print 'List of Files:' + files
#--everything works fine until here!...
#--The Logic which shall delete the files after the are 7 days old--
now = time.time()
for f in os.listdir(path):
if os.stat(f).st_mtime < now - 7 * 86400:
if os.path.isfile(f):
os.remove(os.path.join(path, f))
except:
exit ("Cannot delete files")
print 'Closing FTP connection'
ftp.close()
Хорошо, вместо того, чтобы анализировать код, который вы разместили дальше, вот пример, который может направить вас на правильный путь.
from ftplib import FTP
import re
pattern = r'.* ([A-Z|a-z].. .. .....) (.*)'
def callback(line):
found = re.match(pattern, line)
if (found is not None):
print found.groups()
ftp = FTP('myserver.wherever.com')
ftp.login('elvis','presley')
ftp.cwd('testing123')
ftp.retrlines('LIST',callback)
ftp.close()
del ftp
Запустите его, и вы получите что-то вроде этого, что должно стать началом того, чего вы пытаетесь достичь. Чтобы завершить его, вам нужно преобразовать первый результат в дату и время, сравнить его с «сейчас» и использовать ftp.delete (), чтобы избавиться от удаленного файла, если он слишком старый.
>>>
('May 16 13:47', 'Thumbs.db')
('Feb 16 17:47', 'docs')
('Feb 23 2007', 'marvin')
('May 08 2009', 'notes')
('Aug 04 2009', 'other')
('Feb 11 18:24', 'ppp.xml')
('Jan 20 2010', 'reports')
('Oct 10 2005', 'transition')
>>>
На какой ОС вы работаете? Путь к файлу / test123 /*.*
выполнен в стиле Unix, но в сообщении указано WindowsError
. Вы берете вывод команды ftp LIST в стиле Unix и пытаетесь дословно использовать его в сценарии Windows?
Ну, похоже, что ошибка, которую вы видите, связана с тем, что вы пытаетесь удалить каталог 'test123' с вашего локального компьютера, а не с FTP-сайта. В документах FTP есть метод с именем delete, и это то, что вы хотите использовать для удаления файла. Что касается проверки того, есть ли чему-то 7 дней или нет, вам, возможно, придется временно извлечь эти файлы из FTP, а затем проверить время изменения перед использованием FTP.delete.
OK. Предполагая, что ваш FTP-сервер поддерживает команду MLSD
, создайте модуль со следующим кодом (это код из скрипта, который я использую для синхронизации удаленного FTP-сайта с локальным каталогом):
# for python ≥ 2.6
import sys, os, time, ftplib
import collections
FTPDir= collections.namedtuple("FTPDir", "name size mtime tree")
FTPFile= collections.namedtuple("FTPFile", "name size mtime")
class FTPDirectory(object):
def __init__(self, path='.'):
self.dirs= []
self.files= []
self.path= path
def getdata(self, ftpobj):
ftpobj.retrlines('MLSD', self.addline)
def addline(self, line):
data, _, name= line.partition('; ')
fields= data.split(';')
for field in fields:
field_name, _, field_value= field.partition('=')
if field_name == 'type':
target= self.dirs if field_value == 'dir' else self.files
elif field_name in ('sizd', 'size'):
size= int(field_value)
elif field_name == 'modify':
mtime= time.mktime(time.strptime(field_value, "%Y%m%d%H%M%S"))
if target is self.files:
target.append(FTPFile(name, size, mtime))
else:
target.append(FTPDir(name, size, mtime, self.__class__(os.path.join(self.path, name))))
def walk(self):
for ftpfile in self.files:
yield self.path, ftpfile
for ftpdir in self.dirs:
for path, ftpfile in ftpdir.tree.walk():
yield path, ftpfile
class FTPTree(FTPDirectory):
def getdata(self, ftpobj):
super(FTPTree, self).getdata(ftpobj)
for dirname in self.dirs:
ftpobj.cwd(dirname.name)
dirname.tree.getdata(ftpobj)
ftpobj.cwd('..')
Если вы хотите работать с файлами каталога, вы можете:
import ftplib, time
quite_old= time.time() - 7*86400 # seven days
site= ftplib.FTP(hostname, username, password)
site.cwd(the_directory_to_work_on) # if it's '.', you can skip this line
folder= FTPDirectory()
folder.getdata(site) # get the filenames
for path, ftpfile in folder.walk():
if ftpfile.mtime < quite_old:
site.delete(ftpfile.name)
Это должно сделать то, что вы хотите.
Теперь, если это должно работать рекурсивно, вам придется сделать следующие два изменения в коде для "single directory case":
folder= FTPTree()
и
site.delete(os.path.join(path, ftpfile.name))
Серверы, с которыми я работал, не имели проблем с относительными путями в командах STOR
и DELE
, поэтому site.delete
с относительным путем тоже работает. Если ваш FTP-сервер требует имен файлов без путей, вам следует сначала .cwd
в указанный путь
, .delete
простой ftpfile.name
, а затем .cwd
обратно в базовую папку.