Beefy Boxes and Bandwidth Generously Provided by pair Networks
good chemistry is complicated,
and a little bit messy -LW
 
PerlMonks  

File::Basename and File::MMagic for File Downloads from Website

by agent00013 (Pilgrim)
on Nov 21, 2008 at 00:11 UTC ( [id://725027]=perlquestion: print w/replies, xml ) Need Help??

agent00013 has asked for the wisdom of the Perl Monks concerning the following question:

Hello Monks,

I am working on a script that allows users to download files from a website to their computer. Unfortunately, the original file name has been stored using the name sent by the uploading browser and OS.

This means file names could be any of the following.

Examples:
Z:\my_files\docs\some_kind_of_manual.pdf
myfile.docx
/home/someguy/file.txt

My hope is to get the actual file name regardless of which operating system/browser uploaded the file. If I understand correctly, File::Basename assumes the filename is using the same operating system as the server which isn't necessarily true in this situation.

My question is: will fileparse() work properly anyway with any of these types of filenames if all I need is the $name of the file?
#!/usr/bin/perl use strict; use File::Basename; use File::MMagic; #skip some code here... my ($name,$path,$suffix) = fileparse($filename); my $mm = File::MMagic->new('/usr/share/file/magic'); my $mimetype = $mm->checktype_byfilename($name); print "Content-type: $mimetype\n"; print "Content-Disposition: attachment; filename=\"$name\"\n\n"; #other code goes here to output file...
Thanks for your help.

(Running Perl 5.8.8 on Debian Etch)

Replies are listed 'Best First'.
Re: File::Basename and File::MMagic for File Downloads from Website
by ikegami (Patriarch) on Nov 21, 2008 at 00:23 UTC

    I don't know about all file systems — we had a computer whose file system consisted of a piece of a paper with file names and sector addresses at my last job — but File::Basename treats at least "\" (Windows), "/" (unix and Windows) and ":" (old Macs) as separators.

    >perl -MFile::Basename -le"print basename 'foo/bar'" bar >perl -MFile::Basename -le"print basename 'foo\bar'" bar >perl -MFile::Basename -le"print basename 'foo:bar'" bar

    File::Basename's behaviour is not determined by the system on which the script is executed.

      I am not getting the same results. On my Debian machine, I get the following output using some of the examples.
      > perl -MFile::Basename -le "print basename 'foo/bar'" bar > perl -MFile::Basename -le "print basename 'Z:\my_files\docs\some_kin +d_of_manual.pdf'" Z:\my_files\docs\some_kind_of_manual.pdf > perl -MFile::Basename -le "print basename '/home/someguy/file.txt'" file.txt

        Sorry, it had been a while. It does behave in a system-specific fashion.

        Technically, what you ask is impossible. 'foo\bar' should return 'foo\bar' if a unix path and 'bar' if a Windows path, but you don't know what kind of path your client built. That means you might as well roll out code that does what you want it to do.

        my $basename = ( split /[:\/\\]/, $_ )[-1];
      we had a computer whose file system consisted of a piece of a paper with file names and sector addresses at my last job

      How long has it been since you have changed jobs? My architecture professor used that as an example of how the OS has come to mask out the hardware differences at least 15 years ago. The example he was using was from long before that, in his younger days.

      --MidLifeXis (not sure if he is hiding grey in his blond locks yet)

        Recently, but that's not relevant. Said computer is still in use, controlling a nuclear reactor. It's a replica of a 1972 computer. (36 years!) It has 64KB of RAM, but since it's only word addressable, it has only 32K addresses. I can't remember what it has for disk space, but we're talking about a few of MB max. (I think 3MB up from an original 1MB.)

        It has a custom made OS called "the Executive" or "EXEC" after it's file name. You can't exactly load linux on it. EXEC provided I/O functions and some library functions. A file system was deemed unnecessary.

        Alarming (logging) is done to a CRT (which won't clear even if something happens to the computer) and to a printer. The computer can also talk to PC that pretends to be a paper tape device.

Re: File::Basename and File::MMagic for File Downloads from Website
by fmerges (Chaplain) on Nov 21, 2008 at 04:16 UTC

    Hi,

    You can try like this:

    use strict; use FileUpload::Filename; # Usually used in combination with the upload handler, so it will be # implicitely set. $ENV{HTTP_USER_AGENT} = 'Mozilla/4.0 (compatible; MSIE 7.0; Windows NT + 5.1; .NET CLR 2.0.50727; Zune 2.0)'; my $name = FileUpload::Filename->name({ filename => 'Z:\my_files\docs\some_kind_of_manual.pdf', }); print "[$name]\n"; $name = FileUpload::Filename->name({ filename => '/home/someguy/file.txt', }); print "[$name]\n"; $name = FileUpload::Filename->name({ filename => 'home:anotherguy:A Music Song.mp3', }); print "[$name]\n";

    Output:

    [some_kind_of_manual.pdf] [file.txt] [A_Music_Song.mp3]

    Curiously with the agent set as IE, it works for the three inputs :-)

    Regards,

    fmerges at irc.freenode.net

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://725027]
Approved by planetscape
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others imbibing at the Monastery: (4)
As of 2024-03-29 08:53 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found