Gossamer Forum
Home : Products : Gossamer Links : Version 1.x :

Site of the Day Mod -> Links SQL v.1.11

Quote Reply
Site of the Day Mod -> Links SQL v.1.11
The following script can be used for Links SQL v.1.11. It may work in other versions, but it has only been tested with Links SQL 1.11.

Code:

#!/usr/local/bin/perl
# ==============================================================
# Script Title : Site of the Day Mod
# Script Name : siteday.cgi
# Description : Extracts a Random Link and Prints it in any page
# Author : Anthro TECH, L.L.C, Copyright 2000
# Web Site : http://www.anthrotech.com/
#
# Disclaimer : This script is freeware and will work with LINKS
# SQL v.1.11. This script is to be used at your
# own risk. Anthro TECH does not assume any
# liability of corruption of your Links database
# or web site.
###############################################################

# Load required modules.
# ---------------------------------------------------
use strict;
use vars qw/%in/;
use CGI ();
use CGI::Carp qw/fatalsToBrowser/;
use lib '/absolute/path/to/admindirectory';
use Links::Links;
use Links::DB_Utils;
use Links::HTML_Templates;
use Links::DBSQL;
$|++;

&main();

sub main {
#-----------------------------------------------------------
# Main subroutine of script.

my $in = new CGI;
my $dynamic = $in->param('d') ? $in : undef;
%in = %{&cgi_to_hash ($in)};
my ($id, $category, $getcat, $name, $offset, $total, $rec, $sth, $LINKDB);
print $in->header('text/html');

# Connect to Database
$LINKDB = new Links::DBSQL "$LINKS{admin_root_path}/defs/Links.def";

# Get the random line in the database
$total = $LINKDB->total();
$offset = int rand $total;
$sth = $LINKDB->prepare ( " SELECT * FROM Links LIMIT $offset, 1 ");
$sth->execute() or die $DBI::errstr;
$rec = $sth->fetchrow_hashref;
$id = $rec->{'ID'};

# Get Record to display
$rec = $LINKDB->get_record ($id, 'HASH');
$getcat = $rec->{'CategoryID'};
$name = &get_category_name ($getcat);
$category = &build_clean_name ($name);
$rec or &site_html_error ({error => "Can't Find Random Link."}, $in, $dynamic);

# Prints record to Site of Day file.
open (PAGE, ">$LINKS{db_siteday_file}") or &site_html_error ({error => "Unable to open textfile: $LINKS{db_siteday_file}. Reason: $!"}, $in, $dynamic);
print PAGE &site_html_day ({Category => $category, %$rec});
close PAGE;

# Confirmation message
print qq|Site of the Day Added: ${$rec}{'Title'}|;
}


You will also have to do the following:

1) Create a subroutine in the HTML_Templates.pm file. (Don't forget to add &site_html_day in the @EXPORT array.

Code:

sub site_html_day {
# --------------------------------------------------------
# This routine builds special list of links for Last Link

my ($rec, $dynamic) = @_;
my $template = defined $dynamic ? $dynamic->param('t') : undef;
(ref $rec eq 'HASH') or croak "HTML_TEMPLATES: Argument '$rec' must be hash reference";

# Set new and pop and award to either 1 or 0 for templates.
($rec->{'isNew'} eq 'Y') ? ($rec->{'isNew'} = 1) : (delete $rec->{'isNew'});
($rec->{'isChanged'} eq 'Y') ? ($rec->{'isChanged'} = 1) : (delete $rec->{'isChanged'});
($rec->{'isPopular'} eq 'Y') ? ($rec->{'isPopular'} = 1) : (delete $rec->{'isPopular'});

# Figure out how many days old it is if it's a new link.
if ($LINKS{build_days_old}) {
if ($rec->{'isNew'}) {
$rec->{'Days_Old'} = &Links::DBSQL::date_diff (&Links::DBSQL::get_date(), $rec->{'Add_Date'});
}
else {
$rec->{'Days_Old'} = '';
}
}
my $user = {};
defined $dynamic and &load_user ($dynamic, $user, $rec->{CategoryID});
my $output = &load_template ('siteofday.html', {
%$rec,
%$user,
%GLOBALS
}, undef, $template);
# Don't clean output on a single link.
return $output;
}


2) Add a template file in your templates directory called siteofday.html. This file can contain all tags for fields located in the Links table.

