From b8cf03bfc09fbd3521f1126d6940fa6504ac42ef Mon Sep 17 00:00:00 2001 From: Martin Renvoize Date: Tue, 23 Sep 2025 20:41:09 +0100 Subject: [PATCH] Bug 38489: Standardize list_files API across all transport classes Fix API inconsistency where different transport types returned different formats from list_files(): - SFTP: returned array of hashrefs with detailed file information - FTP: returned simple array of filenames - Local: returned simple array of filenames Now all transports return an array reference of hashrefs with consistent structure containing filename, longname, and additional metadata. This eliminates the need for workarounds like the ref($file) eq 'HASH' check in EDI code and provides a more robust, consistent API. --- Koha/File/Transport/FTP.pm | 32 ++++++++++++++++++++++++++++---- Koha/File/Transport/Local.pm | 28 +++++++++++++++++++++++----- Koha/File/Transport/SFTP.pm | 5 +++-- 3 files changed, 54 insertions(+), 11 deletions(-) diff --git a/Koha/File/Transport/FTP.pm b/Koha/File/Transport/FTP.pm index 7d9c10af521..95dc1ace7ab 100644 --- a/Koha/File/Transport/FTP.pm +++ b/Koha/File/Transport/FTP.pm @@ -141,15 +141,39 @@ sub change_directory { =head3 list_files - my @files = $server->list_files; + my $files = $server->list_files; -Returns an array of filenames found in the current directory of the server connection. +Returns an array reference of hashrefs with file information found in the current directory of the server connection. +Each hashref contains: filename, longname, size, perms. =cut sub list_files { my ($self) = @_; - my $file_list = $self->{connection}->ls or return $self->_abort_operation(); + + # Get detailed listing using dir() for consistency with SFTP format + my $detailed_list = $self->{connection}->dir or return $self->_abort_operation(); + + # Convert to hash format consistent with SFTP + my @file_list; + foreach my $line ( @{$detailed_list} ) { + + # Parse FTP dir output (similar to ls -l format) + # Example: "-rw-r--r-- 1 user group 1234 Jan 01 12:00 filename.txt" + if ( $line =~ /^([d\-rwx]+)\s+\S+\s+\S+\s+\S+\s+(\d+)\s+(.+?)\s+(.+)$/ ) { + my ( $perms, $size, $date_part, $filename ) = ( $1, $2, $3, $4 ); + + # Skip directories (start with 'd') + next if $perms =~ /^d/; + + push @file_list, { + filename => $filename, + longname => $line, + size => $size, + perms => $perms + }; + } + } $self->add_message( { @@ -159,7 +183,7 @@ sub list_files { } ); - return $file_list; + return \@file_list; } =head3 rename_file diff --git a/Koha/File/Transport/Local.pm b/Koha/File/Transport/Local.pm index 22ef93bc5b3..729a7f4a13b 100644 --- a/Koha/File/Transport/Local.pm +++ b/Koha/File/Transport/Local.pm @@ -259,9 +259,10 @@ sub change_directory { =head3 list_files - my @files = $server->list_files; + my $files = $server->list_files; -Returns an array of filenames found in the current directory. +Returns an array reference of hashrefs with file information found in the current directory. +Each hashref contains: filename, longname, size, perms, mtime. =cut @@ -302,9 +303,26 @@ sub list_files { my @files; while ( defined( my $file = $dir_handle->read ) ) { - next if $file =~ /^\.\.?$/; # Skip . and .. - next unless -f File::Spec->catfile( $directory, $file ); # Only files - push @files, $file; + next if $file =~ /^\.\.?$/; # Skip . and .. + my $full_path = File::Spec->catfile( $directory, $file ); + next unless -f $full_path; # Only files + + # Get file stats for consistency with SFTP format + my @stat = stat($full_path); + my $size = $stat[7] || 0; + my $mtime = $stat[9] || 0; + my $mode = $stat[2] || 0; + + # Create permissions string (simplified) + my $perms = sprintf( "%04o", $mode & oct('07777') ); + + push @files, { + filename => $file, + longname => sprintf( "%s %8d %s %s", $perms, $size, scalar( localtime($mtime) ), $file ), + size => $size, + perms => $perms, + mtime => $mtime + }; } $dir_handle->close; diff --git a/Koha/File/Transport/SFTP.pm b/Koha/File/Transport/SFTP.pm index 192e161ef72..2424ae21e26 100644 --- a/Koha/File/Transport/SFTP.pm +++ b/Koha/File/Transport/SFTP.pm @@ -171,9 +171,10 @@ sub change_directory { =head3 list_files - my @files = $server->list_files; + my $files = $server->list_files; -Returns an array of filenames found in the current directory of the server connection. +Returns an array reference of hashrefs with file information found in the current directory of the server connection. +Each hashref contains: filename, longname, a (attributes). =cut -- 2.51.0