i implemented the roxy fileman into my tinymce editor, it works wonderfull, but i have a little bit problems with uploading files with umlauts (ä,ö,ü,ß) and so on. how to handle this problem?
Search for upload.php in your fileman/php/ dir. You will find a foreach loop starting in line 37. Inside the loop you will find the following line (should be the first line in the loop):
$filename = $_FILES['files']['name'][$k];
Insert the following code after this line:
// replace umlaute and white spaces
$filename = str_replace(' ', '-', $filename);
$filename = str_replace(utf8_decode('ä'), 'ae', $filename);
$filename = str_replace(utf8_decode('Ä'), 'Ae', $filename);
$filename = str_replace(utf8_decode('ö'), 'oe', $filename);
$filename = str_replace(utf8_decode('Ö'), 'Oe', $filename);
$filename = str_replace(utf8_decode('ü'), 'ue', $filename);
$filename = str_replace(utf8_decode('Ü'), 'Ue', $filename);
$filename = str_replace(utf8_decode('ß'), 'ss', $filename);
done.
If you want to make sure, the file name only consists of charachters that Roy Fileman can handle, you have to add the following line after the umlaute-conversion.
$filename = preg_replace('/[^A-Za-z0-9\-_.]/', '-', $filename);
This remove all sorts of accents and special charachters without a replacement. If you want to convert more language specific characters (e.g. é, è, ê => e), you can add more str_replace lines.
Related
I am unable to extract the last digits in the filename and rename the file placing the digits at the beginning of the file.
Like suppose my file name is "Gen_TCC_TIF_2110_413010_L3TL_Ae6TL707285_371925.out"
I want to rename the file as "371925_Gen_TCC_TIF_2110_413010_L3TL_Ae6TL707285.out"
my $newFileName ='Gen_TCC_TIF_2110_413010_L3TL_Ae6TL707285_371925.out';
my ($digits) = $newFileName =~ /(\d+)/g;
my $newFileName_2="${digits}_Gen_TCC_TIF_2110_413010_L3TL_Ae6TL707285_371925.out"
try:
$newFileName =~ /(\d+)\.out/;
my $digits = $1;
my $newFileName_2=$digits."_Gen_TCC_TIF_2110_413010_L3TL_Ae6TL707285_371925.out";
(\d+)\.out/ should give you all Digits before .out
Try this:
$newFileName =~ s/(.*?)_(\d+)\.out/$2_$1\.out/;
Or
$newFileName =~ s/(.*?)_(\d+)(\.\w+)/$2_$1$3/;
You can do it with a single regex:
my $newFileName = 'Gen_TCC_TIF_2110_413010_L3TL_Ae6TL707285_371925.out';
my $newFileName_2 = $filename =~ s/(.*)_(\d+)(?=\.out)/$2_$1/r;
# or, for older Perl, use this instead:
(my $newFileName_2 = $filename) =~ s/(.*)_(\d+)(?=\.out)/$2_$1/;
# or, to modify directly the variable $newFileName:
$newFileName =~ s/(.*)_(\d+)(?=\.out)/$2_$1/;
Or if you want to get the digits (because you need them for something else), then you can do:
my ($digits) = $newFileName =~ /_(\d+)\.out/;
You were using /g modifier, which made your regex match all blocks of digits, which isn't what you wanted. (even worst, it was returning an array, but you were only keeping the first element (2110) in the scalar $digit )
I need to be able to propose files to be downloaded but i have to read and print the file in my CGI. I tried to go for :
#!/usr/bin/perl -w
use strict;
push( #INC, $lib_directory );
require 'lib_utils.pl';
dl_file('/tmp/final.pdf');
as main page (dl.pl) and
sub dl_file {
my ($file) = #_;
if ( ! -e $file) {
print "file does not exist";
return 0;
}
my $content = read_file( $file, binmode => ':utf8' ) ;
$file =~ m#(.*)([^/]*)$#;
my $directory = $1;
my $filename = $2;
chdir $directory;
my $form = new CGI;
print $form->header(
-type => 'application/octet-stream',
-attachment => $filename,
-filename => $filename,
-Content-Disposition => "attachment; filename=$filename",
);
$form->print($content);
return 1;
}
for the called function. Funny thing is, this code workes just fine if i dont go for a sub and have all the code in dl.pl BUT as soon as i move the code in a sub, the downloaded file is called after the script (ie dl.pl)
How would you change it or how would you do ?
Thanks in advance for your help
Your line
$file =~ m#(.*)([^/]*)$#
will leave $1 containing the whole of $file and $2 empty. You need a slash in there somewhere, probably like this
$file =~ m#(.*)/([^/]*)$#
It would also make sense to make the directory optional, like so
$file =~ m#(?:(.*)/)?([^/]*)$#
my $directory = $1;
and you would have to write
chdir $directory if $directory
This is what's tripping you up:
$file =~ m#(.*)([^/]*)$#;
Looks like you're trying to split "/tmp/final.pdf" into directory and file. But you don't - that pattern splits you into:
print "F:",$filename,"\n";
print "D:",$directory,"\n";
this output:
F:
D:/tmp/final.pdf
This is why you have the problem - you don't have a filename, so it defaults to using the script name.
I would suggest instead you want:
my ( $directory, $filename ) = ( $file =~ m,(.*/)([\.\w]+)$, );
This gives:
F:final.pdf
D:/tmp/
As has been said, you're suffering from the greedy matching of .* which will eat up the entire string:
$file =~ m{(.*)([^/]*)$};
There are three easy solutions to this
1. Boundary Conditions
As has been stated, you can add a boundary condition that limits how much .* can match:
$file =~ m{(?:(.*)/)?([^/]*)$};
my $dir = $1 // '';
my $filename = $2;
Or this somewhat convoluted lookbehind assertion can also enforce a boundary:
$file =~ m{(.*)(?<![^/])([^/]*)$};
my $dir = $1;
my $filename = $2;
2. Non-greedy matching
However, the simplest regex solution is to use non-greedy matching .*?:
$file =~ m{(.*?)([^/]*)$};
my ($dir, $filename) = ($1, $2);
Basically, anytime you're about to put .* anywhere, check your assumptions. The majority of the time you'll actually want .*? instead.
3. Module for parsing file paths
The bonus option is just to use a module like File::Spec parsing file path information
use File::Spec;
my ($vol, $dirs, $filename) = File::Spec->splitpath( $file );
I am using the Text::CSV module to parse lines into various fields from a tab-separated value file.
Examples of special characters in strings are
"CEZARY Å?UKASZEWICZ, PAWEÅ? WIETESKA","BÜRO FÜR"
My code goes as below:
my $file = $ARGV[0] or die "Need to get TSV file on the command line\n";
my $csv = Text::CSV->new({sep_char => "\t"});
open(my $data,'<', $file) or die "Could not open '$file' $!\n";
while (my $line= <$data>) {
if($csv->parse($line)){
my #curr_arr = $csv->fields();
}
} # end of while
close $data;
The above is some of the important parts of my code. The error I get is as follows:
cvs_xs error : 2026 - EIQ - Binary Character inside quoted field, binary off #pos 15
my $csv = Text::CSV->new({ binary => 1, sep_char => "\t"});
I'm trying to read a file which has only CR as line delimiter. I'm using Mac OS X and Perl v.5.8.8. This script should run on every platform, for every kind of line delimiter (CR, LF, CRLF).
My current code is the following :
open(FILE, "test.txt");
while($record = <FILE>){
print $record;
}
close(TEST);
This currently print only the last line (or worst). What is going on?
Obvisously, I would like to not convert the file. Is it possible?
You can set the delimiter using the special variable $/:
local $/ = "\r" # CR, use "\r\n" for CRLF or "\n" for LF
my $line = <FILE>;
See perldoc perlvar for further information.
Another solution that works with all kinds of linebreaks would be to slurp the whole file at once and then split it into lines using a regex:
local $/ = undef;
my $content = <FILE>;
my #lines = split /\r\n|\n|\r/, $content;
You shouldn't do that with very large files though, as the file is read into memory completely. Note that setting $/ to the undefined value disables the line delimiter, meaning that everything is read until the end of the file.
I solved a more general problem that could be useful here:
How to parse big file line-by-line with any line delimiter (CR/CRLF/LF), but unknown beforehand.
'Big' file means that it is not ok to read the whole file into one variable. Here function 'detectEndOfLine' gets name of file and returns either '\r' or '\n', whatever is used for line ending (it searched for '\r' or '\n' symbol char-by-char starting from the end of the file).
my $file = "test.txt";
local $/ = detectEndOfLine($file);
open(IN, $file) or die "Can't open file \"$file\" for reading: $!\n";
while(<IN>) {
s/\r\n|\n|\r$//;
print "$_\n";
}
sub detectEndOfLine {
my $file = $_[0];
my $size = -s $file;
print "\"$size\"\n";
open(IN, $file) or die "Can't open file \"$file\" for reading: $!\n";
for(my $i = $size; $i >= 0; --$i) {
seek(IN, $i, 0);
$_ = <IN>;
my $sym = substr($_, 0, 1);
return $sym if( $sym eq "\n" or $sym eq "\r" );
}
return undef;
}
I have a file in a different folder I want to rename in perl, I was looking at a solution earlier that showed something like this:
#rename
for (<C:\\backup\\backup.rar>) {
my $file = $_;
my $new = $file . 'backup' . $ts . '.rar';
rename $file, $new or die "Error, can not rename $file as $new: $!";
}
however backup.rar is in a different folder, I did try putting "C:\backup\backup.rar" in the <> above, however I got the same error.
C:\Program Files\WinRAR>perl backup.pl
String found where operator expected at backup.pl line 35, near "$_ 'backup'"
(Missing operator before 'backup'?)
syntax error at backup.pl line 35, near "$_ 'backup'"
Execution of backup.pl aborted due to compilation errors.
I was using
# Get time
my #test = POSIX::strftime("%m-%d-%Y--%H-%M-%S\n", localtime);
print #test;
To get the current time, however I couldn't seem to get it to rename correctly.
What can I do to fix this? Please note I am doing this on a windows box.
Pay attention to the actual error message. Look at the line:
my $new = $_ 'backup'. #test .'.rar';
If you want to interpolate the contents of $_ and the array #test into a string like that, you need to use:
my $new = "${_}backup#test.rar";
but I have a hard time making sense of that.
Now, strftime returns a scalar. Why not use:
my $ts = POSIX::strftime("%m-%d-%Y--%H-%M-%S", localtime);
my $new = sprintf '%s%s%s.rar', $_, backup => $ts;
Incidentally, you might end up making your life much simpler if you put the time stamp first and formatted it as YYYYMMDD-HHMMSS so that there is no confusion about to which date 04-05-2010 refers.
The line
my $new = $_ 'backup'. #test .'.rar';
probably should read
my $new = $file . 'backup' . #test . '.rar';
(You were missing a concatenation operator, and it is clearer to use the named variable from the line before than reusing $_ there...)
I think you missed the string concat symbol . (the period) :
my $new = $_ 'backup'. #test .'.rar';
should be
my $new = $_ . 'backup' . #test . '.rar';
A slight side issue but you don't need
for (<C:\\backup\\backup.rar>) {
my $file = $_;
.....
}
The < > construct would be useful if you were expanding a wildcard but you are not.
Be thoughtful of future readers of this code (you in a year!) and write
my $file = 'C:\backup\backup.rar' ;
Note the single quotes which doen't expand backslashes.