For Programmers: Free Programming Magazines  


Home > Archive > PERL CGI Beginners > December 2004 > Save as a file









You are viewing an archived Text-only version of the thread. To view this thread in it's original format and/or if you want to reply to this thread please [click here]

 

Author Save as a file
Jan Eden

2004-12-15, 3:55 pm

Hi,

I have some content stored within a database, which I want to be saved as a=
file on the user's system when requested. Currently, I generate a temporar=
y file (timestamp_fileid.tex) and use a cron job to clean up the directory =
every 30 minutes:

if ($texcontent) {
my $texfile =3D texer($texcontent, $id);
print qq{<a class=3D"image" href=3D"../tmp/$texfile" target=3D"_sel=
f"><img src=3D"../gifs/latex.jpeg" alt=3D"latex_version" width=3D"70" heigh=
t=3D"37" border=3D"0" /></a>};
}

sub texer {
my ($texcontent, $page_id) =3D @_;
my ($page_id_safe) =3D $page_id =3D~ /(.+)/;
my $filename =3D time . "_$page_id_safe.tex";
chdir "../tmp";
open (FILE, "> $filename") or die "Cannot open file for writing: $!";
print FILE $texcontent;
close (FILE);
chdir "../cgi-bin";
return $filename;
}

How can I make the user's browser

a) save the file instead of just printing its content to the screen (as wit=
h the header text/plain), so I do not need to use a temporary file

b) use a certain filename when saving the file instead of displaying a savi=
ng dialog?

Thanks,

Jan
--=20
Imagine if every Thursday your shoes exploded if you tied them the usual wa=
y. This happens to us all the time with computers, and nobody thinks of com=
plaining. - Jeff Raskin
Lawrence Statton

2004-12-15, 3:55 pm

> Hi,
>
> I have some content stored within a database, which I want to be saved as a f
> ile on the user's system when requested. Currently, I generate a temporary fi
> le (timestamp_fileid.tex) and use a cron job to clean up the directory every
> 30 minutes:


Using timestamp is a poor technique for forming unique filenames.
Someday, you *WILL* get two requests in the same second. Use
File::Temp. Even better -- don't use a file at all. I generate PDF
and Excel spreadsheets all the time, and I never write them out to files.

>
> if ($texcontent) {
> my $texfile = texer($texcontent, $id);
> print qq{<a class="image" href="../tmp/$texfile" target="_self"><img
> src="../gifs/latex.jpeg" alt="latex_version" width="70" height="37" border="0
> " /></a>};
> }
>
> sub texer {
> my ($texcontent, $page_id) = @_;
> my ($page_id_safe) = $page_id =~ /(.+)/;
> my $filename = time . "_$page_id_safe.tex";
> chdir "../tmp";
> open (FILE, "> $filename") or die "Cannot open file for writing: $!";
> print FILE $texcontent;
> close (FILE);
> chdir "../cgi-bin";
> return $filename;
> }
>
> How can I make the user's browser
>
> a) save the file instead of just printing its content to the screen (as with
> the header text/plain), so I do not need to use a temporary file


In your headers, you want to put something like

Content-type: application/x-tex
Content-disposition: attachment; filename="custom-file.tex"

>
> b) use a certain filename when saving the file instead of displaying a saving
> dialog?


The browswer will *ALWAYS* open a dialog, but it should be `primed'
with the name you have suggested.

>
> Thanks,
>
> Jan


-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
Lawrence Statton - lawrenabae@abaluon.abaom s/aba/c/g
Computer software consists of only two components: ones and
zeros, in roughly equal proportions. All that is required is to
sort them into the correct order.
Jan Eden

2004-12-15, 3:55 pm

Lawrence Statton wrote on 15.12.2004:

>
>Using timestamp is a poor technique for forming unique filenames.
>Someday, you *WILL* get two requests in the same second. Use
>File::Temp. Even better -- don't use a file at all. I generate PDF
>and Excel spreadsheets all the time, and I never write them out to
>files.
>

I know, this was just intended as a preliminary solution. It is not in prod=
uction use.

>
>In your headers, you want to put something like
>
>Content-type: application/x-tex Content-disposition: attachment;
>filename=3D"custom-file.tex"
>

The Content-disposition header was what I was looking for. Thank you! I wil=
l do some testing with these options.

Cheers,

Jan
--=20
These are my principles and if you don't like them... well, I have others. =
- Groucho Marx
Jan Eden

2004-12-15, 8:55 pm

Hi Lawrence,

Lawrence Statton wrote on 15.12.2004:

>
>
>Here's a trivial example to get you started
>
>#!/usr/bin/perl=20
>use strict;
>use warnings;
>
>use CGI;
>
>my $query =3D new CGI;
>
>print $query->header(-type =3D> 'text/plain',=20
> content_disposition =3D> 'attachment; filename=3D"foo=

=2Etxt"');

Thank you. Two out of three browsers I tested (IE 5/Mac, Safari) ignore the=
content-disposition header if the content-type is set to text/plain. It do=
es work with the application/x-tex type you mentioned in your earlier messa=
ge.

Although the browsers are supposed to ignore the content-type if they recei=
ve the content-disposition header, only Firefox seems to honor this.

Thanks again,

Jan
--=20
Imagine if every Thursday your shoes exploded if you tied them the usual wa=
y. This happens to us all the time with computers, and nobody thinks of com=
plaining. - Jeff Raskin
Sponsored Links







Also available: Server administration forum archive | Web Design forum archive | Software forum archive | Hardware reviews archive

Copyright 2008 codecomments.com