Скрипт Python для чтения файлов с FTP вместо локальной папки

#python #ftp

Вопрос:

У меня есть рабочий скрипт на python, который локально считывает файлы wav и извлекает свойства каждого файла. Я переместил все свои данные на свой FTP-сервер и не знаю, как переключить скрипт на чтение с моего FTP-сервера, а не с рабочего стола. Не уверен, важно ли для скрипта определить использование порта 21 или 22. Миллион раз спасибо

 import csv
from datetime import timedelta
from os import listdir
from os.path import isfile, join
from os.path import getctime, getatime, getmtime
from wavinfo import WavInfoReader
from time import ctime


# OUTPUT FILE HEADERS
EXTRACTED_HEADERS = ['copyright', 'product', 'album', 'genre', 'artist', 'created_date', 'title']
DURATION_HEADER = 'duration'
CREATED_TIME_HEADER = 'created_time'
MODIFIED_TIME_HEADER = 'modified_time'
ACCESS_TIME_HEADER = 'access_time'

# ERROR FILE HEADERS
FILE_NAME_HEADER = 'file_name'
ERROR_HEADER = 'error'


def get_input():
    wav_folder = input('Path to your folder: ').strip()
    while not wav_folder:
        wav_folder = input('Path to your folder is required (Exit by press Ctrl   C): ').strip()
    o_file = input('Path to your output file (default is output.csv):').strip() or 'output.csv'
    e_file = input('Path to your error file (default is error.csv): ').strip() or 'error.csv'
    return wav_folder, o_file, e_file


def write_output_file(output_list, file):
    with open(file, 'w ') as f:
        dict_writer = csv.DictWriter(f, fieldnames=[FILE_NAME_HEADER]   EXTRACTED_HEADERS   [DURATION_HEADER, CREATED_TIME_HEADER, MODIFIED_TIME_HEADER, ACCESS_TIME_HEADER])
        dict_writer.writeheader()
        for op in output_list:
            dict_writer.writerow(op)


def write_error_file(failure_list, file):
    with open(file, 'w ') as f:
        dict_writer = csv.DictWriter(f, fieldnames=[FILE_NAME_HEADER, ERROR_HEADER])
        dict_writer.writeheader()
        for fl in failure_list:
            dict_writer.writerow(fl)


def run():
    folder_path, output_file, error_file = get_input()
    only_files = [f for f in listdir(folder_path) if isfile(join(folder_path, f))]
    output = []
    failure = []
    for file_name in only_files:
        # Only parse for wav file
        if not file_name.endswith('wav'):
            continue
        properties = {
            FILE_NAME_HEADER: file_name
        }
        full_path = join(folder_path, file_name)
        try:
            # Parse Wav Info
            w = WavInfoReader(full_path, info_encoding='utf-8', bext_encoding='utf-8')
            info_dict = w.info.to_dict()
            for header in EXTRACTED_HEADERS:
                properties[header] = info_dict.get(header, '')

            # Calculate the length
            properties[DURATION_HEADER] = str(timedelta(seconds=w.data.byte_count / w.fmt.byte_rate))

            # Parse File Info
            properties[CREATED_TIME_HEADER] = ctime(getctime(full_path))
            properties[MODIFIED_TIME_HEADER] = ctime(getmtime(full_path))
            properties[ACCESS_TIME_HEADER] = ctime(getatime(full_path))
            output.append(properties)
        except Exception as e:
            failure.append({
                FILE_NAME_HEADER: file_name,
                ERROR_HEADER: str(e)
            })
    write_output_file(output, output_file)
    write_error_file(failure, error_file)


if __name__ == '__main__':
    run()
 

Комментарии:

1. Модуль «ftplib» стандартной библиотеки обеспечивает поддержку FTP-клиента. Прочитайте его документы. Если у вас есть конкретная проблема при решении этой проблемы самостоятельно, вы можете задать ее здесь.

Ответ №1:

Импортируйте эти модули в свой код:

 import ftputil
import urllib2
import shutil
import urllib.request as request
from contextlib import closing
 

и в методе запуска вместо считывания файлов с диска загрузите их и выполните остальную часть процесса:

 a_host = ftputil.FTPHost(hostname, username,passw)

for (dirname, subdirs, files) in a_host.walk("/"): # directory
    for f in files:
        if f.endswith('wav'):
            a_host.download(f, f)  # Download first
            with open(f) as txtfile:
                content = txtfile.read()
 

Комментарии:

1. Хотя такой код технически будет работать, он загрузит полный медиафайл. В то время как операция, похоже, хочет прочитать только заголовок файла. Так что это может быть совершенно неэффективно. Ну, FTP не является идеальным хранилищем для такого рода потребностей.

2. Да, я не хочу загружать какие-либо файлы

3. @hbtousa Ну, ваш модуль, который считывает информацию о файле wave (WavInfoReader), просто принимает путь к файлу с диска, чтобы прочитать его. Вы не можете получить доступ к файлам ftp таким образом. Если вы не хотите загружать на диск, вам нужно найти другой модуль, который принимает файл или объект потока вместо пути к файлу. Это еще одно решение. Я думаю, что другого выбора не будет.

4. @hbtousa, возможно, ищет этот модуль для чтения информации о файле wav, который поможет вместо WavInfoReader.