Привет всем! Интересный вопрос тут пришел в Telegram недавно: «Как скачать из папок на FTP только последние файлы?»:
Хорошо, что человек оставил свои контактные данные. Списались, обсудили задачу, которая в общих чертах выглядит так:
1. Есть FTP-сервер, на который иногда (либо раз в день, либо раз в неделю — это уж как повезет) главный офис заливает файлы. Причем — файлы разбрасываются в момент заливки по фиксированным папкам (их аж 140 штук).
2. Задача: сделать что-то, что будет забирать с FTP-сервера только новые файлы, не затрагивая старые.
Изначально человек, задавший вопрос предполагал идти через формирование списка файлов по времени изменения. Но возникали вопросы — а как контролировать? Что считать точкой отсчета? В итоге было принято решение разбить код на две части:
- 1. — Код, отвечающий за формирование исходного списка файлов — эдакого своеобразного слепка
- 2. — Код, который будет сравнивать текущее состояние FTP со списком, который сделан с помощью первого кода
На практике это выглядит следующим образом:
Код 1:
#Программа для создания исходного списка файлов
import ftplib
import time
from datetime import datetime
#Соединяемся с FTP-сервером
host = str(input('Host?: ')) #Например - ftp.cse.buffalo.edu
ftp_user = str(input('User?: ')) #anonymous
ftp_password = str(input('Password?: ')) #Тут вводим пароль
#после чего каждую переменную подключим к авторизации:
ftp = ftplib.FTP(host, ftp_user, ftp_password)
welcome_text = ftp.getwelcome()
print(welcome_text) #Вывели на экран Welcome-сообщение сервера
#Проверяем текущее состояние папок
directory_list = ftp.nlst() #загоняем в переменную list список содержимого директории
#print(directory_list) #Вывели список папок на сервере
print('Общее количество папок на сервере: ', len(directory_list))
#Получаем список файлов в каталоге
for directory in directory_list:
ftp.cwd(directory) #Входим в папку
sub_directory_list = ftp.nlst() #Получаем список файлов в папке
print('В папке', directory, 'находятся следующие файлы: \n', sub_directory_list)
for sub_directory_file in sub_directory_list:
file_redaction = ftp.sendcmd('mdtm ' + sub_directory_file) #Получаем время последней редакции каждого файла в папке
file_exp = '.txt'
directory = str(directory)
file_for_write = directory + file_exp
with open(file_for_write, 'a', encoding='utf8') as f: #Создаем файл с именем папки, и записываем в созданный файл все файлы, имеющиеся в папке в настоящий момент
f.write(sub_directory_file + '\n')
ftp.sendcmd('cdup') #Выходим из текущей папки
print('Оригинальный список файлов создан... \n')
Код 2:
#Программа для получения обновлений с FTP-сервера
import ftplib
import time
from datetime import datetime
import os
#Соединяемся с FTP-сервером
host = str(input('Host?: ')) #ftp.cse.buffalo.edu
ftp_user = str(input('User?: ')) #anonymous
ftp_password = str(input('Password?: ')) #Указываем пароль для входа
#после чего каждую переменную подключим к авторизации:
ftp = ftplib.FTP(host, ftp_user, ftp_password)
welcome_text = ftp.getwelcome()
print(welcome_text) #Вывели на экран Welcome-сообщение сервера
directory_list = ftp.nlst() #загоняем в переменную list названия всех папок
#Создаем список файлов из исходного
for directory in directory_list:
file_exp = '.txt'
directory = str(directory)
directory_file = directory + '.txt' #формируем имя файла, который будем открывать: название папки + расширение
with open(directory_file) as f:
list_iso = [row.strip() for row in f]
print('Список файлов в папке', directory, ':', list_iso)
#Создаем список файлов с сервера
ftp.cwd(directory) #Входим в папку
sub_directory_list = ftp.nlst()
print('Список файлов в папке', directory, 'на сервере:', sub_directory_list)
new_files = set(list_iso) ^ set(sub_directory_list)
new_files = list(new_files)
print('В папке', directory,'добавлены файлы:', new_files)
if len(new_files) > 0:
print('Изменения есть')
directory_for_save_temp = directory
try:
os.mkdir(directory)
except OSError:
print("Создать директорию %s не удалось" % directory)
else:
print("Успешно создана директория %s " % directory)
for new_file in new_files:
with open(directory + '/' + new_file, 'wb') as local_file:
ftp.retrbinary('retr ' + new_file, local_file.write)
elif len(new_files) == 0:
print('Изменений с прошлой проверки нет')
ftp.sendcmd('cdup') #Выходим из текущей папки
Вроде как все 🙂
В случае возникновения вопросов — пожалуйста, пишите на почту или в Телеграм 😉