/[BackupPC]/trunk/lib/BackupPC/SearchLib.pm
This is repository of my old source code which isn't updated any more. Go to git.rot13.org for current projects!
ViewVC logotype

Diff of /trunk/lib/BackupPC/SearchLib.pm

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 87 by dpavlin, Sun Aug 28 14:05:08 2005 UTC revision 143 by iklaric, Fri Oct 7 09:36:10 2005 UTC
# Line 15  my $pager_pages = 10; Line 15  my $pager_pages = 10;
15  my $dsn = $Conf{SearchDSN};  my $dsn = $Conf{SearchDSN};
16  my $db_user = $Conf{SearchUser} || '';  my $db_user = $Conf{SearchUser} || '';
17    
18  my $index_path = $Conf{HyperEstraierIndex};  my $hest_index_path = $Conf{HyperEstraierIndex};
 if ($index_path) {  
         $index_path = $TopDir . '/' . $index_path;  
         $index_path =~ s#//#/#g;  
 }  
19    
20  my $dbh;  my $dbh;
21    
# Line 175  sub getFiles($) { Line 171  sub getFiles($) {
171          return ($results, \@ret);          return ($results, \@ret);
172  }  }
173    
174    sub getHyperEstraier_url($) {
175            my ($use_hest) = @_;
176    
177            return unless $use_hest;
178    
179            use HyperEstraier;
180            my ($index_path, $index_node_url);
181    
182            if ($use_hest =~ m#^http://#) {
183                    $index_node_url = $use_hest;
184            } else {
185                    $index_path = $TopDir . '/' . $index_path;
186                    $index_path =~ s#//#/#g;
187            }
188            return ($index_path, $index_node_url);
189    }
190    
191  sub getFilesHyperEstraier($) {  sub getFilesHyperEstraier($) {
192          my ($param) = @_;          my ($param) = @_;
193    
194          my $offset = $param->{'offset'} || 0;          my $offset = $param->{'offset'} || 0;
195          $offset *= $on_page;          $offset *= $on_page;
196    
197          die "no index_path?" unless ($index_path);          die "no index_path?" unless ($hest_index_path);
198    
199          use HyperEstraier;          use HyperEstraier;
200    
201            my ($index_path, $index_node_url) = getHyperEstraier_url($hest_index_path);
202    
203          # open the database          # open the database
204          my $db = HyperEstraier::Database->new();          my $db;
205          $db->open($index_path, $HyperEstraier::ESTDBREADER);          if ($index_path) {
206                    $db = HyperEstraier::Database->new();
207                    $db->open($index_path, $HyperEstraier::ESTDBREADER);
208            } elsif ($index_node_url) {
209                    $db ||= HyperEstraier::Node->new($index_node_url);
210                    $db->set_auth('admin', 'admin');
211            } else {
212                    die "BUG: unimplemented";
213            }
214    
215          # create a search condition object          # create a search condition object
216          my $cond = HyperEstraier::Condition->new();          my $cond = HyperEstraier::Condition->new();
# Line 195  sub getFilesHyperEstraier($) { Line 218  sub getFilesHyperEstraier($) {
218          my $q = $param->{'search_filename'};          my $q = $param->{'search_filename'};
219          my $shareid = $param->{'search_share'};          my $shareid = $param->{'search_share'};
220    
221          if ($q) {          if (length($q) > 0) {
222                  $q =~ s/(.)/$1 /g;                  # exact match
223                    $cond->add_attr("filepath ISTRINC $q");
224    
225                    $q =~ s/(.)/$1 /g;
226                  # set the search phrase to the search condition object                  # set the search phrase to the search condition object
227                  $cond->set_phrase($q);                  $cond->set_phrase($q);
228          }          }
# Line 217  sub getFilesHyperEstraier($) { Line 242  sub getFilesHyperEstraier($) {
242          $cond->set_order( 'date NUMA' );          $cond->set_order( 'date NUMA' );
243    
244          # get the result of search          # get the result of search
         my $result = $db->search($cond, 0);  
   
245          my @res;          my @res;
246          my $hits = $result->size;          my ($result, $hits);
247    
248            if ($index_path) {
249                    $result = $db->search($cond, 0);
250                    $hits = $result->size;
251            } elsif ($index_node_url) {
252                    $result = $db->search($cond, 0);
253                    $hits = $result->doc_num;
254            } else {
255                    die "BUG: unimplemented";
256            }
257    
258          # for each document in result          # for each document in result
259          for my $i ($offset .. ($offset + $on_page - 1)) {          for my $i ($offset .. ($offset + $on_page - 1)) {
260                  last if ($i >= $hits);                  last if ($i >= $hits);
261    
262                  my $id = $result->get($i);                  my $doc;
263                  my $doc = $db->get_doc($id, 0);                  if ($index_path) {
264                            my $id = $result->get($i);
265                            $doc = $db->get_doc($id, 0);
266                    } elsif ($index_node_url) {
267                            $doc = $result->get_doc($i);
268                    } else {
269                            die "BUG: unimplemented";
270                    }
271    
272                  my $row;                  my $row;
273                  foreach my $c (qw/fid hname sname backupnum fiilename filepath date type size/) {                  foreach my $c (qw/fid hname sname backupnum fiilename filepath date type size/) {
# Line 239  sub getFilesHyperEstraier($) { Line 279  sub getFilesHyperEstraier($) {
279          return ($hits, \@res);          return ($hits, \@res);
280  }  }
281    
282    sub getGzipName($$$)
283    {
284            my ($host, $share, $backupnum) = @_;
285            my $ret = $Conf{GzipSchema};
286            
287            $share =~ s/\//_/g;
288            $ret =~ s/\\h/$host/ge;
289            $ret =~ s/\\s/$share/ge;
290            $ret =~ s/\\n/$backupnum/ge;
291            
292            return $ret;
293            
294    }
295    
296    sub getGzipSize($$)
297    {
298            my ($hostID, $backupNum) = @_;
299            my $ret;
300            my $sql;
301            my $dbh = get_dbh();
302            
303            $sql = q{
304                                    SELECT hosts.name  as host,
305                                               shares.name as share,
306                                               backups.num as backupnum
307                                    FROM hosts, backups, shares
308                                    WHERE shares.id=backups.shareid AND
309                                              hosts.id =backups.hostid AND
310                                              hosts.id=? AND
311                                              backups.num=?;
312                            };
313            my $sth = $dbh->prepare($sql);
314            $sth->execute($hostID, $backupNUM);
315            my $row = $res->fetchrow_hashref();
316            
317            my (undef,undef,undef,undef,undef,undef,undef,$ret,undef,undef,undef,undef,undef) =
318                            stat( $Conf{InstallDir}.'/'.$Conf{GzipTempDir}.'/'.
319                                    getGzipName($row->{'host'}, $row->{share}, $row->{'backupnum'}));
320            
321            return $ret;    
322    }
323    
324  sub getBackupsNotBurned() {  sub getBackupsNotBurned() {
325    
326          my $dbh = get_dbh();          my $dbh = get_dbh();
327          my $sql = q{  
328          SELECT          my $sql = q{
329                  backups.hostID          AS hostid,                  SELECT
330                  min(hosts.name)         AS host,                          backups.hostID AS hostID,
331                  backups.num             AS backupnum,                          hosts.name AS host,
332                  min(backups.type)       AS type,                          shares.name AS share,
333                  min(backups.date)       AS date,                          backups.id AS backupnum,
334                  min(backups.size)       AS size                          backups.type AS type,
335          FROM files                          backups.date AS date,
336                  INNER JOIN shares       ON files.shareID=shares.ID                          backups.size AS size
337                  INNER JOIN hosts        ON hosts.ID = shares.hostID                  FROM backups
338                  INNER JOIN backups      ON backups.num = files.backupnum and backups.hostID = hosts.ID AND backups.shareID = shares.ID                  INNER JOIN shares       ON backups.shareID=shares.ID
339          GROUP BY                  INNER JOIN hosts        ON backups.hostID = hosts.ID
340                  backups.hostID, backups.num                  LEFT OUTER JOIN archive_backup ON archive_backup.backup_id = backups.id
341          ORDER BY min(backups.date)                  WHERE backups.size > 0 AND archive_backup.backup_id IS NULL
342                    GROUP BY
343                            backups.hostID,
344                            hosts.name,
345                            shares.name,
346                            backups.num,
347                            backups.shareid,
348                            backups.id,
349                            backups.type,
350                            backups.date,
351                            backups.size
352                    ORDER BY backups.date
353          };          };
354          my $sth = $dbh->prepare( $sql );          my $sth = $dbh->prepare( $sql );
355          my @ret;          my @ret;
# Line 265  sub getBackupsNotBurned() { Line 358  sub getBackupsNotBurned() {
358          while ( my $row = $sth->fetchrow_hashref() ) {          while ( my $row = $sth->fetchrow_hashref() ) {
359                  $row->{'age'} = sprintf("%0.1f", ( (time() - $row->{'date'}) / 86400 ) );                  $row->{'age'} = sprintf("%0.1f", ( (time() - $row->{'date'}) / 86400 ) );
360                  $row->{'size'} = sprintf("%0.2f", $row->{'size'} / 1024 / 1024);                  $row->{'size'} = sprintf("%0.2f", $row->{'size'} / 1024 / 1024);
361                    my (undef,undef,undef,undef,undef,undef,undef,$fs_size,undef,undef,undef,undef,undef) =
362                            stat( $Conf{InstallDir}.'/'.$Conf{GzipTempDir}.'/'.
363                                    getGzipName($row->{'host'}, $row->{share}, $row->{'backupnum'}));
364                    $row->{'fs_size'} = $fs_size;
365                  push @ret, $row;                  push @ret, $row;
366          }          }
367                
368          return @ret;                return @ret;      
369  }  }
370    
371  sub displayBackupsGrid()  sub displayBackupsGrid() {
372    {  
373        my $retHTML = "";          my $retHTML .= q{
374        my $addForm = 1;                  <form id="forma" method="POST" action="}.$MyURL.q{?action=burn">
375                  };
       if ($addForm) {  
376    
377              $retHTML .= <<EOF3;          $retHTML .= <<'EOF3';
378  <script language="javascript" type="text/javascript">  <style type="text/css">
379  <!--  <!--
380    DIV#fixedBox {
381            position: absolute;
382            top: 50em;
383            left: -24%;
384            padding: 0.5em;
385            width: 20%;
386            background-color: #E0F0E0;
387            border: 1px solid #00C000;
388    }
389    
390      function checkAll(location)  DIV#fixedBox, DIV#fixedBox INPUT, DIV#fixedBox TEXTAREA {
391      {          font-size: 10pt;
392        for (var i=0;i<document.forma.elements.length;i++)  }
393        {  
394          var e = document.forma.elements[i];  FORM>DIV#fixedBox {
395          if ((e.checked || !e.checked) && e.name != \'all\') {          position: fixed !important;
396              if (eval("document.forma."+location+".checked")) {          left: 0.5em !important;
397                  e.checked = true;          top: auto !important;
398              } else {          bottom: 1em !important;
399                  e.checked = false;          width: 15% !important;
400              }  }
401          }  
402        }  DIV#fixedBox INPUT[type=text], DIV#fixedBox TEXTAREA {
403      }          border: 1px solid #00C000;
404  //-->  }
405  </script>        
406  EOF3  DIV#fixedBox #note {
407                $retHTML .= q{<form name="forma" method="GET" action="}."$MyURL"."?action=burn\"";          display: block;
408                $retHTML.= q{<input type="hidden" value="burn" name="action">};          width: 100%;
409                $retHTML .= q{<input type="hidden" value="results" name="search_results">};  }
410    
411    DIV#fixedBox #submitBurner {
412            display: block;
413            width: 100%;
414            margin-top: 0.5em;
415            cursor: pointer;
416    }
417    
418    * HTML {
419            overflow-y: hidden;
420    }
421    
422    * HTML BODY {
423            overflow-y: auto;
424            height: 100%;
425            font-size: 100%;
426    }
427    
428    * HTML DIV#fixedBox {
429            position: absolute;
430    }
431    
432    #mContainer, #gradient, #mask, #progressIndicator {
433            display: block;
434            width: 100%;
435            font-size: 10pt;
436            font-weight: bold;
437            text-align: center;
438            vertical-align: middle;
439            padding: 1px;
440    }
441    
442    #gradient, #mask, #progressIndicator {
443            left: 0;
444            border-width: 1px;
445            border-style: solid;
446            border-color: #000000;
447            color: #404040;
448            margin: 0.4em;
449            position: absolute;
450            margin-left: -1px;
451            margin-top: -1px;
452            margin-bottom: -1px;
453            overflow: hidden;
454    }
455    
456    #mContainer {
457            display: block;
458            position: relative;
459            padding: 0px;
460            margin-top: 0.4em;
461            margin-bottom: 0.5em;
462    }
463    
464    #gradient {
465            z-index: 1;
466            background-color: #FFFF00;
467    }
468    
469    #mask {
470            z-index: 2;
471            background-color: #FFFFFF;
472    }
473    
474    #progressIndicator {
475            z-index: 3;
476            background-color: transparent;
477    }
478    -->
479    </style>
480    <script type="text/javascript">
481    <!--
482    
483    var debug_div = null;
484    var media_size = 4400 * 1024;
485    
486    function debug(msg) {
487    //      return; // Disable debugging
488    
489            if (! debug_div) debug_div = document.getElementById('debug');
490    
491            // this will create debug div if it doesn't exist.
492            if (! debug_div) {
493                    debug_div = document.createElement('div');
494                    if (document.body) document.body.appendChild(debug_div);
495                    else debug_div = null;
496            }
497            if (debug_div) {
498                    debug_div.appendChild(document.createTextNode(msg));
499                    debug_div.appendChild(document.createElement("br"));
500          }          }
501          $retHTML .= qq{  }
502                  <table style="fview" border="1" cellspacing="0" cellpadding="3">  
                 <tr class="tableheader">  
         };  
