/usr/local/CPAN/WWW-Page/Import/Client.pm
package Import::Client;
use utf8;
use XML::LibXML;
use Import::Datasource;
my $MAX = 10;
sub import
{
my $class = shift;
my $this = {};
return bless $this, $class;
}
sub keywordList
{
my $this = shift;
my $page = shift;
my $node = shift;
my $args = shift;
my $dbh = $Import::Datasource::handler;
my $sth = $dbh->prepare ("select keyword, uri from keywords order by keyword");
$sth->execute();
while (my ($keyword, $uri) = $sth->fetchrow_array())
{
my $item = $page->{'xml'}->createElement ('item');
$item->appendText ($keyword);
$item->setAttribute ('uri', $uri);
$node->appendChild ($item);
}
return $node;
}
sub monthCalendar
{
my $this = shift;
my $page = shift;
my $node = shift;
my $args = shift;
my $dbh = $Import::Datasource::handler;
my $sth = $dbh->prepare ("select distinct count(*), month(date), year(date) from message where site_id=1 and is_published=1 and date <= now() group by concat(month(date), year(date)) order by date desc");
$sth->execute();
while (my ($count, $month, $year) = $sth->fetchrow_array())
{
my $item = $page->{'xml'}->createElement ('item');
$item->setAttribute ('count', $count);
$item->setAttribute ('month', sprintf ("%02i", $month));
$item->setAttribute ('year', $year);
$node->appendChild ($item);
}
return $node;
}
sub currentView
{
my $this = shift;
my $page = shift;
my $node = shift;
my $args = shift;
my $dbh = $Import::Datasource::handler;
my $uri = $ENV{'REQUEST_URI'};
$uri =~ s{/}{}g;
$uri =~ s{\?.*}{};
$uri =~ s{%20}{ }g;
if (length $uri)
{
my $sth = $dbh->prepare ("select count(*) from keywords where uri = " . $dbh->quote ($uri));
$sth->execute();
my ($count) = $sth->fetchrow_array();
$sth->finish();
if ($count)
{
return $this->viewCategory ($page, $node, $uri);
}
else
{
my $site_id = getSiteID();
my $sth = $dbh->prepare ("select count(*) from message where is_published = 1 and site_id = $site_id and message.date <= now() and uri = " . $dbh->quote ($uri));
$sth->execute();
($count) = $sth->fetchrow_array();
$sth->finish();
if ($count)
{
return $this->viewMessage ($page, $node, $uri);
}
else
{
print "Location: http://$ENV{'SERVER_NAME'}/\n\n";
exit;
}
}
}
return $node;
}
sub mainView
{
my $this = shift;
my $page = shift;
my $node = shift;
my $args = shift;
my $dbh = $Import::Datasource::handler;
my $site_id = getSiteID();
my $count = $args->{'count'} || $MAX;
my $sth = $dbh->prepare ("select keywords.keyword, message.id, message.uri, dayofmonth(message.date), month(message.date), year(message.date), message.title, message.content from message left join keyword2message on keyword2message.message_id = message.id left join keywords on keywords.id = keyword2message.keyword_id where message.is_published = 1 and message.site_id = ? and message.date <= now() group by message.id order by message.date desc, message.id desc limit ?");
$sth->execute($site_id, $count);
my @message_ids = ();
while (my ($keyword, $message_id, $message_uri, $day, $month, $year, $title, $content) = $sth->fetchrow_array())
{
push @message_ids, $message_id;
my $messageNode = $page->{'xml'}->createElement ('message');
$node->appendChild ($messageNode);
$messageNode->setAttribute ('day', $day);
$messageNode->setAttribute ('month', $month);
$messageNode->setAttribute ('year', $year);
$messageNode->setAttribute ('id', $message_id);
$messageNode->setAttribute ('uri', $message_uri);
my $titleNode = $page->{'xml'}->createElement ('title');
$messageNode->appendChild ($titleNode);
$titleNode->appendText ($title);
my $contentNode = $page->{'xml'}->createElement ('content');
$messageNode->appendChild ($contentNode);
$contentNode->appendText ($content);
}
$sth->finish();
my $keywordMap = $page->{'xml'}->createElement ('keyword-map');
$node->appendChild ($keywordMap);
if (@message_ids)
{
$sth = $dbh->prepare ("select message_id, keywords.uri from keywords join keyword2message on keywords.id = keyword2message.keyword_id where message_id in (". join (',', @message_ids) . ") order by keyword2message.id");
$sth->execute();
while (my ($message_id, $uri) = $sth->fetchrow_array())
{
my $item = $page->{'xml'}->createElement ('item');
$item->setAttribute ('message-id', $message_id);
$item->setAttribute ('uri', $uri);
$keywordMap->appendChild ($item);
}
$sth->finish();
}
return $node;
}
sub monthView
{
my $this = shift;
my $page = shift;
my $node = shift;
my $uri = shift;
my $dbh = $Import::Datasource::handler;
my ($year, $month) = $ENV{'REQUEST_URI'} =~ m{^/(\d{4})/(\d+\d?)/?};
unless ($year && $month)
{
print "Location: http://$ENV{'SERVER_NAME'}/\n\n";
exit;
}
my $site_id = getSiteID();
my $sth = $dbh->prepare ("select keywords.keyword, message.id, message.uri, dayofmonth(message.date), month(message.date), year(message.date), message.title, message.content from message left join keyword2message on keyword2message.message_id = message.id left join keywords on keywords.id = keyword2message.keyword_id where message.is_published = 1 and message.site_id = $site_id and year(date) = $year and month(date) = $month and message.date <= now() group by message.id order by message.date desc, message.id desc");
$sth->execute();
my @message_ids = ();
while (my ($keyword, $message_id, $message_uri, $day, $month, $year, $title, $content) = $sth->fetchrow_array())
{
push @message_ids, $message_id;
my $messageNode = $page->{'xml'}->createElement ('message');
$node->appendChild ($messageNode);
$messageNode->setAttribute ('day', $day);
$messageNode->setAttribute ('month', $month);
$messageNode->setAttribute ('year', $year);
$messageNode->setAttribute ('id', $message_id);
$messageNode->setAttribute ('uri', $message_uri);
my $titleNode = $page->{'xml'}->createElement ('title');
$messageNode->appendChild ($titleNode);
$titleNode->appendText ($title);
my $contentNode = $page->{'xml'}->createElement ('content');
$messageNode->appendChild ($contentNode);
$contentNode->appendText ($content);
}
$sth->finish();
unless (@message_ids)
{
print "Location: http://$ENV{'SERVER_NAME'}/\n\n";
exit;
}
$node->setAttribute ('month', $month);
$node->setAttribute ('year', $year);
my $keywordMap = $page->{'xml'}->createElement ('keyword-map');
$node->appendChild ($keywordMap);
$sth = $dbh->prepare ("select message_id, keywords.uri from keywords join keyword2message on keywords.id = keyword2message.keyword_id where message_id in (". join (',', @message_ids) . ") order by keyword2message.id");
$sth->execute();
while (my ($message_id, $uri) = $sth->fetchrow_array())
{
my $item = $page->{'xml'}->createElement ('item');
$item->setAttribute ('message-id', $message_id);
$item->setAttribute ('uri', $uri);
$keywordMap->appendChild ($item);
}
$sth->finish();
return $node;
}
sub rssView
{
my $this = shift;
my $page = shift;
my $node = shift;
my $uri = shift;
my $dbh = $Import::Datasource::handler;
use Date::Manip qw(ParseDate UnixDate);
my $rfc822_format = "%a, %d %b %Y %H:%M:%S +0300";
my $today = ParseDate ("Now");
my $rfc822_date = UnixDate ($today, $rfc822_format);
my $pubDate = $page->{'xml'}->createElement ('pub-date');
$pubDate->appendText ($rfc822_date);
$node->appendChild ($pubDate);
my $site_id = getSiteID();
my $sth = $dbh->prepare ("select message.uri, date, message.title, message.content from message where message.is_published = 1 and message.site_id = $site_id and message.date <= now() order by message.date desc, message.id desc limit $MAX");
$sth->execute();
while (my ($message_uri, $date, $title, $content) = $sth->fetchrow_array())
{
my $messageNode = $page->{'xml'}->createElement ('message');
$node->appendChild ($messageNode);
my $rfc822_date = UnixDate (ParseDate ($date), $rfc822_format);
$messageNode->setAttribute ('uri', $message_uri);
$messageNode->setAttribute ('date', $rfc822_date);
my $titleNode = $page->{'xml'}->createElement ('title');
$messageNode->appendChild ($titleNode);
$titleNode->appendText (clearEntities ($title));
my $contentNode = $page->{'xml'}->createElement ('content');
$messageNode->appendChild ($contentNode);
$contentNode->appendText (clearEntities ($content));
}
$sth->finish();
return $node;
}
sub viewCategory
{
my $this = shift;
my $page = shift;
my $node = shift;
my $uri = shift;
my $dbh = $Import::Datasource::handler;
my $site_id = getSiteID();
my $sth = $dbh->prepare ("select keywords.keyword, message.id, message.uri, dayofmonth(message.date), month(message.date), year(message.date), message.title, message.content from message join keyword2message on keyword2message.message_id = message.id join keywords on keywords.id = keyword2message.keyword_id where message.is_published = 1 and message.site_id = $site_id and keywords.uri = " . $dbh->quote ($uri) . " and message.date <= now() order by message.date desc, message.id desc");
$sth->execute();
my @message_ids = ();
my $groupKeyword;
while (my ($keyword, $message_id, $message_uri, $day, $month, $year, $title, $content) = $sth->fetchrow_array())
{
push @message_ids, $message_id;
unless ($groupKeyword)
{
$groupKeyword = $keyword;
my $groupKeyword = $page->{'xml'}->createElement ('group-keyword');
$groupKeyword->appendText ($keyword);
$groupKeyword->setAttribute ('uri', $uri);
$node->appendChild ($groupKeyword);
}
my $messageNode = $page->{'xml'}->createElement ('message');
$node->appendChild ($messageNode);
$messageNode->setAttribute ('day', $day);
$messageNode->setAttribute ('month', $month);
$messageNode->setAttribute ('year', $year);
$messageNode->setAttribute ('id', $message_id);
$messageNode->setAttribute ('uri', $message_uri);
my $titleNode = $page->{'xml'}->createElement ('title');
$messageNode->appendChild ($titleNode);
$titleNode->appendText ($title);
my $contentNode = $page->{'xml'}->createElement ('content');
$messageNode->appendChild ($contentNode);
$contentNode->appendText ($content);
}
$sth->finish();
my $keywordMap = $page->{'xml'}->createElement ('keyword-map');
$node->appendChild ($keywordMap);
$sth = $dbh->prepare ("select message_id, keywords.uri from keywords join keyword2message on keywords.id = keyword2message.keyword_id where message_id in (". join (',', @message_ids) . ") order by keyword2message.id");
$sth->execute();
while (my ($message_id, $uri) = $sth->fetchrow_array())
{
my $item = $page->{'xml'}->createElement ('item');
$item->setAttribute ('message-id', $message_id);
$item->setAttribute ('uri', $uri);
$keywordMap->appendChild ($item);
}
$sth->finish();
return $node;
}
sub viewMessage
{
my $this = shift;
my $page = shift;
my $node = shift;
my $uri = shift;
my $dbh = $Import::Datasource::handler;
my $site_id = getSiteID();
my $sth = $dbh->prepare ("select id, dayofmonth(date), month(date), year(date), title, content from message where is_published = 1 and site_id = $site_id and message.date <= now() and uri = " . $dbh->quote ($uri));
$sth->execute();
my ($message_id, $day, $month, $year, $title, $content) = $sth->fetchrow_array();
$sth->finish();
my $messageNode = $page->{'xml'}->createElement ('message');
$node->appendChild ($messageNode);
$messageNode->setAttribute ('type', 'single-message');
$messageNode->setAttribute ('day', $day);
$messageNode->setAttribute ('month', $month);
$messageNode->setAttribute ('year', $year);
my $titleNode = $page->{'xml'}->createElement ('title');
$messageNode->appendChild ($titleNode);
$titleNode->appendText ($title);
my $contentNode = $page->{'xml'}->createElement ('content');
$messageNode->appendChild ($contentNode);
$contentNode->appendText ($content);
my $keywordsNode = $page->{'xml'}->createElement ('keywords');
$messageNode->appendChild ($keywordsNode);
$sth = $dbh->prepare ("select keyword, uri from keywords join keyword2message on keywords.id = keyword2message.keyword_id where message_id = $message_id order by keyword2message.id");
$sth->execute();
while (my ($keyword, $uri) = $sth->fetchrow_array())
{
my $item = $page->{'xml'}->createElement ('item');
$item->setAttribute ('uri', $uri);
$item->appendText ($keyword);
$keywordsNode->appendChild ($item);
}
$sth->finish();
return $node;
}
sub messageList
{
my $this = shift;
my $page = shift;
my $node = shift;
my $args = shift;
my $dbh = $Import::Datasource::handler;
my $sth = $dbh->prepare ("select id, dayofmonth(date), month(date), year(date), title, is_published, site_id from message and message.date <= now() order by date desc, id desc");
$sth->execute();
while (my ($id, $day, $month, $year, $title, $is_published, $site_id) = $sth->fetchrow_array())
{
my $item = $page->{'xml'}->createElement ('item');
$item->setAttribute ('id', $id);
$item->setAttribute ('day', $day);
$item->setAttribute ('month', $month);
$item->setAttribute ('year', $year);
$item->setAttribute ('is_published', $is_published);
$item->setAttribute ('site_id', $site_id);
$item->appendText ($title);
$node->appendChild ($item);
}
$sth->finish();
return $node;
}
sub tagCloud
{
my $this = shift;
my $page = shift;
my $node = shift;
my $args = shift;
my $dbh = $Import::Datasource::handler;
my $site_id = getSiteID();
my $sth = $dbh->prepare ("select count(*) from message where site_id = $site_id and is_published = 1");
$sth->execute();
my ($total) = $sth->fetchrow_array();
$sth->finish();
$total = 1 unless $total;
$node->setAttribute ('total', $total);
$sth = $dbh->prepare ("select keyword, keywords.uri, count(*) from keywords join keyword2message on keywords.id = keyword2message.keyword_id join message on message.id = keyword2message.message_id where site_id = $site_id and is_published = 1 and message.date <= now() group by keywords.id order by keywords.keyword");
$sth->execute();
my ($min, $max) = ($total, 0);
while (my ($keyword, $keyword_uri, $count) = $sth->fetchrow_array())
{
my $item = $page->{'xml'}->createElement ('item');
$item->setAttribute ('uri', $keyword_uri);
$item->setAttribute ('count', $count);
$item->appendText ($keyword);
$node->appendChild ($item);
$min = $count if $count < $min;
$max = $count if $count > $max;
}
$sth->finish();
$node->setAttribute ('min', $min);
$node->setAttribute ('max', $max);
return $node;
}
sub clearEntities
{
my $text = shift;
$text =~ s{ }{ }gm;
$text =~ s{—}{—}gm;
$text =~ s{«}{«}gm;
$text =~ s{»}{»}gm;
$text =~ s{„}{„}gm;
$text =~ s{“}{”}gm;
$text =~ s{&\w+;}{ }gm;
return $text;
}
sub messageCounter
{
my $this = shift;
my $page = shift;
my $node = shift;
my $args = shift;
my $dbh = $Import::Datasource::handler;
my $site_id = getSiteID();
my $sth = $dbh->prepare ("select count(*) from message where is_published = 1 and site_id = $site_id and message.date <= now()");
$sth->execute();
my ($count) = $sth->fetchrow_array();
$sth->finish();
$node->appendText ($count);
return $node;
}
sub searchResults
{
my $this = shift;
my $page = shift;
my $node = shift;
my $args = shift;
my $dbh = $Import::Datasource::handler;
my $site_id = getSiteID();
my $query = $page->param ('text');
my $sth = $dbh->prepare (
"select
id,
uri,
title,
content
from
message
where
match(content, title) against (". $dbh->quote ($query) . ")
and is_published = 1
and site_id = $site_id"
);
$sth->execute();
while (my ($id, $uri, $title, $content) = $sth->fetchrow_array())
{
my $item = $page->{'xml'}->createElement ('item');
$node->appendChild ($item);
$item->setAttribute ('id', $id);
$item->setAttribute ('uri', $uri);
my $titleNode = $page->{'xml'}->createElement ('title');
$item->appendChild ($titleNode);
$titleNode->appendText (highlight ($title, $query, 1));
my $contentNode = $page->{'xml'}->createElement ('content');
$item->appendChild ($contentNode);
$contentNode->appendText (highlight ($content, $query));
}
$sth->finish();
my $query = $page->{'xml'}->createElement ('query');
$query->appendText ($page->param ('text'));
$node->addChild ($query);
return $node;
}
sub highlight
{
my $content = shift;
my $query = shift;
my $type = shift;
$query =~ s{^\s+}{};
$query =~ s{\s+$}{};
$query =~ s{[^\w\d\s]}{}g;
my @query = split / +/, $query;
foreach my $q (@query)
{
$content =~ s{($q\w*)}{<span class="highlight">$1</span>}gims;
}
return $content if $type == 1;
$content =~ s{^[\s\n]*<p[^>]*>}{}i;
$content =~ s{</p>[\s\n]*$}{}i;
my @p = split /<\/p>\s*?<p[^>]*>/i, $content;
my $result = '';
foreach my $p (@p)
{
if ($p =~ m{<span class="highlight">})
{
$result .= "<p>$p</p>";
}
}
if ($result eq '')
{
$result = "<p>$p[0]</p>";
}
return $result;
}
sub searchKeywords
{
my $this = shift;
my $page = shift;
my $node = shift;
my $args = shift;
my $dbh = $Import::Datasource::handler;
my $query = $page->param ('text');
$query =~ s{^\s+}{};
$query =~ s{\s+$}{};
$query =~ s{[^\w\d\s]}{}g;
my @query = split / +/, $query;
$query = join ', ', map "'$_'", @query;
my $sth = $dbh->prepare ("select keyword, uri from keywords where keyword in ($query)");
$sth->execute();
while (my ($keyword, $uri) = $sth->fetchrow_array())
{
my $item = $page->{'xml'}->createElement ('item');
$item->setAttribute ('uri', $uri);
$item->appendText ($keyword);
$node->appendChild ($item);
}
$sth->finish();
return $node;
}
sub getSiteID()
{
my $site_id = 1;
return $site_id;
}
1;