Note: I have included codes for linking the Category that the link is located in by using the <%Category%> tag.

Like the following:

Code:

<a href="/<%Category%>/"><%Category%></a>


3) You will have to add the following variable to your Links.pm file:

Code:

$LINKS{db_siteday_file} = "$LINKS{build_root_path}/siteday.txt";


4) Then create a file called siteday.txt. This should be placed in your $LINKS{build_root_path} directory and the permission of the file should be 666 (rw-rw-rw-).

5) Then use the following tag in any of your template pages:

Code:

< !--#include virtual="/siteday.txt"-- >


Note: Don't forget to close the spaces before and after the < and >.

You can execute this script via Cron or Windows Scheduler Program everyday to have a true site of the day.

Hope this helps and works for you.

Regards,

Eliot Lee

Quote Reply
Re: Site of the Day Mod -> Links SQL v.1.11 In reply to
To use the #include directives, you'll also need to have SSI enabled and working.



http://www.postcards.com
FAQ: http://www.postcards.com/FAQ/LinkSQL/

Quote Reply
Re: Site of the Day Mod -> Links SQL v.1.11 In reply to
Well done, Eliot!
(I haven't tested it though..)
Just wanted to suggest you add it to the resource center Smile

Quote Reply
Re: Site of the Day Mod -> Links SQL v.1.11 In reply to
i'm not a real fan of SSI.. cron also.. but i can see why this script would need to use cron.. if it wasn't built one day.. then the site of the day.. would turn into site of two days.. or something.

also....

Code:
my $rec = $sth->fetchrow_hashref;
my $id = $rec->{'ID'};
# Get Record to display
$rec = $LINKDB->get_record ($id, 'HASH');
$rec already contains the record.. why get it again..

here is what i'd do for a SOTD thing..

call nph-build.cgi every night to build the homepages.. like most people do..

add.. in sub build_all
Code:
&build_sotd_page ();
add..
Code:
sub build_sotd_page {
# --------------------------------------------------------
# Creates the sotd page.
#
my (%OUT);

$USE_HTML ?
print "Building <a href='$LINKS{admin_root_url}/templates/sotd.txt' target='_blank'>SOTD Page</a> ... \n" :
print "Building SOTD Page ... \n";
my $s = time();

# Check to see if we need to create the page.
my $today = $LINKDB->get_date();
print "\tChecking Tracker\n";
print "\tOpening page: $LINKS{admin_root_path}/sotd.txt\n";
open SOTD, "<$LINKS{admin_root_path}/sotd.txt" or die "unable to open sotd page: $LINKS{admin_root_path}/sotd.txt. Reason: $!";
my $date = <SOTD>;
print "\tLast SOTD Date: $date\n";
close SOTD;
print "\tClosing page.\n";

if ($date ne $today) {
my $total = $LINKDB->total();
my $offset = int rand $total;
my $sth = $LINKDB->prepare ("SELECT * FROM Links LIMIT $offset, 1");
$sth->execute() or die $DBI::errstr;
my $rec = $sth->fetchrow_hashref;
print "\tSOTD: $$rec{Title} ($$rec{ID})\n";
print "\tOpening page: $LINKS{admin_root_path}/templates/sotd.txt\n";
open (SOTD, ">$LINKS{admin_root_path}/templates/sotd.txt") or die "unable to open sotd page: $LINKS{admin_root_path}/templates/sotd.txt. Reason: $!";
print SOTD &site_html_day ( { %$rec, Category => &build_clean_name (&get_category_name ($rec->{'CategoryID'})) } );
close SOTD;
print "\tClosing page.\n";

print "\tUpdating Tracker\n";
print "\tOpening page: $LINKS{admin_root_path}/sotd.txt\n";
open SOTD, ">$LINKS{admin_root_path}/sotd.txt" or die "unable to open sotd page: $LINKS{admin_root_path}/sotd.txt. Reason: $!";
print SOTD $today;
close SOTD;
print "\tClosing page.\n";
}
else {
print "\tSOTD Already exists for today ... Skipping ...\n";
}

my $f = time();
my $e = $f - $s;
print "Done ($e s)\n\n";
}
in HTML_Templates.pm add site_html_sotd to @EXPORT..

add..
Code:
sub site_html_sotd {
# --------------------------------------------------------
# This routine is used to display what a sotd page should
# look like.
my ($tags) = @_;
(ref $tags eq 'HASH') or croak "HTML_TEMPLATES: Argument '$tags' must be hash reference";

($rec->{'isNew'} eq 'Yes') ? ($rec->{'isNew'} = 1) : (delete $rec->{'isNew'});
($rec->{'isPopular'} eq 'Yes') ? ($rec->{'isPopular'} = 1) : (delete $rec->{'isPopular'});

return &load_template ('sotd.txt', { %$tags, %GLOBALS });
}
no SSI..

Jerry Su
Quote Reply
Re: Site of the Day Mod -> Links SQL v.1.11 In reply to
Thanks for the added instruction, pugdog.

Regards,

Eliot

Quote Reply
Re: Site of the Day Mod -> Links SQL v.1.11 In reply to
Thanks for your input, Jerry.

Regards,

Eliot Lee

Quote Reply
Re: Site of the Day Mod -> Links SQL v.1.11 In reply to
Well, gotze...I will release it if people are able to get it working...some of the codes I've placed in this Thread are redundant as Jerry pointed out...so after it is fully de-bugged...I will consider adding it to the Resource Center.

Regards,

Eliot Lee

Quote Reply
Update...Some Problems In reply to
Okay...I have adapted the ideas that widgetz provided and also added an email option to email the Links Owner if the email address is stored. I have also added codes to UPDATE a new table called SiteDay that includes two fields (LinkID, DateAdded).

Okay...here are two problems I am experiencing...(any ideas to solve these problems would be great!)....

1) Today's date is not added to the DateAdded field.

