#!/usr/bin/perl #$id$ #Salam Baker Shanawa use strict; use lib './lib'; no warnings 'utf8'; use database; use webUtil; use edcrypt; use aliCfg; use cookies; use Mail::Sender; my $webUtil = new webUtil; my $web = $webUtil->getWeb; my $edcrypt = new edcrypt(); my $cookies = new cookies; my @thisYear = localtime(); $web->{currentYear} = $thisYear[5] + 1900; my $userInfo; my $cfg = \%{$aliCfg::cfg}; $web->{language} = $cfg->{defaultLanguage} unless $web->{language}; my $templateDir = $cfg->{templates} . '/' . $web->{language}; my $db = new database ($cfg->{database}, $cfg->{dbHost}, $cfg->{dbUser}, $cfg->{dbPassword}) || &fatal; $db->Do ("SET NAMES 'utf8'"); my $allowListingAll = $cfg->{allowListingAll}; my $maxRec = $cfg->{maxRecPerPage}; assignValues ($cfg, $web); $web->{loggedIn} = 0; unless ($web->{func} eq 'login') { if (my $aliCookies = $cookies->ProcessCookie('ali', $ENV{HTTP_COOKIE})) { my $uLogin = $edcrypt->Decrypt($aliCookies, 'DONE'); $web->{cookies} = $cookies->set_cookie ('ali', $aliCookies, 480, '/', ''); $userInfo = $db->SelectOneRec("select * from user where uLogin='$uLogin'"); assignValues ($userInfo, $web); delete $web->{uPassword}; $web->{loggedIn} = 1; } } ## default func $web->{func} = 'home' unless $web->{func}; checkFunc ($web->{func}); my $func = \&{$web->{func}}; &{$func}; exit; ################################ sub fullRecord { my $info =$db->SelectOneRec("select * from resource left join format on format.foId=resource.foId left join type on type.tId=resource.tId left join library on library.liId=resource.rLiId where rId='$web->{rId}'"); assignValues ($info, $web); $webUtil->printTemplate ($templateDir, 'fullRecord', $web); exit; } sub home { $webUtil->printTemplate ($templateDir, 'home', $web); } sub listCoursePackResources { my $info = $db->SelectOneRec("select * from coursePack where cpId='$web->{cpId}'"); assignValues ($info, $web); $web->{records} = $db->SelectMany("select resource.*, type.tName, format.foName from coursePackResource, resource left join format on format.foId=resource.foId left join type on type.tId=resource.tId where coursePackResource.rId=resource.rId and cpId='$web->{cpId}' order by resource.rTitle"); $webUtil->printTemplate ($templateDir, 'coursePackResources', $web); exit; } sub listCoursePacks { unless ($web->{liId}) { $web->{libraries} = $db->SelectMany("select library.*, count(cpId) as coursePacksCount from library left join coursePack on cpLiId=liId group by liId order by liName"); $webUtil->printTemplate ($templateDir, 'listLibraries', $web); exit; } my $info = $db->SelectOneRec ("select * from library where liId = '$web->{liId}'"); assignValues ($info, $web); $web->{coursePacks} = $db->SelectMany ("select SQL_CALC_FOUND_ROWS * from coursePack where cpLiId = '$web->{liId}' order by cpTitle"); $web->{coursePacksCount} = $db->SelectOneRec ("select FOUND_ROWS() as count")->{count}; foreach my $coursePack (@{$web->{coursePacks}}) { $coursePack->{numberOfResources} = $db->SelectOneRec ("select count(*) as count from coursePackResource where cpId='$coursePack->{cpId}'")->{count}; $coursePack->{numberOfResources} = 0 unless $coursePack->{numberOfResources}; } $webUtil->printTemplate ($templateDir, 'listCoursePacks', $web); exit; } sub searchCoursePacks { my ($limit, $offset) = calculateLimit ($cfg->{maxRecordsPerPage}); $web->{searchLabel} = 1; unless ($web->{field}) { $web->{field} = 'all'; } $web->{$web->{field}} = 'checked="checked"'; unless ($web->{query}) { $webUtil->printTemplate ($templateDir, 'searchCoursePacks', $web); exit; } $web->{query} = cleanField ($web->{query}); $web->{queryEscaped} = $web->{query}; $web->{queryEscaped} =~ s|([^0-9a-zA-Z\?/_\.-])|'%' . sprintf("%-2.2X", ord ($1))|ge; my $searchQuery = '+' . $web->{query}; $searchQuery =~ s| | +|g; $web->{coursePacks} = $db->SelectMany ("select SQL_CALC_FOUND_ROWS * from coursePack, library where match(cpTitle) against ('$searchQuery' in boolean mode) and coursePack.cpLiId=library.liId order by cpTitle $limit"); ### join the library table as well to search against them .... like in search $web->{result}= $db->SelectOneRec("select FOUND_ROWS() as count")->{count}; foreach my $coursePack (@{$web->{coursePacks}}) { $coursePack->{numberOfResources} = $db->SelectOneRec ("select count(*) as COUNT from coursePackResource where cpId='$coursePack->{cpId}'")->{COUNT}; $coursePack->{numberOfResources} = 0 unless $coursePack->{numberOfResources}; } $webUtil->printTemplate ($templateDir, 'searchCoursePacks', $web); exit; } sub search { my ($limit, $offset) = calculateLimit ($cfg->{maxRecordsPerPage}); $web->{searchLabel} = 1; unless ($web->{field}) { $web->{field} = 'all'; } $web->{$web->{field}} = 'checked="checked"'; unless ($web->{query}) { $webUtil->printTemplate ($templateDir, 'search', $web); exit; } $web->{query} = cleanField ($web->{query}); $web->{queryEscaped} = $web->{query}; $web->{queryEscaped} =~ s|([^0-9a-zA-Z\?/_\.-])|'%' . sprintf("%-2.2X", ord ($1))|ge; my $searchQuery = '+' . $web->{query}; $searchQuery =~ s| | +|g; # debug ($searchQuery); my $searchQueryTmp = $searchQuery; ### what field my $fields = { 'all' => { 'index' => 'rTitle, rDescription, rISBN, rISSN, rAuthor, rSubTitle, rKeyWords', }, 'rTitle' => { 'index' => 'rTitle, rSubTitle', }, 'rDescription' => { 'index' => 'rDescription', }, 'rISBN' => { 'index' => 'rISBN', }, 'rISSN' => { 'index' => 'rISSN', }, 'rAuthor' => { 'index' => 'rAuthor', }, }; $searchQuery = "where match($fields->{$web->{field}}{index}) against ('$searchQuery' in boolean mode)"; if ($web->{field} eq 'all') { ## search library as well $searchQuery .= " or match library.liName against ('$searchQueryTmp' in boolean mode)"; } $web->{records} = $db->SelectMany ("select SQL_CALC_FOUND_ROWS * from resource left join library on resource.rLiId=library.liId left join format on format.foId=resource.foid left join type on type.tId=resource.tId $searchQuery order by rTitle $limit"); $web->{result} = $db->SelectOneRec("select FOUND_ROWS() as count")->{count}; $webUtil->printTemplate ($templateDir, 'search', $web); exit; } ############################# sub login { unless ($web->{uLogin} and $web->{uPassword}) { $web->{errorMessages} = "Authentication Failed"; $webUtil->printTemplate ($templateDir, 'login', $web); exit; } $userInfo = $db->SelectOneRec("select * from user where uLogin='$web->{uLogin}' and uPassword='$web->{uPassword}'"); unless ($userInfo->{uLiId}) { $web->{errorMessages} = "Authentication Failed"; $webUtil->printTemplate ($templateDir, 'login', $web); exit; } my $aliCookies = $edcrypt->Encrypt($web->{uLogin}, 'DONE'); $web->{cookies} = $cookies->set_cookie ('ali', $aliCookies, 480, '/', ''); assignValues ($userInfo, $web); delete $web->{uPassword}; $web->{loggedIn} = 1; &home; exit; } sub logout { $web->{cookies} = $cookies->remove_cookie ('ali', '/', ''); delete $web->{uName}; delete $web->{uLiId}; $web->{loggedIn} = 0; $webUtil->printTemplate ($templateDir, 'home', $web); exit; } sub download { my $info = $db->SelectOneRec("select rLiId, rAccessable, rPath, fName from resource, file where resource.rId=file.rId and resource.rId= '$web->{rId}'"); fatal ("Please login first") unless $web->{uLiId}; ### check user access unless ($info->{fName}) { fatal ("Unfortunately the file is not availabe"); } unless ($info->{rLiId} == $web->{uLiId} or $info->{rAccessable} eq 'public') { fatal ("You are not allowed to download this resource"); } my $file = "$cfg->{uploadDir}/$info->{rPath}/$info->{fName}"; ##print "Content-type: application/zip\n"; ### print "Content-Disposition: inline;filename=\"$info->{fName}\"\n"; print "Content-Length: " . (-s $file) . "\n\n"; my $bufferLength = 16384; my $buffer; open (DOC, $file) || fatal ("Failed to open '$file': $!"); binmode(DOC); while(read(DOC, $buffer, $bufferLength)) { print $buffer; } close DOC; } sub order { my $info = $db->SelectOneRec("select * from resource, library where resource.rLiId=library.liId and resource.rId='$web->{rId}'"); fatal ("no such record") unless $info->{rId}; fatal ("you need to login first before ordering the resource") unless $userInfo->{uLiId}; my $libraryInfo = $db->SelectOneRec ("select * from library where liId = '$userInfo->{uLiId}'"); my $msg = "Title : $info->{rTitle}\n"; $msg .= "Author : $info->{rAuthor}\n"; $msg .= "Library Producer: $info->{liName}\n"; $msg .= "\n"; $msg .= "User Name : $userInfo->{uName}\n"; my $mailSender = new Mail::Sender ( {subject => "Resource order from ALI", from => $userInfo->{uEmail}, to => "$libraryInfo->{liEmail}", #to => 'sbs@munin.lub.lu.se', }); $Mail::Sender::NO_X_MAILER = 1; if (! ref $mailSender->MailMsg ({msg => $msg})) { fatal ("System error: Please inform") ; } $mailSender->Close (); assignValues ($info, $web); $webUtil->printTemplate ($templateDir, 'orderSent', $web); exit; } ################################ sub feedback { my @fields = ('message'); foreach my $field (@fields) { unless (&checkField ($web->{$field})) { $web->{errorMessages} = "Please try again, Fill in the mandatory fields"; $webUtil->printTemplate($templateDir, 'feedback', $web); exit; } } use Mail::Sender; my $msg = "$web->{message}\n" . "\n------------\n$web->{uName}\n"; my $from = $web->{uEmail}; $from = 'nobody@ali.lub.lu.se' unless $from; my $mailSender = new Mail::Sender ( {subject => "Feedback from ALI user: $web->{subject}", to => 'asa.forsberg@lub.lu.se', from => $from, }); $Mail::Sender::NO_X_MAILER = 1; $mailSender->MailMsg ({msg => $msg}); $mailSender->Close; $webUtil->printTemplate($templateDir, 'thanks', $web); exit; } sub checkField { my $field = shift; $field = &cleanField ($field); return 0 unless $field; return 1; } sub cleanField { my $field = shift; $field =~ s|^ +||; $field =~ s| +| |g; $field =~ s|^\t+||; $field =~ s|'|\\'|g; $field =~ s|"||g; $field =~ s| +$||; return $field; } ############################### sub checkField { my $field = shift; $field = &cleanField ($field); return 0 unless $field; return 1; } sub cleanField { my $field = shift; $field =~ s|^ +||; $field =~ s| +| |g; $field =~ s|^\t+||; $field =~ s|'|\\'|g; $field =~ s|"||g; $field =~ s| +$||; return $field; } sub calculatePages { my ($found, $max) = @_; my $pages; return 1 if ($found <= $max) ; if ($found % $max) { $pages = int ($found / $max + 1); } else { $pages = int ($found / $max); } return $pages; } sub resultPages { my ($found, $perPege) = @_; my $pages = calculatePages ($found, $perPege); if ($pages > 1) { $web->{previousPage} = $web->{p} - 1 if $web->{p} > 1; $web->{nextPage} = $web->{p} + 1 if $web->{p} < $pages; my $lastPage = 10 if $web->{p} < 6; $lastPage = $web->{p} + 5 if $web->{p} > 5; $lastPage = $pages if $lastPage > $pages; my $startPage = $lastPage - 10 + 1 ; $startPage = 1 if $startPage < 1; for (my $i = $startPage ; $i <= $lastPage; $i++) { my $rec = {}; $rec->{p} = $i; $rec->{currentPage} = 1 if $i == $web->{p}; push @{$web->{pages}}, $rec; } } @{$web->{pages1}} = @{$web->{pages}} if $web->{pages}; ## a copy ( do beter in printTemplate. } sub debug { print "Content-type: text/html\n\n"; print join ("
", @_); exit; } sub calculateLimit { my $max = shift; $web->{p} = 1 unless $web->{p}; $web->{p} = 1 unless $web->{p} =~ /\b\d+\b/; my $offset = ($web->{p} - 1 ) * $max; my $limit = 'limit ' . $offset . ', ' . $max; $limit='' if $web->{all} && $cfg->{allowListingAll}; $web->{p} = '' if $web->{all} && $cfg->{allowListingAll}; return ($limit, $offset); } sub checkFunc { my ($func) = shift; my $checkSt = 'main::' . $func; defined &{$checkSt} || fatal ("no such function $func"); 1; } sub loadTempl { ## help page: $web->{helpPage} = 'help-' . $web->{templ}; $web->{findJournalsLabel} = 1; if ($web->{ef}) { ### extra func to be exec if needed checkFunc ($web->{ef}); my $extraFunc = \&{$web->{ef}}; &{$extraFunc}; } $webUtil->printTemplate ($templateDir, $web->{templ}, $web); } sub fatal { my ($error) = shift; $web->{error} = $error; $webUtil->printTemplate ($templateDir, 'error', $web); exit; } sub assignValues { my ($source, $target) = @_; foreach my $k (keys %{$source}) { $target->{$k} = $source->{$k}; } }