503    
504          if ($addForm) {  var element_id_cache = Array();
505              $retHTML .= "<td class=\"tableheader\"><input type=\"checkbox\" name=\"allFiles\" onClick=\"checkAll('allFiles');\"></td>";  
506    function element_id(name,element) {
507            if (! element_id_cache[name]) {
508                    element_id_cache[name] = self.document.getElementById(name);
509          }          }
510          $retHTML .=  qq{          return element_id_cache[name];
511                  <td align="center">Host</td>  }
                 <td align="center">Backup no</td>  
                 <td align="center">Type</td>  
                 <td align="center">date</td>  
                 <td align="center">age/days</td>  
                 <td align="center">size/MB</td>  
                 </tr>  
         };  
512    
513          my @backups = getBackupsNotBurned();  function checkAll(location) {
514          my $backup;          var f = element_id('forma') || null;
515            if (!f) return false;
516    
517            var len = f.elements.length;
518            var check_all = element_id('allFiles');
519            var suma = check_all.checked ? (parseInt(f.elements['totalsize'].value) || 0) : 0;
520    
521            for (var i = 0; i < len; i++) {
522                    var e = f.elements[i];
523                    if (e.name != 'all' && e.name.substr(0, 3) == 'fcb') {
524                            if (check_all.checked) {
525                                    if (e.checked) continue;
526                                    var el = element_id("fss" + e.name.substr(3));
527                                    var size = parseInt(el.value) || 0;
528                                    debug('suma: '+suma+' size: '+size);
529                                    if ((suma + size) < media_size) {
530                                            suma += size;
531                                            e.checked = true;
532                                    } else {
533                                            break;
534                                    }
535                            } else {
536                                    e.checked = false;
537                            }
538                    }
539            }
540            update_sum(suma);
541    }
542    
543          if ($addForm) {  function update_sum(suma) {
544                  $retHTML .= qq{          element_id('forma').elements['totalsize'].value = suma;
545                          <tr><td colspan=7 style="tableheader">          pbar_set(suma, media_size);
546                          <input type="submit" value="Burn selected backups on medium" name="submitBurner">          debug('total size: ' + suma);
547                          </td></tr>  }
548                  };  
549    function sumiraj(e) {
550            var suma = parseInt(element_id('forma').elements['totalsize'].value) || 0;
551            var len = element_id('forma').elements.length;
552            if (e) {
553                    var size = parseInt( element_id("fss" + e.name.substr(3)).value);
554                    if (e.checked) {
555                            suma += size;
556                    } else {
557                            suma -= size;
558                    }
559            } else {
560                    suma = 0;
561                    for (var i = 0; i < len; i++) {
562                            var e = element_id('forma').elements[i];
563                            if (e.name != 'all' && e.checked && e.name.substr(0,3) == 'fcb') {
564                                    var el = element_id("fss" + e.name.substr(3));
565                                    if (el && el.value) suma += parseInt(el.value) || 0;
566                            }
567                    }
568          }          }
569            update_sum(suma);
570            return suma;
571    }
572    
573    /* progress bar */
574    
575          foreach $backup(@backups) {  var _pbar_width = null;
576    var _pbar_warn = 10;    // change color in last 10%
577    
578    function pbar_reset() {
579            element_id("mask").style.left = "0px";
580            _pbar_width = element_id("mContainer").offsetWidth - 2;
581            element_id("mask").style.width = _pbar_width + "px";
582            element_id("mask").style.display = "block";
583            element_id("progressIndicator").style.zIndex  = 10;
584            element_id("progressIndicator").innerHTML = "0";
585    }
586    
587    function dec2hex(d) {
588            var hch = '0123456789ABCDEF';
589            var a = d % 16;
590            var q = (d - a) / 16;
591            return hch.charAt(q) + hch.charAt(a);
592    }
593    
594    function pbar_set(amount, max) {
595            debug('pbar_set('+amount+', '+max+')');
596    
597            if (_pbar_width == null) {
598                    var _mc = element_id("mContainer");
599                    if (_pbar_width == null) _pbar_width = parseInt(_mc.offsetWidth ? (_mc.offsetWidth - 2) : 0) || null;
600                    if (_pbar_width == null) _pbar_width = parseInt(_mc.clientWidth ? (_mc.clientWidth + 2) : 0) || null;
601                    if (_pbar_width == null) _pbar_width = 0;
602            }
603    
604            var pcnt = Math.floor(amount * 100 / max);
605            var p90 = 100 - _pbar_warn;
606            var pcol = pcnt - p90;
607            if (Math.round(pcnt) <= 100) {
608                    if (pcol < 0) pcol = 0;
609                    var e = element_id("submitBurner");
610                    debug('enable_button');
611                    e.disabled = false;
612                    var a = e.getAttributeNode('disabled') || null;
613                    if (a) e.removeAttributeNode(a);
614            } else {
615                    debug('disable button');
616                    pcol = _pbar_warn;
617                    var e = element_id("submitBurner");
618                    if (!e.disabled) e.disabled = true;
619            }
620            var col_g = Math.floor((_pbar_warn - pcol) * 255 / _pbar_warn);
621            var col = '#FF' + dec2hex(col_g) + '00';
622    
623            //debug('pcol: '+pcol+' g:'+col_g+' _pbar_warn:'+ _pbar_warn + ' color: '+col);
624            element_id("gradient").style.backgroundColor = col;
625    
626            element_id("progressIndicator").innerHTML = pcnt + '%';
627            //element_id("progressIndicator").innerHTML = amount;
628    
629            element_id("mask").style.clip = 'rect(' + Array(
630                    '0px',
631                    element_id("mask").offsetWidth + 'px',
632                    element_id("mask").offsetHeight + 'px',
633                    Math.round(_pbar_width * amount / max) + 'px'
634            ).join(' ') + ')';
635    }
636    
637    if (!self.body) self.body = new Object();
638    self.onload = self.document.onload = self.body.onload = function() {
639            //pbar_reset();
640            sumiraj();
641    };
642    
643    // -->
644    </script>
645    <div id="fixedBox">
646    
647    Size: <input type="text" name="totalsize" size="7" readonly="readonly" style="text-align:right;" value="0" /> kB
648    
649    <div id="mContainer">
650            <div id="gradient">&nbsp;</div>
651            <div id="mask">&nbsp;</div>
652            <div id="progressIndicator">0%</div>
653    </div>
654    <br/>
655    
656    Note:
657    <textarea name="note" cols="10" rows="5" id="note"></textarea>
658    
659    <input type="submit" id="submitBurner" value="Burn selected" name="submitBurner" />
660    
661    </div>
662    <!--
663    <div id="debug" style="float: right; width: 10em; border: 1px #ff0000 solid; background-color: #ffe0e0; -moz-opacity: 0.7;">
664    no debug output yet
665    </div>
666    -->
667    EOF3
668            $retHTML .= q{
669                            <input type="hidden" value="burn" name="action">
670                            <input type="hidden" value="results" name="search_results">
671                            <table style="fview" border="0" cellspacing="0" cellpadding="2">
672                            <tr class="tableheader">
673                            <td class="tableheader">
674                                    <input type="checkbox" name="allFiles" id="allFiles" onClick="checkAll('allFiles');">
675                            </td>
676                            <td align="center">Share</td>
677                            <td align="center">Backup no</td>
678                            <td align="center">Type</td>
679                            <td align="center">date</td>
680                            <td align="center">age/days</td>
681                            <td align="center">size/MB</td>
682                            <td align="center">gzip size</td>
683                            </tr>
684    
685            };
686    
687            my @color = (' bgcolor="#e0e0e0"', '');
688    
689            my $i = 0;
690            my $host = '';
691    
692            foreach my $backup ( getBackupsNotBurned() ) {
693    
694                    if ($host ne $backup->{'host'}) {
695                            $i++;
696                            $host = $backup->{'host'};
697                    }
698                  my $ftype = "";                  my $ftype = "";
               
                 $retHTML .= "<tr>";  
                 if ($addForm) {  
                         $retHTML .= '<td class="fview"><input type="checkbox" name="fcb' .  
                                 $backup->{'hostid'}.'_'.$backup->{'backupnum'} .  
                                 '" value="' . $backup->{'hostid'}.'_'.$backup->{'backupnum'} .  
                                 '"></td>';  
                 }            
               
                 $retHTML .= '<td class="fviewborder">' . $backup->{'host'} . '</td>' .  
                         '<td class="fviewborder">' . $backup->{'backupnum'} . '</td>' .  
                         '<td class="fviewborder">' . $backup->{'type'} . '</td>' .  
                         '<td class="fviewborder">' . epoch_to_iso( $backup->{'date'} ) . '</td>' .  
                         '<td class="fviewborder">' . $backup->{'age'} . '</td>' .  
                         '<td class="fviewborder">' . $backup->{'size'} . '</td>' .  
                         '</tr>';  
         }  
699    
700          $retHTML .= "</table>";                  $retHTML .=
701                            '<tr' . $color[$i %2 ] . '>
702                            <td class="fview">';
703                    # FIXME
704                    $backup->{'fs_size'} = int($backup->{'size'} * 1024);
705                    if (($backup->{'fs_size'} || 0) > 0) {
706                            $retHTML .= '
707                            <input type="checkbox" name="fcb' .
708                            $backup->{'hostid'}.'_'.$backup->{'backupnum'} .
709                            '" value="' . $backup->{'hostid'}.'_'.$backup->{'backupnum'} .
710                            '" onClick="sumiraj(this);">';
711                    }
712                    $retHTML .=
713                            '</td>' .
714                            '<td align="right">' . $backup->{'host'} . ':' . $backup->{'share'} . '</td>' .
715                            '<td align="center">' . $backup->{'backupnum'} . '</td>' .
716                            '<td align="center">' . $backup->{'type'} . '</td>' .
717                            '<td align="center">' . epoch_to_iso( $backup->{'date'} ) . '</td>' .
718                            '<td align="center">' . $backup->{'age'} . '</td>' .
719                            '<td align="right">' . $backup->{'size'} . '</td>' .
720                            '<td align="right">' . $backup->{'fs_size'} .
721                            '<input type="hidden" iD="fss'.$backup->{'hostid'}.'_'.$backup->{'backupnum'} . '" value="'. $backup->{'fs_size'} .'"></td>' .
722    
723          if ($addForm) {                          "</tr>\n";
                 $retHTML .= "</form>";  
724          }          }
725    
726            $retHTML .= "</table>";
727            $retHTML .= "</form>";
728                
729          return $retHTML;          return $retHTML;
730  }        }      
# Line 373  sub displayGrid($) { Line 740  sub displayGrid($) {
740          my $start_t = time();          my $start_t = time();
741    
742          my ($results, $files);          my ($results, $files);
743          if ($param->{'use_hest'}) {          if ($param->{'use_hest'} && length($hilite) > 0) {
744                  ($results, $files) = getFilesHyperEstraier($param);                  ($results, $files) = getFilesHyperEstraier($param);
745          } else {          } else {
746                  ($results, $files) = getFiles($param);                  ($results, $files) = getFiles($param);
# Line 435  sub displayGrid($) { Line 802  sub displayGrid($) {
802                  my $typeStr  = BackupPC::Attrib::fileType2Text(undef, $file->{'type'});                  my $typeStr  = BackupPC::Attrib::fileType2Text(undef, $file->{'type'});
803                  $retHTML .= qq{<tr class="fviewborder">};                  $retHTML .= qq{<tr class="fviewborder">};
804    
805                  $retHTML .= qq{<td>$i</td>};                  $retHTML .= qq{<td class="fviewborder">$i</td>};
806    
807                  $retHTML .=                  $retHTML .=
808                          qq{<td class="fviewborder" align="right">} . $file->{'hname'} . ':' . $file->{'sname'} . qq{</td>} .                          qq{<td class="fviewborder" align="right">} . $file->{'hname'} . ':' . $file->{'sname'} . qq{</td>} .

Legend:
Removed from v.87  
changed lines
  Added in v.143

  ViewVC Help
Powered by ViewVC 1.1.26