* I have the following field configurations in the SiteDay.def file:

Code:

DateAdded => ['2', 'DATE', '20', '20', '1', 'NOW', '^\d{4}\-\d{2}\-\d{2}$']


* I am using the following codes in the siteday.cgi file:

Code:

# Update Site of the Day Table
$sth = $SITEDB->prepare ("SELECT 1 FROM SiteDay WHERE LinkID = $id");
$today = $SITEDB->get_date();
$time = $SITEDB->get_time();
$SITEDB->do ("INSERT INTO SiteDay (LinkID, DateAdded) VALUES ($id, $today)");


* I have a confirmation message that prints out the date and time when the site of the day was created:

Code:

print "Script Completed at $today - $time";


This last function works just fine. However, the only thing that is inserted into SiteDay table is LinkID not the DateAdded. The value inserted is the default value of 0000-00-00.

2) Now the reason that I have created a separate table to store the LinkID is that I would like to check to see if the link "chosen" for the site of the day is NOT already in the SiteDay table. I have used $db->query and nothing seems to work. Here is the logic I am planning on employing:

1) Get total number of links
2) Get random link (row in the Links table)
3) Check SiteDay table
* If the LinkID is found in the SiteDay table, then "loop" back to the random codes and choose another link.
* If the LinkID is NOT found in the SiteDay table, then add the LinkID in the SiteDay table and then proceed through the rest of the script.
4) Send award email to Link Owner.
5) Post confirmation message.

The only step that does not work in this info flow is step 3.

Any thoughts?

Thanks in advance.

Regards,

Eliot Lee

Quote Reply
Re: Update...Some Problems In reply to
I haven't been following this, but shouldn't this:

Code:
# Update Site of the Day Table
$sth = $SITEDB->prepare ("SELECT 1 FROM SiteDay WHERE LinkID = $id");
$today = $SITEDB->get_date();
$time = $SITEDB->get_time();
$SITEDB->do ("INSERT INTO SiteDay (LinkID, DateAdded) VALUES ($id, $today)");
be more like:

Code:
# Update Site of the Day Table
$sth = $SITEDB->prepare ("SELECT * FROM Links WHERE LinkID = $id");
## you want to select "all" - '*' fields in the record where
## LinkID's match, but limit it to one in _any_ case.

$sth->execute(); ## get the link from the _Links_ table, unless you
## are check to see if the link already exists in
## the SiteDay DB, then you need an "if" test of some sort

my $today = $SITEDB->get_date(); ## define for this block of code only
my $time = $SITEDB->get_time(); ## define for this block of code only

$SITEDB->do ("INSERT INTO SiteDay (LinkID, DateAdded) VALUES ($id,
$today)");
A $sth->prepare requires an $sth->execute() to carry out.

An $db->do() is executed right away.

