2013-08-14 2 views
0

Я пытаюсь использовать найденный скрипт here, написанный на Perl, но в нем возникает ошибка. Я уже связался с автором, но пока не получил ответа. Я надеюсь, что ты поможешь мне.Изменение скрипта Perl с ошибками, обрабатывающих пробелы в файлах

Ошибка заключается в следующем:

ERROR: unable to copy /home/bruno321/.config/Clementine/albumcovers/271b13967f57caba893b366730337fb03439c60a.jpg to /media/mp3_1/Musica/Amarok/Two%20Lone%20Swordsmen/A%20Bag%20of%20Blue%20Sparks/. error: File or directory does not exist

Я считаю, что ошибка в обработке пространства, так как в каталогах, которые не имеют места, которые выполняет хорошо, однако это не переименовать файл в " cover.jpg ", как я полагаю, сценарий намеревается сделать (и мне это обязательно нужно сделать).

#!/usr/bin/perl 

use strict; 
use warnings; 
use Carp; 

use DBI; 
use strict; 

use Data::Dumper; 
use File::Basename; 
use File::Copy; 

my $db_filename = shift(@ARGV); 
$db_filename 
    || croak 
"missing mandatory param: sqlite filename\n(try ~/.config/Clementine/clementine.db\n"; 

if (!-f $db_filename) { 
    croak "no such database file: $db_filename\n"; 
} 

my $force_rewrite = shift(@ARGV) || 0; 

my $dbh = 
    DBI->connect("dbi:SQLite:$db_filename", q{}, q{}, 
    { 'RaiseError' => 1, 'AutoCommit' => 1 }); 

my $query = q{SELECT artist,album, art_automatic,art_manual,filename 
      FROM songs WHERE art_manual IS NOT NULL GROUP BY(album) ORDER BY artist}; 

my $sth = $dbh->prepare($query); 
$sth || croak 'prepare error: ' . $dbh->errstr . "\n"; 

$sth->execute || croak 'execute error: ' . $dbh->errstr . "\n"; 

my %treated =(); 
while (my $res = $sth->fetchrow_hashref) { 

    (undef, my $dest_dir, undef) = fileparse($res->{'filename'}); 

    next if $treated{$dest_dir}; 
    $treated{$dest_dir}++; 

    # strip leading file:// -> should do this better 
    $dest_dir =~ s/^file:\/\///g; 

    my $dest_file = $dest_dir . 'cover.jpg'; 

    # unless we are given overwrite option, skip dirs that have covers 
    if (!$force_rewrite) { 
     next if (-f $dest_file); 
    } 

    #print "CMD: cp $res->{'art_manual'} $dest_file\n"; 
    copy($res->{'art_manual'}, $dest_dir) 
     || printf("ERROR: unable to copy %s to %s. error: %s\n", 
     $res->{'art_manual'}, $dest_dir, $!); 
} 
exit; 
+3

В этом названии нет пробелов. Сообщение об ошибке ясно; каталог назначения не существует. – tripleee

+0

@ tripleee: Но это действительно так! Ну, по крайней мере, заменив% 20 на пробелы. Чтобы быть более ясным, на нескольких папках, которые не имеют пробелов, он работает хорошо, за исключением того, что он копирует файл дословно, а не переименовывает его в «cover.jpg», как я полагаю, он предназначен. –

ответ

7

Видимо $dest_dir является URL-закодирован, где вам это нужно, чтобы быть буквальным. Другими словами, после обрезки префикса file:// вам необходимо декодировать любые гексагональные экраны %NN в соответствующий литерал. См Using Perl, how do I decode or create those %-encodings on the web? В принципе, вы хотите

use URI::Escape 'uri_unescape'; 

, а затем

$dest_dir = uri_unescape($dest_dir); 

Кроме того, вы создаете $dest_file но игнорируя его и скопировать файл на $dest_dir вместо в конце концов.

В качестве дополнительной стилистической проблемы предупреждения и ошибки должны идти на stderr, а не на stdout.

+0

Спасибо! Я изменяю это в коде. Где я должен изменить '$ dest_dir' на' $ dest_file', чтобы скопировать файл так, как я этого хочу? –

+0

Nevermind, я изменил его в двух последних случаях, и это сработало чудеса. Большое спасибо, тройной! –