Beefy Boxes and Bandwidth Generously Provided by pair Networks
The stupid question is the question not asked
 
PerlMonks  

Web month Calander

by Ryszard (Priest)
on Nov 22, 2001 at 14:26 UTC ( #126950=perlquestion: print w/ replies, xml ) Need Help??
Ryszard has asked for the wisdom of the Perl Monks concerning the following question:

I'm writing a web based calander, and want to display a month (or more) in a html table, add links and pull out whatever data is associated with the link (ala the yahoo datebook).

Now i've got it printing out a nice little table with all the dates in the correct spots etc, (which is good) but i'm iterating thru' three loops. one to pull out the days, one to build a monthly matrix (much like the `cal` command), and the final loop builds the html.

I'm thinking this is pretty slow and inefficient, and was wondering if there is a better way.

I thought of using a hash for the number of days in a month (and making the appropriate exceptions for a LY, then determining what day is the 1st of the month) however i'm still stuck with two loops.

Naturally any comments on the style of the code appreciated.

#!/usr/bin/perl -w use strict; use Data::Dumper; use Date::Calc qw( Delta_Days Add_Delta_Days Date_to_Text ); use CGI; my $q = new CGI; sub date_range { my(@date) = (@_)[0,1,2]; my(@list); my($i); my $output = ''; my $date; my %pos = (Su=>1, Mo=>2, Tu=>3, We=>4, Th=>5, Fr=>6, Sa=>7 ); my @box; $i = Delta_Days(@_); while ($i-- >= 0) { push( @list, [ @date ] ); @date = Add_Delta_Days(@date, 1) if ($i >= 0); } #build the matrix to hold the days. my @box; #the arrray to hold the calendar data my $row=0; foreach $date (@list) { my $col = $pos{substr(Date_to_Text(@{$date}),0,2)}; $box[$row][$col]= (@{$date}[2]); if ($col eq 7) {$row++} } for (my $i=0; $i<5; $i++){ $output .= "<tr>"; for (my $j=0; $j<8;$j++){ if (! defined $box[$i][$j]) { $output .= $q->td({align=>"right"},"&nbsp"); } else { $output .= $q->td({align=>"right"},$box[$i][$j]); } } $output .= "</tr>"; } return $output; } print $q->header(); print $q->table(&date_range(2001,11,1, 2001,11,30)); # in chronologica +l order

Comment on Web month Calander
Download Code
Re: Web month Calander
by growlf (Pilgrim) on Nov 22, 2001 at 15:34 UTC
    Hmm, is there a reason not to use HTML::CalendarMonth? Like so:



    Updated (removed html-assubs, since CGI does all this anyhow)

    #!/usr/bin/perl -w use strict; use HTML::CalendarMonth; use CGI; my $page = new CGI; my $calendar = HTML::CalendarMonth->new(); # Lets do some customization here, since today IS thanksgiving after a +ll $calendar->item($calendar->year, $calendar->month)->attr(bgcolor => '# +FF8000'); $calendar->item(22)->attr(bgcolor => '#FFD080'); $calendar->item(22)->wrap_content( new HTML::Element 'a', href => 'http://www.openresources.com/cgi-bin/ +dict?Form=dict2&Database=*&Query=Thanksgiving+Day', target=> '_blank'); print $page->header(); print $calendar->as_HTML;
    This results in a nice little calendar with alot of options already built for you like so:
    November2001
    SuMTuWThFSa
            123
    45678910
    11121314151617
    18192021222324
    252627282930 

    Please forgive the blatent and almost unhidden plagerism from PerlDoc.com

    *G*

      the only reason was ignorance! i had no idea it existed. sometimes i just launch head-long into things, without doing decent research beforehand.

      thanks for the tip

      In the interest's of efficiency, i'm still interested in how the above code could by modified.
(crazyinsomniac) Re: Web month Calander
by crazyinsomniac (Prior) on Nov 22, 2001 at 19:39 UTC
    Well here's one way to modify it (take advantage of CGI.pm's table generating capabilities, and use map -- don't wanna look at Date::Calc at the moment, maybe tomorrow ;D)
    #!/usr/bin/perl -w use strict; use Data::Dumper; use Date::Calc qw( Delta_Days Add_Delta_Days Date_to_Text ); use CGI; my $q = new CGI; sub date_range { my(@date) = (@_)[0,1,2]; my(@list); my($i); my $output = ''; my $date; my %POS = (Su=>1, Mo=>2, Tu=>3, We=>4, Th=>5, Fr=>6, Sa=>7 ); $i = Delta_Days(@_); while ($i-- >= 0) { push( @list, [ @date ] ); @date = Add_Delta_Days(@date, 1) if ($i >= 0); } #build the matrix to hold the days. my @box; #the arrray to hold the calendar data my $row=0; foreach $date (@list) { my $col = $POS{substr(Date_to_Text(@{$date}),0,2)}; $box[$row][$col]= (@{$date}[2]); $row++ if ($col == 7); } ## for the header ## &nbsp; is in here because array indices start at 0, not one ## and I didn't feel like modifying your code above (-1) $output.= $q->Tr( [ $q->th( [ qw( &nbsp; Su Mo Tu We Th Fr Sa) ] ) ] ); ## gets warnings, since you don't init the array #$output.= join '', map { $q->Tr( [ $q->td( [ @{$_} ]) ] ) } @box +; ## no warnings, cause i test for definedness $output.= join '', map { $q->Tr( [ $q->td( [ map { defined $_ ? $_ :" " } @{$_} ,] ,) ,] ,) } @box; } print $q->header(); ## since => is just a fancy comma, print $q->table( &date_range(2001,11,1 => 2001,11,30) ); ## or for even "better" readability print $q->table( &date_range(qw/2001 11 1/ => qw/2001 11 30/) ); __END__ Yielding the following:
    Content-Type: text/html; charset=ISO-8859-1
      Su Mo Tu We Th Fr Sa
    1 2 3
    4 5 6 7 8 9 10
    11 12 13 14 15 16 17
    18 19 20 21 22 23 24
    25 26 27 28 29 30

     
    ___crazyinsomniac_______________________________________
    Disclaimer: Don't blame. It came from inside the void

    perl -e "$q=$_;map({chr unpack qq;H*;,$_}split(q;;,q*H*));print;$q/$q;"

Re: Web month Calender
by jlongino (Parson) on Nov 22, 2001 at 22:38 UTC
    Ryszard, it looks to me that you are well on your way. I've modified/written something similar for our University calendar that you might want to look at for some ideas on layout. It provides several different views (6-month calendar, plain-text monthly, weekly and daily views). The link is USA Campus Calendar. I borrowed the core 6-month view code from an Ill. University (Urbana, I think, with their permission of course). It reads directly from the xnix cal command.

    I don't really see that the speed to create the calendar table itself will present much of a bottleneck. It is more likely that fetching your data will take much more time (depending on your method), particularly if you have to retrieve data dynamically from Yahoo. You might want to consider a batch process that periodically updates a database or series of files (one file per event). The series of files method is the one I used since our events are generated manually at our site (through a Web interface). Unfortunately, we don't have a hit counter in place, so I can't say exactly how much it is used.

    If you are interested in seeing some of my code, I can post it to my scratch pad. Particularly how the 6-month view is generated.

    As far as your code goes, the only thing that some people might recommend is changing your  for (;;){} loops to  for (..){} loops. But I don't think in this case that it is objectionable (besides, the code that I modified/wrote uses them and doesn't utilize CGI table building methods as you have, so I'm not worthy to complain).

    Good luck finishing your project!

    --Jim

      hey jlongino thanks for the comments.

      You're right. IRT (In Real Time) the routine prolly wouldnt pose much of a performance threat, however it looks messy and i'm sure there are ways to optimise it. The back end is actually a Postgresql database, so that's where i'm thinking there will be some performance hit.

      crazyinsomniac posted some cool CGI.pm stuff i really didnt have a good handle on before.

      The project is fun, (as well as practical). I'm basically writing a personal web portal, with addrbk, datebk, ToDo, and notes interfacing with my palm pilot.

      I'm also thinking of writing a 'file-manager' type interface (using the pilot-xfer tools), as well as some kind of avantgo syncing (with a malsync backend).

      I've pretty much done all the session management, and addressbook thus far and am about 20% into the datebk.

      As you can see I suffer from feature creep. I should concentrate on the datebk before things get out of hand.. :-)

Log In?
Username:
Password:

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

How do I use this? | Other CB clients
Other Users?
Others browsing the Monastery: (5)
As of 2015-07-06 09:04 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    The top three priorities of my open tasks are (in descending order of likelihood to be worked on) ...









    Results (70 votes), past polls