The code to do #3 -- the "check" and "insert" if it doesn't exist, is in the jump.cgi file, for the 'hit_track' table. I've used that skelleton in many places.





http://www.postcards.com
FAQ: http://www.postcards.com/FAQ/LinkSQL/

Quote Reply
Re: Update...Some Problems In reply to
Hmm...The logic seems correct...However, I already have the prepare codes above before updating the SiteDay table. I guess I forgot to include those codes.

Again...the LinkID is not the problem...that is added just fine into the SiteDay table...The problem is with the DateAdded field, which is not updated.

Oh well...I will look at the codes again and see what happens.

And about the checking...I don't know if the logic in jump.cgi could apply to the function I am looking for in this code hack...but I will look at jump.cgi and see if anything pops out.

Thanks for the input.

Regards,

Eliot Lee

Quote Reply
Re: Update...Some Problems In reply to
jump.cgi where it updates the "hit_track" table should apply exactly :)

http://www.postcards.com
FAQ: http://www.postcards.com/FAQ/LinkSQL/

Quote Reply
Re: Site of the Day Mod -> Links SQL v.1.11 In reply to
I just tried to install this mod and i got the following error:

Software error:
Can't locate DB_Utils.pm in @INC (@INC contains: admin /usr/local/lib/perl5/5.00502/sun4-solaris /usr/local/lib/perl5/5.00502 /usr/local/lib/perl5/site_perl/5.005/sun4-solaris /usr/local/lib/perl5/site_perl/5.005 .) at siteday.cgi line 24.
For help, please send mail to the webmaster, giving this error message and the time and date of the error. Content-type: text/html

Software error:
[Sun Jan 7 15:00:21 2001] DB_Utils.pm: Can't locate DB_Utils.pm in @INC (@INC contains: admin /usr/local/lib/perl5/5.00502/sun4-solaris /usr/local/lib/perl5/5.00502 /usr/local/lib/perl5/site_perl/5.005/sun4-solaris /usr/local/lib/perl5/site_perl/5.005 .) at siteday.cgi line 24. BEGIN failed--compilation aborted at siteday.cgi line 24.
For help, please send mail to the webmaster, giving this error message and the time and date of the error.


Can someone help me as to what is causing this?

And secondly why isnt a cron job or something done to choose a new site every day?

What if i wanted to change this mod from site of the day to site of the week it would be pretty easy to do if done in cron i could just change the settings?

Thanks in advance!!

Gian Wilson

Quote Reply
Re: Site of the Day Mod -> Links SQL v.1.11 In reply to
In Reply To:
Can someone help me as to what is causing this?
The problem is that you are probably NOT executing this script within the Links directory, so you would have to change the following codes:

Code:

use strict;
use vars qw/%in/;
use CGI ();
use CGI::Carp qw/fatalsToBrowser/;
use lib 'admin';
use Links;
use DB_Utils;
use HTML_Templates;
use DBSQL;


to the following:

Code:

use strict;
use vars qw/%in/;
use CGI ();
use CGI::Carp qw/fatalsToBrowser/;
use lib '/absoluate/path/to/admin';
use Links::Links;
use Links::DB_Utils;
use Links::HTML_Templates;
use Links::DBSQL;


In Reply To:
And secondly why isnt a cron job or something done to choose a new site every day?
Uh...I guess you glanced over the following text that I wrote:

In Reply To:

You can execute this script via Cron or Windows Scheduler Program everyday to have a true site of the day.


Please read Posts more carefully! Wink

In Reply To:
What if i wanted to change this mod from site of the day to site of the week it would be pretty easy to do if done in cron i could just change the settings?
All you have to do is program the Crontab to execute once a week and you will get a "Site of the Week".

Good luck!


Regards,

Eliot Lee
Quote Reply
Re: Site of the Day Mod -> Links SQL v.1.11 In reply to
Hey thanks for the help elliot, i realised about the error on my part a little while after and changed the code to:

use strict;
use vars qw/%in/;
use CGI ();
use CGI::Carp qw/fatalsToBrowser/;
use lib 'admin';
use Links;
use Links::DB_Utils;
use Links::HTML_Templates;
use Links::DBSQL;

thanks again

Quote Reply
Re: Site of the Day Mod -> Links SQL v.1.11 In reply to
You're welcome.

Regards,

Eliot Lee