Annotation of loncom/interface/lonsearchcourse.pm, revision 1.1

1.1     ! www         1: # The LearningOnline Network with CAPA
        !             2: # Search Course
        !             3: #
        !             4: # $Id: lonsearchcat.pm,v 1.326 2010/08/25 12:38:45 wenzelju Exp $
        !             5: #
        !             6: # Copyright Michigan State University Board of Trustees
        !             7: #
        !             8: # This file is part of the LearningOnline Network with CAPA (LON-CAPA).
        !             9: #
        !            10: # LON-CAPA is free software; you can redistribute it and/or modify
        !            11: # it under the terms of the GNU General Public License as published by
        !            12: # the Free Software Foundation; either version 2 of the License, or
        !            13: # (at your option) any later version.
        !            14: #
        !            15: # LON-CAPA is distributed in the hope that it will be useful,
        !            16: # but WITHOUT ANY WARRANTY; without even the implied warranty of
        !            17: # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
        !            18: # GNU General Public License for more details.
        !            19: #
        !            20: # You should have received a copy of the GNU General Public License
        !            21: # along with LON-CAPA; if not, write to the Free Software
        !            22: # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
        !            23: #
        !            24: # /home/httpd/html/adm/gpl.txt
        !            25: #
        !            26: # http://www.lon-capa.org/
        !            27: #
        !            28: ###############################################################################
        !            29: ###############################################################################
        !            30: 
        !            31: package Apache::lonsearchcourse;
        !            32: 
        !            33: use strict;
        !            34: use Apache::Constants qw(:common :http);
        !            35: use Apache::lonnet;
        !            36: use GDBM_File;
        !            37: use Apache::loncommon();
        !            38: use Apache::lonmeta;
        !            39: use Apache::lonhtmlcommon;
        !            40: use Apache::lonlocal;
        !            41: use LONCAPA::lonmetadata();
        !            42: use HTML::Entities();
        !            43: use Apache::lonnavmaps;
        !            44: use Apache::londocs();
        !            45: use Apache::lonindexer();
        !            46: use LONCAPA;
        !            47: 
        !            48: # Variables For course search
        !            49: my %alreadyseen;
        !            50: my %hash;
        !            51: my $totalfound;
        !            52: 
        !            53: 
        !            54: sub menu {
        !            55:     my $scrout='';
        !            56:     if ($env{'request.course.id'}) {
        !            57:         my %lt=&Apache::lonlocal::texthash('srch' => 'Search',
        !            58:                                            'header' => 'Course Search',
        !            59:          'note' => 'Enter terms or phrases, then press "Search" below',
        !            60:          'use' => 'use related words',
        !            61:          'full' =>'fulltext search (time consuming)',
        !            62:          'disc' => 'search discussion postings (resources and discussion boards)',
        !            63:                                            );
        !            64:         $scrout.=(<<ENDCOURSESEARCH);
        !            65: <form name="loncapa_search" method="post" action="/adm/searchcourse">
        !            66: <center>
        !            67: <hr />
        !            68: <h1>$lt{'header'}</h1>    
        !            69: <input type="hidden" name="phase" value="results" />
        !            70: <p>
        !            71: $lt{'note'}.
        !            72: </p>
        !            73: <table>
        !            74: <tr><td>
        !            75: ENDCOURSESEARCH
        !            76:         $scrout.='&nbsp;'.
        !            77:             &Apache::lonhtmlcommon::textbox('courseexp',
        !            78:                                   $env{'form.courseexp'},40);
        !            79:         my $crscheckbox =
        !            80:             &Apache::lonhtmlcommon::checkbox('crsfulltext',
        !            81:                                    $env{'form.crsfulltext'});
        !            82:         my $relcheckbox =
        !            83:             &Apache::lonhtmlcommon::checkbox('crsrelated',
        !            84:                                    $env{'form.crsrelated'});
        !            85:         my $discheckbox =
        !            86:             &Apache::lonhtmlcommon::checkbox('crsdiscuss',
        !            87:                                    $env{'form.crsrelated'});
        !            88:         $scrout.=(<<ENDENDCOURSE);
        !            89: </td></tr>
        !            90: <tr><td><label>$relcheckbox $lt{'use'}</label></td><td></td></tr>
        !            91: <tr><td><label>$crscheckbox $lt{'full'}</label></td><td></td></tr>
        !            92: <tr><td><label>$discheckbox $lt{'disc'}</label></td><td></td></tr>
        !            93: </table>
        !            94: <p>
        !            95: <input type="submit" name="coursesubmit" value='$lt{'srch'}' />
        !            96: </p>
        !            97: </center>
        !            98: </form>
        !            99: ENDENDCOURSE
        !           100:     }
        !           101:     return $scrout;
        !           102: }
        !           103: 
        !           104: sub make_symb {
        !           105:     my ($id)=@_;
        !           106:     my ($mapid,$resid)=split(/\./,$id);
        !           107:     my $map=$hash{'map_id_'.$mapid};
        !           108:     my $res=$hash{'src_'.$id};
        !           109:     my $symb=&Apache::lonnet::encode_symb($map,$resid,$res);
        !           110:     return $symb;
        !           111: }
        !           112: 
        !           113: sub related_version {
        !           114:     my ($word) = @_;
        !           115:     return (undef) if (lc($word) =~ /\b(or|and|not)\b/);
        !           116:     my @Words = &Apache::loncommon::get_related_words($word);
        !           117:     # Only use 4 related words
        !           118:     @Words = ($#Words>4? @Words[0..4] : @Words);
        !           119:     my $result = join " OR ", ($word,@Words);
        !           120:     return $result,sort(@Words);
        !           121: }
        !           122: 
        !           123: sub course_search {
        !           124:     my $r=shift;
        !           125:     my $pretty_search_string = '<b>'.$env{'form.courseexp'}.'</b>';
        !           126:     my $search_string = $env{'form.courseexp'};
        !           127:     my @New_Words;
        !           128:     undef(%alreadyseen);
        !           129:     if ($env{'form.crsrelated'}) {
        !           130:         ($search_string,@New_Words) = &related_version($env{'form.courseexp'});
        !           131:         if (@New_Words) {
        !           132:             $pretty_search_string .= ' '.&mt("with related words").": <b>@New_Words</b>.";
        !           133:         } else {
        !           134:             $pretty_search_string .= ' '.&mt('with no related words').".";
        !           135:         }
        !           136:     }
        !           137:     my $fulltext=$env{'form.crsfulltext'};
        !           138:     my $discuss=$env{'form.crsdiscuss'};
        !           139:     my @allwords=($search_string,@New_Words);
        !           140:     $totalfound=0;
        !           141: 
        !           142:     $r->print(
        !           143:               '<hr /><center><font size="+2" face="arial">'.
        !           144:               $pretty_search_string.'</font></center>'.
        !           145:               '<hr /><b>'.&mt('Course content').':</b><br />');
        !           146:     $r->rflush();
        !           147: # ======================================================= Go through the course
        !           148:     my $c=$r->connection;
        !           149:     if (tie(%hash,'GDBM_File',$env{'request.course.fn'}.".db",
        !           150:             &GDBM_READER(),0640)) {
        !           151:         foreach (sort(keys(%hash))) {
        !           152:             if ($c->aborted()) { last; }
        !           153:             if (($_=~/^src\_(.+)$/)) {
        !           154:                 if ($hash{'randomout_'.$1} & !$env{'request.role.adv'}) {
        !           155:                     next;
        !           156:                 }
        !           157:                 my $symb=&make_symb($1);
        !           158:                 &checkonthis($r,$1,$hash{$_},0,&Apache::lonnet::gettitle($symb),
        !           159:                              $fulltext,$symb,@allwords);
        !           160:             }
        !           161:         }
        !           162:         untie(%hash);
        !           163:     }
        !           164:     unless ($totalfound) {
        !           165:         $r->print('<p class="LC_info">'.&mt('No matches found in resources.').'</p>');
        !           166:     }
        !           167: 
        !           168: # Check discussions if requested
        !           169:     if ($discuss) {
        !           170:         my $totaldiscussions = 0;
        !           171:         $r->print('<br /><br /><b>'.&mt('Discussion postings').':</b><br />');
        !           172:         my $navmap = Apache::lonnavmaps::navmap->new();
        !           173:         if (defined($navmap)) {
        !           174:             my @allres=$navmap->retrieveResources();
        !           175:             my %discussiontime = &Apache::lonnet::dump('discussiontimes',
        !           176:                                    $env{'course.'.$env{'request.course.id'}.'.domain'},
        !           177:                                    $env{'course.'.$env{'request.course.id'}.'.num'});
        !           178:             foreach my $resource (@allres) {
        !           179:                 my $result = '';
        !           180:                 my $applies = 0;
        !           181:                 my $symb = $resource->symb();
        !           182:                 my $ressymb = $symb;
        !           183:                 if ($symb =~ m#(___adm/$LONCAPA::domain_re/$LONCAPA::username_re)/(\d+)/bulletinboard$#) {
        !           184:                     $ressymb = 'bulletin___'.$2.$1.'/'.$2.'/bulletinboard';
        !           185:                     unless ($ressymb =~ m#bulletin___\d+___adm/wrapper#) {
        !           186:                         $ressymb=~s#(bulletin___\d+___)#$1adm/wrapper/#;
        !           187:                     }
        !           188:                 }
        !           189:                 if (defined($discussiontime{$ressymb})) {
        !           190:                     my %contrib = &Apache::lonnet::restore($ressymb,$env{'request.course.id'},
        !           191:                          $env{'course.'.$env{'request.course.id'}.'.domain'},
        !           192:                          $env{'course.'.$env{'request.course.id'}.'.num'});
        !           193:                     if ($contrib{'version'}) {
        !           194:                         for (my $id=1;$id<=$contrib{'version'};$id++) {
        !           195:                             unless (($contrib{'hidden'}=~/\.$id\./) || ($contrib{'deleted'}=~/\.$id\./)) {
        !           196:                                 if ($contrib{$id.':subject'}) {
        !           197:                                     $result .= $contrib{$id.':subject'};
        !           198:                                 }
        !           199:                                 if ($contrib{$id.':message'}) {
        !           200:                                     $result .= $contrib{$id.':message'};
        !           201:                                 }
        !           202:                                 if ($contrib{$id,':attachmenturl'}) {
        !           203:                                     if ($contrib{$id,':attachmenturl'} =~ m-/([^/]+)$-) {
        !           204:                                         $result .= $1;
        !           205:                                     }
        !           206:                                 }
        !           207:                                 $applies = &checkwords($result,$applies,@allwords);
        !           208:                             }
        !           209:                         }
        !           210:                     }
        !           211:                 }
        !           212: # Does this discussion apply?
        !           213:                 if ($applies) {
        !           214:                     my ($map,$ind,$url)=&Apache::lonnet::decode_symb($ressymb);
        !           215:                     my $disctype = &mt('resource');
        !           216:                     if ($url =~ m#/bulletinboard$#) {
        !           217:                         if ($url =~m#^adm/wrapper/adm/.*/bulletinboard$#) {
        !           218:                             $url =~s#^adm/wrapper##;
        !           219:                         }
        !           220:                         $disctype = &mt('discussion board');
        !           221:                     } else {
        !           222:                         $url = '/res/'.$url;
        !           223:                     }
        !           224:                     if ($url =~ /\?/) {
        !           225:                         $url .= '&amp;symb=';
        !           226:                     } else {
        !           227:                         $url .= '?symb=';
        !           228:                     }
        !           229:                     $url .= &escape($resource->symb());
        !           230:                     my $title = $resource->compTitle();
        !           231:                     $r->print('<br /><a href="'.$url.'" target="cat">'.
        !           232:                          ($title?$title:$url).'</a>&nbsp;&nbsp;-&nbsp;'.
        !           233:                          $disctype.'<br />');
        !           234:                     $totaldiscussions++;
        !           235:                 } else {
        !           236:                     $r->print(' .');
        !           237:                 }
        !           238:             }
        !           239:             unless ($totaldiscussions) {
        !           240:                 $r->print('<p class="LC_info">'.&mt('No matches found in postings.').'</p>');
        !           241:             }
        !           242:         } else {
        !           243:             $r->print('<div class="LC_error">'.&mt('An error occurred retrieving information about resources in the course.').'<br />'.&mt('It is recommended that you [_1]re-initialize the course[_2] and then try your search again.','<a href="/adm/roles">','</a>').'</div>');
        !           244:         }
        !           245:     }
        !           246: 
        !           247: # =================================================== Done going through course
        !           248:     $r->print(&Apache::loncommon::end_page());
        !           249: }
        !           250: 
        !           251: # =============================== This pulls up a resource and its dependencies
        !           252: 
        !           253: sub checkonthis {
        !           254:     my ($r,$id,$url,$level,$title,$fulltext,$symb,@allwords)=@_;
        !           255:     $alreadyseen{$id}=1;
        !           256:     if (&Apache::loncommon::connection_aborted($r)) { return; }
        !           257:     $r->rflush();
        !           258: 
        !           259:     my $result=$title.' ';
        !           260:     if ($env{'request.role.adv'} || !$hash{'encrypted_'.$id}) {
        !           261:         $result.=&Apache::lonnet::metadata($url,'title').' '.
        !           262:             &Apache::lonnet::metadata($url,'subject').' '.
        !           263:             &Apache::lonnet::metadata($url,'abstract').' '.
        !           264:             &Apache::lonnet::metadata($url,'keywords');
        !           265:     }
        !           266:     my ($extension)=($url=~/\.(\w+)$/);
        !           267:     if (&Apache::loncommon::fileembstyle($extension) eq 'ssi' &&
        !           268:         ($url) && ($fulltext)) {
        !           269:         $result.=&Apache::lonnet::ssi_body($url.'?symb='.&escape($symb));
        !           270:     }
        !           271:     $result=~s/\s+/ /gs;
        !           272:     my $applies = 0;
        !           273:     $applies = &checkwords($result,$applies,@allwords);
        !           274: # Does this resource apply?
        !           275:     if ($applies) {
        !           276:        $r->print('<br />');
        !           277:        for (my $i=0;$i<=$level*5;$i++) {
        !           278:            $r->print('&nbsp;');
        !           279:        }
        !           280:        my $href=$url;
        !           281:        if ($hash{'encrypted_'.$id} && !$env{'request.role.adv'}) {
        !           282:            $href=&Apache::lonenc::encrypted($href)
        !           283:                .'?symb='.&Apache::lonenc::encrypted($symb);
        !           284:        } else {
        !           285:            $href.='?symb='.&escape($symb);
        !           286:        }
        !           287:        $r->print('<a href="'.$href.'" target="cat">'.($title?$title:$url).
        !           288:                  '</a><br />');
        !           289:        $totalfound++;
        !           290:     } elsif ($fulltext) {
        !           291:        $r->print(' .');
        !           292:     }
        !           293:     $r->rflush();
        !           294: # Check also the dependencies of this one
        !           295:     my $dependencies=
        !           296:                 &Apache::lonnet::metadata($url,'dependencies');
        !           297:     foreach (split(/\,/,$dependencies)) {
        !           298:        if (($_=~/^\/res\//) && (!$alreadyseen{$id})) {
        !           299:           &checkonthis($r,$id,$_,$level+1,'',$fulltext,undef,@allwords);
        !           300:        }
        !           301:     }
        !           302: }
        !           303: 
        !           304: sub checkwords {
        !           305:     my ($result,$applies,@allwords) = @_;
        !           306:     foreach (@allwords) {
        !           307:         if ($_=~/\w/) {
        !           308:             if ($result=~/$_/si) {
        !           309:                 $applies++;
        !           310:             }
        !           311:         }
        !           312:     }
        !           313:     return $applies;
        !           314: }
        !           315: 
        !           316: sub untiehash {
        !           317:     if (tied(%hash)) {
        !           318:         untie(%hash);
        !           319:     }
        !           320: }
        !           321: 
        !           322: sub handler {
        !           323:     my $r = shift;
        !           324:     &Apache::loncommon::content_type($r,'text/html');
        !           325:     $r->send_http_header;
        !           326:     if ($r->header_only) { return OK; }
        !           327: 
        !           328:     my $crstype = &Apache::loncommon::course_type();
        !           329:     &Apache::loncommon::get_unprocessed_cgi($ENV{'QUERY_STRING'},['phase']);
        !           330:     &Apache::lonhtmlcommon::clear_breadcrumbs();
        !           331:     $r->print(&Apache::loncommon::start_page("$crstype Search"));
        !           332:     $r->print(&Apache::lonhtmlcommon::breadcrumbs("$crstype Search"));
        !           333:     &Apache::londocs::startContentScreen($r,'coursesearch');
        !           334:     if ($env{'form.phase'} eq 'results') {
        !           335:        &course_search($r);
        !           336:     } else {
        !           337:        $r->print(&menu());
        !           338:     }
        !           339:     &Apache::londocs::endContentScreen($r);
        !           340:     $r->print(&Apache::loncommon::end_page());
        !           341:     return OK;
        !           342: }
        !           343: 
        !           344: 1;

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>